From 490ff5f154c7e55f1db5ce49b20c36f31beb7cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1aki=20Baz=20Castillo?= Date: Fri, 24 Apr 2020 13:21:38 +0200 Subject: [PATCH] - libwebrtc Apply patch by @sspanak and @Ivaka to avoid crash. Related issue: #357 - PortManager.cpp: Do not use `UV_UDP_RECVMMSG` in Windows due to a bug in libuv 1.37.0 --- CHANGELOG.md | 2 ++ .../remote_bitrate_estimator/inter_arrival.cc | 21 ++++++++++++++++--- .../remote_bitrate_estimator/inter_arrival.h | 6 +++++- worker/src/RTC/PortManager.cpp | 11 ++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7eb77399e..9e13c5b206 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ### 3.5.9 (WIP) +* `libwebrtc`: Apply patch by @sspanak and @Ivaka to avoid crash. Related issue: #357. +* `PortManager.cpp`: Do not use `UV_UDP_RECVMMSG` in Windows due to a bug in libuv 1.37.0. * Update Node deps. diff --git a/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc b/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc index 5f8821195d..7a7f25cf5f 100644 --- a/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc +++ b/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.cc @@ -48,7 +48,7 @@ bool InterArrival::ComputeDeltas(uint32_t timestamp, current_timestamp_group_.timestamp = timestamp; current_timestamp_group_.first_timestamp = timestamp; current_timestamp_group_.first_arrival_ms = arrival_time_ms; - } else if (!PacketInOrder(timestamp)) { + } else if (!PacketInOrder(timestamp, arrival_time_ms)) { return false; } else if (NewTimestampGroup(arrival_time_ms, timestamp)) { // First packet of a later frame, the previous frame sample is ready. @@ -110,16 +110,31 @@ bool InterArrival::ComputeDeltas(uint32_t timestamp, return calculated_deltas; } -bool InterArrival::PacketInOrder(uint32_t timestamp) { +bool InterArrival::PacketInOrder(uint32_t timestamp, int64_t arrival_time_ms) { if (current_timestamp_group_.IsFirstPacket()) { return true; + } else if (arrival_time_ms < 0) { + // NOTE: Change related to https://github.com/versatica/mediasoup/issues/357 + // + // Sometimes we do get negative arrival time, which causes BelongsToBurst() + // to fail, which may cause anything that uses InterArrival to crash. + // + // Credits to @sspanak and @Ivaka. + return false; } else { // Assume that a diff which is bigger than half the timestamp interval // (32 bits) must be due to reordering. This code is almost identical to // that in IsNewerTimestamp() in module_common_types.h. uint32_t timestamp_diff = timestamp - current_timestamp_group_.first_timestamp; - return timestamp_diff < 0x80000000; + + const static uint32_t int_middle = 0x80000000; + + if (timestamp_diff == int_middle) { + return timestamp > current_timestamp_group_.first_timestamp; + } + + return timestamp_diff < int_middle; } } diff --git a/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.h b/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.h index 8ce1c145d1..1602a62bb7 100644 --- a/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.h +++ b/worker/deps/libwebrtc/libwebrtc/modules/remote_bitrate_estimator/inter_arrival.h @@ -71,7 +71,11 @@ class InterArrival { }; // Returns true if the packet with timestamp |timestamp| arrived in order. - bool PacketInOrder(uint32_t timestamp); + // + // NOTE: Change related to https://github.com/versatica/mediasoup/issues/357 + // + // bool PacketInOrder(uint32_t timestamp); + bool PacketInOrder(uint32_t timestamp, int64_t arrival_time_ms); // Returns true if the last packet was the end of the current batch and the // packet with |timestamp| is the first of a new batch. diff --git a/worker/src/RTC/PortManager.cpp b/worker/src/RTC/PortManager.cpp index d0514fe288..37d88b8892 100644 --- a/worker/src/RTC/PortManager.cpp +++ b/worker/src/RTC/PortManager.cpp @@ -162,8 +162,15 @@ namespace RTC { case Transport::UDP: uvHandle = reinterpret_cast(new uv_udp_t()); - err = uv_udp_init_ex( - DepLibUV::GetLoop(), reinterpret_cast(uvHandle), UV_UDP_RECVMMSG); +#ifdef _WIN32 + // TODO: Avoid libuv bug in Windows. Let's remove this condition once + // the issue is fixed. + // https://github.com/libuv/libuv/issues/2806 + err = uv_udp_init(DepLibUV::GetLoop(), reinterpret_cast(uvHandle)); +#else + err = uv_udp_init_ex( + DepLibUV::GetLoop(), reinterpret_cast(uvHandle), UV_UDP_RECVMMSG); +#endif break; case Transport::TCP: