diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/libwebrtc/test/layer_filtering_transport.cc | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/test/layer_filtering_transport.cc')
-rw-r--r-- | third_party/libwebrtc/test/layer_filtering_transport.cc | 184 |
1 files changed, 184 insertions, 0 deletions
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 <string.h> + +#include <algorithm> +#include <memory> +#include <utility> + +#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<SimulatedPacketReceiverInterface> 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<uint8_t, MediaType>& payload_type_map, + uint32_t ssrc_to_filter_min, + uint32_t ssrc_to_filter_max, + rtc::ArrayView<const RtpExtension> audio_extensions, + rtc::ArrayView<const RtpExtension> 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<SimulatedPacketReceiverInterface> 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<uint8_t, MediaType>& payload_type_map, + rtc::ArrayView<const RtpExtension> audio_extensions, + rtc::ArrayView<const RtpExtension> 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<const uint8_t> 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<RTPVideoHeaderVP8>( + 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<RTPVideoHeaderVP9>( + 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 |