From patchwork Mon Feb 13 09:03:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Chen, Wenbin" X-Patchwork-Id: 40379 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:5494:b0:bf:7b3a:fd32 with SMTP id i20csp3302069pzk; Mon, 13 Feb 2023 01:03:42 -0800 (PST) X-Google-Smtp-Source: AK7set/yFnWN4Ipv2MdAmopAz0hNfQM9Lyb3pvzHPo9iRYofDWmbxLcBsf5qMjCSQWfYLk1bFHBa X-Received: by 2002:a50:cd85:0:b0:4aa:a2de:d59d with SMTP id p5-20020a50cd85000000b004aaa2ded59dmr26441192edi.41.1676279022055; Mon, 13 Feb 2023 01:03:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676279022; cv=none; d=google.com; s=arc-20160816; b=D56XgyWh7B4HMfSRf5dkVuTylGo7xBvgj8iugNS1wmhoGIy0NZgY8+6vuuXw8IVV+3 xU/I3edRNQXOky4XqdgRXqjv3AmEpVKtyva2eh/d8WiLUICDIIoDg6MPmFDPFtEuIqOc hvfhkMCG08+XFkiV76c2X1wQtuDpufnSgYH4vjQfcH8hLD6E7BqvZkqcakP/9D7eTuWz AZ8xNtswR0gq9cy7bhLJq/iBzboo9WixpzMUXjpNccoFp+NM252xJJfYStw4LKo4+sJi 3SQAQVqGxcAkpZXh8LqXE0py51UcPn3VsWhybHgqxqUYXR+b4TLjlJA4HTaFlZlTp7KK mD6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=60wWSzctMejS+1EuFUZV6Dg3t0IUR26u8EJF+o+PQew=; b=Metwp81wrDkktILoyfrTKpEEJUs72ASdfURePMmaqlQUeJ54puAUZFqgqyzJk2ZKE7 rd5QT4PBh+zqeZ4avUHY7h02P15dOnVU8g5A5WfiKGFQU7n/NFR3sTCjm9pFYmuS2MkJ E8EZtU7vVgnGXETWBNqtK94ZLaF9c+NCkvmqelGcVCbeFNv/EAho2JdyKUaC6Of60TRi t3inxhjveYZGieiQnB5kcWhLlgGg3AseW6pXyoB2towddyFoCyOnt8HQOHIpeu4tTWOp tdaReCW7S1prhwdYewtogSL3MV0jwM83n+LDQXP/Ls60v+5zX12AE0qMgH6IeMLxr+OK Jx8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@intel.com header.s=Intel header.b=Aph5nl3A; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d5-20020a50ea85000000b004aaa505ac5fsi15291986edo.76.2023.02.13.01.03.41; Mon, 13 Feb 2023 01:03:42 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@intel.com header.s=Intel header.b=Aph5nl3A; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C809368BDFB; Mon, 13 Feb 2023 11:03:38 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E7F2068BC90 for ; Mon, 13 Feb 2023 11:03:30 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1676279016; x=1707815016; h=from:to:subject:date:message-id:mime-version: content-transfer-encoding; bh=5g/+o/T8xu1UHo8J4LiI/N0ikB5k0v2huMiws/kf5/g=; b=Aph5nl3AzMuraRl+t5wfhcnEuvQTavbDUolaZN1kRxQA/cK0BlH2nx4Q FNb++ugUhP4PHDiM1u8V39bJyVzvG6Qc/2y3CjoveD04YmX/vtwBR0jH8 kLd54RieU+dwQfibhq5f63tx5Ihtu6mdErb85hbJxxT9fGj6fjnXe6pU8 /OFUt4Um6VyhMHOgh6s/DIFt86iQEkaJ7nYNQdTEQKyEQKfd8hOoPoJ5Z rwcqSbTjdQPe8ZtAWU6OkQw99qwfQMbAwDQRU/vfSgw52biggBchx2UJr FSInPMXyFWPvDlwzTHHgHo3WBS3qTaCWWrkNW3JSxUNE7KyQW5dJ83gaq w==; X-IronPort-AV: E=McAfee;i="6500,9779,10619"; a="318870776" X-IronPort-AV: E=Sophos;i="5.97,293,1669104000"; d="scan'208";a="318870776" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Feb 2023 01:03:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10619"; a="792652089" X-IronPort-AV: E=Sophos;i="5.97,293,1669104000"; d="scan'208";a="792652089" Received: from wenbin-z390-aorus-ultra.sh.intel.com ([10.239.35.4]) by orsmga004.jf.intel.com with ESMTP; 13 Feb 2023 01:03:18 -0800 From: wenbin.chen-at-intel.com@ffmpeg.org To: ffmpeg-devel@ffmpeg.org Date: Mon, 13 Feb 2023 17:03:17 +0800 Message-Id: <20230213090317.557782-1-wenbin.chen@intel.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] libavcodec/qsvenc: Flush cached frames before reset encoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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" X-TUID: Uz1JNcwxb2Vl From: Wenbin Chen According to https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#configuration-change. Before calling MFXVideoENCODE_Reset, The application needs to retrieve any cached frames in the SDK encoder. A loop is added before MFXVideoENCODE_Reset to retrieve cached frames and add them to async_fifo, so that dynamic configuration works when async_depth > 1. Signed-off-by: Wenbin Chen --- libavcodec/qsvenc.c | 122 ++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 2f0e94a914..3951f40e7b 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1600,7 +1600,7 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q) q->param.AsyncDepth = q->async_depth; - q->async_fifo = av_fifo_alloc2(q->async_depth, sizeof(QSVPacket), 0); + q->async_fifo = av_fifo_alloc2(q->async_depth, sizeof(QSVPacket), AV_FIFO_FLAG_AUTO_GROW); if (!q->async_fifo) return AVERROR(ENOMEM); @@ -2296,58 +2296,6 @@ static int update_pic_timing_sei(AVCodecContext *avctx, QSVEncContext *q) return updated; } -static int update_parameters(AVCodecContext *avctx, QSVEncContext *q, - const AVFrame *frame) -{ - int needReset = 0, ret = 0; - - if (!frame || avctx->codec_id == AV_CODEC_ID_MJPEG) - return 0; - - needReset = update_qp(avctx, q); - needReset |= update_max_frame_size(avctx, q); - needReset |= update_gop_size(avctx, q); - needReset |= update_rir(avctx, q); - needReset |= update_low_delay_brc(avctx, q); - needReset |= update_frame_rate(avctx, q); - needReset |= update_bitrate(avctx, q); - needReset |= update_pic_timing_sei(avctx, q); - ret = update_min_max_qp(avctx, q); - if (ret < 0) - return ret; - needReset |= ret; - if (!needReset) - return 0; - - if (avctx->hwaccel_context) { - AVQSVContext *qsv = avctx->hwaccel_context; - int i, j; - q->param.ExtParam = q->extparam; - for (i = 0; i < qsv->nb_ext_buffers; i++) - q->param.ExtParam[i] = qsv->ext_buffers[i]; - q->param.NumExtParam = qsv->nb_ext_buffers; - - for (i = 0; i < q->nb_extparam_internal; i++) { - for (j = 0; j < qsv->nb_ext_buffers; j++) { - if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId) - break; - } - if (j < qsv->nb_ext_buffers) - continue; - q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i]; - } - } else { - q->param.ExtParam = q->extparam_internal; - q->param.NumExtParam = q->nb_extparam_internal; - } - av_log(avctx, AV_LOG_DEBUG, "Parameter change, call msdk reset.\n"); - ret = MFXVideoENCODE_Reset(q->session, &q->param); - if (ret < 0) - return ff_qsv_print_error(avctx, ret, "Error during resetting"); - - return 0; -} - static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, const AVFrame *frame) { @@ -2438,7 +2386,7 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, if (ret < 0) { ret = (ret == MFX_ERR_MORE_DATA) ? - 0 : ff_qsv_print_error(avctx, ret, "Error during encoding"); + AVERROR(EAGAIN) : ff_qsv_print_error(avctx, ret, "Error during encoding"); goto free; } @@ -2448,7 +2396,9 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, ret = 0; if (*pkt.sync) { - av_fifo_write(q->async_fifo, &pkt, 1); + ret = av_fifo_write(q->async_fifo, &pkt, 1); + if (ret < 0) + goto free; } else { free: av_freep(&pkt.sync); @@ -2466,6 +2416,66 @@ nomem: goto free; } +static int update_parameters(AVCodecContext *avctx, QSVEncContext *q, + const AVFrame *frame) +{ + int needReset = 0, ret = 0; + + if (!frame || avctx->codec_id == AV_CODEC_ID_MJPEG) + return 0; + + needReset = update_qp(avctx, q); + needReset |= update_max_frame_size(avctx, q); + needReset |= update_gop_size(avctx, q); + needReset |= update_rir(avctx, q); + needReset |= update_low_delay_brc(avctx, q); + needReset |= update_frame_rate(avctx, q); + needReset |= update_bitrate(avctx, q); + needReset |= update_pic_timing_sei(avctx, q); + ret = update_min_max_qp(avctx, q); + if (ret < 0) + return ret; + needReset |= ret; + if (!needReset) + return 0; + + if (avctx->hwaccel_context) { + AVQSVContext *qsv = avctx->hwaccel_context; + int i, j; + q->param.ExtParam = q->extparam; + for (i = 0; i < qsv->nb_ext_buffers; i++) + q->param.ExtParam[i] = qsv->ext_buffers[i]; + q->param.NumExtParam = qsv->nb_ext_buffers; + + for (i = 0; i < q->nb_extparam_internal; i++) { + for (j = 0; j < qsv->nb_ext_buffers; j++) { + if (qsv->ext_buffers[j]->BufferId == q->extparam_internal[i]->BufferId) + break; + } + if (j < qsv->nb_ext_buffers) + continue; + q->param.ExtParam[q->param.NumExtParam++] = q->extparam_internal[i]; + } + } else { + q->param.ExtParam = q->extparam_internal; + q->param.NumExtParam = q->nb_extparam_internal; + } + + // Flush codec before reset configuration. + while (ret != AVERROR(EAGAIN)) { + ret = encode_frame(avctx, q, NULL); + if (ret < 0 && ret != AVERROR(EAGAIN)) + return ret; + } + + av_log(avctx, AV_LOG_DEBUG, "Parameter change, call msdk reset.\n"); + ret = MFXVideoENCODE_Reset(q->session, &q->param); + if (ret < 0) + return ff_qsv_print_error(avctx, ret, "Error during resetting"); + + return 0; +} + int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, AVPacket *pkt, const AVFrame *frame, int *got_packet) { @@ -2476,7 +2486,7 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, return ret; ret = encode_frame(avctx, q, frame); - if (ret < 0) + if (ret < 0 && ret != AVERROR(EAGAIN)) return ret; if ((av_fifo_can_read(q->async_fifo) >= q->async_depth) ||