summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--player/command.c82
-rw-r--r--player/command.h3
-rw-r--r--player/core.h2
-rw-r--r--player/video.c104
4 files changed, 84 insertions, 107 deletions
diff --git a/player/command.c b/player/command.c
index 85f453e0ef..425f040ff2 100644
--- a/player/command.c
+++ b/player/command.c
@@ -2258,88 +2258,6 @@ static int mp_property_detected_hwdec(void *ctx, struct m_property *prop,
return M_PROPERTY_NOT_IMPLEMENTED;
}
-#define VF_DEINTERLACE_LABEL "deinterlace"
-
-static bool probe_deint_filter(struct MPContext *mpctx, const char *filt)
-{
- char filter[80];
- // add a label so that removing the filter is easier
- snprintf(filter, sizeof(filter), "@%s:%s", VF_DEINTERLACE_LABEL, filt);
- return edit_filters(mpctx, mp_null_log, STREAM_VIDEO, "pre", filter) >= 0;
-}
-
-static bool check_output_format(struct MPContext *mpctx, int imgfmt)
-{
- struct vo_chain *vo_c = mpctx->vo_chain;
- if (!vo_c)
- return false;
- return vo_c->vf->allowed_output_formats[imgfmt - IMGFMT_START];
-}
-
-static int probe_deint_filters(struct MPContext *mpctx)
-{
- if (check_output_format(mpctx, IMGFMT_VDPAU)) {
- char filter[80] = "vdpaupp:deint=yes";
- int pref = 0;
- vo_control(mpctx->video_out, VOCTRL_GET_PREF_DEINT, &pref);
- pref = pref < 0 ? -pref : pref;
- if (pref > 0 && pref <= 4) {
- const char *types[] =
- {"", "first-field", "bob", "temporal", "temporal-spatial"};
- mp_snprintf_cat(filter, sizeof(filter), ":deint-mode=%s",
- types[pref]);
- }
-
- probe_deint_filter(mpctx, filter);
- return 0;
- }
- if (check_output_format(mpctx, IMGFMT_VAAPI) &&
- probe_deint_filter(mpctx, "vavpp"))
- return 0;
- if ((check_output_format(mpctx, IMGFMT_D3D11VA) ||
- check_output_format(mpctx, IMGFMT_D3D11NV12)) &&
- probe_deint_filter(mpctx, "d3d11vpp"))
- return 0;
- if (probe_deint_filter(mpctx, "yadif"))
- return 0;
- return -1;
-}
-
-static int get_deinterlacing(struct MPContext *mpctx)
-{
- struct vo_chain *vo_c = mpctx->vo_chain;
- int enabled = 0;
- if (video_vf_vo_control(vo_c, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK)
- enabled = -1;
- if (enabled < 0) {
- // vf_lavfi doesn't support VFCTRL_GET_DEINTERLACE
- if (vf_find_by_label(vo_c->vf, VF_DEINTERLACE_LABEL))
- enabled = 1;
- }
- return enabled;
-}
-
-void remove_deint_filter(struct MPContext *mpctx)
-{
- edit_filters(mpctx, mp_null_log, STREAM_VIDEO, "del", "@" VF_DEINTERLACE_LABEL);
-}
-
-void set_deinterlacing(struct MPContext *mpctx, bool enable)
-{
- struct vo_chain *vo_c = mpctx->vo_chain;
- if (vf_find_by_label(vo_c->vf, VF_DEINTERLACE_LABEL)) {
- if (!enable)
- remove_deint_filter(mpctx);
- } else {
- if ((get_deinterlacing(mpctx) > 0) != enable) {
- int arg = enable;
- if (video_vf_vo_control(vo_c, VFCTRL_SET_DEINTERLACE, &arg) != CONTROL_OK)
- probe_deint_filters(mpctx);
- }
- }
- mpctx->opts->deinterlace = get_deinterlacing(mpctx) > 0;
-}
-
static int mp_property_deinterlace(void *ctx, struct m_property *prop,
int action, void *arg)
{
diff --git a/player/command.h b/player/command.h
index 7c3994c39e..a233319ad7 100644
--- a/player/command.h
+++ b/player/command.h
@@ -59,7 +59,4 @@ void mp_hook_run(struct MPContext *mpctx, char *client, char *type);
void handle_ab_loop(struct MPContext *mpctx);
-void remove_deint_filter(struct MPContext *mpctx);
-void set_deinterlacing(struct MPContext *mpctx, bool enable);
-
#endif /* MPLAYER_COMMAND_H */
diff --git a/player/core.h b/player/core.h
index 61360b726e..8afcfbe64d 100644
--- a/player/core.h
+++ b/player/core.h
@@ -555,5 +555,7 @@ void uninit_video_out(struct MPContext *mpctx);
void uninit_video_chain(struct MPContext *mpctx);
double calc_average_frame_duration(struct MPContext *mpctx);
int init_video_decoder(struct MPContext *mpctx, struct track *track);
+int get_deinterlacing(struct MPContext *mpctx);
+void set_deinterlacing(struct MPContext *mpctx, bool enable);
#endif /* MPLAYER_MP_CORE_H */
diff --git a/player/video.c b/player/video.c
index 1d2dc29fc6..d0d0b60ed5 100644
--- a/player/video.c
+++ b/player/video.c
@@ -49,6 +49,8 @@
#include "command.h"
#include "screenshot.h"
+#define VF_DEINTERLACE_LABEL "deinterlace"
+
enum {
// update_video() - code also uses: <0 error, 0 eof, >0 progress
VD_ERROR = -1,
@@ -153,8 +155,37 @@ static int try_filter(struct vo_chain *vo_c, char *name, char *label, char **arg
return 0;
}
+static bool check_output_format(struct vo_chain *vo_c, int imgfmt)
+{
+ return vo_c->vf->output_params.imgfmt == imgfmt;
+}
+
+static int probe_deint_filters(struct vo_chain *vo_c)
+{
+ if (check_output_format(vo_c, IMGFMT_VDPAU)) {
+ char *args[5] = {"deint", "yes"};
+ int pref = 0;
+ vo_control(vo_c->vo, VOCTRL_GET_PREF_DEINT, &pref);
+ pref = pref < 0 ? -pref : pref;
+ if (pref > 0 && pref <= 4) {
+ const char *types[] =
+ {"", "first-field", "bob", "temporal", "temporal-spatial"};
+ args[2] = "deint-mode";
+ args[3] = (char *)types[pref];
+ }
+
+ return try_filter(vo_c, "vdpaupp", VF_DEINTERLACE_LABEL, args);
+ }
+ if (check_output_format(vo_c, IMGFMT_VAAPI))
+ return try_filter(vo_c, "vavpp", VF_DEINTERLACE_LABEL, NULL);
+ if (check_output_format(vo_c, IMGFMT_D3D11VA) ||
+ check_output_format(vo_c, IMGFMT_D3D11NV12))
+ return try_filter(vo_c, "d3d11vpp", VF_DEINTERLACE_LABEL, NULL);
+ return try_filter(vo_c, "yadif", VF_DEINTERLACE_LABEL, NULL);
+}
+
// Reconfigure the filter chain according to the new input format.
-static void filter_reconfig(struct vo_chain *vo_c)
+static void filter_reconfig(struct MPContext *mpctx, struct vo_chain *vo_c)
{
struct mp_image_params params = vo_c->input_format;
if (!params.imgfmt)
@@ -165,7 +196,7 @@ static void filter_reconfig(struct vo_chain *vo_c)
if (vf_reconfig(vo_c->vf, &params) < 0)
return;
- char *filters[] = {"autorotate", "autostereo3d", NULL};
+ char *filters[] = {"autorotate", "autostereo3d", "deinterlace", NULL};
for (int n = 0; filters[n]; n++) {
struct vf_instance *vf = vf_find_by_label(vo_c->vf, filters[n]);
if (vf) {
@@ -194,6 +225,53 @@ static void filter_reconfig(struct vo_chain *vo_c)
MP_ERR(vo_c, "Can't insert 3D conversion filter.\n");
}
}
+
+ if (mpctx->opts->deinterlace == 1)
+ probe_deint_filters(vo_c);
+}
+
+static void recreate_auto_filters(struct MPContext *mpctx)
+{
+ filter_reconfig(mpctx, mpctx->vo_chain);
+
+ mp_force_video_refresh(mpctx);
+
+ mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
+}
+
+int get_deinterlacing(struct MPContext *mpctx)
+{
+ struct vo_chain *vo_c = mpctx->vo_chain;
+ int enabled = 0;
+ if (video_vf_vo_control(vo_c, VFCTRL_GET_DEINTERLACE, &enabled) != CONTROL_OK)
+ enabled = -1;
+ if (enabled < 0) {
+ // vf_lavfi doesn't support VFCTRL_GET_DEINTERLACE
+ if (vf_find_by_label(vo_c->vf, VF_DEINTERLACE_LABEL))
+ enabled = 1;
+ }
+ return enabled;
+}
+
+void set_deinterlacing(struct MPContext *mpctx, bool enable)
+{
+ struct vo_chain *vo_c = mpctx->vo_chain;
+ if (vf_find_by_label(vo_c->vf, VF_DEINTERLACE_LABEL)) {
+ if (!enable) {
+ mpctx->opts->deinterlace = 0;
+ recreate_auto_filters(mpctx);
+ }
+ } else {
+ if ((get_deinterlacing(mpctx) > 0) != enable) {
+ int arg = enable;
+ if (video_vf_vo_control(vo_c, VFCTRL_SET_DEINTERLACE, &arg) != CONTROL_OK)
+ {
+ mpctx->opts->deinterlace = 1;
+ recreate_auto_filters(mpctx);
+ }
+ }
+ }
+ mpctx->opts->deinterlace = get_deinterlacing(mpctx) > 0;
}
static void recreate_video_filters(struct MPContext *mpctx)
@@ -230,7 +308,7 @@ int reinit_video_filters(struct MPContext *mpctx)
recreate_video_filters(mpctx);
if (need_reconfig)
- filter_reconfig(vo_c);
+ filter_reconfig(mpctx, vo_c);
mp_force_video_refresh(mpctx);
@@ -314,7 +392,6 @@ void uninit_video_chain(struct MPContext *mpctx)
mpctx->video_status = STATUS_EOF;
- remove_deint_filter(mpctx);
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
}
}
@@ -522,22 +599,6 @@ static int decode_image(struct MPContext *mpctx)
}
}
-// Called after video reinit. This can be generally used to try to insert more
-// filters using the filter chain edit functionality in command.c.
-static void init_filter_params(struct MPContext *mpctx)
-{
- struct MPOpts *opts = mpctx->opts;
-
- // Note that the filter chain is already initialized. This code might
- // recreate the chain a second time, which is not very elegant, but allows
- // us to test whether enabling deinterlacing works with the current video
- // format and other filters.
- if (opts->deinterlace >= 0) {
- remove_deint_filter(mpctx);
- set_deinterlacing(mpctx, opts->deinterlace != 0);
- }
-}
-
// Feed newly decoded frames to the filter, take care of format changes.
// If eof=true, drain the filter chain, and return VD_EOF if empty.
static int video_filter(struct MPContext *mpctx, bool eof)
@@ -564,7 +625,7 @@ static int video_filter(struct MPContext *mpctx, bool eof)
return VD_PROGRESS;
// The filter chain is drained; execute the filter format change.
- filter_reconfig(mpctx->vo_chain);
+ filter_reconfig(mpctx, mpctx->vo_chain);
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
@@ -586,7 +647,6 @@ static int video_filter(struct MPContext *mpctx, bool eof)
MP_FATAL(mpctx, "Cannot initialize video filters.\n");
return VD_ERROR;
}
- init_filter_params(mpctx);
return VD_RECONFIG;
}