From b5d8517bbcba57d8adf3aa661c4402c06ff046ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Luis=20Mill=C3=A1n?= Date: Wed, 29 Jan 2025 14:36:02 +0100 Subject: [PATCH] VP8: do not forward RTP packets which payload contains a higher temporal layer than current one. (#1009) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Worker: VP8, do not send frames with temporal layer higher than the current one Fixes #989 --------- Co-authored-by: IƱaki Baz Castillo --- CHANGELOG.md | 2 + worker/src/RTC/Codecs/VP8.cpp | 8 +++- worker/test/src/RTC/Codecs/TestVP8.cpp | 64 ++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1703bc8af..82dc749a00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### NEXT +- `Worker`: Drop VP8 packets with a higher temporal layer than the current one ([PR #1009](https://github.com/versatica/mediasoup/pull/1009)). + ### 3.15.3 - Node: Expose `Index` interface in `types.indexTypes` or via `import { Index as MediasoupIndex } from 'mediasoup/lib/indexTypes'` ([PR #1485](https://github.com/versatica/mediasoup/pull/1485)). diff --git a/worker/src/RTC/Codecs/VP8.cpp b/worker/src/RTC/Codecs/VP8.cpp index 4dd9bc5127..af2d3278d0 100644 --- a/worker/src/RTC/Codecs/VP8.cpp +++ b/worker/src/RTC/Codecs/VP8.cpp @@ -359,7 +359,7 @@ namespace RTC // clang-format off if ( this->payloadDescriptor->hasTlIndex && - this->payloadDescriptor->tlIndex > context->GetCurrentTemporalLayer() + this->payloadDescriptor->tlIndex == context->GetTargetTemporalLayer() ) // clang-format on { @@ -375,6 +375,12 @@ namespace RTC context->SetCurrentTemporalLayer(context->GetTargetTemporalLayer()); } + // Do not send tlIndex higher than current one. + if (this->payloadDescriptor->tlIndex > context->GetCurrentTemporalLayer()) + { + return false; + } + // clang-format off if ( this->payloadDescriptor->hasPictureId && diff --git a/worker/test/src/RTC/Codecs/TestVP8.cpp b/worker/test/src/RTC/Codecs/TestVP8.cpp index a5b663aaea..8b4a418847 100644 --- a/worker/test/src/RTC/Codecs/TestVP8.cpp +++ b/worker/test/src/RTC/Codecs/TestVP8.cpp @@ -322,4 +322,68 @@ SCENARIO("process VP8 payload descriptor", "[codecs][vp8]") forwarded = ProcessPacket(context, 1, 0, 1); REQUIRE_FALSE(forwarded); } + + SECTION("old packets with higher temporal layer than current are dropped") + { + RTC::Codecs::EncodingContext::Params params; + params.spatialLayers = 0; + params.temporalLayers = 2; + Codecs::VP8::EncodingContext context(params); + context.SyncRequired(); + + context.SetCurrentTemporalLayer(0); + context.SetTargetTemporalLayer(0); + + // Frame 1. + auto forwarded = ProcessPacket(context, 1, 0, 0); + REQUIRE(forwarded); + REQUIRE(forwarded->pictureId == 1); + REQUIRE(forwarded->tlIndex == 0); + REQUIRE(forwarded->tl0PictureIndex == 1); + + // Frame 2. + forwarded = ProcessPacket(context, 2, 0, 0); + REQUIRE(forwarded); + REQUIRE(forwarded->pictureId == 2); + REQUIRE(forwarded->tlIndex == 0); + REQUIRE(forwarded->tl0PictureIndex == 1); + + // Frame 3. Old packet with higher temporal layer than current. + forwarded = ProcessPacket(context, 0, 0, 1); + REQUIRE_FALSE(forwarded); + REQUIRE(context.GetCurrentTemporalLayer() == 0); + } + + SECTION("packets with higher temporal layer than current are dropped") + { + RTC::Codecs::EncodingContext::Params params; + params.spatialLayers = 0; + params.temporalLayers = 2; + Codecs::VP8::EncodingContext context(params); + context.SyncRequired(); + + context.SetCurrentTemporalLayer(0); + context.SetTargetTemporalLayer(0); + + // Frame 1. + auto forwarded = ProcessPacket(context, 1, 0, 0); + REQUIRE(forwarded); + REQUIRE(forwarded->pictureId == 1); + REQUIRE(forwarded->tlIndex == 0); + REQUIRE(forwarded->tl0PictureIndex == 1); + + // Frame 2. + forwarded = ProcessPacket(context, 2, 0, 0); + REQUIRE(forwarded); + REQUIRE(forwarded->pictureId == 2); + REQUIRE(forwarded->tlIndex == 0); + REQUIRE(forwarded->tl0PictureIndex == 1); + + context.SetTargetTemporalLayer(2); + + // Frame 3. Old packet with higher temporal layer than current. + forwarded = ProcessPacket(context, 3, 0, 1); + REQUIRE_FALSE(forwarded); + REQUIRE(context.GetCurrentTemporalLayer() == 0); + } }