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.
Files changed (79) hide show
  1. package/node/lib/ActiveSpeakerObserver.d.ts +1 -1
  2. package/node/lib/ActiveSpeakerObserver.d.ts.map +1 -1
  3. package/node/lib/AudioLevelObserver.d.ts +1 -1
  4. package/node/lib/AudioLevelObserver.d.ts.map +1 -1
  5. package/node/lib/Consumer.d.ts +4 -4
  6. package/node/lib/Consumer.d.ts.map +1 -1
  7. package/node/lib/Consumer.js +1 -1
  8. package/node/lib/DataConsumer.d.ts +4 -4
  9. package/node/lib/DataConsumer.d.ts.map +1 -1
  10. package/node/lib/DataConsumer.js +1 -1
  11. package/node/lib/DataProducer.d.ts +4 -4
  12. package/node/lib/DataProducer.d.ts.map +1 -1
  13. package/node/lib/DataProducer.js +1 -1
  14. package/node/lib/DirectTransport.d.ts +1 -1
  15. package/node/lib/DirectTransport.d.ts.map +1 -1
  16. package/node/lib/PipeTransport.d.ts +2 -2
  17. package/node/lib/PipeTransport.d.ts.map +1 -1
  18. package/node/lib/PipeTransport.js +1 -1
  19. package/node/lib/PlainTransport.d.ts +1 -1
  20. package/node/lib/PlainTransport.d.ts.map +1 -1
  21. package/node/lib/Producer.d.ts +4 -4
  22. package/node/lib/Producer.d.ts.map +1 -1
  23. package/node/lib/Producer.js +1 -1
  24. package/node/lib/Router.d.ts +4 -4
  25. package/node/lib/Router.d.ts.map +1 -1
  26. package/node/lib/Router.js +7 -7
  27. package/node/lib/RtpObserver.d.ts +3 -3
  28. package/node/lib/RtpObserver.d.ts.map +1 -1
  29. package/node/lib/RtpObserver.js +1 -1
  30. package/node/lib/Transport.d.ts +3 -3
  31. package/node/lib/Transport.d.ts.map +1 -1
  32. package/node/lib/Transport.js +5 -5
  33. package/node/lib/WebRtcTransport.d.ts +1 -1
  34. package/node/lib/WebRtcTransport.d.ts.map +1 -1
  35. package/node/lib/Worker.d.ts +3 -3
  36. package/node/lib/Worker.d.ts.map +1 -1
  37. package/node/lib/Worker.js +3 -3
  38. package/node/lib/index.d.ts +1 -1
  39. package/node/lib/index.d.ts.map +1 -1
  40. package/node/lib/index.js +2 -2
  41. package/node/lib/ortc.js +1 -0
  42. package/node/lib/supportedRtpCapabilities.d.ts.map +1 -1
  43. package/node/lib/supportedRtpCapabilities.js +15 -0
  44. package/package.json +6 -6
  45. package/worker/include/RTC/Codecs/H264_SVC.hpp +115 -0
  46. package/worker/include/RTC/Codecs/Tools.hpp +11 -0
  47. package/worker/include/RTC/Consumer.hpp +5 -4
  48. package/worker/include/RTC/DirectTransport.hpp +4 -0
  49. package/worker/include/RTC/NackGenerator.hpp +5 -2
  50. package/worker/include/RTC/PipeConsumer.hpp +1 -0
  51. package/worker/include/RTC/RTCP/CompoundPacket.hpp +2 -0
  52. package/worker/include/RTC/RtpDictionaries.hpp +1 -0
  53. package/worker/include/RTC/RtpStream.hpp +2 -0
  54. package/worker/include/RTC/RtpStreamRecv.hpp +7 -1
  55. package/worker/include/RTC/RtpStreamSend.hpp +7 -0
  56. package/worker/include/RTC/SimpleConsumer.hpp +1 -0
  57. package/worker/include/RTC/SimulcastConsumer.hpp +4 -0
  58. package/worker/include/RTC/SvcConsumer.hpp +1 -0
  59. package/worker/meson.build +4 -0
  60. package/worker/src/RTC/Codecs/H264_SVC.cpp +428 -0
  61. package/worker/src/RTC/DirectTransport.cpp +10 -1
  62. package/worker/src/RTC/NackGenerator.cpp +27 -9
  63. package/worker/src/RTC/PipeConsumer.cpp +20 -0
  64. package/worker/src/RTC/Producer.cpp +5 -1
  65. package/worker/src/RTC/RTCP/CompoundPacket.cpp +7 -0
  66. package/worker/src/RTC/RtpDictionaries/RtpCodecMimeType.cpp +2 -0
  67. package/worker/src/RTC/RtpStreamRecv.cpp +4 -3
  68. package/worker/src/RTC/RtpStreamSend.cpp +32 -0
  69. package/worker/src/RTC/SimpleConsumer.cpp +17 -0
  70. package/worker/src/RTC/SimulcastConsumer.cpp +45 -4
  71. package/worker/src/RTC/SvcConsumer.cpp +17 -0
  72. package/worker/src/RTC/Transport.cpp +14 -0
  73. package/worker/src/RTC/TransportCongestionControlClient.cpp +0 -3
  74. package/worker/test/include/helpers.hpp +119 -0
  75. package/worker/test/src/RTC/Codecs/TestH264.cpp +30 -0
  76. package/worker/test/src/RTC/Codecs/TestH264_SVC.cpp +181 -0
  77. package/worker/test/src/RTC/TestNackGenerator.cpp +3 -1
  78. package/worker/test/src/RTC/TestRtpPacketH264Svc.cpp +455 -0
  79. 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 = true;
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 = true;
1076
- this->keyFrameForTsOffsetRequested = false;
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
  {