summaryrefslogtreecommitdiffstats
path: root/filters/f_auto_filters.c
diff options
context:
space:
mode:
Diffstat (limited to 'filters/f_auto_filters.c')
-rw-r--r--filters/f_auto_filters.c69
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,