Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jbuf: adaptive playout time calculation (Work in progress) #2757

Draft
wants to merge 41 commits into
base: main
Choose a base branch
from

Conversation

sreimers
Copy link
Member

@sreimers sreimers commented Oct 9, 2023

Experimental playout time calculation for jitter buffer. It replaces frame calculation, since it uses a local time reference offset (based on clock rate).

TODO:

  • Add unit tests
  • Introduce empty frames (if packet loss is detected a empty frame should scheduled as replacement)
  • Use tmr decode to prevent jbuf overflow on jitter spike (jbuf needs constant offloading)
  • Compare with current solution and jbuf frame completeness #2754
  • Cleanup/refactoring
  • Testing WebRTC

It's based on suggestions from this book: https://csperkins.org/standards/rtp-book.html

image

Future improvements:

  • Maybe the spike/jitter algorithm can be improved (we can test with different modes JBUF_ADAPTIVE_SPIKE...)
  • Currently the jitter and clock skew from soundcard (auplay) is ignored, at least cheap cards/drivers maybe perform badly. A tick based offloading could help to calculate within jbuf. But good skew adaption needs samplerate conversion instead of removing/adding complete frames. Maybe we can use a audio filter module with libsamplerate.

@sreimers sreimers changed the title jbuf: adaptive playout time calculation jbuf: adaptive playout time calculation (Work in progress) Oct 9, 2023
/* Update sequence number for 'get' */
jb->seq_get = f->hdr.seq;
/* Check playout time */
if (f->playout_time > next_playout) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frame completeness is not checked. Is it already ensured by skew and jitter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's ensured by jitter compensation, it's now a time based buffering delay, this should give the lowest delay which is needed to buffer.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, we can compare the plots if you are ready.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, give me some time to prepare and ensure the algorithms are working correctly (wrap-around calculations are tough ;-))

@sreimers sreimers force-pushed the playout_time branch 3 times, most recently from 73fcdd3 to 80b2758 Compare October 9, 2023 22:50
@cspiel1
Copy link
Collaborator

cspiel1 commented Oct 10, 2023

When jitter and/or skew reduces, then jbuf should return EAGAIN --> seems to be done already in this branch.

Then aubuf will increase number of buffered audio frames. Since jbuf already does the jitter compensation and packet re-ordering these extra frames can be dropped from aubuf. Maybe immediately dropped, or after some short time. This should reduce the latency.

Threads involved for audio:
Thread 1 - main thread, or the RX thread in near future

  • jbuf_put() is called
  • jbuf_get(), maybe by a timer. Or maybe by a wait condition (mqueue) from Thread 2.
  • does also decoding
  • pushes to aubuf

Thread 2 - audio playback thread

  • only reads the audio frames from aubuf

Edit: Your PR looks promising for me. I also think that the jitter compensation should be done in jbuf. This will reduce the overall latency because jbuf is able to handle jitter and out-of-order packets.

But unit tests will become difficult or have less coverage because jbuf_get() will depend on timing.

@sreimers
Copy link
Member Author

  • jbuf_get(), maybe by a timer. Or maybe by a wait condition (mqueue) from Thread 2.

I implemented a fallback tmr solution here (fallback since we should avoid to many event loop wakeups): 80b2758

@sreimers
Copy link
Member Author

sreimers commented Oct 10, 2023

But unit tests will become difficult or have less coverage because jbuf_get() will depend on timing.

I think we can use a virtual clock rate and small frames for tests. But yes this increases test time, at least for some milliseconds.
Edit: Or we can try to mockup tmr_jiffies somehow.

@cspiel1
Copy link
Collaborator

cspiel1 commented Oct 10, 2023

But unit tests will become difficult or have less coverage because jbuf_get() will depend on timing.

I think we can use a virtual clock rate and small frames for tests. But yes this increases test time, at least for some milliseconds. Edit: Or we can try to mockup tmr_jiffies somehow.

Okay, let's try this!

Also we could try a from jbuf_put() completely independent timer. E.g. ptime triggered.

@alfredh alfredh added this to the v3.7.0 milestone Oct 12, 2023
@alfredh alfredh removed this from the v3.7.0 milestone Oct 25, 2023
@alfredh
Copy link
Collaborator

alfredh commented Oct 26, 2023

please resolve the conflicts ..

@alfredh
Copy link
Collaborator

alfredh commented Dec 2, 2023

what is the status of this PR ?

Can you please rebase it on top of GIT HEAD ?

@cspiel1
Copy link
Collaborator

cspiel1 commented Dec 4, 2023

I think we should prefer this approach over mine #2754.

Currently, studying the mentioned book.

@sreimers
Copy link
Member Author

sreimers commented Dec 4, 2023

I will try to complete/cleanup this work soon. Maybe later this week.

src/core.h Outdated Show resolved Hide resolved
src/rtprecv.c Show resolved Hide resolved
@sreimers sreimers force-pushed the playout_time branch 2 times, most recently from 2d8b5d6 to 82b2225 Compare January 8, 2024 11:58
@cspiel1
Copy link
Collaborator

cspiel1 commented Jan 9, 2024

I'll try to fix the sanitizer warning. I think it is not related to this PR.

@cspiel1
Copy link
Collaborator

cspiel1 commented Jan 9, 2024

PR for sanitizer warning: #2867

@sreimers sreimers force-pushed the playout_time branch 2 times, most recently from 840fed9 to ebdda6a Compare January 11, 2024 08:51
@sreimers
Copy link
Member Author

The failing valgrind looks also unrelated: #2873

src/config.c Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants