diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
commit | d8bbc7858622b6d9c278469aab701ca0b609cddf (patch) | |
tree | eff41dc61d9f714852212739e6b3738b82a2af87 /third_party/libwebrtc/video/rtp_video_stream_receiver2.cc | |
parent | Releasing progress-linux version 125.0.3-1~progress7.99u1. (diff) | |
download | firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/video/rtp_video_stream_receiver2.cc | 121 |
1 files changed, 76 insertions, 45 deletions
diff --git a/third_party/libwebrtc/video/rtp_video_stream_receiver2.cc b/third_party/libwebrtc/video/rtp_video_stream_receiver2.cc index c4a021d6c0..077f522d41 100644 --- a/third_party/libwebrtc/video/rtp_video_stream_receiver2.cc +++ b/third_party/libwebrtc/video/rtp_video_stream_receiver2.cc @@ -358,7 +358,7 @@ RtpVideoStreamReceiver2::~RtpVideoStreamReceiver2() { void RtpVideoStreamReceiver2::AddReceiveCodec( uint8_t payload_type, VideoCodecType video_codec, - const std::map<std::string, std::string>& codec_params, + const webrtc::CodecParameterMap& codec_params, bool raw_payload) { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); if (codec_params.count(cricket::kH264FmtpSpsPpsIdrInKeyframe) > 0 || @@ -433,23 +433,21 @@ RtpVideoStreamReceiver2::ParseGenericDependenciesExtension( const RtpPacketReceived& rtp_packet, RTPVideoHeader* video_header) { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); - if (rtp_packet.HasExtension<RtpDependencyDescriptorExtension>()) { - webrtc::DependencyDescriptor dependency_descriptor; + if (DependencyDescriptorMandatory dd_mandatory; + rtp_packet.GetExtension<RtpDependencyDescriptorExtensionMandatory>( + &dd_mandatory)) { + const int64_t frame_id = + frame_id_unwrapper_.Unwrap(dd_mandatory.frame_number()); + DependencyDescriptor dependency_descriptor; if (!rtp_packet.GetExtension<RtpDependencyDescriptorExtension>( video_structure_.get(), &dependency_descriptor)) { - // Descriptor is there, but failed to parse. Either it is invalid, - // or too old packet (after relevant video_structure_ changed), - // or too new packet (before relevant video_structure_ arrived). - // Drop such packet to be on the safe side. - // TODO(bugs.webrtc.org/10342): Stash too new packet. - Timestamp now = clock_->CurrentTime(); - if (now - last_logged_failed_to_parse_dd_ > TimeDelta::Seconds(1)) { - last_logged_failed_to_parse_dd_ = now; - RTC_LOG(LS_WARNING) << "ssrc: " << rtp_packet.Ssrc() - << " Failed to parse dependency descriptor."; + if (!video_structure_frame_id_ || frame_id < video_structure_frame_id_) { + return kDropPacket; + } else { + return kStashPacket; } - return kDropPacket; } + if (dependency_descriptor.attached_structure != nullptr && !dependency_descriptor.first_packet_in_frame) { RTC_LOG(LS_WARNING) << "ssrc: " << rtp_packet.Ssrc() @@ -462,8 +460,6 @@ RtpVideoStreamReceiver2::ParseGenericDependenciesExtension( video_header->is_last_packet_in_frame = dependency_descriptor.last_packet_in_frame; - int64_t frame_id = - frame_id_unwrapper_.Unwrap(dependency_descriptor.frame_number); auto& generic_descriptor_info = video_header->generic.emplace(); generic_descriptor_info.frame_id = frame_id; generic_descriptor_info.spatial_index = @@ -538,10 +534,11 @@ RtpVideoStreamReceiver2::ParseGenericDependenciesExtension( return kHasGenericDescriptor; } -void RtpVideoStreamReceiver2::OnReceivedPayloadData( +bool RtpVideoStreamReceiver2::OnReceivedPayloadData( rtc::CopyOnWriteBuffer codec_payload, const RtpPacketReceived& rtp_packet, - const RTPVideoHeader& video) { + const RTPVideoHeader& video, + int times_nacked) { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); auto packet = @@ -594,16 +591,23 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData( video_header.playout_delay = rtp_packet.GetExtension<PlayoutDelayLimits>(); } - ParseGenericDependenciesResult generic_descriptor_state = - ParseGenericDependenciesExtension(rtp_packet, &video_header); - if (!rtp_packet.recovered()) { UpdatePacketReceiveTimestamps( rtp_packet, video_header.frame_type == VideoFrameType::kVideoFrameKey); } - if (generic_descriptor_state == kDropPacket) { + ParseGenericDependenciesResult generic_descriptor_state = + ParseGenericDependenciesExtension(rtp_packet, &video_header); + + if (generic_descriptor_state == kStashPacket) { + return true; + } else if (generic_descriptor_state == kDropPacket) { Timestamp now = clock_->CurrentTime(); + if (now - last_logged_failed_to_parse_dd_ > TimeDelta::Seconds(1)) { + last_logged_failed_to_parse_dd_ = now; + RTC_LOG(LS_WARNING) << "ssrc: " << rtp_packet.Ssrc() + << " Failed to parse dependency descriptor."; + } if (video_structure_ == nullptr && next_keyframe_request_for_missing_video_structure_ < now) { // No video structure received yet, most likely part of the initial @@ -612,7 +616,7 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData( next_keyframe_request_for_missing_video_structure_ = now + TimeDelta::Seconds(1); } - return; + return false; } // Color space should only be transmitted in the last packet of a frame, @@ -658,21 +662,12 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData( } } - if (nack_module_) { - const bool is_keyframe = - video_header.is_first_packet_in_frame && - video_header.frame_type == VideoFrameType::kVideoFrameKey; - - packet->times_nacked = nack_module_->OnReceivedPacket( - rtp_packet.SequenceNumber(), is_keyframe, rtp_packet.recovered()); - } else { - packet->times_nacked = -1; - } + packet->times_nacked = times_nacked; if (codec_payload.size() == 0) { NotifyReceiverOfEmptyPacket(packet->seq_num); rtcp_feedback_buffer_.SendBufferedRtcpFeedback(); - return; + return false; } if (packet->codec() == kVideoCodecH264) { @@ -695,7 +690,7 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData( rtcp_feedback_buffer_.SendBufferedRtcpFeedback(); [[fallthrough]]; case video_coding::H264SpsPpsTracker::kDrop: - return; + return false; case video_coding::H264SpsPpsTracker::kInsert: packet->video_payload = std::move(fixed.bitstream); break; @@ -708,6 +703,7 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData( rtcp_feedback_buffer_.SendBufferedRtcpFeedback(); frame_counter_.Add(packet->timestamp); OnInsertedPacket(packet_buffer_.InsertPacket(std::move(packet))); + return false; } void RtpVideoStreamReceiver2::OnRecoveredPacket( @@ -1111,15 +1107,51 @@ void RtpVideoStreamReceiver2::ReceivePacket(const RtpPacketReceived& packet) { if (type_it == payload_type_map_.end()) { return; } - absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload = - type_it->second->Parse(packet.PayloadBuffer()); - if (parsed_payload == absl::nullopt) { - RTC_LOG(LS_WARNING) << "Failed parsing payload."; - return; - } - OnReceivedPayloadData(std::move(parsed_payload->video_payload), packet, - parsed_payload->video_header); + auto parse_and_insert = [&](const RtpPacketReceived& packet) { + RTC_DCHECK_RUN_ON(&packet_sequence_checker_); + absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload = + type_it->second->Parse(packet.PayloadBuffer()); + if (parsed_payload == absl::nullopt) { + RTC_LOG(LS_WARNING) << "Failed parsing payload."; + return false; + } + + int times_nacked = nack_module_ + ? nack_module_->OnReceivedPacket( + packet.SequenceNumber(), packet.recovered()) + : -1; + + return OnReceivedPayloadData(std::move(parsed_payload->video_payload), + packet, parsed_payload->video_header, + times_nacked); + }; + + // When the dependency descriptor is used and the descriptor fail to parse + // then `OnReceivedPayloadData` may return true to signal the the packet + // should be retried at a later stage, which is why they are stashed here. + // + // TODO(bugs.webrtc.org/15782): + // This is an ugly solution. The way things should work is for the + // `RtpFrameReferenceFinder` to stash assembled frames until the keyframe with + // the relevant template structure has been received, but unfortunately the + // `frame_transformer_delegate_` is called before the frames are inserted into + // the `RtpFrameReferenceFinder`, and it expects the dependency descriptor to + // be parsed at that stage. + if (parse_and_insert(packet)) { + if (stashed_packets_.size() == 100) { + stashed_packets_.clear(); + } + stashed_packets_.push_back(packet); + } else { + for (auto it = stashed_packets_.begin(); it != stashed_packets_.end();) { + if (parse_and_insert(*it)) { + ++it; // keep in the stash. + } else { + it = stashed_packets_.erase(it); + } + } + } } void RtpVideoStreamReceiver2::ParseAndHandleEncapsulatingHeader( @@ -1151,8 +1183,7 @@ void RtpVideoStreamReceiver2::NotifyReceiverOfEmptyPacket(uint16_t seq_num) { OnInsertedPacket(packet_buffer_.InsertPadding(seq_num)); if (nack_module_) { - nack_module_->OnReceivedPacket(seq_num, /* is_keyframe = */ false, - /* is _recovered = */ false); + nack_module_->OnReceivedPacket(seq_num, /*is_recovered=*/false); } if (loss_notification_controller_) { // TODO(bugs.webrtc.org/10336): Handle empty packets. |