From: "Xiang, Haihao" <haihao.xiang-at-intel.com@ffmpeg.org> To: "ffmpeg-devel@ffmpeg.org" <ffmpeg-devel@ffmpeg.org> Cc: "Wu, Tong1" <tong1.wu@intel.com>, "Chen, Wenbin" <wenbin.chen@intel.com> Subject: Re: [FFmpeg-devel] [PATCH] avcodec/qsvenc: make QSV encoder encode VAAPI and D3D11 frames directly Date: Wed, 8 Jun 2022 08:41:30 +0000 Message-ID: <078794290ef4b70ba19dfd436313a58c2ab8bdff.camel@intel.com> (raw) In-Reply-To: <DM8P223MB0365F58F8EBBB9B9A6234ADABAA49@DM8P223MB0365.NAMP223.PROD.OUTLOOK.COM> On Wed, 2022-06-08 at 05:08 +0000, Soft Works wrote: > > -----Original Message----- > > From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Tong Wu > > Sent: Tuesday, June 7, 2022 11:22 AM > > To: ffmpeg-devel@ffmpeg.org > > Cc: Tong Wu <tong1.wu@intel.com>; Wenbin Chen <wenbin.chen@intel.com> > > Subject: [FFmpeg-devel] [PATCH] avcodec/qsvenc: make QSV encoder encode > > VAAPI > > and D3D11 frames directly > > > > QSV encoder is able to encode frames with VAAPI or D3D11 pixel format > > directly. This patch adds support for qsv encoder to accept VAAPI and > > D3D11 pixel formats as input. > > > > Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> > > Signed-off-by: Tong Wu <tong1.wu@intel.com> > > --- > > libavcodec/qsvenc.c | 59 ++++++++++++++++++++++++++++++++++----- > > libavcodec/qsvenc_h264.c | 2 ++ > > libavcodec/qsvenc_hevc.c | 2 ++ > > libavcodec/qsvenc_jpeg.c | 2 ++ > > libavcodec/qsvenc_mpeg2.c | 2 ++ > > libavcodec/qsvenc_vp9.c | 2 ++ > > 6 files changed, 62 insertions(+), 7 deletions(-) > > > > diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c > > index 2b3b06767d..132d9ba93b 100644 > > --- a/libavcodec/qsvenc.c > > +++ b/libavcodec/qsvenc.c > > @@ -524,7 +524,9 @@ static int check_enc_param(AVCodecContext *avctx, > > QSVEncContext *q) > > > > static int init_video_param_jpeg(AVCodecContext *avctx, QSVEncContext *q) > > { > > - enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ? > > + enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV || > > + avctx->pix_fmt == AV_PIX_FMT_VAAPI || > > + avctx->pix_fmt == AV_PIX_FMT_D3D11 ? > > avctx->sw_pix_fmt : avctx->pix_fmt; > > const AVPixFmtDescriptor *desc; > > int ret; > > @@ -591,7 +593,9 @@ static int init_video_param_jpeg(AVCodecContext *avctx, > > QSVEncContext *q) > > > > static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) > > { > > - enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV ? > > + enum AVPixelFormat sw_format = avctx->pix_fmt == AV_PIX_FMT_QSV || > > + avctx->pix_fmt == AV_PIX_FMT_VAAPI || > > + avctx->pix_fmt == AV_PIX_FMT_D3D11 ? > > avctx->sw_pix_fmt : avctx->pix_fmt; > > const AVPixFmtDescriptor *desc; > > float quant; > > @@ -1247,7 +1251,31 @@ int ff_qsv_enc_init(AVCodecContext *avctx, > > QSVEncContext *q) > > > > if (avctx->hw_frames_ctx) { > > AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx- > > > hw_frames_ctx->data; > > > > - AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; > > + AVQSVFramesContext *frames_hwctx = NULL; > > + > > + if (frames_ctx->format == AV_PIX_FMT_VAAPI || frames_ctx->format == > > AV_PIX_FMT_D3D11) { > > + AVBufferRef *derive_device_ref = NULL; > > + AVBufferRef *derive_frames_ref = NULL; > > + ret = av_hwdevice_ctx_create_derived(&derive_device_ref, > > + AV_HWDEVICE_TYPE_QSV, > > frames_ctx->device_ref, 0); > > + if (ret < 0) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to derive QSV device > > context: %d.\n", ret); > > + return ret; > > + } > > + ret = av_hwframe_ctx_create_derived(&derive_frames_ref, > > + AV_PIX_FMT_QSV, > > derive_device_ref, avctx->hw_frames_ctx, 0); > > + if (ret < 0) { > > + av_log(avctx, AV_LOG_ERROR, "Failed to derive QSV frames > > context: %d.\n", ret); > > + av_buffer_unref(&derive_device_ref); > > + return ret; > > + } > > + av_buffer_unref(&avctx->hw_device_ctx); > > + avctx->hw_device_ctx = derive_device_ref; > > + av_buffer_unref(&avctx->hw_frames_ctx); > > + avctx->hw_frames_ctx = derive_frames_ref; > > + frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; > > + } > > + frames_hwctx = frames_ctx->hwctx; > > > > if (!iopattern) { > > if (frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME) > > @@ -1437,10 +1465,25 @@ static int submit_frame(QSVEncContext *q, const > > AVFrame *frame, > > if (ret < 0) > > return ret; > > > > - if (frame->format == AV_PIX_FMT_QSV) { > > - ret = av_frame_ref(qf->frame, frame); > > - if (ret < 0) > > - return ret; > > + if (frame->format == AV_PIX_FMT_QSV || frame->format == > > AV_PIX_FMT_VAAPI > > > > frame->format == AV_PIX_FMT_D3D11) { > > > > + if (frame->format == AV_PIX_FMT_QSV) { > > + ret = av_frame_ref(qf->frame, frame); > > + if (ret < 0) > > + return ret; > > + } else { > > + qf->frame->format = AV_PIX_FMT_QSV; > > + qf->frame->hw_frames_ctx = av_buffer_ref(q->avctx- > > > hw_frames_ctx); > > > > + if (!qf->frame->hw_frames_ctx) > > + return AVERROR(ENOMEM); > > + ret = av_hwframe_map(qf->frame, frame, 0); > > + if (ret < 0) { > > + av_log(q->avctx, AV_LOG_ERROR, "Failed to map to QSV > > frames\n"); > > + return ret; > > + } > > + ret = av_frame_copy_props(qf->frame, frame); > > + if (ret < 0) > > + return ret; > > + } > > > > qf->surface = *(mfxFrameSurface1*)qf->frame->data[3]; > > > > @@ -1735,6 +1778,8 @@ int ff_qsv_enc_close(AVCodecContext *avctx, > > QSVEncContext *q) > > > > const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[] = { > > HW_CONFIG_ENCODER_FRAMES(QSV, QSV), > > + HW_CONFIG_ENCODER_FRAMES(VAAPI,VAAPI), > > + HW_CONFIG_ENCODER_FRAMES(D3D11,D3D11VA), > > HW_CONFIG_ENCODER_DEVICE(NV12, QSV), > > HW_CONFIG_ENCODER_DEVICE(P010, QSV), > > NULL, > > diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c > > index cf77ea575b..93ba8d8ded 100644 > > --- a/libavcodec/qsvenc_h264.c > > +++ b/libavcodec/qsvenc_h264.c > > @@ -196,6 +196,8 @@ const FFCodec ff_h264_qsv_encoder = { > > .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, > > AV_PIX_FMT_P010, > > AV_PIX_FMT_QSV, > > + AV_PIX_FMT_VAAPI, > > + AV_PIX_FMT_D3D11, > > AV_PIX_FMT_NONE }, > > .p.priv_class = &class, > > .defaults = qsv_enc_defaults, > > diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c > > index a6bf39c148..63b6ad9150 100644 > > --- a/libavcodec/qsvenc_hevc.c > > +++ b/libavcodec/qsvenc_hevc.c > > @@ -309,6 +309,8 @@ const FFCodec ff_hevc_qsv_encoder = { > > AV_PIX_FMT_YUYV422, > > AV_PIX_FMT_Y210, > > AV_PIX_FMT_QSV, > > + AV_PIX_FMT_VAAPI, > > + AV_PIX_FMT_D3D11, > > AV_PIX_FMT_BGRA, > > AV_PIX_FMT_X2RGB10, > > AV_PIX_FMT_NONE }, > > diff --git a/libavcodec/qsvenc_jpeg.c b/libavcodec/qsvenc_jpeg.c > > index 825eb8dc06..5b7611bb85 100644 > > --- a/libavcodec/qsvenc_jpeg.c > > +++ b/libavcodec/qsvenc_jpeg.c > > @@ -91,6 +91,8 @@ const FFCodec ff_mjpeg_qsv_encoder = { > > .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, > > .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, > > AV_PIX_FMT_QSV, > > + AV_PIX_FMT_VAAPI, > > + AV_PIX_FMT_D3D11, > > AV_PIX_FMT_NONE }, > > .p.priv_class = &class, > > .defaults = qsv_enc_defaults, > > diff --git a/libavcodec/qsvenc_mpeg2.c b/libavcodec/qsvenc_mpeg2.c > > index 5cb12a2582..cba4001ee1 100644 > > --- a/libavcodec/qsvenc_mpeg2.c > > +++ b/libavcodec/qsvenc_mpeg2.c > > @@ -105,6 +105,8 @@ const FFCodec ff_mpeg2_qsv_encoder = { > > .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, > > .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, > > AV_PIX_FMT_QSV, > > + AV_PIX_FMT_VAAPI, > > + AV_PIX_FMT_D3D11, > > AV_PIX_FMT_NONE }, > > .p.priv_class = &class, > > .defaults = qsv_enc_defaults, > > diff --git a/libavcodec/qsvenc_vp9.c b/libavcodec/qsvenc_vp9.c > > index 4b2a6ce77f..2825b98a4a 100644 > > --- a/libavcodec/qsvenc_vp9.c > > +++ b/libavcodec/qsvenc_vp9.c > > @@ -115,6 +115,8 @@ const FFCodec ff_vp9_qsv_encoder = { > > .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12, > > AV_PIX_FMT_P010, > > AV_PIX_FMT_QSV, > > + AV_PIX_FMT_VAAPI, > > + AV_PIX_FMT_D3D11, > > AV_PIX_FMT_NONE }, > > .p.priv_class = &class, > > .defaults = qsv_enc_defaults, > > -- > > 2.35.1.windows.2 > > Hi, > > thanks for submitting this patch. Though, I'm afraid, but this > > - fundamentally contradicts the logic of ffmpeg's handling of hw acceleration, > hw device and hw frames contexts > - adds code to an encoder, doing things an encoder is not supposed to do- qsv > encoders and decoders have their own context => QSV nvdec and nvenc have CUDA but nvenc can also support D3D11va, it sounds make sense for me to support D3D11va/vaapi in qsvenc too as d3d11va/vaapi are used internally in MediaSDK. > - is not safe/guaranteed to work always > there are different requirements for QSV than for other other cases > like VAAPI - for example: QSV requires a fixed-size frame pool > and encoders often need a larger frame pool than VAAPI > Encoders in MediaSDK don't need a fixed pool, probably we may relax this limitation in QSV. Thanks Haihao > > My personal opinion on such kind of automatic handling is this: > > when you are not able to build a command line in a way that you exactly > know at each stage of the transcoding pipeline in which hw (or sw) context > it will be executed, then you might be lost anyway - in most cases :-) > > When you really want to achieve that kind of behavior, then it would be > a better idea to create a mechanism for "auto-insertion" of hwmap > filters for such cases. > I don't think that such behavior should be active by default though, as > it would most likely create more non-understood failures than convenience > moments for not having to type ,hwmap=derive_device=qsv > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-06-08 8:41 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-06-07 9:22 Tong Wu 2022-06-07 9:33 ` Anton Khirnov 2022-06-08 4:47 ` Wu, Tong1 2022-06-13 9:07 ` Anton Khirnov 2022-06-15 2:54 ` Wu, Tong1 2022-06-08 5:08 ` Soft Works 2022-06-08 8:41 ` Xiang, Haihao [this message] 2022-06-08 11:13 ` Soft Works 2022-06-09 6:47 ` Xiang, Haihao 2022-06-10 23:54 ` Soft Works 2022-06-15 2:48 ` Wu, Tong1
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=078794290ef4b70ba19dfd436313a58c2ab8bdff.camel@intel.com \ --to=haihao.xiang-at-intel.com@ffmpeg.org \ --cc=ffmpeg-devel@ffmpeg.org \ --cc=tong1.wu@intel.com \ --cc=wenbin.chen@intel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git