From ba7397baef796ca3991fe1c921bc91054407c48b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 23 May 2016 09:37:10 +0200 Subject: avconv: factor out initializing stream parameters for encoding Setting the filter input parameters is moved to init_input_stream(), so that it is done before the decoder is opened, potentially overwriting the information from avformat_find_stream_info() with less accurate data. This commit temporarily disables QSV transcoding with hw frames. The functionality will be re-added in the following commits. --- avconv.c | 296 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 144 insertions(+), 152 deletions(-) diff --git a/avconv.c b/avconv.c index 4e19813312..9344a3ee58 100644 --- a/avconv.c +++ b/avconv.c @@ -1616,8 +1616,17 @@ static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags) static int init_input_stream(int ist_index, char *error, int error_len) { - int ret; + int i, ret; InputStream *ist = input_streams[ist_index]; + + for (i = 0; i < ist->nb_filters; i++) { + ret = ifilter_parameters_from_decoder(ist->filters[i], ist->dec_ctx); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "Error initializing filter input\n"); + return ret; + } + } + if (ist->decoding_needed) { AVCodec *codec = ist->dec; if (!codec) { @@ -1872,6 +1881,136 @@ static int init_output_stream_streamcopy(OutputStream *ost) return 0; } +static void set_encoder_id(OutputFile *of, OutputStream *ost) +{ + AVDictionaryEntry *e; + + uint8_t *encoder_string; + int encoder_string_len; + int format_flags = 0; + + e = av_dict_get(of->opts, "fflags", NULL, 0); + if (e) { + const AVOption *o = av_opt_find(of->ctx, "fflags", NULL, 0, 0); + if (!o) + return; + av_opt_eval_flags(of->ctx, o, e->value, &format_flags); + } + + encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(ost->enc->name) + 2; + encoder_string = av_mallocz(encoder_string_len); + if (!encoder_string) + exit_program(1); + + if (!(format_flags & AVFMT_FLAG_BITEXACT)) + av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len); + av_strlcat(encoder_string, ost->enc->name, encoder_string_len); + av_dict_set(&ost->st->metadata, "encoder", encoder_string, + AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE); +} + +static void parse_forced_key_frames(char *kf, OutputStream *ost, + AVCodecContext *avctx) +{ + char *p; + int n = 1, i; + int64_t t; + + for (p = kf; *p; p++) + if (*p == ',') + n++; + ost->forced_kf_count = n; + ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n); + if (!ost->forced_kf_pts) { + av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); + exit_program(1); + } + + p = kf; + for (i = 0; i < n; i++) { + char *next = strchr(p, ','); + + if (next) + *next++ = 0; + + t = parse_time_or_die("force_key_frames", p, 1); + ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); + + p = next; + } +} + +static int init_output_stream_encode(OutputStream *ost) +{ + InputStream *ist = get_input_stream(ost); + AVCodecContext *enc_ctx = ost->enc_ctx; + AVCodecContext *dec_ctx = NULL; + + set_encoder_id(output_files[ost->file_index], ost); + + if (ist) { + ost->st->disposition = ist->st->disposition; + + dec_ctx = ist->dec_ctx; + + enc_ctx->bits_per_raw_sample = dec_ctx->bits_per_raw_sample; + enc_ctx->chroma_sample_location = dec_ctx->chroma_sample_location; + } + + if ((enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO || + enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) && + filtergraph_is_simple(ost->filter->graph)) { + FilterGraph *fg = ost->filter->graph; + + if (configure_filtergraph(fg)) { + av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n"); + exit_program(1); + } + } + + switch (enc_ctx->codec_type) { + case AVMEDIA_TYPE_AUDIO: + enc_ctx->sample_fmt = ost->filter->filter->inputs[0]->format; + enc_ctx->sample_rate = ost->filter->filter->inputs[0]->sample_rate; + enc_ctx->channel_layout = ost->filter->filter->inputs[0]->channel_layout; + enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout); + enc_ctx->time_base = (AVRational){ 1, enc_ctx->sample_rate }; + break; + case AVMEDIA_TYPE_VIDEO: + enc_ctx->time_base = ost->filter->filter->inputs[0]->time_base; + + enc_ctx->width = ost->filter->filter->inputs[0]->w; + enc_ctx->height = ost->filter->filter->inputs[0]->h; + enc_ctx->sample_aspect_ratio = ost->st->sample_aspect_ratio = + ost->frame_aspect_ratio ? // overridden by the -aspect cli option + av_d2q(ost->frame_aspect_ratio * enc_ctx->height/enc_ctx->width, 255) : + ost->filter->filter->inputs[0]->sample_aspect_ratio; + enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format; + + ost->st->avg_frame_rate = ost->frame_rate; + + if (dec_ctx && + (enc_ctx->width != dec_ctx->width || + enc_ctx->height != dec_ctx->height || + enc_ctx->pix_fmt != dec_ctx->pix_fmt)) { + enc_ctx->bits_per_raw_sample = 0; + } + + if (ost->forced_keyframes) + parse_forced_key_frames(ost->forced_keyframes, ost, + ost->enc_ctx); + break; + case AVMEDIA_TYPE_SUBTITLE: + enc_ctx->time_base = (AVRational){1, 1000}; + break; + default: + abort(); + break; + } + + return 0; +} + static int init_output_stream(OutputStream *ost, char *error, int error_len) { int ret = 0; @@ -1881,6 +2020,10 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) AVCodecContext *dec = NULL; InputStream *ist; + ret = init_output_stream_encode(ost); + if (ret < 0) + return ret; + if ((ist = get_input_stream(ost))) dec = ist->dec_ctx; if (dec && dec->subtitle_header) { @@ -1973,69 +2116,9 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) return ret; } -static void parse_forced_key_frames(char *kf, OutputStream *ost, - AVCodecContext *avctx) -{ - char *p; - int n = 1, i; - int64_t t; - - for (p = kf; *p; p++) - if (*p == ',') - n++; - ost->forced_kf_count = n; - ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n); - if (!ost->forced_kf_pts) { - av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n"); - exit_program(1); - } - - p = kf; - for (i = 0; i < n; i++) { - char *next = strchr(p, ','); - - if (next) - *next++ = 0; - - t = parse_time_or_die("force_key_frames", p, 1); - ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base); - - p = next; - } -} - -static void set_encoder_id(OutputFile *of, OutputStream *ost) -{ - AVDictionaryEntry *e; - - uint8_t *encoder_string; - int encoder_string_len; - int format_flags = 0; - - e = av_dict_get(of->opts, "fflags", NULL, 0); - if (e) { - const AVOption *o = av_opt_find(of->ctx, "fflags", NULL, 0, 0); - if (!o) - return; - av_opt_eval_flags(of->ctx, o, e->value, &format_flags); - } - - encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(ost->enc->name) + 2; - encoder_string = av_mallocz(encoder_string_len); - if (!encoder_string) - exit_program(1); - - if (!(format_flags & AVFMT_FLAG_BITEXACT)) - av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len); - av_strlcat(encoder_string, ost->enc->name, encoder_string_len); - av_dict_set(&ost->st->metadata, "encoder", encoder_string, - AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE); -} - static int transcode_init(void) { int ret = 0, i, j, k; - AVFormatContext *oc; OutputStream *ost; InputStream *ist; char error[1024]; @@ -2048,97 +2131,6 @@ static int transcode_init(void) input_streams[j + ifile->ist_index]->start = av_gettime_relative(); } - /* for each output stream, we compute the right encoding parameters */ - for (i = 0; i < nb_output_streams; i++) { - ost = output_streams[i]; - oc = output_files[ost->file_index]->ctx; - ist = get_input_stream(ost); - - if (ost->attachment_filename) - continue; - - if (ist) { - ost->st->disposition = ist->st->disposition; - } - - if (!ost->stream_copy) { - AVCodecContext *enc_ctx = ost->enc_ctx; - AVCodecContext *dec_ctx = NULL; - - set_encoder_id(output_files[ost->file_index], ost); - - if (ist) { - dec_ctx = ist->dec_ctx; - - enc_ctx->bits_per_raw_sample = dec_ctx->bits_per_raw_sample; - enc_ctx->chroma_sample_location = dec_ctx->chroma_sample_location; - } - -#if CONFIG_LIBMFX - if (qsv_transcode_init(ost)) - exit_program(1); -#endif - - if ((enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO || - enc_ctx->codec_type == AVMEDIA_TYPE_AUDIO) && - filtergraph_is_simple(ost->filter->graph)) { - FilterGraph *fg = ost->filter->graph; - - ret = ifilter_parameters_from_decoder(fg->inputs[0], - dec_ctx); - if (ret < 0) { - av_log(NULL, AV_LOG_FATAL, "Error initializing filter input\n"); - exit_program(1); - } - - if (configure_filtergraph(fg)) { - av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n"); - exit_program(1); - } - } - - switch (enc_ctx->codec_type) { - case AVMEDIA_TYPE_AUDIO: - enc_ctx->sample_fmt = ost->filter->filter->inputs[0]->format; - enc_ctx->sample_rate = ost->filter->filter->inputs[0]->sample_rate; - enc_ctx->channel_layout = ost->filter->filter->inputs[0]->channel_layout; - enc_ctx->channels = av_get_channel_layout_nb_channels(enc_ctx->channel_layout); - enc_ctx->time_base = (AVRational){ 1, enc_ctx->sample_rate }; - break; - case AVMEDIA_TYPE_VIDEO: - enc_ctx->time_base = ost->filter->filter->inputs[0]->time_base; - - enc_ctx->width = ost->filter->filter->inputs[0]->w; - enc_ctx->height = ost->filter->filter->inputs[0]->h; - enc_ctx->sample_aspect_ratio = ost->st->sample_aspect_ratio = - ost->frame_aspect_ratio ? // overridden by the -aspect cli option - av_d2q(ost->frame_aspect_ratio * enc_ctx->height/enc_ctx->width, 255) : - ost->filter->filter->inputs[0]->sample_aspect_ratio; - enc_ctx->pix_fmt = ost->filter->filter->inputs[0]->format; - - ost->st->avg_frame_rate = ost->frame_rate; - - if (dec_ctx && - (enc_ctx->width != dec_ctx->width || - enc_ctx->height != dec_ctx->height || - enc_ctx->pix_fmt != dec_ctx->pix_fmt)) { - enc_ctx->bits_per_raw_sample = 0; - } - - if (ost->forced_keyframes) - parse_forced_key_frames(ost->forced_keyframes, ost, - ost->enc_ctx); - break; - case AVMEDIA_TYPE_SUBTITLE: - enc_ctx->time_base = (AVRational){1, 1000}; - break; - default: - abort(); - break; - } - } - } - /* init input streams */ for (i = 0; i < nb_input_streams; i++) if ((ret = init_input_stream(i, error, sizeof(error))) < 0) -- cgit v1.2.3