summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-10-02 21:14:58 +0200
committerwm4 <wm4@nowhere>2019-10-02 21:14:58 +0200
commit49f9146fe4dfa6fb2e76e59b7e75a99707782dd9 (patch)
tree90f51a718bf4a180d7e1316d224bf988ae7e2c8c
parent61961d03f6aed7eb77eca34840e90342b86e92c9 (diff)
downloadmpv-49f9146fe4dfa6fb2e76e59b7e75a99707782dd9.tar.bz2
mpv-49f9146fe4dfa6fb2e76e59b7e75a99707782dd9.tar.xz
f_hwtransfer: add a mp_hwdownload filter
This just wraps the mp_image_hw_download() function as a filter and adds some minor caching/error logging. (Shame that it needs to much boilerplate, I guess.) Will be used by the following commit. Wrapping it as filter seemed more convenient than other choices.
-rw-r--r--filters/f_hwtransfer.c53
-rw-r--r--filters/f_hwtransfer.h9
2 files changed, 62 insertions, 0 deletions
diff --git a/filters/f_hwtransfer.c b/filters/f_hwtransfer.c
index 992dab71e7..0c62644ff3 100644
--- a/filters/f_hwtransfer.c
+++ b/filters/f_hwtransfer.c
@@ -298,3 +298,56 @@ error:
talloc_free(f);
return NULL;
}
+
+static void hwdownload_process(struct mp_filter *f)
+{
+ struct mp_hwdownload *d = f->priv;
+
+ if (!mp_pin_can_transfer_data(f->ppins[1], f->ppins[0]))
+ return;
+
+ struct mp_frame frame = mp_pin_out_read(f->ppins[0]);
+ if (frame.type != MP_FRAME_VIDEO)
+ goto passthrough;
+
+ struct mp_image *src = frame.data;
+ if (!src->hwctx)
+ goto passthrough;
+
+ struct mp_image *dst = mp_image_hw_download(src, d->pool);
+ if (!dst) {
+ MP_ERR(f, "Could not copy hardware frame to CPU memory.\n");
+ goto passthrough;
+ }
+
+ mp_frame_unref(&frame);
+ mp_pin_in_write(f->ppins[1], MAKE_FRAME(MP_FRAME_VIDEO, dst));
+ return;
+
+passthrough:
+ mp_pin_in_write(f->ppins[1], frame);
+ return;
+}
+
+static const struct mp_filter_info hwdownload_filter = {
+ .name = "hwdownload",
+ .priv_size = sizeof(struct mp_hwdownload),
+ .process = hwdownload_process,
+};
+
+struct mp_hwdownload *mp_hwdownload_create(struct mp_filter *parent)
+{
+ struct mp_filter *f = mp_filter_create(parent, &hwdownload_filter);
+ if (!f)
+ return NULL;
+
+ struct mp_hwdownload *d = f->priv;
+
+ d->f = f;
+ d->pool = mp_image_pool_new(d);
+
+ mp_filter_add_pin(f, MP_PIN_IN, "in");
+ mp_filter_add_pin(f, MP_PIN_OUT, "out");
+
+ return d;
+}
diff --git a/filters/f_hwtransfer.h b/filters/f_hwtransfer.h
index 4595cb393d..567bf92213 100644
--- a/filters/f_hwtransfer.h
+++ b/filters/f_hwtransfer.h
@@ -30,3 +30,12 @@ struct mp_hwupload *mp_hwupload_create(struct mp_filter *parent, int hw_imgfmt);
// and otherwise a format that likely results in the least loss.
// Returns 0 if completely unsupported.
int mp_hwupload_find_upload_format(struct mp_hwupload *u, int imgfmt);
+
+// A filter which downloads sw frames from hw. Ignores sw frames.
+struct mp_hwdownload {
+ struct mp_filter *f;
+
+ struct mp_image_pool *pool;
+};
+
+struct mp_hwdownload *mp_hwdownload_create(struct mp_filter *parent);