Index: webrtc/modules/video_coding/main/source/decoding_state.cc |
diff --git a/webrtc/modules/video_coding/main/source/decoding_state.cc b/webrtc/modules/video_coding/main/source/decoding_state.cc |
index cc92f1c83f9d9885c89b8b2cac3744835bbe628b..7475f0b55993bd23ca467f64740a9907ff05022d 100644 |
--- a/webrtc/modules/video_coding/main/source/decoding_state.cc |
+++ b/webrtc/modules/video_coding/main/source/decoding_state.cc |
@@ -24,7 +24,9 @@ VCMDecodingState::VCMDecodingState() |
temporal_id_(kNoTemporalIdx), |
tl0_pic_id_(kNoTl0PicIdx), |
full_sync_(true), |
- in_initial_state_(true) {} |
+ in_initial_state_(true) { |
+ memset(frame_decoded_, 0, sizeof(frame_decoded_)); |
sprang_webrtc
2015/09/15 15:41:22
Don't think you need this?
philipel
2015/09/16 09:35:54
I think I do: http://stackoverflow.com/questions/7
sprang_webrtc
2015/09/25 09:53:15
You're right. I was drunk.
Maybe frame_decoded_{}
|
+} |
VCMDecodingState::~VCMDecodingState() {} |
@@ -37,6 +39,7 @@ void VCMDecodingState::Reset() { |
tl0_pic_id_ = kNoTl0PicIdx; |
full_sync_ = true; |
in_initial_state_ = true; |
+ memset(frame_decoded_, 0, sizeof(frame_decoded_)); |
} |
uint32_t VCMDecodingState::time_stamp() const { |
@@ -63,12 +66,31 @@ bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const { |
void VCMDecodingState::SetState(const VCMFrameBuffer* frame) { |
assert(frame != NULL && frame->GetHighSeqNum() >= 0); |
- UpdateSyncState(frame); |
+ if (frame->CodecSpecific()->codecType != kVideoCodecVP9) |
+ UpdateSyncState(frame); |
sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum()); |
time_stamp_ = frame->TimeStamp(); |
picture_id_ = frame->PictureId(); |
temporal_id_ = frame->TemporalId(); |
tl0_pic_id_ = frame->Tl0PicId(); |
+ |
+ if (UsingFlexibleMode(frame)) { |
+ uint16_t frame_index = picture_id_ % kFrameDecodedLength; |
+ if (in_initial_state_) { |
+ fd_cleared_to_ = frame_index; |
+ frame_decoded_[frame_index] = true; |
+ } else if (frame->FrameType() == kVideoFrameKey) { |
+ memset(frame_decoded_, 0, sizeof(frame_decoded_)); |
+ fd_cleared_to_ = frame_index; |
+ } else { |
+ while (fd_cleared_to_ != frame_index) { |
+ fd_cleared_to_ = (fd_cleared_to_ + 1) % kFrameDecodedLength; |
+ frame_decoded_[fd_cleared_to_] = false; |
+ } |
+ frame_decoded_[frame_index] = true; |
+ } |
+ } |
+ |
in_initial_state_ = false; |
} |
@@ -80,6 +102,8 @@ void VCMDecodingState::CopyFrom(const VCMDecodingState& state) { |
tl0_pic_id_ = state.tl0_pic_id_; |
full_sync_ = state.full_sync_; |
in_initial_state_ = state.in_initial_state_; |
+ fd_cleared_to_ = state.fd_cleared_to_; |
+ memcpy(frame_decoded_, state.frame_decoded_, sizeof(frame_decoded_)); |
} |
bool VCMDecodingState::UpdateEmptyFrame(const VCMFrameBuffer* frame) { |
@@ -173,7 +197,11 @@ bool VCMDecodingState::ContinuousFrame(const VCMFrameBuffer* frame) const { |
if (!full_sync_ && !frame->LayerSync()) |
return false; |
if (UsingPictureId(frame)) { |
- return ContinuousPictureId(frame->PictureId()); |
+ if (UsingFlexibleMode(frame)) { |
+ return ContinuousFrameRefs(frame); |
+ } else { |
+ return ContinuousPictureId(frame->PictureId()); |
+ } |
} else { |
return ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum())); |
} |
@@ -216,8 +244,24 @@ bool VCMDecodingState::ContinuousLayer(int temporal_id, |
return (static_cast<uint8_t>(tl0_pic_id_ + 1) == tl0_pic_id); |
} |
+bool VCMDecodingState::ContinuousFrameRefs(const VCMFrameBuffer* frame) const { |
+ bool continuous = true; |
+ uint8_t num_refs = frame->CodecSpecific()->codecSpecific.VP9.num_ref_pics; |
+ for (uint8_t r = 0; r < num_refs; ++r) { |
+ uint16_t frame_ref = frame->PictureId() - |
+ frame->CodecSpecific()->codecSpecific.VP9.p_diff[r]; |
+ continuous &= frame_decoded_[frame_ref % kFrameDecodedLength]; |
sprang_webrtc
2015/09/15 15:41:22
Just return false early here, and true below.
philipel
2015/09/16 09:35:54
Done.
|
+ } |
+ return continuous; |
+} |
+ |
bool VCMDecodingState::UsingPictureId(const VCMFrameBuffer* frame) const { |
return (frame->PictureId() != kNoPictureId && picture_id_ != kNoPictureId); |
} |
+bool VCMDecodingState::UsingFlexibleMode(const VCMFrameBuffer* frame) const { |
+ return frame->CodecSpecific()->codecType == kVideoCodecVP9 && |
+ frame->CodecSpecific()->codecSpecific.VP9.flexible_mode; |
+} |
+ |
} // namespace webrtc |