From a357d39369737f2f6608c669fac13d26e6c6b33a Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 21 Jul 2015 21:54:15 +0200 Subject: [PATCH] video: always re-probe auto deint filter on filter reconfig If filters are disabled or reconfigured, attempt to remove and probe the deinterlace filter again. This fixes behavior if e.g. a software deint filter was automatically inserted, and then hardware decoding is enabled during playback. Without this commit, initializing hw decoding would fail because of the software filter; with this commit, it'll replace it with the hw deinterlacer instead. --- player/command.c | 22 ++++++++++++++-------- player/command.h | 5 +++++ player/video.c | 7 +++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/player/command.c b/player/command.c index ad87a6314f..8e78099dfb 100644 --- a/player/command.c +++ b/player/command.c @@ -110,7 +110,8 @@ struct hook_handler { bool active; // hook is currently in progress (only 1 at a time for now) }; -static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype, +static int edit_filters(struct MPContext *mpctx, struct mp_log *log, + enum stream_type mediatype, const char *cmd, const char *arg); static int set_filters(struct MPContext *mpctx, enum stream_type mediatype, struct m_obj_settings *new_chain); @@ -2110,7 +2111,7 @@ 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, STREAM_VIDEO, "pre", filter) >= 0; + return edit_filters(mpctx, mp_null_log, STREAM_VIDEO, "pre", filter) >= 0; } static bool check_output_format(struct MPContext *mpctx, int imgfmt) @@ -2160,12 +2161,17 @@ static int get_deinterlacing(struct MPContext *mpctx) return enabled; } -static void set_deinterlacing(struct MPContext *mpctx, bool enable) +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 dec_video *vd = mpctx->d_video; if (vf_find_by_label(vd->vfilter, VF_DEINTERLACE_LABEL)) { if (!enable) - edit_filters(mpctx, STREAM_VIDEO, "del", "@" VF_DEINTERLACE_LABEL); + remove_deint_filter(mpctx); } else { if ((get_deinterlacing(mpctx) > 0) != enable) { int arg = enable; @@ -3870,7 +3876,8 @@ static int set_filters(struct MPContext *mpctx, enum stream_type mediatype, return success ? 0 : -1; } -static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype, +static int edit_filters(struct MPContext *mpctx, struct mp_log *log, + enum stream_type mediatype, const char *cmd, const char *arg) { bstr option = bstr0(filter_opt[mediatype]); @@ -3885,8 +3892,7 @@ static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype, struct m_obj_settings *new_chain = NULL; m_option_copy(co->opt, &new_chain, co->data); - int r = m_option_parse(mpctx->log, co->opt, bstr0(optname), bstr0(arg), - &new_chain); + int r = m_option_parse(log, co->opt, bstr0(optname), bstr0(arg), &new_chain); if (r >= 0) r = set_filters(mpctx, mediatype, new_chain); @@ -3898,7 +3904,7 @@ static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype, static int edit_filters_osd(struct MPContext *mpctx, enum stream_type mediatype, const char *cmd, const char *arg, bool on_osd) { - int r = edit_filters(mpctx, mediatype, cmd, arg); + int r = edit_filters(mpctx, mpctx->log, mediatype, cmd, arg); if (on_osd) { if (r >= 0) { const char *prop = filter_opt[mediatype]; diff --git a/player/command.h b/player/command.h index 85e81966c6..e65ffa0740 100644 --- a/player/command.h +++ b/player/command.h @@ -18,6 +18,8 @@ #ifndef MPLAYER_COMMAND_H #define MPLAYER_COMMAND_H +#include + struct MPContext; struct mp_cmd; struct mp_log; @@ -56,4 +58,7 @@ 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/video.c b/player/video.c index 57ec9d64d1..763f2e5a81 100644 --- a/player/video.c +++ b/player/video.c @@ -231,6 +231,7 @@ void uninit_video_chain(struct MPContext *mpctx) mpctx->video_status = STATUS_EOF; mpctx->sync_audio_to_video = false; reselect_demux_streams(mpctx); + remove_deint_filter(mpctx); } mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL); } @@ -423,8 +424,10 @@ static void init_filter_params(struct MPContext *mpctx) // 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) - mp_property_do("deinterlace", M_PROPERTY_SET, &opts->deinterlace, mpctx); + 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.