summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filters/f_hwtransfer.c47
-rw-r--r--filters/f_lavfi.c4
-rw-r--r--test/ref/img_formats.txt2
-rw-r--r--video/fmt-conversion.c1
-rw-r--r--video/img_format.h1
-rw-r--r--video/mp_image_pool.c27
-rw-r--r--video/mp_image_pool.h2
7 files changed, 80 insertions, 4 deletions
diff --git a/filters/f_hwtransfer.c b/filters/f_hwtransfer.c
index 649d28497c..9640f406ad 100644
--- a/filters/f_hwtransfer.c
+++ b/filters/f_hwtransfer.c
@@ -35,6 +35,10 @@ struct priv {
int *fmt_upload_index;
int *fmt_upload_num;
+ // List of source formats that require hwmap instead of hwupload.
+ int *map_fmts;
+ int num_map_fmts;
+
struct mp_hwupload public;
};
@@ -58,6 +62,25 @@ static const struct ffmpeg_and_other_bugs shitlist[] = {
{0}
};
+struct hwmap_pairs {
+ int first_fmt;
+ int second_fmt;
+};
+
+// We cannot discover which pairs of hardware formats need to use hwmap to
+// convert between the formats, so we need a lookup table.
+static const struct hwmap_pairs hwmap_pairs[] = {
+ {
+ .first_fmt = IMGFMT_VAAPI,
+ .second_fmt = IMGFMT_VULKAN,
+ },
+ {
+ .first_fmt = IMGFMT_DRMPRIME,
+ .second_fmt = IMGFMT_VAAPI,
+ },
+ {0}
+};
+
static bool select_format(struct priv *p, int input_fmt,
int *out_sw_fmt, int *out_upload_fmt)
{
@@ -183,7 +206,19 @@ static void process(struct mp_filter *f)
goto error;
}
- struct mp_image *dst = mp_av_pool_image_hw_upload(p->hw_pool, src);
+ struct mp_image *dst;
+ bool map_images = false;
+ for (int n = 0; n < p->num_map_fmts; n++) {
+ if (src->imgfmt == p->map_fmts[n]) {
+ map_images = true;
+ break;
+ }
+ }
+
+ if (map_images)
+ dst = mp_av_pool_image_hw_map(p->hw_pool, src);
+ else
+ dst = mp_av_pool_image_hw_upload(p->hw_pool, src);
if (!dst)
goto error;
@@ -296,6 +331,16 @@ static bool probe_formats(struct mp_hwupload *u, int hw_imgfmt)
}
}
+ for (int n = 0; hwmap_pairs[n].first_fmt; n++) {
+ if (hwmap_pairs[n].first_fmt == hw_imgfmt) {
+ MP_TARRAY_APPEND(p, p->map_fmts, p->num_map_fmts,
+ hwmap_pairs[n].second_fmt);
+ } else if (hwmap_pairs[n].second_fmt == hw_imgfmt) {
+ MP_TARRAY_APPEND(p, p->map_fmts, p->num_map_fmts,
+ hwmap_pairs[n].first_fmt);
+ }
+ }
+
for (int n = 0; cstr->valid_sw_formats &&
cstr->valid_sw_formats[n] != AV_PIX_FMT_NONE; n++)
{
diff --git a/filters/f_lavfi.c b/filters/f_lavfi.c
index cbb3066430..41a3ea4eac 100644
--- a/filters/f_lavfi.c
+++ b/filters/f_lavfi.c
@@ -561,8 +561,8 @@ static void init_graph(struct lavfi *c)
hwdec_ctx = hwdec_devices_get_first(info->hwdec_devs);
}
if (hwdec_ctx && hwdec_ctx->av_device_ref) {
- MP_VERBOSE(c, "Configuring hwdec_interop=%s for filters\n",
- hwdec_ctx->driver_name);
+ MP_VERBOSE(c, "Configuring hwdec_interop=%s for filter graph: %s\n",
+ hwdec_ctx->driver_name, c->graph_string);
for (int n = 0; n < c->graph->nb_filters; n++) {
AVFilterContext *filter = c->graph->filters[n];
filter->hw_device_ctx =
diff --git a/test/ref/img_formats.txt b/test/ref/img_formats.txt
index 2b1cca1522..cd84963b6a 100644
--- a/test/ref/img_formats.txt
+++ b/test/ref/img_formats.txt
@@ -1239,7 +1239,7 @@ videotoolbox: ctype=unknown
planes=0, chroma=0:0 align=1:1
{}
AVD: name=videotoolbox_vld chroma=0:0 flags=0x8 [hw]
-vulkan: [GENERIC] ctype=unknown
+vulkan: ctype=unknown
Basic desc: [le][be][hw]
planes=0, chroma=0:0 align=1:1
{}
diff --git a/video/fmt-conversion.c b/video/fmt-conversion.c
index 5194221d50..d200a5db31 100644
--- a/video/fmt-conversion.c
+++ b/video/fmt-conversion.c
@@ -67,6 +67,7 @@ static const struct {
{IMGFMT_CUDA, AV_PIX_FMT_CUDA},
{IMGFMT_P010, AV_PIX_FMT_P010},
{IMGFMT_DRMPRIME, AV_PIX_FMT_DRM_PRIME},
+ {IMGFMT_VULKAN, AV_PIX_FMT_VULKAN},
{0, AV_PIX_FMT_NONE}
};
diff --git a/video/img_format.h b/video/img_format.h
index ebdbd66e29..7559c8c172 100644
--- a/video/img_format.h
+++ b/video/img_format.h
@@ -319,6 +319,7 @@ enum mp_imgfmt {
IMGFMT_VDPAU_OUTPUT, // VdpOutputSurface
IMGFMT_VAAPI,
IMGFMT_VIDEOTOOLBOX, // CVPixelBufferRef
+ IMGFMT_VULKAN, // VKImage
// Generic pass-through of AV_PIX_FMT_*. Used for formats which don't have
// a corresponding IMGFMT_ value.
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;
+}
diff --git a/video/mp_image_pool.h b/video/mp_image_pool.h
index 3c7e6221d1..ab9065e6e9 100644
--- a/video/mp_image_pool.h
+++ b/video/mp_image_pool.h
@@ -41,4 +41,6 @@ bool mp_update_av_hw_frames_pool(struct AVBufferRef **hw_frames_ctx,
struct mp_image *mp_av_pool_image_hw_upload(struct AVBufferRef *hw_frames_ctx,
struct mp_image *src);
+struct mp_image *mp_av_pool_image_hw_map(struct AVBufferRef *hw_frames_ctx,
+ struct mp_image *src);
#endif