]> git.sesse.net Git - ffmpeg/blob - doc/examples/transcode_aac.c
Merge commit 'b200a2c8da403b5a5c8b50f8cb4a75fd4f0131b1'
[ffmpeg] / doc / examples / transcode_aac.c
1 /*
2  * Copyright (c) 2013-2017 Andreas Unterweger
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * Simple audio converter
24  *
25  * @example transcode_aac.c
26  * Convert an input audio file to AAC in an MP4 container using FFmpeg.
27  * Formats other than MP4 are supported based on the output file extension.
28  * @author Andreas Unterweger (dustsigns@gmail.com)
29  */
30
31 #include <stdio.h>
32
33 #include "libavformat/avformat.h"
34 #include "libavformat/avio.h"
35
36 #include "libavcodec/avcodec.h"
37
38 #include "libavutil/audio_fifo.h"
39 #include "libavutil/avassert.h"
40 #include "libavutil/avstring.h"
41 #include "libavutil/frame.h"
42 #include "libavutil/opt.h"
43
44 #include "libswresample/swresample.h"
45
46 /* The output bit rate in bit/s */
47 #define OUTPUT_BIT_RATE 96000
48 /* The number of output channels */
49 #define OUTPUT_CHANNELS 2
50
51 /**
52  * Open an input file and the required decoder.
53  * @param      filename             File to be opened
54  * @param[out] input_format_context Format context of opened file
55  * @param[out] input_codec_context  Codec context of opened file
56  * @return Error code (0 if successful)
57  */
58 static int open_input_file(const char *filename,
59                            AVFormatContext **input_format_context,
60                            AVCodecContext **input_codec_context)
61 {
62     AVCodecContext *avctx;
63     AVCodec *input_codec;
64     int error;
65
66     /* Open the input file to read from it. */
67     if ((error = avformat_open_input(input_format_context, filename, NULL,
68                                      NULL)) < 0) {
69         fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
70                 filename, av_err2str(error));
71         *input_format_context = NULL;
72         return error;
73     }
74
75     /* Get information on the input file (number of streams etc.). */
76     if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
77         fprintf(stderr, "Could not open find stream info (error '%s')\n",
78                 av_err2str(error));
79         avformat_close_input(input_format_context);
80         return error;
81     }
82
83     /* Make sure that there is only one stream in the input file. */
84     if ((*input_format_context)->nb_streams != 1) {
85         fprintf(stderr, "Expected one audio input stream, but found %d\n",
86                 (*input_format_context)->nb_streams);
87         avformat_close_input(input_format_context);
88         return AVERROR_EXIT;
89     }
90
91     /* Find a decoder for the audio stream. */
92     if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) {
93         fprintf(stderr, "Could not find input codec\n");
94         avformat_close_input(input_format_context);
95         return AVERROR_EXIT;
96     }
97
98     /* Allocate a new decoding context. */
99     avctx = avcodec_alloc_context3(input_codec);
100     if (!avctx) {
101         fprintf(stderr, "Could not allocate a decoding context\n");
102         avformat_close_input(input_format_context);
103         return AVERROR(ENOMEM);
104     }
105
106     /* Initialize the stream parameters with demuxer information. */
107     error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar);
108     if (error < 0) {
109         avformat_close_input(input_format_context);
110         avcodec_free_context(&avctx);
111         return error;
112     }
113
114     /* Open the decoder for the audio stream to use it later. */
115     if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
116         fprintf(stderr, "Could not open input codec (error '%s')\n",
117                 av_err2str(error));
118         avcodec_free_context(&avctx);
119         avformat_close_input(input_format_context);
120         return error;
121     }
122
123     /* Save the decoder context for easier access later. */
124     *input_codec_context = avctx;
125
126     return 0;
127 }
128
129 /**
130  * Open an output file and the required encoder.
131  * Also set some basic encoder parameters.
132  * Some of these parameters are based on the input file's parameters.
133  * @param      filename              File to be opened
134  * @param      input_codec_context   Codec context of input file
135  * @param[out] output_format_context Format context of output file
136  * @param[out] output_codec_context  Codec context of output file
137  * @return Error code (0 if successful)
138  */
139 static int open_output_file(const char *filename,
140                             AVCodecContext *input_codec_context,
141                             AVFormatContext **output_format_context,
142                             AVCodecContext **output_codec_context)
143 {
144     AVCodecContext *avctx          = NULL;
145     AVIOContext *output_io_context = NULL;
146     AVStream *stream               = NULL;
147     AVCodec *output_codec          = NULL;
148     int error;
149
150     /* Open the output file to write to it. */
151     if ((error = avio_open(&output_io_context, filename,
152                            AVIO_FLAG_WRITE)) < 0) {
153         fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
154                 filename, av_err2str(error));
155         return error;
156     }
157
158     /* Create a new format context for the output container format. */
159     if (!(*output_format_context = avformat_alloc_context())) {
160         fprintf(stderr, "Could not allocate output format context\n");
161         return AVERROR(ENOMEM);
162     }
163
164     /* Associate the output file (pointer) with the container format context. */
165     (*output_format_context)->pb = output_io_context;
166
167     /* Guess the desired container format based on the file extension. */
168     if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
169                                                               NULL))) {
170         fprintf(stderr, "Could not find output file format\n");
171         goto cleanup;
172     }
173
174     av_strlcpy((*output_format_context)->filename, filename,
175                sizeof((*output_format_context)->filename));
176
177     /* Find the encoder to be used by its name. */
178     if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
179         fprintf(stderr, "Could not find an AAC encoder.\n");
180         goto cleanup;
181     }
182
183     /* Create a new audio stream in the output file container. */
184     if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
185         fprintf(stderr, "Could not create new stream\n");
186         error = AVERROR(ENOMEM);
187         goto cleanup;
188     }
189
190     avctx = avcodec_alloc_context3(output_codec);
191     if (!avctx) {
192         fprintf(stderr, "Could not allocate an encoding context\n");
193         error = AVERROR(ENOMEM);
194         goto cleanup;
195     }
196
197     /* Set the basic encoder parameters.
198      * The input file's sample rate is used to avoid a sample rate conversion. */
199     avctx->channels       = OUTPUT_CHANNELS;
200     avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
201     avctx->sample_rate    = input_codec_context->sample_rate;
202     avctx->sample_fmt     = output_codec->sample_fmts[0];
203     avctx->bit_rate       = OUTPUT_BIT_RATE;
204
205     /* Allow the use of the experimental AAC encoder. */
206     avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
207
208     /* Set the sample rate for the container. */
209     stream->time_base.den = input_codec_context->sample_rate;
210     stream->time_base.num = 1;
211
212     /* Some container formats (like MP4) require global headers to be present.
213      * Mark the encoder so that it behaves accordingly. */
214     if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
215         avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
216
217     /* Open the encoder for the audio stream to use it later. */
218     if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
219         fprintf(stderr, "Could not open output codec (error '%s')\n",
220                 av_err2str(error));
221         goto cleanup;
222     }
223
224     error = avcodec_parameters_from_context(stream->codecpar, avctx);
225     if (error < 0) {
226         fprintf(stderr, "Could not initialize stream parameters\n");
227         goto cleanup;
228     }
229
230     /* Save the encoder context for easier access later. */
231     *output_codec_context = avctx;
232
233     return 0;
234
235 cleanup:
236     avcodec_free_context(&avctx);
237     avio_closep(&(*output_format_context)->pb);
238     avformat_free_context(*output_format_context);
239     *output_format_context = NULL;
240     return error < 0 ? error : AVERROR_EXIT;
241 }
242
243 /**
244  * Initialize one data packet for reading or writing.
245  * @param packet Packet to be initialized
246  */
247 static void init_packet(AVPacket *packet)
248 {
249     av_init_packet(packet);
250     /* Set the packet data and size so that it is recognized as being empty. */
251     packet->data = NULL;
252     packet->size = 0;
253 }
254
255 /**
256  * Initialize one audio frame for reading from the input file.
257  * @param[out] frame Frame to be initialized
258  * @return Error code (0 if successful)
259  */
260 static int init_input_frame(AVFrame **frame)
261 {
262     if (!(*frame = av_frame_alloc())) {
263         fprintf(stderr, "Could not allocate input frame\n");
264         return AVERROR(ENOMEM);
265     }
266     return 0;
267 }
268
269 /**
270  * Initialize the audio resampler based on the input and output codec settings.
271  * If the input and output sample formats differ, a conversion is required
272  * libswresample takes care of this, but requires initialization.
273  * @param      input_codec_context  Codec context of the input file
274  * @param      output_codec_context Codec context of the output file
275  * @param[out] resample_context     Resample context for the required conversion
276  * @return Error code (0 if successful)
277  */
278 static int init_resampler(AVCodecContext *input_codec_context,
279                           AVCodecContext *output_codec_context,
280                           SwrContext **resample_context)
281 {
282         int error;
283
284         /*
285          * Create a resampler context for the conversion.
286          * Set the conversion parameters.
287          * Default channel layouts based on the number of channels
288          * are assumed for simplicity (they are sometimes not detected
289          * properly by the demuxer and/or decoder).
290          */
291         *resample_context = swr_alloc_set_opts(NULL,
292                                               av_get_default_channel_layout(output_codec_context->channels),
293                                               output_codec_context->sample_fmt,
294                                               output_codec_context->sample_rate,
295                                               av_get_default_channel_layout(input_codec_context->channels),
296                                               input_codec_context->sample_fmt,
297                                               input_codec_context->sample_rate,
298                                               0, NULL);
299         if (!*resample_context) {
300             fprintf(stderr, "Could not allocate resample context\n");
301             return AVERROR(ENOMEM);
302         }
303         /*
304         * Perform a sanity check so that the number of converted samples is
305         * not greater than the number of samples to be converted.
306         * If the sample rates differ, this case has to be handled differently
307         */
308         av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
309
310         /* Open the resampler with the specified parameters. */
311         if ((error = swr_init(*resample_context)) < 0) {
312             fprintf(stderr, "Could not open resample context\n");
313             swr_free(resample_context);
314             return error;
315         }
316     return 0;
317 }
318
319 /**
320  * Initialize a FIFO buffer for the audio samples to be encoded.
321  * @param[out] fifo                 Sample buffer
322  * @param      output_codec_context Codec context of the output file
323  * @return Error code (0 if successful)
324  */
325 static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
326 {
327     /* Create the FIFO buffer based on the specified output sample format. */
328     if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
329                                       output_codec_context->channels, 1))) {
330         fprintf(stderr, "Could not allocate FIFO\n");
331         return AVERROR(ENOMEM);
332     }
333     return 0;
334 }
335
336 /**
337  * Write the header of the output file container.
338  * @param output_format_context Format context of the output file
339  * @return Error code (0 if successful)
340  */
341 static int write_output_file_header(AVFormatContext *output_format_context)
342 {
343     int error;
344     if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
345         fprintf(stderr, "Could not write output file header (error '%s')\n",
346                 av_err2str(error));
347         return error;
348     }
349     return 0;
350 }
351
352 /**
353  * Decode one audio frame from the input file.
354  * @param      frame                Audio frame to be decoded
355  * @param      input_format_context Format context of the input file
356  * @param      input_codec_context  Codec context of the input file
357  * @param[out] data_present         Indicates whether data has been decoded
358  * @param[out] finished             Indicates whether the end of file has
359  *                                  been reached and all data has been
360  *                                  decoded. If this flag is false, there
361  *                                  is more data to be decoded, i.e., this
362  *                                  function has to be called again.
363  * @return Error code (0 if successful)
364  */
365 static int decode_audio_frame(AVFrame *frame,
366                               AVFormatContext *input_format_context,
367                               AVCodecContext *input_codec_context,
368                               int *data_present, int *finished)
369 {
370     /* Packet used for temporary storage. */
371     AVPacket input_packet;
372     int error;
373     init_packet(&input_packet);
374
375     /* Read one audio frame from the input file into a temporary packet. */
376     if ((error = av_read_frame(input_format_context, &input_packet)) < 0) {
377         /* If we are at the end of the file, flush the decoder below. */
378         if (error == AVERROR_EOF)
379             *finished = 1;
380         else {
381             fprintf(stderr, "Could not read frame (error '%s')\n",
382                     av_err2str(error));
383             return error;
384         }
385     }
386
387     /* Decode the audio frame stored in the temporary packet.
388      * The input audio stream decoder is used to do this.
389      * If we are at the end of the file, pass an empty packet to the decoder
390      * to flush it. */
391     if ((error = avcodec_decode_audio4(input_codec_context, frame,
392                                        data_present, &input_packet)) < 0) {
393         fprintf(stderr, "Could not decode frame (error '%s')\n",
394                 av_err2str(error));
395         av_packet_unref(&input_packet);
396         return error;
397     }
398
399     /* If the decoder has not been flushed completely, we are not finished,
400      * so that this function has to be called again. */
401     if (*finished && *data_present)
402         *finished = 0;
403     av_packet_unref(&input_packet);
404     return 0;
405 }
406
407 /**
408  * Initialize a temporary storage for the specified number of audio samples.
409  * The conversion requires temporary storage due to the different format.
410  * The number of audio samples to be allocated is specified in frame_size.
411  * @param[out] converted_input_samples Array of converted samples. The
412  *                                     dimensions are reference, channel
413  *                                     (for multi-channel audio), sample.
414  * @param      output_codec_context    Codec context of the output file
415  * @param      frame_size              Number of samples to be converted in
416  *                                     each round
417  * @return Error code (0 if successful)
418  */
419 static int init_converted_samples(uint8_t ***converted_input_samples,
420                                   AVCodecContext *output_codec_context,
421                                   int frame_size)
422 {
423     int error;
424
425     /* Allocate as many pointers as there are audio channels.
426      * Each pointer will later point to the audio samples of the corresponding
427      * channels (although it may be NULL for interleaved formats).
428      */
429     if (!(*converted_input_samples = calloc(output_codec_context->channels,
430                                             sizeof(**converted_input_samples)))) {
431         fprintf(stderr, "Could not allocate converted input sample pointers\n");
432         return AVERROR(ENOMEM);
433     }
434
435     /* Allocate memory for the samples of all channels in one consecutive
436      * block for convenience. */
437     if ((error = av_samples_alloc(*converted_input_samples, NULL,
438                                   output_codec_context->channels,
439                                   frame_size,
440                                   output_codec_context->sample_fmt, 0)) < 0) {
441         fprintf(stderr,
442                 "Could not allocate converted input samples (error '%s')\n",
443                 av_err2str(error));
444         av_freep(&(*converted_input_samples)[0]);
445         free(*converted_input_samples);
446         return error;
447     }
448     return 0;
449 }
450
451 /**
452  * Convert the input audio samples into the output sample format.
453  * The conversion happens on a per-frame basis, the size of which is
454  * specified by frame_size.
455  * @param      input_data       Samples to be decoded. The dimensions are
456  *                              channel (for multi-channel audio), sample.
457  * @param[out] converted_data   Converted samples. The dimensions are channel
458  *                              (for multi-channel audio), sample.
459  * @param      frame_size       Number of samples to be converted
460  * @param      resample_context Resample context for the conversion
461  * @return Error code (0 if successful)
462  */
463 static int convert_samples(const uint8_t **input_data,
464                            uint8_t **converted_data, const int frame_size,
465                            SwrContext *resample_context)
466 {
467     int error;
468
469     /* Convert the samples using the resampler. */
470     if ((error = swr_convert(resample_context,
471                              converted_data, frame_size,
472                              input_data    , frame_size)) < 0) {
473         fprintf(stderr, "Could not convert input samples (error '%s')\n",
474                 av_err2str(error));
475         return error;
476     }
477
478     return 0;
479 }
480
481 /**
482  * Add converted input audio samples to the FIFO buffer for later processing.
483  * @param fifo                    Buffer to add the samples to
484  * @param converted_input_samples Samples to be added. The dimensions are channel
485  *                                (for multi-channel audio), sample.
486  * @param frame_size              Number of samples to be converted
487  * @return Error code (0 if successful)
488  */
489 static int add_samples_to_fifo(AVAudioFifo *fifo,
490                                uint8_t **converted_input_samples,
491                                const int frame_size)
492 {
493     int error;
494
495     /* Make the FIFO as large as it needs to be to hold both,
496      * the old and the new samples. */
497     if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
498         fprintf(stderr, "Could not reallocate FIFO\n");
499         return error;
500     }
501
502     /* Store the new samples in the FIFO buffer. */
503     if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
504                             frame_size) < frame_size) {
505         fprintf(stderr, "Could not write data to FIFO\n");
506         return AVERROR_EXIT;
507     }
508     return 0;
509 }
510
511 /**
512  * Read one audio frame from the input file, decode, convert and store
513  * it in the FIFO buffer.
514  * @param      fifo                 Buffer used for temporary storage
515  * @param      input_format_context Format context of the input file
516  * @param      input_codec_context  Codec context of the input file
517  * @param      output_codec_context Codec context of the output file
518  * @param      resampler_context    Resample context for the conversion
519  * @param[out] finished             Indicates whether the end of file has
520  *                                  been reached and all data has been
521  *                                  decoded. If this flag is false,
522  *                                  there is more data to be decoded,
523  *                                  i.e., this function has to be called
524  *                                  again.
525  * @return Error code (0 if successful)
526  */
527 static int read_decode_convert_and_store(AVAudioFifo *fifo,
528                                          AVFormatContext *input_format_context,
529                                          AVCodecContext *input_codec_context,
530                                          AVCodecContext *output_codec_context,
531                                          SwrContext *resampler_context,
532                                          int *finished)
533 {
534     /* Temporary storage of the input samples of the frame read from the file. */
535     AVFrame *input_frame = NULL;
536     /* Temporary storage for the converted input samples. */
537     uint8_t **converted_input_samples = NULL;
538     int data_present;
539     int ret = AVERROR_EXIT;
540
541     /* Initialize temporary storage for one input frame. */
542     if (init_input_frame(&input_frame))
543         goto cleanup;
544     /* Decode one frame worth of audio samples. */
545     if (decode_audio_frame(input_frame, input_format_context,
546                            input_codec_context, &data_present, finished))
547         goto cleanup;
548     /* If we are at the end of the file and there are no more samples
549      * in the decoder which are delayed, we are actually finished.
550      * This must not be treated as an error. */
551     if (*finished && !data_present) {
552         ret = 0;
553         goto cleanup;
554     }
555     /* If there is decoded data, convert and store it. */
556     if (data_present) {
557         /* Initialize the temporary storage for the converted input samples. */
558         if (init_converted_samples(&converted_input_samples, output_codec_context,
559                                    input_frame->nb_samples))
560             goto cleanup;
561
562         /* Convert the input samples to the desired output sample format.
563          * This requires a temporary storage provided by converted_input_samples. */
564         if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
565                             input_frame->nb_samples, resampler_context))
566             goto cleanup;
567
568         /* Add the converted input samples to the FIFO buffer for later processing. */
569         if (add_samples_to_fifo(fifo, converted_input_samples,
570                                 input_frame->nb_samples))
571             goto cleanup;
572         ret = 0;
573     }
574     ret = 0;
575
576 cleanup:
577     if (converted_input_samples) {
578         av_freep(&converted_input_samples[0]);
579         free(converted_input_samples);
580     }
581     av_frame_free(&input_frame);
582
583     return ret;
584 }
585
586 /**
587  * Initialize one input frame for writing to the output file.
588  * The frame will be exactly frame_size samples large.
589  * @param[out] frame                Frame to be initialized
590  * @param      output_codec_context Codec context of the output file
591  * @param      frame_size           Size of the frame
592  * @return Error code (0 if successful)
593  */
594 static int init_output_frame(AVFrame **frame,
595                              AVCodecContext *output_codec_context,
596                              int frame_size)
597 {
598     int error;
599
600     /* Create a new frame to store the audio samples. */
601     if (!(*frame = av_frame_alloc())) {
602         fprintf(stderr, "Could not allocate output frame\n");
603         return AVERROR_EXIT;
604     }
605
606     /* Set the frame's parameters, especially its size and format.
607      * av_frame_get_buffer needs this to allocate memory for the
608      * audio samples of the frame.
609      * Default channel layouts based on the number of channels
610      * are assumed for simplicity. */
611     (*frame)->nb_samples     = frame_size;
612     (*frame)->channel_layout = output_codec_context->channel_layout;
613     (*frame)->format         = output_codec_context->sample_fmt;
614     (*frame)->sample_rate    = output_codec_context->sample_rate;
615
616     /* Allocate the samples of the created frame. This call will make
617      * sure that the audio frame can hold as many samples as specified. */
618     if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
619         fprintf(stderr, "Could not allocate output frame samples (error '%s')\n",
620                 av_err2str(error));
621         av_frame_free(frame);
622         return error;
623     }
624
625     return 0;
626 }
627
628 /* Global timestamp for the audio frames. */
629 static int64_t pts = 0;
630
631 /**
632  * Encode one frame worth of audio to the output file.
633  * @param      frame                 Samples to be encoded
634  * @param      output_format_context Format context of the output file
635  * @param      output_codec_context  Codec context of the output file
636  * @param[out] data_present          Indicates whether data has been
637  *                                   decoded
638  * @return Error code (0 if successful)
639  */
640 static int encode_audio_frame(AVFrame *frame,
641                               AVFormatContext *output_format_context,
642                               AVCodecContext *output_codec_context,
643                               int *data_present)
644 {
645     /* Packet used for temporary storage. */
646     AVPacket output_packet;
647     int error;
648     init_packet(&output_packet);
649
650     /* Set a timestamp based on the sample rate for the container. */
651     if (frame) {
652         frame->pts = pts;
653         pts += frame->nb_samples;
654     }
655
656     /* Encode the audio frame and store it in the temporary packet.
657      * The output audio stream encoder is used to do this. */
658     if ((error = avcodec_encode_audio2(output_codec_context, &output_packet,
659                                        frame, data_present)) < 0) {
660         fprintf(stderr, "Could not encode frame (error '%s')\n",
661                 av_err2str(error));
662         av_packet_unref(&output_packet);
663         return error;
664     }
665
666     /* Write one audio frame from the temporary packet to the output file. */
667     if (*data_present) {
668         if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
669             fprintf(stderr, "Could not write frame (error '%s')\n",
670                     av_err2str(error));
671             av_packet_unref(&output_packet);
672             return error;
673         }
674
675         av_packet_unref(&output_packet);
676     }
677
678     return 0;
679 }
680
681 /**
682  * Load one audio frame from the FIFO buffer, encode and write it to the
683  * output file.
684  * @param fifo                  Buffer used for temporary storage
685  * @param output_format_context Format context of the output file
686  * @param output_codec_context  Codec context of the output file
687  * @return Error code (0 if successful)
688  */
689 static int load_encode_and_write(AVAudioFifo *fifo,
690                                  AVFormatContext *output_format_context,
691                                  AVCodecContext *output_codec_context)
692 {
693     /* Temporary storage of the output samples of the frame written to the file. */
694     AVFrame *output_frame;
695     /* Use the maximum number of possible samples per frame.
696      * If there is less than the maximum possible frame size in the FIFO
697      * buffer use this number. Otherwise, use the maximum possible frame size. */
698     const int frame_size = FFMIN(av_audio_fifo_size(fifo),
699                                  output_codec_context->frame_size);
700     int data_written;
701
702     /* Initialize temporary storage for one output frame. */
703     if (init_output_frame(&output_frame, output_codec_context, frame_size))
704         return AVERROR_EXIT;
705
706     /* Read as many samples from the FIFO buffer as required to fill the frame.
707      * The samples are stored in the frame temporarily. */
708     if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
709         fprintf(stderr, "Could not read data from FIFO\n");
710         av_frame_free(&output_frame);
711         return AVERROR_EXIT;
712     }
713
714     /* Encode one frame worth of audio samples. */
715     if (encode_audio_frame(output_frame, output_format_context,
716                            output_codec_context, &data_written)) {
717         av_frame_free(&output_frame);
718         return AVERROR_EXIT;
719     }
720     av_frame_free(&output_frame);
721     return 0;
722 }
723
724 /**
725  * Write the trailer of the output file container.
726  * @param output_format_context Format context of the output file
727  * @return Error code (0 if successful)
728  */
729 static int write_output_file_trailer(AVFormatContext *output_format_context)
730 {
731     int error;
732     if ((error = av_write_trailer(output_format_context)) < 0) {
733         fprintf(stderr, "Could not write output file trailer (error '%s')\n",
734                 av_err2str(error));
735         return error;
736     }
737     return 0;
738 }
739
740 int main(int argc, char **argv)
741 {
742     AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
743     AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
744     SwrContext *resample_context = NULL;
745     AVAudioFifo *fifo = NULL;
746     int ret = AVERROR_EXIT;
747
748     if (argc != 3) {
749         fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
750         exit(1);
751     }
752
753     /* Register all codecs and formats so that they can be used. */
754     av_register_all();
755     /* Open the input file for reading. */
756     if (open_input_file(argv[1], &input_format_context,
757                         &input_codec_context))
758         goto cleanup;
759     /* Open the output file for writing. */
760     if (open_output_file(argv[2], input_codec_context,
761                          &output_format_context, &output_codec_context))
762         goto cleanup;
763     /* Initialize the resampler to be able to convert audio sample formats. */
764     if (init_resampler(input_codec_context, output_codec_context,
765                        &resample_context))
766         goto cleanup;
767     /* Initialize the FIFO buffer to store audio samples to be encoded. */
768     if (init_fifo(&fifo, output_codec_context))
769         goto cleanup;
770     /* Write the header of the output file container. */
771     if (write_output_file_header(output_format_context))
772         goto cleanup;
773
774     /* Loop as long as we have input samples to read or output samples
775      * to write; abort as soon as we have neither. */
776     while (1) {
777         /* Use the encoder's desired frame size for processing. */
778         const int output_frame_size = output_codec_context->frame_size;
779         int finished                = 0;
780
781         /* Make sure that there is one frame worth of samples in the FIFO
782          * buffer so that the encoder can do its work.
783          * Since the decoder's and the encoder's frame size may differ, we
784          * need to FIFO buffer to store as many frames worth of input samples
785          * that they make up at least one frame worth of output samples. */
786         while (av_audio_fifo_size(fifo) < output_frame_size) {
787             /* Decode one frame worth of audio samples, convert it to the
788              * output sample format and put it into the FIFO buffer. */
789             if (read_decode_convert_and_store(fifo, input_format_context,
790                                               input_codec_context,
791                                               output_codec_context,
792                                               resample_context, &finished))
793                 goto cleanup;
794
795             /* If we are at the end of the input file, we continue
796              * encoding the remaining audio samples to the output file. */
797             if (finished)
798                 break;
799         }
800
801         /* If we have enough samples for the encoder, we encode them.
802          * At the end of the file, we pass the remaining samples to
803          * the encoder. */
804         while (av_audio_fifo_size(fifo) >= output_frame_size ||
805                (finished && av_audio_fifo_size(fifo) > 0))
806             /* Take one frame worth of audio samples from the FIFO buffer,
807              * encode it and write it to the output file. */
808             if (load_encode_and_write(fifo, output_format_context,
809                                       output_codec_context))
810                 goto cleanup;
811
812         /* If we are at the end of the input file and have encoded
813          * all remaining samples, we can exit this loop and finish. */
814         if (finished) {
815             int data_written;
816             /* Flush the encoder as it may have delayed frames. */
817             do {
818                 if (encode_audio_frame(NULL, output_format_context,
819                                        output_codec_context, &data_written))
820                     goto cleanup;
821             } while (data_written);
822             break;
823         }
824     }
825
826     /* Write the trailer of the output file container. */
827     if (write_output_file_trailer(output_format_context))
828         goto cleanup;
829     ret = 0;
830
831 cleanup:
832     if (fifo)
833         av_audio_fifo_free(fifo);
834     swr_free(&resample_context);
835     if (output_codec_context)
836         avcodec_free_context(&output_codec_context);
837     if (output_format_context) {
838         avio_closep(&output_format_context->pb);
839         avformat_free_context(output_format_context);
840     }
841     if (input_codec_context)
842         avcodec_free_context(&input_codec_context);
843     if (input_format_context)
844         avformat_close_input(&input_format_context);
845
846     return ret;
847 }