mediasoup 3.9.13 → 3.9.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node/lib/ActiveSpeakerObserver.d.ts +1 -1
- package/node/lib/ActiveSpeakerObserver.d.ts.map +1 -1
- package/node/lib/AudioLevelObserver.d.ts +1 -1
- package/node/lib/AudioLevelObserver.d.ts.map +1 -1
- package/node/lib/Consumer.d.ts +4 -4
- package/node/lib/Consumer.d.ts.map +1 -1
- package/node/lib/Consumer.js +1 -1
- package/node/lib/DataConsumer.d.ts +4 -4
- package/node/lib/DataConsumer.d.ts.map +1 -1
- package/node/lib/DataConsumer.js +1 -1
- package/node/lib/DataProducer.d.ts +4 -4
- package/node/lib/DataProducer.d.ts.map +1 -1
- package/node/lib/DataProducer.js +1 -1
- package/node/lib/DirectTransport.d.ts +1 -1
- package/node/lib/DirectTransport.d.ts.map +1 -1
- package/node/lib/PipeTransport.d.ts +2 -2
- package/node/lib/PipeTransport.d.ts.map +1 -1
- package/node/lib/PipeTransport.js +1 -1
- package/node/lib/PlainTransport.d.ts +1 -1
- package/node/lib/PlainTransport.d.ts.map +1 -1
- package/node/lib/Producer.d.ts +4 -4
- package/node/lib/Producer.d.ts.map +1 -1
- package/node/lib/Producer.js +1 -1
- package/node/lib/Router.d.ts +4 -4
- package/node/lib/Router.d.ts.map +1 -1
- package/node/lib/Router.js +7 -7
- package/node/lib/RtpObserver.d.ts +3 -3
- package/node/lib/RtpObserver.d.ts.map +1 -1
- package/node/lib/RtpObserver.js +1 -1
- package/node/lib/Transport.d.ts +3 -3
- package/node/lib/Transport.d.ts.map +1 -1
- package/node/lib/Transport.js +5 -5
- package/node/lib/WebRtcTransport.d.ts +1 -1
- package/node/lib/WebRtcTransport.d.ts.map +1 -1
- package/node/lib/Worker.d.ts +3 -3
- package/node/lib/Worker.d.ts.map +1 -1
- package/node/lib/Worker.js +3 -3
- package/node/lib/index.d.ts +1 -1
- package/node/lib/index.d.ts.map +1 -1
- package/node/lib/index.js +2 -2
- package/node/lib/ortc.js +1 -0
- package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
- package/node/lib/supportedRtpCapabilities.js +15 -0
- package/package.json +6 -6
- package/worker/include/RTC/Codecs/H264_SVC.hpp +115 -0
- package/worker/include/RTC/Codecs/Tools.hpp +11 -0
- package/worker/include/RTC/Consumer.hpp +5 -4
- package/worker/include/RTC/DirectTransport.hpp +4 -0
- package/worker/include/RTC/NackGenerator.hpp +5 -2
- package/worker/include/RTC/PipeConsumer.hpp +1 -0
- package/worker/include/RTC/RTCP/CompoundPacket.hpp +2 -0
- package/worker/include/RTC/RtpDictionaries.hpp +1 -0
- package/worker/include/RTC/RtpStream.hpp +2 -0
- package/worker/include/RTC/RtpStreamRecv.hpp +7 -1
- package/worker/include/RTC/RtpStreamSend.hpp +7 -0
- package/worker/include/RTC/SimpleConsumer.hpp +1 -0
- package/worker/include/RTC/SimulcastConsumer.hpp +4 -0
- package/worker/include/RTC/SvcConsumer.hpp +1 -0
- package/worker/meson.build +4 -0
- package/worker/src/RTC/Codecs/H264_SVC.cpp +428 -0
- package/worker/src/RTC/DirectTransport.cpp +10 -1
- package/worker/src/RTC/NackGenerator.cpp +27 -9
- package/worker/src/RTC/PipeConsumer.cpp +20 -0
- package/worker/src/RTC/Producer.cpp +5 -1
- package/worker/src/RTC/RTCP/CompoundPacket.cpp +7 -0
- package/worker/src/RTC/RtpDictionaries/RtpCodecMimeType.cpp +2 -0
- package/worker/src/RTC/RtpStreamRecv.cpp +4 -3
- package/worker/src/RTC/RtpStreamSend.cpp +32 -0
- package/worker/src/RTC/SimpleConsumer.cpp +17 -0
- package/worker/src/RTC/SimulcastConsumer.cpp +45 -4
- package/worker/src/RTC/SvcConsumer.cpp +17 -0
- package/worker/src/RTC/Transport.cpp +14 -0
- package/worker/src/RTC/TransportCongestionControlClient.cpp +0 -3
- package/worker/test/include/helpers.hpp +119 -0
- package/worker/test/src/RTC/Codecs/TestH264.cpp +30 -0
- package/worker/test/src/RTC/Codecs/TestH264_SVC.cpp +181 -0
- package/worker/test/src/RTC/TestNackGenerator.cpp +3 -1
- package/worker/test/src/RTC/TestRtpPacketH264Svc.cpp +455 -0
- package/worker/test/src/RTC/TestRtpStreamRecv.cpp +4 -3
|
@@ -338,6 +338,16 @@ namespace RTC
|
|
|
338
338
|
|
|
339
339
|
packet->AddSdesChunk(sdesChunk);
|
|
340
340
|
|
|
341
|
+
auto* dlrr = this->rtpStream->GetRtcpXrDelaySinceLastRr(nowMs);
|
|
342
|
+
|
|
343
|
+
if (dlrr)
|
|
344
|
+
{
|
|
345
|
+
auto* report = new RTC::RTCP::DelaySinceLastRr();
|
|
346
|
+
|
|
347
|
+
report->AddSsrcInfo(dlrr);
|
|
348
|
+
packet->AddDelaySinceLastRr(report);
|
|
349
|
+
}
|
|
350
|
+
|
|
341
351
|
this->lastRtcpSentTime = nowMs;
|
|
342
352
|
}
|
|
343
353
|
|
|
@@ -406,6 +416,13 @@ namespace RTC
|
|
|
406
416
|
this->rtpStream->ReceiveRtcpReceiverReport(report);
|
|
407
417
|
}
|
|
408
418
|
|
|
419
|
+
void SimpleConsumer::ReceiveRtcpXrReceiverReferenceTime(RTC::RTCP::ReceiverReferenceTime* report)
|
|
420
|
+
{
|
|
421
|
+
MS_TRACE();
|
|
422
|
+
|
|
423
|
+
this->rtpStream->ReceiveRtcpXrReceiverReferenceTime(report);
|
|
424
|
+
}
|
|
425
|
+
|
|
409
426
|
uint32_t SimpleConsumer::GetTransmissionRate(uint64_t nowMs)
|
|
410
427
|
{
|
|
411
428
|
MS_TRACE();
|
|
@@ -16,6 +16,7 @@ namespace RTC
|
|
|
16
16
|
static constexpr uint64_t StreamMinActiveMs{ 2000u }; // In ms.
|
|
17
17
|
static constexpr uint64_t BweDowngradeConservativeMs{ 10000u }; // In ms.
|
|
18
18
|
static constexpr uint64_t BweDowngradeMinActiveMs{ 8000u }; // In ms.
|
|
19
|
+
static constexpr uint16_t MaxSequenceNumberGap{ 100u };
|
|
19
20
|
|
|
20
21
|
/* Instance methods. */
|
|
21
22
|
|
|
@@ -674,7 +675,8 @@ namespace RTC
|
|
|
674
675
|
shouldSwitchCurrentSpatialLayer = true;
|
|
675
676
|
|
|
676
677
|
// Need to resync the stream.
|
|
677
|
-
this->syncRequired
|
|
678
|
+
this->syncRequired = true;
|
|
679
|
+
this->spatialLayerToSync = spatialLayer;
|
|
678
680
|
}
|
|
679
681
|
// If the packet belongs to different spatial layer than the one being sent,
|
|
680
682
|
// drop it.
|
|
@@ -691,7 +693,7 @@ namespace RTC
|
|
|
691
693
|
bool isSyncPacket = this->syncRequired;
|
|
692
694
|
|
|
693
695
|
// Sync sequence number and timestamp if required.
|
|
694
|
-
if (isSyncPacket)
|
|
696
|
+
if (isSyncPacket && (this->spatialLayerToSync == -1 || this->spatialLayerToSync == spatialLayer))
|
|
695
697
|
{
|
|
696
698
|
if (packet->IsKeyFrame())
|
|
697
699
|
MS_DEBUG_TAG(rtp, "sync key frame received");
|
|
@@ -818,9 +820,25 @@ namespace RTC
|
|
|
818
820
|
this->encodingContext->SyncRequired();
|
|
819
821
|
|
|
820
822
|
this->syncRequired = false;
|
|
823
|
+
this->spatialLayerToSync = -1;
|
|
821
824
|
this->keyFrameForTsOffsetRequested = false;
|
|
822
825
|
}
|
|
823
826
|
|
|
827
|
+
if (!shouldSwitchCurrentSpatialLayer && this->checkingForOldPacketsInSpatialLayer)
|
|
828
|
+
{
|
|
829
|
+
// If this is a packet previous to the spatial layer switch, ignore the packet.
|
|
830
|
+
if (SeqManager<uint16_t>::IsSeqLowerThan(
|
|
831
|
+
packet->GetSequenceNumber(), this->snReferenceSpatialLayer))
|
|
832
|
+
{
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
else if (SeqManager<uint16_t>::IsSeqHigherThan(
|
|
836
|
+
packet->GetSequenceNumber(), this->snReferenceSpatialLayer + MaxSequenceNumberGap))
|
|
837
|
+
{
|
|
838
|
+
this->checkingForOldPacketsInSpatialLayer = false;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
824
842
|
bool marker{ false };
|
|
825
843
|
|
|
826
844
|
if (shouldSwitchCurrentSpatialLayer)
|
|
@@ -828,6 +846,9 @@ namespace RTC
|
|
|
828
846
|
// Update current spatial layer.
|
|
829
847
|
this->currentSpatialLayer = this->targetSpatialLayer;
|
|
830
848
|
|
|
849
|
+
this->snReferenceSpatialLayer = packet->GetSequenceNumber();
|
|
850
|
+
this->checkingForOldPacketsInSpatialLayer = true;
|
|
851
|
+
|
|
831
852
|
// Update target and current temporal layer.
|
|
832
853
|
this->encodingContext->SetTargetTemporalLayer(this->targetTemporalLayer);
|
|
833
854
|
this->encodingContext->SetCurrentTemporalLayer(packet->GetTemporalLayer());
|
|
@@ -947,6 +968,16 @@ namespace RTC
|
|
|
947
968
|
|
|
948
969
|
packet->AddSdesChunk(sdesChunk);
|
|
949
970
|
|
|
971
|
+
auto* dlrr = this->rtpStream->GetRtcpXrDelaySinceLastRr(nowMs);
|
|
972
|
+
|
|
973
|
+
if (dlrr)
|
|
974
|
+
{
|
|
975
|
+
auto* report = new RTC::RTCP::DelaySinceLastRr();
|
|
976
|
+
|
|
977
|
+
report->AddSsrcInfo(dlrr);
|
|
978
|
+
packet->AddDelaySinceLastRr(report);
|
|
979
|
+
}
|
|
980
|
+
|
|
950
981
|
this->lastRtcpSentTime = nowMs;
|
|
951
982
|
}
|
|
952
983
|
|
|
@@ -1015,6 +1046,13 @@ namespace RTC
|
|
|
1015
1046
|
this->rtpStream->ReceiveRtcpReceiverReport(report);
|
|
1016
1047
|
}
|
|
1017
1048
|
|
|
1049
|
+
void SimulcastConsumer::ReceiveRtcpXrReceiverReferenceTime(RTC::RTCP::ReceiverReferenceTime* report)
|
|
1050
|
+
{
|
|
1051
|
+
MS_TRACE();
|
|
1052
|
+
|
|
1053
|
+
this->rtpStream->ReceiveRtcpXrReceiverReferenceTime(report);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1018
1056
|
uint32_t SimulcastConsumer::GetTransmissionRate(uint64_t nowMs)
|
|
1019
1057
|
{
|
|
1020
1058
|
MS_TRACE();
|
|
@@ -1037,6 +1075,7 @@ namespace RTC
|
|
|
1037
1075
|
MS_TRACE();
|
|
1038
1076
|
|
|
1039
1077
|
this->syncRequired = true;
|
|
1078
|
+
this->spatialLayerToSync = -1;
|
|
1040
1079
|
this->keyFrameForTsOffsetRequested = false;
|
|
1041
1080
|
|
|
1042
1081
|
if (IsActive())
|
|
@@ -1072,8 +1111,10 @@ namespace RTC
|
|
|
1072
1111
|
{
|
|
1073
1112
|
MS_TRACE();
|
|
1074
1113
|
|
|
1075
|
-
this->syncRequired
|
|
1076
|
-
this->
|
|
1114
|
+
this->syncRequired = true;
|
|
1115
|
+
this->spatialLayerToSync = -1;
|
|
1116
|
+
this->keyFrameForTsOffsetRequested = false;
|
|
1117
|
+
this->checkingForOldPacketsInSpatialLayer = false;
|
|
1077
1118
|
|
|
1078
1119
|
if (IsActive())
|
|
1079
1120
|
MayChangeLayers();
|
|
@@ -685,6 +685,16 @@ namespace RTC
|
|
|
685
685
|
|
|
686
686
|
packet->AddSdesChunk(sdesChunk);
|
|
687
687
|
|
|
688
|
+
auto* dlrr = this->rtpStream->GetRtcpXrDelaySinceLastRr(nowMs);
|
|
689
|
+
|
|
690
|
+
if (dlrr)
|
|
691
|
+
{
|
|
692
|
+
auto* report = new RTC::RTCP::DelaySinceLastRr();
|
|
693
|
+
|
|
694
|
+
report->AddSsrcInfo(dlrr);
|
|
695
|
+
packet->AddDelaySinceLastRr(report);
|
|
696
|
+
}
|
|
697
|
+
|
|
688
698
|
this->lastRtcpSentTime = nowMs;
|
|
689
699
|
}
|
|
690
700
|
|
|
@@ -751,6 +761,13 @@ namespace RTC
|
|
|
751
761
|
this->rtpStream->ReceiveRtcpReceiverReport(report);
|
|
752
762
|
}
|
|
753
763
|
|
|
764
|
+
void SvcConsumer::ReceiveRtcpXrReceiverReferenceTime(RTC::RTCP::ReceiverReferenceTime* report)
|
|
765
|
+
{
|
|
766
|
+
MS_TRACE();
|
|
767
|
+
|
|
768
|
+
this->rtpStream->ReceiveRtcpXrReceiverReferenceTime(report);
|
|
769
|
+
}
|
|
770
|
+
|
|
754
771
|
uint32_t SvcConsumer::GetTransmissionRate(uint64_t nowMs)
|
|
755
772
|
{
|
|
756
773
|
MS_TRACE();
|
|
@@ -2270,6 +2270,20 @@ namespace RTC
|
|
|
2270
2270
|
break;
|
|
2271
2271
|
}
|
|
2272
2272
|
|
|
2273
|
+
case RTC::RTCP::ExtendedReportBlock::Type::RRT:
|
|
2274
|
+
{
|
|
2275
|
+
auto* rrt = static_cast<RTC::RTCP::ReceiverReferenceTime*>(report);
|
|
2276
|
+
|
|
2277
|
+
for (auto& kv : this->mapConsumers)
|
|
2278
|
+
{
|
|
2279
|
+
auto* consumer = kv.second;
|
|
2280
|
+
|
|
2281
|
+
consumer->ReceiveRtcpXrReceiverReferenceTime(rrt);
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
break;
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2273
2287
|
default:;
|
|
2274
2288
|
}
|
|
2275
2289
|
}
|
|
@@ -262,9 +262,6 @@ namespace RTC
|
|
|
262
262
|
|
|
263
263
|
void TransportCongestionControlClient::SetMaxOutgoingBitrate(uint32_t maxBitrate)
|
|
264
264
|
{
|
|
265
|
-
if (maxBitrate < this->initialAvailableBitrate)
|
|
266
|
-
MS_THROW_ERROR("maxOutgoingBitrate must be >= initialAvailableOutgoingBitrate");
|
|
267
|
-
|
|
268
265
|
if (maxBitrate < MinBitrate)
|
|
269
266
|
MS_THROW_ERROR("maxOutgoingBitrate must be >= 30000bps");
|
|
270
267
|
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
#include <fstream>
|
|
6
6
|
#include <string>
|
|
7
7
|
|
|
8
|
+
static int BUFFER_SIZE = 65536;
|
|
9
|
+
|
|
8
10
|
namespace helpers
|
|
9
11
|
{
|
|
10
12
|
inline bool readBinaryFile(const char* file, uint8_t* buffer, size_t* len)
|
|
@@ -25,6 +27,123 @@ namespace helpers
|
|
|
25
27
|
|
|
26
28
|
return true;
|
|
27
29
|
}
|
|
30
|
+
|
|
31
|
+
inline bool addToBuffer(uint8_t* buf, int* size, uint8_t* data, size_t len)
|
|
32
|
+
{
|
|
33
|
+
if (*size + len > BUFFER_SIZE)
|
|
34
|
+
return false;
|
|
35
|
+
|
|
36
|
+
int i = 0;
|
|
37
|
+
if (len == 1)
|
|
38
|
+
{
|
|
39
|
+
buf[*size] = *data;
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
{
|
|
43
|
+
for (i = 0; i < len; i++)
|
|
44
|
+
{
|
|
45
|
+
buf[*size + i] = data[i];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
*size += len;
|
|
49
|
+
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
inline bool readPayloadData(const char* file, int pos, int bytes, uint8_t* payload)
|
|
54
|
+
{
|
|
55
|
+
std::string filePath = "test/" + std::string(file);
|
|
56
|
+
#ifdef _WIN32
|
|
57
|
+
std::replace(filePath.begin(), filePath.end(), '/', '\\');
|
|
58
|
+
#endif
|
|
59
|
+
std::ifstream in(filePath, std::ios::ate | std::ios::binary);
|
|
60
|
+
|
|
61
|
+
if (!in)
|
|
62
|
+
return false;
|
|
63
|
+
|
|
64
|
+
in.seekg(pos, std::ios::beg);
|
|
65
|
+
in.read(reinterpret_cast<char*>(payload), bytes);
|
|
66
|
+
|
|
67
|
+
in.close();
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
inline bool writeRtpPacket(
|
|
72
|
+
const char* file,
|
|
73
|
+
uint8_t nalType,
|
|
74
|
+
size_t nalLength,
|
|
75
|
+
int32_t sid,
|
|
76
|
+
int32_t tid,
|
|
77
|
+
int32_t isIdr,
|
|
78
|
+
int32_t firstSliceId,
|
|
79
|
+
int32_t lastSliceId,
|
|
80
|
+
uint8_t* payload,
|
|
81
|
+
uint8_t* buf,
|
|
82
|
+
size_t* len)
|
|
83
|
+
{
|
|
84
|
+
std::string filePath = "test/" + std::string(file);
|
|
85
|
+
#ifdef _WIN32
|
|
86
|
+
std::replace(filePath.begin(), filePath.end(), '/', '\\');
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
uint8_t buffer[16] = { 144, 111, 92, 65, 98, 245, 71, 218, 159, 113, 8, 226, 190, 222, 0, 1 };
|
|
90
|
+
|
|
91
|
+
int packet_size = 0;
|
|
92
|
+
uint8_t oneByte = 0;
|
|
93
|
+
|
|
94
|
+
// write the RTP header
|
|
95
|
+
if (!addToBuffer(buf, &packet_size, buffer, 16))
|
|
96
|
+
return false;
|
|
97
|
+
|
|
98
|
+
// write ID and length of frame marking extension
|
|
99
|
+
// if first layer then length should be 0, else 1
|
|
100
|
+
oneByte = oneByte | 1 << 4;
|
|
101
|
+
if (sid != -1)
|
|
102
|
+
{
|
|
103
|
+
oneByte = oneByte | 0x01;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!addToBuffer(buf, &packet_size, &oneByte, 1))
|
|
107
|
+
return false;
|
|
108
|
+
|
|
109
|
+
// write SEIDB TID bits
|
|
110
|
+
oneByte = 0;
|
|
111
|
+
if (firstSliceId == 1)
|
|
112
|
+
oneByte = oneByte | 1 << 7;
|
|
113
|
+
|
|
114
|
+
if (lastSliceId == 1)
|
|
115
|
+
oneByte = oneByte | 1 << 6;
|
|
116
|
+
|
|
117
|
+
if (isIdr == 1)
|
|
118
|
+
oneByte = oneByte | 1 << 5;
|
|
119
|
+
|
|
120
|
+
if (tid != -1)
|
|
121
|
+
oneByte = oneByte | tid;
|
|
122
|
+
|
|
123
|
+
if (!addToBuffer(buf, &packet_size, &oneByte, 1))
|
|
124
|
+
return false;
|
|
125
|
+
|
|
126
|
+
// write DID QID bits
|
|
127
|
+
oneByte = 0;
|
|
128
|
+
if (sid != -1)
|
|
129
|
+
oneByte = oneByte | sid << 6;
|
|
130
|
+
|
|
131
|
+
if (!addToBuffer(buf, &packet_size, &oneByte, 1))
|
|
132
|
+
return false;
|
|
133
|
+
|
|
134
|
+
// write TL0PICIDX
|
|
135
|
+
oneByte = 0;
|
|
136
|
+
if (!addToBuffer(buf, &packet_size, &oneByte, 1))
|
|
137
|
+
return false;
|
|
138
|
+
|
|
139
|
+
// write payload
|
|
140
|
+
if (!addToBuffer(buf, &packet_size, payload, nalLength))
|
|
141
|
+
return false;
|
|
142
|
+
|
|
143
|
+
*len = packet_size;
|
|
144
|
+
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
28
147
|
} // namespace helpers
|
|
29
148
|
|
|
30
149
|
#endif
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#include "common.hpp"
|
|
2
|
+
#include "RTC/Codecs/H264.hpp"
|
|
3
|
+
#include <catch2/catch.hpp>
|
|
4
|
+
#include <cstring> // std::memcmp()
|
|
5
|
+
|
|
6
|
+
using namespace RTC;
|
|
7
|
+
|
|
8
|
+
SCENARIO("parse H264 payload descriptor", "[codecs][h264]")
|
|
9
|
+
{
|
|
10
|
+
SECTION("parse payload descriptor")
|
|
11
|
+
{
|
|
12
|
+
// clang-format off
|
|
13
|
+
uint8_t originalBuffer[] =
|
|
14
|
+
{
|
|
15
|
+
0x07, 0x80, 0x11, 0x00
|
|
16
|
+
};
|
|
17
|
+
// clang-format on
|
|
18
|
+
//
|
|
19
|
+
// Keep a copy of the original buffer for comparing.
|
|
20
|
+
uint8_t buffer[4] = { 0 };
|
|
21
|
+
|
|
22
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
23
|
+
|
|
24
|
+
const auto* payloadDescriptor = Codecs::H264::Parse(buffer, sizeof(buffer));
|
|
25
|
+
|
|
26
|
+
REQUIRE(payloadDescriptor);
|
|
27
|
+
|
|
28
|
+
delete payloadDescriptor;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#include "common.hpp"
|
|
2
|
+
#include "RTC/Codecs/H264_SVC.hpp"
|
|
3
|
+
#include <catch2/catch.hpp>
|
|
4
|
+
#include <cstring> // std::memcmp()
|
|
5
|
+
|
|
6
|
+
using namespace RTC;
|
|
7
|
+
|
|
8
|
+
SCENARIO("parse H264_SVC payload descriptor", "[codecs][h264_svc]")
|
|
9
|
+
{
|
|
10
|
+
SECTION("parse payload descriptor for NALU 7")
|
|
11
|
+
{
|
|
12
|
+
// clang-format off
|
|
13
|
+
uint8_t originalBuffer[] =
|
|
14
|
+
{
|
|
15
|
+
0x67,0x42,0xc0,0x33
|
|
16
|
+
};
|
|
17
|
+
// clang-format on
|
|
18
|
+
|
|
19
|
+
// Keep a copy of the original buffer for comparing.
|
|
20
|
+
uint8_t buffer[4] = { 0 };
|
|
21
|
+
|
|
22
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
23
|
+
|
|
24
|
+
const auto* payloadDescriptor = Codecs::H264_SVC::Parse(buffer, sizeof(buffer));
|
|
25
|
+
|
|
26
|
+
REQUIRE(payloadDescriptor);
|
|
27
|
+
|
|
28
|
+
REQUIRE(payloadDescriptor->tlIndex == 0);
|
|
29
|
+
REQUIRE(payloadDescriptor->slIndex == 0);
|
|
30
|
+
|
|
31
|
+
REQUIRE(payloadDescriptor->isKeyFrame == true);
|
|
32
|
+
REQUIRE(payloadDescriptor->hasTlIndex == false);
|
|
33
|
+
REQUIRE(payloadDescriptor->hasSlIndex == false);
|
|
34
|
+
|
|
35
|
+
delete payloadDescriptor;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
SECTION("parse payload descriptor for NALU 8")
|
|
39
|
+
{
|
|
40
|
+
// clang-format off
|
|
41
|
+
uint8_t originalBuffer[] =
|
|
42
|
+
{
|
|
43
|
+
0x68,0xce,0x01,0xa8
|
|
44
|
+
};
|
|
45
|
+
// clang-format on
|
|
46
|
+
|
|
47
|
+
// Keep a copy of the original buffer for comparing.
|
|
48
|
+
uint8_t buffer[4] = { 0 };
|
|
49
|
+
|
|
50
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
51
|
+
|
|
52
|
+
const auto* payloadDescriptor = Codecs::H264_SVC::Parse(buffer, sizeof(buffer));
|
|
53
|
+
|
|
54
|
+
REQUIRE(payloadDescriptor);
|
|
55
|
+
|
|
56
|
+
REQUIRE(payloadDescriptor->tlIndex == 0);
|
|
57
|
+
REQUIRE(payloadDescriptor->slIndex == 0);
|
|
58
|
+
|
|
59
|
+
REQUIRE(payloadDescriptor->isKeyFrame == false);
|
|
60
|
+
REQUIRE(payloadDescriptor->hasTlIndex == false);
|
|
61
|
+
REQUIRE(payloadDescriptor->hasSlIndex == false);
|
|
62
|
+
|
|
63
|
+
delete payloadDescriptor;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
SECTION("parse payload descriptor for NALU 1")
|
|
67
|
+
{
|
|
68
|
+
// clang-format off
|
|
69
|
+
uint8_t originalBuffer[] =
|
|
70
|
+
{
|
|
71
|
+
0x81,0xe0,0x00,0x4e
|
|
72
|
+
};
|
|
73
|
+
// clang-format on
|
|
74
|
+
|
|
75
|
+
// Keep a copy of the original buffer for comparing.
|
|
76
|
+
uint8_t buffer[4] = { 0 };
|
|
77
|
+
|
|
78
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
79
|
+
|
|
80
|
+
const auto* payloadDescriptor = Codecs::H264_SVC::Parse(buffer, sizeof(buffer));
|
|
81
|
+
|
|
82
|
+
REQUIRE(payloadDescriptor);
|
|
83
|
+
|
|
84
|
+
REQUIRE(payloadDescriptor->tlIndex == 0);
|
|
85
|
+
REQUIRE(payloadDescriptor->slIndex == 0);
|
|
86
|
+
|
|
87
|
+
REQUIRE(payloadDescriptor->isKeyFrame == false);
|
|
88
|
+
REQUIRE(payloadDescriptor->hasTlIndex == false);
|
|
89
|
+
REQUIRE(payloadDescriptor->hasSlIndex == false);
|
|
90
|
+
|
|
91
|
+
delete payloadDescriptor;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
SECTION("parse payload descriptor for NALU 5")
|
|
95
|
+
{
|
|
96
|
+
// clang-format off
|
|
97
|
+
uint8_t originalBuffer[] =
|
|
98
|
+
{
|
|
99
|
+
0x85,0xb8,0x00,0x04
|
|
100
|
+
};
|
|
101
|
+
// clang-format on
|
|
102
|
+
|
|
103
|
+
// Keep a copy of the original buffer for comparing.
|
|
104
|
+
uint8_t buffer[4] = { 0 };
|
|
105
|
+
|
|
106
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
107
|
+
|
|
108
|
+
const auto* payloadDescriptor = Codecs::H264_SVC::Parse(buffer, sizeof(buffer));
|
|
109
|
+
|
|
110
|
+
REQUIRE(payloadDescriptor);
|
|
111
|
+
|
|
112
|
+
REQUIRE(payloadDescriptor->tlIndex == 0);
|
|
113
|
+
REQUIRE(payloadDescriptor->slIndex == 0);
|
|
114
|
+
|
|
115
|
+
REQUIRE(payloadDescriptor->isKeyFrame == true);
|
|
116
|
+
REQUIRE(payloadDescriptor->hasTlIndex == false);
|
|
117
|
+
REQUIRE(payloadDescriptor->hasSlIndex == false);
|
|
118
|
+
|
|
119
|
+
delete payloadDescriptor;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
SECTION("parse payload descriptor for NALU 14")
|
|
123
|
+
{
|
|
124
|
+
// clang-format off
|
|
125
|
+
uint8_t originalBuffer[] =
|
|
126
|
+
{
|
|
127
|
+
0x6e,0x80,0x90,0x20
|
|
128
|
+
};
|
|
129
|
+
// clang-format on
|
|
130
|
+
|
|
131
|
+
// Keep a copy of the original buffer for comparing.
|
|
132
|
+
uint8_t buffer[4] = { 0 };
|
|
133
|
+
|
|
134
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
135
|
+
|
|
136
|
+
const auto* payloadDescriptor = Codecs::H264_SVC::Parse(buffer, sizeof(buffer));
|
|
137
|
+
|
|
138
|
+
REQUIRE(payloadDescriptor);
|
|
139
|
+
|
|
140
|
+
REQUIRE(payloadDescriptor->idr == 0);
|
|
141
|
+
|
|
142
|
+
REQUIRE(payloadDescriptor->tlIndex == 1);
|
|
143
|
+
REQUIRE(payloadDescriptor->slIndex == 1);
|
|
144
|
+
|
|
145
|
+
REQUIRE(payloadDescriptor->isKeyFrame == false);
|
|
146
|
+
REQUIRE(payloadDescriptor->hasTlIndex == true);
|
|
147
|
+
REQUIRE(payloadDescriptor->hasSlIndex == true);
|
|
148
|
+
|
|
149
|
+
delete payloadDescriptor;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
SECTION("parse payload descriptor for NALU 20")
|
|
153
|
+
{
|
|
154
|
+
// clang-format off
|
|
155
|
+
uint8_t originalBuffer[] =
|
|
156
|
+
{
|
|
157
|
+
0x74,0x80,0x90,0x20
|
|
158
|
+
};
|
|
159
|
+
// clang-format on
|
|
160
|
+
|
|
161
|
+
// Keep a copy of the original buffer for comparing.
|
|
162
|
+
uint8_t buffer[4] = { 0 };
|
|
163
|
+
|
|
164
|
+
std::memcpy(buffer, originalBuffer, sizeof(buffer));
|
|
165
|
+
|
|
166
|
+
const auto* payloadDescriptor = Codecs::H264_SVC::Parse(buffer, sizeof(buffer));
|
|
167
|
+
|
|
168
|
+
REQUIRE(payloadDescriptor);
|
|
169
|
+
|
|
170
|
+
REQUIRE(payloadDescriptor->idr == 0);
|
|
171
|
+
|
|
172
|
+
REQUIRE(payloadDescriptor->tlIndex == 1);
|
|
173
|
+
REQUIRE(payloadDescriptor->slIndex == 1);
|
|
174
|
+
|
|
175
|
+
REQUIRE(payloadDescriptor->isKeyFrame == false);
|
|
176
|
+
REQUIRE(payloadDescriptor->hasTlIndex == true);
|
|
177
|
+
REQUIRE(payloadDescriptor->hasSlIndex == true);
|
|
178
|
+
|
|
179
|
+
delete payloadDescriptor;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
using namespace RTC;
|
|
10
10
|
|
|
11
|
+
static constexpr unsigned int SendNackDelay{ 0u }; // In ms.
|
|
12
|
+
|
|
11
13
|
struct TestNackGeneratorInput
|
|
12
14
|
{
|
|
13
15
|
TestNackGeneratorInput() = default;
|
|
@@ -121,7 +123,7 @@ RtpPacket* packet = RtpPacket::Parse(rtpBuffer, sizeof(rtpBuffer));
|
|
|
121
123
|
void validate(std::vector<TestNackGeneratorInput>& inputs)
|
|
122
124
|
{
|
|
123
125
|
TestNackGeneratorListener listener;
|
|
124
|
-
NackGenerator nackGenerator = NackGenerator(&listener);
|
|
126
|
+
NackGenerator nackGenerator = NackGenerator(&listener, SendNackDelay);
|
|
125
127
|
|
|
126
128
|
for (auto input : inputs)
|
|
127
129
|
{
|