From 41776ba9c0ebbb71394cefdf7dd1b243e6c852d5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 5 Apr 2014 08:48:24 +0200 Subject: avconv: do not use the stream codec context for decoding --- avconv.c | 66 +++++++++++++++++++++++++++++---------------------------- avconv.h | 1 + avconv_filter.c | 18 ++++++++-------- avconv_opt.c | 28 +++++++++++++++++------- 4 files changed, 64 insertions(+), 49 deletions(-) diff --git a/avconv.c b/avconv.c index 2cee09bc22..30b85cc770 100644 --- a/avconv.c +++ b/avconv.c @@ -206,6 +206,8 @@ static void avconv_cleanup(int ret) av_freep(&ist->filters); av_freep(&ist->hwaccel_device); + avcodec_free_context(&ist->dec_ctx); + av_freep(&input_streams[i]); } @@ -800,7 +802,7 @@ static void print_final_stats(int64_t total_size) for (j = 0; j < f->nb_streams; j++) { InputStream *ist = input_streams[f->ist_index + j]; - enum AVMediaType type = ist->st->codec->codec_type; + enum AVMediaType type = ist->dec_ctx->codec_type; total_size += ist->data_size; total_packets += ist->nb_packets; @@ -1139,7 +1141,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p int guess_input_channel_layout(InputStream *ist) { - AVCodecContext *dec = ist->st->codec; + AVCodecContext *dec = ist->dec_ctx; if (!dec->channel_layout) { char layout_name[256]; @@ -1158,7 +1160,7 @@ int guess_input_channel_layout(InputStream *ist) static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) { AVFrame *decoded_frame, *f; - AVCodecContext *avctx = ist->st->codec; + AVCodecContext *avctx = ist->dec_ctx; int i, ret, err = 0, resample_changed; if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) @@ -1231,7 +1233,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) if (decoded_frame->pts != AV_NOPTS_VALUE) decoded_frame->pts = av_rescale_q(decoded_frame->pts, ist->st->time_base, - (AVRational){1, ist->st->codec->sample_rate}); + (AVRational){1, avctx->sample_rate}); for (i = 0; i < ist->nb_filters; i++) { if (i < ist->nb_filters - 1) { f = ist->filter_frame; @@ -1262,7 +1264,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) return AVERROR(ENOMEM); decoded_frame = ist->decoded_frame; - ret = avcodec_decode_video2(ist->st->codec, + ret = avcodec_decode_video2(ist->dec_ctx, decoded_frame, got_output, pkt); if (!*got_output || ret < 0) { if (!pkt->size) { @@ -1275,7 +1277,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) ist->frames_decoded++; if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { - err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame); + err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame); if (err < 0) goto fail; } @@ -1337,7 +1339,7 @@ fail: static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) { AVSubtitle subtitle; - int i, ret = avcodec_decode_subtitle2(ist->st->codec, + int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); if (ret < 0) return ret; @@ -1396,7 +1398,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) ist->showed_multi_packet_warning = 1; } - switch (ist->st->codec->codec_type) { + switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: ret = decode_audio (ist, &avpkt, &got_output); break; @@ -1407,10 +1409,10 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) else if (ist->st->avg_frame_rate.num) ist->next_dts += av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate), AV_TIME_BASE_Q); - else if (ist->st->codec->time_base.num != 0) { + else if (ist->dec_ctx->time_base.num != 0) { int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : - ist->st->codec->ticks_per_frame; - ist->next_dts += av_rescale_q(ticks, ist->st->codec->time_base, AV_TIME_BASE_Q); + ist->dec_ctx->ticks_per_frame; + ist->next_dts += av_rescale_q(ticks, ist->dec_ctx->time_base, AV_TIME_BASE_Q); } break; case AVMEDIA_TYPE_SUBTITLE: @@ -1435,17 +1437,17 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) /* handle stream copy */ if (!ist->decoding_needed) { ist->last_dts = ist->next_dts; - switch (ist->st->codec->codec_type) { + switch (ist->dec_ctx->codec_type) { case AVMEDIA_TYPE_AUDIO: - ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / - ist->st->codec->sample_rate; + ist->next_dts += ((int64_t)AV_TIME_BASE * ist->dec_ctx->frame_size) / + ist->dec_ctx->sample_rate; break; case AVMEDIA_TYPE_VIDEO: - if (ist->st->codec->time_base.num != 0) { - int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame; + if (ist->dec_ctx->time_base.num != 0) { + int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->dec_ctx->ticks_per_frame; ist->next_dts += ((int64_t)AV_TIME_BASE * - ist->st->codec->time_base.num * ticks) / - ist->st->codec->time_base.den; + ist->dec_ctx->time_base.num * ticks) / + ist->dec_ctx->time_base.den; } break; } @@ -1544,7 +1546,7 @@ static int init_input_stream(int ist_index, char *error, int error_len) AVCodec *codec = ist->dec; if (!codec) { snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d", - ist->st->codec->codec_id, ist->file_index, ist->st->index); + ist->dec_ctx->codec_id, ist->file_index, ist->st->index); return AVERROR(EINVAL); } @@ -1553,21 +1555,21 @@ static int init_input_stream(int ist_index, char *error, int error_len) for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; if (ost->source_index == ist_index) { - update_sample_fmt(ist->st->codec, codec, ost->st->codec); + update_sample_fmt(ist->dec_ctx, codec, ost->st->codec); break; } } - ist->st->codec->opaque = ist; - ist->st->codec->get_format = get_format; - ist->st->codec->get_buffer2 = get_buffer; - ist->st->codec->thread_safe_callbacks = 1; + ist->dec_ctx->opaque = ist; + ist->dec_ctx->get_format = get_format; + ist->dec_ctx->get_buffer2 = get_buffer; + ist->dec_ctx->thread_safe_callbacks = 1; - av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0); + av_opt_set_int(ist->dec_ctx, "refcounted_frames", 1, 0); if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) av_dict_set(&ist->decoder_opts, "threads", "auto", 0); - if ((ret = avcodec_open2(ist->st->codec, codec, &ist->decoder_opts)) < 0) { + if ((ret = avcodec_open2(ist->dec_ctx, codec, &ist->decoder_opts)) < 0) { char errbuf[128]; if (ret == AVERROR_EXPERIMENTAL) abort_codec_experimental(codec, 0); @@ -1583,7 +1585,7 @@ static int init_input_stream(int ist_index, char *error, int error_len) assert_avoptions(ist->decoder_opts); } - ist->last_dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; + ist->last_dts = ist->st->avg_frame_rate.num ? - ist->dec_ctx->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; ist->next_dts = AV_NOPTS_VALUE; init_pts_correction(&ist->pts_ctx); @@ -1600,7 +1602,7 @@ static InputStream *get_input_stream(OutputStream *ost) int i; for (i = 0; i < fg->nb_inputs; i++) - if (fg->inputs[i]->ist->st->codec->codec_type == ost->st->codec->codec_type) + if (fg->inputs[i]->ist->dec_ctx->codec_type == ost->st->codec->codec_type) return fg->inputs[i]->ist; } @@ -1712,7 +1714,7 @@ static int transcode_init(void) enc_ctx = ost->st->codec; if (ist) { - dec_ctx = ist->st->codec; + dec_ctx = ist->dec_ctx; ost->st->disposition = ist->st->disposition; enc_ctx->bits_per_raw_sample = dec_ctx->bits_per_raw_sample; @@ -1943,7 +1945,7 @@ static int transcode_init(void) AVCodecContext *dec = NULL; if ((ist = get_input_stream(ost))) - dec = ist->st->codec; + dec = ist->dec_ctx; if (dec && dec->subtitle_header) { ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size); if (!ost->st->codec->subtitle_header) { @@ -2512,9 +2514,9 @@ static int transcode(void) for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; if (ist->decoding_needed) { - avcodec_close(ist->st->codec); + avcodec_close(ist->dec_ctx); if (ist->hwaccel_uninit) - ist->hwaccel_uninit(ist->st->codec); + ist->hwaccel_uninit(ist->dec_ctx); } } diff --git a/avconv.h b/avconv.h index 56ce9f01ff..64d8ad0b16 100644 --- a/avconv.h +++ b/avconv.h @@ -219,6 +219,7 @@ typedef struct InputStream { AVStream *st; int discard; /* true if stream data should be discarded */ int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ + AVCodecContext *dec_ctx; AVCodec *dec; AVFrame *decoded_frame; AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */ diff --git a/avconv_filter.c b/avconv_filter.c index 892db00f47..c667992165 100644 --- a/avconv_filter.c +++ b/avconv_filter.c @@ -149,7 +149,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) /* find the first unused stream of corresponding type */ for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; - if (ist->st->codec->codec_type == type && ist->discard) + if (ist->dec_ctx->codec_type == type && ist->discard) break; } if (i == nb_input_streams) { @@ -433,10 +433,10 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter, sar = ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio : - ist->st->codec->sample_aspect_ratio; - snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width, - ist->st->codec->height, - ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->st->codec->pix_fmt, + ist->dec_ctx->sample_aspect_ratio; + snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->dec_ctx->width, + ist->dec_ctx->height, + ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : ist->dec_ctx->pix_fmt, tb.num, tb.den, sar.num, sar.den); snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, ist->file_index, ist->st->index); @@ -487,10 +487,10 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter, snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s" ":channel_layout=0x%"PRIx64, - 1, ist->st->codec->sample_rate, - ist->st->codec->sample_rate, - av_get_sample_fmt_name(ist->st->codec->sample_fmt), - ist->st->codec->channel_layout); + 1, ist->dec_ctx->sample_rate, + ist->dec_ctx->sample_rate, + av_get_sample_fmt_name(ist->dec_ctx->sample_fmt), + ist->dec_ctx->channel_layout); snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index, ist->file_index, ist->st->index); diff --git a/avconv_opt.c b/avconv_opt.c index 12d676054d..539b1a0f61 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -462,7 +462,7 @@ static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream * * list of input streams. */ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) { - int i; + int i, ret; for (i = 0; i < ic->nb_streams; i++) { AVStream *st = ic->streams[i]; @@ -497,11 +497,23 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ist->dec = choose_decoder(o, ic, st); ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec); + ist->dec_ctx = avcodec_alloc_context3(ist->dec); + if (!ist->dec_ctx) { + av_log(NULL, AV_LOG_ERROR, "Error allocating the decoder context.\n"); + exit_program(1); + } + + ret = avcodec_copy_context(ist->dec_ctx, dec); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n"); + exit_program(1); + } + switch (dec->codec_type) { case AVMEDIA_TYPE_VIDEO: - ist->resample_height = dec->height; - ist->resample_width = dec->width; - ist->resample_pix_fmt = dec->pix_fmt; + ist->resample_height = ist->dec_ctx->height; + ist->resample_width = ist->dec_ctx->width; + ist->resample_pix_fmt = ist->dec_ctx->pix_fmt; MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st); if (framerate && av_parse_video_rate(&ist->framerate, @@ -550,10 +562,10 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) case AVMEDIA_TYPE_AUDIO: guess_input_channel_layout(ist); - ist->resample_sample_fmt = dec->sample_fmt; - ist->resample_sample_rate = dec->sample_rate; - ist->resample_channels = dec->channels; - ist->resample_channel_layout = dec->channel_layout; + ist->resample_sample_fmt = ist->dec_ctx->sample_fmt; + ist->resample_sample_rate = ist->dec_ctx->sample_rate; + ist->resample_channels = ist->dec_ctx->channels; + ist->resample_channel_layout = ist->dec_ctx->channel_layout; break; case AVMEDIA_TYPE_DATA: -- cgit v1.2.3