Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: webrtc/modules/video_coding/main/source/decoding_state.cc

Issue 1328113004: Work on flexible mode and screen sharing. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase + comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/video_coding/main/source/decoding_state.h" 11 #include "webrtc/modules/video_coding/main/source/decoding_state.h"
12 12
13 #include "webrtc/modules/include/module_common_types.h" 13 #include "webrtc/modules/include/module_common_types.h"
14 #include "webrtc/modules/video_coding/main/source/frame_buffer.h" 14 #include "webrtc/modules/video_coding/main/source/frame_buffer.h"
15 #include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h" 15 #include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h"
16 #include "webrtc/modules/video_coding/main/source/packet.h" 16 #include "webrtc/modules/video_coding/main/source/packet.h"
17 17
18 namespace webrtc { 18 namespace webrtc {
19 19
20 VCMDecodingState::VCMDecodingState() 20 VCMDecodingState::VCMDecodingState()
21 : sequence_num_(0), 21 : sequence_num_(0),
22 time_stamp_(0), 22 time_stamp_(0),
23 picture_id_(kNoPictureId), 23 picture_id_(kNoPictureId),
24 temporal_id_(kNoTemporalIdx), 24 temporal_id_(kNoTemporalIdx),
25 tl0_pic_id_(kNoTl0PicIdx), 25 tl0_pic_id_(kNoTl0PicIdx),
26 full_sync_(true), 26 full_sync_(true),
27 in_initial_state_(true) {} 27 in_initial_state_(true) {
28 memset(frame_decoded_, 0, sizeof(frame_decoded_));
29 }
28 30
29 VCMDecodingState::~VCMDecodingState() {} 31 VCMDecodingState::~VCMDecodingState() {}
30 32
31 void VCMDecodingState::Reset() { 33 void VCMDecodingState::Reset() {
32 // TODO(mikhal): Verify - not always would want to reset the sync 34 // TODO(mikhal): Verify - not always would want to reset the sync
33 sequence_num_ = 0; 35 sequence_num_ = 0;
34 time_stamp_ = 0; 36 time_stamp_ = 0;
35 picture_id_ = kNoPictureId; 37 picture_id_ = kNoPictureId;
36 temporal_id_ = kNoTemporalIdx; 38 temporal_id_ = kNoTemporalIdx;
37 tl0_pic_id_ = kNoTl0PicIdx; 39 tl0_pic_id_ = kNoTl0PicIdx;
38 full_sync_ = true; 40 full_sync_ = true;
39 in_initial_state_ = true; 41 in_initial_state_ = true;
42 memset(frame_decoded_, 0, sizeof(frame_decoded_));
40 } 43 }
41 44
42 uint32_t VCMDecodingState::time_stamp() const { 45 uint32_t VCMDecodingState::time_stamp() const {
43 return time_stamp_; 46 return time_stamp_;
44 } 47 }
45 48
46 uint16_t VCMDecodingState::sequence_num() const { 49 uint16_t VCMDecodingState::sequence_num() const {
47 return sequence_num_; 50 return sequence_num_;
48 } 51 }
49 52
50 bool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const { 53 bool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const {
51 assert(frame != NULL); 54 assert(frame != NULL);
52 if (in_initial_state_) 55 if (in_initial_state_)
53 return false; 56 return false;
54 return !IsNewerTimestamp(frame->TimeStamp(), time_stamp_); 57 return !IsNewerTimestamp(frame->TimeStamp(), time_stamp_);
55 } 58 }
56 59
57 bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const { 60 bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const {
58 assert(packet != NULL); 61 assert(packet != NULL);
59 if (in_initial_state_) 62 if (in_initial_state_)
60 return false; 63 return false;
61 return !IsNewerTimestamp(packet->timestamp, time_stamp_); 64 return !IsNewerTimestamp(packet->timestamp, time_stamp_);
62 } 65 }
63 66
64 void VCMDecodingState::SetState(const VCMFrameBuffer* frame) { 67 void VCMDecodingState::SetState(const VCMFrameBuffer* frame) {
65 assert(frame != NULL && frame->GetHighSeqNum() >= 0); 68 assert(frame != NULL && frame->GetHighSeqNum() >= 0);
66 UpdateSyncState(frame); 69 if (!UsingFlexibleMode(frame))
70 UpdateSyncState(frame);
67 sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum()); 71 sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum());
68 time_stamp_ = frame->TimeStamp(); 72 time_stamp_ = frame->TimeStamp();
69 picture_id_ = frame->PictureId(); 73 picture_id_ = frame->PictureId();
70 temporal_id_ = frame->TemporalId(); 74 temporal_id_ = frame->TemporalId();
71 tl0_pic_id_ = frame->Tl0PicId(); 75 tl0_pic_id_ = frame->Tl0PicId();
76
77 if (UsingFlexibleMode(frame)) {
78 uint16_t frame_index = picture_id_ % kFrameDecodedLength;
79 if (in_initial_state_) {
80 frame_decoded_cleared_to_ = frame_index;
81 } else if (frame->FrameType() == kVideoFrameKey) {
82 memset(frame_decoded_, 0, sizeof(frame_decoded_));
83 frame_decoded_cleared_to_ = frame_index;
84 } else {
85 if (AheadOfFramesDecodedClearedTo(frame_index)) {
86 while (frame_decoded_cleared_to_ != frame_index) {
87 frame_decoded_cleared_to_ =
88 (frame_decoded_cleared_to_ + 1) % kFrameDecodedLength;
89 frame_decoded_[frame_decoded_cleared_to_] = false;
90 }
91 }
92 }
93 frame_decoded_[frame_index] = true;
94 }
95
72 in_initial_state_ = false; 96 in_initial_state_ = false;
73 } 97 }
74 98
75 void VCMDecodingState::CopyFrom(const VCMDecodingState& state) { 99 void VCMDecodingState::CopyFrom(const VCMDecodingState& state) {
76 sequence_num_ = state.sequence_num_; 100 sequence_num_ = state.sequence_num_;
77 time_stamp_ = state.time_stamp_; 101 time_stamp_ = state.time_stamp_;
78 picture_id_ = state.picture_id_; 102 picture_id_ = state.picture_id_;
79 temporal_id_ = state.temporal_id_; 103 temporal_id_ = state.temporal_id_;
80 tl0_pic_id_ = state.tl0_pic_id_; 104 tl0_pic_id_ = state.tl0_pic_id_;
81 full_sync_ = state.full_sync_; 105 full_sync_ = state.full_sync_;
82 in_initial_state_ = state.in_initial_state_; 106 in_initial_state_ = state.in_initial_state_;
107 frame_decoded_cleared_to_ = state.frame_decoded_cleared_to_;
108 memcpy(frame_decoded_, state.frame_decoded_, sizeof(frame_decoded_));
83 } 109 }
84 110
85 bool VCMDecodingState::UpdateEmptyFrame(const VCMFrameBuffer* frame) { 111 bool VCMDecodingState::UpdateEmptyFrame(const VCMFrameBuffer* frame) {
86 bool empty_packet = frame->GetHighSeqNum() == frame->GetLowSeqNum(); 112 bool empty_packet = frame->GetHighSeqNum() == frame->GetLowSeqNum();
87 if (in_initial_state_ && empty_packet) { 113 if (in_initial_state_ && empty_packet) {
88 // Drop empty packets as long as we are in the initial state. 114 // Drop empty packets as long as we are in the initial state.
89 return true; 115 return true;
90 } 116 }
91 if ((empty_packet && ContinuousSeqNum(frame->GetHighSeqNum())) || 117 if ((empty_packet && ContinuousSeqNum(frame->GetHighSeqNum())) ||
92 ContinuousFrame(frame)) { 118 ContinuousFrame(frame)) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 return true; 192 return true;
167 // tl0picId is either not used, or should remain unchanged. 193 // tl0picId is either not used, or should remain unchanged.
168 if (frame->Tl0PicId() != tl0_pic_id_) 194 if (frame->Tl0PicId() != tl0_pic_id_)
169 return false; 195 return false;
170 // Base layers are not continuous or temporal layers are inactive. 196 // Base layers are not continuous or temporal layers are inactive.
171 // In the presence of temporal layers, check for Picture ID/sequence number 197 // In the presence of temporal layers, check for Picture ID/sequence number
172 // continuity if sync can be restored by this frame. 198 // continuity if sync can be restored by this frame.
173 if (!full_sync_ && !frame->LayerSync()) 199 if (!full_sync_ && !frame->LayerSync())
174 return false; 200 return false;
175 if (UsingPictureId(frame)) { 201 if (UsingPictureId(frame)) {
176 return ContinuousPictureId(frame->PictureId()); 202 if (UsingFlexibleMode(frame)) {
203 return ContinuousFrameRefs(frame);
204 } else {
205 return ContinuousPictureId(frame->PictureId());
206 }
177 } else { 207 } else {
178 return ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum())); 208 return ContinuousSeqNum(static_cast<uint16_t>(frame->GetLowSeqNum()));
179 } 209 }
180 } 210 }
181 211
182 bool VCMDecodingState::ContinuousPictureId(int picture_id) const { 212 bool VCMDecodingState::ContinuousPictureId(int picture_id) const {
183 int next_picture_id = picture_id_ + 1; 213 int next_picture_id = picture_id_ + 1;
184 if (picture_id < picture_id_) { 214 if (picture_id < picture_id_) {
185 // Wrap 215 // Wrap
186 if (picture_id_ >= 0x80) { 216 if (picture_id_ >= 0x80) {
(...skipping 22 matching lines...) Expand all
209 else if (tl0_pic_id_ == kNoTl0PicIdx && temporal_id_ == kNoTemporalIdx && 239 else if (tl0_pic_id_ == kNoTl0PicIdx && temporal_id_ == kNoTemporalIdx &&
210 temporal_id == 0) 240 temporal_id == 0)
211 return true; 241 return true;
212 242
213 // Current implementation: Look for base layer continuity. 243 // Current implementation: Look for base layer continuity.
214 if (temporal_id != 0) 244 if (temporal_id != 0)
215 return false; 245 return false;
216 return (static_cast<uint8_t>(tl0_pic_id_ + 1) == tl0_pic_id); 246 return (static_cast<uint8_t>(tl0_pic_id_ + 1) == tl0_pic_id);
217 } 247 }
218 248
249 bool VCMDecodingState::ContinuousFrameRefs(const VCMFrameBuffer* frame) const {
250 uint8_t num_refs = frame->CodecSpecific()->codecSpecific.VP9.num_ref_pics;
251 for (uint8_t r = 0; r < num_refs; ++r) {
252 uint16_t frame_ref = frame->PictureId() -
253 frame->CodecSpecific()->codecSpecific.VP9.p_diff[r];
254 uint16_t frame_index = frame_ref % kFrameDecodedLength;
255 if (AheadOfFramesDecodedClearedTo(frame_index) ||
256 !frame_decoded_[frame_index]) {
257 return false;
258 }
259 }
260 return true;
261 }
262
219 bool VCMDecodingState::UsingPictureId(const VCMFrameBuffer* frame) const { 263 bool VCMDecodingState::UsingPictureId(const VCMFrameBuffer* frame) const {
220 return (frame->PictureId() != kNoPictureId && picture_id_ != kNoPictureId); 264 return (frame->PictureId() != kNoPictureId && picture_id_ != kNoPictureId);
221 } 265 }
222 266
267 bool VCMDecodingState::UsingFlexibleMode(const VCMFrameBuffer* frame) const {
268 return frame->CodecSpecific()->codecType == kVideoCodecVP9 &&
269 frame->CodecSpecific()->codecSpecific.VP9.flexible_mode;
270 }
271
272 // TODO(philipel): change how check work, this check practially
273 // limits the max p_diff to 64.
274 bool VCMDecodingState::AheadOfFramesDecodedClearedTo(uint16_t index) const {
275 // No way of knowing for sure if we are actually ahead of
276 // frame_decoded_cleared_to_. We just make the assumption
277 // that we are not trying to reference back to a very old
278 // index, but instead are referencing a newer index.
279 uint16_t diff =
280 index > frame_decoded_cleared_to_
281 ? kFrameDecodedLength - (index - frame_decoded_cleared_to_)
282 : frame_decoded_cleared_to_ - index;
283 return diff > kFrameDecodedLength / 2;
284 }
285
223 } // namespace webrtc 286 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698