blob: c3d5f370911fe6654b5fabf66c71bc7b44ca87db [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mallinath@webrtc.org12984f02012-02-16 18:18:21 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga9b74ad2013-07-12 10:03:52 +000011#include "webrtc/modules/video_capture/video_capture_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
elham@webrtc.org5f49dba2012-04-23 21:24:02 +000013#include <stdlib.h>
14
Peter Boström1d194412016-03-21 16:44:31 +010015#include "webrtc/base/refcount.h"
Niels Möllerd28db7f2016-05-10 16:31:47 +020016#include "webrtc/base/timeutils.h"
tommie4f96502015-10-20 23:00:48 -070017#include "webrtc/base/trace_event.h"
pbos@webrtc.orga9b74ad2013-07-12 10:03:52 +000018#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010019#include "webrtc/modules/include/module_common_types.h"
pbos@webrtc.orga9b74ad2013-07-12 10:03:52 +000020#include "webrtc/modules/video_capture/video_capture_config.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010021#include "webrtc/system_wrappers/include/clock.h"
22#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
23#include "webrtc/system_wrappers/include/logging.h"
pbos@webrtc.orga9b74ad2013-07-12 10:03:52 +000024
Peter Boström1d194412016-03-21 16:44:31 +010025namespace webrtc {
26namespace videocapturemodule {
27rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create(
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000028 const int32_t id,
Peter Boström1d194412016-03-21 16:44:31 +010029 VideoCaptureExternal*& externalCapture) {
30 rtc::scoped_refptr<VideoCaptureImpl> implementation(
31 new rtc::RefCountedObject<VideoCaptureImpl>(id));
32 externalCapture = implementation.get();
33 return implementation;
niklase@google.com470e71d2011-07-07 08:21:25 +000034}
35
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000036const char* VideoCaptureImpl::CurrentDeviceName() const
niklase@google.com470e71d2011-07-07 08:21:25 +000037{
38 return _deviceUniqueId;
39}
40
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000041// static
42int32_t VideoCaptureImpl::RotationFromDegrees(int degrees,
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000043 VideoRotation* rotation) {
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000044 switch (degrees) {
45 case 0:
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000046 *rotation = kVideoRotation_0;
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000047 return 0;
48 case 90:
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000049 *rotation = kVideoRotation_90;
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000050 return 0;
51 case 180:
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000052 *rotation = kVideoRotation_180;
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000053 return 0;
54 case 270:
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000055 *rotation = kVideoRotation_270;
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000056 return 0;
57 default:
58 return -1;;
59 }
60}
61
62// static
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000063int32_t VideoCaptureImpl::RotationInDegrees(VideoRotation rotation,
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000064 int* degrees) {
65 switch (rotation) {
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000066 case kVideoRotation_0:
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000067 *degrees = 0;
68 return 0;
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000069 case kVideoRotation_90:
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000070 *degrees = 90;
71 return 0;
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000072 case kVideoRotation_180:
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000073 *degrees = 180;
74 return 0;
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +000075 case kVideoRotation_270:
fischman@webrtc.org4e65e072013-10-03 18:23:13 +000076 *degrees = 270;
77 return 0;
78 }
79 return -1;
80}
81
niklase@google.com470e71d2011-07-07 08:21:25 +000082// returns the number of milliseconds until the module want a worker thread to call Process
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +000083int64_t VideoCaptureImpl::TimeUntilNextProcess()
niklase@google.com470e71d2011-07-07 08:21:25 +000084{
perkj@webrtc.orgc2fde802012-08-08 14:01:09 +000085 CriticalSectionScoped cs(&_callBackCs);
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +000086 const int64_t kProcessIntervalMs = 300;
87 return kProcessIntervalMs -
Niels Möllerd28db7f2016-05-10 16:31:47 +020088 (rtc::TimeNanos() - _lastProcessTimeNanos) /
89 rtc::kNumNanosecsPerMillisec;
niklase@google.com470e71d2011-07-07 08:21:25 +000090}
91
92// Process any pending tasks such as timeouts
pbosa26ac922016-02-25 04:50:01 -080093void VideoCaptureImpl::Process()
niklase@google.com470e71d2011-07-07 08:21:25 +000094{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +000095 CriticalSectionScoped cs(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +000096
Niels Möllerd28db7f2016-05-10 16:31:47 +020097 const int64_t now_ns = rtc::TimeNanos();
98 _lastProcessTimeNanos = rtc::TimeNanos();
niklase@google.com470e71d2011-07-07 08:21:25 +000099
100 // Handle No picture alarm
101
Niels Möllerd28db7f2016-05-10 16:31:47 +0200102 if (_lastProcessFrameTimeNanos == _incomingFrameTimesNanos[0] &&
niklase@google.com470e71d2011-07-07 08:21:25 +0000103 _captureAlarm != Raised)
104 {
105 if (_noPictureAlarmCallBack && _captureCallBack)
106 {
107 _captureAlarm = Raised;
108 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm);
109 }
110 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200111 else if (_lastProcessFrameTimeNanos != _incomingFrameTimesNanos[0] &&
niklase@google.com470e71d2011-07-07 08:21:25 +0000112 _captureAlarm != Cleared)
113 {
114 if (_noPictureAlarmCallBack && _captureCallBack)
115 {
116 _captureAlarm = Cleared;
117 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm);
118
119 }
120 }
121
122 // Handle frame rate callback
Niels Möllerd28db7f2016-05-10 16:31:47 +0200123 if ((now_ns - _lastFrameRateCallbackTimeNanos) /
124 rtc::kNumNanosecsPerMillisec
niklase@google.com470e71d2011-07-07 08:21:25 +0000125 > kFrameRateCallbackInterval)
126 {
127 if (_frameRateCallBack && _captureCallBack)
128 {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200129 const uint32_t frameRate = CalculateFrameRate(now_ns);
niklase@google.com470e71d2011-07-07 08:21:25 +0000130 _captureCallBack->OnCaptureFrameRate(_id, frameRate);
131 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200132 // Can be set by EnableFrameRateCallback
133 _lastFrameRateCallbackTimeNanos = now_ns;
niklase@google.com470e71d2011-07-07 08:21:25 +0000134
135 }
136
Niels Möllerd28db7f2016-05-10 16:31:47 +0200137 _lastProcessFrameTimeNanos = _incomingFrameTimesNanos[0];
niklase@google.com470e71d2011-07-07 08:21:25 +0000138}
139
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000140VideoCaptureImpl::VideoCaptureImpl(const int32_t id)
pbos@webrtc.org504af452013-07-02 10:15:43 +0000141 : _id(id),
142 _deviceUniqueId(NULL),
143 _apiCs(*CriticalSectionWrapper::CreateCriticalSection()),
144 _captureDelay(0),
145 _requestedCapability(),
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 _callBackCs(*CriticalSectionWrapper::CreateCriticalSection()),
Niels Möllerd28db7f2016-05-10 16:31:47 +0200147 _lastProcessTimeNanos(rtc::TimeNanos()),
148 _lastFrameRateCallbackTimeNanos(rtc::TimeNanos()),
pbos@webrtc.org504af452013-07-02 10:15:43 +0000149 _frameRateCallBack(false),
150 _noPictureAlarmCallBack(false),
151 _captureAlarm(Cleared),
152 _setCaptureDelay(0),
153 _dataCallBack(NULL),
154 _captureCallBack(NULL),
Niels Möllerd28db7f2016-05-10 16:31:47 +0200155 _lastProcessFrameTimeNanos(rtc::TimeNanos()),
guoweis@webrtc.org59140d62015-03-09 17:07:31 +0000156 _rotateFrame(kVideoRotation_0),
deadbeeff5629ad2016-03-18 11:38:26 -0700157 apply_rotation_(false) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000158 _requestedCapability.width = kDefaultWidth;
159 _requestedCapability.height = kDefaultHeight;
160 _requestedCapability.maxFPS = 30;
161 _requestedCapability.rawType = kVideoI420;
162 _requestedCapability.codecType = kVideoCodecUnknown;
Niels Möllerd28db7f2016-05-10 16:31:47 +0200163 memset(_incomingFrameTimesNanos, 0, sizeof(_incomingFrameTimesNanos));
niklase@google.com470e71d2011-07-07 08:21:25 +0000164}
165
166VideoCaptureImpl::~VideoCaptureImpl()
167{
168 DeRegisterCaptureDataCallback();
169 DeRegisterCaptureCallback();
170 delete &_callBackCs;
171 delete &_apiCs;
172
173 if (_deviceUniqueId)
174 delete[] _deviceUniqueId;
175}
176
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000177void VideoCaptureImpl::RegisterCaptureDataCallback(
178 VideoCaptureDataCallback& dataCallBack) {
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000179 CriticalSectionScoped cs(&_apiCs);
180 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000181 _dataCallBack = &dataCallBack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000182}
183
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000184void VideoCaptureImpl::DeRegisterCaptureDataCallback() {
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000185 CriticalSectionScoped cs(&_apiCs);
186 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000187 _dataCallBack = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000188}
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000189void VideoCaptureImpl::RegisterCaptureCallback(VideoCaptureFeedBack& callBack) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000190
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000191 CriticalSectionScoped cs(&_apiCs);
192 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000193 _captureCallBack = &callBack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000194}
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000195void VideoCaptureImpl::DeRegisterCaptureCallback() {
niklase@google.com470e71d2011-07-07 08:21:25 +0000196
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000197 CriticalSectionScoped cs(&_apiCs);
198 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000199 _captureCallBack = NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +0000200}
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000201void VideoCaptureImpl::SetCaptureDelay(int32_t delayMS) {
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000202 CriticalSectionScoped cs(&_apiCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000203 _captureDelay = delayMS;
niklase@google.com470e71d2011-07-07 08:21:25 +0000204}
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000205int32_t VideoCaptureImpl::CaptureDelay()
niklase@google.com470e71d2011-07-07 08:21:25 +0000206{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000207 CriticalSectionScoped cs(&_apiCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000208 return _setCaptureDelay;
209}
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000210
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700211int32_t VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame) {
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000212 UpdateFrameCount(); // frame count used for local frame rate callback.
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000213
214 const bool callOnCaptureDelayChanged = _setCaptureDelay != _captureDelay;
215 // Capture delay changed
216 if (_setCaptureDelay != _captureDelay) {
217 _setCaptureDelay = _captureDelay;
218 }
219
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000220 if (_dataCallBack) {
221 if (callOnCaptureDelayChanged) {
222 _dataCallBack->OnCaptureDelayChanged(_id, _captureDelay);
223 }
mikhal@webrtc.orge83d3112012-10-29 15:59:40 +0000224 _dataCallBack->OnIncomingCapturedFrame(_id, captureFrame);
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000225 }
226
227 return 0;
228}
229
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000230int32_t VideoCaptureImpl::IncomingFrame(
231 uint8_t* videoFrame,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000232 size_t videoFrameLength,
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000233 const VideoCaptureCapability& frameInfo,
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000234 int64_t captureTime/*=0*/)
niklase@google.com470e71d2011-07-07 08:21:25 +0000235{
fischman@webrtc.org42694c52014-06-06 18:28:28 +0000236 CriticalSectionScoped cs(&_apiCs);
237 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000238
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000239 const int32_t width = frameInfo.width;
240 const int32_t height = frameInfo.height;
niklase@google.com470e71d2011-07-07 08:21:25 +0000241
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000242 TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime);
243
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000244 if (frameInfo.codecType == kVideoCodecUnknown)
niklase@google.com470e71d2011-07-07 08:21:25 +0000245 {
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000246 // Not encoded, convert to I420.
mikhal@webrtc.orge39de162011-12-27 23:45:30 +0000247 const VideoType commonVideoType =
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000248 RawVideoTypeToCommonVideoVideoType(frameInfo.rawType);
249
250 if (frameInfo.rawType != kVideoMJPEG &&
elham@webrtc.org5f49dba2012-04-23 21:24:02 +0000251 CalcBufferSize(commonVideoType, width,
252 abs(height)) != videoFrameLength)
niklase@google.com470e71d2011-07-07 08:21:25 +0000253 {
pbos@webrtc.org3d5cb332014-05-14 08:42:07 +0000254 LOG(LS_ERROR) << "Wrong incoming frame length.";
niklase@google.com470e71d2011-07-07 08:21:25 +0000255 return -1;
256 }
257
mikhal@webrtc.org4c4d01d2012-11-21 22:18:32 +0000258 int stride_y = width;
259 int stride_uv = (width + 1) / 2;
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000260 int target_width = width;
261 int target_height = height;
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000262
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700263 // SetApplyRotation doesn't take any lock. Make a local copy here.
264 bool apply_rotation = apply_rotation_;
265
266 if (apply_rotation) {
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000267 // Rotating resolution when for 90/270 degree rotations.
guoweis@webrtc.org59140d62015-03-09 17:07:31 +0000268 if (_rotateFrame == kVideoRotation_90 ||
269 _rotateFrame == kVideoRotation_270) {
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000270 target_width = abs(height);
271 target_height = width;
272 }
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000273 }
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000274
mikhal@webrtc.org4c4d01d2012-11-21 22:18:32 +0000275 // TODO(mikhal): Update correct aligned stride values.
276 //Calc16ByteAlignedStride(target_width, &stride_y, &stride_uv);
mikhal@webrtc.org2f4ff892012-09-24 21:09:54 +0000277 // Setting absolute height (in case it was negative).
278 // In Windows, the image starts bottom left, instead of top left.
279 // Setting a negative source height, inverts the image (within LibYuv).
Niels Möller739fcb92016-02-29 13:11:45 +0100280 _captureFrame.CreateEmptyFrame(target_width,
281 abs(target_height),
282 stride_y,
283 stride_uv, stride_uv);
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000284 const int conversionResult = ConvertToI420(
285 commonVideoType, videoFrame, 0, 0, // No cropping
286 width, height, videoFrameLength,
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700287 apply_rotation ? _rotateFrame : kVideoRotation_0, &_captureFrame);
mikhal@webrtc.org2ab104e2011-12-09 02:46:22 +0000288 if (conversionResult < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000289 {
pbos@webrtc.org3d5cb332014-05-14 08:42:07 +0000290 LOG(LS_ERROR) << "Failed to convert capture frame from type "
291 << frameInfo.rawType << "to I420.";
niklase@google.com470e71d2011-07-07 08:21:25 +0000292 return -1;
293 }
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000294
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700295 if (!apply_rotation) {
guoweis@webrtc.org59140d62015-03-09 17:07:31 +0000296 _captureFrame.set_rotation(_rotateFrame);
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000297 } else {
298 _captureFrame.set_rotation(kVideoRotation_0);
299 }
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000300 _captureFrame.set_ntp_time_ms(captureTime);
Niels Möllerd28db7f2016-05-10 16:31:47 +0200301 _captureFrame.set_render_time_ms(rtc::TimeMillis());
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000302
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000303 DeliverCapturedFrame(_captureFrame);
niklase@google.com470e71d2011-07-07 08:21:25 +0000304 }
305 else // Encoded format
306 {
mflodman@webrtc.org3ba883f2013-06-07 13:57:57 +0000307 assert(false);
308 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 }
310
niklase@google.com470e71d2011-07-07 08:21:25 +0000311 return 0;
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000312}
niklase@google.com470e71d2011-07-07 08:21:25 +0000313
guoweis@webrtc.org5a7dc392015-02-13 14:31:26 +0000314int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) {
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000315 CriticalSectionScoped cs(&_apiCs);
316 CriticalSectionScoped cs2(&_callBackCs);
guoweis@webrtc.org59140d62015-03-09 17:07:31 +0000317 _rotateFrame = rotation;
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000318 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000319}
320
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000321void VideoCaptureImpl::EnableFrameRateCallback(const bool enable) {
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000322 CriticalSectionScoped cs(&_apiCs);
323 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 _frameRateCallBack = enable;
325 if (enable)
326 {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200327 _lastFrameRateCallbackTimeNanos = rtc::TimeNanos();
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000329}
330
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000331bool VideoCaptureImpl::SetApplyRotation(bool enable) {
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700332 // We can't take any lock here as it'll cause deadlock with IncomingFrame.
333
guoweis@webrtc.org1226e922015-02-11 18:37:54 +0000334 // The effect of this is the last caller wins.
335 apply_rotation_ = enable;
336 return true;
337}
338
mallinath@webrtc.org7433a082014-01-29 00:56:02 +0000339void VideoCaptureImpl::EnableNoPictureAlarm(const bool enable) {
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000340 CriticalSectionScoped cs(&_apiCs);
341 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 _noPictureAlarmCallBack = enable;
niklase@google.com470e71d2011-07-07 08:21:25 +0000343}
344
345void VideoCaptureImpl::UpdateFrameCount()
346{
Niels Möllerd28db7f2016-05-10 16:31:47 +0200347 if (_incomingFrameTimesNanos[0] / rtc::kNumNanosecsPerMicrosec == 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 {
349 // first no shift
350 }
351 else
352 {
353 // shift
354 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--)
355 {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200356 _incomingFrameTimesNanos[i + 1] = _incomingFrameTimesNanos[i];
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 }
358 }
Niels Möllerd28db7f2016-05-10 16:31:47 +0200359 _incomingFrameTimesNanos[0] = rtc::TimeNanos();
niklase@google.com470e71d2011-07-07 08:21:25 +0000360}
361
Niels Möllerd28db7f2016-05-10 16:31:47 +0200362uint32_t VideoCaptureImpl::CalculateFrameRate(int64_t now_ns)
niklase@google.com470e71d2011-07-07 08:21:25 +0000363{
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000364 int32_t num = 0;
365 int32_t nrOfFrames = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000366 for (num = 1; num < (kFrameRateCountHistorySize - 1); num++)
367 {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200368 if (_incomingFrameTimesNanos[num] <= 0 ||
369 (now_ns - _incomingFrameTimesNanos[num]) /
370 rtc::kNumNanosecsPerMillisec >
371 kFrameRateHistoryWindowMs) // don't use data older than 2sec
niklase@google.com470e71d2011-07-07 08:21:25 +0000372 {
373 break;
374 }
375 else
376 {
377 nrOfFrames++;
378 }
379 }
380 if (num > 1)
381 {
Niels Möllerd28db7f2016-05-10 16:31:47 +0200382 int64_t diff = (now_ns - _incomingFrameTimesNanos[num - 1]) /
383 rtc::kNumNanosecsPerMillisec;
niklase@google.com470e71d2011-07-07 08:21:25 +0000384 if (diff > 0)
385 {
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000386 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f);
niklase@google.com470e71d2011-07-07 08:21:25 +0000387 }
388 }
389
390 return nrOfFrames;
391}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000392} // namespace videocapturemodule
393} // namespace webrtc