Remove temporary VP9 pid/tl0 jump fix.
Earlier the pid/tl0 was incorrectly reinitialized upon encoder reconfiguration, and this fix was implemented to mitigate that. This fix can however guess wrong and cause a valid stream to be interupted. BUG=webrtc:7920 Review-Url: https://codereview.webrtc.org/2969043002 Cr-Commit-Position: refs/heads/master@{#19268}
This commit is contained in:
@ -397,11 +397,6 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9(
|
|||||||
RTC_DCHECK(rtp_codec_header);
|
RTC_DCHECK(rtp_codec_header);
|
||||||
const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9;
|
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 ||
|
if (codec_header.picture_id == kNoPictureId ||
|
||||||
codec_header.temporal_idx == kNoTemporalIdx) {
|
codec_header.temporal_idx == kNoTemporalIdx) {
|
||||||
return ManageFrameGeneric(std::move(frame), codec_header.picture_id);
|
return ManageFrameGeneric(std::move(frame), codec_header.picture_id);
|
||||||
@ -608,148 +603,5 @@ uint16_t RtpFrameReferenceFinder::UnwrapPictureId(uint16_t picture_id) {
|
|||||||
return last_unwrap_;
|
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<uint32_t>(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<uint32_t>(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<uint32_t>(frame.timestamp, vp9_fix_last_timestamp_))
|
|
||||||
vp9_fix_last_timestamp_ = frame.timestamp;
|
|
||||||
|
|
||||||
uint16_t fixed_pid = Add<kPicIdLength>(*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<kTl0PicIdLength>(*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<uint8_t>(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<uint16_t, kPicIdLength>(
|
|
||||||
*picture_id, vp9_fix_last_picture_id_);
|
|
||||||
vp9_fix_pid_offset_ += kMaxPidDiff;
|
|
||||||
|
|
||||||
fixed_pid = Add<kPicIdLength>(*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<uint8_t>(*tl0_pic_idx, vp9_fix_last_tl0_pic_idx_);
|
|
||||||
vp9_fix_tl0_pic_idx_offset_ += kMaxGofSaved;
|
|
||||||
fixed_tl0 =
|
|
||||||
Add<kTl0PicIdLength>(*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<uint16_t, kPicIdLength>(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<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
|
|
||||||
AheadOf<uint16_t, kPicIdLength>(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<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
|
|
||||||
ForwardDiff<uint16_t, kPicIdLength>(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<kPicIdLength>(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<kPicIdLength>(
|
|
||||||
last_pid_gof_idx_0, info_it->second.gof->num_frames_in_gof);
|
|
||||||
if (AheadOf<uint16_t, kPicIdLength>(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<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
|
|
||||||
AheadOf<uint8_t>(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<uint8_t>(gof_info_.begin()->first, fixed_tl0)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace video_coding
|
} // namespace video_coding
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -213,15 +213,6 @@ class RtpFrameReferenceFinder {
|
|||||||
int cleared_to_seq_num_ GUARDED_BY(crit_);
|
int cleared_to_seq_num_ GUARDED_BY(crit_);
|
||||||
|
|
||||||
OnCompleteFrameCallback* frame_callback_;
|
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
|
} // namespace video_coding
|
||||||
|
|||||||
@ -1308,233 +1308,5 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) {
|
|||||||
CheckReferencesVp9(pid + 8, 1, pid + 7);
|
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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<RtpFrameObject>(
|
|
||||||
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 video_coding
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Reference in New Issue
Block a user