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 |
| 11 #include "webrtc/modules/video_capture/video_capture_impl.h" | 11 #include "webrtc/modules/video_capture/video_capture_impl.h" |
| 12 | 12 |
| 13 #include <stdlib.h> | 13 #include <stdlib.h> |
| 14 | 14 |
| 15 #include "webrtc/base/refcount.h" | 15 #include "webrtc/base/refcount.h" |
| 16 #include "webrtc/base/timeutils.h" | |
| 16 #include "webrtc/base/trace_event.h" | 17 #include "webrtc/base/trace_event.h" |
| 17 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 18 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 18 #include "webrtc/modules/include/module_common_types.h" | 19 #include "webrtc/modules/include/module_common_types.h" |
| 19 #include "webrtc/modules/video_capture/video_capture_config.h" | 20 #include "webrtc/modules/video_capture/video_capture_config.h" |
| 20 #include "webrtc/system_wrappers/include/clock.h" | 21 #include "webrtc/system_wrappers/include/clock.h" |
| 21 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 22 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
| 22 #include "webrtc/system_wrappers/include/logging.h" | 23 #include "webrtc/system_wrappers/include/logging.h" |
| 23 #include "webrtc/system_wrappers/include/tick_util.h" | |
| 24 | 24 |
| 25 namespace webrtc { | 25 namespace webrtc { |
| 26 namespace videocapturemodule { | 26 namespace videocapturemodule { |
| 27 rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create( | 27 rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create( |
| 28 const int32_t id, | 28 const int32_t id, |
| 29 VideoCaptureExternal*& externalCapture) { | 29 VideoCaptureExternal*& externalCapture) { |
| 30 rtc::scoped_refptr<VideoCaptureImpl> implementation( | 30 rtc::scoped_refptr<VideoCaptureImpl> implementation( |
| 31 new rtc::RefCountedObject<VideoCaptureImpl>(id)); | 31 new rtc::RefCountedObject<VideoCaptureImpl>(id)); |
| 32 externalCapture = implementation.get(); | 32 externalCapture = implementation.get(); |
| 33 return implementation; | 33 return implementation; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 } | 78 } |
| 79 return -1; | 79 return -1; |
| 80 } | 80 } |
| 81 | 81 |
| 82 // returns the number of milliseconds until the module want a worker thread to c all Process | 82 // returns the number of milliseconds until the module want a worker thread to c all Process |
| 83 int64_t VideoCaptureImpl::TimeUntilNextProcess() | 83 int64_t VideoCaptureImpl::TimeUntilNextProcess() |
| 84 { | 84 { |
| 85 CriticalSectionScoped cs(&_callBackCs); | 85 CriticalSectionScoped cs(&_callBackCs); |
| 86 const int64_t kProcessIntervalMs = 300; | 86 const int64_t kProcessIntervalMs = 300; |
| 87 return kProcessIntervalMs - | 87 return kProcessIntervalMs - |
| 88 (TickTime::Now() - _lastProcessTime).Milliseconds(); | 88 (rtc::TimeNanos() - _lastProcessTime) / rtc::kNumNanosecsPerMillisec; |
| 89 } | 89 } |
| 90 | 90 |
| 91 // Process any pending tasks such as timeouts | 91 // Process any pending tasks such as timeouts |
| 92 void VideoCaptureImpl::Process() | 92 void VideoCaptureImpl::Process() |
| 93 { | 93 { |
| 94 CriticalSectionScoped cs(&_callBackCs); | 94 CriticalSectionScoped cs(&_callBackCs); |
| 95 | 95 |
| 96 const TickTime now = TickTime::Now(); | 96 const int64_t now = rtc::TimeNanos(); |
| 97 _lastProcessTime = TickTime::Now(); | 97 _lastProcessTime = rtc::TimeNanos(); |
|
stefan-webrtc
2016/04/19 09:19:12
Units
nisse-webrtc
2016/04/19 12:19:25
Done.
| |
| 98 | 98 |
| 99 // Handle No picture alarm | 99 // Handle No picture alarm |
| 100 | 100 |
| 101 if (_lastProcessFrameCount.Ticks() == _incomingFrameTimes[0].Ticks() && | 101 if (_lastProcessFrameCount == _incomingFrameTimes[0] && |
| 102 _captureAlarm != Raised) | 102 _captureAlarm != Raised) |
| 103 { | 103 { |
| 104 if (_noPictureAlarmCallBack && _captureCallBack) | 104 if (_noPictureAlarmCallBack && _captureCallBack) |
| 105 { | 105 { |
| 106 _captureAlarm = Raised; | 106 _captureAlarm = Raised; |
| 107 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm); | 107 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm); |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 else if (_lastProcessFrameCount.Ticks() != _incomingFrameTimes[0].Ticks() && | 110 else if (_lastProcessFrameCount != _incomingFrameTimes[0] && |
| 111 _captureAlarm != Cleared) | 111 _captureAlarm != Cleared) |
| 112 { | 112 { |
| 113 if (_noPictureAlarmCallBack && _captureCallBack) | 113 if (_noPictureAlarmCallBack && _captureCallBack) |
| 114 { | 114 { |
| 115 _captureAlarm = Cleared; | 115 _captureAlarm = Cleared; |
| 116 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm); | 116 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm); |
| 117 | 117 |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 // Handle frame rate callback | 121 // Handle frame rate callback |
| 122 if ((now - _lastFrameRateCallbackTime).Milliseconds() | 122 if ((now - _lastFrameRateCallbackTime) / rtc::kNumNanosecsPerMillisec |
| 123 > kFrameRateCallbackInterval) | 123 > kFrameRateCallbackInterval) |
| 124 { | 124 { |
| 125 if (_frameRateCallBack && _captureCallBack) | 125 if (_frameRateCallBack && _captureCallBack) |
| 126 { | 126 { |
| 127 const uint32_t frameRate = CalculateFrameRate(now); | 127 const uint32_t frameRate = CalculateFrameRate(now); |
| 128 _captureCallBack->OnCaptureFrameRate(_id, frameRate); | 128 _captureCallBack->OnCaptureFrameRate(_id, frameRate); |
| 129 } | 129 } |
| 130 _lastFrameRateCallbackTime = now; // Can be set by EnableFrameRateCallba ck | 130 _lastFrameRateCallbackTime = now; // Can be set by EnableFrameRateCallba ck |
| 131 | 131 |
| 132 } | 132 } |
| 133 | 133 |
| 134 _lastProcessFrameCount = _incomingFrameTimes[0]; | 134 _lastProcessFrameCount = _incomingFrameTimes[0]; |
| 135 } | 135 } |
| 136 | 136 |
| 137 VideoCaptureImpl::VideoCaptureImpl(const int32_t id) | 137 VideoCaptureImpl::VideoCaptureImpl(const int32_t id) |
| 138 : _id(id), | 138 : _id(id), |
| 139 _deviceUniqueId(NULL), | 139 _deviceUniqueId(NULL), |
| 140 _apiCs(*CriticalSectionWrapper::CreateCriticalSection()), | 140 _apiCs(*CriticalSectionWrapper::CreateCriticalSection()), |
| 141 _captureDelay(0), | 141 _captureDelay(0), |
| 142 _requestedCapability(), | 142 _requestedCapability(), |
| 143 _callBackCs(*CriticalSectionWrapper::CreateCriticalSection()), | 143 _callBackCs(*CriticalSectionWrapper::CreateCriticalSection()), |
| 144 _lastProcessTime(TickTime::Now()), | 144 _lastProcessTime(rtc::TimeNanos()), |
| 145 _lastFrameRateCallbackTime(TickTime::Now()), | 145 _lastFrameRateCallbackTime(rtc::TimeNanos()), |
| 146 _frameRateCallBack(false), | 146 _frameRateCallBack(false), |
| 147 _noPictureAlarmCallBack(false), | 147 _noPictureAlarmCallBack(false), |
| 148 _captureAlarm(Cleared), | 148 _captureAlarm(Cleared), |
| 149 _setCaptureDelay(0), | 149 _setCaptureDelay(0), |
| 150 _dataCallBack(NULL), | 150 _dataCallBack(NULL), |
| 151 _captureCallBack(NULL), | 151 _captureCallBack(NULL), |
| 152 _lastProcessFrameCount(TickTime::Now()), | 152 _lastProcessFrameCount(rtc::TimeNanos()), |
| 153 _rotateFrame(kVideoRotation_0), | 153 _rotateFrame(kVideoRotation_0), |
| 154 apply_rotation_(false) { | 154 apply_rotation_(false) { |
| 155 _requestedCapability.width = kDefaultWidth; | 155 _requestedCapability.width = kDefaultWidth; |
| 156 _requestedCapability.height = kDefaultHeight; | 156 _requestedCapability.height = kDefaultHeight; |
| 157 _requestedCapability.maxFPS = 30; | 157 _requestedCapability.maxFPS = 30; |
| 158 _requestedCapability.rawType = kVideoI420; | 158 _requestedCapability.rawType = kVideoI420; |
| 159 _requestedCapability.codecType = kVideoCodecUnknown; | 159 _requestedCapability.codecType = kVideoCodecUnknown; |
| 160 memset(_incomingFrameTimes, 0, sizeof(_incomingFrameTimes)); | 160 memset(_incomingFrameTimes, 0, sizeof(_incomingFrameTimes)); |
| 161 } | 161 } |
| 162 | 162 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 << frameInfo.rawType << "to I420."; | 288 << frameInfo.rawType << "to I420."; |
| 289 return -1; | 289 return -1; |
| 290 } | 290 } |
| 291 | 291 |
| 292 if (!apply_rotation) { | 292 if (!apply_rotation) { |
| 293 _captureFrame.set_rotation(_rotateFrame); | 293 _captureFrame.set_rotation(_rotateFrame); |
| 294 } else { | 294 } else { |
| 295 _captureFrame.set_rotation(kVideoRotation_0); | 295 _captureFrame.set_rotation(kVideoRotation_0); |
| 296 } | 296 } |
| 297 _captureFrame.set_ntp_time_ms(captureTime); | 297 _captureFrame.set_ntp_time_ms(captureTime); |
| 298 _captureFrame.set_render_time_ms(TickTime::MillisecondTimestamp()); | 298 _captureFrame.set_render_time_ms(rtc::Time64()); |
| 299 | 299 |
| 300 DeliverCapturedFrame(_captureFrame); | 300 DeliverCapturedFrame(_captureFrame); |
| 301 } | 301 } |
| 302 else // Encoded format | 302 else // Encoded format |
| 303 { | 303 { |
| 304 assert(false); | 304 assert(false); |
| 305 return -1; | 305 return -1; |
| 306 } | 306 } |
| 307 | 307 |
| 308 return 0; | 308 return 0; |
| 309 } | 309 } |
| 310 | 310 |
| 311 int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) { | 311 int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) { |
| 312 CriticalSectionScoped cs(&_apiCs); | 312 CriticalSectionScoped cs(&_apiCs); |
| 313 CriticalSectionScoped cs2(&_callBackCs); | 313 CriticalSectionScoped cs2(&_callBackCs); |
| 314 _rotateFrame = rotation; | 314 _rotateFrame = rotation; |
| 315 return 0; | 315 return 0; |
| 316 } | 316 } |
| 317 | 317 |
| 318 void VideoCaptureImpl::EnableFrameRateCallback(const bool enable) { | 318 void VideoCaptureImpl::EnableFrameRateCallback(const bool enable) { |
| 319 CriticalSectionScoped cs(&_apiCs); | 319 CriticalSectionScoped cs(&_apiCs); |
| 320 CriticalSectionScoped cs2(&_callBackCs); | 320 CriticalSectionScoped cs2(&_callBackCs); |
| 321 _frameRateCallBack = enable; | 321 _frameRateCallBack = enable; |
| 322 if (enable) | 322 if (enable) |
| 323 { | 323 { |
| 324 _lastFrameRateCallbackTime = TickTime::Now(); | 324 _lastFrameRateCallbackTime = rtc::TimeNanos(); |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 | 327 |
| 328 bool VideoCaptureImpl::SetApplyRotation(bool enable) { | 328 bool VideoCaptureImpl::SetApplyRotation(bool enable) { |
| 329 // We can't take any lock here as it'll cause deadlock with IncomingFrame. | 329 // We can't take any lock here as it'll cause deadlock with IncomingFrame. |
| 330 | 330 |
| 331 // The effect of this is the last caller wins. | 331 // The effect of this is the last caller wins. |
| 332 apply_rotation_ = enable; | 332 apply_rotation_ = enable; |
| 333 return true; | 333 return true; |
| 334 } | 334 } |
| 335 | 335 |
| 336 void VideoCaptureImpl::EnableNoPictureAlarm(const bool enable) { | 336 void VideoCaptureImpl::EnableNoPictureAlarm(const bool enable) { |
| 337 CriticalSectionScoped cs(&_apiCs); | 337 CriticalSectionScoped cs(&_apiCs); |
| 338 CriticalSectionScoped cs2(&_callBackCs); | 338 CriticalSectionScoped cs2(&_callBackCs); |
| 339 _noPictureAlarmCallBack = enable; | 339 _noPictureAlarmCallBack = enable; |
| 340 } | 340 } |
| 341 | 341 |
| 342 void VideoCaptureImpl::UpdateFrameCount() | 342 void VideoCaptureImpl::UpdateFrameCount() |
| 343 { | 343 { |
| 344 if (_incomingFrameTimes[0].MicrosecondTimestamp() == 0) | 344 if (_incomingFrameTimes[0] / rtc::kNumNanosecsPerMicrosec == 0) |
| 345 { | 345 { |
| 346 // first no shift | 346 // first no shift |
| 347 } | 347 } |
| 348 else | 348 else |
| 349 { | 349 { |
| 350 // shift | 350 // shift |
| 351 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--) | 351 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--) |
| 352 { | 352 { |
| 353 _incomingFrameTimes[i + 1] = _incomingFrameTimes[i]; | 353 _incomingFrameTimes[i + 1] = _incomingFrameTimes[i]; |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 _incomingFrameTimes[0] = TickTime::Now(); | 356 _incomingFrameTimes[0] = rtc::TimeNanos(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 uint32_t VideoCaptureImpl::CalculateFrameRate(const TickTime& now) | 359 uint32_t VideoCaptureImpl::CalculateFrameRate(int64_t now_ns) |
| 360 { | 360 { |
| 361 int32_t num = 0; | 361 int32_t num = 0; |
| 362 int32_t nrOfFrames = 0; | 362 int32_t nrOfFrames = 0; |
| 363 for (num = 1; num < (kFrameRateCountHistorySize - 1); num++) | 363 for (num = 1; num < (kFrameRateCountHistorySize - 1); num++) |
| 364 { | 364 { |
| 365 if (_incomingFrameTimes[num].Ticks() <= 0 | 365 if (_incomingFrameTimes[num] <= 0 || |
| 366 || (now - _incomingFrameTimes[num]).Milliseconds() > kFrameRateHisto ryWindowMs) // don't use data older than 2sec | 366 (now_ns - _incomingFrameTimes[num]) / rtc::kNumNanosecsPerMillisec > |
| 367 kFrameRateHistoryWindowMs) // don't use data older than 2sec | |
| 367 { | 368 { |
| 368 break; | 369 break; |
| 369 } | 370 } |
| 370 else | 371 else |
| 371 { | 372 { |
| 372 nrOfFrames++; | 373 nrOfFrames++; |
| 373 } | 374 } |
| 374 } | 375 } |
| 375 if (num > 1) | 376 if (num > 1) |
| 376 { | 377 { |
| 377 int64_t diff = (now - _incomingFrameTimes[num - 1]).Milliseconds(); | 378 int64_t diff = (now_ns - _incomingFrameTimes[num - 1]) / |
| 379 rtc::kNumNanosecsPerMillisec; | |
| 378 if (diff > 0) | 380 if (diff > 0) |
| 379 { | 381 { |
| 380 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f); | 382 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f); |
| 381 } | 383 } |
| 382 } | 384 } |
| 383 | 385 |
| 384 return nrOfFrames; | 386 return nrOfFrames; |
| 385 } | 387 } |
| 386 } // namespace videocapturemodule | 388 } // namespace videocapturemodule |
| 387 } // namespace webrtc | 389 } // namespace webrtc |
| OLD | NEW |