From patchwork Thu Jun 11 15:43:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fu, Linjie" X-Patchwork-Id: 20283 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id ABCED44AB81 for ; Thu, 11 Jun 2020 18:48:03 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 85EE968B611; Thu, 11 Jun 2020 18:48:03 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5486468B067 for ; Thu, 11 Jun 2020 18:47:57 +0300 (EEST) IronPort-SDR: ZQJ+9S3X+EigqoKx2rutiF6RCQLKWPhAMvHVpRDgCPLDnhrk2Q/KNZ7+TeQfJdEJwaC+8M7zxG I5EgJTBFSxUg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2020 08:47:29 -0700 IronPort-SDR: lZ4qJMf78DSWwIHYlH/ngGqQ5QHpwuimZwAlVArBW3/p9fhj+LIGA/UMrpR+R3sWeQIk/L8n8/ 0BrF8AY3a4bg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,499,1583222400"; d="scan'208";a="296631067" Received: from icl-dev.sh.intel.com ([10.239.158.73]) by fmsmga004.fm.intel.com with ESMTP; 11 Jun 2020 08:47:28 -0700 From: Linjie Fu To: ffmpeg-devel@ffmpeg.org Date: Thu, 11 Jun 2020 23:43:02 +0800 Message-Id: <1591890182-22085-1-git-send-email-linjie.fu@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [FFmpeg-devel] [PATCH v2 4/5] fftools/ffmpeg: flush and recreate encoder instance if resolution changes X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Linjie Fu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Add recreate_encoder_instance() function. If resolution changing is allowed, discard AV_CODEC_FLAG_GLOBAL_HEADER even if the avformat/container declares AVFMT_GLOBALHEADER flag. Place header information in every keyframe instead of single global header. Signed-off-by: Linjie Fu --- Should be squashed with: https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=1434 fftools/ffmpeg.c | 40 ++++++++++++++++++++++++++++++++++++++++ fftools/ffmpeg_opt.c | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 5859781..86562c9 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -130,6 +130,7 @@ static void do_video_stats(OutputStream *ost, int frame_size); static BenchmarkTimeStamps get_benchmark_time_stamps(void); static int64_t getmaxrss(void); static int ifilter_has_all_input_formats(FilterGraph *fg); +static void flush_encoders(void); static int run_as_daemon = 0; static int nb_frames_dup = 0; @@ -1039,6 +1040,37 @@ static void do_subtitle_out(OutputFile *of, } } +static int recreate_encoder_instance(OutputStream *ost, + int width, int height) +{ + AVCodec *encoder = ost->enc_ctx->codec; + AVRational time_base = ost->enc_ctx->time_base; + int ret; + + avcodec_free_context(&ost->enc_ctx); + + ost->enc_ctx = avcodec_alloc_context3(encoder); + if (!ost->enc_ctx) + return AVERROR(ENOMEM); + + ost->st->codecpar->width = width; + ost->st->codecpar->height = height; + + if (ret = avcodec_parameters_to_context(ost->enc_ctx, ost->st->codecpar) < 0) + return ret; + + ost->enc_ctx->time_base = time_base; + + if (ret = avcodec_open2(ost->enc_ctx, encoder, &ost->encoder_opts) < 0) { + av_log(NULL, AV_LOG_ERROR, "Error while re-opening encoder for output stream #%d:%d - " + "maybe incorrect parameters such as bit_rate, rate, width or height.\n", + ost->file_index, ost->index); + return ret; + } + + return 0; +} + static void do_video_out(OutputFile *of, OutputStream *ost, AVFrame *next_picture, @@ -1058,11 +1090,19 @@ static void do_video_out(OutputFile *of, if (next_picture && (enc->width != next_picture->width || enc->height != next_picture->height)) { + flush_encoders(); + avcodec_flush_buffers(enc); + if (!(enc->codec->capabilities & AV_CODEC_CAP_VARIABLE_DIMENSIONS)) { av_log(NULL, AV_LOG_ERROR, "Variable dimension encoding " "is not supported by %s.\n", enc->codec->name); goto error; } + + if (recreate_encoder_instance(ost, next_picture->width, next_picture->height) < 0) + goto error; + + enc = ost->enc_ctx; } if (ost->source_index >= 0) diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 9d1489c..334c6ec 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -1562,7 +1562,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st); ost->max_muxing_queue_size *= sizeof(AVPacket); - if (oc->oformat->flags & AVFMT_GLOBALHEADER) + if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->autoscale) ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0); From patchwork Thu Jun 11 15:43:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fu, Linjie" X-Patchwork-Id: 20284 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id A4CF644B563 for ; Thu, 11 Jun 2020 18:48:23 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8CB6C68B604; Thu, 11 Jun 2020 18:48:23 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C066C68B067 for ; Thu, 11 Jun 2020 18:48:16 +0300 (EEST) IronPort-SDR: g9sMxA1bGOcN2p+ma7CO/ImCvshF2RxEoSVT0a+TlwRbYqQEmcbmuf4M2f2IjWYM2rFPhf+iEX Fxl36BGBsfbQ== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 11 Jun 2020 08:48:11 -0700 IronPort-SDR: 2CaIAZc4bW0WsZZZdgXagoqO/4+rhpZd4xLHtLZ69lq3ij/2lNL4yDct3Acm4a0RUQmkSeXttn zUj1kRTiRQlA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,499,1583222400"; d="scan'208";a="473846872" Received: from icl-dev.sh.intel.com ([10.239.158.73]) by fmsmga005.fm.intel.com with ESMTP; 11 Jun 2020 08:48:10 -0700 From: Linjie Fu To: ffmpeg-devel@ffmpeg.org Date: Thu, 11 Jun 2020 23:43:44 +0800 Message-Id: <1591890224-22387-1-git-send-email-linjie.fu@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [FFmpeg-devel] [PATCH v2 5/5] lavc/encoder: declare caps for encoding with variable dimension X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Linjie Fu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Linjie Fu --- Tested following encoders with container muxer(like mp4 muxer for x264, which previously use extradata to store a global header) and raw video muxer, results are good. libavcodec/libopenh264enc.c | 4 +++- libavcodec/libvpxenc.c | 4 +++- libavcodec/libx264.c | 4 +++- libavcodec/libx265.c | 4 +++- libavcodec/rawenc.c | 3 ++- libavcodec/wrapped_avframe.c | 3 ++- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c index f63aa52..b86041b 100644 --- a/libavcodec/libopenh264enc.c +++ b/libavcodec/libopenh264enc.c @@ -438,7 +438,9 @@ AVCodec ff_libopenh264_encoder = { .init = svc_encode_init, .encode2 = svc_encode_frame, .close = svc_encode_close, - .capabilities = AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_AUTO_THREADS | + AV_CODEC_CAP_VARIABLE_DIMENSIONS | + AV_CODEC_CAP_ENCODER_FLUSH, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 8e0ea42..9faec48 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -1789,7 +1789,9 @@ AVCodec ff_libvpx_vp9_encoder = { .init = vp9_init, .encode2 = vpx_encode, .close = vpx_free, - .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS, + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | + AV_CODEC_CAP_VARIABLE_DIMENSIONS | + AV_CODEC_CAP_ENCODER_FLUSH, .profiles = NULL_IF_CONFIG_SMALL(ff_vp9_profiles), .priv_class = &class_vp9, .defaults = defaults, diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index d4b1fd0..016c53c 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -1177,7 +1177,9 @@ AVCodec ff_libx264_encoder = { .encode2 = X264_frame, .close = X264_close, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE | + AV_CODEC_CAP_VARIABLE_DIMENSIONS | + AV_CODEC_CAP_ENCODER_FLUSH, .priv_class = &x264_class, .defaults = x264_defaults, .init_static_data = X264_init_static, diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index f560d7f..2a9ec4e 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -701,6 +701,8 @@ AVCodec ff_libx265_encoder = { .priv_class = &class, .defaults = x265_defaults, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, + AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE | + AV_CODEC_CAP_VARIABLE_DIMENSIONS | + AV_CODEC_CAP_ENCODER_FLUSH, .wrapper_name = "libx265", }; diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c index 486c0d7..85298dc 100644 --- a/libavcodec/rawenc.c +++ b/libavcodec/rawenc.c @@ -92,5 +92,6 @@ AVCodec ff_rawvideo_encoder = { .id = AV_CODEC_ID_RAWVIDEO, .init = raw_encode_init, .encode2 = raw_encode, - .capabilities = AV_CODEC_CAP_VARIABLE_DIMENSIONS, + .capabilities = AV_CODEC_CAP_VARIABLE_DIMENSIONS | + AV_CODEC_CAP_ENCODER_FLUSH, }; diff --git a/libavcodec/wrapped_avframe.c b/libavcodec/wrapped_avframe.c index ae29328..9af3193 100644 --- a/libavcodec/wrapped_avframe.c +++ b/libavcodec/wrapped_avframe.c @@ -116,7 +116,8 @@ AVCodec ff_wrapped_avframe_encoder = { .id = AV_CODEC_ID_WRAPPED_AVFRAME, .encode2 = wrapped_avframe_encode, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, - .capabilities = AV_CODEC_CAP_VARIABLE_DIMENSIONS, + .capabilities = AV_CODEC_CAP_VARIABLE_DIMENSIONS | + AV_CODEC_CAP_ENCODER_FLUSH, }; AVCodec ff_wrapped_avframe_decoder = {