Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm

Issue 2188883002: Use 15fps for iPhone 4S (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: guard ios only import. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 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 "avfoundationvideocapturer.h" 11 #include "avfoundationvideocapturer.h"
12 12
13 #import <AVFoundation/AVFoundation.h> 13 #import <AVFoundation/AVFoundation.h>
14 #import <Foundation/Foundation.h> 14 #import <Foundation/Foundation.h>
15 #if TARGET_OS_IPHONE 15 #if TARGET_OS_IPHONE
16 #import <UIKit/UIKit.h> 16 #import <UIKit/UIKit.h>
17 #endif 17 #endif
18 18
19 #import "RTCDispatcher+Private.h" 19 #import "RTCDispatcher+Private.h"
20 #import "WebRTC/RTCLogging.h" 20 #import "WebRTC/RTCLogging.h"
21 #if TARGET_OS_IPHONE
22 #import "WebRTC/UIDevice+RTCDevice.h"
23 #endif
21 24
22 #include "webrtc/base/bind.h" 25 #include "webrtc/base/bind.h"
23 #include "webrtc/base/checks.h" 26 #include "webrtc/base/checks.h"
24 #include "webrtc/base/thread.h" 27 #include "webrtc/base/thread.h"
25 #include "webrtc/common_video/include/corevideo_frame_buffer.h" 28 #include "webrtc/common_video/include/corevideo_frame_buffer.h"
26 29
27 // TODO(tkchin): support other formats. 30 // TODO(tkchin): support other formats.
28 static NSString *const kDefaultPreset = AVCaptureSessionPreset640x480; 31 static NSString *const kDefaultPreset = AVCaptureSessionPreset640x480;
29 static cricket::VideoFormat const kDefaultFormat = 32 static cricket::VideoFormat const kDefaultFormat =
30 cricket::VideoFormat(640, 33 cricket::VideoFormat(640,
31 480, 34 480,
32 cricket::VideoFormat::FpsToInterval(30), 35 cricket::VideoFormat::FpsToInterval(30),
33 cricket::FOURCC_NV12); 36 cricket::FOURCC_NV12);
37 // iPhone4S is too slow to handle 30fps.
38 static cricket::VideoFormat const kIPhone4SFormat =
39 cricket::VideoFormat(640,
40 480,
41 cricket::VideoFormat::FpsToInterval(15),
42 cricket::FOURCC_NV12);
34 43
35 // This class used to capture frames using AVFoundation APIs on iOS. It is meant 44 // This class used to capture frames using AVFoundation APIs on iOS. It is meant
36 // to be owned by an instance of AVFoundationVideoCapturer. The reason for this 45 // to be owned by an instance of AVFoundationVideoCapturer. The reason for this
37 // because other webrtc objects own cricket::VideoCapturer, which is not 46 // because other webrtc objects own cricket::VideoCapturer, which is not
38 // ref counted. To prevent bad behavior we do not expose this class directly. 47 // ref counted. To prevent bad behavior we do not expose this class directly.
39 @interface RTCAVFoundationVideoCapturerInternal : NSObject 48 @interface RTCAVFoundationVideoCapturerInternal : NSObject
40 <AVCaptureVideoDataOutputSampleBufferDelegate> 49 <AVCaptureVideoDataOutputSampleBufferDelegate>
41 50
42 @property(nonatomic, readonly) AVCaptureSession *captureSession; 51 @property(nonatomic, readonly) AVCaptureSession *captureSession;
43 @property(nonatomic, readonly) dispatch_queue_t frameQueue; 52 @property(nonatomic, readonly) dispatch_queue_t frameQueue;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 385
377 // Add the inputs. 386 // Add the inputs.
378 if (![captureSession canAddInput:frontCameraInput] || 387 if (![captureSession canAddInput:frontCameraInput] ||
379 (backCameraInput && ![captureSession canAddInput:backCameraInput])) { 388 (backCameraInput && ![captureSession canAddInput:backCameraInput])) {
380 RTCLogError(@"Session does not support capture inputs."); 389 RTCLogError(@"Session does not support capture inputs.");
381 return NO; 390 return NO;
382 } 391 }
383 AVCaptureDeviceInput *input = self.useBackCamera ? 392 AVCaptureDeviceInput *input = self.useBackCamera ?
384 backCameraInput : frontCameraInput; 393 backCameraInput : frontCameraInput;
385 [captureSession addInput:input]; 394 [captureSession addInput:input];
395 #if TARGET_OS_IPHONE
396 if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) {
397 [self setMinFrameDuration:CMTimeMake(1, 15) forDevice:input.device];
398 }
399 #endif
386 _captureSession = captureSession; 400 _captureSession = captureSession;
387 return YES; 401 return YES;
388 } 402 }
389 403
390 - (AVCaptureVideoDataOutput *)videoDataOutput { 404 - (AVCaptureVideoDataOutput *)videoDataOutput {
391 if (!_videoDataOutput) { 405 if (!_videoDataOutput) {
392 // Make the capturer output NV12. Ideally we want I420 but that's not 406 // Make the capturer output NV12. Ideally we want I420 but that's not
393 // currently supported on iPhone / iPad. 407 // currently supported on iPhone / iPad.
394 AVCaptureVideoDataOutput *videoDataOutput = 408 AVCaptureVideoDataOutput *videoDataOutput =
395 [[AVCaptureVideoDataOutput alloc] init]; 409 [[AVCaptureVideoDataOutput alloc] init];
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 if (!backCameraInput) { 472 if (!backCameraInput) {
459 RTCLogError(@"Failed to create front camera input: %@", 473 RTCLogError(@"Failed to create front camera input: %@",
460 error.localizedDescription); 474 error.localizedDescription);
461 return nil; 475 return nil;
462 } 476 }
463 _backCameraInput = backCameraInput; 477 _backCameraInput = backCameraInput;
464 } 478 }
465 return _backCameraInput; 479 return _backCameraInput;
466 } 480 }
467 481
482 - (void)setMinFrameDuration:(CMTime)minFrameDuration
483 forDevice:(AVCaptureDevice *)device {
484 NSError *error = nil;
485 if (![device lockForConfiguration:&error]) {
486 RTCLogError(@"Failed to lock device for configuration. Error: %@", error.loc alizedDescription);
487 return;
488 }
489 device.activeVideoMinFrameDuration = minFrameDuration;
490 [device unlockForConfiguration];
491 }
492
468 // Called from capture session queue. 493 // Called from capture session queue.
469 - (void)updateOrientation { 494 - (void)updateOrientation {
470 AVCaptureConnection *connection = 495 AVCaptureConnection *connection =
471 [_videoDataOutput connectionWithMediaType:AVMediaTypeVideo]; 496 [_videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
472 if (!connection.supportsVideoOrientation) { 497 if (!connection.supportsVideoOrientation) {
473 // TODO(tkchin): set rotation bit on frames. 498 // TODO(tkchin): set rotation bit on frames.
474 return; 499 return;
475 } 500 }
476 #if TARGET_OS_IPHONE 501 #if TARGET_OS_IPHONE
477 AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationPortrait; 502 AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationPortrait;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 } 538 }
514 if (oldInput) { 539 if (oldInput) {
515 // Ok to remove this even if it's not attached. Will be no-op. 540 // Ok to remove this even if it's not attached. Will be no-op.
516 [_captureSession removeInput:oldInput]; 541 [_captureSession removeInput:oldInput];
517 } 542 }
518 if (newInput) { 543 if (newInput) {
519 [_captureSession addInput:newInput]; 544 [_captureSession addInput:newInput];
520 } 545 }
521 [self updateOrientation]; 546 [self updateOrientation];
522 [_captureSession commitConfiguration]; 547 [_captureSession commitConfiguration];
548 #if TARGET_OS_IPHONE
549 if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) {
550 [self setMinFrameDuration:CMTimeMake(1, 15) forDevice:newInput.device];
551 }
552 #endif
523 }]; 553 }];
524 } 554 }
525 555
526 @end 556 @end
527 557
528 namespace webrtc { 558 namespace webrtc {
529 559
530 enum AVFoundationVideoCapturerMessageType : uint32_t { 560 enum AVFoundationVideoCapturerMessageType : uint32_t {
531 kMessageTypeFrame, 561 kMessageTypeFrame,
532 }; 562 };
533 563
534 struct AVFoundationFrame { 564 struct AVFoundationFrame {
535 AVFoundationFrame(CVImageBufferRef buffer, int64_t time) 565 AVFoundationFrame(CVImageBufferRef buffer, int64_t time)
536 : image_buffer(buffer), capture_time(time) {} 566 : image_buffer(buffer), capture_time(time) {}
537 CVImageBufferRef image_buffer; 567 CVImageBufferRef image_buffer;
538 int64_t capture_time; 568 int64_t capture_time;
539 }; 569 };
540 570
541 AVFoundationVideoCapturer::AVFoundationVideoCapturer() 571 AVFoundationVideoCapturer::AVFoundationVideoCapturer()
542 : _capturer(nil), _startThread(nullptr) { 572 : _capturer(nil), _startThread(nullptr) {
543 // Set our supported formats. This matches kDefaultPreset. 573 // Set our supported formats. This matches kDefaultPreset.
544 std::vector<cricket::VideoFormat> supportedFormats; 574 std::vector<cricket::VideoFormat> supported_formats;
545 supportedFormats.push_back(cricket::VideoFormat(kDefaultFormat)); 575 #if TARGET_OS_IPHONE
546 SetSupportedFormats(supportedFormats); 576 if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) {
577 supported_formats.push_back(cricket::VideoFormat(kIPhone4SFormat));
578 } else {
579 supported_formats.push_back(cricket::VideoFormat(kDefaultFormat));
580 }
581 #else
582 supported_formats.push_back(cricket::VideoFormat(kDefaultFormat));
583 #endif
584 SetSupportedFormats(supported_formats);
547 _capturer = 585 _capturer =
548 [[RTCAVFoundationVideoCapturerInternal alloc] initWithCapturer:this]; 586 [[RTCAVFoundationVideoCapturerInternal alloc] initWithCapturer:this];
549 } 587 }
550 588
551 AVFoundationVideoCapturer::~AVFoundationVideoCapturer() { 589 AVFoundationVideoCapturer::~AVFoundationVideoCapturer() {
552 _capturer = nil; 590 _capturer = nil;
553 } 591 }
554 592
555 cricket::CaptureState AVFoundationVideoCapturer::Start( 593 cricket::CaptureState AVFoundationVideoCapturer::Start(
556 const cricket::VideoFormat& format) { 594 const cricket::VideoFormat& format) {
557 if (!_capturer) { 595 if (!_capturer) {
558 LOG(LS_ERROR) << "Failed to create AVFoundation capturer."; 596 LOG(LS_ERROR) << "Failed to create AVFoundation capturer.";
559 return cricket::CaptureState::CS_FAILED; 597 return cricket::CaptureState::CS_FAILED;
560 } 598 }
561 if (_capturer.isRunning) { 599 if (_capturer.isRunning) {
562 LOG(LS_ERROR) << "The capturer is already running."; 600 LOG(LS_ERROR) << "The capturer is already running.";
563 return cricket::CaptureState::CS_FAILED; 601 return cricket::CaptureState::CS_FAILED;
564 } 602 }
565 if (format != kDefaultFormat) { 603 if (format != kDefaultFormat && format != kIPhone4SFormat) {
566 LOG(LS_ERROR) << "Unsupported format provided."; 604 LOG(LS_ERROR) << "Unsupported format provided.";
567 return cricket::CaptureState::CS_FAILED; 605 return cricket::CaptureState::CS_FAILED;
568 } 606 }
569 607
570 // Keep track of which thread capture started on. This is the thread that 608 // Keep track of which thread capture started on. This is the thread that
571 // frames need to be sent to. 609 // frames need to be sent to.
572 RTC_DCHECK(!_startThread); 610 RTC_DCHECK(!_startThread);
573 _startThread = rtc::Thread::Current(); 611 _startThread = rtc::Thread::Current();
574 612
575 SetCaptureFormat(&format); 613 SetCaptureFormat(&format);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 } 718 }
681 719
682 OnFrame(cricket::WebRtcVideoFrame(buffer, webrtc::kVideoRotation_0, 720 OnFrame(cricket::WebRtcVideoFrame(buffer, webrtc::kVideoRotation_0,
683 translated_camera_time_us), 721 translated_camera_time_us),
684 captured_width, captured_height); 722 captured_width, captured_height);
685 723
686 CVBufferRelease(image_buffer); 724 CVBufferRelease(image_buffer);
687 } 725 }
688 726
689 } // namespace webrtc 727 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/UIDevice+RTCDevice.mm ('k') | webrtc/sdk/objc/Framework/Headers/WebRTC/UIDevice+RTCDevice.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698