| 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 |