diff options
author | Haihao Xiang <haihao.xiang@intel.com> | 2021-08-11 14:01:54 +0800 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2021-08-11 13:45:36 -0300 |
commit | ecee3b07cde23e05bcc6b4eaa55d860b62dbd2dc (patch) | |
tree | a7654ef7c9328b861fb97c706c4c13d1f86a8ae0 /libavcodec/qsvdec.c | |
parent | 35b1f46d7930b052d8accb63ccf0993451ae36f2 (diff) | |
download | ffmpeg-ecee3b07cde23e05bcc6b4eaa55d860b62dbd2dc.tar.gz |
qsvdec: add support for HW_DEVICE_CTX method
This allows user set hw_device_ctx instead of hw_frames_ctx for QSV
decoders, hence we may remove the ad-hoc libmfx setup code from FFmpeg.
"-hwaccel_output_format format" is applied to QSV decoders after
removing the ad-hoc libmfx code. In order to keep compatibility with old
commandlines, the default format is set to AV_PIX_FMT_QSV, but this
behavior will be removed in the future. Please set "-hwaccel_output_format qsv"
explicitly if AV_PIX_FMT_QSV is expected.
The normal device stuff works for QSV decoders now, user may use
"-init_hw_device args" to initialise device and "-hwaccel_device
devicename" to select a device for QSV decoders.
"-qsv_device device" which was added for workarounding device selection
in the ad-hoc libmfx code still works
For example:
$> ffmpeg -init_hw_device qsv=qsv:hw_any,child_device=/dev/dri/card0
-hwaccel qsv -c:v h264_qsv -i input.h264 -f null -
/dev/dri/renderD128 is actually open for h264_qsv decoder in the above
command without this patch. After applying this patch, /dev/dri/card0
is used.
$> ffmpeg -init_hw_device vaapi=va:/dev/dri/card0 -init_hw_device
qsv=hw@va -hwaccel_device hw -hwaccel qsv -c:v h264_qsv -i input.h264
-f null -
device hw of type qsv is not usable in the above command without this
patch. After applying this patch, this command works as expected.
Reviewed-by: Soft Works <softworkz@hotmail.com>
Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec/qsvdec.c')
-rw-r--r-- | libavcodec/qsvdec.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 19a6a776db..8bce9f2cf0 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -99,7 +99,7 @@ static const AVCodecHWConfigInternal *const qsv_hw_configs[] = { .public = { .pix_fmt = AV_PIX_FMT_QSV, .methods = AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX | - AV_CODEC_HW_CONFIG_METHOD_AD_HOC, + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX, .device_type = AV_HWDEVICE_TYPE_QSV, }, .hwaccel = NULL, @@ -248,6 +248,35 @@ static int qsv_decode_preinit(AVCodecContext *avctx, QSVContext *q, enum AVPixel q->nb_ext_buffers = user_ctx->nb_ext_buffers; } + if (avctx->hw_device_ctx && !avctx->hw_frames_ctx && ret == AV_PIX_FMT_QSV) { + AVHWFramesContext *hwframes_ctx; + AVQSVFramesContext *frames_hwctx; + + avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx); + + if (!avctx->hw_frames_ctx) { + av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n"); + return AVERROR(ENOMEM); + } + + hwframes_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; + frames_hwctx = hwframes_ctx->hwctx; + hwframes_ctx->width = FFALIGN(avctx->coded_width, 32); + hwframes_ctx->height = FFALIGN(avctx->coded_height, 32); + hwframes_ctx->format = AV_PIX_FMT_QSV; + hwframes_ctx->sw_format = avctx->sw_pix_fmt; + hwframes_ctx->initial_pool_size = 64 + avctx->extra_hw_frames; + frames_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + + ret = av_hwframe_ctx_init(avctx->hw_frames_ctx); + + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error initializing a QSV frame pool\n"); + av_buffer_unref(&avctx->hw_frames_ctx); + return ret; + } + } + if (avctx->hw_frames_ctx) { AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx; |