OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 set_frame_factory(new WebRtcVideoFrameFactory()); | 145 set_frame_factory(new WebRtcVideoFrameFactory()); |
146 } | 146 } |
147 | 147 |
148 WebRtcVideoCapturer::~WebRtcVideoCapturer() { | 148 WebRtcVideoCapturer::~WebRtcVideoCapturer() { |
149 if (module_) { | 149 if (module_) { |
150 module_->Release(); | 150 module_->Release(); |
151 } | 151 } |
152 } | 152 } |
153 | 153 |
154 bool WebRtcVideoCapturer::Init(const Device& device) { | 154 bool WebRtcVideoCapturer::Init(const Device& device) { |
155 DCHECK(!start_thread_); | 155 RTC_DCHECK(!start_thread_); |
156 if (module_) { | 156 if (module_) { |
157 LOG(LS_ERROR) << "The capturer is already initialized"; | 157 LOG(LS_ERROR) << "The capturer is already initialized"; |
158 return false; | 158 return false; |
159 } | 159 } |
160 | 160 |
161 webrtc::VideoCaptureModule::DeviceInfo* info = factory_->CreateDeviceInfo(0); | 161 webrtc::VideoCaptureModule::DeviceInfo* info = factory_->CreateDeviceInfo(0); |
162 if (!info) { | 162 if (!info) { |
163 return false; | 163 return false; |
164 } | 164 } |
165 | 165 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 SetId(device.id); | 219 SetId(device.id); |
220 SetSupportedFormats(supported); | 220 SetSupportedFormats(supported); |
221 | 221 |
222 // Ensure these 2 have the same value. | 222 // Ensure these 2 have the same value. |
223 SetApplyRotation(module_->GetApplyRotation()); | 223 SetApplyRotation(module_->GetApplyRotation()); |
224 | 224 |
225 return true; | 225 return true; |
226 } | 226 } |
227 | 227 |
228 bool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) { | 228 bool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) { |
229 DCHECK(!start_thread_); | 229 RTC_DCHECK(!start_thread_); |
230 if (module_) { | 230 if (module_) { |
231 LOG(LS_ERROR) << "The capturer is already initialized"; | 231 LOG(LS_ERROR) << "The capturer is already initialized"; |
232 return false; | 232 return false; |
233 } | 233 } |
234 if (!module) { | 234 if (!module) { |
235 LOG(LS_ERROR) << "Invalid VCM supplied"; | 235 LOG(LS_ERROR) << "Invalid VCM supplied"; |
236 return false; | 236 return false; |
237 } | 237 } |
238 // TODO(juberti): Set id and formats. | 238 // TODO(juberti): Set id and formats. |
239 (module_ = module)->AddRef(); | 239 (module_ = module)->AddRef(); |
(...skipping 16 matching lines...) Expand all Loading... |
256 LOG(LS_INFO) << "Failed to find best capture format," | 256 LOG(LS_INFO) << "Failed to find best capture format," |
257 << " fall back to the requested format " | 257 << " fall back to the requested format " |
258 << best_format->ToString(); | 258 << best_format->ToString(); |
259 } | 259 } |
260 return true; | 260 return true; |
261 } | 261 } |
262 bool WebRtcVideoCapturer::SetApplyRotation(bool enable) { | 262 bool WebRtcVideoCapturer::SetApplyRotation(bool enable) { |
263 // Can't take lock here as this will cause deadlock with | 263 // Can't take lock here as this will cause deadlock with |
264 // OnIncomingCapturedFrame. In fact, the whole method, including methods it | 264 // OnIncomingCapturedFrame. In fact, the whole method, including methods it |
265 // calls, can't take lock. | 265 // calls, can't take lock. |
266 DCHECK(module_); | 266 RTC_DCHECK(module_); |
267 | 267 |
268 const std::string group_name = | 268 const std::string group_name = |
269 webrtc::field_trial::FindFullName("WebRTC-CVO"); | 269 webrtc::field_trial::FindFullName("WebRTC-CVO"); |
270 | 270 |
271 if (group_name == "Disabled") { | 271 if (group_name == "Disabled") { |
272 return true; | 272 return true; |
273 } | 273 } |
274 | 274 |
275 if (!VideoCapturer::SetApplyRotation(enable)) { | 275 if (!VideoCapturer::SetApplyRotation(enable)) { |
276 return false; | 276 return false; |
277 } | 277 } |
278 return module_->SetApplyRotation(enable); | 278 return module_->SetApplyRotation(enable); |
279 } | 279 } |
280 | 280 |
281 CaptureState WebRtcVideoCapturer::Start(const VideoFormat& capture_format) { | 281 CaptureState WebRtcVideoCapturer::Start(const VideoFormat& capture_format) { |
282 if (!module_) { | 282 if (!module_) { |
283 LOG(LS_ERROR) << "The capturer has not been initialized"; | 283 LOG(LS_ERROR) << "The capturer has not been initialized"; |
284 return CS_NO_DEVICE; | 284 return CS_NO_DEVICE; |
285 } | 285 } |
286 if (start_thread_) { | 286 if (start_thread_) { |
287 LOG(LS_ERROR) << "The capturer is already running"; | 287 LOG(LS_ERROR) << "The capturer is already running"; |
288 DCHECK(start_thread_->IsCurrent()) | 288 RTC_DCHECK(start_thread_->IsCurrent()) |
289 << "Trying to start capturer on different threads"; | 289 << "Trying to start capturer on different threads"; |
290 return CS_FAILED; | 290 return CS_FAILED; |
291 } | 291 } |
292 | 292 |
293 start_thread_ = rtc::Thread::Current(); | 293 start_thread_ = rtc::Thread::Current(); |
294 DCHECK(!async_invoker_); | 294 RTC_DCHECK(!async_invoker_); |
295 async_invoker_.reset(new rtc::AsyncInvoker()); | 295 async_invoker_.reset(new rtc::AsyncInvoker()); |
296 captured_frames_ = 0; | 296 captured_frames_ = 0; |
297 | 297 |
298 SetCaptureFormat(&capture_format); | 298 SetCaptureFormat(&capture_format); |
299 | 299 |
300 webrtc::VideoCaptureCapability cap; | 300 webrtc::VideoCaptureCapability cap; |
301 if (!FormatToCapability(capture_format, &cap)) { | 301 if (!FormatToCapability(capture_format, &cap)) { |
302 LOG(LS_ERROR) << "Invalid capture format specified"; | 302 LOG(LS_ERROR) << "Invalid capture format specified"; |
303 return CS_FAILED; | 303 return CS_FAILED; |
304 } | 304 } |
(...skipping 15 matching lines...) Expand all Loading... |
320 | 320 |
321 SetCaptureState(CS_RUNNING); | 321 SetCaptureState(CS_RUNNING); |
322 return CS_STARTING; | 322 return CS_STARTING; |
323 } | 323 } |
324 | 324 |
325 void WebRtcVideoCapturer::Stop() { | 325 void WebRtcVideoCapturer::Stop() { |
326 if (!start_thread_) { | 326 if (!start_thread_) { |
327 LOG(LS_ERROR) << "The capturer is already stopped"; | 327 LOG(LS_ERROR) << "The capturer is already stopped"; |
328 return; | 328 return; |
329 } | 329 } |
330 DCHECK(start_thread_); | 330 RTC_DCHECK(start_thread_); |
331 DCHECK(start_thread_->IsCurrent()); | 331 RTC_DCHECK(start_thread_->IsCurrent()); |
332 DCHECK(async_invoker_); | 332 RTC_DCHECK(async_invoker_); |
333 if (IsRunning()) { | 333 if (IsRunning()) { |
334 // The module is responsible for OnIncomingCapturedFrame being called, if | 334 // The module is responsible for OnIncomingCapturedFrame being called, if |
335 // we stop it we will get no further callbacks. | 335 // we stop it we will get no further callbacks. |
336 module_->StopCapture(); | 336 module_->StopCapture(); |
337 } | 337 } |
338 module_->DeRegisterCaptureDataCallback(); | 338 module_->DeRegisterCaptureDataCallback(); |
339 | 339 |
340 // TODO(juberti): Determine if the VCM exposes any drop stats we can use. | 340 // TODO(juberti): Determine if the VCM exposes any drop stats we can use. |
341 double drop_ratio = 0.0; | 341 double drop_ratio = 0.0; |
342 LOG(LS_INFO) << "Camera '" << GetId() << "' stopped after capturing " | 342 LOG(LS_INFO) << "Camera '" << GetId() << "' stopped after capturing " |
(...skipping 22 matching lines...) Expand all Loading... |
365 for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) { | 365 for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) { |
366 fourccs->push_back(kSupportedFourCCs[i].fourcc); | 366 fourccs->push_back(kSupportedFourCCs[i].fourcc); |
367 } | 367 } |
368 return true; | 368 return true; |
369 } | 369 } |
370 | 370 |
371 void WebRtcVideoCapturer::OnIncomingCapturedFrame( | 371 void WebRtcVideoCapturer::OnIncomingCapturedFrame( |
372 const int32_t id, | 372 const int32_t id, |
373 const webrtc::VideoFrame& sample) { | 373 const webrtc::VideoFrame& sample) { |
374 // This can only happen between Start() and Stop(). | 374 // This can only happen between Start() and Stop(). |
375 DCHECK(start_thread_); | 375 RTC_DCHECK(start_thread_); |
376 DCHECK(async_invoker_); | 376 RTC_DCHECK(async_invoker_); |
377 if (start_thread_->IsCurrent()) { | 377 if (start_thread_->IsCurrent()) { |
378 SignalFrameCapturedOnStartThread(sample); | 378 SignalFrameCapturedOnStartThread(sample); |
379 } else { | 379 } else { |
380 // This currently happens on with at least VideoCaptureModuleV4L2 and | 380 // This currently happens on with at least VideoCaptureModuleV4L2 and |
381 // possibly other implementations of WebRTC's VideoCaptureModule. | 381 // possibly other implementations of WebRTC's VideoCaptureModule. |
382 // In order to maintain the threading contract with the upper layers and | 382 // In order to maintain the threading contract with the upper layers and |
383 // consistency with other capturers such as in Chrome, we need to do a | 383 // consistency with other capturers such as in Chrome, we need to do a |
384 // thread hop. | 384 // thread hop. |
385 // Note that Stop() can cause the async invoke call to be cancelled. | 385 // Note that Stop() can cause the async invoke call to be cancelled. |
386 async_invoker_->AsyncInvoke<void>(start_thread_, | 386 async_invoker_->AsyncInvoke<void>(start_thread_, |
387 // Note that this results in a shallow copying of the frame. | 387 // Note that this results in a shallow copying of the frame. |
388 rtc::Bind(&WebRtcVideoCapturer::SignalFrameCapturedOnStartThread, | 388 rtc::Bind(&WebRtcVideoCapturer::SignalFrameCapturedOnStartThread, |
389 this, sample)); | 389 this, sample)); |
390 } | 390 } |
391 } | 391 } |
392 | 392 |
393 void WebRtcVideoCapturer::OnCaptureDelayChanged(const int32_t id, | 393 void WebRtcVideoCapturer::OnCaptureDelayChanged(const int32_t id, |
394 const int32_t delay) { | 394 const int32_t delay) { |
395 LOG(LS_INFO) << "Capture delay changed to " << delay << " ms"; | 395 LOG(LS_INFO) << "Capture delay changed to " << delay << " ms"; |
396 } | 396 } |
397 | 397 |
398 void WebRtcVideoCapturer::SignalFrameCapturedOnStartThread( | 398 void WebRtcVideoCapturer::SignalFrameCapturedOnStartThread( |
399 const webrtc::VideoFrame frame) { | 399 const webrtc::VideoFrame frame) { |
400 // This can only happen between Start() and Stop(). | 400 // This can only happen between Start() and Stop(). |
401 DCHECK(start_thread_); | 401 RTC_DCHECK(start_thread_); |
402 DCHECK(start_thread_->IsCurrent()); | 402 RTC_DCHECK(start_thread_->IsCurrent()); |
403 DCHECK(async_invoker_); | 403 RTC_DCHECK(async_invoker_); |
404 | 404 |
405 ++captured_frames_; | 405 ++captured_frames_; |
406 // Log the size and pixel aspect ratio of the first captured frame. | 406 // Log the size and pixel aspect ratio of the first captured frame. |
407 if (1 == captured_frames_) { | 407 if (1 == captured_frames_) { |
408 LOG(LS_INFO) << "Captured frame size " | 408 LOG(LS_INFO) << "Captured frame size " |
409 << frame.width() << "x" << frame.height() | 409 << frame.width() << "x" << frame.height() |
410 << ". Expected format " << GetCaptureFormat()->ToString(); | 410 << ". Expected format " << GetCaptureFormat()->ToString(); |
411 } | 411 } |
412 | 412 |
413 // Signal down stream components on captured frame. | 413 // Signal down stream components on captured frame. |
(...skipping 23 matching lines...) Expand all Loading... |
437 elapsed_time = sample.render_time_ms() * rtc::kNumNanosecsPerMillisec; | 437 elapsed_time = sample.render_time_ms() * rtc::kNumNanosecsPerMillisec; |
438 time_stamp = elapsed_time; | 438 time_stamp = elapsed_time; |
439 data_size = rtc::checked_cast<uint32>(length); | 439 data_size = rtc::checked_cast<uint32>(length); |
440 data = buffer; | 440 data = buffer; |
441 rotation = sample.rotation(); | 441 rotation = sample.rotation(); |
442 } | 442 } |
443 | 443 |
444 } // namespace cricket | 444 } // namespace cricket |
445 | 445 |
446 #endif // HAVE_WEBRTC_VIDEO | 446 #endif // HAVE_WEBRTC_VIDEO |
OLD | NEW |