FFmpeg
transcode_aac.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2022 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 audio transcoding to MPEG/AAC API usage example
23  * @example transcode_aac.c
24  *
25  * Convert an input audio file to AAC in an MP4 container. Formats other than
26  * MP4 are supported based on the output file extension.
27  * @author Andreas Unterweger (dustsigns@gmail.com)
28  */
29 
30 #include <stdio.h>
31 
32 #include <libavutil/mem.h>
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>
42 #include <libavutil/frame.h>
43 #include <libavutil/opt.h>
44 
46 
47 /* The output bit rate in bit/s */
48 #define OUTPUT_BIT_RATE 96000
49 /* The number of output channels */
50 #define OUTPUT_CHANNELS 2
51 
52 /**
53  * Open an input file and the required decoder.
54  * @param filename File to be opened
55  * @param[out] input_format_context Format context of opened file
56  * @param[out] input_codec_context Codec context of opened file
57  * @return Error code (0 if successful)
58  */
59 static int open_input_file(const char *filename,
60  AVFormatContext **input_format_context,
61  AVCodecContext **input_codec_context)
62 {
63  AVCodecContext *avctx;
64  const AVCodec *input_codec;
65  const AVStream *stream;
66  int error;
67 
68  /* Open the input file to read from it. */
69  if ((error = avformat_open_input(input_format_context, filename, NULL,
70  NULL)) < 0) {
71  fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
72  filename, av_err2str(error));
73  *input_format_context = NULL;
74  return error;
75  }
76 
77  /* Get information on the input file (number of streams etc.). */
78  if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
79  fprintf(stderr, "Could not open find stream info (error '%s')\n",
80  av_err2str(error));
81  avformat_close_input(input_format_context);
82  return error;
83  }
84 
85  /* Make sure that there is only one stream in the input file. */
86  if ((*input_format_context)->nb_streams != 1) {
87  fprintf(stderr, "Expected one audio input stream, but found %d\n",
88  (*input_format_context)->nb_streams);
89  avformat_close_input(input_format_context);
90  return AVERROR_EXIT;
91  }
92 
93  stream = (*input_format_context)->streams[0];
94 
95  /* Find a decoder for the audio stream. */
96  if (!(input_codec = avcodec_find_decoder(stream->codecpar->codec_id))) {
97  fprintf(stderr, "Could not find input codec\n");
98  avformat_close_input(input_format_context);
99  return AVERROR_EXIT;
100  }
101 
102  /* Allocate a new decoding context. */
103  avctx = avcodec_alloc_context3(input_codec);
104  if (!avctx) {
105  fprintf(stderr, "Could not allocate a decoding context\n");
106  avformat_close_input(input_format_context);
107  return AVERROR(ENOMEM);
108  }
109 
110  /* Initialize the stream parameters with demuxer information. */
111  error = avcodec_parameters_to_context(avctx, stream->codecpar);
112  if (error < 0) {
113  avformat_close_input(input_format_context);
114  avcodec_free_context(&avctx);
115  return error;
116  }
117 
118  /* Open the decoder for the audio stream to use it later. */
119  if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) {
120  fprintf(stderr, "Could not open input codec (error '%s')\n",
121  av_err2str(error));
122  avcodec_free_context(&avctx);
123  avformat_close_input(input_format_context);
124  return error;
125  }
126 
127  /* Set the packet timebase for the decoder. */
128  avctx->pkt_timebase = stream->time_base;
129 
130  /* Save the decoder context for easier access later. */
131  *input_codec_context = avctx;
132 
133  return 0;
134 }
135 
136 /**
137  * Open an output file and the required encoder.
138  * Also set some basic encoder parameters.
139  * Some of these parameters are based on the input file's parameters.
140  * @param filename File to be opened
141  * @param input_codec_context Codec context of input file
142  * @param[out] output_format_context Format context of output file
143  * @param[out] output_codec_context Codec context of output file
144  * @return Error code (0 if successful)
145  */
146 static int open_output_file(const char *filename,
147  AVCodecContext *input_codec_context,
148  AVFormatContext **output_format_context,
149  AVCodecContext **output_codec_context)
150 {
151  AVCodecContext *avctx = NULL;
152  AVIOContext *output_io_context = NULL;
153  AVStream *stream = NULL;
154  const AVCodec *output_codec = NULL;
155  const void *sample_fmts;
156  int error;
157 
158  /* Open the output file to write to it. */
159  if ((error = avio_open(&output_io_context, filename,
160  AVIO_FLAG_WRITE)) < 0) {
161  fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
162  filename, av_err2str(error));
163  return error;
164  }
165 
166  /* Create a new format context for the output container format. */
167  if (!(*output_format_context = avformat_alloc_context())) {
168  fprintf(stderr, "Could not allocate output format context\n");
169  return AVERROR(ENOMEM);
170  }
171 
172  /* Associate the output file (pointer) with the container format context. */
173  (*output_format_context)->pb = output_io_context;
174 
175  /* Guess the desired container format based on the file extension. */
176  if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
177  NULL))) {
178  fprintf(stderr, "Could not find output file format\n");
179  goto cleanup;
180  }
181 
182  if (!((*output_format_context)->url = av_strdup(filename))) {
183  fprintf(stderr, "Could not allocate url.\n");
184  error = AVERROR(ENOMEM);
185  goto cleanup;
186  }
187 
188  /* Find the encoder to be used by its name. */
189  if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
190  fprintf(stderr, "Could not find an AAC encoder.\n");
191  goto cleanup;
192  }
193 
194  /* Create a new audio stream in the output file container. */
195  if (!(stream = avformat_new_stream(*output_format_context, NULL))) {
196  fprintf(stderr, "Could not create new stream\n");
197  error = AVERROR(ENOMEM);
198  goto cleanup;
199  }
200 
201  avctx = avcodec_alloc_context3(output_codec);
202  if (!avctx) {
203  fprintf(stderr, "Could not allocate an encoding context\n");
204  error = AVERROR(ENOMEM);
205  goto cleanup;
206  }
207 
208  /* Set the basic encoder parameters.
209  * The input file's sample rate is used to avoid a sample rate conversion. */
212  0, &sample_fmts, NULL);
213  av_assert0(error >= 0);
214  avctx->sample_fmt = sample_fmts ? *(const enum AVSampleFormat*)sample_fmts
215  : input_codec_context->sample_fmt;
216  avctx->sample_rate = input_codec_context->sample_rate;
217  avctx->bit_rate = OUTPUT_BIT_RATE;
218 
219  /* Set the sample rate for the container. */
220  stream->time_base.den = input_codec_context->sample_rate;
221  stream->time_base.num = 1;
222 
223  /* Some container formats (like MP4) require global headers to be present.
224  * Mark the encoder so that it behaves accordingly. */
225  if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
227 
228  /* Open the encoder for the audio stream to use it later. */
229  if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) {
230  fprintf(stderr, "Could not open output codec (error '%s')\n",
231  av_err2str(error));
232  goto cleanup;
233  }
234 
236  if (error < 0) {
237  fprintf(stderr, "Could not initialize stream parameters\n");
238  goto cleanup;
239  }
240 
241  /* Save the encoder context for easier access later. */
242  *output_codec_context = avctx;
243 
244  return 0;
245 
246 cleanup:
247  avcodec_free_context(&avctx);
248  avio_closep(&(*output_format_context)->pb);
249  avformat_free_context(*output_format_context);
250  *output_format_context = NULL;
251  return error < 0 ? error : AVERROR_EXIT;
252 }
253 
254 /**
255  * Initialize one data packet for reading or writing.
256  * @param[out] packet Packet to be initialized
257  * @return Error code (0 if successful)
258  */
259 static int init_packet(AVPacket **packet)
260 {
261  if (!(*packet = av_packet_alloc())) {
262  fprintf(stderr, "Could not allocate packet\n");
263  return AVERROR(ENOMEM);
264  }
265  return 0;
266 }
267 
268 /**
269  * Initialize one audio frame for reading from the input file.
270  * @param[out] frame Frame to be initialized
271  * @return Error code (0 if successful)
272  */
274 {
275  if (!(*frame = av_frame_alloc())) {
276  fprintf(stderr, "Could not allocate input frame\n");
277  return AVERROR(ENOMEM);
278  }
279  return 0;
280 }
281 
282 /**
283  * Initialize the audio resampler based on the input and output codec settings.
284  * If the input and output sample formats differ, a conversion is required
285  * libswresample takes care of this, but requires initialization.
286  * @param input_codec_context Codec context of the input file
287  * @param output_codec_context Codec context of the output file
288  * @param[out] resample_context Resample context for the required conversion
289  * @return Error code (0 if successful)
290  */
291 static int init_resampler(AVCodecContext *input_codec_context,
292  AVCodecContext *output_codec_context,
293  SwrContext **resample_context)
294 {
295  int error;
296 
297  /*
298  * Create a resampler context for the conversion.
299  * Set the conversion parameters.
300  */
301  error = swr_alloc_set_opts2(resample_context,
302  &output_codec_context->ch_layout,
303  output_codec_context->sample_fmt,
304  output_codec_context->sample_rate,
305  &input_codec_context->ch_layout,
306  input_codec_context->sample_fmt,
307  input_codec_context->sample_rate,
308  0, NULL);
309  if (error < 0) {
310  fprintf(stderr, "Could not allocate resample context\n");
311  return error;
312  }
313  /*
314  * Perform a sanity check so that the number of converted samples is
315  * not greater than the number of samples to be converted.
316  * If the sample rates differ, this case has to be handled differently
317  */
318  av_assert0(output_codec_context->sample_rate == input_codec_context->sample_rate);
319 
320  /* Open the resampler with the specified parameters. */
321  if ((error = swr_init(*resample_context)) < 0) {
322  fprintf(stderr, "Could not open resample context\n");
323  swr_free(resample_context);
324  return error;
325  }
326  return 0;
327 }
328 
329 /**
330  * Initialize a FIFO buffer for the audio samples to be encoded.
331  * @param[out] fifo Sample buffer
332  * @param output_codec_context Codec context of the output file
333  * @return Error code (0 if successful)
334  */
335 static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
336 {
337  /* Create the FIFO buffer based on the specified output sample format. */
338  if (!(*fifo = av_audio_fifo_alloc(output_codec_context->sample_fmt,
339  output_codec_context->ch_layout.nb_channels, 1))) {
340  fprintf(stderr, "Could not allocate FIFO\n");
341  return AVERROR(ENOMEM);
342  }
343  return 0;
344 }
345 
346 /**
347  * Write the header of the output file container.
348  * @param output_format_context Format context of the output file
349  * @return Error code (0 if successful)
350  */
351 static int write_output_file_header(AVFormatContext *output_format_context)
352 {
353  int error;
354  if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
355  fprintf(stderr, "Could not write output file header (error '%s')\n",
356  av_err2str(error));
357  return error;
358  }
359  return 0;
360 }
361 
362 /**
363  * Decode one audio frame from the input file.
364  * @param frame Audio frame to be decoded
365  * @param input_format_context Format context of the input file
366  * @param input_codec_context Codec context of the input file
367  * @param[out] data_present Indicates whether data has been decoded
368  * @param[out] finished Indicates whether the end of file has
369  * been reached and all data has been
370  * decoded. If this flag is false, there
371  * is more data to be decoded, i.e., this
372  * function has to be called again.
373  * @return Error code (0 if successful)
374  */
376  AVFormatContext *input_format_context,
377  AVCodecContext *input_codec_context,
378  int *data_present, int *finished)
379 {
380  /* Packet used for temporary storage. */
381  AVPacket *input_packet;
382  int error;
383 
384  error = init_packet(&input_packet);
385  if (error < 0)
386  return error;
387 
388  *data_present = 0;
389  *finished = 0;
390  /* Read one audio frame from the input file into a temporary packet. */
391  if ((error = av_read_frame(input_format_context, input_packet)) < 0) {
392  /* If we are at the end of the file, flush the decoder below. */
393  if (error == AVERROR_EOF)
394  *finished = 1;
395  else {
396  fprintf(stderr, "Could not read frame (error '%s')\n",
397  av_err2str(error));
398  goto cleanup;
399  }
400  }
401 
402  /* Send the audio frame stored in the temporary packet to the decoder.
403  * The input audio stream decoder is used to do this. */
404  if ((error = avcodec_send_packet(input_codec_context, input_packet)) < 0) {
405  fprintf(stderr, "Could not send packet for decoding (error '%s')\n",
406  av_err2str(error));
407  goto cleanup;
408  }
409 
410  /* Receive one frame from the decoder. */
411  error = avcodec_receive_frame(input_codec_context, frame);
412  /* If the decoder asks for more data to be able to decode a frame,
413  * return indicating that no data is present. */
414  if (error == AVERROR(EAGAIN)) {
415  error = 0;
416  goto cleanup;
417  /* If the end of the input file is reached, stop decoding. */
418  } else if (error == AVERROR_EOF) {
419  *finished = 1;
420  error = 0;
421  goto cleanup;
422  } else if (error < 0) {
423  fprintf(stderr, "Could not decode frame (error '%s')\n",
424  av_err2str(error));
425  goto cleanup;
426  /* Default case: Return decoded data. */
427  } else {
428  *data_present = 1;
429  goto cleanup;
430  }
431 
432 cleanup:
433  av_packet_free(&input_packet);
434  return error;
435 }
436 
437 /**
438  * Initialize a temporary storage for the specified number of audio samples.
439  * The conversion requires temporary storage due to the different format.
440  * The number of audio samples to be allocated is specified in frame_size.
441  * @param[out] converted_input_samples Array of converted samples. The
442  * dimensions are reference, channel
443  * (for multi-channel audio), sample.
444  * @param output_codec_context Codec context of the output file
445  * @param frame_size Number of samples to be converted in
446  * each round
447  * @return Error code (0 if successful)
448  */
449 static int init_converted_samples(uint8_t ***converted_input_samples,
450  AVCodecContext *output_codec_context,
451  int frame_size)
452 {
453  int error;
454 
455  /* Allocate as many pointers as there are audio channels.
456  * Each pointer will point to the audio samples of the corresponding
457  * channels (although it may be NULL for interleaved formats).
458  * Allocate memory for the samples of all channels in one consecutive
459  * block for convenience. */
460  if ((error = av_samples_alloc_array_and_samples(converted_input_samples, NULL,
461  output_codec_context->ch_layout.nb_channels,
462  frame_size,
463  output_codec_context->sample_fmt, 0)) < 0) {
464  fprintf(stderr,
465  "Could not allocate converted input samples (error '%s')\n",
466  av_err2str(error));
467  return error;
468  }
469  return 0;
470 }
471 
472 /**
473  * Convert the input audio samples into the output sample format.
474  * The conversion happens on a per-frame basis, the size of which is
475  * specified by frame_size.
476  * @param input_data Samples to be decoded. The dimensions are
477  * channel (for multi-channel audio), sample.
478  * @param[out] converted_data Converted samples. The dimensions are channel
479  * (for multi-channel audio), sample.
480  * @param frame_size Number of samples to be converted
481  * @param resample_context Resample context for the conversion
482  * @return Error code (0 if successful)
483  */
484 static int convert_samples(const uint8_t **input_data,
485  uint8_t **converted_data, const int frame_size,
486  SwrContext *resample_context)
487 {
488  int error;
489 
490  /* Convert the samples using the resampler. */
491  if ((error = swr_convert(resample_context,
492  converted_data, frame_size,
493  input_data , frame_size)) < 0) {
494  fprintf(stderr, "Could not convert input samples (error '%s')\n",
495  av_err2str(error));
496  return error;
497  }
498 
499  return 0;
500 }
501 
502 /**
503  * Add converted input audio samples to the FIFO buffer for later processing.
504  * @param fifo Buffer to add the samples to
505  * @param converted_input_samples Samples to be added. The dimensions are channel
506  * (for multi-channel audio), sample.
507  * @param frame_size Number of samples to be converted
508  * @return Error code (0 if successful)
509  */
511  uint8_t **converted_input_samples,
512  const int frame_size)
513 {
514  int error;
515 
516  /* Make the FIFO as large as it needs to be to hold both,
517  * the old and the new samples. */
518  if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
519  fprintf(stderr, "Could not reallocate FIFO\n");
520  return error;
521  }
522 
523  /* Store the new samples in the FIFO buffer. */
524  if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
525  frame_size) < frame_size) {
526  fprintf(stderr, "Could not write data to FIFO\n");
527  return AVERROR_EXIT;
528  }
529  return 0;
530 }
531 
532 /**
533  * Read one audio frame from the input file, decode, convert and store
534  * it in the FIFO buffer.
535  * @param fifo Buffer used for temporary storage
536  * @param input_format_context Format context of the input file
537  * @param input_codec_context Codec context of the input file
538  * @param output_codec_context Codec context of the output file
539  * @param resampler_context Resample context for the conversion
540  * @param[out] finished Indicates whether the end of file has
541  * been reached and all data has been
542  * decoded. If this flag is false,
543  * there is more data to be decoded,
544  * i.e., this function has to be called
545  * again.
546  * @return Error code (0 if successful)
547  */
549  AVFormatContext *input_format_context,
550  AVCodecContext *input_codec_context,
551  AVCodecContext *output_codec_context,
552  SwrContext *resampler_context,
553  int *finished)
554 {
555  /* Temporary storage of the input samples of the frame read from the file. */
556  AVFrame *input_frame = NULL;
557  /* Temporary storage for the converted input samples. */
558  uint8_t **converted_input_samples = NULL;
559  int data_present;
560  int ret = AVERROR_EXIT;
561 
562  /* Initialize temporary storage for one input frame. */
563  if (init_input_frame(&input_frame))
564  goto cleanup;
565  /* Decode one frame worth of audio samples. */
566  if (decode_audio_frame(input_frame, input_format_context,
567  input_codec_context, &data_present, finished))
568  goto cleanup;
569  /* If we are at the end of the file and there are no more samples
570  * in the decoder which are delayed, we are actually finished.
571  * This must not be treated as an error. */
572  if (*finished) {
573  ret = 0;
574  goto cleanup;
575  }
576  /* If there is decoded data, convert and store it. */
577  if (data_present) {
578  /* Initialize the temporary storage for the converted input samples. */
579  if (init_converted_samples(&converted_input_samples, output_codec_context,
580  input_frame->nb_samples))
581  goto cleanup;
582 
583  /* Convert the input samples to the desired output sample format.
584  * This requires a temporary storage provided by converted_input_samples. */
585  if (convert_samples((const uint8_t**)input_frame->extended_data, converted_input_samples,
586  input_frame->nb_samples, resampler_context))
587  goto cleanup;
588 
589  /* Add the converted input samples to the FIFO buffer for later processing. */
590  if (add_samples_to_fifo(fifo, converted_input_samples,
591  input_frame->nb_samples))
592  goto cleanup;
593  ret = 0;
594  }
595  ret = 0;
596 
597 cleanup:
598  if (converted_input_samples)
599  av_freep(&converted_input_samples[0]);
600  av_freep(&converted_input_samples);
601  av_frame_free(&input_frame);
602 
603  return ret;
604 }
605 
606 /**
607  * Initialize one input frame for writing to the output file.
608  * The frame will be exactly frame_size samples large.
609  * @param[out] frame Frame to be initialized
610  * @param output_codec_context Codec context of the output file
611  * @param frame_size Size of the frame
612  * @return Error code (0 if successful)
613  */
615  AVCodecContext *output_codec_context,
616  int frame_size)
617 {
618  int error;
619 
620  /* Create a new frame to store the audio samples. */
621  if (!(*frame = av_frame_alloc())) {
622  fprintf(stderr, "Could not allocate output frame\n");
623  return AVERROR_EXIT;
624  }
625 
626  /* Set the frame's parameters, especially its size and format.
627  * av_frame_get_buffer needs this to allocate memory for the
628  * audio samples of the frame.
629  * Default channel layouts based on the number of channels
630  * are assumed for simplicity. */
631  (*frame)->nb_samples = frame_size;
632  av_channel_layout_copy(&(*frame)->ch_layout, &output_codec_context->ch_layout);
633  (*frame)->format = output_codec_context->sample_fmt;
634  (*frame)->sample_rate = output_codec_context->sample_rate;
635 
636  /* Allocate the samples of the created frame. This call will make
637  * sure that the audio frame can hold as many samples as specified. */
638  if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
639  fprintf(stderr, "Could not allocate output frame samples (error '%s')\n",
640  av_err2str(error));
642  return error;
643  }
644 
645  return 0;
646 }
647 
648 /* Global timestamp for the audio frames. */
649 static int64_t pts = 0;
650 
651 /**
652  * Encode one frame worth of audio to the output file.
653  * @param frame Samples to be encoded
654  * @param output_format_context Format context of the output file
655  * @param output_codec_context Codec context of the output file
656  * @param[out] data_present Indicates whether data has been
657  * encoded
658  * @return Error code (0 if successful)
659  */
661  AVFormatContext *output_format_context,
662  AVCodecContext *output_codec_context,
663  int *data_present)
664 {
665  /* Packet used for temporary storage. */
667  int error;
668 
670  if (error < 0)
671  return error;
672 
673  /* Set a timestamp based on the sample rate for the container. */
674  if (frame) {
675  frame->pts = pts;
676  pts += frame->nb_samples;
677  }
678 
679  *data_present = 0;
680  /* Send the audio frame stored in the temporary packet to the encoder.
681  * The output audio stream encoder is used to do this. */
682  error = avcodec_send_frame(output_codec_context, frame);
683  /* Check for errors, but proceed with fetching encoded samples if the
684  * encoder signals that it has nothing more to encode. */
685  if (error < 0 && error != AVERROR_EOF) {
686  fprintf(stderr, "Could not send packet for encoding (error '%s')\n",
687  av_err2str(error));
688  goto cleanup;
689  }
690 
691  /* Receive one encoded frame from the encoder. */
692  error = avcodec_receive_packet(output_codec_context, output_packet);
693  /* If the encoder asks for more data to be able to provide an
694  * encoded frame, return indicating that no data is present. */
695  if (error == AVERROR(EAGAIN)) {
696  error = 0;
697  goto cleanup;
698  /* If the last frame has been encoded, stop encoding. */
699  } else if (error == AVERROR_EOF) {
700  error = 0;
701  goto cleanup;
702  } else if (error < 0) {
703  fprintf(stderr, "Could not encode frame (error '%s')\n",
704  av_err2str(error));
705  goto cleanup;
706  /* Default case: Return encoded data. */
707  } else {
708  *data_present = 1;
709  }
710 
711  /* Write one audio frame from the temporary packet to the output file. */
712  if (*data_present &&
713  (error = av_write_frame(output_format_context, output_packet)) < 0) {
714  fprintf(stderr, "Could not write frame (error '%s')\n",
715  av_err2str(error));
716  goto cleanup;
717  }
718 
719 cleanup:
721  return error;
722 }
723 
724 /**
725  * Load one audio frame from the FIFO buffer, encode and write it to the
726  * output file.
727  * @param fifo Buffer used for temporary storage
728  * @param output_format_context Format context of the output file
729  * @param output_codec_context Codec context of the output file
730  * @return Error code (0 if successful)
731  */
733  AVFormatContext *output_format_context,
734  AVCodecContext *output_codec_context)
735 {
736  /* Temporary storage of the output samples of the frame written to the file. */
738  /* Use the maximum number of possible samples per frame.
739  * If there is less than the maximum possible frame size in the FIFO
740  * buffer use this number. Otherwise, use the maximum possible frame size. */
741  const int frame_size = FFMIN(av_audio_fifo_size(fifo),
742  output_codec_context->frame_size);
743  int data_written;
744 
745  /* Initialize temporary storage for one output frame. */
746  if (init_output_frame(&output_frame, output_codec_context, frame_size))
747  return AVERROR_EXIT;
748 
749  /* Read as many samples from the FIFO buffer as required to fill the frame.
750  * The samples are stored in the frame temporarily. */
751  if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
752  fprintf(stderr, "Could not read data from FIFO\n");
754  return AVERROR_EXIT;
755  }
756 
757  /* Encode one frame worth of audio samples. */
758  if (encode_audio_frame(output_frame, output_format_context,
759  output_codec_context, &data_written)) {
761  return AVERROR_EXIT;
762  }
764  return 0;
765 }
766 
767 /**
768  * Write the trailer of the output file container.
769  * @param output_format_context Format context of the output file
770  * @return Error code (0 if successful)
771  */
772 static int write_output_file_trailer(AVFormatContext *output_format_context)
773 {
774  int error;
775  if ((error = av_write_trailer(output_format_context)) < 0) {
776  fprintf(stderr, "Could not write output file trailer (error '%s')\n",
777  av_err2str(error));
778  return error;
779  }
780  return 0;
781 }
782 
783 int main(int argc, char **argv)
784 {
785  AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
786  AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
787  SwrContext *resample_context = NULL;
788  AVAudioFifo *fifo = NULL;
789  int ret = AVERROR_EXIT;
790 
791  if (argc != 3) {
792  fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
793  exit(1);
794  }
795 
796  /* Open the input file for reading. */
797  if (open_input_file(argv[1], &input_format_context,
798  &input_codec_context))
799  goto cleanup;
800  /* Open the output file for writing. */
801  if (open_output_file(argv[2], input_codec_context,
802  &output_format_context, &output_codec_context))
803  goto cleanup;
804  /* Initialize the resampler to be able to convert audio sample formats. */
805  if (init_resampler(input_codec_context, output_codec_context,
806  &resample_context))
807  goto cleanup;
808  /* Initialize the FIFO buffer to store audio samples to be encoded. */
809  if (init_fifo(&fifo, output_codec_context))
810  goto cleanup;
811  /* Write the header of the output file container. */
812  if (write_output_file_header(output_format_context))
813  goto cleanup;
814 
815  /* Loop as long as we have input samples to read or output samples
816  * to write; abort as soon as we have neither. */
817  while (1) {
818  /* Use the encoder's desired frame size for processing. */
819  const int output_frame_size = output_codec_context->frame_size;
820  int finished = 0;
821 
822  /* Make sure that there is one frame worth of samples in the FIFO
823  * buffer so that the encoder can do its work.
824  * Since the decoder's and the encoder's frame size may differ, we
825  * need to FIFO buffer to store as many frames worth of input samples
826  * that they make up at least one frame worth of output samples. */
827  while (av_audio_fifo_size(fifo) < output_frame_size) {
828  /* Decode one frame worth of audio samples, convert it to the
829  * output sample format and put it into the FIFO buffer. */
830  if (read_decode_convert_and_store(fifo, input_format_context,
831  input_codec_context,
832  output_codec_context,
833  resample_context, &finished))
834  goto cleanup;
835 
836  /* If we are at the end of the input file, we continue
837  * encoding the remaining audio samples to the output file. */
838  if (finished)
839  break;
840  }
841 
842  /* If we have enough samples for the encoder, we encode them.
843  * At the end of the file, we pass the remaining samples to
844  * the encoder. */
845  while (av_audio_fifo_size(fifo) >= output_frame_size ||
846  (finished && av_audio_fifo_size(fifo) > 0))
847  /* Take one frame worth of audio samples from the FIFO buffer,
848  * encode it and write it to the output file. */
849  if (load_encode_and_write(fifo, output_format_context,
850  output_codec_context))
851  goto cleanup;
852 
853  /* If we are at the end of the input file and have encoded
854  * all remaining samples, we can exit this loop and finish. */
855  if (finished) {
856  int data_written;
857  /* Flush the encoder as it may have delayed frames. */
858  do {
859  if (encode_audio_frame(NULL, output_format_context,
860  output_codec_context, &data_written))
861  goto cleanup;
862  } while (data_written);
863  break;
864  }
865  }
866 
867  /* Write the trailer of the output file container. */
868  if (write_output_file_trailer(output_format_context))
869  goto cleanup;
870  ret = 0;
871 
872 cleanup:
873  if (fifo)
874  av_audio_fifo_free(fifo);
875  swr_free(&resample_context);
876  if (output_codec_context)
877  avcodec_free_context(&output_codec_context);
878  if (output_format_context) {
879  avio_closep(&output_format_context->pb);
880  avformat_free_context(output_format_context);
881  }
882  if (input_codec_context)
883  avcodec_free_context(&input_codec_context);
884  if (input_format_context)
885  avformat_close_input(&input_format_context);
886 
887  return ret;
888 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
av_audio_fifo_free
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:48
AVCodecContext::frame_size
int frame_size
Number of samples per channel in an audio frame.
Definition: avcodec.h:1068
AVCodec
AVCodec.
Definition: codec.h:172
load_encode_and_write
static int load_encode_and_write(AVAudioFifo *fifo, AVFormatContext *output_format_context, AVCodecContext *output_codec_context)
Load one audio frame from the FIFO buffer, encode and write it to the output file.
Definition: transcode_aac.c:732
avcodec_receive_packet
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Read encoded data from the encoder.
Definition: encode.c:552
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
open_input_file
static int open_input_file(const char *filename, AVFormatContext **input_format_context, AVCodecContext **input_codec_context)
Open an input file and the required decoder.
Definition: transcode_aac.c:59
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:206
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1040
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:931
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
av_audio_fifo_write
int av_audio_fifo_write(AVAudioFifo *af, void *const *data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:119
av_audio_fifo_realloc
int av_audio_fifo_realloc(AVAudioFifo *af, int nb_samples)
Reallocate an AVAudioFifo.
Definition: audio_fifo.c:99
int64_t
long long int64_t
Definition: coverity.c:34
init_fifo
static int init_fifo(AVAudioFifo **fifo, AVCodecContext *output_codec_context)
Initialize a FIFO buffer for the audio samples to be encoded.
Definition: transcode_aac.c:335
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:64
avcodec_find_encoder
const AVCodec * avcodec_find_encoder(enum AVCodecID id)
Find a registered encoder with a matching codec ID.
Definition: allcodecs.c:1044
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:466
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
write_output_file_header
static int write_output_file_header(AVFormatContext *output_format_context)
Write the header of the output file container.
Definition: transcode_aac.c:351
open_output_file
static int open_output_file(const char *filename, AVCodecContext *input_codec_context, AVFormatContext **output_format_context, AVCodecContext **output_codec_context)
Open an output file and the required encoder.
Definition: transcode_aac.c:146
avio_open
int avio_open(AVIOContext **s, const char *filename, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: avio.c:503
av_read_frame
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: demux.c:1588
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: packet.c:74
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:318
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:377
AVAudioFifo
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:37
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1055
output_packet
static int output_packet(AVFormatContext *ctx, int flush)
Definition: mpegenc.c:1011
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
pts
static int64_t pts
Definition: transcode_aac.c:649
AVRational::num
int num
Numerator.
Definition: rational.h:59
swr_convert
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *const *out_arg, int out_count, const uint8_t *const *in_arg, int in_count)
Convert audio.
Definition: swresample.c:725
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:52
avassert.h
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:156
avformat_open_input
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
Definition: demux.c:231
avcodec_alloc_context3
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:149
AV_CODEC_CONFIG_SAMPLE_FORMAT
@ AV_CODEC_CONFIG_SAMPLE_FORMAT
AVSampleFormat, terminated by AV_SAMPLE_FMT_NONE.
Definition: avcodec.h:2563
add_samples_to_fifo
static int add_samples_to_fifo(AVAudioFifo *fifo, uint8_t **converted_input_samples, const int frame_size)
Add converted input audio samples to the FIFO buffer for later processing.
Definition: transcode_aac.c:510
frame_size
int frame_size
Definition: mxfenc.c:2489
decode_audio_frame
static int decode_audio_frame(AVFrame *frame, AVFormatContext *input_format_context, AVCodecContext *input_codec_context, int *data_present, int *finished)
Decode one audio frame from the input file.
Definition: transcode_aac.c:375
avcodec_receive_frame
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Alias for avcodec_receive_frame_flags(avctx, frame, 0).
Definition: avcodec.c:731
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
avformat_write_header
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:467
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1314
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:770
AVCodecParameters::avcodec_parameters_to_context
int avcodec_parameters_to_context(AVCodecContext *codec, const struct AVCodecParameters *par)
Fill the codec context based on the values from the supplied codec parameters.
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:786
NULL
#define NULL
Definition: coverity.c:32
avcodec_free_context
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition: options.c:164
av_audio_fifo_alloc
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:62
read_decode_convert_and_store
static int read_decode_convert_and_store(AVAudioFifo *fifo, AVFormatContext *input_format_context, AVCodecContext *input_codec_context, AVCodecContext *output_codec_context, SwrContext *resampler_context, int *finished)
Read one audio frame from the input file, decode, convert and store it in the FIFO buffer.
Definition: transcode_aac.c:548
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:493
OUTPUT_BIT_RATE
#define OUTPUT_BIT_RATE
Definition: transcode_aac.c:48
avcodec_open2
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition: avcodec.c:144
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:1176
init_output_frame
static int init_output_frame(AVFrame **frame, AVCodecContext *output_codec_context, int frame_size)
Initialize one input frame for writing to the output file.
Definition: transcode_aac.c:614
swresample.h
avcodec_find_decoder
const AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:1049
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:463
avcodec_get_supported_config
int avcodec_get_supported_config(const AVCodecContext *avctx, const AVCodec *codec, enum AVCodecConfig config, unsigned flags, const void **out, int *out_num)
Retrieve a list of all supported values for a given configuration type.
Definition: avcodec.c:831
init_input_frame
static int init_input_frame(AVFrame **frame)
Initialize one audio frame for reading from the input file.
Definition: transcode_aac.c:273
avformat_find_stream_info
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
Definition: demux.c:2607
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
swr_alloc_set_opts2
int swr_alloc_set_opts2(struct SwrContext **ps, const AVChannelLayout *out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, const AVChannelLayout *in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx)
Allocate SwrContext if needed and set/reset common parameters.
Definition: swresample.c:54
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:164
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1047
AVCodecContext::pkt_timebase
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are expressed.
Definition: avcodec.h:554
av_audio_fifo_read
int av_audio_fifo_read(AVAudioFifo *af, void *const *data, int nb_samples)
Read data from an AVAudioFifo.
Definition: audio_fifo.c:175
encode_audio_frame
static int encode_audio_frame(AVFrame *frame, AVFormatContext *output_format_context, AVCodecContext *output_codec_context, int *data_present)
Encode one frame worth of audio to the output file.
Definition: transcode_aac.c:660
main
int main(int argc, char **argv)
Definition: transcode_aac.c:783
avio.h
swr_free
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
Definition: swresample.c:137
init_packet
static int init_packet(AVPacket **packet)
Initialize one data packet for reading or writing.
Definition: transcode_aac.c:259
frame.h
OUTPUT_CHANNELS
#define OUTPUT_CHANNELS
Definition: transcode_aac.c:50
output_frame
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:860
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: packet.c:63
av_audio_fifo_size
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:222
init_resampler
static int init_resampler(AVCodecContext *input_codec_context, AVCodecContext *output_codec_context, SwrContext **resample_context)
Initialize the audio resampler based on the input and output codec settings.
Definition: transcode_aac.c:291
av_channel_layout_default
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
Definition: channel_layout.c:841
avcodec_send_packet
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition: decode.c:722
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1238
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:546
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:478
convert_samples
static int convert_samples(const uint8_t **input_data, uint8_t **converted_data, const int frame_size, SwrContext *resample_context)
Convert the input audio samples into the output sample format.
Definition: transcode_aac.c:484
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:527
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
init_converted_samples
static int init_converted_samples(uint8_t ***converted_input_samples, AVCodecContext *output_codec_context, int frame_size)
Initialize a temporary storage for the specified number of audio samples.
Definition: transcode_aac.c:449
audio_fifo.h
avcodec_send_frame
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Supply a raw video or audio frame to the encoder.
Definition: encode.c:519
avcodec.h
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:747
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
avformat.h
AVCodecContext
main external API structure.
Definition: avcodec.h:443
channel_layout.h
AVRational::den
int den
Denominator.
Definition: rational.h:60
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:149
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:450
av_guess_format
const AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:79
mem.h
av_strdup
#define av_strdup(s)
Definition: ops_asmgen.c:47
av_samples_alloc_array_and_samples
int av_samples_alloc_array_and_samples(uint8_t ***audio_data, int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
Allocate a data pointers array, samples buffer for nb_samples samples, and fill data pointers and lin...
Definition: samplefmt.c:207
AVCodecParameters::avcodec_parameters_from_context
int avcodec_parameters_from_context(struct AVCodecParameters *par, const AVCodecContext *codec)
Fill the parameters struct based on the values from the supplied codec context.
Definition: codec_par.c:138
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
AVPacket
This structure stores compressed data.
Definition: packet.h:580
avio_closep
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: avio.c:655
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
avstring.h
input_data
static void input_data(MLPEncodeContext *ctx, MLPSubstream *s, uint8_t **const samples, int nb_samples)
Wrapper function for inputting data in two different bit-depths.
Definition: mlpenc.c:1219
write_output_file_trailer
static int write_output_file_trailer(AVFormatContext *output_format_context)
Write the trailer of the output file container.
Definition: transcode_aac.c:772