mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
player: make --lavfi-complex changeable at runtime
Tends to be somewhat glitchy if subtitles are enabled, and you enable and disable tracks. On error, this will disable --lavfi-complex, which will result in whatever behavior.
This commit is contained in:
parent
baead23ea0
commit
f1d161d55f
@ -35,6 +35,9 @@ Interface changes
|
||||
framebuffer that was ever passed to the renderer. Having GL framebuffers
|
||||
with a size larger than 8 bit per component is quite rare. If you need
|
||||
it, set the --dither-depth option instead.
|
||||
- --lavfi-complex can now be set during runtime. If you set this in
|
||||
expectation it would be applied only after a reload, you might observe
|
||||
weird behavior.
|
||||
--- mpv 0.26.0 ---
|
||||
- remove remaining deprecated audio device options, like --alsa-device
|
||||
Some of them were removed in earlier releases.
|
||||
|
@ -408,7 +408,8 @@ struct m_option {
|
||||
#define UPDATE_PRIORITY (1 << 15) // --priority (Windows-only)
|
||||
#define UPDATE_SCREENSAVER (1 << 16) // --stop-screensaver
|
||||
#define UPDATE_VOL (1 << 17) // softvol related options
|
||||
#define UPDATE_OPT_LAST (1 << 17)
|
||||
#define UPDATE_LAVFI_COMPLEX (1 << 18) // --lavfi-complex
|
||||
#define UPDATE_OPT_LAST (1 << 18)
|
||||
|
||||
// All bits between _FIRST and _LAST (inclusive)
|
||||
#define UPDATE_OPTS_MASK \
|
||||
|
@ -362,7 +362,7 @@ const m_option_t mp_opts[] = {
|
||||
OPT_STRINGLIST("alang", stream_lang[STREAM_AUDIO], 0),
|
||||
OPT_STRINGLIST("slang", stream_lang[STREAM_SUB], 0),
|
||||
|
||||
OPT_STRING("lavfi-complex", lavfi_complex, 0),
|
||||
OPT_STRING("lavfi-complex", lavfi_complex, UPDATE_LAVFI_COMPLEX),
|
||||
|
||||
OPT_CHOICE("audio-display", audio_display, 0,
|
||||
({"no", 0}, {"attachment", 1})),
|
||||
|
@ -557,25 +557,19 @@ init_error:
|
||||
|
||||
void reinit_audio_chain(struct MPContext *mpctx)
|
||||
{
|
||||
reinit_audio_chain_src(mpctx, NULL);
|
||||
struct track *track = NULL;
|
||||
track = mpctx->current_track[0][STREAM_AUDIO];
|
||||
if (!track || !track->stream) {
|
||||
uninit_audio_out(mpctx);
|
||||
error_on_track(mpctx, track);
|
||||
return;
|
||||
}
|
||||
reinit_audio_chain_src(mpctx, track);
|
||||
}
|
||||
|
||||
void reinit_audio_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
// (track=NULL creates a blank chain, used for lavfi-complex)
|
||||
void reinit_audio_chain_src(struct MPContext *mpctx, struct track *track)
|
||||
{
|
||||
struct track *track = NULL;
|
||||
struct sh_stream *sh = NULL;
|
||||
if (!src) {
|
||||
track = mpctx->current_track[0][STREAM_AUDIO];
|
||||
if (!track) {
|
||||
uninit_audio_out(mpctx);
|
||||
return;
|
||||
}
|
||||
sh = track->stream;
|
||||
if (!sh) {
|
||||
uninit_audio_out(mpctx);
|
||||
goto no_audio;
|
||||
}
|
||||
}
|
||||
assert(!mpctx->ao_chain);
|
||||
|
||||
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
|
||||
@ -584,15 +578,14 @@ void reinit_audio_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
mpctx->ao_chain = ao_c;
|
||||
ao_c->log = mpctx->log;
|
||||
ao_c->af = af_new(mpctx->global);
|
||||
if (sh)
|
||||
ao_c->af->replaygain_data = sh->codec->replaygain_data;
|
||||
if (track && track->stream)
|
||||
ao_c->af->replaygain_data = track->stream->codec->replaygain_data;
|
||||
ao_c->spdif_passthrough = true;
|
||||
ao_c->pts = MP_NOPTS_VALUE;
|
||||
ao_c->ao_buffer = mp_audio_buffer_create(NULL);
|
||||
ao_c->ao = mpctx->ao;
|
||||
|
||||
ao_c->filter_src = src;
|
||||
if (!ao_c->filter_src) {
|
||||
if (track) {
|
||||
ao_c->track = track;
|
||||
track->ao_c = ao_c;
|
||||
if (!init_audio_decoder(mpctx, track))
|
||||
@ -614,7 +607,6 @@ void reinit_audio_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
init_error:
|
||||
uninit_audio_chain(mpctx);
|
||||
uninit_audio_out(mpctx);
|
||||
no_audio:
|
||||
error_on_track(mpctx, track);
|
||||
}
|
||||
|
||||
|
@ -5901,6 +5901,9 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags)
|
||||
|
||||
if (flags & UPDATE_VOL)
|
||||
audio_update_volume(mpctx);
|
||||
|
||||
if (flags & UPDATE_LAVFI_COMPLEX)
|
||||
update_lavfi_complex(mpctx);
|
||||
}
|
||||
|
||||
void mp_notify_property(struct MPContext *mpctx, const char *property)
|
||||
|
@ -367,6 +367,8 @@ typedef struct MPContext {
|
||||
double last_frame_duration;
|
||||
// Video PTS, or audio PTS if video has ended.
|
||||
double playback_pts;
|
||||
// Last known "good" PTS
|
||||
double canonical_pts;
|
||||
// audio stats only
|
||||
int64_t audio_stat_start;
|
||||
double written_audio;
|
||||
@ -478,7 +480,7 @@ void update_playback_speed(struct MPContext *mpctx);
|
||||
void uninit_audio_out(struct MPContext *mpctx);
|
||||
void uninit_audio_chain(struct MPContext *mpctx);
|
||||
int init_audio_decoder(struct MPContext *mpctx, struct track *track);
|
||||
void reinit_audio_chain_src(struct MPContext *mpctx, struct lavfi_pad *src);
|
||||
void reinit_audio_chain_src(struct MPContext *mpctx, struct track *track);
|
||||
void audio_update_volume(struct MPContext *mpctx);
|
||||
void audio_update_balance(struct MPContext *mpctx);
|
||||
void reload_audio_output(struct MPContext *mpctx);
|
||||
@ -522,6 +524,7 @@ void prefetch_next(struct MPContext *mpctx);
|
||||
void close_recorder(struct MPContext *mpctx);
|
||||
void close_recorder_and_error(struct MPContext *mpctx);
|
||||
void open_recorder(struct MPContext *mpctx, bool on_init);
|
||||
void update_lavfi_complex(struct MPContext *mpctx);
|
||||
|
||||
// main.c
|
||||
int mp_initialize(struct MPContext *mpctx, char **argv);
|
||||
@ -611,8 +614,8 @@ int video_set_colors(struct vo_chain *vo_c, const char *item, int value);
|
||||
int video_vf_vo_control(struct vo_chain *vo_c, int vf_cmd, void *data);
|
||||
void reset_video_state(struct MPContext *mpctx);
|
||||
int init_video_decoder(struct MPContext *mpctx, struct track *track);
|
||||
int reinit_video_chain(struct MPContext *mpctx);
|
||||
int reinit_video_chain_src(struct MPContext *mpctx, struct lavfi_pad *src);
|
||||
void reinit_video_chain(struct MPContext *mpctx);
|
||||
void reinit_video_chain_src(struct MPContext *mpctx, struct track *track);
|
||||
int reinit_video_filters(struct MPContext *mpctx);
|
||||
void write_video(struct MPContext *mpctx);
|
||||
void mp_force_video_refresh(struct MPContext *mpctx);
|
||||
|
@ -249,12 +249,19 @@ struct lavfi *lavfi_create(struct mp_log *log, char *graph_string)
|
||||
|
||||
void lavfi_destroy(struct lavfi *c)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
free_graph(c);
|
||||
clear_data(c);
|
||||
av_frame_free(&c->tmp_frame);
|
||||
talloc_free(c);
|
||||
}
|
||||
|
||||
const char *lavfi_get_graph(struct lavfi *c)
|
||||
{
|
||||
return c->graph_string;
|
||||
}
|
||||
|
||||
struct lavfi_pad *lavfi_find_pad(struct lavfi *c, char *name)
|
||||
{
|
||||
for (int n = 0; n < c->num_pads; n++) {
|
||||
@ -484,9 +491,11 @@ static void dump_graph(struct lavfi *c)
|
||||
#endif
|
||||
}
|
||||
|
||||
void lavfi_set_hwdec_devs(struct lavfi *c, struct mp_hwdec_devices *hwdevs)
|
||||
void lavfi_pad_set_hwdec_devs(struct lavfi_pad *pad,
|
||||
struct mp_hwdec_devices *hwdevs)
|
||||
{
|
||||
c->hwdec_devs = hwdevs;
|
||||
// We don't actually treat this per-pad.
|
||||
pad->main->hwdec_devs = hwdevs;
|
||||
}
|
||||
|
||||
// Initialize the graph if all inputs have formats set. If it's already
|
||||
|
@ -13,6 +13,7 @@ enum lavfi_direction {
|
||||
};
|
||||
|
||||
struct lavfi *lavfi_create(struct mp_log *log, char *graph_string);
|
||||
const char *lavfi_get_graph(struct lavfi *c);
|
||||
void lavfi_destroy(struct lavfi *c);
|
||||
struct lavfi_pad *lavfi_find_pad(struct lavfi *c, char *name);
|
||||
enum lavfi_direction lavfi_pad_direction(struct lavfi_pad *pad);
|
||||
@ -22,7 +23,8 @@ bool lavfi_get_connected(struct lavfi_pad *pad);
|
||||
bool lavfi_process(struct lavfi *c);
|
||||
bool lavfi_has_failed(struct lavfi *c);
|
||||
void lavfi_seek_reset(struct lavfi *c);
|
||||
void lavfi_set_hwdec_devs(struct lavfi *c, struct mp_hwdec_devices *hwdevs);
|
||||
void lavfi_pad_set_hwdec_devs(struct lavfi_pad *pad,
|
||||
struct mp_hwdec_devices *hwdevs);
|
||||
int lavfi_request_frame_a(struct lavfi_pad *pad, struct mp_audio **out_aframe);
|
||||
int lavfi_request_frame_v(struct lavfi_pad *pad, struct mp_image **out_vframe);
|
||||
bool lavfi_needs_input(struct lavfi_pad *pad);
|
||||
|
@ -945,21 +945,83 @@ void prefetch_next(struct MPContext *mpctx)
|
||||
}
|
||||
}
|
||||
|
||||
static bool init_complex_filters(struct MPContext *mpctx)
|
||||
// Destroy the complex filter, and remove the references to the filter pads.
|
||||
// (Call cleanup_deassociated_complex_filters() to close decoders/VO/AO
|
||||
// that are not connected anymore due to this.)
|
||||
static void deassociate_complex_filters(struct MPContext *mpctx)
|
||||
{
|
||||
assert(!mpctx->lavfi);
|
||||
for (int n = 0; n < mpctx->num_tracks; n++)
|
||||
mpctx->tracks[n]->sink = NULL;
|
||||
if (mpctx->vo_chain)
|
||||
mpctx->vo_chain->filter_src = NULL;
|
||||
if (mpctx->ao_chain)
|
||||
mpctx->ao_chain->filter_src = NULL;
|
||||
lavfi_destroy(mpctx->lavfi);
|
||||
mpctx->lavfi = NULL;
|
||||
}
|
||||
|
||||
// Close all decoders and sinks (AO/VO) that are not connected to either
|
||||
// a track or a filter pad.
|
||||
static void cleanup_deassociated_complex_filters(struct MPContext *mpctx)
|
||||
{
|
||||
for (int n = 0; n < mpctx->num_tracks; n++) {
|
||||
struct track *track = mpctx->tracks[n];
|
||||
if (!(track->sink || track->vo_c || track->ao_c)) {
|
||||
if (track->d_video && !track->vo_c) {
|
||||
video_uninit(track->d_video);
|
||||
track->d_video = NULL;
|
||||
}
|
||||
if (track->d_audio && !track->ao_c) {
|
||||
audio_uninit(track->d_audio);
|
||||
track->d_audio = NULL;
|
||||
}
|
||||
track->selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mpctx->vo_chain && !mpctx->vo_chain->video_src &&
|
||||
!mpctx->vo_chain->filter_src)
|
||||
{
|
||||
uninit_video_chain(mpctx);
|
||||
}
|
||||
if (mpctx->ao_chain && !mpctx->ao_chain->audio_src &&
|
||||
!mpctx->ao_chain->filter_src)
|
||||
{
|
||||
uninit_audio_chain(mpctx);
|
||||
}
|
||||
}
|
||||
|
||||
// >0: changed, 0: no change, -1: error
|
||||
static int reinit_complex_filters(struct MPContext *mpctx, bool force_uninit)
|
||||
{
|
||||
char *graph = mpctx->opts->lavfi_complex;
|
||||
bool have_graph = graph && graph[0] && !force_uninit;
|
||||
if (have_graph && mpctx->lavfi &&
|
||||
strcmp(graph, lavfi_get_graph(mpctx->lavfi)) == 0 &&
|
||||
!lavfi_has_failed(mpctx->lavfi))
|
||||
return 0;
|
||||
if (!mpctx->lavfi && !have_graph)
|
||||
return 0;
|
||||
|
||||
if (!graph || !graph[0])
|
||||
return true;
|
||||
// Deassociate the old filter pads. We leave both sources (tracks) and
|
||||
// sinks (AO/VO) "dangling", connected to neither track or filter pad.
|
||||
// Later, we either reassociate them with new pads, or uninit them if
|
||||
// they are still dangling. This avoids too interruptive actions like
|
||||
// recreating the VO.
|
||||
deassociate_complex_filters(mpctx);
|
||||
|
||||
bool success = false;
|
||||
if (!have_graph) {
|
||||
success = true; // normal full removal of graph
|
||||
goto done;
|
||||
}
|
||||
|
||||
mpctx->lavfi = lavfi_create(mpctx->log, graph);
|
||||
if (!mpctx->lavfi)
|
||||
return false;
|
||||
goto done;
|
||||
|
||||
if (lavfi_has_failed(mpctx->lavfi))
|
||||
return false;
|
||||
goto done;
|
||||
|
||||
for (int n = 0; n < mpctx->num_tracks; n++) {
|
||||
struct track *track = mpctx->tracks[n];
|
||||
@ -983,6 +1045,12 @@ static bool init_complex_filters(struct MPContext *mpctx)
|
||||
if (lavfi_get_connected(pad))
|
||||
continue;
|
||||
|
||||
assert(!track->sink);
|
||||
if (track->vo_c || track->ao_c) {
|
||||
MP_ERR(mpctx, "Pad %s tries to connect to already selected track.\n",
|
||||
label);
|
||||
goto done;
|
||||
}
|
||||
track->sink = pad;
|
||||
lavfi_set_connected(pad, true);
|
||||
track->selected = true;
|
||||
@ -992,66 +1060,81 @@ static bool init_complex_filters(struct MPContext *mpctx)
|
||||
if (pad && lavfi_pad_type(pad) == STREAM_VIDEO &&
|
||||
lavfi_pad_direction(pad) == LAVFI_OUT)
|
||||
{
|
||||
if (mpctx->vo_chain) {
|
||||
if (mpctx->vo_chain->video_src) {
|
||||
MP_ERR(mpctx, "Pad vo tries to connected to already used VO.\n");
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
reinit_video_chain_src(mpctx, NULL);
|
||||
if (!mpctx->vo_chain)
|
||||
goto done;
|
||||
}
|
||||
lavfi_set_connected(pad, true);
|
||||
reinit_video_chain_src(mpctx, pad);
|
||||
struct vo_chain *vo_c = mpctx->vo_chain;
|
||||
vo_c->filter_src = pad;
|
||||
lavfi_pad_set_hwdec_devs(vo_c->filter_src, vo_c->hwdec_devs);
|
||||
}
|
||||
|
||||
pad = lavfi_find_pad(mpctx->lavfi, "ao");
|
||||
if (pad && lavfi_pad_type(pad) == STREAM_AUDIO &&
|
||||
lavfi_pad_direction(pad) == LAVFI_OUT)
|
||||
{
|
||||
if (mpctx->ao_chain) {
|
||||
if (mpctx->ao_chain->audio_src) {
|
||||
MP_ERR(mpctx, "Pad ao tries to connected to already used AO.\n");
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
reinit_audio_chain_src(mpctx, NULL);
|
||||
if (!mpctx->ao_chain)
|
||||
goto done;
|
||||
}
|
||||
lavfi_set_connected(pad, true);
|
||||
reinit_audio_chain_src(mpctx, pad);
|
||||
mpctx->ao_chain->filter_src = pad;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool init_complex_filter_decoders(struct MPContext *mpctx)
|
||||
{
|
||||
if (!mpctx->lavfi)
|
||||
return true;
|
||||
|
||||
for (int n = 0; n < mpctx->num_tracks; n++) {
|
||||
struct track *track = mpctx->tracks[n];
|
||||
if (track->sink && track->type == STREAM_VIDEO) {
|
||||
if (!init_video_decoder(mpctx, track))
|
||||
return false;
|
||||
if (!track->d_video && !init_video_decoder(mpctx, track))
|
||||
goto done;
|
||||
}
|
||||
if (track->sink && track->type == STREAM_AUDIO) {
|
||||
if (!init_audio_decoder(mpctx, track))
|
||||
return false;
|
||||
if (!track->d_audio && !init_audio_decoder(mpctx, track))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
success = true;
|
||||
done:
|
||||
|
||||
if (!success)
|
||||
deassociate_complex_filters(mpctx);
|
||||
|
||||
cleanup_deassociated_complex_filters(mpctx);
|
||||
|
||||
if (mpctx->playback_initialized) {
|
||||
for (int n = 0; n < mpctx->num_tracks; n++)
|
||||
reselect_demux_stream(mpctx, mpctx->tracks[n]);
|
||||
}
|
||||
|
||||
mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
|
||||
|
||||
return success ? 1 : -1;
|
||||
}
|
||||
|
||||
static void uninit_complex_filters(struct MPContext *mpctx)
|
||||
void update_lavfi_complex(struct MPContext *mpctx)
|
||||
{
|
||||
if (!mpctx->lavfi)
|
||||
return;
|
||||
|
||||
for (int n = 0; n < mpctx->num_tracks; n++) {
|
||||
struct track *track = mpctx->tracks[n];
|
||||
|
||||
if (track->d_video && !track->vo_c) {
|
||||
video_uninit(track->d_video);
|
||||
track->d_video = NULL;
|
||||
}
|
||||
if (track->d_audio && !track->ao_c) {
|
||||
audio_uninit(track->d_audio);
|
||||
track->d_audio = NULL;
|
||||
if (mpctx->playback_initialized) {
|
||||
if (reinit_complex_filters(mpctx, false) != 0 &&
|
||||
mpctx->canonical_pts != MP_NOPTS_VALUE)
|
||||
{
|
||||
// Refresh seek to avoid weird situations.
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->canonical_pts,
|
||||
MPSEEK_EXACT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (mpctx->vo_chain && mpctx->vo_chain->filter_src)
|
||||
uninit_video_chain(mpctx);
|
||||
if (mpctx->ao_chain && mpctx->ao_chain->filter_src)
|
||||
uninit_audio_chain(mpctx);
|
||||
|
||||
lavfi_destroy(mpctx->lavfi);
|
||||
mpctx->lavfi = NULL;
|
||||
}
|
||||
|
||||
// Start playing the current playlist entry.
|
||||
@ -1083,6 +1166,7 @@ static void play_current_file(struct MPContext *mpctx)
|
||||
mpctx->speed_factor_a = mpctx->speed_factor_v = 1.0;
|
||||
mpctx->display_sync_error = 0.0;
|
||||
mpctx->display_sync_active = false;
|
||||
mpctx->canonical_pts = MP_NOPTS_VALUE;
|
||||
mpctx->seek = (struct seek_params){ 0 };
|
||||
|
||||
reset_playback_state(mpctx);
|
||||
@ -1176,7 +1260,7 @@ reopen_file:
|
||||
if (process_preloaded_hooks(mpctx))
|
||||
goto terminate_playback;
|
||||
|
||||
if (!init_complex_filters(mpctx))
|
||||
if (reinit_complex_filters(mpctx, false) < 0)
|
||||
goto terminate_playback;
|
||||
|
||||
assert(NUM_PTRACKS == 2); // opts->stream_id is hardcoded to 2
|
||||
@ -1223,9 +1307,6 @@ reopen_file:
|
||||
|
||||
update_playback_speed(mpctx);
|
||||
|
||||
if (!init_complex_filter_decoders(mpctx))
|
||||
goto terminate_playback;
|
||||
|
||||
reinit_video_chain(mpctx);
|
||||
reinit_audio_chain(mpctx);
|
||||
reinit_sub_all(mpctx);
|
||||
@ -1307,7 +1388,7 @@ terminate_playback:
|
||||
close_recorder(mpctx);
|
||||
|
||||
// time to uninit all, except global stuff:
|
||||
uninit_complex_filters(mpctx);
|
||||
reinit_complex_filters(mpctx, true);
|
||||
uninit_audio_chain(mpctx);
|
||||
uninit_video_chain(mpctx);
|
||||
uninit_sub_all(mpctx);
|
||||
|
@ -376,6 +376,8 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
|
||||
!hr_seek && !(demux_flags & SEEK_FORWARD);
|
||||
|
||||
mpctx->ab_loop_clip = mpctx->last_seek_pts < opts->ab_loop[1];
|
||||
|
||||
mpctx->canonical_pts = mpctx->last_seek_pts;
|
||||
}
|
||||
|
||||
// This combines consecutive seek requests.
|
||||
@ -956,6 +958,8 @@ static void handle_playback_time(struct MPContext *mpctx)
|
||||
{
|
||||
mpctx->playback_pts = playing_audio_pts(mpctx);
|
||||
}
|
||||
if (mpctx->playback_pts != MP_NOPTS_VALUE)
|
||||
mpctx->canonical_pts = mpctx->playback_pts;
|
||||
}
|
||||
|
||||
// We always make sure audio and video buffers are filled before actually
|
||||
|
@ -456,23 +456,20 @@ err_out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reinit_video_chain(struct MPContext *mpctx)
|
||||
void reinit_video_chain(struct MPContext *mpctx)
|
||||
{
|
||||
return reinit_video_chain_src(mpctx, NULL);
|
||||
struct track *track = mpctx->current_track[0][STREAM_VIDEO];
|
||||
if (!track || !track->stream) {
|
||||
error_on_track(mpctx, track);
|
||||
handle_force_window(mpctx, true);
|
||||
return;
|
||||
}
|
||||
reinit_video_chain_src(mpctx, track);
|
||||
}
|
||||
|
||||
int reinit_video_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
// (track=NULL creates a blank chain, used for lavfi-complex)
|
||||
void reinit_video_chain_src(struct MPContext *mpctx, struct track *track)
|
||||
{
|
||||
struct track *track = NULL;
|
||||
struct sh_stream *sh = NULL;
|
||||
if (!src) {
|
||||
track = mpctx->current_track[0][STREAM_VIDEO];
|
||||
if (!track)
|
||||
return 0;
|
||||
sh = track->stream;
|
||||
if (!sh)
|
||||
goto no_video;
|
||||
}
|
||||
assert(!mpctx->vo_chain);
|
||||
|
||||
if (!mpctx->video_out) {
|
||||
@ -504,11 +501,7 @@ int reinit_video_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
|
||||
vo_c->hwdec_devs = vo_c->vo->hwdec_devs;
|
||||
|
||||
if (mpctx->lavfi)
|
||||
lavfi_set_hwdec_devs(mpctx->lavfi, vo_c->hwdec_devs);
|
||||
|
||||
vo_c->filter_src = src;
|
||||
if (!vo_c->filter_src) {
|
||||
if (track) {
|
||||
vo_c->track = track;
|
||||
track->vo_c = vo_c;
|
||||
if (!init_video_decoder(mpctx, track))
|
||||
@ -516,7 +509,7 @@ int reinit_video_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
|
||||
vo_c->video_src = track->d_video;
|
||||
vo_c->container_fps = vo_c->video_src->fps;
|
||||
vo_c->is_coverart = !!sh->attached_picture;
|
||||
vo_c->is_coverart = !!track->stream->attached_picture;
|
||||
|
||||
track->vo_c = vo_c;
|
||||
vo_c->track = track;
|
||||
@ -540,14 +533,12 @@ int reinit_video_chain_src(struct MPContext *mpctx, struct lavfi_pad *src)
|
||||
reset_video_state(mpctx);
|
||||
reset_subtitle_state(mpctx);
|
||||
|
||||
return 1;
|
||||
return;
|
||||
|
||||
err_out:
|
||||
no_video:
|
||||
uninit_video_chain(mpctx);
|
||||
error_on_track(mpctx, track);
|
||||
handle_force_window(mpctx, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Try to refresh the video by doing a precise seek to the currently displayed
|
||||
|
Loading…
Reference in New Issue
Block a user