summaryrefslogtreecommitdiffstats
path: root/video/filter/vf_vdpaupp.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/filter/vf_vdpaupp.c')
-rw-r--r--video/filter/vf_vdpaupp.c175
1 files changed, 71 insertions, 104 deletions
diff --git a/video/filter/vf_vdpaupp.c b/video/filter/vf_vdpaupp.c
index 391dc9e6b1..3b10e13421 100644
--- a/video/filter/vf_vdpaupp.c
+++ b/video/filter/vf_vdpaupp.c
@@ -26,62 +26,34 @@
#include "common/common.h"
#include "common/msg.h"
#include "options/m_option.h"
-
+#include "filters/filter.h"
+#include "filters/filter_internal.h"
+#include "filters/user_filters.h"
#include "video/img_format.h"
#include "video/mp_image.h"
#include "video/hwdec.h"
#include "video/vdpau.h"
#include "video/vdpau_mixer.h"
-#include "vf.h"
#include "refqueue.h"
// Note: this filter does no actual filtering; it merely sets appropriate
// flags on vdpau images (mp_vdpau_mixer_frame) to do the appropriate
// processing on the final rendering process in the VO.
-struct vf_priv_s {
- struct mp_vdpau_ctx *ctx;
- struct mp_refqueue *queue;
-
- int def_deintmode;
+struct opts {
int deint_enabled;
int interlaced_only;
struct mp_vdpau_mixer_opts opts;
};
-static int filter_ext(struct vf_instance *vf, struct mp_image *mpi)
-{
- struct vf_priv_s *p = vf->priv;
-
- if (p->opts.deint >= 2) {
- mp_refqueue_set_refs(p->queue, 1, 1); // 2 past fields, 1 future field
- } else {
- mp_refqueue_set_refs(p->queue, 0, 0);
- }
- mp_refqueue_set_mode(p->queue,
- (p->deint_enabled ? MP_MODE_DEINT : 0) |
- (p->interlaced_only ? MP_MODE_INTERLACED_ONLY : 0) |
- (p->opts.deint >= 2 ? MP_MODE_OUTPUT_FIELDS : 0));
-
- if (mpi) {
- struct mp_image *new = mp_vdpau_upload_video_surface(p->ctx, mpi);
- talloc_free(mpi);
- if (!new)
- return -1;
- mpi = new;
-
- if (mp_vdpau_mixed_frame_get(mpi)) {
- MP_ERR(vf, "Can't apply vdpaupp filter multiple times.\n");
- vf_add_output_frame(vf, mpi);
- return -1;
- }
- }
-
- mp_refqueue_add_input(p->queue, mpi);
- return 0;
-}
+struct priv {
+ struct opts *opts;
+ struct mp_vdpau_ctx *ctx;
+ struct mp_refqueue *queue;
+ struct mp_pin *in_pin;
+};
-static VdpVideoSurface ref_field(struct vf_priv_s *p,
+static VdpVideoSurface ref_field(struct priv *p,
struct mp_vdpau_mixer_frame *frame, int pos)
{
struct mp_image *mpi = mp_image_new_ref(mp_refqueue_get_field(p->queue, pos));
@@ -91,17 +63,19 @@ static VdpVideoSurface ref_field(struct vf_priv_s *p,
return (uintptr_t)mpi->planes[3];
}
-static int filter_out(struct vf_instance *vf)
+static void vf_vdpaupp_process(struct mp_filter *f)
{
- struct vf_priv_s *p = vf->priv;
+ struct priv *p = f->priv;
- if (!mp_refqueue_has_output(p->queue))
- return 0;
+ mp_refqueue_execute_reinit(p->queue);
+
+ if (!mp_refqueue_can_output(p->queue))
+ return;
struct mp_image *mpi =
mp_vdpau_mixed_frame_create(mp_refqueue_get_field(p->queue, 0));
if (!mpi)
- return -1; // OOM
+ return; // OOM
struct mp_vdpau_mixer_frame *frame = mp_vdpau_mixed_frame_get(mpi);
if (!mp_refqueue_should_deint(p->queue)) {
@@ -117,72 +91,52 @@ static int filter_out(struct vf_instance *vf)
frame->past[0] = ref_field(p, frame, -1);
frame->past[1] = ref_field(p, frame, -2);
- frame->opts = p->opts;
+ frame->opts = p->opts->opts;
mpi->planes[3] = (void *)(uintptr_t)frame->current;
- mp_refqueue_next_field(p->queue);
+ mpi->params.hw_subfmt = 0; // force mixer
- vf_add_output_frame(vf, mpi);
- return 0;
+ mp_refqueue_write_out_pin(p->queue, mpi);
}
-static int reconfig(struct vf_instance *vf, struct mp_image_params *in,
- struct mp_image_params *out)
+static void vf_vdpaupp_reset(struct mp_filter *f)
{
- struct vf_priv_s *p = vf->priv;
+ struct priv *p = f->priv;
mp_refqueue_flush(p->queue);
- *out = *in;
- out->imgfmt = IMGFMT_VDPAU;
- out->hw_subfmt = 0;
- return 0;
}
-static int query_format(struct vf_instance *vf, unsigned int fmt)
+static void vf_vdpaupp_destroy(struct mp_filter *f)
{
- if (fmt == IMGFMT_VDPAU || mp_vdpau_get_format(fmt, NULL, NULL))
- return vf_next_query_format(vf, IMGFMT_VDPAU);
- return 0;
+ struct priv *p = f->priv;
+ talloc_free(p->queue);
}
-static int control(vf_instance_t *vf, int request, void *data)
-{
- struct vf_priv_s *p = vf->priv;
-
- switch (request) {
- case VFCTRL_SEEK_RESET:
- mp_refqueue_flush(p->queue);
- return CONTROL_OK;
- }
- return CONTROL_UNKNOWN;
-}
-
-static void uninit(struct vf_instance *vf)
-{
- struct vf_priv_s *p = vf->priv;
-
- mp_refqueue_free(p->queue);
-}
+static const struct mp_filter_info vf_vdpaupp_filter = {
+ .name = "vdpaupp",
+ .process = vf_vdpaupp_process,
+ .reset = vf_vdpaupp_reset,
+ .destroy = vf_vdpaupp_destroy,
+ .priv_size = sizeof(struct priv),
+};
-static int vf_open(vf_instance_t *vf)
+static struct mp_filter *vf_vdpaupp_create(struct mp_filter *parent, void *options)
{
- struct vf_priv_s *p = vf->priv;
+ struct mp_filter *f = mp_filter_create(parent, &vf_vdpaupp_filter);
+ if (!f) {
+ talloc_free(options);
+ return NULL;
+ }
- if (!vf->hwdec_devs)
- return 0;
+ mp_filter_add_pin(f, MP_PIN_IN, "in");
+ mp_filter_add_pin(f, MP_PIN_OUT, "out");
- vf->reconfig = reconfig;
- vf->filter_ext = filter_ext;
- vf->filter_out = filter_out;
- vf->query_format = query_format;
- vf->control = control;
- vf->uninit = uninit;
+ struct priv *p = f->priv;
+ p->opts = talloc_steal(p, options);
- p->queue = mp_refqueue_alloc();
+ p->queue = mp_refqueue_alloc(f);
- hwdec_devices_request_all(vf->hwdec_devs);
- AVBufferRef *ref =
- hwdec_devices_get_lavc(vf->hwdec_devs, AV_HWDEVICE_TYPE_VDPAU);
+ AVBufferRef *ref = mp_filter_load_hwdec_device(f, AV_HWDEVICE_TYPE_VDPAU);
if (!ref)
goto error;
p->ctx = mp_vdpau_get_ctx_from_av(ref);
@@ -190,18 +144,29 @@ static int vf_open(vf_instance_t *vf)
if (!p->ctx)
goto error;
- p->def_deintmode = p->opts.deint;
- if (!p->deint_enabled)
- p->opts.deint = 0;
+ if (!p->opts->deint_enabled)
+ p->opts->opts.deint = 0;
- return 1;
+ if (p->opts->opts.deint >= 2) {
+ mp_refqueue_set_refs(p->queue, 1, 1); // 2 past fields, 1 future field
+ } else {
+ mp_refqueue_set_refs(p->queue, 0, 0);
+ }
+ mp_refqueue_set_mode(p->queue,
+ (p->opts->deint_enabled ? MP_MODE_DEINT : 0) |
+ (p->opts->interlaced_only ? MP_MODE_INTERLACED_ONLY : 0) |
+ (p->opts->opts.deint >= 2 ? MP_MODE_OUTPUT_FIELDS : 0));
+
+ mp_refqueue_add_in_format(p->queue, IMGFMT_VDPAU, 0);
+
+ return f;
error:
- uninit(vf);
- return 0;
+ talloc_free(f);
+ return NULL;
}
-#define OPT_BASE_STRUCT struct vf_priv_s
+#define OPT_BASE_STRUCT struct opts
static const m_option_t vf_opts_fields[] = {
OPT_CHOICE("deint-mode", opts.deint, 0,
({"first-field", 1},
@@ -219,10 +184,12 @@ static const m_option_t vf_opts_fields[] = {
{0}
};
-const vf_info_t vf_info_vdpaupp = {
- .description = "vdpau postprocessing",
- .name = "vdpaupp",
- .open = vf_open,
- .priv_size = sizeof(struct vf_priv_s),
- .options = vf_opts_fields,
+const struct mp_user_filter_entry vf_vdpaupp = {
+ .desc = {
+ .description = "vdpau postprocessing",
+ .name = "vdpaupp",
+ .priv_size = sizeof(OPT_BASE_STRUCT),
+ .options = vf_opts_fields,
+ },
+ .create = vf_vdpaupp_create,
};