WICG / video-rvfc

video.requestVideoFrameCallback() incubation
https://wicg.github.io/video-rvfc/
Other
54 stars 19 forks source link

metadata.presentationTime vs performance.now() of seeking #67

Closed lincolnneu closed 3 years ago

lincolnneu commented 3 years ago

The spec says

presentationTime: The time at which the user agent submitted the frame for composition.

Does it refer to when a seek action is performed? e.g. performance.now() when a video.currentTime = newTime is called? If so, there's a guaranteed way to get the most up to date PTS time of frame displayed when video is paused:

Right before each seek operation, we record the performance.now(). Inside rVFC, record metadata.presentationTime. onpause: compare the above two variables. If latest metadata.presentationTime >= time when latest seek action happens, we can be 100% sure that the metadata.mediaTime matches what's displayed on the video player. Else, seek +- 0.1s to try to trigger a new rVFC, and keep comparing the two. It usually takes 0~5 rounds to meet the condition from my experiment.

tguilbert-google commented 3 years ago

Does it refer to when a seek action is performed?

No, this is when last frame was sent to the compositor (so that it can be displayed with the next vsync). A seek might cause a new frame to be sent for presentation, so it might update this value, but so can frames from regular playback.

I am not 100% sure if performance.now() and presentationTime are on the exact same time domain. Both use an similar (same?) internal clock, but there is a different code path for their conversion into DOMHighResTimestamps, and I can't tell if there is a meaningful difference. If it seems to be working ok for you, then that's good.

lincolnneu commented 3 years ago

if performance.now() and presentationTime are on the exact same time domain

According to this: The high resolution timer is currently available in Chrome (Stable) as window.performance.webkitNow(), and this value is generally equal to the new argument value passed into the requestAnimationFrame callback.

So if rVFC uses the same approach to measure time as rAF, they'll be generally equal.

lincolnneu commented 3 years ago

Which clock does rVFC use? Can we calibrate the time using the now from rVFC:

callback VideoFrameRequestCallback = undefined(DOMHighResTimeStamp now, VideoFrameMetadata metadata);

If the now in the above callback is the time in rVFC clock when we get the rVFC, then we can use it as a reference to convert the metadata.presentationTime to the clock used by performance.now()

tguilbert-google commented 3 years ago

presentationTime is set here. It seems to be using the same clock as performance::now(). These clocks are used on different threads, but it's probably not a problem this case. I dug in the code an made sure that both conversions from now to the DOMHighResTimestamp uses the same time origin.

The now above is the same as the window.rAF now, and corresponds to a "now" which is set when the rendering steps start for the duration of the rendering steps, and can/should be earlier than performance.now().

EDIT: Clarified second paragraph.

tguilbert-google commented 3 years ago

I think this question is resolved.