-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Do not clone audio RTP packets... #850
Conversation
.., nor create a shared_ptr for each of them. Audio packets do not need to be referenced in the future as video ones (for retransmission).
This PR avoids the overhead of cloning and creating a Internal API changes:
One of which arguments is
I started creating two separated methods with one argument each. That required having a private method that would handle both in order to avoid duplicating code. Such approach makes the PR totally unreadable. |
There was new Rust release yesterday, probably related to that. It is not a compilation, rather it is a clippy lint that checks for good code practices. It has a link to the documentation, just apply the fix suggested there (you can reproduce lint error locally with |
Note: This is a bit convoluted, making Consumer's and RtpStreamSend decide wether they should use the raw or the shared pointer. It also adds few I'm going to rework this a bit and do some performance test, with the idea of keeping the current signatures |
Is really that important from perf point of view to avoid wrapping audio packets in a shared pointer? |
Indeed I feel this PR is too complex and it makes hard to know when we have to operate with packets and shared pointers. |
We can't know until we test it.
Exactly this is what I say I'm going to avoid. |
So the raw pointer is the only thing Consumers need to deal with. shared pointer should only be needed by |
Having the following test, for 10M nullptr && initialized shared_ptr: for (size_t i = 0; i < iterations; i++)
{
// Create packet.
auto* packet = RtpPacket::Parse(rtpBuffer1, 1500);
packet->SetSsrc(1111);
// Wrap it into a shared pointer.
std::shared_ptr<RtpPacket> sharedPacket(packet);
stream->ReceivePacket(nullptr, sharedPacket);
} raw && empty shared_ptr duration: for (size_t i = 0; i < iterations; i++)
{
// Create packet.
auto* packet = RtpPacket::Parse(rtpBuffer1, 1500);
packet->SetSsrc(1111);
// Create an empty shared pointer.
std::shared_ptr<RtpPacket> sharedPacket;
stream->ReceivePacket(packet, sharedPacket);
}
Avoiding the initialisation of a shared pointer when no needed comes with ~= 25% performance gain. IMHO we should go for it, we will get that performance gain for audio. As indicated previously I would always pass a raw pointer (as we always did) and an empty shared pointer. Such shared pointer will be initialized by the first Comments @ibc? |
If the shared pointer is gonna be created by the first RtpStreamSend that needs it, how does the receiving Transport or Router knows whether it should delete the original packet or not? Or will it delete is always? |
No, the sharer pointer will be created by Router, not initialized (as in test raw && empty shared_ptr duration ), and it will be initialised
The original packet is deleted as always, by Transport. The shared one is automatically handled. |
|
Ok, let's see how it looks. |
It will be passed to RtpStreamSend. The first that needs it will clone the RtpPacket and reset with it the shared_ptr that will be ref count increased by all RtpStreamSend who need it.
I hope the code is clear enough:
|
I like it |
Tested with real packet loss? |
Yes, tested in a real environment and working as expected. |
Please convert into PR |
This reverts commit afd3bbb.
Only clone RTP packets when needed
.., nor create a shared_ptr for each of them.
Audio packets do not need to be referenced in the future as video ones
(for retransmission).