diff options
Diffstat (limited to 'filters/f_auto_filters.c')
-rw-r--r-- | filters/f_auto_filters.c | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/filters/f_auto_filters.c b/filters/f_auto_filters.c index a5394dd35a..6fa38b96c2 100644 --- a/filters/f_auto_filters.c +++ b/filters/f_auto_filters.c @@ -6,6 +6,7 @@ #include "common/msg.h" #include "options/m_config.h" #include "options/options.h" +#include "video/filter/refqueue.h" #include "video/mp_image.h" #include "video/mp_image_pool.h" @@ -21,7 +22,7 @@ struct deint_priv { struct mp_subfilter sub; int prev_imgfmt; - int prev_setting; + bool deinterlace_active; struct m_config_cache *opts; }; @@ -45,15 +46,18 @@ static void deint_process(struct mp_filter *f) return; } + struct mp_image *img = frame.data; + bool interlaced = img->fields & MP_IMGFIELD_INTERLACED; + m_config_cache_update(p->opts); struct filter_opts *opts = p->opts->opts; + bool should_deinterlace = (opts->deinterlace == -1 && interlaced) || + opts->deinterlace == 1; - if (!opts->deinterlace) + if (!should_deinterlace) mp_subfilter_destroy(&p->sub); - struct mp_image *img = frame.data; - - if (img->imgfmt == p->prev_imgfmt && p->prev_setting == opts->deinterlace) { + if (img->imgfmt == p->prev_imgfmt && p->deinterlace_active == should_deinterlace) { mp_subfilter_continue(&p->sub); return; } @@ -64,24 +68,50 @@ static void deint_process(struct mp_filter *f) assert(!p->sub.filter); p->prev_imgfmt = img->imgfmt; - p->prev_setting = opts->deinterlace; - if (!p->prev_setting) { + p->deinterlace_active = should_deinterlace; + if (!p->deinterlace_active) { mp_subfilter_continue(&p->sub); return; } + char *field_parity; + switch (opts->field_parity) { + case MP_FIELD_PARITY_TFF: + field_parity = "tff"; + break; + case MP_FIELD_PARITY_BFF: + field_parity = "bff"; + break; + default: + field_parity = "auto"; + } + bool has_filter = true; if (img->imgfmt == IMGFMT_VDPAU) { - char *args[] = {"deint", "yes", NULL}; + char *args[] = {"deint", "yes", + "parity", field_parity, NULL}; p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "vdpaupp", args); } else if (img->imgfmt == IMGFMT_D3D11) { + char *args[] = {"parity", field_parity, NULL}; p->sub.filter = - mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "d3d11vpp", NULL); + mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "d3d11vpp", args); } else if (img->imgfmt == IMGFMT_CUDA) { - char *args[] = {"mode", "send_field", NULL}; + char *args[] = {"mode", "send_field", + "parity", field_parity, NULL}; p->sub.filter = - mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "yadif_cuda", args); + mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "bwdif_cuda", args); + } else if (img->imgfmt == IMGFMT_VULKAN) { + char *args[] = {"mode", "send_field", + "parity", field_parity, NULL}; + p->sub.filter = + mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "bwdif_vulkan", args); + } else if (img->imgfmt == IMGFMT_VAAPI) { + char *args[] = {"deint", "motion-adaptive", + "interlaced-only", "yes", + "parity", field_parity, NULL}; + p->sub.filter = + mp_create_user_filter(f, MP_OUTPUT_CHAIN_VIDEO, "vavpp", args); } else { has_filter = false; } @@ -96,7 +126,7 @@ static void deint_process(struct mp_filter *f) struct mp_autoconvert *ac = mp_autoconvert_create(subf); if (ac) { filters[0] = ac->f; - // We know vf_yadif does not support hw inputs. + // We know vf_bwdif does not support hw inputs. mp_autoconvert_add_all_sw_imgfmts(ac); if (!mp_autoconvert_probe_input_video(ac, img)) { @@ -108,9 +138,10 @@ static void deint_process(struct mp_filter *f) } } - char *args[] = {"mode", "send_field", NULL}; + char *args[] = {"mode", "send_field", + "parity", field_parity, NULL}; filters[1] = - mp_create_user_filter(subf, MP_OUTPUT_CHAIN_VIDEO, "yadif", args); + mp_create_user_filter(subf, MP_OUTPUT_CHAIN_VIDEO, "bwdif", args); mp_chain_filters(subf->ppins[0], subf->ppins[1], filters, 2); p->sub.filter = subf; @@ -154,6 +185,12 @@ static const struct mp_filter_info deint_filter = { .destroy = deint_destroy, }; +bool mp_deint_active(struct mp_filter *f) +{ + struct deint_priv *p = f->priv; + return p->deinterlace_active; +} + struct mp_filter *mp_deint_create(struct mp_filter *parent) { struct mp_filter *f = mp_filter_create(parent, &deint_filter); @@ -329,9 +366,9 @@ static void aspeed_process(struct mp_filter *f) if (req_filter) { if (req_filter == 1) { - MP_VERBOSE(f, "adding scaletempo\n"); + MP_VERBOSE(f, "adding scaletempo2\n"); p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO, - "scaletempo", NULL); + "scaletempo2", NULL); } else if (req_filter == 2) { MP_VERBOSE(f, "adding drop\n"); p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO, |