mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-04 13:07:32 +00:00
Merge pull request #13692 from alvaroelpob/feat/libwebrtc-rtcp-common-header
feat(libwebrtc): implement webrtc::rtcp::CommonHeader::Parse
This commit is contained in:
7 files changed
+259
-7
No files matched your search
@@ -3,6 +3,7 @@ target_include_directories(libwebrtc PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
configure_windows_unwind(libwebrtc)
|
||||
|
||||
target_sources(libwebrtc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/ExpFilter.cpp)
|
||||
target_sources(libwebrtc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/RtcpCommonHeader.cpp)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_webrtc_fast_int_to_buffer_tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/FastIntToBuffer.cpp)
|
||||
@@ -25,4 +26,14 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(guest_webrtc_exp_filter PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libwebrtc>")
|
||||
endif()
|
||||
add_test_executable(guest_webrtc_rtcp_common_header_tests ${CMAKE_CURRENT_SOURCE_DIR}/tests/RtcpCommonHeader.cpp)
|
||||
target_include_directories(guest_webrtc_rtcp_common_header_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_webrtc_rtcp_common_header_tests PRIVATE libwebrtc libc)
|
||||
configure_windows_unwind(guest_webrtc_rtcp_common_header_tests)
|
||||
add_test(NAME guest_webrtc_rtcp_common_header COMMAND guest_webrtc_rtcp_common_header_tests)
|
||||
set_tests_properties(guest_webrtc_rtcp_common_header PROPERTIES TIMEOUT 20)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_webrtc_rtcp_common_header PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libwebrtc>")
|
||||
endif()
|
||||
endif()
|
||||
@@ -1128,11 +1128,6 @@ int APS5_VABI _ZN6webrtc4rtcp3AppD1Ev_nid_postfix(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(void) {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
APS5_EXPORT("PEV9t77ljzc", libwebrtcUnknown34);
|
||||
int APS5_VABI libwebrtcUnknown34(void) {
|
||||
NotImplemented_nid_no_patch("PEV9t77ljzc");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libwebrtc/include/ExpFilter.hpp"
|
||||
#include "prx/libwebrtc/include/RtcpCommonHeader.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -222,7 +223,7 @@ int APS5_VABI _ZNK6webrtc4rtcp10RtcpPacket5BuildEv_nid_postfix(void);
|
||||
int APS5_VABI _ZN6webrtc4rtcp3App5ParseERKNS0_12CommonHeaderE_nid_postfix(void);
|
||||
int APS5_VABI _ZN6webrtc4rtcp3AppC1Ev_nid_postfix(void);
|
||||
int APS5_VABI _ZN6webrtc4rtcp3AppD1Ev_nid_postfix(void);
|
||||
int APS5_VABI _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(void);
|
||||
bool APS5_VABI _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(WebRtcRtcpCommonHeader* header, const std::uint8_t* buffer, std::size_t size);
|
||||
int APS5_VABI libwebrtcUnknown34(void);
|
||||
int APS5_VABI _ZN6webrtc4rtcp14CompoundPacketC1Ev_nid_postfix(void);
|
||||
int APS5_VABI _ZN6webrtc4rtcp14CompoundPacketD1Ev_nid_postfix(void);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
constexpr std::size_t WebRtcRtcpCommonHeaderSize = 4;
|
||||
|
||||
struct WebRtcRtcpCommonHeader {
|
||||
std::uint8_t packetType;
|
||||
std::uint8_t countOrFormat;
|
||||
std::uint8_t paddingSize;
|
||||
std::uint32_t payloadSize;
|
||||
const std::uint8_t* payload;
|
||||
};
|
||||
|
||||
static_assert(sizeof(WebRtcRtcpCommonHeader) == 16);
|
||||
static_assert(offsetof(WebRtcRtcpCommonHeader, paddingSize) == 2);
|
||||
static_assert(offsetof(WebRtcRtcpCommonHeader, payloadSize) == 4);
|
||||
static_assert(offsetof(WebRtcRtcpCommonHeader, payload) == 8);
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011, The WebRTC project authors. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the name of Google nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "prx/libwebrtc/libwebrtc.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool APS5_VABI _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(WebRtcRtcpCommonHeader* header, const std::uint8_t* buffer, std::size_t size) {
|
||||
if (!header)
|
||||
throw std::invalid_argument("CommonHeader::Parse requires a header");
|
||||
if (size < WebRtcRtcpCommonHeaderSize)
|
||||
return false;
|
||||
if (!buffer)
|
||||
throw std::invalid_argument("CommonHeader::Parse requires a buffer");
|
||||
if ((buffer[0] >> 6) != 2)
|
||||
return false;
|
||||
bool hasPadding = (buffer[0] & 0x20) != 0;
|
||||
header->countOrFormat = buffer[0] & 0x1F;
|
||||
header->packetType = buffer[1];
|
||||
header->payloadSize = ((static_cast<std::uint32_t>(buffer[2]) << 8) | buffer[3]) * 4u;
|
||||
header->payload = buffer + WebRtcRtcpCommonHeaderSize;
|
||||
header->paddingSize = 0;
|
||||
if (size < WebRtcRtcpCommonHeaderSize + header->payloadSize)
|
||||
return false;
|
||||
if (hasPadding) {
|
||||
if (header->payloadSize == 0)
|
||||
return false;
|
||||
header->paddingSize = header->payload[header->payloadSize - 1];
|
||||
if (header->paddingSize == 0)
|
||||
return false;
|
||||
if (header->paddingSize > header->payloadSize)
|
||||
return false;
|
||||
header->payloadSize -= header->paddingSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "prx/libwebrtc/libwebrtc.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <source_location>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
void Require(bool condition, std::source_location location = std::source_location::current()) {
|
||||
if (condition) return;
|
||||
std::fprintf(stderr, "libwebrtc rtcp::CommonHeader check failed at line %u\n", location.line());
|
||||
std::abort();
|
||||
}
|
||||
|
||||
template<typename TAction> void RequireInvalidArgument(TAction action, std::source_location location = std::source_location::current()) {
|
||||
try {
|
||||
action();
|
||||
} catch (const std::invalid_argument&) {
|
||||
return;
|
||||
}
|
||||
Require(false, location);
|
||||
}
|
||||
|
||||
WebRtcRtcpCommonHeader Filled() {
|
||||
WebRtcRtcpCommonHeader header;
|
||||
std::memset(&header, 0xA5, sizeof(header));
|
||||
return header;
|
||||
}
|
||||
|
||||
bool Parse(WebRtcRtcpCommonHeader& header, const std::vector<std::uint8_t>& packet, std::size_t size) {
|
||||
return _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(&header, packet.data(), size);
|
||||
}
|
||||
|
||||
bool Unchanged(const WebRtcRtcpCommonHeader& header) {
|
||||
WebRtcRtcpCommonHeader filled = Filled();
|
||||
return header.packetType == filled.packetType && header.countOrFormat == filled.countOrFormat && header.paddingSize == filled.paddingSize &&
|
||||
header.payloadSize == filled.payloadSize && header.payload == filled.payload;
|
||||
}
|
||||
|
||||
void TestReceiverReport() {
|
||||
std::vector<std::uint8_t> packet {0x81, 201, 0x00, 0x07};
|
||||
packet.resize(32, 0x11);
|
||||
WebRtcRtcpCommonHeader header = Filled();
|
||||
Require(Parse(header, packet, packet.size()));
|
||||
Require(header.countOrFormat == 1);
|
||||
Require(header.packetType == 201);
|
||||
Require(header.payloadSize == 28);
|
||||
Require(header.paddingSize == 0);
|
||||
Require(header.payload == packet.data() + 4);
|
||||
}
|
||||
|
||||
void TestFeedbackFormatAndEmptyPayload() {
|
||||
std::vector<std::uint8_t> packet {0x9F, 206, 0x00, 0x00};
|
||||
WebRtcRtcpCommonHeader header = Filled();
|
||||
Require(Parse(header, packet, packet.size()));
|
||||
Require(header.countOrFormat == 31);
|
||||
Require(header.packetType == 206);
|
||||
Require(header.payloadSize == 0);
|
||||
Require(header.paddingSize == 0);
|
||||
}
|
||||
|
||||
void TestPadding() {
|
||||
std::vector<std::uint8_t> packet {0xA0, 200, 0x00, 0x02, 1, 2, 3, 4, 5, 0, 0, 3};
|
||||
WebRtcRtcpCommonHeader header = Filled();
|
||||
Require(Parse(header, packet, packet.size()));
|
||||
Require(header.countOrFormat == 0);
|
||||
Require(header.paddingSize == 3);
|
||||
Require(header.payloadSize == 5);
|
||||
Require(header.payload == packet.data() + 4);
|
||||
|
||||
packet[11] = 8;
|
||||
header = Filled();
|
||||
Require(Parse(header, packet, packet.size()));
|
||||
Require(header.paddingSize == 8);
|
||||
Require(header.payloadSize == 0);
|
||||
}
|
||||
|
||||
void TestRejectsBeforeReading() {
|
||||
std::vector<std::uint8_t> packet {0x80, 200, 0x00, 0x00};
|
||||
WebRtcRtcpCommonHeader header = Filled();
|
||||
Require(!Parse(header, packet, 3));
|
||||
Require(Unchanged(header));
|
||||
Require(!_ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(&header, nullptr, 3));
|
||||
Require(Unchanged(header));
|
||||
for (std::uint8_t first : {0x00, 0x41, 0xC1}) {
|
||||
packet[0] = first;
|
||||
Require(!Parse(header, packet, packet.size()));
|
||||
Require(Unchanged(header));
|
||||
}
|
||||
}
|
||||
|
||||
void TestRejectsAfterReading() {
|
||||
std::vector<std::uint8_t> packet {0x81, 201, 0x00, 0x02, 1, 2, 3, 4, 5, 6, 7};
|
||||
WebRtcRtcpCommonHeader header = Filled();
|
||||
Require(!Parse(header, packet, packet.size()));
|
||||
Require(header.countOrFormat == 1);
|
||||
Require(header.packetType == 201);
|
||||
Require(header.payloadSize == 8);
|
||||
Require(header.paddingSize == 0);
|
||||
Require(header.payload == packet.data() + 4);
|
||||
|
||||
std::vector<std::uint8_t> empty {0xA0, 200, 0x00, 0x00};
|
||||
header = Filled();
|
||||
Require(!Parse(header, empty, empty.size()));
|
||||
Require(header.payloadSize == 0);
|
||||
Require(header.paddingSize == 0);
|
||||
|
||||
std::vector<std::uint8_t> zeroPadding {0xA0, 200, 0x00, 0x01, 1, 2, 3, 0};
|
||||
header = Filled();
|
||||
Require(!Parse(header, zeroPadding, zeroPadding.size()));
|
||||
Require(header.payloadSize == 4);
|
||||
Require(header.paddingSize == 0);
|
||||
|
||||
std::vector<std::uint8_t> tooMuchPadding {0xA0, 200, 0x00, 0x01, 1, 2, 3, 5};
|
||||
header = Filled();
|
||||
Require(!Parse(header, tooMuchPadding, tooMuchPadding.size()));
|
||||
Require(header.payloadSize == 4);
|
||||
Require(header.paddingSize == 5);
|
||||
}
|
||||
|
||||
void TestNullArguments() {
|
||||
std::array<std::uint8_t, 4> packet {0x80, 200, 0x00, 0x00};
|
||||
RequireInvalidArgument([&] { _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(nullptr, packet.data(), packet.size()); });
|
||||
WebRtcRtcpCommonHeader header = Filled();
|
||||
RequireInvalidArgument([&] { _ZN6webrtc4rtcp12CommonHeader5ParseEPKhm_nid_postfix(&header, nullptr, 4); });
|
||||
Require(Unchanged(header));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
TestReceiverReport();
|
||||
TestFeedbackFormatAndEmptyPayload();
|
||||
TestPadding();
|
||||
TestRejectsBeforeReading();
|
||||
TestRejectsAfterReading();
|
||||
TestNullArguments();
|
||||
std::puts("libwebrtc rtcp::CommonHeader tests passed");
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Unknown function info
|
||||
|
||||
- [409 exports (60 without a known name, bound by NID)](../../../core/libs/prx/libwebrtc/Export.cpp) (libwebrtc) - every function export of `libwebrtc.sprx` from the firmware 13.60 export table that the next section does not implement, names from aerolib.csv only where `tools/nid_names.py` `compute_nid` reproduces the NID. Signatures, parameter layouts and behaviour are unknown; every export throws through `NotImplemented_nid_no_patch`
|
||||
- [408 exports (60 without a known name, bound by NID)](../../../core/libs/prx/libwebrtc/Export.cpp) (libwebrtc) - every function export of `libwebrtc.sprx` from the firmware 13.60 export table that the next section does not implement, names from aerolib.csv only where `tools/nid_names.py` `compute_nid` reproduces the NID. Signatures, parameter layouts and behaviour are unknown; every export throws through `NotImplemented_nid_no_patch`
|
||||
- [31 data exports](../../../core/libs/prx/libwebrtc/Export.cpp) (libwebrtc) - the module also exports 31 data objects (+qcl2IzxTzg, -ix-knPYqWA, 00mefEErs+Y, 5FM0YOa3NWc, 67nsSkXmJ7E, 7I2xDnqfDV4, 8Dzy4JayJSU, CVCDyAzGrhI, HpbtuVdvO-w, PGIpx6NnFLE, Q+xnDp4KI-s, QXDv9OpZNvM, aOOjLmup+u4, g5USRJNh3bU, hvpHGXjlpbk, iU6+qODNSjU, jpkYoOv34AM, lHLJlq3NEqE, lQJvoyxHov4, nUaORqH85DQ, o6LS+08kOUs, oh8srl3AcNE, oslHzys1vV0, sp5NqvqDdHw, t66Gw3OIpSo, tr8vseK8-ro, uSis0q+bv6k, uTz5pEKL+hM, uxkudCJIYJA, whHm70jlRXw, yW0sV3sCdPA); they are not defined, so imports of them stay unresolved until their layout is known
|
||||
|
||||
### Public source implementations
|
||||
@@ -10,3 +10,4 @@
|
||||
- [Source revision](../../../core/libs/prx/libwebrtc/Export.cpp) (libwebrtc) - the module's exact WebRTC revision is not identified. Its `rtc::` names and `InterleavedView` resampler overloads place it between M127 ([branch-heads/6533](https://webrtc.googlesource.com/src/+/e0b28a6a81a989c1f5c89e30fcd247870047390d)) and M134 ([branch-heads/6998](https://webrtc.googlesource.com/src/+/8d78f5de6c27b2c793039989ea381f1428fb0100)), so the exports below follow code that is the same at both. Nothing is checked on the console. Closes when: the revision is identified and the exports are compared with the console.
|
||||
- [absl::numbers_internal::FastIntToBuffer(int, char*)](../../../core/libs/prx/libwebrtc/Export.cpp) (libwebrtc) - follows the abseil both branches pin, [65ef38d368](https://chromium.googlesource.com/chromium/src/third_party/+/65ef38d36813d1ad9d4cbf8a18b32ac3691f418b/abseil-cpp/absl/strings/numbers.cc) and [d212a71416](https://chromium.googlesource.com/chromium/src/third_party/+/d212a71416ad7c6ceca04d6d27dfdd84fd00c04c/abseil-cpp/absl/strings/numbers.cc): the decimal text and a NUL, returning a pointer to the NUL. For magnitudes from 10 to 99999999 its 8-byte store also zeroes the bytes after the digits up to 8 from the first digit. A null buffer, which abseil writes through, throws. Closes when: compared with the console.
|
||||
- [rtc::ExpFilter::Reset and Apply](../../../core/libs/prx/libwebrtc/src/ExpFilter.cpp) (libwebrtc) - adapted from [exp_filter.cc](https://webrtc.googlesource.com/src/+/8d78f5de6c27b2c793039989ea381f1428fb0100/rtc_base/numerics/exp_filter.cc), with its WebRTC copyright notice and BSD licence at the top of the file, on the 12-byte `alpha_`, `filtered_` and `max_` layout of `exp_filter.h`. -1 marks both an unset output and no maximum, so an output that lands on exactly -1 restarts the filter on the next sample, as upstream does. The last bit of a result can differ if the console build fuses the multiply-adds. A null filter throws. Closes when: compared with the console.
|
||||
- [webrtc::rtcp::CommonHeader::Parse](../../../core/libs/prx/libwebrtc/src/RtcpCommonHeader.cpp) (libwebrtc) - adapted from [common_header.cc](https://webrtc.googlesource.com/src/+/8d78f5de6c27b2c793039989ea381f1428fb0100/modules/rtp_rtcp/source/rtcp_packet/common_header.cc), with its WebRTC copyright notice and BSD licence at the top of the file, on the 16-byte layout of `common_header.h`: packet type, count or format and padding size at 0 to 2, payload size at 4 and payload pointer at 8. Its checks run in the same order, so a short buffer or a wrong version leaves the header untouched and the later failures leave the fields already parsed. The `RTC_LOG(LS_WARNING)` message each failure logs upstream is not emitted. A null header, or a null buffer of 4 bytes or more, which upstream reads, throws. Closes when: the warnings are logged through libwebrtc's logging and the parse is compared with the console.
|
||||
Reference in new issue
Block a user