mediasoup 3.13.12 → 3.13.13

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ortc.d.ts","sourceRoot":"","sources":["../src/ortc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ortc.d.ts","sourceRoot":"","sources":["../src/ortc.ts"],"names":[],"mappings":"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"}
package/node/lib/ortc.js CHANGED
@@ -949,7 +949,7 @@ function matchCodecs(aCodec, bCodec, { strict = false, modify = false } = {}) {
949
949
  let selectedProfileLevelId;
950
950
  try {
951
951
  selectedProfileLevelId =
952
- h264.generateProfileLevelIdForAnswer(aCodec.parameters, bCodec.parameters);
952
+ h264.generateProfileLevelIdStringForAnswer(aCodec.parameters, bCodec.parameters);
953
953
  }
954
954
  catch (error) {
955
955
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediasoup",
3
- "version": "3.13.12",
3
+ "version": "3.13.13",
4
4
  "description": "Cutting Edge WebRTC Video Conferencing",
5
5
  "contributors": [
6
6
  "Iñaki Baz Castillo <ibc@aliax.net> (https://inakibaz.me)",
@@ -99,7 +99,7 @@
99
99
  "dependencies": {
100
100
  "debug": "^4.3.4",
101
101
  "flatbuffers": "^23.5.26",
102
- "h264-profile-level-id": "^1.1.0",
102
+ "h264-profile-level-id": "^2.0.0",
103
103
  "node-fetch": "^3.3.2",
104
104
  "supports-color": "^9.4.0",
105
105
  "tar": "^6.2.0"
@@ -109,8 +109,8 @@
109
109
  "@types/debug": "^4.1.12",
110
110
  "@types/jest": "^29.5.11",
111
111
  "@types/node": "^20.10.5",
112
- "@typescript-eslint/eslint-plugin": "^6.14.0",
113
- "@typescript-eslint/parser": "^6.14.0",
112
+ "@typescript-eslint/eslint-plugin": "^6.16.0",
113
+ "@typescript-eslint/parser": "^6.16.0",
114
114
  "eslint": "^8.56.0",
115
115
  "eslint-plugin-jest": "^27.6.0",
116
116
  "jest": "^29.7.0",
@@ -80,6 +80,10 @@ public:
80
80
  {
81
81
  return this->active;
82
82
  }
83
+ bool IsZeroCopyEnabled() const
84
+ {
85
+ return this->zeroCopyEnabled;
86
+ }
83
87
  io_uring* GetRing()
84
88
  {
85
89
  return std::addressof(this->ring);
@@ -103,18 +107,22 @@ public:
103
107
  private:
104
108
  // io_uring instance.
105
109
  io_uring ring;
106
- // Event file descriptor to watch for completions.
110
+ // Event file descriptor to watch for io_uring completions.
107
111
  int efd;
108
112
  // libuv handle used to poll io_uring completions.
109
113
  uv_poll_t* uvHandle{ nullptr };
110
114
  // Whether we are currently sending RTP over io_uring.
111
115
  bool active{ false };
116
+ // Whether Zero Copy feature is enabled.
117
+ bool zeroCopyEnabled{ true };
112
118
  // Pre-allocated UserData's.
113
119
  UserData userDatas[QueueDepth]{};
114
120
  // Indexes of available UserData entries.
115
121
  std::queue<size_t> availableUserDataEntries;
116
122
  // Pre-allocated SendBuffer's.
117
123
  SendBuffer sendBuffers[QueueDepth];
124
+ // iovec structs to be registered for Zero Copy.
125
+ struct iovec iovecs[QueueDepth];
118
126
  // Submission queue entry process count.
119
127
  uint64_t sqeProcessCount{ 0u };
120
128
  // Submission queue entry miss count.
@@ -89,7 +89,7 @@ namespace RTC
89
89
  public:
90
90
  void TransportConnected();
91
91
  void TransportDisconnected();
92
- void RtpPacketSent(SentInfo& sentInfo);
92
+ void RtpPacketSent(const SentInfo& sentInfo);
93
93
  void ReceiveRtcpTransportFeedback(const RTC::RTCP::FeedbackRtpTransportPacket* feedback);
94
94
  void EstimateAvailableBitrate(CummulativeResult& cummulativeResult);
95
95
  void UpdateRtt(float rtt);
@@ -69,7 +69,7 @@ namespace RTC
69
69
  void TransportDisconnected();
70
70
  void InsertPacket(webrtc::RtpPacketSendInfo& packetInfo);
71
71
  webrtc::PacedPacketInfo GetPacingInfo();
72
- void PacketSent(webrtc::RtpPacketSendInfo& packetInfo, int64_t nowMs);
72
+ void PacketSent(const webrtc::RtpPacketSendInfo& packetInfo, int64_t nowMs);
73
73
  void ReceiveEstimatedBitrate(uint32_t bitrate);
74
74
  void ReceiveRtcpReceiverReport(RTC::RTCP::ReceiverReportPacket* packet, float rtt, int64_t nowMs);
75
75
  void ReceiveRtcpTransportFeedback(const RTC::RTCP::FeedbackRtpTransportPacket* feedback);
@@ -23,6 +23,8 @@ namespace Utils
23
23
 
24
24
  static void GetAddressInfo(const struct sockaddr* addr, int& family, std::string& ip, uint16_t& port);
25
25
 
26
+ static size_t GetAddressLen(const struct sockaddr* addr);
27
+
26
28
  static bool CompareAddresses(const struct sockaddr* addr1, const struct sockaddr* addr2)
27
29
  {
28
30
  // Compare family.
@@ -44,6 +44,18 @@ if get_option('ms_rtc_logger_rtp')
44
44
  ]
45
45
  endif
46
46
 
47
+ cpp = meson.get_compiler('cpp')
48
+
49
+ # This is a workaround to define FLATBUFFERS_LOCALE_INDEPENDENT=0 outside
50
+ # flatbuffers project, which is needed in case the current arch doesn't support
51
+ # strtoll_l or strtoull_l (such as musl in Alpine Linux). Problem is that
52
+ # flatbuffers build system not only defines it for its own usage but also relies
53
+ # on it in its include/flatbuffers/util.h file, and if such a file is included
54
+ # by mediasoup source files (and it is included) build fails with "error:
55
+ # 'strtoull_l' was not declared in this scope".
56
+ # See issue: https://github.com/versatica/mediasoup/issues/1223
57
+ add_project_arguments('-DFLATBUFFERS_LOCALE_INDEPENDENT=@0@'.format(cpp.has_function('strtoull_l')), language: 'cpp')
58
+
47
59
  common_sources = [
48
60
  'src/lib.cpp',
49
61
  'src/DepLibSRTP.cpp',
@@ -163,14 +175,13 @@ common_sources = [
163
175
  'src/RTC/RTCP/XrReceiverReferenceTime.cpp',
164
176
  ]
165
177
 
166
- cpp = meson.get_compiler('cpp')
167
-
168
178
  openssl_proj = subproject(
169
179
  'openssl',
170
180
  default_options: [
171
181
  'warning_level=0',
172
182
  ],
173
183
  )
184
+
174
185
  libuv_proj = subproject(
175
186
  'libuv',
176
187
  default_options: [
@@ -179,6 +190,7 @@ libuv_proj = subproject(
179
190
  'build_benchmarks=false',
180
191
  ],
181
192
  )
193
+
182
194
  libsrtp2_proj = subproject(
183
195
  'libsrtp2',
184
196
  default_options: [
@@ -188,6 +200,7 @@ libsrtp2_proj = subproject(
188
200
  'tests=disabled',
189
201
  ],
190
202
  )
203
+
191
204
  usrsctp_proj = subproject(
192
205
  'usrsctp',
193
206
  default_options: [
@@ -195,6 +208,7 @@ usrsctp_proj = subproject(
195
208
  'sctp_build_programs=false',
196
209
  ],
197
210
  )
211
+
198
212
  abseil_cpp_proj = subproject(
199
213
  'abseil-cpp',
200
214
  default_options: [
@@ -202,20 +216,24 @@ abseil_cpp_proj = subproject(
202
216
  'cpp_std=c++17',
203
217
  ],
204
218
  )
219
+
205
220
  catch2_proj = subproject(
206
221
  'catch2',
207
222
  default_options: [
208
223
  'warning_level=0',
209
224
  ],
210
225
  )
226
+
211
227
  flatbuffers_proj = subproject(
212
228
  'flatbuffers',
213
229
  default_options: [
214
230
  'warning_level=0',
215
231
  ],
216
232
  )
233
+
217
234
  # flatbuffers schemas subdirectory.
218
235
  subdir('fbs')
236
+
219
237
  # Add current build directory so libwebrtc has access to FBS folder.
220
238
  libwebrtc_include_directories = include_directories('include', 'fbs')
221
239
  subdir('deps/libwebrtc')
@@ -305,48 +323,48 @@ executable(
305
323
  )
306
324
 
307
325
  test_sources = [
308
- 'test/src/tests.cpp',
309
- 'test/src/RTC/TestKeyFrameRequestManager.cpp',
310
- 'test/src/RTC/TestNackGenerator.cpp',
311
- 'test/src/RTC/TestRateCalculator.cpp',
312
- 'test/src/RTC/TestRtpPacket.cpp',
313
- 'test/src/RTC/TestRtpPacketH264Svc.cpp',
314
- 'test/src/RTC/TestRtpRetransmissionBuffer.cpp',
315
- 'test/src/RTC/TestRtpStreamSend.cpp',
316
- 'test/src/RTC/TestRtpStreamRecv.cpp',
317
- 'test/src/RTC/TestSeqManager.cpp',
318
- 'test/src/RTC/TestTrendCalculator.cpp',
319
- 'test/src/RTC/TestRtpEncodingParameters.cpp',
320
- 'test/src/RTC/Codecs/TestVP8.cpp',
321
- 'test/src/RTC/Codecs/TestVP9.cpp',
322
- 'test/src/RTC/Codecs/TestH264.cpp',
323
- 'test/src/RTC/Codecs/TestH264_SVC.cpp',
324
- 'test/src/RTC/RTCP/TestFeedbackPsAfb.cpp',
325
- 'test/src/RTC/RTCP/TestFeedbackPsFir.cpp',
326
- 'test/src/RTC/RTCP/TestFeedbackPsLei.cpp',
327
- 'test/src/RTC/RTCP/TestFeedbackPsPli.cpp',
328
- 'test/src/RTC/RTCP/TestFeedbackPsRemb.cpp',
329
- 'test/src/RTC/RTCP/TestFeedbackPsRpsi.cpp',
330
- 'test/src/RTC/RTCP/TestFeedbackPsSli.cpp',
331
- 'test/src/RTC/RTCP/TestFeedbackPsTst.cpp',
332
- 'test/src/RTC/RTCP/TestFeedbackPsVbcm.cpp',
333
- 'test/src/RTC/RTCP/TestFeedbackRtpEcn.cpp',
334
- 'test/src/RTC/RTCP/TestFeedbackRtpNack.cpp',
335
- 'test/src/RTC/RTCP/TestFeedbackRtpSrReq.cpp',
336
- 'test/src/RTC/RTCP/TestFeedbackRtpTllei.cpp',
337
- 'test/src/RTC/RTCP/TestFeedbackRtpTmmb.cpp',
338
- 'test/src/RTC/RTCP/TestFeedbackRtpTransport.cpp',
339
- 'test/src/RTC/RTCP/TestBye.cpp',
340
- 'test/src/RTC/RTCP/TestReceiverReport.cpp',
341
- 'test/src/RTC/RTCP/TestSdes.cpp',
342
- 'test/src/RTC/RTCP/TestSenderReport.cpp',
343
- 'test/src/RTC/RTCP/TestPacket.cpp',
344
- 'test/src/RTC/RTCP/TestXr.cpp',
345
- 'test/src/Utils/TestBits.cpp',
346
- 'test/src/Utils/TestByte.cpp',
347
- 'test/src/Utils/TestIP.cpp',
348
- 'test/src/Utils/TestString.cpp',
349
- 'test/src/Utils/TestTime.cpp',
326
+ 'test/src/tests.cpp',
327
+ 'test/src/RTC/TestKeyFrameRequestManager.cpp',
328
+ 'test/src/RTC/TestNackGenerator.cpp',
329
+ 'test/src/RTC/TestRateCalculator.cpp',
330
+ 'test/src/RTC/TestRtpPacket.cpp',
331
+ 'test/src/RTC/TestRtpPacketH264Svc.cpp',
332
+ 'test/src/RTC/TestRtpRetransmissionBuffer.cpp',
333
+ 'test/src/RTC/TestRtpStreamSend.cpp',
334
+ 'test/src/RTC/TestRtpStreamRecv.cpp',
335
+ 'test/src/RTC/TestSeqManager.cpp',
336
+ 'test/src/RTC/TestTrendCalculator.cpp',
337
+ 'test/src/RTC/TestRtpEncodingParameters.cpp',
338
+ 'test/src/RTC/Codecs/TestVP8.cpp',
339
+ 'test/src/RTC/Codecs/TestVP9.cpp',
340
+ 'test/src/RTC/Codecs/TestH264.cpp',
341
+ 'test/src/RTC/Codecs/TestH264_SVC.cpp',
342
+ 'test/src/RTC/RTCP/TestFeedbackPsAfb.cpp',
343
+ 'test/src/RTC/RTCP/TestFeedbackPsFir.cpp',
344
+ 'test/src/RTC/RTCP/TestFeedbackPsLei.cpp',
345
+ 'test/src/RTC/RTCP/TestFeedbackPsPli.cpp',
346
+ 'test/src/RTC/RTCP/TestFeedbackPsRemb.cpp',
347
+ 'test/src/RTC/RTCP/TestFeedbackPsRpsi.cpp',
348
+ 'test/src/RTC/RTCP/TestFeedbackPsSli.cpp',
349
+ 'test/src/RTC/RTCP/TestFeedbackPsTst.cpp',
350
+ 'test/src/RTC/RTCP/TestFeedbackPsVbcm.cpp',
351
+ 'test/src/RTC/RTCP/TestFeedbackRtpEcn.cpp',
352
+ 'test/src/RTC/RTCP/TestFeedbackRtpNack.cpp',
353
+ 'test/src/RTC/RTCP/TestFeedbackRtpSrReq.cpp',
354
+ 'test/src/RTC/RTCP/TestFeedbackRtpTllei.cpp',
355
+ 'test/src/RTC/RTCP/TestFeedbackRtpTmmb.cpp',
356
+ 'test/src/RTC/RTCP/TestFeedbackRtpTransport.cpp',
357
+ 'test/src/RTC/RTCP/TestBye.cpp',
358
+ 'test/src/RTC/RTCP/TestReceiverReport.cpp',
359
+ 'test/src/RTC/RTCP/TestSdes.cpp',
360
+ 'test/src/RTC/RTCP/TestSenderReport.cpp',
361
+ 'test/src/RTC/RTCP/TestPacket.cpp',
362
+ 'test/src/RTC/RTCP/TestXr.cpp',
363
+ 'test/src/Utils/TestBits.cpp',
364
+ 'test/src/Utils/TestByte.cpp',
365
+ 'test/src/Utils/TestIP.cpp',
366
+ 'test/src/Utils/TestString.cpp',
367
+ 'test/src/Utils/TestTime.cpp',
350
368
  ]
351
369
 
352
370
  mediasoup_worker_test = executable(
@@ -29,7 +29,7 @@ CPPCHECKS="warning,style,performance,portability,unusedFunction"
29
29
  XML_FILE="/tmp/mediasoup-worker-cppcheck.xml"
30
30
  HTML_REPORT_DIR="/tmp/mediasoup-worker-cppcheck-report"
31
31
 
32
- echo ">>> [INFO] running cppcheck ..."
32
+ echo ">>> [INFO] running cppcheck..."
33
33
  cppcheck --std=c++11 --enable=${CPPCHECKS} -v --quiet --report-progress --inline-suppr --error-exitcode=69 -I include src --xml-version=2 2> $XML_FILE
34
34
 
35
35
  # If exit code is 1 it means that some cppcheck option is wrong, so abort.
@@ -40,12 +40,12 @@ fi
40
40
 
41
41
  echo ">>> [INFO] cppcheck XML report file generated in ${XML_FILE}"
42
42
 
43
- echo ">>> [INFO] running cppcheck-htmlreport ..."
43
+ echo ">>> [INFO] running cppcheck-htmlreport..."
44
44
  cppcheck-htmlreport --title="mediasoup-worker" --file=${XML_FILE} --report-dir=${HTML_REPORT_DIR} --source-dir=. > /dev/null
45
45
 
46
46
  echo ">>> [INFO] cppcheck HTML report generated in ${HTML_REPORT_DIR}"
47
47
 
48
48
  if type "open" &> /dev/null; then
49
- echo ">>> [INFO] opening HTML report ..."
49
+ echo ">>> [INFO] opening HTML report..."
50
50
  open ${HTML_REPORT_DIR}/index.html
51
51
  fi
@@ -13,9 +13,9 @@ if ! type "flint++" &> /dev/null; then
13
13
  exit 1
14
14
  fi
15
15
 
16
- echo ">>> [INFO] running flint++ in src/ folder ..."
16
+ echo ">>> [INFO] running flint++ in src/ folder..."
17
17
  flint++ --recursive --verbose src/
18
18
 
19
19
  echo
20
- echo ">>> [INFO] running flint++ in include/ folder ..."
20
+ echo ">>> [INFO] running flint++ in include/ folder..."
21
21
  flint++ --recursive --verbose include/
@@ -17,24 +17,24 @@ function get_dep()
17
17
  GIT_TAG="$2"
18
18
  DEST="$3"
19
19
 
20
- echo ">>> [INFO] getting dep '${DEP}' ..."
20
+ echo ">>> [INFO] getting dep '${DEP}'..."
21
21
 
22
22
  if [ -d "${DEST}" ] ; then
23
- echo ">>> [INFO] deleting ${DEST} ..."
23
+ echo ">>> [INFO] deleting ${DEST}..."
24
24
  git rm -rf --ignore-unmatch ${DEST} > /dev/null
25
25
  rm -rf ${DEST}
26
26
  fi
27
27
 
28
- echo ">>> [INFO] cloning ${GIT_REPO} ..."
28
+ echo ">>> [INFO] cloning ${GIT_REPO}..."
29
29
  git clone ${GIT_REPO} ${DEST}
30
30
 
31
31
  cd ${DEST}
32
32
 
33
- echo ">>> [INFO] setting '${GIT_TAG}' git tag ..."
33
+ echo ">>> [INFO] setting '${GIT_TAG}' git tag..."
34
34
  git checkout --quiet ${GIT_TAG}
35
35
  set -e
36
36
 
37
- echo ">>> [INFO] adding dep source code to the repository ..."
37
+ echo ">>> [INFO] adding dep source code to the repository..."
38
38
  rm -rf .git
39
39
  git add .
40
40
 
@@ -4,6 +4,7 @@
4
4
  #include "DepLibUring.hpp"
5
5
  #include "Logger.hpp"
6
6
  #include "MediaSoupErrors.hpp"
7
+ #include "Utils.hpp"
7
8
  #include <sys/eventfd.h>
8
9
  #include <sys/utsname.h>
9
10
 
@@ -30,9 +31,13 @@ inline static void onFdEvent(uv_poll_t* handle, int status, int events)
30
31
  // the counter in order to avoid libuv calling this callback indefinitely.
31
32
  eventfd_t v;
32
33
  int err = eventfd_read(liburing->GetEventFd(), std::addressof(v));
34
+
33
35
  if (err < 0)
34
36
  {
35
- MS_ABORT("eventfd_read() failed: %s", std::strerror(-err));
37
+ // Get positive errno.
38
+ int error = -err;
39
+
40
+ MS_ABORT("eventfd_read() failed: %s", std::strerror(error));
36
41
  };
37
42
 
38
43
  for (unsigned int i{ 0 }; i < count; ++i)
@@ -40,27 +45,69 @@ inline static void onFdEvent(uv_poll_t* handle, int status, int events)
40
45
  struct io_uring_cqe* cqe = cqes[i];
41
46
  auto* userData = static_cast<DepLibUring::UserData*>(io_uring_cqe_get_data(cqe));
42
47
 
43
- if (cqe->res < 0)
48
+ if (liburing->IsZeroCopyEnabled())
44
49
  {
45
- MS_ERROR("sending failed: %s", std::strerror(-cqe->res));
50
+ // CQE notification for a zero-copy submission.
51
+ if (cqe->flags & IORING_CQE_F_NOTIF)
52
+ {
53
+ // The send buffer is now in the network card, run the send callback.
54
+ if (userData->cb)
55
+ {
56
+ (*userData->cb)(true);
57
+ delete userData->cb;
58
+ userData->cb = nullptr;
59
+ }
60
+
61
+ liburing->ReleaseUserDataEntry(userData->idx);
62
+ io_uring_cqe_seen(liburing->GetRing(), cqe);
63
+
64
+ continue;
65
+ }
46
66
 
67
+ // CQE for a zero-copy submission, a CQE notification will follow.
68
+ if (cqe->flags & IORING_CQE_F_MORE)
69
+ {
70
+ if (cqe->res < 0)
71
+ {
72
+ if (userData->cb)
73
+ {
74
+ (*userData->cb)(false);
75
+ delete userData->cb;
76
+ userData->cb = nullptr;
77
+ }
78
+ }
79
+
80
+ // NOTE: Do not release the user data as it will be done upon reception
81
+ // of CQE notification.
82
+ io_uring_cqe_seen(liburing->GetRing(), cqe);
83
+
84
+ continue;
85
+ }
86
+ }
87
+
88
+ // Successfull SQE.
89
+ if (cqe->res >= 0)
90
+ {
47
91
  if (userData->cb)
48
92
  {
49
- (*userData->cb)(false);
93
+ (*userData->cb)(true);
50
94
  delete userData->cb;
95
+ userData->cb = nullptr;
51
96
  }
52
97
  }
98
+ // Failed SQE.
53
99
  else
54
100
  {
55
101
  if (userData->cb)
56
102
  {
57
- (*userData->cb)(true);
103
+ (*userData->cb)(false);
58
104
  delete userData->cb;
105
+ userData->cb = nullptr;
59
106
  }
60
107
  }
61
108
 
62
- io_uring_cqe_seen(liburing->GetRing(), cqe);
63
109
  liburing->ReleaseUserDataEntry(userData->idx);
110
+ io_uring_cqe_seen(liburing->GetRing(), cqe);
64
111
  }
65
112
  }
66
113
 
@@ -234,7 +281,10 @@ DepLibUring::LibUring::LibUring()
234
281
 
235
282
  if (err < 0)
236
283
  {
237
- MS_THROW_ERROR("io_uring_queue_init() failed: %s", std::strerror(-err));
284
+ // Get positive errno.
285
+ int error = -err;
286
+
287
+ MS_THROW_ERROR("io_uring_queue_init() failed: %s", std::strerror(error));
238
288
  }
239
289
 
240
290
  // Create an eventfd instance.
@@ -249,7 +299,10 @@ DepLibUring::LibUring::LibUring()
249
299
 
250
300
  if (err < 0)
251
301
  {
252
- MS_THROW_ERROR("io_uring_register_eventfd() failed: %s", std::strerror(-err));
302
+ // Get positive errno.
303
+ int error = -err;
304
+
305
+ MS_THROW_ERROR("io_uring_register_eventfd() failed: %s", std::strerror(error));
253
306
  }
254
307
 
255
308
  // Initialize available UserData entries.
@@ -258,6 +311,35 @@ DepLibUring::LibUring::LibUring()
258
311
  this->userDatas[i].store = this->sendBuffers[i];
259
312
  this->availableUserDataEntries.push(i);
260
313
  }
314
+
315
+ // Initialize iovecs.
316
+ for (size_t i{ 0 }; i < DepLibUring::QueueDepth; ++i)
317
+ {
318
+ this->iovecs[i].iov_base = this->sendBuffers[i];
319
+ this->iovecs[i].iov_len = DepLibUring::SendBufferSize;
320
+ }
321
+
322
+ err = io_uring_register_buffers(std::addressof(this->ring), this->iovecs, DepLibUring::QueueDepth);
323
+
324
+ if (err < 0)
325
+ {
326
+ // Get positive errno.
327
+ int error = -err;
328
+
329
+ if (error == ENOMEM)
330
+ {
331
+ this->zeroCopyEnabled = false;
332
+
333
+ MS_WARN_TAG(
334
+ info,
335
+ "io_uring_register_buffers() failed due to low memlock limit (ulimit -l), disabling zero copy: %s",
336
+ std::strerror(error));
337
+ }
338
+ else
339
+ {
340
+ MS_THROW_ERROR("io_uring_register_buffers() failed: %s", std::strerror(error));
341
+ }
342
+ }
261
343
  }
262
344
 
263
345
  DepLibUring::LibUring::~LibUring()
@@ -269,7 +351,10 @@ DepLibUring::LibUring::~LibUring()
269
351
 
270
352
  if (err != 0)
271
353
  {
272
- MS_ABORT("close() failed: %s", std::strerror(-err));
354
+ // Get positive errno.
355
+ int error = -err;
356
+
357
+ MS_ABORT("close() failed: %s", std::strerror(error));
273
358
  }
274
359
 
275
360
  // Close the ring.
@@ -372,8 +457,6 @@ bool DepLibUring::LibUring::PrepareSend(
372
457
  return false;
373
458
  }
374
459
 
375
- userData->cb = cb;
376
-
377
460
  // The send data buffer belongs to us, no need to memcpy.
378
461
  if (this->IsDataInSendBuffers(data))
379
462
  {
@@ -384,21 +467,30 @@ bool DepLibUring::LibUring::PrepareSend(
384
467
  std::memcpy(userData->store, data, len);
385
468
  }
386
469
 
470
+ userData->cb = cb;
471
+
387
472
  io_uring_sqe_set_data(sqe, userData);
388
473
 
389
- socklen_t addrlen = 0;
474
+ socklen_t addrlen = Utils::IP::GetAddressLen(addr);
390
475
 
391
- if (addr->sa_family == AF_INET)
476
+ if (this->zeroCopyEnabled)
392
477
  {
393
- addrlen = sizeof(struct sockaddr_in);
478
+ auto iovec = this->iovecs[userData->idx];
479
+ iovec.iov_len = len;
480
+
481
+ io_uring_prep_send_zc(sqe, sockfd, iovec.iov_base, iovec.iov_len, 0, 0);
482
+ io_uring_prep_send_set_addr(sqe, addr, addrlen);
483
+
484
+ // Tell io_uring that we are providing the already registered send buffer
485
+ // for zero copy.
486
+ sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
487
+ sqe->buf_index = userData->idx;
394
488
  }
395
- else if (addr->sa_family == AF_INET6)
489
+ else
396
490
  {
397
- addrlen = sizeof(struct sockaddr_in6);
491
+ io_uring_prep_sendto(sqe, sockfd, userData->store, len, 0, addr, addrlen);
398
492
  }
399
493
 
400
- io_uring_prep_sendto(sqe, sockfd, userData->store, len, 0, addr, addrlen);
401
-
402
494
  this->sqeProcessCount++;
403
495
 
404
496
  return true;
@@ -482,7 +574,10 @@ void DepLibUring::LibUring::Submit()
482
574
  }
483
575
  else
484
576
  {
485
- MS_ERROR("io_uring_submit() failed: %s", std::strerror(-err));
577
+ // Get positive errno.
578
+ int error = -err;
579
+
580
+ MS_ERROR("io_uring_submit() failed: %s", std::strerror(error));
486
581
  }
487
582
  }
488
583
 
@@ -503,7 +503,7 @@ namespace RTC
503
503
  auto streamId = dataProducer->GetSctpStreamParameters().streamId;
504
504
 
505
505
  // Send SCTP_RESET_STREAMS to the remote.
506
- // https://tools.ietf.org/html/draft-ietf-rtcweb-data-channel-13#section-6.7
506
+ // https://tools.ietf.org/html/rfc8831#section-6.7
507
507
  if (this->isDataChannel)
508
508
  {
509
509
  ResetSctpStream(streamId, StreamDirection::OUTGOING);
@@ -47,7 +47,7 @@ namespace RTC
47
47
  this->cummulativeResult.Reset();
48
48
  }
49
49
 
50
- void SenderBandwidthEstimator::RtpPacketSent(SentInfo& sentInfo)
50
+ void SenderBandwidthEstimator::RtpPacketSent(const SentInfo& sentInfo)
51
51
  {
52
52
  MS_TRACE();
53
53
 
@@ -2493,7 +2493,7 @@ namespace RTC
2493
2493
  sentInfo.sendingAtMs = DepLibUV::GetTimeMs();
2494
2494
 
2495
2495
  auto* cb = new onSendCallback(
2496
- [tccClientWeakPtr, &packetInfo, senderBweWeakPtr, &sentInfo](bool sent)
2496
+ [tccClientWeakPtr, packetInfo, senderBweWeakPtr, sentInfo](bool sent)
2497
2497
  {
2498
2498
  if (sent)
2499
2499
  {
@@ -2517,7 +2517,7 @@ namespace RTC
2517
2517
  SendRtpPacket(consumer, packet, cb);
2518
2518
  #else
2519
2519
  const auto* cb = new onSendCallback(
2520
- [tccClientWeakPtr, &packetInfo](bool sent)
2520
+ [tccClientWeakPtr, packetInfo](bool sent)
2521
2521
  {
2522
2522
  if (sent)
2523
2523
  {
@@ -2582,7 +2582,7 @@ namespace RTC
2582
2582
  sentInfo.sendingAtMs = DepLibUV::GetTimeMs();
2583
2583
 
2584
2584
  auto* cb = new onSendCallback(
2585
- [tccClientWeakPtr, &packetInfo, senderBweWeakPtr, &sentInfo](bool sent)
2585
+ [tccClientWeakPtr, packetInfo, senderBweWeakPtr, sentInfo](bool sent)
2586
2586
  {
2587
2587
  if (sent)
2588
2588
  {
@@ -2606,7 +2606,7 @@ namespace RTC
2606
2606
  SendRtpPacket(consumer, packet, cb);
2607
2607
  #else
2608
2608
  const auto* cb = new onSendCallback(
2609
- [tccClientWeakPtr, &packetInfo](bool sent)
2609
+ [tccClientWeakPtr, packetInfo](bool sent)
2610
2610
  {
2611
2611
  if (sent)
2612
2612
  {
@@ -2982,7 +2982,7 @@ namespace RTC
2982
2982
  sentInfo.sendingAtMs = DepLibUV::GetTimeMs();
2983
2983
 
2984
2984
  auto* cb = new onSendCallback(
2985
- [tccClientWeakPtr, &packetInfo, senderBweWeakPtr, &sentInfo](bool sent)
2985
+ [tccClientWeakPtr, packetInfo, senderBweWeakPtr, sentInfo](bool sent)
2986
2986
  {
2987
2987
  if (sent)
2988
2988
  {
@@ -3006,7 +3006,7 @@ namespace RTC
3006
3006
  SendRtpPacket(nullptr, packet, cb);
3007
3007
  #else
3008
3008
  const auto* cb = new onSendCallback(
3009
- [tccClientWeakPtr, &packetInfo](bool sent)
3009
+ [tccClientWeakPtr, packetInfo](bool sent)
3010
3010
  {
3011
3011
  if (sent)
3012
3012
  {
@@ -152,7 +152,8 @@ namespace RTC
152
152
  return this->rtpTransportControllerSend->packet_sender()->GetPacingInfo();
153
153
  }
154
154
 
155
- void TransportCongestionControlClient::PacketSent(webrtc::RtpPacketSendInfo& packetInfo, int64_t nowMs)
155
+ void TransportCongestionControlClient::PacketSent(
156
+ const webrtc::RtpPacketSendInfo& packetInfo, int64_t nowMs)
156
157
  {
157
158
  MS_TRACE();
158
159
 
@@ -91,6 +91,29 @@ namespace Utils
91
91
  ip.assign(ipBuffer);
92
92
  }
93
93
 
94
+ size_t IP::GetAddressLen(const struct sockaddr* addr)
95
+ {
96
+ MS_TRACE();
97
+
98
+ switch (addr->sa_family)
99
+ {
100
+ case AF_INET:
101
+ {
102
+ return sizeof(struct sockaddr_in);
103
+ }
104
+
105
+ case AF_INET6:
106
+ {
107
+ return sizeof(struct sockaddr_in6);
108
+ }
109
+
110
+ default:
111
+ {
112
+ MS_ABORT("unknown network family: %d", static_cast<int>(addr->sa_family));
113
+ }
114
+ }
115
+ }
116
+
94
117
  void IP::NormalizeIp(std::string& ip)
95
118
  {
96
119
  MS_TRACE();
package/worker/tasks.py CHANGED
@@ -140,59 +140,30 @@ def setup(ctx):
140
140
  """
141
141
  Run meson setup
142
142
  """
143
- # We add --reconfigure first as a workaround for this issue:
144
- # https://github.com/ninja-build/ninja/issues/1997
145
143
  if MEDIASOUP_BUILDTYPE == 'Release':
146
- try:
147
- with ctx.cd(WORKER_DIR):
148
- ctx.run(
149
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true -Db_pie=true -Db_staticpic=true --reconfigure {MESON_ARGS} "{BUILD_DIR}"',
150
- echo=True,
151
- pty=PTY_SUPPORTED,
152
- shell=SHELL
153
- );
154
- except:
155
- with ctx.cd(WORKER_DIR):
156
- ctx.run(
157
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true -Db_pie=true -Db_staticpic=true {MESON_ARGS} "{BUILD_DIR}"',
158
- echo=True,
159
- pty=PTY_SUPPORTED,
160
- shell=SHELL
161
- );
144
+ with ctx.cd(WORKER_DIR):
145
+ ctx.run(
146
+ f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype release -Db_ndebug=true -Db_pie=true -Db_staticpic=true {MESON_ARGS} "{BUILD_DIR}"',
147
+ echo=True,
148
+ pty=PTY_SUPPORTED,
149
+ shell=SHELL
150
+ );
162
151
  elif MEDIASOUP_BUILDTYPE == 'Debug':
163
- try:
164
- with ctx.cd(WORKER_DIR):
165
- ctx.run(
166
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug -Db_pie=true -Db_staticpic=true --reconfigure {MESON_ARGS} "{BUILD_DIR}"',
167
- echo=True,
168
- pty=PTY_SUPPORTED,
169
- shell=SHELL
170
- );
171
- except:
172
- with ctx.cd(WORKER_DIR):
173
- ctx.run(
174
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug -Db_pie=true -Db_staticpic=true {MESON_ARGS} "{BUILD_DIR}"',
175
- echo=True,
176
- pty=PTY_SUPPORTED,
177
- shell=SHELL
178
- );
152
+ with ctx.cd(WORKER_DIR):
153
+ ctx.run(
154
+ f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype debug -Db_pie=true -Db_staticpic=true {MESON_ARGS} "{BUILD_DIR}"',
155
+ echo=True,
156
+ pty=PTY_SUPPORTED,
157
+ shell=SHELL
158
+ );
179
159
  else:
180
- try:
181
- with ctx.cd(WORKER_DIR):
182
- ctx.run(
183
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release -Db_pie=true -Db_staticpic=true --reconfigure {MESON_ARGS} "{BUILD_DIR}"',
184
- echo=True,
185
- pty=PTY_SUPPORTED,
186
- shell=SHELL
187
- );
188
- except:
189
- with ctx.cd(WORKER_DIR):
190
- ctx.run(
191
- f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release -Db_pie=true -Db_staticpic=true {MESON_ARGS} "{BUILD_DIR}"',
192
- echo=True,
193
- pty=PTY_SUPPORTED,
194
- shell=SHELL
195
- );
160
+ with ctx.cd(WORKER_DIR):
161
+ ctx.run(
162
+ f'"{MESON}" setup --prefix "{MEDIASOUP_INSTALL_DIR}" --bindir "" --libdir "" --buildtype {MEDIASOUP_BUILDTYPE} -Db_ndebug=if-release -Db_pie=true -Db_staticpic=true {MESON_ARGS} "{BUILD_DIR}"',
163
+ echo=True,
164
+ pty=PTY_SUPPORTED,
165
+ shell=SHELL
166
+ );
196
167
 
197
168
 
198
169
  @task
@@ -350,7 +321,7 @@ def xcode(ctx):
350
321
  """
351
322
  with ctx.cd(WORKER_DIR):
352
323
  ctx.run(
353
- f'"{MESON}" setup --buildtype {MEDIASOUP_BUILDTYPE} --backend xcode "{MEDIASOUP_OUT_DIR}/xcode"',
324
+ f'"{MESON}" setup --buildtype {MEDIASOUP_BUILDTYPE.lower()} --backend xcode "{MEDIASOUP_OUT_DIR}/xcode"',
354
325
  echo=True,
355
326
  pty=PTY_SUPPORTED,
356
327
  shell=SHELL