blob: 886cc975385e30794a78ce1eed818c0717d07914 [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
11#include "video_capture_impl.h"
mikhal@webrtc.orge39de162011-12-27 23:45:30 +000012
andrew@webrtc.orgc1354bd2012-07-27 18:21:16 +000013#include "common_video/libyuv/include/webrtc_libyuv.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000014#include "critical_section_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000015#include "module_common_types.h"
perkj@webrtc.org0cc68dc2011-09-12 08:53:36 +000016#include "ref_count.h"
mikhal@webrtc.orge39de162011-12-27 23:45:30 +000017#include "tick_util.h"
18#include "trace.h"
hclam@chromium.org806dc3b2013-04-09 19:54:10 +000019#include "trace_event.h"
mikhal@webrtc.orge39de162011-12-27 23:45:30 +000020#include "video_capture_config.h"
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +000021#include "webrtc/system_wrappers/interface/clock.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000022
elham@webrtc.org5f49dba2012-04-23 21:24:02 +000023#include <stdlib.h>
24
niklase@google.com470e71d2011-07-07 08:21:25 +000025namespace webrtc
26{
perkj@webrtc.org0cc68dc2011-09-12 08:53:36 +000027namespace videocapturemodule
niklase@google.com470e71d2011-07-07 08:21:25 +000028{
perkj@webrtc.org0cc68dc2011-09-12 08:53:36 +000029VideoCaptureModule* VideoCaptureImpl::Create(
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000030 const int32_t id,
perkj@webrtc.org0cc68dc2011-09-12 08:53:36 +000031 VideoCaptureExternal*& externalCapture)
32{
33 RefCountImpl<VideoCaptureImpl>* implementation =
34 new RefCountImpl<VideoCaptureImpl>(id);
niklase@google.com470e71d2011-07-07 08:21:25 +000035 externalCapture = implementation;
36 return implementation;
37}
38
leozwang@webrtc.org1745e932012-03-01 16:30:40 +000039const char* VideoCaptureImpl::CurrentDeviceName() const
niklase@google.com470e71d2011-07-07 08:21:25 +000040{
41 return _deviceUniqueId;
42}
43
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000044int32_t VideoCaptureImpl::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000045{
46 _id = id;
47 return 0;
48}
49
50// returns the number of milliseconds until the module want a worker thread to call Process
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000051int32_t VideoCaptureImpl::TimeUntilNextProcess()
niklase@google.com470e71d2011-07-07 08:21:25 +000052{
perkj@webrtc.orgc2fde802012-08-08 14:01:09 +000053 CriticalSectionScoped cs(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +000054
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000055 int32_t timeToNormalProcess = kProcessInterval
56 - (int32_t)((TickTime::Now() - _lastProcessTime).Milliseconds());
mikhal@webrtc.org9a5b9042012-10-19 16:44:35 +000057
58 return timeToNormalProcess;
niklase@google.com470e71d2011-07-07 08:21:25 +000059}
60
61// Process any pending tasks such as timeouts
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000062int32_t VideoCaptureImpl::Process()
niklase@google.com470e71d2011-07-07 08:21:25 +000063{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +000064 CriticalSectionScoped cs(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +000065
66 const TickTime now = TickTime::Now();
67 _lastProcessTime = TickTime::Now();
68
69 // Handle No picture alarm
70
71 if (_lastProcessFrameCount.Ticks() == _incomingFrameTimes[0].Ticks() &&
72 _captureAlarm != Raised)
73 {
74 if (_noPictureAlarmCallBack && _captureCallBack)
75 {
76 _captureAlarm = Raised;
77 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm);
78 }
79 }
80 else if (_lastProcessFrameCount.Ticks() != _incomingFrameTimes[0].Ticks() &&
81 _captureAlarm != Cleared)
82 {
83 if (_noPictureAlarmCallBack && _captureCallBack)
84 {
85 _captureAlarm = Cleared;
86 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm);
87
88 }
89 }
90
91 // Handle frame rate callback
92 if ((now - _lastFrameRateCallbackTime).Milliseconds()
93 > kFrameRateCallbackInterval)
94 {
95 if (_frameRateCallBack && _captureCallBack)
96 {
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +000097 const uint32_t frameRate = CalculateFrameRate(now);
niklase@google.com470e71d2011-07-07 08:21:25 +000098 _captureCallBack->OnCaptureFrameRate(_id, frameRate);
99 }
100 _lastFrameRateCallbackTime = now; // Can be set by EnableFrameRateCallback
101
102 }
103
104 _lastProcessFrameCount = _incomingFrameTimes[0];
105
niklase@google.com470e71d2011-07-07 08:21:25 +0000106 return 0;
107}
108
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000109VideoCaptureImpl::VideoCaptureImpl(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 : _id(id), _deviceUniqueId(NULL), _apiCs(*CriticalSectionWrapper::CreateCriticalSection()),
111 _captureDelay(0), _requestedCapability(),
112 _callBackCs(*CriticalSectionWrapper::CreateCriticalSection()),
113 _lastProcessTime(TickTime::Now()),
114 _lastFrameRateCallbackTime(TickTime::Now()), _frameRateCallBack(false),
115 _noPictureAlarmCallBack(false), _captureAlarm(Cleared), _setCaptureDelay(0),
mallinath@webrtc.org12984f02012-02-16 18:18:21 +0000116 _dataCallBack(NULL), _captureCallBack(NULL),
mflodman@webrtc.org29d75b32011-11-01 17:10:49 +0000117 _lastProcessFrameCount(TickTime::Now()), _rotateFrame(kRotateNone),
118 last_capture_time_(TickTime::MillisecondTimestamp())
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
120{
121 _requestedCapability.width = kDefaultWidth;
122 _requestedCapability.height = kDefaultHeight;
123 _requestedCapability.maxFPS = 30;
124 _requestedCapability.rawType = kVideoI420;
125 _requestedCapability.codecType = kVideoCodecUnknown;
126 memset(_incomingFrameTimes, 0, sizeof(_incomingFrameTimes));
127}
128
129VideoCaptureImpl::~VideoCaptureImpl()
130{
131 DeRegisterCaptureDataCallback();
132 DeRegisterCaptureCallback();
133 delete &_callBackCs;
134 delete &_apiCs;
135
136 if (_deviceUniqueId)
137 delete[] _deviceUniqueId;
138}
139
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000140int32_t VideoCaptureImpl::RegisterCaptureDataCallback(
niklase@google.com470e71d2011-07-07 08:21:25 +0000141 VideoCaptureDataCallback& dataCallBack)
142{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000143 CriticalSectionScoped cs(&_apiCs);
144 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000145 _dataCallBack = &dataCallBack;
146
147 return 0;
148}
149
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000150int32_t VideoCaptureImpl::DeRegisterCaptureDataCallback()
niklase@google.com470e71d2011-07-07 08:21:25 +0000151{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000152 CriticalSectionScoped cs(&_apiCs);
153 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000154 _dataCallBack = NULL;
155 return 0;
156}
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000157int32_t VideoCaptureImpl::RegisterCaptureCallback(VideoCaptureFeedBack& callBack)
niklase@google.com470e71d2011-07-07 08:21:25 +0000158{
niklase@google.com470e71d2011-07-07 08:21:25 +0000159
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000160 CriticalSectionScoped cs(&_apiCs);
161 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000162 _captureCallBack = &callBack;
163 return 0;
164}
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000165int32_t VideoCaptureImpl::DeRegisterCaptureCallback()
niklase@google.com470e71d2011-07-07 08:21:25 +0000166{
niklase@google.com470e71d2011-07-07 08:21:25 +0000167
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000168 CriticalSectionScoped cs(&_apiCs);
169 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000170 _captureCallBack = NULL;
171 return 0;
172
173}
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000174int32_t VideoCaptureImpl::SetCaptureDelay(int32_t delayMS)
niklase@google.com470e71d2011-07-07 08:21:25 +0000175{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000176 CriticalSectionScoped cs(&_apiCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000177 _captureDelay = delayMS;
178 return 0;
179}
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000180int32_t VideoCaptureImpl::CaptureDelay()
niklase@google.com470e71d2011-07-07 08:21:25 +0000181{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000182 CriticalSectionScoped cs(&_apiCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000183 return _setCaptureDelay;
184}
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000185
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000186int32_t VideoCaptureImpl::DeliverCapturedFrame(I420VideoFrame& captureFrame,
187 int64_t capture_time) {
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000188 UpdateFrameCount(); // frame count used for local frame rate callback.
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000189
190 const bool callOnCaptureDelayChanged = _setCaptureDelay != _captureDelay;
191 // Capture delay changed
192 if (_setCaptureDelay != _captureDelay) {
193 _setCaptureDelay = _captureDelay;
194 }
195
196 // Set the capture time
stefan@webrtc.orgcb60fb22013-04-24 23:54:31 +0000197 const int64_t ntp_time_ms =
198 Clock::GetRealTimeClock()->CurrentNtpInMilliseconds();
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000199 int64_t internal_capture_time = TickTime::MillisecondTimestamp();
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000200 if (capture_time != 0) {
stefan@webrtc.orgcb60fb22013-04-24 23:54:31 +0000201 int64_t time_since_capture = ntp_time_ms - capture_time;
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000202 internal_capture_time -= time_since_capture;
203 captureFrame.set_render_time_ms(internal_capture_time);
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000204 }
205 else {
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000206 captureFrame.set_render_time_ms(internal_capture_time);
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000207 }
208
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000209 TRACE_EVENT1("webrtc", "VC::DeliverCapturedFrame",
210 "capture_time", capture_time);
211
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000212 if (captureFrame.render_time_ms() == last_capture_time_) {
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000213 // We don't allow the same capture time for two frames, drop this one.
214 return -1;
215 }
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000216 last_capture_time_ = captureFrame.render_time_ms();
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000217
218 if (_dataCallBack) {
219 if (callOnCaptureDelayChanged) {
220 _dataCallBack->OnCaptureDelayChanged(_id, _captureDelay);
221 }
mikhal@webrtc.orge83d3112012-10-29 15:59:40 +0000222 _dataCallBack->OnIncomingCapturedFrame(_id, captureFrame);
mikhal@webrtc.org80f14d22012-10-11 15:03:53 +0000223 }
224
225 return 0;
226}
227
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000228int32_t VideoCaptureImpl::IncomingFrame(
229 uint8_t* videoFrame,
230 int32_t videoFrameLength,
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000231 const VideoCaptureCapability& frameInfo,
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000232 int64_t captureTime/*=0*/)
niklase@google.com470e71d2011-07-07 08:21:25 +0000233{
234 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceVideoCapture, _id,
235 "IncomingFrame width %d, height %d", (int) frameInfo.width,
236 (int) frameInfo.height);
237
238 TickTime startProcessTime = TickTime::Now();
239
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000240 CriticalSectionScoped cs(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000241
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000242 const int32_t width = frameInfo.width;
243 const int32_t height = frameInfo.height;
niklase@google.com470e71d2011-07-07 08:21:25 +0000244
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000245 TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime);
246
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000247 if (frameInfo.codecType == kVideoCodecUnknown)
niklase@google.com470e71d2011-07-07 08:21:25 +0000248 {
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000249 // Not encoded, convert to I420.
mikhal@webrtc.orge39de162011-12-27 23:45:30 +0000250 const VideoType commonVideoType =
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000251 RawVideoTypeToCommonVideoVideoType(frameInfo.rawType);
252
253 if (frameInfo.rawType != kVideoMJPEG &&
elham@webrtc.org5f49dba2012-04-23 21:24:02 +0000254 CalcBufferSize(commonVideoType, width,
255 abs(height)) != videoFrameLength)
niklase@google.com470e71d2011-07-07 08:21:25 +0000256 {
257 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
mflodman@webrtc.org4f9e44f2012-02-23 09:00:26 +0000258 "Wrong incoming frame length.");
niklase@google.com470e71d2011-07-07 08:21:25 +0000259 return -1;
260 }
261
mikhal@webrtc.org4c4d01d2012-11-21 22:18:32 +0000262 int stride_y = width;
263 int stride_uv = (width + 1) / 2;
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000264 int target_width = width;
265 int target_height = height;
266 // Rotating resolution when for 90/270 degree rotations.
267 if (_rotateFrame == kRotate90 || _rotateFrame == kRotate270) {
268 target_width = abs(height);
269 target_height = width;
270 }
mikhal@webrtc.org4c4d01d2012-11-21 22:18:32 +0000271 // TODO(mikhal): Update correct aligned stride values.
272 //Calc16ByteAlignedStride(target_width, &stride_y, &stride_uv);
mikhal@webrtc.org2f4ff892012-09-24 21:09:54 +0000273 // Setting absolute height (in case it was negative).
274 // In Windows, the image starts bottom left, instead of top left.
275 // Setting a negative source height, inverts the image (within LibYuv).
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000276 int ret = _captureFrame.CreateEmptyFrame(target_width,
277 abs(target_height),
mikhal@webrtc.org91a03402012-10-30 19:19:32 +0000278 stride_y,
279 stride_uv, stride_uv);
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000280 if (ret < 0)
281 {
282 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
283 "Failed to allocate I420 frame.");
284 return -1;
285 }
mikhal@webrtc.orga58888d2012-01-04 19:23:24 +0000286 const int conversionResult = ConvertToI420(commonVideoType,
287 videoFrame,
288 0, 0, // No cropping
289 width, height,
mflodman@webrtc.orgf3811192012-02-27 08:10:17 +0000290 videoFrameLength,
mikhal@webrtc.orga58888d2012-01-04 19:23:24 +0000291 _rotateFrame,
mikhal@webrtc.org2f4ff892012-09-24 21:09:54 +0000292 &_captureFrame);
mikhal@webrtc.org2ab104e2011-12-09 02:46:22 +0000293 if (conversionResult < 0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000294 {
295 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
296 "Failed to convert capture frame from type %d to I420",
297 frameInfo.rawType);
298 return -1;
299 }
mikhal@webrtc.orge83d3112012-10-29 15:59:40 +0000300 DeliverCapturedFrame(_captureFrame, captureTime);
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 }
302 else // Encoded format
303 {
mflodman@webrtc.org3ba883f2013-06-07 13:57:57 +0000304 assert(false);
305 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000306 }
307
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000308 const uint32_t processTime =
309 (uint32_t)(TickTime::Now() - startProcessTime).Milliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000310 if (processTime > 10) // If the process time is too long MJPG will not work well.
311 {
312 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id,
313 "Too long processing time of Incoming frame: %ums",
314 (unsigned int) processTime);
315 }
316
317 return 0;
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000318}
niklase@google.com470e71d2011-07-07 08:21:25 +0000319
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000320int32_t VideoCaptureImpl::IncomingFrameI420(
321 const VideoFrameI420& video_frame, int64_t captureTime) {
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000322
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000323 CriticalSectionScoped cs(&_callBackCs);
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000324 int size_y = video_frame.height * video_frame.y_pitch;
mikhal@webrtc.org701567a2012-11-09 18:45:12 +0000325 int size_u = video_frame.u_pitch * ((video_frame.height + 1) / 2);
326 int size_v = video_frame.v_pitch * ((video_frame.height + 1) / 2);
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000327 // TODO(mikhal): Can we use Swap here? This will do a memcpy.
328 int ret = _captureFrame.CreateFrame(size_y, video_frame.y_plane,
329 size_u, video_frame.u_plane,
330 size_v, video_frame.v_plane,
331 video_frame.width, video_frame.height,
332 video_frame.y_pitch, video_frame.u_pitch,
333 video_frame.v_pitch);
334 if (ret < 0) {
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000335 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000336 "Failed to create I420VideoFrame");
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000337 return -1;
338 }
339
mikhal@webrtc.orge83d3112012-10-29 15:59:40 +0000340 DeliverCapturedFrame(_captureFrame, captureTime);
wu@webrtc.orgf10ea312011-10-14 17:16:04 +0000341
342 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000343}
344
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000345int32_t VideoCaptureImpl::SetCaptureRotation(VideoCaptureRotation rotation) {
mikhal@webrtc.org0f34fd72012-11-19 21:15:35 +0000346 CriticalSectionScoped cs(&_apiCs);
347 CriticalSectionScoped cs2(&_callBackCs);
348 switch (rotation){
349 case kCameraRotate0:
350 _rotateFrame = kRotateNone;
351 break;
352 case kCameraRotate90:
353 _rotateFrame = kRotate90;
354 break;
355 case kCameraRotate180:
356 _rotateFrame = kRotate180;
357 break;
358 case kCameraRotate270:
359 _rotateFrame = kRotate270;
360 break;
361 }
362 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000363}
364
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000365int32_t VideoCaptureImpl::EnableFrameRateCallback(const bool enable)
niklase@google.com470e71d2011-07-07 08:21:25 +0000366{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000367 CriticalSectionScoped cs(&_apiCs);
368 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000369 _frameRateCallBack = enable;
370 if (enable)
371 {
372 _lastFrameRateCallbackTime = TickTime::Now();
373 }
374 return 0;
375}
376
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000377int32_t VideoCaptureImpl::EnableNoPictureAlarm(const bool enable)
niklase@google.com470e71d2011-07-07 08:21:25 +0000378{
mflodman@webrtc.org7845d072012-03-08 08:09:17 +0000379 CriticalSectionScoped cs(&_apiCs);
380 CriticalSectionScoped cs2(&_callBackCs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000381 _noPictureAlarmCallBack = enable;
382 return 0;
383}
384
385void VideoCaptureImpl::UpdateFrameCount()
386{
387 if (_incomingFrameTimes[0].MicrosecondTimestamp() == 0)
388 {
389 // first no shift
390 }
391 else
392 {
393 // shift
394 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--)
395 {
396 _incomingFrameTimes[i + 1] = _incomingFrameTimes[i];
397 }
398 }
399 _incomingFrameTimes[0] = TickTime::Now();
400}
401
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000402uint32_t VideoCaptureImpl::CalculateFrameRate(const TickTime& now)
niklase@google.com470e71d2011-07-07 08:21:25 +0000403{
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000404 int32_t num = 0;
405 int32_t nrOfFrames = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000406 for (num = 1; num < (kFrameRateCountHistorySize - 1); num++)
407 {
408 if (_incomingFrameTimes[num].Ticks() <= 0
409 || (now - _incomingFrameTimes[num]).Milliseconds() > kFrameRateHistoryWindowMs) // don't use data older than 2sec
410 {
411 break;
412 }
413 else
414 {
415 nrOfFrames++;
416 }
417 }
418 if (num > 1)
419 {
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000420 int64_t diff = (now - _incomingFrameTimes[num - 1]).Milliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000421 if (diff > 0)
422 {
pbos@webrtc.orgdfc5bb92013-04-10 08:23:13 +0000423 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f);
niklase@google.com470e71d2011-07-07 08:21:25 +0000424 }
425 }
426
427 return nrOfFrames;
428}
perkj@webrtc.org0cc68dc2011-09-12 08:53:36 +0000429} // namespace videocapturemodule
niklase@google.com470e71d2011-07-07 08:21:25 +0000430} // namespace webrtc