vlc | branch: master | Steve Lhomme <[email protected]> | Tue Nov 17 13:52:20 2020 +0100| [6f6ba9cec8a6a762f30eb458382a7574a005fd67] | committer: Steve Lhomme
video_output: rework the decision to use the next picture to display Until now, in normal playback (ie not frame by frame), the way to skip to the next frame to display was : * get displayed.current * get displayed.next * if displayed.next has time to render use it to replace displayed.current * the vout thread waits until the deadline to render displayed.current Now we don't use displayed.next anymore. We keep the displayed.current as long as the "time to render" (the deadline to render - current time) is bigger than the time it takes to render (render_delay: average of previous frames + 4 ms tolerance). If there is not enough time, we try to get the next picture from the decoder+prerender. And we check if there's enough time to render that one. If there is not enough time, we try to get the next picture from the decoder+prerender. And so on... This allows having one picture about to be displayed in memory rather than 2 (displayed.current and displayed.next), which should be useful to decide when to change the display module (when displayed.current changes, not displayed.next). date_refresh is set to the render date of the next picture if there is one and the render date of the current picture otherwise. Before, the deadline was the date of the next picture even if we're sticking to the current picture. It would potentially start the rendering of the current picture too late. Now the (start render) deadline always corresponds to the date of displayed.current. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6f6ba9cec8a6a762f30eb458382a7574a005fd67 --- src/video_output/video_output.c | 46 +++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 93c3d50c75..eafd367c5f 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -1502,15 +1502,6 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline) } else { - if (!paused) - { - if (!sys->displayed.next) - { - sys->displayed.next = - ThreadDisplayPreparePicture(vout, false, false, &paused); - } - } - const vlc_tick_t system_now = vlc_tick_now(); const vlc_tick_t render_delay = vout_chrono_GetHigh(&sys->render) + VOUT_MWAIT_TOLERANCE; @@ -1534,27 +1525,42 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline) } render_now = refresh; - if (!paused && sys->displayed.next) { - const vlc_tick_t next_system_pts = + if (!paused) { + vlc_tick_t pic_system_pts = vlc_clock_ConvertToSystem(sys->clock, system_now, - sys->displayed.next->date, sys->rate); - if (likely(next_system_pts != INT64_MAX)) + sys->displayed.current->date, sys->rate); + if (likely(pic_system_pts != INT64_MAX)) { - vlc_tick_t date_next = next_system_pts - render_delay; - if (date_refresh == VLC_TICK_INVALID || date_next < date_refresh) - date_refresh = date_next; - - if (date_next <= system_now) + vlc_tick_t pic_render_deadline = pic_system_pts - render_delay; + while (pic_render_deadline <= system_now) { + // not enough (predicted) time to render current, get non-late pic + picture_t *next; + next = ThreadDisplayPreparePicture(vout, false, false, &paused); + if (unlikely(next == NULL)) + break; + else + { // next frame will still need some waiting before display dropped_current_frame = true; render_now = false; if (likely(sys->displayed.current != NULL)) picture_Release(sys->displayed.current); - sys->displayed.current = sys->displayed.next; - sys->displayed.next = NULL; + sys->displayed.current = next; + + pic_system_pts = + vlc_clock_ConvertToSystem(sys->clock, vlc_tick_now(), + sys->displayed.current->date, sys->rate); + if (unlikely(pic_system_pts == INT64_MAX)) + break; + else + pic_render_deadline = pic_system_pts - render_delay; + } } + + if (date_refresh == VLC_TICK_INVALID || pic_render_deadline < date_refresh) + date_refresh = pic_render_deadline; } } if (date_refresh != VLC_TICK_INVALID) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
