1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/main/source/decoding_state.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/interface/module_common_types.h" 14a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/main/source/frame_buffer.h" 15a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h" 16a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/main/source/packet.h" 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMDecodingState::VCMDecodingState() 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : sequence_num_(0), 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_stamp_(0), 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_(kNoPictureId), 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org temporal_id_(kNoTemporalIdx), 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tl0_pic_id_(kNoTl0PicIdx), 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org full_sync_(true), 27bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org in_initial_state_(true) {} 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVCMDecodingState::~VCMDecodingState() {} 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMDecodingState::Reset() { 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // TODO(mikhal): Verify - not always would want to reset the sync 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sequence_num_ = 0; 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_stamp_ = 0; 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_ = kNoPictureId; 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org temporal_id_ = kNoTemporalIdx; 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tl0_pic_id_ = kNoTl0PicIdx; 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org full_sync_ = true; 39bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org in_initial_state_ = true; 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orguint32_t VCMDecodingState::time_stamp() const { 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return time_stamp_; 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orguint16_t VCMDecodingState::sequence_num() const { 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return sequence_num_; 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const { 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(frame != NULL); 52bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (in_initial_state_) 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 5442c7409229636a59e28814451bd49ada2c6803a1stefan@webrtc.org return !IsNewerTimestamp(frame->TimeStamp(), time_stamp_); 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const { 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(packet != NULL); 59bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (in_initial_state_) 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 6142c7409229636a59e28814451bd49ada2c6803a1stefan@webrtc.org return !IsNewerTimestamp(packet->timestamp, time_stamp_); 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMDecodingState::SetState(const VCMFrameBuffer* frame) { 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(frame != NULL && frame->GetHighSeqNum() >= 0); 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateSyncState(frame); 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum()); 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_stamp_ = frame->TimeStamp(); 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_ = frame->PictureId(); 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org temporal_id_ = frame->TemporalId(); 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tl0_pic_id_ = frame->Tl0PicId(); 72bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org in_initial_state_ = false; 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 7540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.orgvoid VCMDecodingState::CopyFrom(const VCMDecodingState& state) { 7640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org sequence_num_ = state.sequence_num_; 7740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org time_stamp_ = state.time_stamp_; 7840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org picture_id_ = state.picture_id_; 7940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org temporal_id_ = state.temporal_id_; 8040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org tl0_pic_id_ = state.tl0_pic_id_; 8140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org full_sync_ = state.full_sync_; 8240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org in_initial_state_ = state.in_initial_state_; 8340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org} 8440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 85376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.orgbool VCMDecodingState::UpdateEmptyFrame(const VCMFrameBuffer* frame) { 86376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org bool empty_packet = frame->GetHighSeqNum() == frame->GetLowSeqNum(); 87376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (in_initial_state_ && empty_packet) { 88376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // Drop empty packets as long as we are in the initial state. 89376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return true; 90376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org } 91376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if ((empty_packet && ContinuousSeqNum(frame->GetHighSeqNum())) || 92376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org ContinuousFrame(frame)) { 93376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // Continuous empty packets or continuous frames can be dropped if we 94376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // advance the sequence number. 958bf7456eb477062c2a0a0693c3fa99063d529ed9tnakamura@webrtc.org sequence_num_ = frame->GetHighSeqNum(); 96376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org time_stamp_ = frame->TimeStamp(); 97376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return true; 98c54118274ff0879c38b36494cf57ee9376ccee61stefan@webrtc.org } 99376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return false; 100c54118274ff0879c38b36494cf57ee9376ccee61stefan@webrtc.org} 101c54118274ff0879c38b36494cf57ee9376ccee61stefan@webrtc.org 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMDecodingState::UpdateOldPacket(const VCMPacket* packet) { 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(packet != NULL); 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (packet->timestamp == time_stamp_) { 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Late packet belonging to the last decoded frame - make sure we update the 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // last decoded sequence number. 10742c7409229636a59e28814451bd49ada2c6803a1stefan@webrtc.org sequence_num_ = LatestSequenceNumber(packet->seqNum, sequence_num_); 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMDecodingState::SetSeqNum(uint16_t new_seq_num) { 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sequence_num_ = new_seq_num; 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 115bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.orgbool VCMDecodingState::in_initial_state() const { 116bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org return in_initial_state_; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::full_sync() const { 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return full_sync_; 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VCMDecodingState::UpdateSyncState(const VCMFrameBuffer* frame) { 124bb78b2c7ce8cc4445811d0e881890a29b14a4f2bstefan@webrtc.org if (in_initial_state_) 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frame->TemporalId() == kNoTemporalIdx || 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->Tl0PicId() == kNoTl0PicIdx) { 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org full_sync_ = true; 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (frame->FrameType() == kVideoFrameKey || frame->LayerSync()) { 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org full_sync_ = true; 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (full_sync_) { 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Verify that we are still in sync. 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Sync will be broken if continuity is true for layers but not for the 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // other methods (PictureId and SeqNum). 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (UsingPictureId(frame)) { 136991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org // First check for a valid tl0PicId. 137991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org if (frame->Tl0PicId() - tl0_pic_id_ > 1) { 138991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org full_sync_ = false; 139991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org } else { 140991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org full_sync_ = ContinuousPictureId(frame->PictureId()); 141991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org } 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org full_sync_ = ContinuousSeqNum(static_cast<uint16_t>( 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frame->GetLowSeqNum())); 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::ContinuousFrame(const VCMFrameBuffer* frame) const { 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Check continuity based on the following hierarchy: 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // - Temporal layers (stop here if out of sync). 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // - Picture Id when available. 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // - Sequence numbers. 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Return true when in initial state. 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Note that when a method is not applicable it will return false. 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(frame != NULL); 157376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // A key frame is always considered continuous as it doesn't refer to any 158376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // frames and therefore won't introduce any errors even if prior frames are 159376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // missing. 160376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (frame->FrameType() == kVideoFrameKey) 161376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org return true; 162376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org // When in the initial state we always require a key frame to start decoding. 163376ae3eaeb3751c41f2e2640b692a657e0e2d78dstefan@webrtc.org if (in_initial_state_) 164b47b7e077c86e3b02c4db99bdb4a2d2c0722b52bmikhal@webrtc.org return false; 165991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org if (ContinuousLayer(frame->TemporalId(), frame->Tl0PicId())) 166991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org return true; 167991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org // tl0picId is either not used, or should remain unchanged. 168991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org if (frame->Tl0PicId() != tl0_pic_id_) 169991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org return false; 170991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org // Base layers are not continuous or temporal layers are inactive. 171991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org // In the presence of temporal layers, check for Picture ID/sequence number 172991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org // continuity if sync can be restored by this frame. 173991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org if (!full_sync_ && !frame->LayerSync()) 174991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org return false; 175991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org if (UsingPictureId(frame)) { 176991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org return ContinuousPictureId(frame->PictureId()); 177991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org } else { 178991d66abe94107b866c29ede42602d2169e16739mikhal@webrtc.org return ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum())); 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::ContinuousPictureId(int picture_id) const { 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int next_picture_id = picture_id_ + 1; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (picture_id < picture_id_) { 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Wrap 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (picture_id_ >= 0x80) { 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 15 bits used for picture id 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ((next_picture_id & 0x7FFF) == picture_id); 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 7 bits used for picture id 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ((next_picture_id & 0x7F) == picture_id); 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No wrap 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (next_picture_id == picture_id); 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::ContinuousSeqNum(uint16_t seq_num) const { 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (seq_num == static_cast<uint16_t>(sequence_num_ + 1)); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::ContinuousLayer(int temporal_id, 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int tl0_pic_id) const { 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // First, check if applicable. 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (temporal_id == kNoTemporalIdx || tl0_pic_id == kNoTl0PicIdx) 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // If this is the first frame to use temporal layers, make sure we start 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // from base. 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (tl0_pic_id_ == kNoTl0PicIdx && temporal_id_ == kNoTemporalIdx && 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org temporal_id == 0) 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Current implementation: Look for base layer continuity. 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (temporal_id != 0) 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (static_cast<uint8_t>(tl0_pic_id_ + 1) == tl0_pic_id); 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VCMDecodingState::UsingPictureId(const VCMFrameBuffer* frame) const { 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (frame->PictureId() != kNoPictureId && picture_id_ != kNoPictureId); 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 224