diff options
author | wm4 <wm4@nowhere> | 2016-07-06 14:08:47 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-07-06 14:08:47 +0200 |
commit | 771a8bf5c67417b7aad07fac0913c37b4633a205 (patch) | |
tree | 41a2e929fb25f3199b48ce141576cd3e06c4f90b /player/video.c | |
parent | 08cd50b84b853fc525a9074099fbf0a12830afe2 (diff) | |
download | mpv-771a8bf5c67417b7aad07fac0913c37b4633a205.tar.bz2 mpv-771a8bf5c67417b7aad07fac0913c37b4633a205.tar.xz |
video: fix deinterlace filter handling for VFCTRL_SET_DEINTERLACE filters
Some filters support VFCTRL_SET_DEINTERLACE. This affects most hardware
deinterlace filters. They can be inserted by the user manually, or auto-
inserted by vf.c itself as conversion filter (vf_d3d11vpp). In these
cases, we shouldn't insert or remove filters outselves, and instead
VFCTRL_SET_DEINTERLACE should be invoked to switch the mode.
This wasn't done correctly in the recently refactored code and could
have broken with --deinterlace. (The refactor only considered switching
via property in this case.) Fix it by making it a proper part of the
filter_reconfig() function, and making set_deinterlacing() (which is
called by the property handler) merely call filter_reconfig() in all
cases to do the real work.
We can even avoid rebuilding the filter chain - though only if no other
auto-filters are inserted. It probably also provides a slightly cleaner
way to implement functionality in the VO while still inserting video
filter fallbacks correctly if required.
Diffstat (limited to 'player/video.c')
-rw-r--r-- | player/video.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/player/video.c b/player/video.c index dab604bb01..d413ffe4fb 100644 --- a/player/video.c +++ b/player/video.c @@ -162,6 +162,14 @@ static bool check_output_format(struct vo_chain *vo_c, int imgfmt) static int probe_deint_filters(struct vo_chain *vo_c) { + // Usually, we prefer inserting/removing deint filters. But If there's VO + // support, or the user inserted a filter that supports swichting deint and + // that has no VF_DEINTERLACE_LABEL, or if the filter was auto-inserted + // for other reasons and supports switching deint (like vf_d3d11vpp), then + // use the runtime switching method. + if (video_vf_vo_control(vo_c, VFCTRL_SET_DEINTERLACE, &(int){1}) == CONTROL_OK) + return 0; + if (check_output_format(vo_c, IMGFMT_VDPAU)) { char *args[5] = {"deint", "yes"}; int pref = 0; @@ -200,8 +208,13 @@ static void filter_reconfig(struct MPContext *mpctx, struct vo_chain *vo_c) vf_remove_filter(vo_c->vf, vf); } - if (vf_reconfig(vo_c->vf, ¶ms) < 0) - return; + if (vo_c->vf->initialized < 1) { + if (vf_reconfig(vo_c->vf, ¶ms) < 0) + return; + } + + // Make sure to reset this even if runtime deint switching is used. + video_vf_vo_control(vo_c, VFCTRL_SET_DEINTERLACE, &(int){0}); if (params.rotate && (params.rotate % 90 == 0)) { if (!(vo_c->vo->driver->caps & VO_CAP_ROTATE90)) { @@ -252,22 +265,11 @@ int get_deinterlacing(struct MPContext *mpctx) 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); - } - } - } + if (enable == (get_deinterlacing(mpctx) > 0)) + return; + + mpctx->opts->deinterlace = enable; + recreate_auto_filters(mpctx); mpctx->opts->deinterlace = get_deinterlacing(mpctx) > 0; } |