Chromium Code Reviews| 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 |