diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder.cc b/webrtc/modules/video_coding/rtp_frame_reference_finder.cc index 66e57b06ed..8d74c363c5 100644 --- a/webrtc/modules/video_coding/rtp_frame_reference_finder.cc +++ b/webrtc/modules/video_coding/rtp_frame_reference_finder.cc @@ -397,11 +397,6 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9( RTC_DCHECK(rtp_codec_header); const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9; - bool old_frame = Vp9PidTl0Fix(*frame, &rtp_codec_header->VP9.picture_id, - &rtp_codec_header->VP9.tl0_pic_idx); - if (old_frame) - return kDrop; - if (codec_header.picture_id == kNoPictureId || codec_header.temporal_idx == kNoTemporalIdx) { return ManageFrameGeneric(std::move(frame), codec_header.picture_id); @@ -608,148 +603,5 @@ uint16_t RtpFrameReferenceFinder::UnwrapPictureId(uint16_t picture_id) { return last_unwrap_; } -bool RtpFrameReferenceFinder::Vp9PidTl0Fix(const RtpFrameObject& frame, - int16_t* picture_id, - int16_t* tl0_pic_idx) { - const int kTl0PicIdLength = 256; - const uint8_t kMaxPidDiff = 128; - - // We are currently receiving VP9 without PID, nothing to fix. - if (*picture_id == kNoPictureId) - return false; - - // If |vp9_fix_jump_timestamp_| != -1 then a jump has occurred recently. - if (vp9_fix_jump_timestamp_ != -1) { - // If this frame has a timestamp older than |vp9_fix_jump_timestamp_| then - // this frame is old (more previous than the frame where we detected the - // jump) and should be dropped. - if (AheadOf(vp9_fix_jump_timestamp_, frame.timestamp)) - return true; - - // After 60 seconds, reset |vp9_fix_jump_timestamp_| in order to not - // discard old frames when the timestamp wraps. - int diff_ms = - ForwardDiff(vp9_fix_jump_timestamp_, frame.timestamp) / 90; - if (diff_ms > 60 * 1000) - vp9_fix_jump_timestamp_ = -1; - } - - // Update |vp9_fix_last_timestamp_| with the most recent timestamp. - if (vp9_fix_last_timestamp_ == -1) - vp9_fix_last_timestamp_ = frame.timestamp; - if (AheadOf(frame.timestamp, vp9_fix_last_timestamp_)) - vp9_fix_last_timestamp_ = frame.timestamp; - - uint16_t fixed_pid = Add(*picture_id, vp9_fix_pid_offset_); - if (vp9_fix_last_picture_id_ == -1) - vp9_fix_last_picture_id_ = *picture_id; - - int16_t fixed_tl0 = kNoTl0PicIdx; - if (*tl0_pic_idx != kNoTl0PicIdx) { - fixed_tl0 = Add(*tl0_pic_idx, vp9_fix_tl0_pic_idx_offset_); - // Update |vp9_fix_last_tl0_pic_idx_| with the most recent tl0 pic index. - if (vp9_fix_last_tl0_pic_idx_ == -1) - vp9_fix_last_tl0_pic_idx_ = *tl0_pic_idx; - if (AheadOf(fixed_tl0, vp9_fix_last_tl0_pic_idx_)) - vp9_fix_last_tl0_pic_idx_ = fixed_tl0; - } - - bool has_jumped = DetectVp9PicIdJump(fixed_pid, fixed_tl0, frame.timestamp); - if (!has_jumped) - has_jumped = DetectVp9Tl0PicIdxJump(fixed_tl0, frame.timestamp); - - if (has_jumped) { - // First we calculate the offset to get to the previous picture id, and then - // we add kMaxPid to avoid accidently referencing any previous - // frames that was inserted into the FrameBuffer. - vp9_fix_pid_offset_ = ForwardDiff( - *picture_id, vp9_fix_last_picture_id_); - vp9_fix_pid_offset_ += kMaxPidDiff; - - fixed_pid = Add(*picture_id, vp9_fix_pid_offset_); - vp9_fix_last_picture_id_ = fixed_pid; - vp9_fix_jump_timestamp_ = frame.timestamp; - gof_info_.clear(); - - if (fixed_tl0 != kNoTl0PicIdx) { - vp9_fix_tl0_pic_idx_offset_ = - ForwardDiff(*tl0_pic_idx, vp9_fix_last_tl0_pic_idx_); - vp9_fix_tl0_pic_idx_offset_ += kMaxGofSaved; - fixed_tl0 = - Add(*tl0_pic_idx, vp9_fix_tl0_pic_idx_offset_); - vp9_fix_last_tl0_pic_idx_ = fixed_tl0; - } - } - - // Update |vp9_fix_last_picture_id_| with the most recent picture id. - if (AheadOf(fixed_pid, vp9_fix_last_picture_id_)) - vp9_fix_last_picture_id_ = fixed_pid; - - *picture_id = fixed_pid; - *tl0_pic_idx = fixed_tl0; - - return false; -} - -bool RtpFrameReferenceFinder::DetectVp9PicIdJump(int fixed_pid, - int fixed_tl0, - uint32_t timestamp) const { - // Test if there has been a jump backwards in the picture id. - if (AheadOrAt(timestamp, vp9_fix_last_timestamp_) && - AheadOf(vp9_fix_last_picture_id_, fixed_pid)) { - return true; - } - - // Test if we have jumped forward too much. The reason we have to do this - // is because the FrameBuffer holds history of old frames and inserting - // frames with a much advanced picture id can result in the frame buffer - // holding more than half of the interval of picture ids. - if (AheadOrAt(timestamp, vp9_fix_last_timestamp_) && - ForwardDiff(vp9_fix_last_picture_id_, fixed_pid) > - 128) { - return true; - } - - // Special case where the picture id jump forward but not by much and the - // tl0 jumps to the id of an already saved gof for that id. In order to - // detect this we check if the picture id span over the length of the GOF. - if (fixed_tl0 != kNoTl0PicIdx) { - auto info_it = gof_info_.find(fixed_tl0); - if (info_it != gof_info_.end()) { - int last_pid_gof_idx_0 = - Subtract(info_it->second.last_picture_id, - info_it->second.last_picture_id % - info_it->second.gof->num_frames_in_gof); - int pif_gof_end = Add( - last_pid_gof_idx_0, info_it->second.gof->num_frames_in_gof); - if (AheadOf(fixed_pid, pif_gof_end)) - return true; - } - } - - return false; -} - -bool RtpFrameReferenceFinder::DetectVp9Tl0PicIdxJump(int fixed_tl0, - uint32_t timestamp) const { - if (fixed_tl0 != kNoTl0PicIdx) { - // Test if there has been a jump backwards in tl0 pic index. - if (AheadOrAt(timestamp, vp9_fix_last_timestamp_) && - AheadOf(vp9_fix_last_tl0_pic_idx_, fixed_tl0)) { - return true; - } - - // Test if there has been a jump forward. If the jump forward results - // in the tl0 pic index for this frame to be considered smaller than the - // smallest item in |gof_info_| then we have jumped forward far enough to - // wrap. - if (!gof_info_.empty() && - AheadOf(gof_info_.begin()->first, fixed_tl0)) { - return true; - } - } - return false; -} - } // namespace video_coding } // namespace webrtc diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder.h b/webrtc/modules/video_coding/rtp_frame_reference_finder.h index 99688e6657..74db45a2b8 100644 --- a/webrtc/modules/video_coding/rtp_frame_reference_finder.h +++ b/webrtc/modules/video_coding/rtp_frame_reference_finder.h @@ -213,15 +213,6 @@ class RtpFrameReferenceFinder { int cleared_to_seq_num_ GUARDED_BY(crit_); OnCompleteFrameCallback* frame_callback_; - - // Vp9PidFix variables - // TODO(philipel): Remove when VP9 PID does not jump mid-stream. - int vp9_fix_last_timestamp_ = -1; - int vp9_fix_jump_timestamp_ = -1; - int vp9_fix_last_picture_id_ = -1; - int vp9_fix_pid_offset_ = 0; - int vp9_fix_last_tl0_pic_idx_ = -1; - int vp9_fix_tl0_pic_idx_offset_ = 0; }; } // namespace video_coding diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc index c75c45eb0f..7d1c86d7fa 100644 --- a/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc +++ b/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc @@ -1308,233 +1308,5 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) { CheckReferencesVp9(pid + 8, 1, pid + 7); } -// TODO(philipel): Remove when VP9 PID/TL0 does not jump mid-stream (should be -// around M59). -TEST_F(TestRtpFrameReferenceFinder, Vp9PidFix_PidJumpsForwardNoTl0PicIdx) { - GofInfoVP9 ss; - ss.SetGofInfoVP9(kTemporalStructureMode1); - - VCMPacket packet; - packet.timestamp = 0; - packet.codec = kVideoCodecVP9; - packet.frameType = kVideoFrameKey; - packet.markerBit = true; - packet.video_header.codecHeader.VP9.flexible_mode = false; - packet.video_header.codecHeader.VP9.picture_id = 0; - packet.video_header.codecHeader.VP9.temporal_idx = kNoTemporalIdx; - packet.video_header.codecHeader.VP9.spatial_idx = kNoSpatialIdx; - packet.video_header.codecHeader.VP9.tl0_pic_idx = kNoTl0PicIdx; - packet.video_header.codecHeader.VP9.temporal_up_switch = true; - packet.video_header.codecHeader.VP9.ss_data_available = true; - packet.video_header.codecHeader.VP9.gof = ss; - - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 1; - packet.video_header.codecHeader.VP9.picture_id = 5000; - - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - ASSERT_EQ(2UL, frames_from_callback_.size()); - CheckReferencesVp9(0, 0); - CheckReferencesVp9(128, 0); -} - -// TODO(philipel): Remove when VP9 PID/TL0 does not jump mid-stream (should be -// around M59). -TEST_F(TestRtpFrameReferenceFinder, Vp9PidFix_PidJumpsBackwardThenForward) { - GofInfoVP9 ss; - ss.SetGofInfoVP9(kTemporalStructureMode1); - - VCMPacket packet; - packet.timestamp = 0; - packet.codec = kVideoCodecVP9; - packet.frameType = kVideoFrameKey; - packet.markerBit = true; - packet.video_header.codecHeader.VP9.flexible_mode = false; - packet.video_header.codecHeader.VP9.picture_id = 1; - packet.video_header.codecHeader.VP9.temporal_idx = 0; - packet.video_header.codecHeader.VP9.spatial_idx = 0; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 0; - packet.video_header.codecHeader.VP9.temporal_up_switch = true; - packet.video_header.codecHeader.VP9.ss_data_available = true; - packet.video_header.codecHeader.VP9.gof = ss; - - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - // Timestamp goes forward but pid goes backwards. - packet.timestamp = 1; - packet.video_header.codecHeader.VP9.picture_id = 0; - - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 2; - packet.video_header.codecHeader.VP9.picture_id = 5000; - - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - ASSERT_EQ(3UL, frames_from_callback_.size()); - CheckReferencesVp9(1, 0); - CheckReferencesVp9(129, 0); - CheckReferencesVp9(257, 0); -} - -// TODO(philipel): Remove when VP9 PID/TL0 does not jump mid-stream (should be -// around M59). -TEST_F(TestRtpFrameReferenceFinder, Vp9PidFix_Tl0JumpsBackwardThenForward) { - GofInfoVP9 ss; - ss.SetGofInfoVP9(kTemporalStructureMode1); - - VCMPacket packet; - packet.timestamp = 0; - packet.codec = kVideoCodecVP9; - packet.frameType = kVideoFrameKey; - packet.markerBit = true; - packet.video_header.codecHeader.VP9.flexible_mode = false; - packet.video_header.codecHeader.VP9.picture_id = 0; - packet.video_header.codecHeader.VP9.temporal_idx = 0; - packet.video_header.codecHeader.VP9.spatial_idx = 0; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 1; - packet.video_header.codecHeader.VP9.temporal_up_switch = true; - packet.video_header.codecHeader.VP9.ss_data_available = true; - packet.video_header.codecHeader.VP9.gof = ss; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 1; - packet.video_header.codecHeader.VP9.picture_id = 1; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 0; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 2; - packet.frameType = kVideoFrameDelta; - packet.video_header.codecHeader.VP9.picture_id = 2; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 2; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 3; - packet.frameType = kVideoFrameKey; - packet.video_header.codecHeader.VP9.ss_data_available = true; - packet.video_header.codecHeader.VP9.picture_id = 3; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 129; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - ASSERT_EQ(4UL, frames_from_callback_.size()); - CheckReferencesVp9(0, 0); - CheckReferencesVp9(128, 0); - CheckReferencesVp9(129, 0, 128); - CheckReferencesVp9(257, 0); -} - -// TODO(philipel): Remove when VP9 PID/TL0 does not jump mid-stream (should be -// around M59). -TEST_F(TestRtpFrameReferenceFinder, Vp9PidFix_PidSmallJumpForward) { - GofInfoVP9 ss; - ss.SetGofInfoVP9(kTemporalStructureMode1); - - VCMPacket packet; - packet.timestamp = 0; - packet.codec = kVideoCodecVP9; - packet.frameType = kVideoFrameKey; - packet.markerBit = true; - packet.video_header.codecHeader.VP9.flexible_mode = false; - packet.video_header.codecHeader.VP9.picture_id = 1; - packet.video_header.codecHeader.VP9.temporal_idx = 0; - packet.video_header.codecHeader.VP9.spatial_idx = 0; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 1; - packet.video_header.codecHeader.VP9.temporal_up_switch = true; - packet.video_header.codecHeader.VP9.ss_data_available = true; - packet.video_header.codecHeader.VP9.gof = ss; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 1; - packet.video_header.codecHeader.VP9.picture_id = 2; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 2; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 2; - packet.video_header.codecHeader.VP9.picture_id = 3; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 2; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 2; - packet.video_header.codecHeader.VP9.picture_id = 4; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 1; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - ASSERT_EQ(4UL, frames_from_callback_.size()); - CheckReferencesVp9(1, 0); - CheckReferencesVp9(2, 0); - CheckReferencesVp9(3, 0); - CheckReferencesVp9(131, 0); -} - -// TODO(philipel): Remove when VP9 PID/TL0 does not jump mid-stream (should be -// around M59). -TEST_F(TestRtpFrameReferenceFinder, Vp9PidFix_DropOldFrame) { - GofInfoVP9 ss; - ss.SetGofInfoVP9(kTemporalStructureMode1); - - VCMPacket packet; - packet.timestamp = 0; - packet.codec = kVideoCodecVP9; - packet.frameType = kVideoFrameKey; - packet.markerBit = true; - packet.video_header.codecHeader.VP9.flexible_mode = false; - packet.video_header.codecHeader.VP9.picture_id = 1; - packet.video_header.codecHeader.VP9.temporal_idx = 0; - packet.video_header.codecHeader.VP9.spatial_idx = 0; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 1; - packet.video_header.codecHeader.VP9.temporal_up_switch = true; - packet.video_header.codecHeader.VP9.ss_data_available = true; - packet.video_header.codecHeader.VP9.gof = ss; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 1; - packet.video_header.codecHeader.VP9.picture_id = 0; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 2; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - packet.timestamp = 0; - packet.video_header.codecHeader.VP9.picture_id = 3; - packet.video_header.codecHeader.VP9.tl0_pic_idx = 2; - ref_packet_buffer_->InsertPacket(&packet); - reference_finder_->ManageFrame(std::unique_ptr( - new RtpFrameObject(ref_packet_buffer_, 0, 0, 0, 0, 0))); - - ASSERT_EQ(2UL, frames_from_callback_.size()); - CheckReferencesVp9(1, 0); - CheckReferencesVp9(129, 0); -} - } // namespace video_coding } // namespace webrtc