obsproject / obsproject/obs-studio

Buffered async video lags behind

Open
#12,459 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
76.4k
Forks
10.2k
Avg merge
4d 23h
Merged PRs (30d)
12

Description

Operating System Info

Ubuntu 24.04

Other OS

No response

OBS Studio Version

31.1.2

OBS Studio Version (Other)

No response

OBS Studio Log URL

https://obsproject.com/logs/MLjBf83CxDTC3U8y

OBS Studio Crash Log URL

No response

Expected Behavior

The square for the Sync Test (Async Video/Audio Source) should alternative from black to white every second. There should be a tone playing when the square is white.

Current Behavior

In the original version of the (test) source: The tone plays while the audio is black, and is silent while it is white.

In the modified version (using absolute timestamps): there is a 1 second delay before the square starts alternating colour.

Steps to Reproduce
  1. Build OBS with the test sources.
  2. Add a Sync Test (Async Video/Audio Source) to the scene.
  3. Start/End recording then listen to result.

I also modified the test source to use an absolute timestamp (i.e. one that doesn't start at zero) by making the following changes:

--- a/test/test-input/sync-async-source.c
+++ b/test/test-input/sync-async-source.c
@@ -60,7 +60,7 @@ static void *video_thread(void *data)
        uint64_t cur_time = os_gettime_ns();
        bool whitelist = false;
        double cos_val = 0.0;
-       uint64_t start_time = cur_time;
+       // uint64_t start_time = cur_time;
 
        struct obs_source_frame frame = {
                .data = {[0] = (uint8_t *)pixels},
@@ -80,8 +80,8 @@ static void *video_thread(void *data)
        while (os_event_try(ast->stop_signal) == EAGAIN) {
                fill_texture(pixels, whitelist ? 0xFFFFFFFF : 0xFF000000);
 
-               frame.timestamp = cur_time - start_time;
-               audio.timestamp = cur_time - start_time;
+               frame.timestamp = cur_time; // - start_time;
+               audio.timestamp = cur_time; //- start_time;
 
                if (whitelist) {
                        for (size_t i = 0; i < sample_rate; i++) {

I then performed the same test.

Anything else we should know?

There are two relatively obvious causes of these bugs within obs-source.c: Firstly, the following test incorrectly short-circuits the frame-readying procedure if the first timestamp was zero:

https://github.com/obsproject/obs-studio/blob/7778070cbd8e4689d91d90068091ced467c5fdef/libobs/obs-source.c#L4072

The second issue is that changes in the system (video) time are only accounted for when the queue is non-empty. This effectively guarantees that async video is one frame behind at all times; see the code surrounding:

https://github.com/obsproject/obs-studio/blob/7778070cbd8e4689d91d90068091ced467c5fdef/libobs/obs-source.c#L4016).

The potential for incorrect accumulation for last_frame_ts is almost certainly related to other issues with buffered async video observed here: https://obsproject.com/forum/threads/video-gradually-falling-behind-audio-where-can-i-start-investigating.187021/

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the referenced sections of libobs/obs-source.c around lines 4016 and 4072, then reproduce the behavior using test/test-input/sync-async-source.c and the linked OBS log. Compare zero-based and absolute timestamps while tracing buffered async video timing. Done means the Sync Test alternates on time with its audio tone and no persistent one-frame or one-second lag remains.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
audio-video-rtc
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.