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

Unified Diff: webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm

Issue 2349223002: Replace SessionPresets with AVCaptureDeviceFormats (Closed)
Patch Set: Remove unused method Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm
diff --git a/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm b/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm
index 5708346ae2bccdee06da02c5eea8d2a13d37d453..53578a0d4193d0792fe84c815c83f4967e0c592f 100644
--- a/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm
+++ b/webrtc/sdk/objc/Framework/Classes/avfoundationvideocapturer.mm
@@ -30,41 +30,66 @@
#include "webrtc/common_video/include/corevideo_frame_buffer.h"
#include "webrtc/common_video/rotation.h"
-struct AVCaptureSessionPresetResolution {
- NSString *sessionPreset;
- int width;
- int height;
-};
+// Maping from cricket::VideoFormat to AVCaptureDeviceFormat.
kthelgason 2016/09/20 07:00:30 nit: mapping
+static AVCaptureDeviceFormat *GetDeviceFormatForVideoFormat(const AVCaptureDevice *device,
+ const cricket::VideoFormat& videoFormat) {
+
+ AVCaptureDeviceFormat *desiredDeviceFormat = nil;
+ for (AVCaptureDeviceFormat *deviceFormat in [device formats]) {
+ CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions([deviceFormat formatDescription]);
+ FourCharCode code = CMFormatDescriptionGetMediaSubType([deviceFormat formatDescription]);
+
+ if (code != kCVPixelFormatType_420YpCbCr8BiPlanarFullRange &&
+ code !=kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) {
+ continue;
+ }
-#if TARGET_OS_IPHONE
-static const AVCaptureSessionPresetResolution kAvailablePresets[] = {
- { AVCaptureSessionPreset352x288, 352, 288},
- { AVCaptureSessionPreset640x480, 640, 480},
- { AVCaptureSessionPreset1280x720, 1280, 720},
- { AVCaptureSessionPreset1920x1080, 1920, 1080},
-};
-#else // macOS
-static const AVCaptureSessionPresetResolution kAvailablePresets[] = {
- { AVCaptureSessionPreset320x240, 320, 240},
- { AVCaptureSessionPreset352x288, 352, 288},
- { AVCaptureSessionPreset640x480, 640, 480},
- { AVCaptureSessionPreset960x540, 960, 540},
- { AVCaptureSessionPreset1280x720, 1280, 720},
-};
-#endif
+ if (videoFormat.width == dimension.width && videoFormat.height == dimension.height) {
magjed_webrtc 2016/09/20 08:42:18 Shouldn't we also look at fps? Maybe it would be b
daniela-webrtc 2016/09/26 11:03:15 Acknowledged.
+ if (code == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
+ //this is the preferred format so no need to wait for better option
+ return deviceFormat;
+ } else {
+ //this is good candidate, but let's wait for something better
+ desiredDeviceFormat = deviceFormat;
+ }
+ }
+ }
+ return desiredDeviceFormat;
+}
+
+// Mapping from AVCaptureDeviceFormat to cricket::VideoFormat for given input device.
+static std::vector<cricket::VideoFormat> GetSupportedVideoFormatsForDevice(AVCaptureDevice *device) {
+ std::vector<cricket::VideoFormat> supportedFormats;
-// Mapping from cricket::VideoFormat to AVCaptureSession presets.
-static NSString *GetSessionPresetForVideoFormat(
- const cricket::VideoFormat& format) {
- for (const auto preset : kAvailablePresets) {
- // Check both orientations
- if ((format.width == preset.width && format.height == preset.height) ||
- (format.width == preset.height && format.height == preset.width)) {
- return preset.sessionPreset;
+ for (AVCaptureDeviceFormat *deviceFormat in [device formats]) {
+ FourCharCode code = CMFormatDescriptionGetMediaSubType([deviceFormat formatDescription]);
+
+ if (code != kCVPixelFormatType_420YpCbCr8BiPlanarFullRange &&
+ code !=kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) {
kthelgason 2016/09/20 07:00:30 nit: missing space
daniela-webrtc 2016/09/23 08:49:17 Acknowledged.
+ continue;
+ }
+
+ CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions([deviceFormat formatDescription]);
+
+ for (AVFrameRateRange* frameRate in [deviceFormat videoSupportedFrameRateRanges]) {
+ Float64 fps = frameRate.maxFrameRate;
kthelgason 2016/09/20 07:00:30 is there a need to introduce this variable?
daniela-webrtc 2016/09/26 11:03:15 Acknowledged.
+ int64_t interval = cricket::VideoFormat::FpsToInterval(fps);
+ cricket::VideoFormat format = cricket::VideoFormat(dimension.width,
+ dimension.height,
+ interval,
+ cricket::FOURCC_NV12);
+
+ std::vector<cricket::VideoFormat>::iterator iterator = std::find(supportedFormats.begin(),
kthelgason 2016/09/20 07:00:30 I'd go for auto here, this type is very unwieldy.
daniela-webrtc 2016/09/23 08:49:17 This will no longer be needed once I implement the
+ supportedFormats.end(),
+ format);
+ if (iterator != supportedFormats.end()) {
+ continue;
+ } else {
+ supportedFormats.push_back(format);
+ }
}
kthelgason 2016/09/20 07:00:30 We might be better off just using a std::set for s
magjed_webrtc 2016/09/20 08:42:18 +1 Go with a std::set, it should simplify the code
daniela-webrtc 2016/09/23 08:49:17 Acknowledged.
}
- // If no matching preset is found, use a default one.
- return AVCaptureSessionPreset640x480;
+ return supportedFormats;
}
// This class used to capture frames using AVFoundation APIs on iOS. It is meant
@@ -87,6 +112,9 @@ static NSString *GetSessionPresetForVideoFormat(
- (instancetype)initWithCapturer:(webrtc::AVFoundationVideoCapturer *)capturer;
- (AVCaptureDevice *)getActiveCaptureDevice;
+- (nullable AVCaptureDevice *)frontCaptureDevice;
+- (nullable AVCaptureDevice *)backCaptureDevice;
+
// Starts and stops the capture session asynchronously. We cannot do this
// synchronously without blocking a WebRTC thread.
- (void)start;
@@ -175,6 +203,15 @@ static NSString *GetSessionPresetForVideoFormat(
return self.useBackCamera ? _backCameraInput.device : _frontCameraInput.device;
}
+- (AVCaptureDevice *)frontCaptureDevice {
+ return _frontCameraInput.device;
+}
+
+- (AVCaptureDevice *)backCaptureDevice {
+ return _backCameraInput.device;
+}
+
+
- (dispatch_queue_t)frameQueue {
if (!_frameQueue) {
_frameQueue =
@@ -597,32 +634,24 @@ enum AVFoundationVideoCapturerMessageType : uint32_t {
};
AVFoundationVideoCapturer::AVFoundationVideoCapturer() : _capturer(nil) {
- // Set our supported formats. This matches kAvailablePresets.
- _capturer =
- [[RTCAVFoundationVideoCapturerInternal alloc] initWithCapturer:this];
+ _capturer = [[RTCAVFoundationVideoCapturerInternal alloc] initWithCapturer:this];
- std::vector<cricket::VideoFormat> supported_formats;
- int framerate = 30;
+ std::vector<cricket::VideoFormat> frontCameraSupportedVideoFormats =
+ GetSupportedVideoFormatsForDevice([_capturer frontCaptureDevice]);
+ std::vector<cricket::VideoFormat> backCameraSupportedVideoFormats =
kthelgason 2016/09/20 07:00:30 I would use auto for all these types, I try to use
magjed_webrtc 2016/09/20 08:42:18 See https://google.github.io/styleguide/cppguide.h
+ GetSupportedVideoFormatsForDevice([_capturer backCaptureDevice]);
-#if TARGET_OS_IPHONE
- if ([UIDevice deviceType] == RTCDeviceTypeIPhone4S) {
- set_enable_video_adapter(false);
- framerate = 15;
- }
-#endif
+ std::sort(frontCameraSupportedVideoFormats.begin(), frontCameraSupportedVideoFormats.end());
+ std::sort(backCameraSupportedVideoFormats.begin(), backCameraSupportedVideoFormats.end());
- for (const auto preset : kAvailablePresets) {
- if ([_capturer.captureSession canSetSessionPreset:preset.sessionPreset]) {
- const auto format = cricket::VideoFormat(
- preset.width,
- preset.height,
- cricket::VideoFormat::FpsToInterval(framerate),
- cricket::FOURCC_NV12);
- supported_formats.push_back(format);
- }
- }
+ std::vector<cricket::VideoFormat> intersectionVideoFormats;
+ std::set_intersection(frontCameraSupportedVideoFormats.begin(),
+ frontCameraSupportedVideoFormats.end(),
+ backCameraSupportedVideoFormats.begin(),
+ backCameraSupportedVideoFormats.end(),
+ std::back_inserter(intersectionVideoFormats));
- SetSupportedFormats(supported_formats);
+ SetSupportedFormats(intersectionVideoFormats);
}
AVFoundationVideoCapturer::~AVFoundationVideoCapturer() {
@@ -640,17 +669,26 @@ cricket::CaptureState AVFoundationVideoCapturer::Start(
return cricket::CaptureState::CS_FAILED;
}
- NSString *desiredPreset = GetSessionPresetForVideoFormat(format);
- RTC_DCHECK(desiredPreset);
+ AVCaptureDeviceFormat *deviceFormat =
+ GetDeviceFormatForVideoFormat([_capturer getActiveCaptureDevice], format);
magjed_webrtc 2016/09/20 08:42:18 You need to indent the new line with 4 spaces. htt
daniela-webrtc 2016/09/26 11:03:15 Acknowledged.
+ AVCaptureDevice *device = [_capturer getActiveCaptureDevice];
+ AVCaptureSession *session = [_capturer captureSession];
+ NSError *error = nil;
- [_capturer.captureSession beginConfiguration];
- if (![_capturer.captureSession canSetSessionPreset:desiredPreset]) {
- LOG(LS_ERROR) << "Unsupported video format.";
- [_capturer.captureSession commitConfiguration];
- return cricket::CaptureState::CS_FAILED;
+ [session beginConfiguration]; // the session to which the receiver's AVCaptureDeviceInput is added.
kthelgason 2016/09/20 07:00:30 Is this necessary when only re-configuring the dev
daniela-webrtc 2016/09/23 08:49:17 Yes. Because this essentially causes the session t
+ if ([device lockForConfiguration:&error]) {
+ @try {
+ [device setActiveFormat:deviceFormat];
+ } @catch (NSException *exception) {
+ LOG(LS_ERROR) << [NSString stringWithFormat:
+ @"Exception occured while setting active format!\n User info:%@", exception.userInfo];
+ return cricket::CaptureState::CS_FAILED;
+ }
+
+ [device unlockForConfiguration];
}
- _capturer.captureSession.sessionPreset = desiredPreset;
- [_capturer.captureSession commitConfiguration];
+
+ [session commitConfiguration];
SetCaptureFormat(&format);
// This isn't super accurate because it takes a while for the AVCaptureSession
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698