diff --git a/video/BUILD.gn b/video/BUILD.gn index cf9ce46c41..0f9829e9e2 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -286,6 +286,7 @@ if (rtc_include_tests) { "../modules/audio_device:windows_core_audio_utility", "../modules/audio_mixer:audio_mixer_impl", "../modules/rtp_rtcp", + "../modules/rtp_rtcp:rtp_rtcp_format", "../modules/video_coding", "../modules/video_coding:video_coding_utility", "../modules/video_coding:webrtc_h264", diff --git a/video/picture_id_tests.cc b/video/picture_id_tests.cc index da952f7c68..19c1141b0a 100644 --- a/video/picture_id_tests.cc +++ b/video/picture_id_tests.cc @@ -16,7 +16,7 @@ #include "call/simulated_network.h" #include "media/engine/internal_encoder_factory.h" #include "media/engine/simulcast_encoder_adapter.h" -#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h" #include "modules/rtp_rtcp/source/rtp_packet.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp9/include/vp9.h" @@ -43,7 +43,7 @@ class PictureIdObserver : public test::RtpRtcpObserver { public: explicit PictureIdObserver(VideoCodecType codec_type) : test::RtpRtcpObserver(test::CallTest::kDefaultTimeoutMs), - codec_type_(codec_type), + depacketizer_(CreateVideoRtpDepacketizer(codec_type)), max_expected_picture_id_gap_(0), max_expected_tl0_idx_gap_(0), num_ssrcs_to_observe_(1) {} @@ -88,43 +88,32 @@ class PictureIdObserver : public test::RtpRtcpObserver { rtp_packet.Ssrc() == test::CallTest::kVideoSendSsrcs[2]) << "Unknown SSRC sent."; - rtc::ArrayView rtp_payload = rtp_packet.payload(); - if (rtp_payload.empty()) { + if (rtp_packet.payload_size() == 0) { return false; // Padding packet. } parsed->timestamp = rtp_packet.Timestamp(); parsed->ssrc = rtp_packet.Ssrc(); - std::unique_ptr depacketizer( - RtpDepacketizer::Create(codec_type_)); - RtpDepacketizer::ParsedPayload parsed_payload; - EXPECT_TRUE(depacketizer->Parse(&parsed_payload, rtp_payload.data(), - rtp_payload.size())); + absl::optional parsed_payload = + depacketizer_->Parse(rtp_packet.PayloadBuffer()); + EXPECT_TRUE(parsed_payload); - switch (codec_type_) { - case kVideoCodecVP8: { - const auto& vp8_header = absl::get( - parsed_payload.video_header().video_type_header); - parsed->picture_id = vp8_header.pictureId; - parsed->tl0_pic_idx = vp8_header.tl0PicIdx; - parsed->temporal_idx = vp8_header.temporalIdx; - break; - } - case kVideoCodecVP9: { - const auto& vp9_header = absl::get( - parsed_payload.video_header().video_type_header); - parsed->picture_id = vp9_header.picture_id; - parsed->tl0_pic_idx = vp9_header.tl0_pic_idx; - parsed->temporal_idx = vp9_header.temporal_idx; - break; - } - default: - RTC_NOTREACHED(); - break; + if (const auto* vp8_header = absl::get_if( + &parsed_payload->video_header.video_type_header)) { + parsed->picture_id = vp8_header->pictureId; + parsed->tl0_pic_idx = vp8_header->tl0PicIdx; + parsed->temporal_idx = vp8_header->temporalIdx; + } else if (const auto* vp9_header = absl::get_if( + &parsed_payload->video_header.video_type_header)) { + parsed->picture_id = vp9_header->picture_id; + parsed->tl0_pic_idx = vp9_header->tl0_pic_idx; + parsed->temporal_idx = vp9_header->temporal_idx; + } else { + RTC_NOTREACHED(); } - parsed->frame_type = parsed_payload.video_header().frame_type; + parsed->frame_type = parsed_payload->video_header.frame_type; return true; } @@ -208,7 +197,7 @@ class PictureIdObserver : public test::RtpRtcpObserver { } rtc::CriticalSection crit_; - const VideoCodecType codec_type_; + const std::unique_ptr depacketizer_; std::map last_observed_packet_ RTC_GUARDED_BY(crit_); std::map num_packets_sent_ RTC_GUARDED_BY(crit_); int max_expected_picture_id_gap_ RTC_GUARDED_BY(crit_); diff --git a/video/video_analyzer.cc b/video/video_analyzer.cc index 018ec8b458..f2822efbea 100644 --- a/video/video_analyzer.cc +++ b/video/video_analyzer.cc @@ -16,8 +16,8 @@ #include "absl/flags/flag.h" #include "absl/flags/parse.h" #include "common_video/libyuv/include/webrtc_libyuv.h" -#include "modules/rtp_rtcp/source/rtp_format.h" -#include "modules/rtp_rtcp/source/rtp_utility.h" +#include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h" +#include "modules/rtp_rtcp/source/rtp_packet.h" #include "rtc_base/cpu_time.h" #include "rtc_base/format_macros.h" #include "rtc_base/memory_usage.h" @@ -109,6 +109,8 @@ VideoAnalyzer::VideoAnalyzer(test::LayerFilteringTransport* transport, is_quick_test_enabled_(is_quick_test_enabled), quit_(false), done_(true, false), + vp8_depacketizer_(CreateVideoRtpDepacketizer(kVideoCodecVP8)), + vp9_depacketizer_(CreateVideoRtpDepacketizer(kVideoCodecVP9)), clock_(clock), start_ms_(clock->TimeInMilliseconds()), task_queue_(task_queue) { @@ -221,18 +223,18 @@ PacketReceiver::DeliveryStatus VideoAnalyzer::DeliverPacket( rtp_file_writer_->WritePacket(&p); } - RtpUtility::RtpHeaderParser parser(packet.cdata(), packet.size()); - RTPHeader header; - parser.Parse(&header); - if (!IsFlexfec(header.payloadType) && (header.ssrc == ssrc_to_analyze_ || - header.ssrc == rtx_ssrc_to_analyze_)) { + RtpPacket rtp_packet; + rtp_packet.Parse(packet); + if (!IsFlexfec(rtp_packet.PayloadType()) && + (rtp_packet.Ssrc() == ssrc_to_analyze_ || + rtp_packet.Ssrc() == rtx_ssrc_to_analyze_)) { // Ignore FlexFEC timestamps, to avoid collisions with media timestamps. // (FlexFEC and media are sent on different SSRCs, which have different // timestamps spaces.) // Also ignore packets from wrong SSRC, but include retransmits. rtc::CritScope lock(&crit_); int64_t timestamp = - wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); + wrap_handler_.Unwrap(rtp_packet.Timestamp() - rtp_timestamp_delta_); recv_times_[timestamp] = clock_->CurrentNtpInMilliseconds(); } @@ -262,32 +264,31 @@ void VideoAnalyzer::PostEncodeOnFrame(size_t stream_id, uint32_t timestamp) { bool VideoAnalyzer::SendRtp(const uint8_t* packet, size_t length, const PacketOptions& options) { - RtpUtility::RtpHeaderParser parser(packet, length); - RTPHeader header; - parser.Parse(&header); + RtpPacket rtp_packet; + rtp_packet.Parse(packet, length); int64_t current_time = clock_->CurrentNtpInMilliseconds(); bool result = transport_->SendRtp(packet, length, options); { rtc::CritScope lock(&crit_); - if (rtp_timestamp_delta_ == 0 && header.ssrc == ssrc_to_analyze_) { + if (rtp_timestamp_delta_ == 0 && rtp_packet.Ssrc() == ssrc_to_analyze_) { RTC_CHECK(static_cast(first_sent_timestamp_)); - rtp_timestamp_delta_ = header.timestamp - *first_sent_timestamp_; + rtp_timestamp_delta_ = rtp_packet.Timestamp() - *first_sent_timestamp_; } - if (!IsFlexfec(header.payloadType) && header.ssrc == ssrc_to_analyze_) { + if (!IsFlexfec(rtp_packet.PayloadType()) && + rtp_packet.Ssrc() == ssrc_to_analyze_) { // Ignore FlexFEC timestamps, to avoid collisions with media timestamps. // (FlexFEC and media are sent on different SSRCs, which have different // timestamps spaces.) // Also ignore packets from wrong SSRC and retransmits. int64_t timestamp = - wrap_handler_.Unwrap(header.timestamp - rtp_timestamp_delta_); + wrap_handler_.Unwrap(rtp_packet.Timestamp() - rtp_timestamp_delta_); send_times_[timestamp] = current_time; - if (IsInSelectedSpatialAndTemporalLayer(packet, length, header)) { - encoded_frame_sizes_[timestamp] += - length - (header.headerLength + header.paddingLength); + if (IsInSelectedSpatialAndTemporalLayer(rtp_packet)) { + encoded_frame_sizes_[timestamp] += rtp_packet.payload_size(); } } } @@ -428,44 +429,31 @@ double VideoAnalyzer::GetCpuUsagePercent() { } bool VideoAnalyzer::IsInSelectedSpatialAndTemporalLayer( - const uint8_t* packet, - size_t length, - const RTPHeader& header) { - if (header.payloadType != test::CallTest::kPayloadTypeVP9 && - header.payloadType != test::CallTest::kPayloadTypeVP8) { - return true; - } else { - // Get VP8 and VP9 specific header to check layers indexes. - const uint8_t* payload = packet + header.headerLength; - const size_t payload_length = length - header.headerLength; - const size_t payload_data_length = payload_length - header.paddingLength; - const bool is_vp8 = header.payloadType == test::CallTest::kPayloadTypeVP8; - std::unique_ptr depacketizer( - RtpDepacketizer::Create(is_vp8 ? kVideoCodecVP8 : kVideoCodecVP9)); - RtpDepacketizer::ParsedPayload parsed_payload; - bool result = - depacketizer->Parse(&parsed_payload, payload, payload_data_length); - RTC_DCHECK(result); - - int temporal_idx; - int spatial_idx; - if (is_vp8) { - temporal_idx = absl::get( - parsed_payload.video_header().video_type_header) - .temporalIdx; - spatial_idx = kNoTemporalIdx; - } 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; - } + const RtpPacket& rtp_packet) { + if (rtp_packet.PayloadType() == test::CallTest::kPayloadTypeVP8) { + auto parsed_payload = vp8_depacketizer_->Parse(rtp_packet.PayloadBuffer()); + RTC_DCHECK(parsed_payload); + const auto& vp8_header = absl::get( + parsed_payload->video_header.video_type_header); + int temporal_idx = vp8_header.temporalIdx; + return selected_tl_ < 0 || temporal_idx == kNoTemporalIdx || + temporal_idx <= selected_tl_; + } + if (rtp_packet.PayloadType() == test::CallTest::kPayloadTypeVP9) { + auto parsed_payload = vp9_depacketizer_->Parse(rtp_packet.PayloadBuffer()); + RTC_DCHECK(parsed_payload); + const auto& vp9_header = absl::get( + parsed_payload->video_header.video_type_header); + int temporal_idx = vp9_header.temporal_idx; + int spatial_idx = vp9_header.spatial_idx; return (selected_tl_ < 0 || temporal_idx == kNoTemporalIdx || temporal_idx <= selected_tl_) && (selected_sl_ < 0 || spatial_idx == kNoSpatialIdx || spatial_idx <= selected_sl_); } + + return true; } void VideoAnalyzer::PollStats() { diff --git a/video/video_analyzer.h b/video/video_analyzer.h index 1069abf1ce..7d60e7c8fa 100644 --- a/video/video_analyzer.h +++ b/video/video_analyzer.h @@ -18,6 +18,8 @@ #include "api/task_queue/task_queue_base.h" #include "api/video/video_source_interface.h" +#include "modules/rtp_rtcp/source/rtp_packet.h" +#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h" #include "rtc_base/event.h" #include "rtc_base/numerics/running_statistics.h" #include "rtc_base/platform_thread.h" @@ -173,9 +175,7 @@ class VideoAnalyzer : public PacketReceiver, VideoFrame frame; }; - bool IsInSelectedSpatialAndTemporalLayer(const uint8_t* packet, - size_t length, - const RTPHeader& header); + bool IsInSelectedSpatialAndTemporalLayer(const RtpPacket& rtp_packet); void AddFrameComparison(const VideoFrame& reference, const VideoFrame& render, @@ -296,6 +296,8 @@ class VideoAnalyzer : public PacketReceiver, bool quit_ RTC_GUARDED_BY(comparison_lock_); rtc::Event done_; + std::unique_ptr vp8_depacketizer_; + std::unique_ptr vp9_depacketizer_; std::unique_ptr rtp_file_writer_; Clock* const clock_; const int64_t start_ms_;