| 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/timeutils.h" |
| 17 #include "webrtc/base/trace_event.h" | 17 #include "webrtc/base/trace_event.h" |
| 18 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" | 18 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" |
| 19 #include "webrtc/modules/include/module_common_types.h" | 19 #include "webrtc/modules/include/module_common_types.h" |
| 20 #include "webrtc/modules/video_capture/video_capture_config.h" | 20 #include "webrtc/modules/video_capture/video_capture_config.h" |
| 21 #include "webrtc/system_wrappers/include/clock.h" | 21 #include "webrtc/system_wrappers/include/clock.h" |
| 22 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 22 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
| 23 #include "webrtc/system_wrappers/include/logging.h" | 23 #include "webrtc/system_wrappers/include/logging.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, | |
| 29 VideoCaptureExternal*& externalCapture) { | 28 VideoCaptureExternal*& externalCapture) { |
| 30 rtc::scoped_refptr<VideoCaptureImpl> implementation( | 29 rtc::scoped_refptr<VideoCaptureImpl> implementation( |
| 31 new rtc::RefCountedObject<VideoCaptureImpl>(id)); | 30 new rtc::RefCountedObject<VideoCaptureImpl>()); |
| 32 externalCapture = implementation.get(); | 31 externalCapture = implementation.get(); |
| 33 return implementation; | 32 return implementation; |
| 34 } | 33 } |
| 35 | 34 |
| 36 const char* VideoCaptureImpl::CurrentDeviceName() const | 35 const char* VideoCaptureImpl::CurrentDeviceName() const |
| 37 { | 36 { |
| 38 return _deviceUniqueId; | 37 return _deviceUniqueId; |
| 39 } | 38 } |
| 40 | 39 |
| 41 // static | 40 // static |
| (...skipping 30 matching lines...) Expand all Loading... |
| 72 case kVideoRotation_180: | 71 case kVideoRotation_180: |
| 73 *degrees = 180; | 72 *degrees = 180; |
| 74 return 0; | 73 return 0; |
| 75 case kVideoRotation_270: | 74 case kVideoRotation_270: |
| 76 *degrees = 270; | 75 *degrees = 270; |
| 77 return 0; | 76 return 0; |
| 78 } | 77 } |
| 79 return -1; | 78 return -1; |
| 80 } | 79 } |
| 81 | 80 |
| 82 // returns the number of milliseconds until the module want a worker thread to c
all Process | 81 VideoCaptureImpl::VideoCaptureImpl() |
| 83 int64_t VideoCaptureImpl::TimeUntilNextProcess() | 82 : _deviceUniqueId(NULL), |
| 84 { | |
| 85 CriticalSectionScoped cs(&_callBackCs); | |
| 86 const int64_t kProcessIntervalMs = 300; | |
| 87 return kProcessIntervalMs - | |
| 88 (rtc::TimeNanos() - _lastProcessTimeNanos) / | |
| 89 rtc::kNumNanosecsPerMillisec; | |
| 90 } | |
| 91 | |
| 92 // Process any pending tasks such as timeouts | |
| 93 void VideoCaptureImpl::Process() | |
| 94 { | |
| 95 CriticalSectionScoped cs(&_callBackCs); | |
| 96 | |
| 97 const int64_t now_ns = rtc::TimeNanos(); | |
| 98 _lastProcessTimeNanos = rtc::TimeNanos(); | |
| 99 | |
| 100 // Handle No picture alarm | |
| 101 | |
| 102 if (_lastProcessFrameTimeNanos == _incomingFrameTimesNanos[0] && | |
| 103 _captureAlarm != Raised) | |
| 104 { | |
| 105 if (_noPictureAlarmCallBack && _captureCallBack) | |
| 106 { | |
| 107 _captureAlarm = Raised; | |
| 108 _captureCallBack->OnNoPictureAlarm(_id, _captureAlarm); | |
| 109 } | |
| 110 } | |
| 111 else if (_lastProcessFrameTimeNanos != _incomingFrameTimesNanos[0] && | |
| 112 _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 | |
| 123 if ((now_ns - _lastFrameRateCallbackTimeNanos) / | |
| 124 rtc::kNumNanosecsPerMillisec | |
| 125 > kFrameRateCallbackInterval) | |
| 126 { | |
| 127 if (_frameRateCallBack && _captureCallBack) | |
| 128 { | |
| 129 const uint32_t frameRate = CalculateFrameRate(now_ns); | |
| 130 _captureCallBack->OnCaptureFrameRate(_id, frameRate); | |
| 131 } | |
| 132 // Can be set by EnableFrameRateCallback | |
| 133 _lastFrameRateCallbackTimeNanos = now_ns; | |
| 134 | |
| 135 } | |
| 136 | |
| 137 _lastProcessFrameTimeNanos = _incomingFrameTimesNanos[0]; | |
| 138 } | |
| 139 | |
| 140 VideoCaptureImpl::VideoCaptureImpl(const int32_t id) | |
| 141 : _id(id), | |
| 142 _deviceUniqueId(NULL), | |
| 143 _apiCs(*CriticalSectionWrapper::CreateCriticalSection()), | 83 _apiCs(*CriticalSectionWrapper::CreateCriticalSection()), |
| 144 _captureDelay(0), | 84 _captureDelay(0), |
| 145 _requestedCapability(), | 85 _requestedCapability(), |
| 146 _callBackCs(*CriticalSectionWrapper::CreateCriticalSection()), | |
| 147 _lastProcessTimeNanos(rtc::TimeNanos()), | 86 _lastProcessTimeNanos(rtc::TimeNanos()), |
| 148 _lastFrameRateCallbackTimeNanos(rtc::TimeNanos()), | 87 _lastFrameRateCallbackTimeNanos(rtc::TimeNanos()), |
| 149 _frameRateCallBack(false), | |
| 150 _noPictureAlarmCallBack(false), | |
| 151 _captureAlarm(Cleared), | |
| 152 _setCaptureDelay(0), | |
| 153 _dataCallBack(NULL), | 88 _dataCallBack(NULL), |
| 154 _captureCallBack(NULL), | |
| 155 _lastProcessFrameTimeNanos(rtc::TimeNanos()), | 89 _lastProcessFrameTimeNanos(rtc::TimeNanos()), |
| 156 _rotateFrame(kVideoRotation_0), | 90 _rotateFrame(kVideoRotation_0), |
| 157 apply_rotation_(false) { | 91 apply_rotation_(false) { |
| 158 _requestedCapability.width = kDefaultWidth; | 92 _requestedCapability.width = kDefaultWidth; |
| 159 _requestedCapability.height = kDefaultHeight; | 93 _requestedCapability.height = kDefaultHeight; |
| 160 _requestedCapability.maxFPS = 30; | 94 _requestedCapability.maxFPS = 30; |
| 161 _requestedCapability.rawType = kVideoI420; | 95 _requestedCapability.rawType = kVideoI420; |
| 162 _requestedCapability.codecType = kVideoCodecUnknown; | 96 _requestedCapability.codecType = kVideoCodecUnknown; |
| 163 memset(_incomingFrameTimesNanos, 0, sizeof(_incomingFrameTimesNanos)); | 97 memset(_incomingFrameTimesNanos, 0, sizeof(_incomingFrameTimesNanos)); |
| 164 } | 98 } |
| 165 | 99 |
| 166 VideoCaptureImpl::~VideoCaptureImpl() | 100 VideoCaptureImpl::~VideoCaptureImpl() |
| 167 { | 101 { |
| 168 DeRegisterCaptureDataCallback(); | 102 DeRegisterCaptureDataCallback(); |
| 169 DeRegisterCaptureCallback(); | |
| 170 delete &_callBackCs; | |
| 171 delete &_apiCs; | 103 delete &_apiCs; |
| 172 | 104 |
| 173 if (_deviceUniqueId) | 105 if (_deviceUniqueId) |
| 174 delete[] _deviceUniqueId; | 106 delete[] _deviceUniqueId; |
| 175 } | 107 } |
| 176 | 108 |
| 177 void VideoCaptureImpl::RegisterCaptureDataCallback( | 109 void VideoCaptureImpl::RegisterCaptureDataCallback( |
| 178 VideoCaptureDataCallback& dataCallBack) { | 110 rtc::VideoSinkInterface<VideoFrame>* dataCallBack) { |
| 179 CriticalSectionScoped cs(&_apiCs); | 111 CriticalSectionScoped cs(&_apiCs); |
| 180 CriticalSectionScoped cs2(&_callBackCs); | 112 _dataCallBack = dataCallBack; |
| 181 _dataCallBack = &dataCallBack; | |
| 182 } | 113 } |
| 183 | 114 |
| 184 void VideoCaptureImpl::DeRegisterCaptureDataCallback() { | 115 void VideoCaptureImpl::DeRegisterCaptureDataCallback() { |
| 185 CriticalSectionScoped cs(&_apiCs); | 116 CriticalSectionScoped cs(&_apiCs); |
| 186 CriticalSectionScoped cs2(&_callBackCs); | |
| 187 _dataCallBack = NULL; | 117 _dataCallBack = NULL; |
| 188 } | 118 } |
| 189 void VideoCaptureImpl::RegisterCaptureCallback(VideoCaptureFeedBack& callBack) { | |
| 190 | |
| 191 CriticalSectionScoped cs(&_apiCs); | |
| 192 CriticalSectionScoped cs2(&_callBackCs); | |
| 193 _captureCallBack = &callBack; | |
| 194 } | |
| 195 void VideoCaptureImpl::DeRegisterCaptureCallback() { | |
| 196 | |
| 197 CriticalSectionScoped cs(&_apiCs); | |
| 198 CriticalSectionScoped cs2(&_callBackCs); | |
| 199 _captureCallBack = NULL; | |
| 200 } | |
| 201 void VideoCaptureImpl::SetCaptureDelay(int32_t delayMS) { | |
| 202 CriticalSectionScoped cs(&_apiCs); | |
| 203 _captureDelay = delayMS; | |
| 204 } | |
| 205 int32_t VideoCaptureImpl::CaptureDelay() | |
| 206 { | |
| 207 CriticalSectionScoped cs(&_apiCs); | |
| 208 return _setCaptureDelay; | |
| 209 } | |
| 210 | |
| 211 int32_t VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame) { | 119 int32_t VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame) { |
| 212 UpdateFrameCount(); // frame count used for local frame rate callback. | 120 UpdateFrameCount(); // frame count used for local frame rate callback. |
| 213 | 121 |
| 214 const bool callOnCaptureDelayChanged = _setCaptureDelay != _captureDelay; | |
| 215 // Capture delay changed | |
| 216 if (_setCaptureDelay != _captureDelay) { | |
| 217 _setCaptureDelay = _captureDelay; | |
| 218 } | |
| 219 | |
| 220 if (_dataCallBack) { | 122 if (_dataCallBack) { |
| 221 if (callOnCaptureDelayChanged) { | 123 _dataCallBack->OnFrame(captureFrame); |
| 222 _dataCallBack->OnCaptureDelayChanged(_id, _captureDelay); | |
| 223 } | |
| 224 _dataCallBack->OnIncomingCapturedFrame(_id, captureFrame); | |
| 225 } | 124 } |
| 226 | 125 |
| 227 return 0; | 126 return 0; |
| 228 } | 127 } |
| 229 | 128 |
| 230 int32_t VideoCaptureImpl::IncomingFrame( | 129 int32_t VideoCaptureImpl::IncomingFrame( |
| 231 uint8_t* videoFrame, | 130 uint8_t* videoFrame, |
| 232 size_t videoFrameLength, | 131 size_t videoFrameLength, |
| 233 const VideoCaptureCapability& frameInfo, | 132 const VideoCaptureCapability& frameInfo, |
| 234 int64_t captureTime/*=0*/) | 133 int64_t captureTime/*=0*/) |
| 235 { | 134 { |
| 236 CriticalSectionScoped cs(&_apiCs); | 135 CriticalSectionScoped cs(&_apiCs); |
| 237 CriticalSectionScoped cs2(&_callBackCs); | |
| 238 | 136 |
| 239 const int32_t width = frameInfo.width; | 137 const int32_t width = frameInfo.width; |
| 240 const int32_t height = frameInfo.height; | 138 const int32_t height = frameInfo.height; |
| 241 | 139 |
| 242 TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime); | 140 TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime); |
| 243 | 141 |
| 244 if (frameInfo.codecType == kVideoCodecUnknown) | 142 if (frameInfo.codecType == kVideoCodecUnknown) |
| 245 { | 143 { |
| 246 // Not encoded, convert to I420. | 144 // Not encoded, convert to I420. |
| 247 const VideoType commonVideoType = | 145 const VideoType commonVideoType = |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 { | 199 { |
| 302 assert(false); | 200 assert(false); |
| 303 return -1; | 201 return -1; |
| 304 } | 202 } |
| 305 | 203 |
| 306 return 0; | 204 return 0; |
| 307 } | 205 } |
| 308 | 206 |
| 309 int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) { | 207 int32_t VideoCaptureImpl::SetCaptureRotation(VideoRotation rotation) { |
| 310 CriticalSectionScoped cs(&_apiCs); | 208 CriticalSectionScoped cs(&_apiCs); |
| 311 CriticalSectionScoped cs2(&_callBackCs); | |
| 312 _rotateFrame = rotation; | 209 _rotateFrame = rotation; |
| 313 return 0; | 210 return 0; |
| 314 } | 211 } |
| 315 | 212 |
| 316 void VideoCaptureImpl::EnableFrameRateCallback(const bool enable) { | |
| 317 CriticalSectionScoped cs(&_apiCs); | |
| 318 CriticalSectionScoped cs2(&_callBackCs); | |
| 319 _frameRateCallBack = enable; | |
| 320 if (enable) | |
| 321 { | |
| 322 _lastFrameRateCallbackTimeNanos = rtc::TimeNanos(); | |
| 323 } | |
| 324 } | |
| 325 | |
| 326 bool VideoCaptureImpl::SetApplyRotation(bool enable) { | 213 bool VideoCaptureImpl::SetApplyRotation(bool enable) { |
| 327 // We can't take any lock here as it'll cause deadlock with IncomingFrame. | 214 // We can't take any lock here as it'll cause deadlock with IncomingFrame. |
| 328 | 215 |
| 329 // The effect of this is the last caller wins. | 216 // The effect of this is the last caller wins. |
| 330 apply_rotation_ = enable; | 217 apply_rotation_ = enable; |
| 331 return true; | 218 return true; |
| 332 } | 219 } |
| 333 | 220 |
| 334 void VideoCaptureImpl::EnableNoPictureAlarm(const bool enable) { | |
| 335 CriticalSectionScoped cs(&_apiCs); | |
| 336 CriticalSectionScoped cs2(&_callBackCs); | |
| 337 _noPictureAlarmCallBack = enable; | |
| 338 } | |
| 339 | |
| 340 void VideoCaptureImpl::UpdateFrameCount() | 221 void VideoCaptureImpl::UpdateFrameCount() |
| 341 { | 222 { |
| 342 if (_incomingFrameTimesNanos[0] / rtc::kNumNanosecsPerMicrosec == 0) | 223 if (_incomingFrameTimesNanos[0] / rtc::kNumNanosecsPerMicrosec == 0) |
| 343 { | 224 { |
| 344 // first no shift | 225 // first no shift |
| 345 } | 226 } |
| 346 else | 227 else |
| 347 { | 228 { |
| 348 // shift | 229 // shift |
| 349 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--) | 230 for (int i = (kFrameRateCountHistorySize - 2); i >= 0; i--) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 379 if (diff > 0) | 260 if (diff > 0) |
| 380 { | 261 { |
| 381 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f); | 262 return uint32_t((nrOfFrames * 1000.0f / diff) + 0.5f); |
| 382 } | 263 } |
| 383 } | 264 } |
| 384 | 265 |
| 385 return nrOfFrames; | 266 return nrOfFrames; |
| 386 } | 267 } |
| 387 } // namespace videocapturemodule | 268 } // namespace videocapturemodule |
| 388 } // namespace webrtc | 269 } // namespace webrtc |
| OLD | NEW |