diff options
Diffstat (limited to 'video')
-rw-r--r-- | video/decode/d3d.c | 20 | ||||
-rw-r--r-- | video/filter/vf_d3d11vpp.c | 1 | ||||
-rw-r--r-- | video/hwdec.c | 22 | ||||
-rw-r--r-- | video/hwdec.h | 18 | ||||
-rw-r--r-- | video/mp_image.c | 8 | ||||
-rw-r--r-- | video/mp_image.h | 6 |
6 files changed, 74 insertions, 1 deletions
diff --git a/video/decode/d3d.c b/video/decode/d3d.c index a5408f2133..0a44c0f507 100644 --- a/video/decode/d3d.c +++ b/video/decode/d3d.c @@ -111,7 +111,12 @@ void d3d_hwframes_refine(struct lavc_ctx *ctx, AVBufferRef *hw_frames_ctx) if (fctx->format == AV_PIX_FMT_D3D11) { AVD3D11VAFramesContext *hwctx = fctx->hwctx; - hwctx->BindFlags |= D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE; + hwctx->BindFlags |= D3D11_BIND_DECODER; + + // According to hwcontex_d3d11va.h, yuv420p means DXGI_FORMAT_420_OPAQUE, + // which has no shader support. + if (fctx->sw_format != AV_PIX_FMT_YUV420P) + hwctx->BindFlags |= D3D11_BIND_SHADER_RESOURCE; } } @@ -132,3 +137,16 @@ 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) +{ + // 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; +} + +const struct hwcontext_fns hwcontext_fns_d3d11 = { + .av_hwdevice_type = AV_HWDEVICE_TYPE_D3D11VA, + .complete_image_params = d3d11_complete_image_params, +}; diff --git a/video/filter/vf_d3d11vpp.c b/video/filter/vf_d3d11vpp.c index 44178a8622..cafa5df122 100644 --- a/video/filter/vf_d3d11vpp.c +++ b/video/filter/vf_d3d11vpp.c @@ -402,6 +402,7 @@ static int reconfig(struct vf_instance *vf, struct mp_image_params *in, p->out_shared = true; p->out_rgb = true; } + out->hw_flags = 0; p->require_filtering = in->hw_subfmt != out->hw_subfmt; diff --git a/video/hwdec.c b/video/hwdec.c index 371c368fa3..df0cf88839 100644 --- a/video/hwdec.c +++ b/video/hwdec.c @@ -1,6 +1,8 @@ #include <pthread.h> #include <assert.h> +#include "config.h" + #include "hwdec.h" struct mp_hwdec_devices { @@ -86,3 +88,23 @@ void *hwdec_devices_load(struct mp_hwdec_devices *devs, enum hwdec_type type) struct mp_hwdec_ctx *hwctx = hwdec_devices_get(devs, type); return hwctx ? hwctx->ctx : NULL; } + +#if HAVE_D3D_HWACCEL +extern const struct hwcontext_fns hwcontext_fns_d3d11; +#endif + +static const struct hwcontext_fns *const hwcontext_fns[] = { +#if HAVE_D3D_HWACCEL + &hwcontext_fns_d3d11, +#endif + NULL, +}; + +const struct hwcontext_fns *hwdec_get_hwcontext_fns(int av_hwdevice_type) +{ + for (int n = 0; hwcontext_fns[n]; n++) { + if (hwcontext_fns[n]->av_hwdevice_type == av_hwdevice_type) + return hwcontext_fns[n]; + } + return NULL; +} diff --git a/video/hwdec.h b/video/hwdec.h index 461ea6a3e6..4376d47a14 100644 --- a/video/hwdec.h +++ b/video/hwdec.h @@ -114,4 +114,22 @@ void hwdec_devices_request(struct mp_hwdec_devices *devs, enum hwdec_type type); // - then return the mp_hwdec_ctx.ctx field void *hwdec_devices_load(struct mp_hwdec_devices *devs, enum hwdec_type type); +struct AVHWFramesContext; +struct mp_image_params; + +// Per AV_HWDEVICE_TYPE_* functions, queryable via hwdec_get_hwcontext_fns(). +// 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); +}; + +// The parameter is of type enum AVHWDeviceType (as in int to avoid extensive +// recursive includes). May return NULL for unknown device types. +const struct hwcontext_fns *hwdec_get_hwcontext_fns(int av_hwdevice_type); + #endif diff --git a/video/mp_image.c b/video/mp_image.c index d2299bfcc2..3d755fd7b2 100644 --- a/video/mp_image.c +++ b/video/mp_image.c @@ -30,6 +30,7 @@ #include "config.h" #include "common/common.h" +#include "hwdec.h" #include "mp_image.h" #include "sws_utils.h" #include "fmt-conversion.h" @@ -617,6 +618,8 @@ char *mp_image_params_to_str_buf(char *b, size_t bs, mp_snprintf_cat(b, bs, " %s", mp_imgfmt_to_name(p->imgfmt)); if (p->hw_subfmt) mp_snprintf_cat(b, bs, "[%s]", mp_imgfmt_to_name(p->hw_subfmt)); + if (p->hw_flags) + mp_snprintf_cat(b, bs, "[0x%x]", p->hw_flags); mp_snprintf_cat(b, bs, " %s/%s/%s/%s", m_opt_choice_str(mp_csp_names, p->color.space), m_opt_choice_str(mp_csp_prim_names, p->color.primaries), @@ -688,6 +691,7 @@ bool mp_image_params_equal(const struct mp_image_params *p1, { return p1->imgfmt == p2->imgfmt && p1->hw_subfmt == p2->hw_subfmt && + p1->hw_flags == p2->hw_flags && p1->w == p2->w && p1->h == p2->h && p1->p_w == p2->p_w && p1->p_h == p2->p_h && mp_colorspace_equal(p1->color, p2->color) && @@ -847,6 +851,10 @@ static void mp_image_copy_fields_from_av_frame(struct mp_image *dst, 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){ diff --git a/video/mp_image.h b/video/mp_image.h index db6085cfc8..cf8436a36d 100644 --- a/video/mp_image.h +++ b/video/mp_image.h @@ -48,12 +48,18 @@ struct mp_spherical_params { float ref_angles[3]; // yaw/pitch/roll, refer to AVSphericalMapping }; +enum mp_image_hw_flags { + MP_IMAGE_HW_FLAG_OPAQUE = 1, // an opaque hw format is used - the exact + // format is subject to hwctx internals +}; + // Describes image parameters that usually stay constant. // New fields can be added in the future. Code changing the parameters should // usually copy the whole struct, so that fields added later will be preserved. struct mp_image_params { enum mp_imgfmt imgfmt; // pixel format enum mp_imgfmt hw_subfmt; // underlying format for some hwaccel pixfmts + unsigned hw_flags; // bit mask of mp_image_hw_flags int w, h; // image dimensions int p_w, p_h; // define pixel aspect ratio (undefined: 0/0) struct mp_colorspace color; |