mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
61961d03f6
commit
49f9146fe4
|
@ -298,3 +298,56 @@ error:
|
||||||
talloc_free(f);
|
talloc_free(f);
|
||||||
return NULL;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
// and otherwise a format that likely results in the least loss.
|
||||||
// Returns 0 if completely unsupported.
|
// Returns 0 if completely unsupported.
|
||||||
int mp_hwupload_find_upload_format(struct mp_hwupload *u, int imgfmt);
|
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);
|
||||||
|
|
Loading…
Reference in New Issue