From patchwork Wed Oct 9 13:28:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rogozhkin, Dmitry V" X-Patchwork-Id: 15642 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 DE34244A401 for ; Thu, 10 Oct 2019 00:32:18 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id CBAAF6880F2; Thu, 10 Oct 2019 00:32:18 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5EED1688113 for ; Thu, 10 Oct 2019 00:32:12 +0300 (EEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Oct 2019 14:32:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,277,1566889200"; d="scan'208";a="345491980" Received: from dvrscl.jf.intel.com ([10.54.72.26]) by orsmga004.jf.intel.com with ESMTP; 09 Oct 2019 14:32:10 -0700 From: Dmitry Rogozhkin To: ffmpeg-devel@ffmpeg.org Date: Wed, 9 Oct 2019 06:28:11 -0700 Message-Id: <1570627691-9464-2-git-send-email-dmitry.v.rogozhkin@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1570627691-9464-1-git-send-email-dmitry.v.rogozhkin@intel.com> References: <1570627691-9464-1-git-send-email-dmitry.v.rogozhkin@intel.com> Subject: [FFmpeg-devel] [PATCH] avcodec/qsv: polling free synchronization 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: Andrey Orlov MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Andrey Orlov synchronization by sync point after DEVICE_BUSY Fixes: CPU usage on AVC decode cases (18% -> 9%) --- libavcodec/qsv.c | 17 +++++++++++++++++ libavcodec/qsv_internal.h | 2 ++ libavcodec/qsvdec.c | 12 ++++++++---- libavcodec/qsvdec.h | 2 ++ libavcodec/qsvenc.c | 13 +++++++++---- libavcodec/qsvenc.h | 2 ++ 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index b00e427..4b5018b 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -32,6 +32,7 @@ #include "libavutil/hwcontext_qsv.h" #include "libavutil/imgutils.h" #include "libavutil/avassert.h" +#include "libavutil/time.h" #include "avcodec.h" #include "qsv_internal.h" @@ -852,3 +853,19 @@ int ff_qsv_close_internal_session(QSVSession *qs) #endif return 0; } + +void ff_qsv_handle_device_busy(mfxSession *session, mfxSyncPoint *sync, mfxStatus *ret, unsigned sleep) +{ + int sync_ret; + + if (*sync) { + sync_ret = MFXVideoCORE_SyncOperation(*session, *sync, MFX_INFINITE); + if (sync_ret == MFX_ERR_NONE) { + *sync = NULL; + } else { + *ret = MFX_ERR_ABORTED; + } + } else { + av_usleep(sleep); + } +} diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index 3755927..01c98cc 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -141,4 +141,6 @@ int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *session, int ff_qsv_find_surface_idx(QSVFramesContext *ctx, QSVFrame *frame); +void ff_qsv_handle_device_busy(mfxSession *session, mfxSyncPoint *sync, mfxStatus *ret, unsigned sleep); + #endif /* AVCODEC_QSV_INTERNAL_H */ diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index ae50239..aa83272 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -457,8 +457,12 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL, insurf, &outsurf, sync); + + if (ret == MFX_ERR_NONE) + q->last_dec_sync = *sync; + if (ret == MFX_WRN_DEVICE_BUSY) - av_usleep(500); + ff_qsv_handle_device_busy(&q->session, &q->last_dec_sync, &ret, 500); } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE); @@ -510,9 +514,9 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q, out_frame->queued = 0; if (avctx->pix_fmt != AV_PIX_FMT_QSV) { - do { - ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000); - } while (ret == MFX_WRN_IN_EXECUTION); + ret = MFXVideoCORE_SyncOperation(q->session, *sync, MFX_INFINITE); + if (ret < 0) + return ret; } av_freep(&sync); diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h index dec1f61..d27ea68 100644 --- a/libavcodec/qsvdec.h +++ b/libavcodec/qsvdec.h @@ -72,6 +72,8 @@ typedef struct QSVContext { mfxExtBuffer **ext_buffers; int nb_ext_buffers; + + mfxSyncPoint last_dec_sync; } QSVContext; extern const AVCodecHWConfigInternal *ff_qsv_hw_configs[]; diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index ba85d64..bd5dd75 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1368,8 +1368,13 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, do { ret = MFXVideoENCODE_EncodeFrameAsync(q->session, enc_ctrl, surf, bs, sync); + + if (ret == MFX_ERR_NONE) + q->last_enc_sync = *sync; + if (ret == MFX_WRN_DEVICE_BUSY) - av_usleep(500); + ff_qsv_handle_device_busy(&q->session, &q->last_enc_sync, &ret, 500); + } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_WRN_IN_EXECUTION); if (ret > 0) @@ -1435,9 +1440,9 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q, av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL); av_fifo_generic_read(q->async_fifo, &bs, sizeof(bs), NULL); - do { - ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000); - } while (ret == MFX_WRN_IN_EXECUTION); + ret = MFXVideoCORE_SyncOperation(q->session, *sync, MFX_INFINITE); + if (ret < 0) + return ret; new_pkt.dts = av_rescale_q(bs->DecodeTimeStamp, (AVRational){1, 90000}, avctx->time_base); new_pkt.pts = av_rescale_q(bs->TimeStamp, (AVRational){1, 90000}, avctx->time_base); diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index ec8b541..f1c22d7 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -185,6 +185,8 @@ typedef struct QSVEncContext { char *load_plugins; SetEncodeCtrlCB *set_encode_ctrl_cb; int forced_idr; + + mfxSyncPoint last_enc_sync; } QSVEncContext; int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);