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