1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <stddef.h>
19 #include <stdbool.h>
20 #include <inttypes.h>
21 #include <math.h>
22 #include <assert.h>
23 
24 #include "config.h"
25 #include "mpv_talloc.h"
26 
27 #include "common/msg.h"
28 #include "options/options.h"
29 #include "options/m_config.h"
30 #include "options/m_option.h"
31 #include "common/common.h"
32 #include "common/encode.h"
33 #include "options/m_property.h"
34 #include "osdep/timer.h"
35 
36 #include "audio/out/ao.h"
37 #include "audio/format.h"
38 #include "demux/demux.h"
39 #include "stream/stream.h"
40 #include "sub/osd.h"
41 #include "video/hwdec.h"
42 #include "filters/f_decoder_wrapper.h"
43 #include "video/out/vo.h"
44 
45 #include "core.h"
46 #include "command.h"
47 #include "screenshot.h"
48 
49 enum {
50     // update_video() - code also uses: <0 error, 0 eof, >0 progress
51     VD_ERROR = -1,
52     VD_EOF = 0,         // end of file - no new output
53     VD_PROGRESS = 1,    // progress, but no output; repeat call with no waiting
54     VD_NEW_FRAME = 2,   // the call produced a new frame
55     VD_WAIT = 3,        // no EOF, but no output; wait until wakeup
56 };
57 
58 static const char av_desync_help_text[] =
59 "\n"
60 "Audio/Video desynchronisation detected! Possible reasons include too slow\n"
61 "hardware, temporary CPU spikes, broken drivers, and broken files. Audio\n"
62 "position will not match to the video (see A-V status field).\n"
63 "\n";
64 
recreate_video_filters(struct MPContext * mpctx)65 static bool recreate_video_filters(struct MPContext *mpctx)
66 {
67     struct MPOpts *opts = mpctx->opts;
68     struct vo_chain *vo_c = mpctx->vo_chain;
69     assert(vo_c);
70 
71     return mp_output_chain_update_filters(vo_c->filter, opts->vf_settings);
72 }
73 
reinit_video_filters(struct MPContext * mpctx)74 int reinit_video_filters(struct MPContext *mpctx)
75 {
76     struct vo_chain *vo_c = mpctx->vo_chain;
77 
78     if (!vo_c)
79         return 0;
80 
81     if (!recreate_video_filters(mpctx))
82         return -1;
83 
84     mp_force_video_refresh(mpctx);
85 
86     mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
87 
88     return 0;
89 }
90 
vo_chain_reset_state(struct vo_chain * vo_c)91 static void vo_chain_reset_state(struct vo_chain *vo_c)
92 {
93     vo_seek_reset(vo_c->vo);
94     vo_c->underrun = false;
95     vo_c->underrun_signaled = false;
96 }
97 
reset_video_state(struct MPContext * mpctx)98 void reset_video_state(struct MPContext *mpctx)
99 {
100     if (mpctx->vo_chain) {
101         vo_chain_reset_state(mpctx->vo_chain);
102         struct track *t = mpctx->vo_chain->track;
103         if (t && t->dec)
104             mp_decoder_wrapper_set_play_dir(t->dec, mpctx->play_dir);
105     }
106 
107     for (int n = 0; n < mpctx->num_next_frames; n++)
108         mp_image_unrefp(&mpctx->next_frames[n]);
109     mpctx->num_next_frames = 0;
110     mp_image_unrefp(&mpctx->saved_frame);
111 
112     mpctx->delay = 0;
113     mpctx->time_frame = 0;
114     mpctx->video_pts = MP_NOPTS_VALUE;
115     mpctx->last_frame_duration = 0;
116     mpctx->num_past_frames = 0;
117     mpctx->total_avsync_change = 0;
118     mpctx->last_av_difference = 0;
119     mpctx->mistimed_frames_total = 0;
120     mpctx->drop_message_shown = 0;
121     mpctx->display_sync_drift_dir = 0;
122 
123     mpctx->video_status = mpctx->vo_chain ? STATUS_SYNCING : STATUS_EOF;
124 }
125 
uninit_video_out(struct MPContext * mpctx)126 void uninit_video_out(struct MPContext *mpctx)
127 {
128     uninit_video_chain(mpctx);
129     if (mpctx->video_out) {
130         vo_destroy(mpctx->video_out);
131         mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
132     }
133     mpctx->video_out = NULL;
134 }
135 
vo_chain_uninit(struct vo_chain * vo_c)136 static void vo_chain_uninit(struct vo_chain *vo_c)
137 {
138     struct track *track = vo_c->track;
139     if (track) {
140         assert(track->vo_c == vo_c);
141         track->vo_c = NULL;
142         if (vo_c->dec_src)
143             assert(track->dec->f->pins[0] == vo_c->dec_src);
144         talloc_free(track->dec->f);
145         track->dec = NULL;
146     }
147 
148     if (vo_c->filter_src)
149         mp_pin_disconnect(vo_c->filter_src);
150 
151     talloc_free(vo_c->filter->f);
152     talloc_free(vo_c);
153     // this does not free the VO
154 }
155 
uninit_video_chain(struct MPContext * mpctx)156 void uninit_video_chain(struct MPContext *mpctx)
157 {
158     if (mpctx->vo_chain) {
159         reset_video_state(mpctx);
160         vo_chain_uninit(mpctx->vo_chain);
161         mpctx->vo_chain = NULL;
162 
163         mpctx->video_status = STATUS_EOF;
164 
165         mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
166     }
167 }
168 
init_video_decoder(struct MPContext * mpctx,struct track * track)169 int init_video_decoder(struct MPContext *mpctx, struct track *track)
170 {
171     assert(!track->dec);
172     if (!track->stream)
173         goto err_out;
174 
175     struct mp_filter *parent = mpctx->filter_root;
176 
177     // If possible, set this as parent so the decoder gets the hwdec and DR
178     // interfaces.
179     // Note: at least mpv_opengl_cb_uninit_gl() relies on being able to get
180     //       rid of all references to the VO by destroying the VO chain. Thus,
181     //       decoders not linked to vo_chain must not use the hwdec context.
182     if (track->vo_c)
183         parent = track->vo_c->filter->f;
184 
185     track->dec = mp_decoder_wrapper_create(parent, track->stream);
186     if (!track->dec)
187         goto err_out;
188 
189     if (!mp_decoder_wrapper_reinit(track->dec))
190         goto err_out;
191 
192     return 1;
193 
194 err_out:
195     if (track->sink)
196         mp_pin_disconnect(track->sink);
197     track->sink = NULL;
198     error_on_track(mpctx, track);
199     return 0;
200 }
201 
reinit_video_chain(struct MPContext * mpctx)202 void reinit_video_chain(struct MPContext *mpctx)
203 {
204     struct track *track = mpctx->current_track[0][STREAM_VIDEO];
205     if (!track || !track->stream) {
206         error_on_track(mpctx, track);
207         return;
208     }
209     reinit_video_chain_src(mpctx, track);
210 }
211 
filter_update_subtitles(void * ctx,double pts)212 static void filter_update_subtitles(void *ctx, double pts)
213 {
214     struct MPContext *mpctx = ctx;
215 
216     if (osd_get_render_subs_in_filter(mpctx->osd))
217         update_subtitles(mpctx, pts);
218 }
219 
220 // (track=NULL creates a blank chain, used for lavfi-complex)
reinit_video_chain_src(struct MPContext * mpctx,struct track * track)221 void reinit_video_chain_src(struct MPContext *mpctx, struct track *track)
222 {
223     assert(!mpctx->vo_chain);
224 
225     if (!mpctx->video_out) {
226         struct vo_extra ex = {
227             .input_ctx = mpctx->input,
228             .osd = mpctx->osd,
229             .encode_lavc_ctx = mpctx->encode_lavc_ctx,
230             .wakeup_cb = mp_wakeup_core_cb,
231             .wakeup_ctx = mpctx,
232         };
233         mpctx->video_out = init_best_video_out(mpctx->global, &ex);
234         if (!mpctx->video_out) {
235             MP_FATAL(mpctx, "Error opening/initializing "
236                     "the selected video_out (--vo) device.\n");
237             mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
238             goto err_out;
239         }
240         mpctx->mouse_cursor_visible = true;
241     }
242 
243     update_window_title(mpctx, true);
244 
245     struct vo_chain *vo_c = talloc_zero(NULL, struct vo_chain);
246     mpctx->vo_chain = vo_c;
247     vo_c->log = mpctx->log;
248     vo_c->vo = mpctx->video_out;
249     vo_c->filter =
250         mp_output_chain_create(mpctx->filter_root, MP_OUTPUT_CHAIN_VIDEO);
251     mp_output_chain_set_vo(vo_c->filter, vo_c->vo);
252     vo_c->filter->update_subtitles = filter_update_subtitles;
253     vo_c->filter->update_subtitles_ctx = mpctx;
254 
255     if (track) {
256         vo_c->track = track;
257         track->vo_c = vo_c;
258         if (!init_video_decoder(mpctx, track))
259             goto err_out;
260 
261         vo_c->dec_src = track->dec->f->pins[0];
262         vo_c->filter->container_fps =
263             mp_decoder_wrapper_get_container_fps(track->dec);
264         vo_c->is_coverart = !!track->attached_picture;
265         vo_c->is_sparse = track->stream->still_image || vo_c->is_coverart;
266 
267         if (vo_c->is_coverart)
268             mp_decoder_wrapper_set_coverart_flag(track->dec, true);
269 
270         track->vo_c = vo_c;
271         vo_c->track = track;
272 
273         mp_pin_connect(vo_c->filter->f->pins[0], vo_c->dec_src);
274     }
275 
276     if (!recreate_video_filters(mpctx))
277         goto err_out;
278 
279     update_screensaver_state(mpctx);
280 
281     vo_set_paused(vo_c->vo, get_internal_paused(mpctx));
282 
283     // If we switch on video again, ensure audio position matches up.
284     if (mpctx->ao_chain && mpctx->ao_chain->ao) {
285         ao_reset(mpctx->ao_chain->ao);
286         mpctx->ao_chain->start_pts_known = false;
287         mpctx->audio_status = STATUS_SYNCING;
288     }
289 
290     reset_video_state(mpctx);
291     term_osd_set_subs(mpctx, NULL);
292 
293     return;
294 
295 err_out:
296     uninit_video_chain(mpctx);
297     error_on_track(mpctx, track);
298     handle_force_window(mpctx, true);
299 }
300 
301 // Try to refresh the video by doing a precise seek to the currently displayed
302 // frame. This can go wrong in all sorts of ways, so use sparingly.
mp_force_video_refresh(struct MPContext * mpctx)303 void mp_force_video_refresh(struct MPContext *mpctx)
304 {
305     struct MPOpts *opts = mpctx->opts;
306     struct vo_chain *vo_c = mpctx->vo_chain;
307 
308     if (!vo_c)
309         return;
310 
311     // If not paused, the next frame should come soon enough.
312     if (opts->pause || mpctx->time_frame >= 0.5 ||
313         mpctx->video_status == STATUS_EOF)
314     {
315         issue_refresh_seek(mpctx, MPSEEK_VERY_EXACT);
316     }
317 }
318 
check_framedrop(struct MPContext * mpctx,struct vo_chain * vo_c)319 static void check_framedrop(struct MPContext *mpctx, struct vo_chain *vo_c)
320 {
321     struct MPOpts *opts = mpctx->opts;
322     // check for frame-drop:
323     if (mpctx->video_status == STATUS_PLAYING && !mpctx->paused &&
324         mpctx->audio_status == STATUS_PLAYING && !ao_untimed(mpctx->ao) &&
325         vo_c->track && vo_c->track->dec && (opts->frame_dropping & 2))
326     {
327         float fps = vo_c->filter->container_fps;
328         // it's a crappy heuristic; avoid getting upset by incorrect fps
329         if (fps <= 20 || fps >= 500)
330             return;
331         double frame_time =  1.0 / fps;
332         // try to drop as many frames as we appear to be behind
333         mp_decoder_wrapper_set_frame_drops(vo_c->track->dec,
334             MPCLAMP((mpctx->last_av_difference - 0.010) / frame_time, 0, 100));
335     }
336 }
337 
338 /* Modify video timing to match the audio timeline. There are two main
339  * reasons this is needed. First, video and audio can start from different
340  * positions at beginning of file or after a seek (MPlayer starts both
341  * immediately even if they have different pts). Second, the file can have
342  * audio timestamps that are inconsistent with the duration of the audio
343  * packets, for example two consecutive timestamp values differing by
344  * one second but only a packet with enough samples for half a second
345  * of playback between them.
346  */
adjust_sync(struct MPContext * mpctx,double v_pts,double frame_time)347 static void adjust_sync(struct MPContext *mpctx, double v_pts, double frame_time)
348 {
349     struct MPOpts *opts = mpctx->opts;
350 
351     if (mpctx->audio_status != STATUS_PLAYING)
352         return;
353 
354     double a_pts = written_audio_pts(mpctx) + opts->audio_delay - mpctx->delay;
355     double av_delay = a_pts - v_pts;
356 
357     double change = av_delay * 0.1;
358     double factor = fabs(av_delay) < 0.3 ? 0.1 : 0.4;
359     double max_change = opts->default_max_pts_correction >= 0 ?
360                         opts->default_max_pts_correction : frame_time * factor;
361     if (change < -max_change)
362         change = -max_change;
363     else if (change > max_change)
364         change = max_change;
365     mpctx->delay += change;
366     mpctx->total_avsync_change += change;
367 
368     if (mpctx->display_sync_active)
369         mpctx->total_avsync_change = 0;
370 }
371 
372 // Make the frame at position 0 "known" to the playback logic. This must happen
373 // only once for each frame, so this function has to be called carefully.
374 // Generally, if position 0 gets a new frame, this must be called.
handle_new_frame(struct MPContext * mpctx)375 static void handle_new_frame(struct MPContext *mpctx)
376 {
377     assert(mpctx->num_next_frames >= 1);
378 
379     double frame_time = 0;
380     double pts = mpctx->next_frames[0]->pts;
381     bool is_sparse = mpctx->vo_chain && mpctx->vo_chain->is_sparse;
382 
383     if (mpctx->video_pts != MP_NOPTS_VALUE) {
384         frame_time = pts - mpctx->video_pts;
385         double tolerance = mpctx->demuxer->ts_resets_possible &&
386                            !is_sparse ? 5 : 1e4;
387         if (frame_time <= 0 || frame_time >= tolerance) {
388             // Assume a discontinuity.
389             MP_WARN(mpctx, "Invalid video timestamp: %f -> %f\n",
390                     mpctx->video_pts, pts);
391             frame_time = 0;
392         }
393     }
394     mpctx->delay -= frame_time;
395     mpctx->time_frame += frame_time / mpctx->video_speed;
396     if (mpctx->video_status >= STATUS_PLAYING)
397         adjust_sync(mpctx, pts, frame_time);
398     MP_TRACE(mpctx, "frametime=%5.3f\n", frame_time);
399 }
400 
401 // Remove the first frame in mpctx->next_frames
shift_frames(struct MPContext * mpctx)402 static void shift_frames(struct MPContext *mpctx)
403 {
404     if (mpctx->num_next_frames < 1)
405         return;
406     talloc_free(mpctx->next_frames[0]);
407     for (int n = 0; n < mpctx->num_next_frames - 1; n++)
408         mpctx->next_frames[n] = mpctx->next_frames[n + 1];
409     mpctx->num_next_frames -= 1;
410 }
411 
use_video_lookahead(struct MPContext * mpctx)412 static bool use_video_lookahead(struct MPContext *mpctx)
413 {
414     return mpctx->video_out &&
415            !(mpctx->video_out->driver->caps & VO_CAP_NORETAIN) &&
416            !(mpctx->opts->untimed || mpctx->video_out->driver->untimed) &&
417            !mpctx->opts->video_latency_hacks;
418 }
419 
get_req_frames(struct MPContext * mpctx,bool eof)420 static int get_req_frames(struct MPContext *mpctx, bool eof)
421 {
422     // On EOF, drain all frames.
423     if (eof)
424         return 1;
425 
426     if (!use_video_lookahead(mpctx))
427         return 1;
428 
429     if (mpctx->vo_chain && mpctx->vo_chain->is_sparse)
430         return 1;
431 
432     // Normally require at least 2 frames, so we can compute a frame duration.
433     int min = 2;
434 
435     // On the first frame, output a new frame as quickly as possible.
436     if (mpctx->video_pts == MP_NOPTS_VALUE)
437         return min;
438 
439     int req = vo_get_num_req_frames(mpctx->video_out);
440     return MPCLAMP(req, min, MP_ARRAY_SIZE(mpctx->next_frames) - 1);
441 }
442 
443 // Whether it's fine to call add_new_frame() now.
needs_new_frame(struct MPContext * mpctx)444 static bool needs_new_frame(struct MPContext *mpctx)
445 {
446     return mpctx->num_next_frames < get_req_frames(mpctx, false);
447 }
448 
449 // Queue a frame to mpctx->next_frames[]. Call only if needs_new_frame() signals ok.
add_new_frame(struct MPContext * mpctx,struct mp_image * frame)450 static void add_new_frame(struct MPContext *mpctx, struct mp_image *frame)
451 {
452     assert(mpctx->num_next_frames < MP_ARRAY_SIZE(mpctx->next_frames));
453     assert(frame);
454     mpctx->next_frames[mpctx->num_next_frames++] = frame;
455     if (mpctx->num_next_frames == 1)
456         handle_new_frame(mpctx);
457 }
458 
459 // Enough video filtered already to push one frame to the VO?
460 // Set eof to true if no new frames are to be expected.
have_new_frame(struct MPContext * mpctx,bool eof)461 static bool have_new_frame(struct MPContext *mpctx, bool eof)
462 {
463     return mpctx->num_next_frames >= get_req_frames(mpctx, eof);
464 }
465 
466 // Fill mpctx->next_frames[] with a newly filtered or decoded image.
467 // logical_eof: is set to true if there is EOF after currently queued frames
468 // returns VD_* code
video_output_image(struct MPContext * mpctx,bool * logical_eof)469 static int video_output_image(struct MPContext *mpctx, bool *logical_eof)
470 {
471     struct vo_chain *vo_c = mpctx->vo_chain;
472     bool hrseek = false;
473     double hrseek_pts = mpctx->hrseek_pts;
474     double tolerance = mpctx->hrseek_backstep ? 0 : .005;
475     if (mpctx->video_status == STATUS_SYNCING) {
476         hrseek = mpctx->hrseek_active;
477         // playback_pts is normally only set when audio and video have started
478         // playing normally. If video is in syncing mode, then this must mean
479         // video was just enabled via track switching - skip to current time.
480         if (!hrseek && mpctx->playback_pts != MP_NOPTS_VALUE) {
481             hrseek = true;
482             hrseek_pts = mpctx->playback_pts;
483         }
484     }
485 
486     if (vo_c->is_coverart) {
487         *logical_eof = true;
488         if (vo_has_frame(mpctx->video_out))
489             return VD_EOF;
490         hrseek = false;
491     }
492 
493     if (have_new_frame(mpctx, false))
494         return VD_NEW_FRAME;
495 
496     // Get a new frame if we need one.
497     int r = VD_PROGRESS;
498     if (needs_new_frame(mpctx)) {
499         // Filter a new frame.
500         struct mp_image *img = NULL;
501         struct mp_frame frame = mp_pin_out_read(vo_c->filter->f->pins[1]);
502         if (frame.type == MP_FRAME_NONE) {
503             r = vo_c->filter->got_output_eof ? VD_EOF : VD_WAIT;
504         } else if (frame.type == MP_FRAME_EOF) {
505             r = VD_EOF;
506         } else if (frame.type == MP_FRAME_VIDEO) {
507             img = frame.data;
508         } else {
509             MP_ERR(mpctx, "unexpected frame type %s\n",
510                    mp_frame_type_str(frame.type));
511             mp_frame_unref(&frame);
512             return VD_ERROR;
513         }
514         if (img) {
515             double endpts = get_play_end_pts(mpctx);
516             if (endpts != MP_NOPTS_VALUE)
517                 endpts *= mpctx->play_dir;
518             if ((endpts != MP_NOPTS_VALUE && img->pts >= endpts) ||
519                 mpctx->max_frames == 0)
520             {
521                 mp_pin_out_unread(vo_c->filter->f->pins[1], frame);
522                 img = NULL;
523                 r = VD_EOF;
524             } else if (hrseek && (img->pts < hrseek_pts - tolerance ||
525                                   mpctx->hrseek_lastframe))
526             {
527                 /* just skip - but save in case it was the last frame */
528                 mp_image_setrefp(&mpctx->saved_frame, img);
529             } else {
530                 if (hrseek && mpctx->hrseek_backstep) {
531                     if (mpctx->saved_frame) {
532                         add_new_frame(mpctx, mpctx->saved_frame);
533                         mpctx->saved_frame = NULL;
534                     } else {
535                         MP_WARN(mpctx, "Backstep failed.\n");
536                     }
537                     mpctx->hrseek_backstep = false;
538                 }
539                 mp_image_unrefp(&mpctx->saved_frame);
540                 add_new_frame(mpctx, img);
541                 img = NULL;
542             }
543             talloc_free(img);
544         }
545     }
546 
547     if (!hrseek)
548         mp_image_unrefp(&mpctx->saved_frame);
549 
550     if (r == VD_EOF) {
551         // If hr-seek went past EOF, use the last frame.
552         if (mpctx->saved_frame)
553             add_new_frame(mpctx, mpctx->saved_frame);
554         mpctx->saved_frame = NULL;
555         *logical_eof = true;
556     }
557 
558     return have_new_frame(mpctx, r <= 0) ? VD_NEW_FRAME : r;
559 }
560 
check_for_hwdec_fallback(struct MPContext * mpctx)561 static bool check_for_hwdec_fallback(struct MPContext *mpctx)
562 {
563     struct vo_chain *vo_c = mpctx->vo_chain;
564 
565     if (!vo_c->filter->failed_output_conversion || !vo_c->track)
566         return false;
567 
568     if (mp_decoder_wrapper_control(vo_c->track->dec,
569                             VDCTRL_FORCE_HWDEC_FALLBACK, NULL) != CONTROL_OK)
570         return false;
571 
572     mp_output_chain_reset_harder(vo_c->filter);
573     return true;
574 }
575 
576 /* Update avsync before a new video frame is displayed. Actually, this can be
577  * called arbitrarily often before the actual display.
578  * This adjusts the time of the next video frame */
update_avsync_before_frame(struct MPContext * mpctx)579 static void update_avsync_before_frame(struct MPContext *mpctx)
580 {
581     struct MPOpts *opts = mpctx->opts;
582     struct vo *vo = mpctx->video_out;
583 
584     if (mpctx->video_status < STATUS_READY) {
585         mpctx->time_frame = 0;
586     } else if (mpctx->display_sync_active || opts->video_sync == VS_NONE) {
587         // don't touch the timing
588     } else if (mpctx->audio_status == STATUS_PLAYING &&
589                mpctx->video_status == STATUS_PLAYING &&
590                !ao_untimed(mpctx->ao))
591     {
592         double buffered_audio = ao_get_delay(mpctx->ao);
593 
594         double predicted = mpctx->delay / mpctx->video_speed +
595                            mpctx->time_frame;
596         double difference = buffered_audio - predicted;
597         MP_STATS(mpctx, "value %f audio-diff", difference);
598 
599         if (opts->autosync) {
600             /* Smooth reported playback position from AO by averaging
601              * it with the value expected based on previus value and
602              * time elapsed since then. May help smooth video timing
603              * with audio output that have inaccurate position reporting.
604              * This is badly implemented; the behavior of the smoothing
605              * now undesirably depends on how often this code runs
606              * (mainly depends on video frame rate). */
607             buffered_audio = predicted + difference / opts->autosync;
608         }
609 
610         mpctx->time_frame = buffered_audio - mpctx->delay / mpctx->video_speed;
611     } else {
612         /* If we're more than 200 ms behind the right playback
613          * position, don't try to speed up display of following
614          * frames to catch up; continue with default speed from
615          * the current frame instead.
616          * If untimed is set always output frames immediately
617          * without sleeping.
618          */
619         if (mpctx->time_frame < -0.2 || opts->untimed || vo->driver->untimed)
620             mpctx->time_frame = 0;
621     }
622 }
623 
624 // Update the A/V sync difference when a new video frame is being shown.
update_av_diff(struct MPContext * mpctx,double offset)625 static void update_av_diff(struct MPContext *mpctx, double offset)
626 {
627     struct MPOpts *opts = mpctx->opts;
628 
629     mpctx->last_av_difference = 0;
630 
631     if (mpctx->audio_status != STATUS_PLAYING ||
632         mpctx->video_status != STATUS_PLAYING)
633         return;
634 
635     if (mpctx->vo_chain && mpctx->vo_chain->is_sparse)
636         return;
637 
638     double a_pos = playing_audio_pts(mpctx);
639     if (a_pos != MP_NOPTS_VALUE && mpctx->video_pts != MP_NOPTS_VALUE) {
640         mpctx->last_av_difference = a_pos - mpctx->video_pts
641                                   + opts->audio_delay + offset;
642     }
643 
644     if (fabs(mpctx->last_av_difference) > 0.5 && !mpctx->drop_message_shown) {
645         MP_WARN(mpctx, "%s", av_desync_help_text);
646         mpctx->drop_message_shown = true;
647     }
648 }
649 
calc_average_frame_duration(struct MPContext * mpctx)650 double calc_average_frame_duration(struct MPContext *mpctx)
651 {
652     double total = 0;
653     int num = 0;
654     for (int n = 0; n < mpctx->num_past_frames; n++) {
655         double dur = mpctx->past_frames[n].approx_duration;
656         if (dur <= 0)
657             continue;
658         total += dur;
659         num += 1;
660     }
661     return num > 0 ? total / num : 0;
662 }
663 
664 // Find a speed factor such that the display FPS is an integer multiple of the
665 // effective video FPS. If this is not possible, try to do it for multiples,
666 // which still leads to an improved end result.
667 // Both parameters are durations in seconds.
calc_best_speed(double vsync,double frame,int max_factor)668 static double calc_best_speed(double vsync, double frame, int max_factor)
669 {
670     double ratio = frame / vsync;
671     double best_scale = -1;
672     double best_dev = INFINITY;
673     for (int factor = 1; factor <= max_factor; factor++) {
674         double scale = ratio * factor / rint(ratio * factor);
675         double dev = fabs(scale - 1);
676         if (dev < best_dev) {
677             best_scale = scale;
678             best_dev = dev;
679         }
680     }
681     return best_scale;
682 }
683 
find_best_speed(struct MPContext * mpctx,double vsync)684 static double find_best_speed(struct MPContext *mpctx, double vsync)
685 {
686     double total = 0;
687     int num = 0;
688     for (int n = 0; n < mpctx->num_past_frames; n++) {
689         double dur = mpctx->past_frames[n].approx_duration;
690         if (dur <= 0)
691             continue;
692         total += calc_best_speed(vsync, dur / mpctx->opts->playback_speed,
693                                  mpctx->opts->sync_max_factor);
694         num++;
695     }
696     return num > 0 ? total / num : 1;
697 }
698 
using_spdif_passthrough(struct MPContext * mpctx)699 static bool using_spdif_passthrough(struct MPContext *mpctx)
700 {
701     if (mpctx->ao_chain && mpctx->ao_chain->ao) {
702         int samplerate;
703         int format;
704         struct mp_chmap channels;
705         ao_get_format(mpctx->ao_chain->ao, &samplerate, &format, &channels);
706         return !af_fmt_is_pcm(format);
707     }
708     return false;
709 }
710 
711 // Compute the relative audio speed difference by taking A/V dsync into account.
compute_audio_drift(struct MPContext * mpctx,double vsync)712 static double compute_audio_drift(struct MPContext *mpctx, double vsync)
713 {
714     // Least-squares linear regression, using relative real time for x, and
715     // audio desync for y. Assume speed didn't change for the frames we're
716     // looking at for simplicity. This also should actually use the realtime
717     // (minus paused time) for x, but use vsync scheduling points instead.
718     if (mpctx->num_past_frames <= 10)
719         return NAN;
720     int num = mpctx->num_past_frames - 1;
721     double sum_x = 0, sum_y = 0, sum_xy = 0, sum_xx = 0;
722     double x = 0;
723     for (int n = 0; n < num; n++) {
724         struct frame_info *frame = &mpctx->past_frames[n + 1];
725         if (frame->num_vsyncs < 0)
726             return NAN;
727         double y = frame->av_diff;
728         sum_x += x;
729         sum_y += y;
730         sum_xy += x * y;
731         sum_xx += x * x;
732         x -= frame->num_vsyncs * vsync;
733     }
734     return (sum_x * sum_y - num * sum_xy) / (sum_x * sum_x - num * sum_xx);
735 }
736 
adjust_audio_resample_speed(struct MPContext * mpctx,double vsync)737 static void adjust_audio_resample_speed(struct MPContext *mpctx, double vsync)
738 {
739     struct MPOpts *opts = mpctx->opts;
740     int mode = opts->video_sync;
741 
742     if (mode != VS_DISP_RESAMPLE || mpctx->audio_status != STATUS_PLAYING) {
743         mpctx->speed_factor_a = mpctx->speed_factor_v;
744         return;
745     }
746 
747     // Try to smooth out audio timing drifts. This can happen if either
748     // video isn't playing at expected speed, or audio is not playing at
749     // the requested speed. Both are unavoidable.
750     // The audio desync is made up of 2 parts: 1. drift due to rounding
751     // errors and imperfect information, and 2. an offset, due to
752     // unaligned audio/video start, or disruptive events halting audio
753     // or video for a small time.
754     // Instead of trying to be clever, just apply an awfully dumb drift
755     // compensation with a constant factor, which does what we want. In
756     // theory we could calculate the exact drift compensation needed,
757     // but it likely would be wrong anyway, and we'd run into the same
758     // issues again, except with more complex code.
759     // 1 means drifts to positive, -1 means drifts to negative
760     double max_drift = vsync / 2;
761     double av_diff = mpctx->last_av_difference;
762     int new = mpctx->display_sync_drift_dir;
763     if (av_diff * -mpctx->display_sync_drift_dir >= 0)
764         new = 0;
765     if (fabs(av_diff) > max_drift)
766         new = av_diff >= 0 ? 1 : -1;
767 
768     bool change = mpctx->display_sync_drift_dir != new;
769     if (new || change) {
770         if (change)
771             MP_VERBOSE(mpctx, "Change display sync audio drift: %d\n", new);
772         mpctx->display_sync_drift_dir = new;
773 
774         double max_correct = opts->sync_max_audio_change / 100;
775         double audio_factor = 1 + max_correct * -mpctx->display_sync_drift_dir;
776 
777         if (new == 0) {
778             // If we're resetting, actually try to be clever and pick a speed
779             // which compensates the general drift we're getting.
780             double drift = compute_audio_drift(mpctx, vsync);
781             if (isnormal(drift)) {
782                 // other = will be multiplied with audio_factor for final speed
783                 double other = mpctx->opts->playback_speed * mpctx->speed_factor_v;
784                 audio_factor = (mpctx->audio_speed - drift) / other;
785                 MP_VERBOSE(mpctx, "Compensation factor: %f\n", audio_factor);
786             }
787         }
788 
789         audio_factor = MPCLAMP(audio_factor, 1 - max_correct, 1 + max_correct);
790         mpctx->speed_factor_a = audio_factor * mpctx->speed_factor_v;
791     }
792 }
793 
794 // Manipulate frame timing for display sync, or do nothing for normal timing.
handle_display_sync_frame(struct MPContext * mpctx,struct vo_frame * frame)795 static void handle_display_sync_frame(struct MPContext *mpctx,
796                                       struct vo_frame *frame)
797 {
798     struct MPOpts *opts = mpctx->opts;
799     struct vo *vo = mpctx->video_out;
800     int mode = opts->video_sync;
801 
802     if (!mpctx->display_sync_active) {
803         mpctx->display_sync_error = 0.0;
804         mpctx->display_sync_drift_dir = 0;
805     }
806 
807     mpctx->display_sync_active = false;
808 
809     if (!VS_IS_DISP(mode))
810         return;
811     bool resample = mode == VS_DISP_RESAMPLE || mode == VS_DISP_RESAMPLE_VDROP ||
812                     mode == VS_DISP_RESAMPLE_NONE;
813     bool drop = mode == VS_DISP_VDROP || mode == VS_DISP_RESAMPLE ||
814                 mode == VS_DISP_ADROP || mode == VS_DISP_RESAMPLE_VDROP;
815     drop &= frame->can_drop;
816 
817     if (resample && using_spdif_passthrough(mpctx))
818         return;
819 
820     double vsync = vo_get_vsync_interval(vo) / 1e6;
821     if (vsync <= 0)
822         return;
823 
824     double adjusted_duration = MPMAX(0, mpctx->past_frames[0].approx_duration);
825     adjusted_duration /= opts->playback_speed;
826     if (adjusted_duration > 0.5)
827         return;
828 
829     mpctx->speed_factor_v = 1.0;
830     if (mode != VS_DISP_VDROP) {
831         double best = find_best_speed(mpctx, vsync);
832         // If it doesn't work, play at normal speed.
833         if (fabs(best - 1.0) <= opts->sync_max_video_change / 100)
834             mpctx->speed_factor_v = best;
835     }
836 
837     // Determine for how many vsyncs a frame should be displayed. This can be
838     // e.g. 2 for 30hz on a 60hz display. It can also be 0 if the video
839     // framerate is higher than the display framerate.
840     // We use the speed-adjusted (i.e. real) frame duration for this.
841     double frame_duration = adjusted_duration / mpctx->speed_factor_v;
842     double ratio = (frame_duration + mpctx->display_sync_error) / vsync;
843     int num_vsyncs = MPMAX(lrint(ratio), 0);
844     double prev_error = mpctx->display_sync_error;
845     mpctx->display_sync_error += frame_duration - num_vsyncs * vsync;
846 
847     MP_TRACE(mpctx, "s=%f vsyncs=%d dur=%f ratio=%f err=%.20f (%f/%f)\n",
848             mpctx->speed_factor_v, num_vsyncs, adjusted_duration, ratio,
849             mpctx->display_sync_error, mpctx->display_sync_error / vsync,
850             mpctx->display_sync_error / frame_duration);
851 
852     double av_diff = mpctx->last_av_difference;
853     MP_STATS(mpctx, "value %f avdiff", av_diff);
854 
855     // Intended number of additional display frames to drop (<0) or repeat (>0)
856     int drop_repeat = 0;
857 
858     // If we are too far ahead/behind, attempt to drop/repeat frames.
859     // Tolerate some desync to avoid frame dropping due to jitter.
860     if (drop && fabs(av_diff) >= 0.020 && fabs(av_diff) / vsync >= 1)
861         drop_repeat = -av_diff / vsync; // round towards 0
862 
863     // We can only drop all frames at most. We can repeat much more frames,
864     // but we still limit it to 10 times the original frames to avoid that
865     // corner cases or exceptional situations cause too much havoc.
866     drop_repeat = MPCLAMP(drop_repeat, -num_vsyncs, num_vsyncs * 10);
867     num_vsyncs += drop_repeat;
868 
869     // Always show the first frame.
870     if (mpctx->num_past_frames <= 1 && num_vsyncs < 1)
871         num_vsyncs = 1;
872 
873     // Estimate the video position, so we can calculate a good A/V difference
874     // value below. This is used to estimate A/V drift.
875     double time_left = vo_get_delay(vo);
876 
877     // We also know that the timing is (necessarily) off, because we have to
878     // align frame timings on the vsync boundaries. This is unavoidable, and
879     // for the sake of the A/V sync calculations we pretend it's perfect.
880     time_left += prev_error;
881     // Likewise, we know sync is off, but is going to be compensated.
882     time_left += drop_repeat * vsync;
883 
884     // If syncing took too long, disregard timing of the first frame.
885     if (mpctx->num_past_frames == 2 && time_left < 0) {
886         vo_discard_timing_info(vo);
887         time_left = 0;
888     }
889 
890     if (drop_repeat) {
891         mpctx->mistimed_frames_total += 1;
892         MP_STATS(mpctx, "mistimed");
893     }
894 
895     mpctx->total_avsync_change = 0;
896     update_av_diff(mpctx, time_left * opts->playback_speed);
897 
898     mpctx->past_frames[0].num_vsyncs = num_vsyncs;
899     mpctx->past_frames[0].av_diff = mpctx->last_av_difference;
900 
901     if (resample || mode == VS_DISP_ADROP) {
902         adjust_audio_resample_speed(mpctx, vsync);
903     } else {
904         mpctx->speed_factor_a = 1.0;
905     }
906 
907     // A bad guess, only needed when reverting to audio sync.
908     mpctx->time_frame = time_left;
909 
910     frame->vsync_interval = vsync;
911     frame->vsync_offset = -prev_error;
912     frame->ideal_frame_duration = frame_duration;
913     frame->num_vsyncs = num_vsyncs;
914     frame->display_synced = true;
915 
916     mpctx->display_sync_active = true;
917     update_playback_speed(mpctx);
918 
919     MP_STATS(mpctx, "value %f aspeed", mpctx->speed_factor_a - 1);
920     MP_STATS(mpctx, "value %f vspeed", mpctx->speed_factor_v - 1);
921 }
922 
schedule_frame(struct MPContext * mpctx,struct vo_frame * frame)923 static void schedule_frame(struct MPContext *mpctx, struct vo_frame *frame)
924 {
925     handle_display_sync_frame(mpctx, frame);
926 
927     if (mpctx->num_past_frames > 1 &&
928         ((mpctx->past_frames[1].num_vsyncs >= 0) != mpctx->display_sync_active))
929     {
930         MP_VERBOSE(mpctx, "Video sync mode %s.\n",
931                    mpctx->display_sync_active ? "enabled" : "disabled");
932     }
933 
934     if (!mpctx->display_sync_active) {
935         mpctx->speed_factor_a = 1.0;
936         mpctx->speed_factor_v = 1.0;
937         update_playback_speed(mpctx);
938 
939         update_av_diff(mpctx, mpctx->time_frame > 0 ?
940             mpctx->time_frame * mpctx->video_speed : 0);
941     }
942 }
943 
944 // Determine the mpctx->past_frames[0] frame duration.
calculate_frame_duration(struct MPContext * mpctx)945 static void calculate_frame_duration(struct MPContext *mpctx)
946 {
947     struct vo_chain *vo_c = mpctx->vo_chain;
948     assert(mpctx->num_past_frames >= 1 && mpctx->num_next_frames >= 1);
949 
950     double demux_duration = vo_c->filter->container_fps > 0
951                             ? 1.0 / vo_c->filter->container_fps : -1;
952     double duration = demux_duration;
953 
954     if (mpctx->num_next_frames >= 2) {
955         double pts0 = mpctx->next_frames[0]->pts;
956         double pts1 = mpctx->next_frames[1]->pts;
957         if (pts0 != MP_NOPTS_VALUE && pts1 != MP_NOPTS_VALUE && pts1 >= pts0)
958             duration = pts1 - pts0;
959     }
960 
961     // The following code tries to compensate for rounded Matroska timestamps
962     // by "unrounding" frame durations, or if not possible, approximating them.
963     // These formats usually round on 1ms. Some muxers do this incorrectly,
964     // and might go off by 1ms more, and compensate for it later by an equal
965     // rounding error into the opposite direction.
966     double tolerance = 0.001 * 3 + 0.0001;
967 
968     double total = 0;
969     int num_dur = 0;
970     for (int n = 1; n < mpctx->num_past_frames; n++) {
971         // Eliminate likely outliers using a really dumb heuristic.
972         double dur = mpctx->past_frames[n].duration;
973         if (dur <= 0 || fabs(dur - duration) >= tolerance)
974             break;
975         total += dur;
976         num_dur += 1;
977     }
978     double approx_duration = num_dur > 0 ? total / num_dur : duration;
979 
980     // Try if the demuxer frame rate fits - if so, just take it.
981     if (demux_duration > 0) {
982         // Note that even if each timestamp is within rounding tolerance, it
983         // could literally not add up (e.g. if demuxer FPS is rounded itself).
984         if (fabs(duration - demux_duration) < tolerance &&
985             fabs(total - demux_duration * num_dur) < tolerance &&
986             (num_dur >= 16 || num_dur >= mpctx->num_past_frames - 4))
987         {
988             approx_duration = demux_duration;
989         }
990     }
991 
992     mpctx->past_frames[0].duration = duration;
993     mpctx->past_frames[0].approx_duration = approx_duration;
994 
995     MP_STATS(mpctx, "value %f frame-duration", MPMAX(0, duration));
996     MP_STATS(mpctx, "value %f frame-duration-approx", MPMAX(0, approx_duration));
997 }
998 
write_video(struct MPContext * mpctx)999 void write_video(struct MPContext *mpctx)
1000 {
1001     struct MPOpts *opts = mpctx->opts;
1002 
1003     if (!mpctx->vo_chain)
1004         return;
1005     struct track *track = mpctx->vo_chain->track;
1006     struct vo_chain *vo_c = mpctx->vo_chain;
1007     struct vo *vo = vo_c->vo;
1008 
1009     if (vo_c->filter->reconfig_happened) {
1010         mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
1011         vo_c->filter->reconfig_happened = false;
1012     }
1013 
1014     // Actual playback starts when both audio and video are ready.
1015     if (mpctx->video_status == STATUS_READY)
1016         return;
1017 
1018     if (mpctx->paused && mpctx->video_status >= STATUS_READY)
1019         return;
1020 
1021     bool logical_eof = false;
1022     int r = video_output_image(mpctx, &logical_eof);
1023     MP_TRACE(mpctx, "video_output_image: r=%d/eof=%d/st=%s\n", r, logical_eof,
1024              mp_status_str(mpctx->video_status));
1025 
1026     if (r < 0)
1027         goto error;
1028 
1029     if (r == VD_WAIT) {
1030         // Heuristic to detect underruns.
1031         if (mpctx->video_status == STATUS_PLAYING && !vo_still_displaying(vo) &&
1032             !vo_c->underrun_signaled)
1033         {
1034             vo_c->underrun = true;
1035             vo_c->underrun_signaled = true;
1036         }
1037         // Demuxer will wake us up for more packets to decode.
1038         return;
1039     }
1040 
1041     if (r == VD_EOF) {
1042         if (check_for_hwdec_fallback(mpctx))
1043             return;
1044         if (vo_c->filter->failed_output_conversion)
1045             goto error;
1046 
1047         mpctx->delay = 0;
1048         mpctx->last_av_difference = 0;
1049 
1050         if (mpctx->video_status <= STATUS_PLAYING) {
1051             mpctx->video_status = STATUS_DRAINING;
1052             get_relative_time(mpctx);
1053             if (vo_c->is_sparse && !mpctx->ao_chain) {
1054                 MP_VERBOSE(mpctx, "assuming this is an image\n");
1055                 mpctx->time_frame += opts->image_display_duration;
1056             } else if (mpctx->last_frame_duration > 0) {
1057                 MP_VERBOSE(mpctx, "using demuxer frame duration for last frame\n");
1058                 mpctx->time_frame += mpctx->last_frame_duration;
1059             } else {
1060                 mpctx->time_frame = 0;
1061             }
1062             // Encode mode can't honor this; it'll only delay finishing.
1063             if (mpctx->encode_lavc_ctx)
1064                 mpctx->time_frame = 0;
1065         }
1066 
1067         // Wait for the VO to signal actual EOF, then exit if the frame timer
1068         // has expired.
1069         bool has_frame = vo_has_frame(vo); // maybe not configured
1070         if (mpctx->video_status == STATUS_DRAINING &&
1071             (vo_is_ready_for_frame(vo, -1) || !has_frame))
1072         {
1073             mpctx->time_frame -= get_relative_time(mpctx);
1074             mp_set_timeout(mpctx, mpctx->time_frame);
1075             if (mpctx->time_frame <= 0 || !has_frame) {
1076                 MP_VERBOSE(mpctx, "video EOF reached\n");
1077                 mpctx->video_status = STATUS_EOF;
1078             }
1079         }
1080 
1081         MP_DBG(mpctx, "video EOF (status=%d)\n", mpctx->video_status);
1082         return;
1083     }
1084 
1085     if (mpctx->video_status > STATUS_PLAYING)
1086         mpctx->video_status = STATUS_PLAYING;
1087 
1088     if (r != VD_NEW_FRAME) {
1089         mp_wakeup_core(mpctx); // Decode more in next iteration.
1090         return;
1091     }
1092 
1093     if (logical_eof && !mpctx->num_past_frames && mpctx->num_next_frames == 1 &&
1094         use_video_lookahead(mpctx) && !vo_c->is_sparse)
1095     {
1096         // Too much danger to accidentally mark video as sparse when e.g.
1097         // seeking exactly to the last frame, so as a heuristic, do this only
1098         // if it looks like the "first" video frame (unreliable, but often
1099         // works out well). Helps with seeking with single-image video tracks,
1100         // as well as detecting whether as video track is really an image.
1101         if (mpctx->next_frames[0]->pts == 0) {
1102             MP_VERBOSE(mpctx, "assuming single-image video stream\n");
1103             vo_c->is_sparse = true;
1104         }
1105     }
1106 
1107     // Filter output is different from VO input?
1108     struct mp_image_params p = mpctx->next_frames[0]->params;
1109     if (!vo->params || !mp_image_params_equal(&p, vo->params)) {
1110         // Changing config deletes the current frame; wait until it's finished.
1111         if (vo_still_displaying(vo)) {
1112             vo_request_wakeup_on_done(vo);
1113             return;
1114         }
1115 
1116         const struct vo_driver *info = mpctx->video_out->driver;
1117         char extra[20] = {0};
1118         if (p.p_w != p.p_h) {
1119             int d_w, d_h;
1120             mp_image_params_get_dsize(&p, &d_w, &d_h);
1121             snprintf(extra, sizeof(extra), " => %dx%d", d_w, d_h);
1122         }
1123         char sfmt[20] = {0};
1124         if (p.hw_subfmt)
1125             snprintf(sfmt, sizeof(sfmt), "[%s]", mp_imgfmt_to_name(p.hw_subfmt));
1126         MP_INFO(mpctx, "VO: [%s] %dx%d%s %s%s\n",
1127                 info->name, p.w, p.h, extra, mp_imgfmt_to_name(p.imgfmt), sfmt);
1128         MP_VERBOSE(mpctx, "VO: Description: %s\n", info->description);
1129 
1130         int vo_r = vo_reconfig2(vo, mpctx->next_frames[0]);
1131         if (vo_r < 0) {
1132             mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
1133             goto error;
1134         }
1135         mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
1136     }
1137 
1138     mpctx->time_frame -= get_relative_time(mpctx);
1139     update_avsync_before_frame(mpctx);
1140 
1141     // Enforce timing subtitles to video frames.
1142     osd_set_force_video_pts(mpctx->osd, MP_NOPTS_VALUE);
1143 
1144     if (!update_subtitles(mpctx, mpctx->next_frames[0]->pts)) {
1145         MP_VERBOSE(mpctx, "Video frame delayed due to waiting on subtitles.\n");
1146         return;
1147     }
1148 
1149     double time_frame = MPMAX(mpctx->time_frame, -1);
1150     int64_t pts = mp_time_us() + (int64_t)(time_frame * 1e6);
1151 
1152     // wait until VO wakes us up to get more frames
1153     // (NB: in theory, the 1st frame after display sync mode change uses the
1154     //      wrong waiting mode)
1155     if (!vo_is_ready_for_frame(vo, mpctx->display_sync_active ? -1 : pts))
1156         return;
1157 
1158     assert(mpctx->num_next_frames >= 1);
1159 
1160     if (mpctx->num_past_frames >= MAX_NUM_VO_PTS)
1161         mpctx->num_past_frames--;
1162     MP_TARRAY_INSERT_AT(mpctx, mpctx->past_frames, mpctx->num_past_frames, 0,
1163                         (struct frame_info){0});
1164     mpctx->past_frames[0] = (struct frame_info){
1165         .pts = mpctx->next_frames[0]->pts,
1166         .num_vsyncs = -1,
1167     };
1168     calculate_frame_duration(mpctx);
1169 
1170     int req = vo_get_num_req_frames(mpctx->video_out);
1171     assert(req >= 1 && req <= VO_MAX_REQ_FRAMES);
1172     struct vo_frame dummy = {
1173         .pts = pts,
1174         .duration = -1,
1175         .still = mpctx->step_frames > 0,
1176         .can_drop = opts->frame_dropping & 1,
1177         .num_frames = MPMIN(mpctx->num_next_frames, req),
1178         .num_vsyncs = 1,
1179     };
1180     for (int n = 0; n < dummy.num_frames; n++)
1181         dummy.frames[n] = mpctx->next_frames[n];
1182     struct vo_frame *frame = vo_frame_ref(&dummy);
1183 
1184     double diff = mpctx->past_frames[0].approx_duration;
1185     if (opts->untimed || vo->driver->untimed)
1186         diff = -1; // disable frame dropping and aspects of frame timing
1187     if (diff >= 0) {
1188         // expected A/V sync correction is ignored
1189         diff /= mpctx->video_speed;
1190         if (mpctx->time_frame < 0)
1191             diff += mpctx->time_frame;
1192         frame->duration = MPCLAMP(diff, 0, 10) * 1e6;
1193     }
1194 
1195     mpctx->video_pts = mpctx->next_frames[0]->pts;
1196     mpctx->last_frame_duration =
1197         mpctx->next_frames[0]->pkt_duration / mpctx->video_speed;
1198 
1199     shift_frames(mpctx);
1200 
1201     schedule_frame(mpctx, frame);
1202 
1203     mpctx->osd_force_update = true;
1204     update_osd_msg(mpctx);
1205 
1206     vo_queue_frame(vo, frame);
1207 
1208     check_framedrop(mpctx, vo_c);
1209 
1210     // The frames were shifted down; "initialize" the new first entry.
1211     if (mpctx->num_next_frames >= 1)
1212         handle_new_frame(mpctx);
1213 
1214     mpctx->shown_vframes++;
1215     if (mpctx->video_status < STATUS_PLAYING) {
1216         mpctx->video_status = STATUS_READY;
1217         // After a seek, make sure to wait until the first frame is visible.
1218         if (!opts->video_latency_hacks) {
1219             vo_wait_frame(vo);
1220             MP_VERBOSE(mpctx, "first video frame after restart shown\n");
1221         }
1222     }
1223 
1224     mp_notify(mpctx, MPV_EVENT_TICK, NULL);
1225 
1226     // hr-seek past EOF -> returns last frame, but terminates playback. The
1227     // early EOF is needed to trigger the exit before the next seek is executed.
1228     // Always using early EOF breaks other cases, like images.
1229     if (logical_eof && !mpctx->num_next_frames && mpctx->ao_chain)
1230         mpctx->video_status = STATUS_EOF;
1231 
1232     if (mpctx->video_status != STATUS_EOF) {
1233         if (mpctx->step_frames > 0) {
1234             mpctx->step_frames--;
1235             if (!mpctx->step_frames)
1236                 set_pause_state(mpctx, true);
1237         }
1238         if (mpctx->max_frames == 0 && !mpctx->stop_play)
1239             mpctx->stop_play = AT_END_OF_FILE;
1240         if (mpctx->max_frames > 0)
1241             mpctx->max_frames--;
1242     }
1243 
1244     vo_c->underrun_signaled = false;
1245 
1246     if (mpctx->video_status == STATUS_EOF || mpctx->stop_play)
1247         mp_wakeup_core(mpctx);
1248     return;
1249 
1250 error:
1251     MP_FATAL(mpctx, "Could not initialize video chain.\n");
1252     uninit_video_chain(mpctx);
1253     error_on_track(mpctx, track);
1254     handle_force_window(mpctx, true);
1255     mp_wakeup_core(mpctx);
1256 }
1257