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