]> git.sesse.net Git - ffmpeg/blob - doc/examples/encode_audio.c
b788775a5670cc680b34b622d1e2dd85d39946ca
[ffmpeg] / doc / examples / encode_audio.c
1 /*
2  * Copyright (c) 2001 Fabrice Bellard
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22
23 /**
24  * @file
25  * audio encoding with libavcodec API example.
26  *
27  * @example encode_audio.c
28  */
29
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #include "libavcodec/avcodec.h"
35
36 #include "libavutil/channel_layout.h"
37 #include "libavutil/common.h"
38 #include "libavutil/frame.h"
39 #include "libavutil/samplefmt.h"
40
41 /* check that a given sample format is supported by the encoder */
42 static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
43 {
44     const enum AVSampleFormat *p = codec->sample_fmts;
45
46     while (*p != AV_SAMPLE_FMT_NONE) {
47         if (*p == sample_fmt)
48             return 1;
49         p++;
50     }
51     return 0;
52 }
53
54 /* just pick the highest supported samplerate */
55 static int select_sample_rate(const AVCodec *codec)
56 {
57     const int *p;
58     int best_samplerate = 0;
59
60     if (!codec->supported_samplerates)
61         return 44100;
62
63     p = codec->supported_samplerates;
64     while (*p) {
65         best_samplerate = FFMAX(*p, best_samplerate);
66         p++;
67     }
68     return best_samplerate;
69 }
70
71 /* select layout with the highest channel count */
72 static int select_channel_layout(const AVCodec *codec)
73 {
74     const uint64_t *p;
75     uint64_t best_ch_layout = 0;
76     int best_nb_channels   = 0;
77
78     if (!codec->channel_layouts)
79         return AV_CH_LAYOUT_STEREO;
80
81     p = codec->channel_layouts;
82     while (*p) {
83         int nb_channels = av_get_channel_layout_nb_channels(*p);
84
85         if (nb_channels > best_nb_channels) {
86             best_ch_layout    = *p;
87             best_nb_channels = nb_channels;
88         }
89         p++;
90     }
91     return best_ch_layout;
92 }
93
94 int main(int argc, char **argv)
95 {
96     const char *filename;
97     const AVCodec *codec;
98     AVCodecContext *c= NULL;
99     AVFrame *frame;
100     AVPacket pkt;
101     int i, j, k, ret, got_output;
102     int buffer_size;
103     FILE *f;
104     uint16_t *samples;
105     float t, tincr;
106
107     if (argc <= 1) {
108         fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
109         return 0;
110     }
111     filename = argv[1];
112
113     /* register all the codecs */
114     avcodec_register_all();
115
116     /* find the MP2 encoder */
117     codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
118     if (!codec) {
119         fprintf(stderr, "Codec not found\n");
120         exit(1);
121     }
122
123     c = avcodec_alloc_context3(codec);
124     if (!c) {
125         fprintf(stderr, "Could not allocate audio codec context\n");
126         exit(1);
127     }
128
129     /* put sample parameters */
130     c->bit_rate = 64000;
131
132     /* check that the encoder supports s16 pcm input */
133     c->sample_fmt = AV_SAMPLE_FMT_S16;
134     if (!check_sample_fmt(codec, c->sample_fmt)) {
135         fprintf(stderr, "Encoder does not support sample format %s",
136                 av_get_sample_fmt_name(c->sample_fmt));
137         exit(1);
138     }
139
140     /* select other audio parameters supported by the encoder */
141     c->sample_rate    = select_sample_rate(codec);
142     c->channel_layout = select_channel_layout(codec);
143     c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
144
145     /* open it */
146     if (avcodec_open2(c, codec, NULL) < 0) {
147         fprintf(stderr, "Could not open codec\n");
148         exit(1);
149     }
150
151     f = fopen(filename, "wb");
152     if (!f) {
153         fprintf(stderr, "Could not open %s\n", filename);
154         exit(1);
155     }
156
157     /* frame containing input raw audio */
158     frame = av_frame_alloc();
159     if (!frame) {
160         fprintf(stderr, "Could not allocate audio frame\n");
161         exit(1);
162     }
163
164     frame->nb_samples     = c->frame_size;
165     frame->format         = c->sample_fmt;
166     frame->channel_layout = c->channel_layout;
167
168     /* the codec gives us the frame size, in samples,
169      * we calculate the size of the samples buffer in bytes */
170     buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
171                                              c->sample_fmt, 0);
172     if (buffer_size < 0) {
173         fprintf(stderr, "Could not get sample buffer size\n");
174         exit(1);
175     }
176     samples = av_malloc(buffer_size);
177     if (!samples) {
178         fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
179                 buffer_size);
180         exit(1);
181     }
182     /* setup the data pointers in the AVFrame */
183     ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
184                                    (const uint8_t*)samples, buffer_size, 0);
185     if (ret < 0) {
186         fprintf(stderr, "Could not setup audio frame\n");
187         exit(1);
188     }
189
190     /* encode a single tone sound */
191     t = 0;
192     tincr = 2 * M_PI * 440.0 / c->sample_rate;
193     for (i = 0; i < 200; i++) {
194         av_init_packet(&pkt);
195         pkt.data = NULL; // packet data will be allocated by the encoder
196         pkt.size = 0;
197
198         for (j = 0; j < c->frame_size; j++) {
199             samples[2*j] = (int)(sin(t) * 10000);
200
201             for (k = 1; k < c->channels; k++)
202                 samples[2*j + k] = samples[2*j];
203             t += tincr;
204         }
205         /* encode the samples */
206         ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
207         if (ret < 0) {
208             fprintf(stderr, "Error encoding audio frame\n");
209             exit(1);
210         }
211         if (got_output) {
212             fwrite(pkt.data, 1, pkt.size, f);
213             av_packet_unref(&pkt);
214         }
215     }
216
217     /* get the delayed frames */
218     for (got_output = 1; got_output; i++) {
219         ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
220         if (ret < 0) {
221             fprintf(stderr, "Error encoding frame\n");
222             exit(1);
223         }
224
225         if (got_output) {
226             fwrite(pkt.data, 1, pkt.size, f);
227             av_packet_unref(&pkt);
228         }
229     }
230     fclose(f);
231
232     av_freep(&samples);
233     av_frame_free(&frame);
234     avcodec_free_context(&c);
235 }