OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 } else if (codec_specific->codecType == kVideoCodecVP8) { | 226 } else if (codec_specific->codecType == kVideoCodecVP8) { |
227 simulcast_svc_idx = codec_specific->codecSpecific.VP8.simulcastIdx; | 227 simulcast_svc_idx = codec_specific->codecSpecific.VP8.simulcastIdx; |
228 } else if (codec_specific->codecType == kVideoCodecGeneric) { | 228 } else if (codec_specific->codecType == kVideoCodecGeneric) { |
229 simulcast_svc_idx = codec_specific->codecSpecific.generic.simulcast_idx; | 229 simulcast_svc_idx = codec_specific->codecSpecific.generic.simulcast_idx; |
230 } else if (codec_specific->codecType == kVideoCodecH264) { | 230 } else if (codec_specific->codecType == kVideoCodecH264) { |
231 // TODO(ilnik): When h264 simulcast is landed, extract simulcast idx here. | 231 // TODO(ilnik): When h264 simulcast is landed, extract simulcast idx here. |
232 } | 232 } |
233 | 233 |
234 { | 234 { |
235 rtc::CritScope crit(&timing_params_lock_); | 235 rtc::CritScope crit(&timing_params_lock_); |
236 RTC_CHECK_LT(simulcast_svc_idx, timing_frames_info_.size()); | 236 // TODO(ilnik): Workaround for hardware encoders, which do not call |
237 // |OnEncodeStarted| correctly. Once fixed, remove conditional check. | |
238 if (simulcast_svc_idx < timing_frames_info_.size()) { | |
239 RTC_CHECK_LT(simulcast_svc_idx, timing_frames_info_.size()); | |
237 | 240 |
238 auto encode_start_map = | 241 auto encode_start_map = |
239 &timing_frames_info_[simulcast_svc_idx].encode_start_time_ms; | 242 &timing_frames_info_[simulcast_svc_idx].encode_start_time_ms; |
240 auto it = encode_start_map->find(encoded_image.capture_time_ms_); | 243 auto it = encode_start_map->find(encoded_image.capture_time_ms_); |
241 if (it != encode_start_map->end()) { | 244 if (it != encode_start_map->end()) { |
242 encode_start_ms = it->second; | 245 encode_start_ms = it->second; |
243 // Assuming all encoders do not reorder frames within single stream, | 246 // Assuming all encoders do not reorder frames within single stream, |
244 // there may be some dropped frames with smaller timestamps. These should | 247 // there may be some dropped frames with smaller timestamps. These |
245 // be purged. | 248 // should be purged. |
246 encode_start_map->erase(encode_start_map->begin(), it); | 249 encode_start_map->erase(encode_start_map->begin(), it); |
247 encode_start_map->erase(it); | 250 encode_start_map->erase(it); |
251 } else { | |
252 // Some chromium remoting unittests use generic encoder incorrectly | |
brandtr
2017/06/28 10:33:33
Maybe we should update these tests to be more corr
| |
253 // If timestamps do not match, purge them all. | |
254 encode_start_map->erase(encode_start_map->begin(), | |
255 encode_start_map->end()); | |
256 } | |
257 | |
258 int64_t timing_frame_delay_ms = | |
259 encoded_image.capture_time_ms_ - last_timing_frame_time_ms_; | |
260 if (last_timing_frame_time_ms_ == -1 || | |
261 timing_frame_delay_ms >= timing_frames_thresholds_.delay_ms || | |
262 timing_frame_delay_ms == 0) { | |
263 is_timing_frame = true; | |
264 last_timing_frame_time_ms_ = encoded_image.capture_time_ms_; | |
265 } | |
266 // TODO(ilnik): Once OnFramerateChanged is called correctly by hardware | |
267 // encoders, remove the conditional check below. | |
268 if (framerate_ > 0) { | |
269 RTC_CHECK_GT(framerate_, 0); | |
270 size_t average_frame_size = | |
271 timing_frames_info_[simulcast_svc_idx].target_bitrate_bytes_per_sec | |
272 / framerate_; | |
273 outlier_frame_size = average_frame_size * | |
274 timing_frames_thresholds_.outlier_ratio_percent / | |
275 100; | |
276 } else { | |
277 outlier_frame_size = encoded_image._length + 1; | |
278 } | |
248 } else { | 279 } else { |
249 // Some chromium remoting unittests use generic encoder incorrectly | 280 // We don't have any information prior to encode start, thus we can't |
250 // If timestamps do not match, purge them all. | 281 // reliably detect outliers. Set outlier size to anything larger than |
251 encode_start_map->erase(encode_start_map->begin(), | 282 // current frame size. |
252 encode_start_map->end()); | 283 outlier_frame_size = encoded_image._length + 1; |
253 } | 284 } |
254 | |
255 int64_t timing_frame_delay_ms = | |
256 encoded_image.capture_time_ms_ - last_timing_frame_time_ms_; | |
257 if (last_timing_frame_time_ms_ == -1 || | |
258 timing_frame_delay_ms >= timing_frames_thresholds_.delay_ms || | |
259 timing_frame_delay_ms == 0) { | |
260 is_timing_frame = true; | |
261 last_timing_frame_time_ms_ = encoded_image.capture_time_ms_; | |
262 } | |
263 RTC_CHECK_GT(framerate_, 0); | |
264 size_t average_frame_size = | |
265 timing_frames_info_[simulcast_svc_idx].target_bitrate_bytes_per_sec / | |
266 framerate_; | |
267 outlier_frame_size = average_frame_size * | |
268 timing_frames_thresholds_.outlier_ratio_percent / 100; | |
269 } | 285 } |
270 | 286 |
271 if (encoded_image._length >= outlier_frame_size) { | 287 if (encoded_image._length >= outlier_frame_size) { |
272 is_timing_frame = true; | 288 is_timing_frame = true; |
273 } | 289 } |
274 if (encode_start_ms >= 0 && is_timing_frame) { | 290 if (encode_start_ms >= 0 && is_timing_frame) { |
275 encoded_image.SetEncodeTime(encode_start_ms, rtc::TimeMillis()); | 291 encoded_image.SetEncodeTime(encode_start_ms, rtc::TimeMillis()); |
276 } | 292 } |
277 | 293 |
278 Result result = post_encode_callback_->OnEncodedImage( | 294 Result result = post_encode_callback_->OnEncodedImage( |
279 encoded_image, codec_specific, fragmentation_header); | 295 encoded_image, codec_specific, fragmentation_header); |
280 if (result.error != Result::OK) | 296 if (result.error != Result::OK) |
281 return result; | 297 return result; |
282 | 298 |
283 if (media_opt_) { | 299 if (media_opt_) { |
284 media_opt_->UpdateWithEncodedData(encoded_image); | 300 media_opt_->UpdateWithEncodedData(encoded_image); |
285 if (internal_source_) { | 301 if (internal_source_) { |
286 // Signal to encoder to drop next frame. | 302 // Signal to encoder to drop next frame. |
287 result.drop_next_frame = media_opt_->DropFrame(); | 303 result.drop_next_frame = media_opt_->DropFrame(); |
288 } | 304 } |
289 } | 305 } |
290 return result; | 306 return result; |
291 } | 307 } |
292 | 308 |
293 } // namespace webrtc | 309 } // namespace webrtc |
OLD | NEW |