History

api-example: update to new audio encoding API.

Anton Khirnov committed 14 years ago

Commit 5702c861 parent 154caa61 file · +120 −17Browse files

Unified · Split

libavcodec/api-example.c+120−17
@@ -37,6 +37,7 @@ · 36 unmodified lines
3737 #endif
3838
3939 #include "libavcodec/avcodec.h"
40+#include "libavutil/audioconvert.h"
4041 #include "libavutil/mathematics.h"
4142 #include "libavutil/samplefmt.h"
4243
@@ -44,6 +45,59 @@ · 1 unmodified line
4445 #define AUDIO_INBUF_SIZE 20480
4546 #define AUDIO_REFILL_THRESH 4096
4647
48+/* check that a given sample format is supported by the encoder */
49+static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
50+{
51+ const enum AVSampleFormat *p = codec->sample_fmts;
52+
53+ while (*p != AV_SAMPLE_FMT_NONE) {
54+ if (*p == sample_fmt)
55+ return 1;
56+ p++;
57+ }
58+ return 0;
59+}
60+
61+/* just pick the highest supported samplerate */
62+static int select_sample_rate(AVCodec *codec)
63+{
64+ const int *p;
65+ int best_samplerate = 0;
66+
67+ if (!codec->supported_samplerates)
68+ return 44100;
69+
70+ p = codec->supported_samplerates;
71+ while (*p) {
72+ best_samplerate = FFMAX(*p, best_samplerate);
73+ p++;
74+ }
75+ return best_samplerate;
76+}
77+
78+/* select layout with the highest channel count */
79+static int select_channel_layout(AVCodec *codec)
80+{
81+ const uint64_t *p;
82+ uint64_t best_ch_layout = 0;
83+ int best_nb_channells = 0;
84+
85+ if (!codec->channel_layouts)
86+ return AV_CH_LAYOUT_STEREO;
87+
88+ p = codec->channel_layouts;
89+ while (*p) {
90+ int nb_channels = av_get_channel_layout_nb_channels(*p);
91+
92+ if (nb_channels > best_nb_channells) {
93+ best_ch_layout = *p;
94+ best_nb_channells = nb_channels;
95+ }
96+ p++;
97+ }
98+ return best_ch_layout;
99+}
100+
47101 /*
48102 * Audio encoding example
49103 */
@@ -51,11 +105,13 @@ static void audio_encode_example(const char *filename) · 1 unmodified line
51105 {
52106 AVCodec *codec;
53107 AVCodecContext *c= NULL;
54− int frame_size, i, j, out_size, outbuf_size;
108+ AVFrame *frame;
109+ AVPacket pkt;
110+ int i, j, k, ret, got_output;
111+ int buffer_size;
55112 FILE *f;
56− short *samples;
113+ uint16_t *samples;
57114 float t, tincr;
58− uint8_t *outbuf;
59115
60116 printf("Audio encoding\n");
61117
@@ -70,8 +126,19 @@ static void audio_encode_example(const char *filename) · 8 unmodified lines
70126
71127 /* put sample parameters */
72128 c->bit_rate = 64000;
73− c->sample_rate = 44100;
74− c->channels = 2;
129+
130+ /* check that the encoder supports s16 pcm input */
131+ c->sample_fmt = AV_SAMPLE_FMT_S16;
132+ if (!check_sample_fmt(codec, c->sample_fmt)) {
133+ fprintf(stderr, "encoder does not support %s",
134+ av_get_sample_fmt_name(c->sample_fmt));
135+ exit(1);
136+ }
137+
138+ /* select other audio parameters supported by the encoder */
139+ c->sample_rate = select_sample_rate(codec);
140+ c->channel_layout = select_channel_layout(codec);
141+ c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
75142
76143 /* open it */
77144 if (avcodec_open2(c, codec, NULL) < 0) {
@@ -79,35 +146,71 @@ static void audio_encode_example(const char *filename) · 1 unmodified line
79146 exit(1);
80147 }
81148
82− /* the codec gives us the frame size, in samples */
83− frame_size = c->frame_size;
84− samples = malloc(frame_size * 2 * c->channels);
85− outbuf_size = 10000;
86− outbuf = malloc(outbuf_size);
87−
88149 f = fopen(filename, "wb");
89150 if (!f) {
90151 fprintf(stderr, "could not open %s\n", filename);
91152 exit(1);
92153 }
93154
155+ /* frame containing input raw audio */
156+ frame = avcodec_alloc_frame();
157+ if (!frame) {
158+ fprintf(stderr, "could not allocate audio frame\n");
159+ exit(1);
160+ }
161+
162+ frame->nb_samples = c->frame_size;
163+ frame->format = c->sample_fmt;
164+ frame->channel_layout = c->channel_layout;
165+
166+ /* the codec gives us the frame size, in samples,
167+ * we calculate the size of the samples buffer in bytes */
168+ buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
169+ c->sample_fmt, 0);
170+ samples = av_malloc(buffer_size);
171+ if (!samples) {
172+ fprintf(stderr, "could not allocate %d bytes for samples buffer\n",
173+ buffer_size);
174+ exit(1);
175+ }
176+ /* setup the data pointers in the AVFrame */
177+ ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
178+ (const uint8_t*)samples, buffer_size, 0);
179+ if (ret < 0) {
180+ fprintf(stderr, "could not setup audio frame\n");
181+ exit(1);
182+ }
183+
94184 /* encode a single tone sound */
95185 t = 0;
96186 tincr = 2 * M_PI * 440.0 / c->sample_rate;
97187 for(i=0;i<200;i++) {
98− for(j=0;j<frame_size;j++) {
188+ av_init_packet(&pkt);
189+ pkt.data = NULL; // packet data will be allocated by the encoder
190+ pkt.size = 0;
191+
192+ for (j = 0; j < c->frame_size; j++) {
99193 samples[2*j] = (int)(sin(t) * 10000);
100− samples[2*j+1] = samples[2*j];
194+
195+ for (k = 1; k < c->channels; k++)
196+ samples[2*j + k] = samples[2*j];
101197 t += tincr;
102198 }
103199 /* encode the samples */
104− out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
105− fwrite(outbuf, 1, out_size, f);
200+ ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
201+ if (ret < 0) {
202+ fprintf(stderr, "error encoding audio frame\n");
203+ exit(1);
204+ }
205+ if (got_output) {
206+ fwrite(pkt.data, 1, pkt.size, f);
207+ av_free_packet(&pkt);
208+ }
106209 }
107210 fclose(f);
108− free(outbuf);
109− free(samples);
110211
212+ av_freep(&samples);
213+ av_freep(&frame);
111214 avcodec_close(c);
112215 av_free(c);
113216 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t