examples/avcodec: split audio encoding into a separate example
authorAnton Khirnov <anton@khirnov.net>
Wed, 19 Oct 2016 19:05:22 +0000 (21:05 +0200)
committerAnton Khirnov <anton@khirnov.net>
Wed, 2 Nov 2016 09:11:46 +0000 (10:11 +0100)
The four examples (audio/video encoding/decoding) are completely
independent so it makes little sense to have them all in one file.

configure
doc/Makefile
doc/examples/avcodec.c
doc/examples/encode_audio.c [new file with mode: 0644]

index 8c2b4fd..28567bb 100755 (executable)
--- a/configure
+++ b/configure
@@ -1210,6 +1210,7 @@ COMPONENT_LIST="
 
 EXAMPLE_LIST="
     avcodec_example
+    encode_audio_example
     filter_audio_example
     metadata_example
     output_example
@@ -2435,6 +2436,7 @@ scale_vaapi_filter_deps="vaapi VAProcPipelineParameterBuffer"
 
 # examples
 avcodec_example_deps="avcodec avutil"
+encode_audio_example_deps="avcodec avutil"
 filter_audio_example_deps="avfilter avutil"
 metadata_example_deps="avformat avutil"
 output_example_deps="avcodec avformat avutil swscale"
index c464a48..738e601 100644 (file)
@@ -17,12 +17,13 @@ DOCS-$(CONFIG_TEXI2HTML)                        += $(HTMLPAGES)
 DOCS = $(DOCS-yes)
 
 DOC_EXAMPLES-$(CONFIG_AVCODEC_EXAMPLE)          += avcodec
+DOC_EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)     += encode_audio
 DOC_EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE)     += filter_audio
 DOC_EXAMPLES-$(CONFIG_METADATA_EXAMPLE)         += metadata
 DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE)           += output
 DOC_EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)           += qsvdec
 DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE)    += transcode_aac
-ALL_DOC_EXAMPLES = avcodec filter_audio metadata output transcode_aac
+ALL_DOC_EXAMPLES = avcodec encode_audio filter_audio metadata output transcode_aac
 
 DOC_EXAMPLES     := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF))
 ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES:%=doc/examples/%$(EXESUF))
index 8fee552..63812d9 100644 (file)
 #define AUDIO_INBUF_SIZE 20480
 #define AUDIO_REFILL_THRESH 4096
 
-/* check that a given sample format is supported by the encoder */
-static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
-{
-    const enum AVSampleFormat *p = codec->sample_fmts;
-
-    while (*p != AV_SAMPLE_FMT_NONE) {
-        if (*p == sample_fmt)
-            return 1;
-        p++;
-    }
-    return 0;
-}
-
-/* just pick the highest supported samplerate */
-static int select_sample_rate(AVCodec *codec)
-{
-    const int *p;
-    int best_samplerate = 0;
-
-    if (!codec->supported_samplerates)
-        return 44100;
-
-    p = codec->supported_samplerates;
-    while (*p) {
-        best_samplerate = FFMAX(*p, best_samplerate);
-        p++;
-    }
-    return best_samplerate;
-}
-
-/* select layout with the highest channel count */
-static int select_channel_layout(AVCodec *codec)
-{
-    const uint64_t *p;
-    uint64_t best_ch_layout = 0;
-    int best_nb_channels   = 0;
-
-    if (!codec->channel_layouts)
-        return AV_CH_LAYOUT_STEREO;
-
-    p = codec->channel_layouts;
-    while (*p) {
-        int nb_channels = av_get_channel_layout_nb_channels(*p);
-
-        if (nb_channels > best_nb_channels) {
-            best_ch_layout    = *p;
-            best_nb_channels = nb_channels;
-        }
-        p++;
-    }
-    return best_ch_layout;
-}
-
-/*
- * Audio encoding example
- */
-static void audio_encode_example(const char *filename)
-{
-    AVCodec *codec;
-    AVCodecContext *c= NULL;
-    AVFrame *frame;
-    AVPacket pkt;
-    int i, j, k, ret, got_output;
-    int buffer_size;
-    FILE *f;
-    uint16_t *samples;
-    float t, tincr;
-
-    printf("Audio encoding\n");
-
-    /* find the MP2 encoder */
-    codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    c = avcodec_alloc_context3(codec);
-
-    /* put sample parameters */
-    c->bit_rate = 64000;
-
-    /* check that the encoder supports s16 pcm input */
-    c->sample_fmt = AV_SAMPLE_FMT_S16;
-    if (!check_sample_fmt(codec, c->sample_fmt)) {
-        fprintf(stderr, "encoder does not support %s",
-                av_get_sample_fmt_name(c->sample_fmt));
-        exit(1);
-    }
-
-    /* select other audio parameters supported by the encoder */
-    c->sample_rate    = select_sample_rate(codec);
-    c->channel_layout = select_channel_layout(codec);
-    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
-
-    /* open it */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        fprintf(stderr, "could not open %s\n", filename);
-        exit(1);
-    }
-
-    /* frame containing input raw audio */
-    frame = av_frame_alloc();
-    if (!frame) {
-        fprintf(stderr, "could not allocate audio frame\n");
-        exit(1);
-    }
-
-    frame->nb_samples     = c->frame_size;
-    frame->format         = c->sample_fmt;
-    frame->channel_layout = c->channel_layout;
-
-    /* the codec gives us the frame size, in samples,
-     * we calculate the size of the samples buffer in bytes */
-    buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
-                                             c->sample_fmt, 0);
-    samples = av_malloc(buffer_size);
-    if (!samples) {
-        fprintf(stderr, "could not allocate %d bytes for samples buffer\n",
-                buffer_size);
-        exit(1);
-    }
-    /* setup the data pointers in the AVFrame */
-    ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
-                                   (const uint8_t*)samples, buffer_size, 0);
-    if (ret < 0) {
-        fprintf(stderr, "could not setup audio frame\n");
-        exit(1);
-    }
-
-    /* encode a single tone sound */
-    t = 0;
-    tincr = 2 * M_PI * 440.0 / c->sample_rate;
-    for(i=0;i<200;i++) {
-        av_init_packet(&pkt);
-        pkt.data = NULL; // packet data will be allocated by the encoder
-        pkt.size = 0;
-
-        for (j = 0; j < c->frame_size; j++) {
-            samples[2*j] = (int)(sin(t) * 10000);
-
-            for (k = 1; k < c->channels; k++)
-                samples[2*j + k] = samples[2*j];
-            t += tincr;
-        }
-        /* encode the samples */
-        ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
-        if (ret < 0) {
-            fprintf(stderr, "error encoding audio frame\n");
-            exit(1);
-        }
-        if (got_output) {
-            fwrite(pkt.data, 1, pkt.size, f);
-            av_packet_unref(&pkt);
-        }
-    }
-    fclose(f);
-
-    av_freep(&samples);
-    av_frame_free(&frame);
-    avcodec_free_context(&c);
-}
-
 /*
  * Audio decoding.
  */
@@ -575,7 +406,6 @@ int main(int argc, char **argv)
     avcodec_register_all();
 
     if (argc <= 1) {
-        audio_encode_example("/tmp/test.mp2");
         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
 
         video_encode_example("/tmp/test.mpg");
diff --git a/doc/examples/encode_audio.c b/doc/examples/encode_audio.c
new file mode 100644 (file)
index 0000000..cabe589
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * audio encoding with libavcodec API example.
+ *
+ * @example encode_audio.c
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libavcodec/avcodec.h"
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/frame.h"
+#include "libavutil/samplefmt.h"
+
+/* check that a given sample format is supported by the encoder */
+static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
+{
+    const enum AVSampleFormat *p = codec->sample_fmts;
+
+    while (*p != AV_SAMPLE_FMT_NONE) {
+        if (*p == sample_fmt)
+            return 1;
+        p++;
+    }
+    return 0;
+}
+
+/* just pick the highest supported samplerate */
+static int select_sample_rate(AVCodec *codec)
+{
+    const int *p;
+    int best_samplerate = 0;
+
+    if (!codec->supported_samplerates)
+        return 44100;
+
+    p = codec->supported_samplerates;
+    while (*p) {
+        best_samplerate = FFMAX(*p, best_samplerate);
+        p++;
+    }
+    return best_samplerate;
+}
+
+/* select layout with the highest channel count */
+static int select_channel_layout(AVCodec *codec)
+{
+    const uint64_t *p;
+    uint64_t best_ch_layout = 0;
+    int best_nb_channels   = 0;
+
+    if (!codec->channel_layouts)
+        return AV_CH_LAYOUT_STEREO;
+
+    p = codec->channel_layouts;
+    while (*p) {
+        int nb_channels = av_get_channel_layout_nb_channels(*p);
+
+        if (nb_channels > best_nb_channels) {
+            best_ch_layout    = *p;
+            best_nb_channels = nb_channels;
+        }
+        p++;
+    }
+    return best_ch_layout;
+}
+
+int main(int argc, char **argv)
+{
+    const char *filename;
+    AVCodec *codec;
+    AVCodecContext *c= NULL;
+    AVFrame *frame;
+    AVPacket pkt;
+    int i, j, k, ret, got_output;
+    int buffer_size;
+    FILE *f;
+    uint16_t *samples;
+    float t, tincr;
+
+    if (argc <= 1) {
+        fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
+        return 0;
+    }
+    filename = argv[1];
+
+    /* register all the codecs */
+    avcodec_register_all();
+
+    /* find the MP2 encoder */
+    codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
+    if (!codec) {
+        fprintf(stderr, "codec not found\n");
+        exit(1);
+    }
+
+    c = avcodec_alloc_context3(codec);
+
+    /* put sample parameters */
+    c->bit_rate = 64000;
+
+    /* check that the encoder supports s16 pcm input */
+    c->sample_fmt = AV_SAMPLE_FMT_S16;
+    if (!check_sample_fmt(codec, c->sample_fmt)) {
+        fprintf(stderr, "encoder does not support %s",
+                av_get_sample_fmt_name(c->sample_fmt));
+        exit(1);
+    }
+
+    /* select other audio parameters supported by the encoder */
+    c->sample_rate    = select_sample_rate(codec);
+    c->channel_layout = select_channel_layout(codec);
+    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
+
+    /* open it */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "could not open codec\n");
+        exit(1);
+    }
+
+    f = fopen(filename, "wb");
+    if (!f) {
+        fprintf(stderr, "could not open %s\n", filename);
+        exit(1);
+    }
+
+    /* frame containing input raw audio */
+    frame = av_frame_alloc();
+    if (!frame) {
+        fprintf(stderr, "could not allocate audio frame\n");
+        exit(1);
+    }
+
+    frame->nb_samples     = c->frame_size;
+    frame->format         = c->sample_fmt;
+    frame->channel_layout = c->channel_layout;
+
+    /* the codec gives us the frame size, in samples,
+     * we calculate the size of the samples buffer in bytes */
+    buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
+                                             c->sample_fmt, 0);
+    samples = av_malloc(buffer_size);
+    if (!samples) {
+        fprintf(stderr, "could not allocate %d bytes for samples buffer\n",
+                buffer_size);
+        exit(1);
+    }
+    /* setup the data pointers in the AVFrame */
+    ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
+                                   (const uint8_t*)samples, buffer_size, 0);
+    if (ret < 0) {
+        fprintf(stderr, "could not setup audio frame\n");
+        exit(1);
+    }
+
+    /* encode a single tone sound */
+    t = 0;
+    tincr = 2 * M_PI * 440.0 / c->sample_rate;
+    for(i=0;i<200;i++) {
+        av_init_packet(&pkt);
+        pkt.data = NULL; // packet data will be allocated by the encoder
+        pkt.size = 0;
+
+        for (j = 0; j < c->frame_size; j++) {
+            samples[2*j] = (int)(sin(t) * 10000);
+
+            for (k = 1; k < c->channels; k++)
+                samples[2*j + k] = samples[2*j];
+            t += tincr;
+        }
+        /* encode the samples */
+        ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
+        if (ret < 0) {
+            fprintf(stderr, "error encoding audio frame\n");
+            exit(1);
+        }
+        if (got_output) {
+            fwrite(pkt.data, 1, pkt.size, f);
+            av_packet_unref(&pkt);
+        }
+    }
+    fclose(f);
+
+    av_freep(&samples);
+    av_frame_free(&frame);
+    avcodec_free_context(&c);
+}