diff options
author | Philip Langdale <philipl@overt.org> | 2022-04-03 20:12:50 -0700 |
---|---|---|
committer | Philip Langdale <github.philipl@overt.org> | 2022-09-21 09:39:34 -0700 |
commit | f221666ade9a60195a37d809973fbc18391306ed (patch) | |
tree | 787e48c1ba96a02ec5d11644352fe2fa442b1b2b /video/mp_image_pool.c | |
parent | 7b84e6fa8988f31e297cbc3adcd8a81e18e63bc8 (diff) | |
download | mpv-f221666ade9a60195a37d809973fbc18391306ed.tar.bz2 mpv-f221666ade9a60195a37d809973fbc18391306ed.tar.xz |
f_hwtransfer: mp_image_pool: support HW -> HW mapping
Certain combinations of hardware formats require the use of hwmap to
transfer frames between the formats, rather than hwupload, which will
fail if attempted.
To keep the usage of vf_format for HW -> HW transfers as intuitive as
possible, we should detect these cases and do the map operation instead
of uploading.
For now, the relevant cases are moving between VAAPI and Vulkan, and
VAAPI and DRM Prime, in both directions. I have introduced the IMGFMT
entry for Vulkan here so that I can put in the complete mapping table.
It's actually not useless, as you can map to Vulkan, use a Vulkan
filter and then map back to VAAPI for display output.
Diffstat (limited to 'video/mp_image_pool.c')
-rw-r--r-- | video/mp_image_pool.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/video/mp_image_pool.c b/video/mp_image_pool.c index 2a4a8940c0..d80c65d3b5 100644 --- a/video/mp_image_pool.c +++ b/video/mp_image_pool.c @@ -426,3 +426,30 @@ struct mp_image *mp_av_pool_image_hw_upload(struct AVBufferRef *hw_frames_ctx, mp_image_copy_attributes(dst, src); return dst; } + +struct mp_image *mp_av_pool_image_hw_map(struct AVBufferRef *hw_frames_ctx, + struct mp_image *src) +{ + AVFrame *dst_frame = av_frame_alloc(); + if (!dst_frame) + return NULL; + + dst_frame->format = ((AVHWFramesContext*)hw_frames_ctx->data)->format; + dst_frame->hw_frames_ctx = av_buffer_ref(hw_frames_ctx); + + AVFrame *src_frame = mp_image_to_av_frame(src); + if (av_hwframe_map(dst_frame, src_frame, 0) < 0) { + av_frame_free(&src_frame); + av_frame_free(&dst_frame); + return NULL; + } + av_frame_free(&src_frame); + + struct mp_image *dst = mp_image_from_av_frame(dst_frame); + av_frame_free(&dst_frame); + if (!dst) + return NULL; + + mp_image_copy_attributes(dst, src); + return dst; +} |