Skip to content

Conversation

@thatsnotright
Copy link
Contributor

Description

This PR Should hopefully improve the performance for use by SampleBuilder and in the general case.

@at-wat If you have time would you be able to test this PR and the corresponding branch I created in the webrtc repository? pion/webrtc#2959

Thank you!

@thatsnotright thatsnotright requested a review from at-wat November 26, 2024 23:51
@codecov
Copy link

codecov bot commented Nov 26, 2024

Codecov Report

❌ Patch coverage is 83.50000% with 66 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.60%. Comparing base (3cb438f) to head (7e03435).

Files with missing lines Patch % Lines
pkg/jitterbuffer/rbtree.go 84.26% 45 Missing and 11 partials ⚠️
pkg/jitterbuffer/jitter_buffer.go 61.53% 5 Missing ⚠️
pkg/jitterbuffer/receiver_interceptor.go 80.00% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #292      +/-   ##
==========================================
- Coverage   78.64%   78.60%   -0.04%     
==========================================
  Files          82       83       +1     
  Lines        5113     5497     +384     
==========================================
+ Hits         4021     4321     +300     
- Misses        921      995      +74     
- Partials      171      181      +10     
Flag Coverage Δ
go 78.60% <83.50%> (-0.04%) ⬇️
wasm 76.20% <83.50%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@at-wat
Copy link
Member

at-wat commented Nov 27, 2024

I'll try it later!

@at-wat
Copy link
Member

at-wat commented Dec 10, 2024

@thatsnotright I tested this branch locally in my usecase and confirmed that SampleBuilder's performance is good! (mostly same CPU/memory usage as the latest release)

@thatsnotright
Copy link
Contributor Author

@thatsnotright I tested this branch locally in my usecase and confirmed that SampleBuilder's performance is good! (mostly same CPU/memory usage as the latest release)

@at-wat Thank you for taking the time to test, I appreciate your time! I'll clean up the code a little and make some test coverage improvements and then work with @Sean-Der on next steps!

@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 2 times, most recently from ea085bb to ab615fe Compare February 26, 2025 00:11
@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 4 times, most recently from 521c4f0 to 339f38e Compare April 2, 2025 00:36
@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 3 times, most recently from 3ff714b to 6982678 Compare April 29, 2025 00:46
@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 3 times, most recently from 7639fd0 to 72641d8 Compare May 7, 2025 00:21
@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 5 times, most recently from e7aab86 to 8e6a4ed Compare May 29, 2025 00:46
@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 6 times, most recently from 9e75f82 to 77fa007 Compare June 11, 2025 00:12
@thatsnotright thatsnotright force-pushed the rob/jb_perf branch 3 times, most recently from 6572218 to 2de1b4e Compare June 11, 2025 12:41
@thatsnotright thatsnotright marked this pull request as ready for review September 11, 2025 23:29
thatsnotright and others added 2 commits September 11, 2025 19:30
Rework the jitterbuffer for SampleBuilder use
Allow Skipping packets
@at-wat
Copy link
Member

at-wat commented Sep 24, 2025

@thatsnotright could you add a benchmark test and post a comparison between the master branch and this PR?

Copy link
Member

@at-wat at-wat left a comment

Choose a reason for hiding this comment

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

Please consider adding a benchmark test to compare with the master branch.
It would be better to have bench test cases for some different amount of unordered packet.

PriorityQueue is now unused but the code is remained. It should be removed.

Comment on lines +15 to +35
func safeUint16(i int) uint16 {
if i < 0 {
return 0
}
if i > math.MaxUint16 {
return math.MaxUint16
}

return uint16(i)
}

func safeUint32(i int) uint32 {
if i < 0 {
return 0
}
if i > math.MaxInt32 {
return math.MaxUint32
}

return uint32(i)
}
Copy link
Member

Choose a reason for hiding this comment

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

They seems to be used to clamp sequence number and timestamp.
Is it correct to clamp instead of rolling over?
e.g. testing the sequence of (0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF) doesn't make sense and should be (0xFFFE, 0xFFFF, 0x0001, 0x0002)

}

func TestJitterBufferInOrderPackets(t *testing.T) {
assert := assert.New(t)
Copy link
Member

Choose a reason for hiding this comment

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

I think overriding a package name by a local variable makes confusion

}

// Wait for buffer to transition to emitting state
for jb.state == Buffering {
Copy link
Member

Choose a reason for hiding this comment

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

I guess this should be accessed with lock

tree.Clear()
_, err := tree.Pop()
assert.Error(err)
assert.Contains(err.Error(), "priority not found")
Copy link
Member

Choose a reason for hiding this comment

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

Should be checked by assert.ErrorIs

Comment on lines +23 to +27
tests := []struct {
name string
ops func(*RBTree)
validate func(*testing.T, *RBTree)
}{
Copy link
Member

Choose a reason for hiding this comment

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

IMO, these test cases don't share almost any code and doesn't make sense to be a table driven. Simply writing t.Run("TableRotation", ...) { would be better

Comment on lines +45 to +56
if diff > 32768 {
return -1
}
if diff < -32768 {
return 1
}
if diff < 0 {
return -1
}
if diff > 0 {
return 1
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if diff > 32768 {
return -1
}
if diff < -32768 {
return 1
}
if diff < 0 {
return -1
}
if diff > 0 {
return 1
}
switch {
case diff > 32768:
return -1
case diff < -32768:
return 1
case diff < 0:
return -1
case diff > 0:
return 1
}

Comment on lines +25 to +34
// RBTree structure is a red-black tree for fast access based on priority.
type RBTree struct {
root *rbnode
length uint16
}

// NewTree creates a new red-black tree.
func NewTree() *RBTree {
return &RBTree{}
}
Copy link
Member

Choose a reason for hiding this comment

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

Having public RBTree in jitterbuffer package looks not proper.
(Users shouldn't have to take care of the internal implementation)
I think it should be an internal sub-package.

if err != nil {
if errors.Is(err, ErrNotFound) {
if i.skipMissingPackets {
i.log.Warn("Skipping missing packet")
Copy link
Member

Choose a reason for hiding this comment

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

I guess this may spam the logs. Maybe it should be debug level?

}

// Pop will remove the root in the queue.
func (t *RBTree) Pop() (*rtp.Packet, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Does the root node mean the approx. median of the stored priority (sequence number)?
I'm not sure popping this makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants