mirror of
https://github.com/mpv-player/mpv
synced 2024-10-02 16:25:33 +02:00
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.
This commit is contained in:
parent
e5fac76b3b
commit
a357d39369
@ -110,7 +110,8 @@ struct hook_handler {
|
|||||||
bool active; // hook is currently in progress (only 1 at a time for now)
|
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);
|
const char *cmd, const char *arg);
|
||||||
static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
|
static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
|
||||||
struct m_obj_settings *new_chain);
|
struct m_obj_settings *new_chain);
|
||||||
@ -2110,7 +2111,7 @@ static bool probe_deint_filter(struct MPContext *mpctx, const char *filt)
|
|||||||
char filter[80];
|
char filter[80];
|
||||||
// add a label so that removing the filter is easier
|
// add a label so that removing the filter is easier
|
||||||
snprintf(filter, sizeof(filter), "@%s:%s", VF_DEINTERLACE_LABEL, filt);
|
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)
|
static bool check_output_format(struct MPContext *mpctx, int imgfmt)
|
||||||
@ -2160,12 +2161,17 @@ static int get_deinterlacing(struct MPContext *mpctx)
|
|||||||
return enabled;
|
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;
|
struct dec_video *vd = mpctx->d_video;
|
||||||
if (vf_find_by_label(vd->vfilter, VF_DEINTERLACE_LABEL)) {
|
if (vf_find_by_label(vd->vfilter, VF_DEINTERLACE_LABEL)) {
|
||||||
if (!enable)
|
if (!enable)
|
||||||
edit_filters(mpctx, STREAM_VIDEO, "del", "@" VF_DEINTERLACE_LABEL);
|
remove_deint_filter(mpctx);
|
||||||
} else {
|
} else {
|
||||||
if ((get_deinterlacing(mpctx) > 0) != enable) {
|
if ((get_deinterlacing(mpctx) > 0) != enable) {
|
||||||
int arg = enable;
|
int arg = enable;
|
||||||
@ -3870,7 +3876,8 @@ static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
|
|||||||
return success ? 0 : -1;
|
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)
|
const char *cmd, const char *arg)
|
||||||
{
|
{
|
||||||
bstr option = bstr0(filter_opt[mediatype]);
|
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;
|
struct m_obj_settings *new_chain = NULL;
|
||||||
m_option_copy(co->opt, &new_chain, co->data);
|
m_option_copy(co->opt, &new_chain, co->data);
|
||||||
|
|
||||||
int r = m_option_parse(mpctx->log, co->opt, bstr0(optname), bstr0(arg),
|
int r = m_option_parse(log, co->opt, bstr0(optname), bstr0(arg), &new_chain);
|
||||||
&new_chain);
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
r = set_filters(mpctx, mediatype, new_chain);
|
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,
|
static int edit_filters_osd(struct MPContext *mpctx, enum stream_type mediatype,
|
||||||
const char *cmd, const char *arg, bool on_osd)
|
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 (on_osd) {
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
const char *prop = filter_opt[mediatype];
|
const char *prop = filter_opt[mediatype];
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#ifndef MPLAYER_COMMAND_H
|
#ifndef MPLAYER_COMMAND_H
|
||||||
#define MPLAYER_COMMAND_H
|
#define MPLAYER_COMMAND_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct MPContext;
|
struct MPContext;
|
||||||
struct mp_cmd;
|
struct mp_cmd;
|
||||||
struct mp_log;
|
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 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 */
|
#endif /* MPLAYER_COMMAND_H */
|
||||||
|
@ -231,6 +231,7 @@ void uninit_video_chain(struct MPContext *mpctx)
|
|||||||
mpctx->video_status = STATUS_EOF;
|
mpctx->video_status = STATUS_EOF;
|
||||||
mpctx->sync_audio_to_video = false;
|
mpctx->sync_audio_to_video = false;
|
||||||
reselect_demux_streams(mpctx);
|
reselect_demux_streams(mpctx);
|
||||||
|
remove_deint_filter(mpctx);
|
||||||
}
|
}
|
||||||
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
|
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
|
// recreate the chain a second time, which is not very elegant, but allows
|
||||||
// us to test whether enabling deinterlacing works with the current video
|
// us to test whether enabling deinterlacing works with the current video
|
||||||
// format and other filters.
|
// format and other filters.
|
||||||
if (opts->deinterlace >= 0)
|
if (opts->deinterlace >= 0) {
|
||||||
mp_property_do("deinterlace", M_PROPERTY_SET, &opts->deinterlace, mpctx);
|
remove_deint_filter(mpctx);
|
||||||
|
set_deinterlacing(mpctx, opts->deinterlace != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feed newly decoded frames to the filter, take care of format changes.
|
// Feed newly decoded frames to the filter, take care of format changes.
|
||||||
|
Loading…
Reference in New Issue
Block a user