summaryrefslogtreecommitdiff
path: root/libavcodec/qsvdec.c
diff options
context:
space:
mode:
authorHaihao Xiang <haihao.xiang@intel.com>2021-08-11 14:01:54 +0800
committerJames Almer <jamrial@gmail.com>2021-08-11 13:45:36 -0300
commitecee3b07cde23e05bcc6b4eaa55d860b62dbd2dc (patch)
treea7654ef7c9328b861fb97c706c4c13d1f86a8ae0 /libavcodec/qsvdec.c
parent35b1f46d7930b052d8accb63ccf0993451ae36f2 (diff)
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.c31
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;