| @@ -61,6 +61,7 @@ static int open_input_file(const char *filename, | |||||
| AVFormatContext **input_format_context, | AVFormatContext **input_format_context, | ||||
| AVCodecContext **input_codec_context) | AVCodecContext **input_codec_context) | ||||
| { | { | ||||
| AVCodecContext *avctx; | |||||
| AVCodec *input_codec; | AVCodec *input_codec; | ||||
| int error; | int error; | ||||
| @@ -90,23 +91,39 @@ static int open_input_file(const char *filename, | |||||
| } | } | ||||
| /** Find a decoder for the audio stream. */ | /** Find a decoder for the audio stream. */ | ||||
| if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codec->codec_id))) { | |||||
| if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codecpar->codec_id))) { | |||||
| fprintf(stderr, "Could not find input codec\n"); | fprintf(stderr, "Could not find input codec\n"); | ||||
| avformat_close_input(input_format_context); | avformat_close_input(input_format_context); | ||||
| return AVERROR_EXIT; | return AVERROR_EXIT; | ||||
| } | } | ||||
| /** allocate a new decoding context */ | |||||
| avctx = avcodec_alloc_context3(input_codec); | |||||
| if (!avctx) { | |||||
| fprintf(stderr, "Could not allocate a decoding context\n"); | |||||
| avformat_close_input(input_format_context); | |||||
| return AVERROR(ENOMEM); | |||||
| } | |||||
| /** initialize the stream parameters with demuxer information */ | |||||
| error = avcodec_parameters_to_context(avctx, (*input_format_context)->streams[0]->codecpar); | |||||
| if (error < 0) { | |||||
| avformat_close_input(input_format_context); | |||||
| avcodec_free_context(&avctx); | |||||
| return error; | |||||
| } | |||||
| /** Open the decoder for the audio stream to use it later. */ | /** Open the decoder for the audio stream to use it later. */ | ||||
| if ((error = avcodec_open2((*input_format_context)->streams[0]->codec, | |||||
| input_codec, NULL)) < 0) { | |||||
| if ((error = avcodec_open2(avctx, input_codec, NULL)) < 0) { | |||||
| fprintf(stderr, "Could not open input codec (error '%s')\n", | fprintf(stderr, "Could not open input codec (error '%s')\n", | ||||
| get_error_text(error)); | get_error_text(error)); | ||||
| avcodec_free_context(&avctx); | |||||
| avformat_close_input(input_format_context); | avformat_close_input(input_format_context); | ||||
| return error; | return error; | ||||
| } | } | ||||
| /** Save the decoder context for easier access later. */ | /** Save the decoder context for easier access later. */ | ||||
| *input_codec_context = (*input_format_context)->streams[0]->codec; | |||||
| *input_codec_context = avctx; | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -121,6 +138,7 @@ static int open_output_file(const char *filename, | |||||
| AVFormatContext **output_format_context, | AVFormatContext **output_format_context, | ||||
| AVCodecContext **output_codec_context) | AVCodecContext **output_codec_context) | ||||
| { | { | ||||
| AVCodecContext *avctx = NULL; | |||||
| AVIOContext *output_io_context = NULL; | AVIOContext *output_io_context = NULL; | ||||
| AVStream *stream = NULL; | AVStream *stream = NULL; | ||||
| AVCodec *output_codec = NULL; | AVCodec *output_codec = NULL; | ||||
| @@ -160,27 +178,31 @@ static int open_output_file(const char *filename, | |||||
| } | } | ||||
| /** Create a new audio stream in the output file container. */ | /** Create a new audio stream in the output file container. */ | ||||
| if (!(stream = avformat_new_stream(*output_format_context, output_codec))) { | |||||
| if (!(stream = avformat_new_stream(*output_format_context, NULL))) { | |||||
| fprintf(stderr, "Could not create new stream\n"); | fprintf(stderr, "Could not create new stream\n"); | ||||
| error = AVERROR(ENOMEM); | error = AVERROR(ENOMEM); | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| /** Save the encoder context for easier access later. */ | |||||
| *output_codec_context = stream->codec; | |||||
| avctx = avcodec_alloc_context3(output_codec); | |||||
| if (!avctx) { | |||||
| fprintf(stderr, "Could not allocate an encoding context\n"); | |||||
| error = AVERROR(ENOMEM); | |||||
| goto cleanup; | |||||
| } | |||||
| /** | /** | ||||
| * Set the basic encoder parameters. | * Set the basic encoder parameters. | ||||
| * The input file's sample rate is used to avoid a sample rate conversion. | * The input file's sample rate is used to avoid a sample rate conversion. | ||||
| */ | */ | ||||
| (*output_codec_context)->channels = OUTPUT_CHANNELS; | |||||
| (*output_codec_context)->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS); | |||||
| (*output_codec_context)->sample_rate = input_codec_context->sample_rate; | |||||
| (*output_codec_context)->sample_fmt = output_codec->sample_fmts[0]; | |||||
| (*output_codec_context)->bit_rate = OUTPUT_BIT_RATE; | |||||
| avctx->channels = OUTPUT_CHANNELS; | |||||
| avctx->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS); | |||||
| avctx->sample_rate = input_codec_context->sample_rate; | |||||
| avctx->sample_fmt = output_codec->sample_fmts[0]; | |||||
| avctx->bit_rate = OUTPUT_BIT_RATE; | |||||
| /** Allow the use of the experimental AAC encoder */ | /** Allow the use of the experimental AAC encoder */ | ||||
| (*output_codec_context)->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; | |||||
| avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; | |||||
| /** Set the sample rate for the container. */ | /** Set the sample rate for the container. */ | ||||
| stream->time_base.den = input_codec_context->sample_rate; | stream->time_base.den = input_codec_context->sample_rate; | ||||
| @@ -191,18 +213,28 @@ static int open_output_file(const char *filename, | |||||
| * Mark the encoder so that it behaves accordingly. | * Mark the encoder so that it behaves accordingly. | ||||
| */ | */ | ||||
| if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER) | if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER) | ||||
| (*output_codec_context)->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; | |||||
| avctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; | |||||
| /** Open the encoder for the audio stream to use it later. */ | /** Open the encoder for the audio stream to use it later. */ | ||||
| if ((error = avcodec_open2(*output_codec_context, output_codec, NULL)) < 0) { | |||||
| if ((error = avcodec_open2(avctx, output_codec, NULL)) < 0) { | |||||
| fprintf(stderr, "Could not open output codec (error '%s')\n", | fprintf(stderr, "Could not open output codec (error '%s')\n", | ||||
| get_error_text(error)); | get_error_text(error)); | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| error = avcodec_parameters_from_context(stream->codecpar, avctx); | |||||
| if (error < 0) { | |||||
| fprintf(stderr, "Could not initialize stream parameters\n"); | |||||
| goto cleanup; | |||||
| } | |||||
| /** Save the encoder context for easier access later. */ | |||||
| *output_codec_context = avctx; | |||||
| return 0; | return 0; | ||||
| cleanup: | cleanup: | ||||
| avcodec_free_context(&avctx); | |||||
| avio_close((*output_format_context)->pb); | avio_close((*output_format_context)->pb); | ||||
| avformat_free_context(*output_format_context); | avformat_free_context(*output_format_context); | ||||
| *output_format_context = NULL; | *output_format_context = NULL; | ||||
| @@ -773,13 +805,13 @@ cleanup: | |||||
| avresample_free(&resample_context); | avresample_free(&resample_context); | ||||
| } | } | ||||
| if (output_codec_context) | if (output_codec_context) | ||||
| avcodec_close(output_codec_context); | |||||
| avcodec_free_context(&output_codec_context); | |||||
| if (output_format_context) { | if (output_format_context) { | ||||
| avio_close(output_format_context->pb); | avio_close(output_format_context->pb); | ||||
| avformat_free_context(output_format_context); | avformat_free_context(output_format_context); | ||||
| } | } | ||||
| if (input_codec_context) | if (input_codec_context) | ||||
| avcodec_close(input_codec_context); | |||||
| avcodec_free_context(&input_codec_context); | |||||
| if (input_format_context) | if (input_format_context) | ||||
| avformat_close_input(&input_format_context); | avformat_close_input(&input_format_context); | ||||