]> git.sesse.net Git - ffmpeg/blob - doc/examples/encode_audio.c
Merge commit '67351924fa91dea4339109100a4c0689f006581f'
[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     FILE *f;
103     uint16_t *samples;
104     float t, tincr;
105
106     if (argc <= 1) {
107         fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
108         return 0;
109     }
110     filename = argv[1];
111
112     /* register all the codecs */
113     avcodec_register_all();
114
115     /* find the MP2 encoder */
116     codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
117     if (!codec) {
118         fprintf(stderr, "Codec not found\n");
119         exit(1);
120     }
121
122     c = avcodec_alloc_context3(codec);
123     if (!c) {
124         fprintf(stderr, "Could not allocate audio codec context\n");
125         exit(1);
126     }
127
128     /* put sample parameters */
129     c->bit_rate = 64000;
130
131     /* check that the encoder supports s16 pcm input */
132     c->sample_fmt = AV_SAMPLE_FMT_S16;
133     if (!check_sample_fmt(codec, c->sample_fmt)) {
134         fprintf(stderr, "Encoder does not support sample format %s",
135                 av_get_sample_fmt_name(c->sample_fmt));
136         exit(1);
137     }
138
139     /* select other audio parameters supported by the encoder */
140     c->sample_rate    = select_sample_rate(codec);
141     c->channel_layout = select_channel_layout(codec);
142     c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
143
144     /* open it */
145     if (avcodec_open2(c, codec, NULL) < 0) {
146         fprintf(stderr, "Could not open codec\n");
147         exit(1);
148     }
149
150     f = fopen(filename, "wb");
151     if (!f) {
152         fprintf(stderr, "Could not open %s\n", filename);
153         exit(1);
154     }
155
156     /* frame containing input raw audio */
157     frame = av_frame_alloc();
158     if (!frame) {
159         fprintf(stderr, "Could not allocate audio frame\n");
160         exit(1);
161     }
162
163     frame->nb_samples     = c->frame_size;
164     frame->format         = c->sample_fmt;
165     frame->channel_layout = c->channel_layout;
166
167     /* allocate the data buffers */
168     ret = av_frame_get_buffer(frame, 0);
169     if (ret < 0) {
170         fprintf(stderr, "Could not allocate audio data buffers\n");
171         exit(1);
172     }
173
174     /* encode a single tone sound */
175     t = 0;
176     tincr = 2 * M_PI * 440.0 / c->sample_rate;
177     for (i = 0; i < 200; i++) {
178         av_init_packet(&pkt);
179         pkt.data = NULL; // packet data will be allocated by the encoder
180         pkt.size = 0;
181
182         /* make sure the frame is writable -- makes a copy if the encoder
183          * kept a reference internally */
184         ret = av_frame_make_writable(frame);
185         if (ret < 0)
186             exit(1);
187         samples = (uint16_t*)frame->data[0];
188
189         for (j = 0; j < c->frame_size; j++) {
190             samples[2*j] = (int)(sin(t) * 10000);
191
192             for (k = 1; k < c->channels; k++)
193                 samples[2*j + k] = samples[2*j];
194             t += tincr;
195         }
196         /* encode the samples */
197         ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
198         if (ret < 0) {
199             fprintf(stderr, "Error encoding audio frame\n");
200             exit(1);
201         }
202         if (got_output) {
203             fwrite(pkt.data, 1, pkt.size, f);
204             av_packet_unref(&pkt);
205         }
206     }
207
208     /* get the delayed frames */
209     for (got_output = 1; got_output; i++) {
210         ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
211         if (ret < 0) {
212             fprintf(stderr, "Error encoding frame\n");
213             exit(1);
214         }
215
216         if (got_output) {
217             fwrite(pkt.data, 1, pkt.size, f);
218             av_packet_unref(&pkt);
219         }
220     }
221     fclose(f);
222
223     av_frame_free(&frame);
224     avcodec_free_context(&c);
225
226     return 0;
227 }