Repository navigation
fix(rtc): keep AVSynchronizer sending video after reset() mid-frame - #871
Open
ANDROIDHASSAN wants to merge 1 commit into
Open
ANDROIDHASSAN wants to merge 1 commit into
ANDROIDHASSAN wants to merge 1 commit into
Conversation
The capture task waits for each frame's slot inside the FPS controller. reset() during that wait cleared the schedule, so after_process() hit its assert, the task ended silently, and pushes blocked once the video queue filled. after_process() now starts a new schedule from the current time.
ANDROIDHASSAN
requested review from
changt,
cloudwebrtc,
lukasIO and
xianshijing-lk
as code owners
October 16, 2026 07:14
This branch has not been deployed
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.
AVSynchronizer._capture_videosends each frame insideasync with self._fps_controller, and most of its time is spent inwait_next_process(), sleeping until the frame's slot.AVSynchronizer.reset()clears the controller's schedule (_next_frame_time = None). Called during that sleep, it made the controller'safter_process()hitassert self._next_frame_time is not None, which ended the capture task. Nothing logs that, and the video queue is bounded (one frame at 10 fps with the default 100 ms), so every laterpush()of a video frame waits forever andwait_for_playout()never returns.A script with fake audio and video sources, 10 fps: push two frames, call
reset()30 ms later (while the task waits for the second frame's slot), push a third:after_process()now starts a new schedule from the current time when the controller was reset afterwait_next_process(), the same thingwait_next_process()does for the first frame after a reset.Tests in
tests/rtc/test_synchronizer.py, with fake sources:test_av_synchronizer_keeps_sending_after_a_reset_mid_frame: the fake video source callsreset()fromcapture_frame, which always falls betweenwait_next_process()andafter_process(). All three frames must be captured andwait_for_playout()must return. Onmainit times out (the task died with theAssertionError).test_fps_controller_schedules_from_now_after_a_reset_mid_frame: onmaintheAssertionError; now the next frame is one interval after the call.tests/rtcandlivekit-rtc/testshere, without the FFI library: the same 17 failures and 17 errors before and after, from the missing native library; 131 passed before, 133 now.ruff check,ruff format --check(0.15.4) pass;mypy(1.19.1) onlivekit-rtcreports the same 4 errors injupyter.pybefore and after.Not changed: any other exception in
_capture_video, for example fromVideoSource.capture_frameafter the source is closed, still ends the task without a log and leavespush()waiting.