From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../libwebrtc/test/layer_filtering_transport.cc | 184 +++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 third_party/libwebrtc/test/layer_filtering_transport.cc (limited to 'third_party/libwebrtc/test/layer_filtering_transport.cc') diff --git a/third_party/libwebrtc/test/layer_filtering_transport.cc b/third_party/libwebrtc/test/layer_filtering_transport.cc new file mode 100644 index 0000000000..931a89b9da --- /dev/null +++ b/third_party/libwebrtc/test/layer_filtering_transport.cc @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2015 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. + */ + +#include "test/layer_filtering_transport.h" + +#include + +#include +#include +#include + +#include "api/rtp_headers.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h" +#include "modules/rtp_rtcp/source/rtp_video_header.h" +#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h" +#include "modules/video_coding/codecs/interface/common_constants.h" +#include "modules/video_coding/codecs/vp8/include/vp8_globals.h" +#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" +#include "rtc_base/checks.h" + +namespace webrtc { +namespace test { + +LayerFilteringTransport::LayerFilteringTransport( + TaskQueueBase* task_queue, + std::unique_ptr pipe, + Call* send_call, + uint8_t vp8_video_payload_type, + uint8_t vp9_video_payload_type, + int selected_tl, + int selected_sl, + const std::map& payload_type_map, + uint32_t ssrc_to_filter_min, + uint32_t ssrc_to_filter_max, + rtc::ArrayView audio_extensions, + rtc::ArrayView video_extensions) + : DirectTransport(task_queue, + std::move(pipe), + send_call, + payload_type_map, + audio_extensions, + video_extensions), + vp8_video_payload_type_(vp8_video_payload_type), + vp9_video_payload_type_(vp9_video_payload_type), + vp8_depacketizer_(CreateVideoRtpDepacketizer(kVideoCodecVP8)), + vp9_depacketizer_(CreateVideoRtpDepacketizer(kVideoCodecVP9)), + selected_tl_(selected_tl), + selected_sl_(selected_sl), + discarded_last_packet_(false), + ssrc_to_filter_min_(ssrc_to_filter_min), + ssrc_to_filter_max_(ssrc_to_filter_max) {} + +LayerFilteringTransport::LayerFilteringTransport( + TaskQueueBase* task_queue, + std::unique_ptr pipe, + Call* send_call, + uint8_t vp8_video_payload_type, + uint8_t vp9_video_payload_type, + int selected_tl, + int selected_sl, + const std::map& payload_type_map, + rtc::ArrayView audio_extensions, + rtc::ArrayView video_extensions) + : LayerFilteringTransport(task_queue, + std::move(pipe), + send_call, + vp8_video_payload_type, + vp9_video_payload_type, + selected_tl, + selected_sl, + payload_type_map, + /*ssrc_to_filter_min=*/0, + /*ssrc_to_filter_max=*/0xFFFFFFFF, + audio_extensions, + video_extensions) {} + +bool LayerFilteringTransport::DiscardedLastPacket() const { + return discarded_last_packet_; +} + +bool LayerFilteringTransport::SendRtp(rtc::ArrayView packet, + const PacketOptions& options) { + if (selected_tl_ == -1 && selected_sl_ == -1) { + // Nothing to change, forward the packet immediately. + return test::DirectTransport::SendRtp(packet, options); + } + + RtpPacket rtp_packet; + rtp_packet.Parse(packet); + + if (rtp_packet.Ssrc() < ssrc_to_filter_min_ || + rtp_packet.Ssrc() > ssrc_to_filter_max_) { + // Nothing to change, forward the packet immediately. + return test::DirectTransport::SendRtp(packet, options); + } + + if (rtp_packet.PayloadType() == vp8_video_payload_type_ || + rtp_packet.PayloadType() == vp9_video_payload_type_) { + const bool is_vp8 = rtp_packet.PayloadType() == vp8_video_payload_type_; + VideoRtpDepacketizer& depacketizer = + is_vp8 ? *vp8_depacketizer_ : *vp9_depacketizer_; + if (auto parsed_payload = depacketizer.Parse(rtp_packet.PayloadBuffer())) { + int temporal_idx; + int spatial_idx; + bool non_ref_for_inter_layer_pred; + bool end_of_frame; + + if (is_vp8) { + temporal_idx = absl::get( + parsed_payload->video_header.video_type_header) + .temporalIdx; + spatial_idx = kNoSpatialIdx; + num_active_spatial_layers_ = 1; + non_ref_for_inter_layer_pred = false; + end_of_frame = true; + } else { + const auto& vp9_header = absl::get( + parsed_payload->video_header.video_type_header); + temporal_idx = vp9_header.temporal_idx; + spatial_idx = vp9_header.spatial_idx; + non_ref_for_inter_layer_pred = vp9_header.non_ref_for_inter_layer_pred; + end_of_frame = vp9_header.end_of_frame; + if (vp9_header.ss_data_available) { + RTC_DCHECK(vp9_header.temporal_idx == kNoTemporalIdx || + vp9_header.temporal_idx == 0); + num_active_spatial_layers_ = vp9_header.num_spatial_layers; + } + } + + if (spatial_idx == kNoSpatialIdx) + num_active_spatial_layers_ = 1; + + RTC_CHECK_GT(num_active_spatial_layers_, 0); + + if (selected_sl_ >= 0 && + spatial_idx == + std::min(num_active_spatial_layers_ - 1, selected_sl_) && + end_of_frame) { + // This layer is now the last in the superframe. + rtp_packet.SetMarker(true); + } else { + const bool higher_temporal_layer = + (selected_tl_ >= 0 && temporal_idx != kNoTemporalIdx && + temporal_idx > selected_tl_); + + const bool higher_spatial_layer = + (selected_sl_ >= 0 && spatial_idx != kNoSpatialIdx && + spatial_idx > selected_sl_); + + // Filter out non-reference lower spatial layers since they are not + // needed for decoding of target spatial layer. + const bool lower_non_ref_spatial_layer = + (selected_sl_ >= 0 && spatial_idx != kNoSpatialIdx && + spatial_idx < + std::min(num_active_spatial_layers_ - 1, selected_sl_) && + non_ref_for_inter_layer_pred); + + if (higher_temporal_layer || higher_spatial_layer || + lower_non_ref_spatial_layer) { + // Truncate packet to a padding packet. + rtp_packet.SetPayloadSize(0); + rtp_packet.SetPadding(1); + rtp_packet.SetMarker(false); + discarded_last_packet_ = true; + } + } + } else { + RTC_DCHECK_NOTREACHED() << "Parse error"; + } + } + + return test::DirectTransport::SendRtp(rtp_packet, options); +} + +} // namespace test +} // namespace webrtc -- cgit v1.2.3