summaryrefslogtreecommitdiff
path: root/libavcodec/qsvdec.c
diff options
context:
space:
mode:
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;