Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 ++frame_it; | 78 ++frame_it; |
| 79 } | 79 } |
| 80 | 80 |
| 81 // |continuous_end_it| points to the first frame after the | 81 // |continuous_end_it| points to the first frame after the |
| 82 // |last_continuous_frame_it_|. | 82 // |last_continuous_frame_it_|. |
| 83 auto continuous_end_it = last_continuous_frame_it_; | 83 auto continuous_end_it = last_continuous_frame_it_; |
| 84 if (continuous_end_it != frames_.end()) | 84 if (continuous_end_it != frames_.end()) |
| 85 ++continuous_end_it; | 85 ++continuous_end_it; |
| 86 | 86 |
| 87 for (; frame_it != continuous_end_it; ++frame_it) { | 87 for (; frame_it != continuous_end_it; ++frame_it) { |
| 88 if (frame_it->second.num_missing_decodable > 0) | 88 if (!frame_it->second.continuous || |
| 89 frame_it->second.num_missing_decodable > 0) { | |
| 89 continue; | 90 continue; |
| 91 } | |
| 90 | 92 |
| 91 FrameObject* frame = frame_it->second.frame.get(); | 93 FrameObject* frame = frame_it->second.frame.get(); |
| 92 next_frame_it = frame_it; | 94 next_frame_it = frame_it; |
| 93 if (frame->RenderTime() == -1) | 95 if (frame->RenderTime() == -1) |
| 94 frame->SetRenderTime(timing_->RenderTimeMs(frame->timestamp, now_ms)); | 96 frame->SetRenderTime(timing_->RenderTimeMs(frame->timestamp, now_ms)); |
| 95 wait_ms = timing_->MaxWaitingTime(frame->RenderTime(), now_ms); | 97 wait_ms = timing_->MaxWaitingTime(frame->RenderTime(), now_ms); |
| 96 | 98 |
| 97 // This will cause the frame buffer to prefer high framerate rather | 99 // This will cause the frame buffer to prefer high framerate rather |
| 98 // than high resolution in the case of the decoder not decoding fast | 100 // than high resolution in the case of the decoder not decoding fast |
| 99 // enough and the stream has multiple spatial and temporal layers. | 101 // enough and the stream has multiple spatial and temporal layers. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 } | 146 } |
| 145 | 147 |
| 146 void FrameBuffer::Stop() { | 148 void FrameBuffer::Stop() { |
| 147 rtc::CritScope lock(&crit_); | 149 rtc::CritScope lock(&crit_); |
| 148 stopped_ = true; | 150 stopped_ = true; |
| 149 new_countinuous_frame_event_.Set(); | 151 new_countinuous_frame_event_.Set(); |
| 150 } | 152 } |
| 151 | 153 |
| 152 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { | 154 int FrameBuffer::InsertFrame(std::unique_ptr<FrameObject> frame) { |
| 153 rtc::CritScope lock(&crit_); | 155 rtc::CritScope lock(&crit_); |
| 156 RTC_DCHECK(frame); | |
| 157 | |
| 154 FrameKey key(frame->picture_id, frame->spatial_layer); | 158 FrameKey key(frame->picture_id, frame->spatial_layer); |
| 155 int last_continuous_picture_id = | 159 int last_continuous_picture_id = |
| 156 last_continuous_frame_it_ == frames_.end() | 160 last_continuous_frame_it_ == frames_.end() |
| 157 ? -1 | 161 ? -1 |
| 158 : last_continuous_frame_it_->first.picture_id; | 162 : last_continuous_frame_it_->first.picture_id; |
| 159 | 163 |
| 160 if (num_frames_buffered_ >= kMaxFramesBuffered) { | 164 if (num_frames_buffered_ >= kMaxFramesBuffered) { |
| 161 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id | 165 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id |
| 162 << ":" << static_cast<int>(key.spatial_layer) | 166 << ":" << static_cast<int>(key.spatial_layer) |
| 163 << ") could not be inserted due to the frame " | 167 << ") could not be inserted due to the frame " |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 179 << ") inserted after frame (" | 183 << ") inserted after frame (" |
| 180 << last_decoded_frame_it_->first.picture_id << ":" | 184 << last_decoded_frame_it_->first.picture_id << ":" |
| 181 << static_cast<int>( | 185 << static_cast<int>( |
| 182 last_decoded_frame_it_->first.spatial_layer) | 186 last_decoded_frame_it_->first.spatial_layer) |
| 183 << ") was handed off for decoding, dropping frame."; | 187 << ") was handed off for decoding, dropping frame."; |
| 184 return last_continuous_picture_id; | 188 return last_continuous_picture_id; |
| 185 } | 189 } |
| 186 | 190 |
| 187 auto info = frames_.insert(std::make_pair(key, FrameInfo())).first; | 191 auto info = frames_.insert(std::make_pair(key, FrameInfo())).first; |
| 188 | 192 |
| 189 if (!UpdateFrameInfoWithIncomingFrame(*frame, info)) { | 193 if (info->second.frame) { |
| 190 frames_.erase(info); | 194 LOG(LS_WARNING) << "Frame with (picture_id:spatial_id) (" << key.picture_id |
| 195 << ":" << static_cast<int>(key.spatial_layer) | |
| 196 << ") already inserted, dropping frame."; | |
| 191 return last_continuous_picture_id; | 197 return last_continuous_picture_id; |
| 192 } | 198 } |
| 193 | 199 |
| 200 if (!UpdateFrameInfoWithIncomingFrame(*frame, info)) | |
| 201 return last_continuous_picture_id; | |
| 202 | |
| 194 info->second.frame = std::move(frame); | 203 info->second.frame = std::move(frame); |
| 195 ++num_frames_buffered_; | 204 ++num_frames_buffered_; |
| 196 | 205 |
| 197 if (info->second.num_missing_continuous == 0) { | 206 if (info->second.num_missing_continuous == 0) { |
| 198 info->second.continuous = true; | 207 info->second.continuous = true; |
| 199 PropagateContinuity(info); | 208 PropagateContinuity(info); |
| 200 last_continuous_picture_id = last_continuous_frame_it_->first.picture_id; | 209 last_continuous_picture_id = last_continuous_frame_it_->first.picture_id; |
| 201 | 210 |
| 202 // Since we now have new continuous frames there might be a better frame | 211 // Since we now have new continuous frames there might be a better frame |
| 203 // to return from NextFrame. Signal that thread so that it again can choose | 212 // to return from NextFrame. Signal that thread so that it again can choose |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 234 frame_ref->second.continuous = true; | 243 frame_ref->second.continuous = true; |
| 235 continuous_frames.push(frame_ref); | 244 continuous_frames.push(frame_ref); |
| 236 } | 245 } |
| 237 } | 246 } |
| 238 } | 247 } |
| 239 } | 248 } |
| 240 | 249 |
| 241 void FrameBuffer::PropagateDecodability(const FrameInfo& info) { | 250 void FrameBuffer::PropagateDecodability(const FrameInfo& info) { |
| 242 for (size_t d = 0; d < info.num_dependent_frames; ++d) { | 251 for (size_t d = 0; d < info.num_dependent_frames; ++d) { |
| 243 auto ref_info = frames_.find(info.dependent_frames[d]); | 252 auto ref_info = frames_.find(info.dependent_frames[d]); |
| 253 RTC_DCHECK(ref_info != frames_.end()); | |
|
stefan-webrtc
2016/10/05 14:02:49
NE?
philipel
2016/10/05 14:30:01
Sorry, comparing iterators don't work with the DCH
| |
| 244 RTC_DCHECK_GT(ref_info->second.num_missing_decodable, 0U); | 254 RTC_DCHECK_GT(ref_info->second.num_missing_decodable, 0U); |
| 245 --ref_info->second.num_missing_decodable; | 255 --ref_info->second.num_missing_decodable; |
| 246 } | 256 } |
| 247 } | 257 } |
| 248 | 258 |
| 249 void FrameBuffer::AdvanceLastDecodedFrame(FrameMap::iterator decoded) { | 259 void FrameBuffer::AdvanceLastDecodedFrame(FrameMap::iterator decoded) { |
| 250 if (last_decoded_frame_it_ == frames_.end()) { | 260 if (last_decoded_frame_it_ == frames_.end()) { |
| 251 last_decoded_frame_it_ = frames_.begin(); | 261 last_decoded_frame_it_ = frames_.begin(); |
| 252 } else { | 262 } else { |
| 253 RTC_DCHECK(last_decoded_frame_it_->first < decoded->first); | 263 RTC_DCHECK(last_decoded_frame_it_->first < decoded->first); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 | 314 |
| 305 if (ref_info->second.continuous) | 315 if (ref_info->second.continuous) |
| 306 --info->second.num_missing_continuous; | 316 --info->second.num_missing_continuous; |
| 307 | 317 |
| 308 // Add backwards reference so |frame| can be updated when new | 318 // Add backwards reference so |frame| can be updated when new |
| 309 // frames are inserted or decoded. | 319 // frames are inserted or decoded. |
| 310 ref_info->second.dependent_frames[ref_info->second.num_dependent_frames] = | 320 ref_info->second.dependent_frames[ref_info->second.num_dependent_frames] = |
| 311 key; | 321 key; |
| 312 ++ref_info->second.num_dependent_frames; | 322 ++ref_info->second.num_dependent_frames; |
| 313 } | 323 } |
| 324 RTC_DCHECK_LE(ref_info->second.num_missing_continuous, | |
| 325 ref_info->second.num_missing_decodable); | |
| 314 } | 326 } |
| 315 | 327 |
| 316 // Check if we have the lower spatial layer frame. | 328 // Check if we have the lower spatial layer frame. |
| 317 if (frame.inter_layer_predicted) { | 329 if (frame.inter_layer_predicted) { |
| 318 ++info->second.num_missing_continuous; | 330 ++info->second.num_missing_continuous; |
| 319 ++info->second.num_missing_decodable; | 331 ++info->second.num_missing_decodable; |
| 320 | 332 |
| 321 FrameKey ref_key(frame.picture_id, frame.spatial_layer - 1); | 333 FrameKey ref_key(frame.picture_id, frame.spatial_layer - 1); |
| 322 // Gets or create the FrameInfo for the referenced frame. | 334 // Gets or create the FrameInfo for the referenced frame. |
| 323 auto ref_info = frames_.insert(std::make_pair(ref_key, FrameInfo())).first; | 335 auto ref_info = frames_.insert(std::make_pair(ref_key, FrameInfo())).first; |
| 324 if (ref_info->second.continuous) | 336 if (ref_info->second.continuous) |
| 325 --info->second.num_missing_continuous; | 337 --info->second.num_missing_continuous; |
| 326 | 338 |
| 327 if (ref_info == last_decoded_frame_it_) { | 339 if (ref_info == last_decoded_frame_it_) { |
| 328 --info->second.num_missing_decodable; | 340 --info->second.num_missing_decodable; |
| 329 } else { | 341 } else { |
| 330 ref_info->second.dependent_frames[ref_info->second.num_dependent_frames] = | 342 ref_info->second.dependent_frames[ref_info->second.num_dependent_frames] = |
| 331 key; | 343 key; |
| 332 ++ref_info->second.num_dependent_frames; | 344 ++ref_info->second.num_dependent_frames; |
| 333 } | 345 } |
| 346 RTC_DCHECK_LE(ref_info->second.num_missing_continuous, | |
| 347 ref_info->second.num_missing_decodable); | |
| 334 } | 348 } |
| 335 | 349 |
| 350 RTC_DCHECK_LE(info->second.num_missing_continuous, | |
| 351 info->second.num_missing_decodable); | |
| 352 | |
| 336 return true; | 353 return true; |
| 337 } | 354 } |
| 338 | 355 |
| 339 } // namespace video_coding | 356 } // namespace video_coding |
| 340 } // namespace webrtc | 357 } // namespace webrtc |
| OLD | NEW |