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 |