Smooth DVR playback: match display refresh to the file (true 90fps at 720p90) and stop quantizing recorder timestamps#618
Open
bob9 wants to merge 2 commits into
Open
Conversation
DVR playback on the goggles dropped frames badly for two reasons: - The menu UI drives the panel at 1080p50, so 60fps DVR files lost 10 frames a second in an uneven 6:5 cadence and 90fps race files lost 40. The player now reads the file's frame rate from the demuxer and retimes the UI output to 1080p60 for the duration of playback (same 148.5MHz pixel clock, so OLED/FPGA settings stay valid), restoring 1080p50 on exit. 90fps files fall into an even 3:2 pulldown, the best the panel path can do. - The recorder muxed with a 1/fps stream time base, rounding every capture timestamp to a whole frame slot and baking judder into the file (the reason behind the "fps=59 or DVR is wrong" workaround). Streams are now muxed on the standard 90kHz clock so timestamps stay exact; this also makes recordings play smoother on PCs.
Follow-up to the playback smoothing fix: instead of playing 90fps race DVR at 60Hz with a 3:2 pulldown, the player now retimes the output to 720p90 while the file plays, showing every frame. The menu stays at 1080p for browsing; starting a 90fps file switches the vdpo output to 720p90 reusing the timing, clock phases and OLED mode already proven by the live 720p90 path, and the video surface is sized 1280x720 to fill it. Exiting the player restores the stock menu timing with a full Display_UI_init. 60fps files keep the lighter 1080p60 retime on the same pixel clock. The retime decision moved from ui_player into the media engine, since the video output rect has to be sized before the decoder pipeline is prepared; failure paths restore the menu timing too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi HDZero team — thanks for all the work on this firmware, and for considering this PR. It tries to improve on-goggle DVR playback smoothness, which a number of racers (myself included) have noticed, particularly with 90fps recordings. Happy to adjust anything here to fit the project's direction — feedback very welcome.
Problem
On-goggle DVR playback can drop frames noticeably. As far as I can tell there are two independent causes:
Playback runs at the menu's 50Hz panel timing. The playback page lives in UI mode, where
Display_UI_init()drives the panel at 1080p50. A 60fps recording loses 10 frames/second in an uneven 6:5 cadence; a 90fps race recording loses 40 frames/second irregularly. The frames decode fine — they just have nowhere to go at 50Hz.Recorded timestamps are quantized.
ffpackwrites the video stream with a1/fpstime base, which rounds every capture timestamp to a whole frame slot (~±8ms). That judder is baked into the file and shows on any player, including PCs. I suspect (though can't be certain) this also explains the existing note indvr.c— "If set fps to 60, DVR is wrong. I don't know why. 59 or 61 is ok." — with a 1/60 tick and real ~60fps input, jittered frames can occasionally round to identical PTS, which the muxer rejects; fps=59 happens to avoid the collisions.Proposed fix
Playback — the player reads the file's frame rate from the demuxer (
mFrameRate) and retimes the UI output for the duration of playback via a newDisplay_UI_SetRefresh(hz):1080p60. Same 148.5MHz pixel clock as the 1080p50 menu, so only the vdpo timing changes.720p90, showing every frame. This reuses the vdpo timing, vclk/pclk phases and OLED mode already used by the live 720p90 path — the FPGA simply stays on the UI input — and the VO layer is sized 1280x720 to fill it.Display_UI_init(). Menu browsing stays at 1080p throughout; only active playback retimes.The retime decision lives in
media_instantiate()because the VO rect needs to be sized before the decoder pipeline is prepared.Recording — the muxed video stream now uses the standard 90kHz time base instead of
1/fps, so capture timestamps are written exactly. MPEG-TS is 90kHz internally anyway, and for MP4 it's the most common track timescale.avg_frame_ratemetadata is unchanged, and the existing fps=59 setting is left untouched. With ~1500 ticks between consecutive frames, the PTS-collision scenario described above can no longer occur, and new recordings also play noticeably smoother off-goggle (PC players, editors, YouTube).Targets
Display_UI_SetRefreshis a no-op — its UI already runs 720p60, which suits 60fps files and gives 90fps files an even 3:2 cadence.Testing
Thanks again for taking a look!