From 1ff6a1c8c7eae341a4052b115083005663c44503 Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 16 Oct 2017 16:56:24 +0200 Subject: video: make previously added hwdec params mechanism more generic The mechanism introduced in b135af6842bf assumed AVHWFramesContext would be enough. Apparently it's not - the intended use with Rockchip (not Rokchip btw.) requires accessing actual frame data in order to access the AVDRMFrameDescriptor struct. Just pass the entire mp_image to the new function. This is more flexible, although it slightly worries me that it will be less reusable for things which require setting up mp_image_params before any real frames are processed (such as filters). --- video/decode/d3d.c | 9 +++++---- video/hwdec.h | 11 ++++++----- video/mp_image.c | 18 +++++++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/video/decode/d3d.c b/video/decode/d3d.c index 0a44c0f507..cb323f9b01 100644 --- a/video/decode/d3d.c +++ b/video/decode/d3d.c @@ -138,12 +138,13 @@ AVBufferRef *d3d11_wrap_device_ref(ID3D11Device *device) return device_ref; } -static void d3d11_complete_image_params(struct AVHWFramesContext *hw_frames, - struct mp_image_params *p) +static void d3d11_complete_image_params(struct mp_image *img) { + AVHWFramesContext *hw_frames = (void *)img->hwctx->data; + // According to hwcontex_d3d11va.h, this means DXGI_FORMAT_420_OPAQUE. - p->hw_flags = hw_frames->sw_format == AV_PIX_FMT_YUV420P - ? MP_IMAGE_HW_FLAG_OPAQUE : 0; + img->params.hw_flags = hw_frames->sw_format == AV_PIX_FMT_YUV420P + ? MP_IMAGE_HW_FLAG_OPAQUE : 0; } const struct hwcontext_fns hwcontext_fns_d3d11 = { diff --git a/video/hwdec.h b/video/hwdec.h index 4376d47a14..d65db3bc1d 100644 --- a/video/hwdec.h +++ b/video/hwdec.h @@ -121,11 +121,12 @@ struct mp_image_params; // For now, all entries are strictly optional. struct hwcontext_fns { int av_hwdevice_type; - // Set any mp_image_params fields that can not be set in generic code. - // (Generic code sets width, height, hw_subfmt, etc., but some very specific - // flags or such might require specific code for some hwcontexts.) - void (*complete_image_params)(struct AVHWFramesContext *hw_frames, - struct mp_image_params *p); + // Set any mp_image fields that require hwcontext specific code, such as + // fields or flags not present in AVFrame or AVHWFramesContext in a + // portable way. This is called directly after img is converted from an + // AVFrame, with all other fields already set. img.hwctx will be set, and + // use the correct AV_HWDEVICE_TYPE_. + void (*complete_image_params)(struct mp_image *img); }; // The parameter is of type enum AVHWDeviceType (as in int to avoid extensive diff --git a/video/mp_image.c b/video/mp_image.c index 18d700df15..63670a6726 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -855,15 +855,6 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src) if (src->repeat_pict == 1) dst->fields |= MP_IMGFIELD_REPEAT_FIRST; - if (src->hw_frames_ctx) { - AVHWFramesContext *fctx = (void *)src->hw_frames_ctx->data; - dst->params.hw_subfmt = pixfmt2imgfmt(fctx->sw_format); - const struct hwcontext_fns *fns = - hwdec_get_hwcontext_fns(fctx->device_ctx->type); - if (fns && fns->complete_image_params) - fns->complete_image_params(fctx, &dst->params); - } - dst->params.color = (struct mp_colorspace){ .space = avcol_spc_to_mp_csp(src->colorspace), .levels = avcol_range_to_mp_csp_levels(src->color_range), @@ -888,6 +879,15 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src) dst->icc_profile = av_buffer_ref(sd->buf); #endif + if (dst->hwctx) { + AVHWFramesContext *fctx = (void *)dst->hwctx->data; + dst->params.hw_subfmt = pixfmt2imgfmt(fctx->sw_format); + const struct hwcontext_fns *fns = + hwdec_get_hwcontext_fns(fctx->device_ctx->type); + if (fns && fns->complete_image_params) + fns->complete_image_params(dst); + } + return mp_image_new_ref(dst); } -- cgit v1.2.3