diff options
Diffstat (limited to 'video/filter/vf_vdpaupp.c')
-rw-r--r-- | video/filter/vf_vdpaupp.c | 175 |
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, }; |