diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc index cce557a878..e78bc58774 100644 --- a/video/rtp_video_stream_receiver.cc +++ b/video/rtp_video_stream_receiver.cc @@ -327,6 +327,52 @@ absl::optional RtpVideoStreamReceiver::GetSyncInfo() const { return info; } +RtpVideoStreamReceiver::ParseGenericDependenciesResult +RtpVideoStreamReceiver::ParseGenericDependenciesExtension( + const RtpPacketReceived& rtp_packet, + RTPVideoHeader* video_header) { + if (rtp_packet.HasExtension() && + rtp_packet.HasExtension()) { + RTC_LOG(LS_WARNING) << "RTP packet had two different GFD versions."; + return kDropPacket; + } + + RtpGenericFrameDescriptor generic_descriptor; + bool has_generic_descriptor = + rtp_packet.GetExtension( + &generic_descriptor) || + rtp_packet.GetExtension( + &generic_descriptor); + if (!has_generic_descriptor) { + return kNoGenericDescriptor; + } + + video_header->is_first_packet_in_frame = + generic_descriptor.FirstPacketInSubFrame(); + video_header->is_last_packet_in_frame = + generic_descriptor.LastPacketInSubFrame(); + + if (generic_descriptor.FirstPacketInSubFrame()) { + video_header->frame_type = + generic_descriptor.FrameDependenciesDiffs().empty() + ? VideoFrameType::kVideoFrameKey + : VideoFrameType::kVideoFrameDelta; + + auto& descriptor = video_header->generic.emplace(); + int64_t frame_id = frame_id_unwrapper_.Unwrap(generic_descriptor.FrameId()); + descriptor.frame_id = frame_id; + descriptor.spatial_index = generic_descriptor.SpatialLayer(); + descriptor.temporal_index = generic_descriptor.TemporalLayer(); + descriptor.discardable = generic_descriptor.Discardable().value_or(false); + for (uint16_t fdiff : generic_descriptor.FrameDependenciesDiffs()) { + descriptor.dependencies.push_back(frame_id - fdiff); + } + } + video_header->width = generic_descriptor.Width(); + video_header->height = generic_descriptor.Height(); + return kHasGenericDescriptor; +} + void RtpVideoStreamReceiver::OnReceivedPayloadData( rtc::CopyOnWriteBuffer codec_payload, const RtpPacketReceived& rtp_packet, @@ -368,44 +414,10 @@ void RtpVideoStreamReceiver::OnReceivedPayloadData( rtp_packet.GetExtension(&video_header.playout_delay); rtp_packet.GetExtension(&video_header.frame_marking); - if (rtp_packet.HasExtension() && - rtp_packet.HasExtension()) { - RTC_LOG(LS_WARNING) << "RTP packet had two different GFD versions."; + ParseGenericDependenciesResult generic_descriptor_state = + ParseGenericDependenciesExtension(rtp_packet, &video_header); + if (generic_descriptor_state == kDropPacket) return; - } - - RtpGenericFrameDescriptor generic_descriptor; - bool has_generic_descriptor = - rtp_packet.GetExtension( - &generic_descriptor) || - rtp_packet.GetExtension( - &generic_descriptor); - if (has_generic_descriptor) { - video_header.is_first_packet_in_frame = - generic_descriptor.FirstPacketInSubFrame(); - video_header.is_last_packet_in_frame = - generic_descriptor.LastPacketInSubFrame(); - - if (generic_descriptor.FirstPacketInSubFrame()) { - video_header.frame_type = - generic_descriptor.FrameDependenciesDiffs().empty() - ? VideoFrameType::kVideoFrameKey - : VideoFrameType::kVideoFrameDelta; - - auto& descriptor = video_header.generic.emplace(); - int64_t frame_id = - frame_id_unwrapper_.Unwrap(generic_descriptor.FrameId()); - descriptor.frame_id = frame_id; - descriptor.spatial_index = generic_descriptor.SpatialLayer(); - descriptor.temporal_index = generic_descriptor.TemporalLayer(); - descriptor.discardable = generic_descriptor.Discardable().value_or(false); - for (uint16_t fdiff : generic_descriptor.FrameDependenciesDiffs()) { - descriptor.dependencies.push_back(frame_id - fdiff); - } - } - video_header.width = generic_descriptor.Width(); - video_header.height = generic_descriptor.Height(); - } // Color space should only be transmitted in the last packet of a frame, // therefore, neglect it otherwise so that last_color_space_ is not reset by @@ -428,7 +440,7 @@ void RtpVideoStreamReceiver::OnReceivedPayloadData( // TODO(bugs.webrtc.org/10336): Implement support for reordering. RTC_LOG(LS_INFO) << "LossNotificationController does not support reordering."; - } else if (!has_generic_descriptor) { + } else if (generic_descriptor_state == kNoGenericDescriptor) { RTC_LOG(LS_WARNING) << "LossNotificationController requires generic " "frame descriptor, but it is missing."; } else { diff --git a/video/rtp_video_stream_receiver.h b/video/rtp_video_stream_receiver.h index 8b6ffbd830..e6a8068003 100644 --- a/video/rtp_video_stream_receiver.h +++ b/video/rtp_video_stream_receiver.h @@ -236,6 +236,11 @@ class RtpVideoStreamReceiver : public LossNotificationSender, }; absl::optional lntf_state_ RTC_GUARDED_BY(cs_); }; + enum ParseGenericDependenciesResult { + kDropPacket, + kHasGenericDescriptor, + kNoGenericDescriptor + }; // Entry point doing non-stats work for a received packet. Called // for the same packet both before and after RED decapsulation. @@ -248,6 +253,9 @@ class RtpVideoStreamReceiver : public LossNotificationSender, bool IsRedEnabled() const; void InsertSpsPpsIntoTracker(uint8_t payload_type); void OnInsertedPacket(video_coding::PacketBuffer::InsertResult result); + ParseGenericDependenciesResult ParseGenericDependenciesExtension( + const RtpPacketReceived& rtp_packet, + RTPVideoHeader* video_header) RTC_RUN_ON(worker_task_checker_); void OnAssembledFrame(std::unique_ptr frame); Clock* const clock_;