OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 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 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 best_it = it; | 235 best_it = it; |
236 } | 236 } |
237 } | 237 } |
238 return *best_it; | 238 return *best_it; |
239 } | 239 } |
240 | 240 |
241 // Set |option| to the highest-priority value of |key| in the constraints. | 241 // Set |option| to the highest-priority value of |key| in the constraints. |
242 // Return false if the key is mandatory, and the value is invalid. | 242 // Return false if the key is mandatory, and the value is invalid. |
243 bool ExtractOption(const MediaConstraintsInterface* all_constraints, | 243 bool ExtractOption(const MediaConstraintsInterface* all_constraints, |
244 const std::string& key, | 244 const std::string& key, |
245 rtc::Optional<bool>* option) { | 245 bool* option) { |
246 size_t mandatory = 0; | 246 size_t mandatory = 0; |
247 bool value; | 247 *option = false; |
248 if (FindConstraint(all_constraints, key, &value, &mandatory)) { | 248 if (FindConstraint(all_constraints, key, option, &mandatory)) { |
249 *option = rtc::Optional<bool>(value); | |
250 return true; | 249 return true; |
251 } | 250 } |
252 | 251 |
253 return mandatory == 0; | 252 return mandatory == 0; |
254 } | 253 } |
255 | 254 |
256 // Search |all_constraints| for known video options. Apply all options that are | |
257 // found with valid values, and return false if any mandatory video option was | |
258 // found with an invalid value. | |
259 bool ExtractVideoOptions(const MediaConstraintsInterface* all_constraints, | |
260 cricket::VideoOptions* options) { | |
261 bool all_valid = true; | |
262 | |
263 all_valid &= | |
264 ExtractOption(all_constraints, MediaConstraintsInterface::kNoiseReduction, | |
265 &(options->video_noise_reduction)); | |
266 | |
267 return all_valid; | |
268 } | |
269 | |
270 } // anonymous namespace | 255 } // anonymous namespace |
271 | 256 |
272 namespace webrtc { | 257 namespace webrtc { |
273 | 258 |
274 rtc::scoped_refptr<VideoTrackSourceInterface> VideoCapturerTrackSource::Create( | 259 rtc::scoped_refptr<VideoTrackSourceInterface> VideoCapturerTrackSource::Create( |
275 rtc::Thread* worker_thread, | 260 rtc::Thread* worker_thread, |
276 cricket::VideoCapturer* capturer, | 261 cricket::VideoCapturer* capturer, |
277 const webrtc::MediaConstraintsInterface* constraints, | 262 const webrtc::MediaConstraintsInterface* constraints, |
278 bool remote) { | 263 bool remote) { |
279 RTC_DCHECK(worker_thread != NULL); | 264 RTC_DCHECK(worker_thread != NULL); |
(...skipping 15 matching lines...) Expand all Loading... |
295 new rtc::RefCountedObject<VideoCapturerTrackSource>(worker_thread, | 280 new rtc::RefCountedObject<VideoCapturerTrackSource>(worker_thread, |
296 capturer, remote)); | 281 capturer, remote)); |
297 source->Initialize(nullptr); | 282 source->Initialize(nullptr); |
298 return source; | 283 return source; |
299 } | 284 } |
300 | 285 |
301 VideoCapturerTrackSource::VideoCapturerTrackSource( | 286 VideoCapturerTrackSource::VideoCapturerTrackSource( |
302 rtc::Thread* worker_thread, | 287 rtc::Thread* worker_thread, |
303 cricket::VideoCapturer* capturer, | 288 cricket::VideoCapturer* capturer, |
304 bool remote) | 289 bool remote) |
305 : signaling_thread_(rtc::Thread::Current()), | 290 : VideoTrackSource(capturer, worker_thread, remote), |
306 worker_thread_(worker_thread), | 291 signaling_thread_(rtc::Thread::Current()), |
307 video_capturer_(capturer), | 292 video_capturer_(capturer), |
308 started_(false), | 293 started_(false), |
309 state_(kInitializing), | 294 needs_denoising_(false) { |
310 remote_(remote) { | |
311 video_capturer_->SignalStateChange.connect( | 295 video_capturer_->SignalStateChange.connect( |
312 this, &VideoCapturerTrackSource::OnStateChange); | 296 this, &VideoCapturerTrackSource::OnStateChange); |
313 } | 297 } |
314 | 298 |
315 VideoCapturerTrackSource::~VideoCapturerTrackSource() { | 299 VideoCapturerTrackSource::~VideoCapturerTrackSource() { |
316 video_capturer_->SignalStateChange.disconnect(this); | 300 video_capturer_->SignalStateChange.disconnect(this); |
317 Stop(); | 301 Stop(); |
318 } | 302 } |
319 | 303 |
320 void VideoCapturerTrackSource::Initialize( | 304 void VideoCapturerTrackSource::Initialize( |
(...skipping 30 matching lines...) Expand all Loading... |
351 formats = | 335 formats = |
352 FilterFormats(mandatory_constraints, optional_constraints, formats); | 336 FilterFormats(mandatory_constraints, optional_constraints, formats); |
353 } | 337 } |
354 | 338 |
355 if (formats.size() == 0) { | 339 if (formats.size() == 0) { |
356 LOG(LS_WARNING) << "Failed to find a suitable video format."; | 340 LOG(LS_WARNING) << "Failed to find a suitable video format."; |
357 SetState(kEnded); | 341 SetState(kEnded); |
358 return; | 342 return; |
359 } | 343 } |
360 | 344 |
361 cricket::VideoOptions options; | 345 if (!ExtractOption(constraints, MediaConstraintsInterface::kNoiseReduction, |
362 if (!ExtractVideoOptions(constraints, &options)) { | 346 &needs_denoising_)) { |
363 LOG(LS_WARNING) << "Could not satisfy mandatory options."; | 347 LOG(LS_WARNING) << "Invalid mandatory value for" |
| 348 << MediaConstraintsInterface::kNoiseReduction; |
364 SetState(kEnded); | 349 SetState(kEnded); |
365 return; | 350 return; |
366 } | 351 } |
367 options_.SetAll(options); | |
368 options_.is_screencast = rtc::Optional<bool>(video_capturer_->IsScreencast()); | |
369 | 352 |
370 format_ = GetBestCaptureFormat(formats); | 353 format_ = GetBestCaptureFormat(formats); |
371 // Start the camera with our best guess. | 354 // Start the camera with our best guess. |
372 // TODO(perkj): Should we try again with another format it it turns out that | 355 if (!worker_thread()->Invoke<bool>( |
373 // the camera doesn't produce frames with the correct format? Or will | |
374 // cricket::VideCapturer be able to re-scale / crop to the requested | |
375 // resolution? | |
376 if (!worker_thread_->Invoke<bool>( | |
377 rtc::Bind(&cricket::VideoCapturer::StartCapturing, | 356 rtc::Bind(&cricket::VideoCapturer::StartCapturing, |
378 video_capturer_.get(), format_))) { | 357 video_capturer_.get(), format_))) { |
379 SetState(kEnded); | 358 SetState(kEnded); |
380 return; | 359 return; |
381 } | 360 } |
382 started_ = true; | 361 started_ = true; |
383 // Initialize hasn't succeeded until a successful state change has occurred. | 362 // Initialize hasn't succeeded until a successful state change has occurred. |
384 } | 363 } |
385 | 364 |
386 void VideoCapturerTrackSource::Stop() { | 365 void VideoCapturerTrackSource::Stop() { |
387 if (!started_) { | 366 if (!started_) { |
388 return; | 367 return; |
389 } | 368 } |
390 started_ = false; | 369 started_ = false; |
391 worker_thread_->Invoke<void>( | 370 worker_thread()->Invoke<void>( |
392 rtc::Bind(&cricket::VideoCapturer::Stop, video_capturer_.get())); | 371 rtc::Bind(&cricket::VideoCapturer::Stop, video_capturer_.get())); |
393 } | 372 } |
394 | 373 |
395 void VideoCapturerTrackSource::Restart() { | 374 void VideoCapturerTrackSource::Restart() { |
396 if (started_) { | 375 if (started_) { |
397 return; | 376 return; |
398 } | 377 } |
399 if (!worker_thread_->Invoke<bool>( | 378 if (!worker_thread()->Invoke<bool>( |
400 rtc::Bind(&cricket::VideoCapturer::StartCapturing, | 379 rtc::Bind(&cricket::VideoCapturer::StartCapturing, |
401 video_capturer_.get(), format_))) { | 380 video_capturer_.get(), format_))) { |
402 SetState(kEnded); | 381 SetState(kEnded); |
403 return; | 382 return; |
404 } | 383 } |
405 started_ = true; | 384 started_ = true; |
406 } | 385 } |
407 | 386 |
408 void VideoCapturerTrackSource::AddOrUpdateSink( | |
409 rtc::VideoSinkInterface<cricket::VideoFrame>* sink, | |
410 const rtc::VideoSinkWants& wants) { | |
411 worker_thread_->Invoke<void>( | |
412 rtc::Bind(&cricket::VideoCapturer::AddOrUpdateSink, video_capturer_.get(), | |
413 sink, wants)); | |
414 } | |
415 | |
416 void VideoCapturerTrackSource::RemoveSink( | |
417 rtc::VideoSinkInterface<cricket::VideoFrame>* output) { | |
418 worker_thread_->Invoke<void>(rtc::Bind(&cricket::VideoCapturer::RemoveSink, | |
419 video_capturer_.get(), output)); | |
420 } | |
421 | |
422 // OnStateChange listens to the cricket::VideoCapturer::SignalStateChange. | 387 // OnStateChange listens to the cricket::VideoCapturer::SignalStateChange. |
423 void VideoCapturerTrackSource::OnStateChange( | 388 void VideoCapturerTrackSource::OnStateChange( |
424 cricket::VideoCapturer* capturer, | 389 cricket::VideoCapturer* capturer, |
425 cricket::CaptureState capture_state) { | 390 cricket::CaptureState capture_state) { |
426 if (rtc::Thread::Current() != signaling_thread_) { | 391 if (rtc::Thread::Current() != signaling_thread_) { |
427 invoker_.AsyncInvoke<void>( | 392 invoker_.AsyncInvoke<void>( |
428 signaling_thread_, rtc::Bind(&VideoCapturerTrackSource::OnStateChange, | 393 signaling_thread_, rtc::Bind(&VideoCapturerTrackSource::OnStateChange, |
429 this, capturer, capture_state)); | 394 this, capturer, capture_state)); |
430 return; | 395 return; |
431 } | 396 } |
432 | 397 |
433 if (capturer == video_capturer_.get()) { | 398 if (capturer == video_capturer_.get()) { |
434 SetState(GetReadyState(capture_state)); | 399 SetState(GetReadyState(capture_state)); |
435 } | 400 } |
436 } | 401 } |
437 | 402 |
438 void VideoCapturerTrackSource::SetState(SourceState new_state) { | |
439 if (state_ != new_state) { | |
440 state_ = new_state; | |
441 FireOnChanged(); | |
442 } | |
443 } | |
444 | |
445 } // namespace webrtc | 403 } // namespace webrtc |
OLD | NEW |