From patchwork Wed Mar 6 19:08:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Collyer X-Patchwork-Id: 12222 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 89225448736 for ; Wed, 6 Mar 2019 21:08:15 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6822968971C; Wed, 6 Mar 2019 21:08:15 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from st43p00im-zteg10062001.me.com (st43p00im-zteg10062001.me.com [17.58.63.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8BEEF680806 for ; Wed, 6 Mar 2019 21:08:08 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mac.com; s=04042017; t=1551899286; bh=Ptg7lAE03eVZTpzGuS7uZNhgLF59hAotfBDH5UHYpfY=; h=From:Content-Type:Mime-Version:Subject:Date:To:Message-Id; b=qIurkh4HvKxZwXq9TwwIz0CojGzudk44jLxL8oUZzbAqhkvmNd8kAOpa8lcUTadmA HuElT+w1gNm1wB45LXTVsr5FBuC5Cftae9B3AIP02y29bwFzj1TZb7VCXa0i8Jm2iJ fNEIt+IQLsVYKta+fIEPaSu1WbHvgfcdzBqFoxzrwb2epS1aorme40GaCeneyIf3h6 RjRxDM8SelWuNcy/z7z4S2uq3mHKWoER74ehvsdnvLZtuFOYS0bdwukbGoZ1gSnz9A oZrtjcJTEgRJNrSUm9QX4gxLmaFK3IXXKozwboND/WqcrUms0/pdexR8Xtjk6B/nvl 3BJJhg+VDOtug== Received: from [192.168.1.100] (host81-150-182-56.in-addr.btopenworld.com [81.150.182.56]) by st43p00im-zteg10062001.me.com (Postfix) with ESMTPSA id 7382C6C02D8 for ; Wed, 6 Mar 2019 19:08:06 +0000 (UTC) From: Oliver Collyer Mime-Version: 1.0 (Mac OS X Mail 12.2 \(3445.102.3\)) Date: Wed, 6 Mar 2019 19:08:02 +0000 References: <15484CA6-B6B2-479C-BED0-5950A97D3E91@mac.com> To: FFmpeg development discussions and patches In-Reply-To: Message-Id: <4FD50327-D018-40C4-AC20-F64C598A9ED8@mac.com> X-Mailer: Apple Mail (2.3445.102.3) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-03-06_12:, , signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1812120000 definitions=main-1903060131 Subject: Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Reconfigure resolution on-the-fly 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" >> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h >> index 0ce22ec4fa..7087f82ce1 100644 >> --- a/libavcodec/avcodec.h >> +++ b/libavcodec/avcodec.h >> @@ -3357,6 +3357,12 @@ typedef struct AVCodecContext { >> * - encoding: unused >> */ >> int discard_damaged_percentage; >> + >> + /* >> + * Video encoding only. Sets the maximum picture size for encoders that >> + * support adjusting the picture size dynamically during encoding. >> + */ >> + int max_width, max_height; >> } AVCodecContext; >> > > I really don't like introducing public API fields for this. Maybe a > private nvenc option would be better at this point. > So would this be suitable? The only thing was that I wasn't sure about exposing these options to ffmpeg though, as they're useless to ffmpeg unless ffmpeg were to add features for dynamically changing the encoded resolution....I just couldn't figure out how you can add a private option that isn't exposed in this way though. >>>>> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 304a684e0c..1a1331d468 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -384,6 +384,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) #endif ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE); + ctx->support_dyn_res = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_RES_CHANGE); return 0; } @@ -1121,6 +1122,8 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) ctx->init_encode_params.encodeHeight = avctx->height; ctx->init_encode_params.encodeWidth = avctx->width; + ctx->init_encode_params.maxEncodeHeight = ctx->max_height; + ctx->init_encode_params.maxEncodeWidth = ctx->max_width; ctx->init_encode_params.encodeConfig = &ctx->encode_config; @@ -1276,8 +1279,8 @@ static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) } allocSurf.version = NV_ENC_CREATE_INPUT_BUFFER_VER; - allocSurf.width = avctx->width; - allocSurf.height = avctx->height; + allocSurf.width = FFMAX(ctx->max_width, avctx->width); + allocSurf.height = FFMAX(ctx->max_height, avctx->height); allocSurf.bufferFmt = ctx->surfaces[idx].format; nv_status = p_nvenc->nvEncCreateInputBuffer(ctx->nvencoder, &allocSurf); @@ -1926,7 +1929,7 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame) NV_ENC_RECONFIGURE_PARAMS params = { 0 }; int needs_reconfig = 0; int needs_encode_config = 0; - int reconfig_bitrate = 0, reconfig_dar = 0; + int reconfig_bitrate = 0, reconfig_dar = 0, reconfig_res = 0; int dw, dh; params.version = NV_ENC_RECONFIGURE_PARAMS_VER; @@ -1986,6 +1989,24 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame) } } + if (ctx->support_dyn_res && ctx->init_encode_params.maxEncodeWidth && ctx->init_encode_params.maxEncodeHeight) { + if (params.reInitEncodeParams.encodeWidth != avctx->width || params.reInitEncodeParams.encodeHeight != avctx->height) { + av_log(avctx, AV_LOG_VERBOSE, + "resolution change: %d x %d -> %d x %d\n", + params.reInitEncodeParams.encodeWidth, + params.reInitEncodeParams.encodeHeight, + (uint32_t)avctx->width, + (uint32_t)avctx->height); + + params.reInitEncodeParams.encodeWidth = avctx->width; + params.reInitEncodeParams.encodeHeight = avctx->height; + params.forceIDR = 1; + + needs_reconfig = 1; + reconfig_res = 1; + } + } + if (!needs_encode_config) params.reInitEncodeParams.encodeConfig = NULL; @@ -2005,6 +2026,10 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame) ctx->encode_config.rcParams.vbvBufferSize = params.reInitEncodeParams.encodeConfig->rcParams.vbvBufferSize; } + if (reconfig_res) { + ctx->init_encode_params.encodeWidth = params.reInitEncodeParams.encodeWidth; + ctx->init_encode_params.encodeHeight = params.reInitEncodeParams.encodeHeight; + } } } } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index ddd6168409..30a3aa6f6f 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -158,6 +158,7 @@ typedef struct NvencContext int first_packet_output; int support_dyn_bitrate; + int support_dyn_res; void *nvencoder; @@ -192,6 +193,8 @@ typedef struct NvencContext int coder; int b_ref_mode; int a53_cc; + int max_width; + int max_height; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index a6623f5f35..9c9a0c7b8d 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -138,6 +138,10 @@ static const AVOption options[] = { { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" }, #endif { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, + { "max_width", "Maximum encode width for dynamic resolution encoding", + OFFSET(max_width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, VE }, + { "max_height", "Maximum encode height for dynamic resolution encoding", + OFFSET(max_height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, VE }, { NULL } }; diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index d567d960ba..49cb526740 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -127,6 +127,10 @@ static const AVOption options[] = { { "each", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "b_ref_mode" }, { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" }, #endif + { "max_width", "Maximum encode width for dynamic resolution encoding", + OFFSET(max_width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, VE }, + { "max_height", "Maximum encode height for dynamic resolution encoding", + OFFSET(max_height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, VE }, { NULL } };