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

Unified Diff: webrtc/sdk/objc/Framework/Classes/Video/avfoundationformatmapper.mm

Issue 2890733003: Reland of Split iOS sdk in to separate targets (Closed)
Patch Set: Created 3 years, 7 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
Index: webrtc/sdk/objc/Framework/Classes/Video/avfoundationformatmapper.mm
diff --git a/webrtc/sdk/objc/Framework/Classes/Video/avfoundationformatmapper.mm b/webrtc/sdk/objc/Framework/Classes/Video/avfoundationformatmapper.mm
new file mode 100644
index 0000000000000000000000000000000000000000..19afa337683bacbeb7b1a14e2cd539cf821b6f09
--- /dev/null
+++ b/webrtc/sdk/objc/Framework/Classes/Video/avfoundationformatmapper.mm
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "avfoundationformatmapper.h"
+
+#import "WebRTC/RTCLogging.h"
+
+// TODO(denicija): add support for higher frame rates.
+// See http://crbug/webrtc/6355 for more info.
+static const int kFramesPerSecond = 30;
+
+static inline BOOL IsMediaSubTypeSupported(FourCharCode mediaSubType) {
+ return (mediaSubType == kCVPixelFormatType_420YpCbCr8PlanarFullRange ||
+ mediaSubType == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange);
+}
+
+static inline BOOL IsFrameRateWithinRange(int fps, AVFrameRateRange* range) {
+ return range.minFrameRate <= fps && range.maxFrameRate >= fps;
+}
+
+// Returns filtered array of device formats based on predefined constraints our
+// stack imposes.
+static NSArray<AVCaptureDeviceFormat*>* GetEligibleDeviceFormats(
+ const AVCaptureDevice* device,
+ int supportedFps) {
+ NSMutableArray<AVCaptureDeviceFormat*>* eligibleDeviceFormats =
+ [NSMutableArray array];
+
+ for (AVCaptureDeviceFormat* format in device.formats) {
+ // Filter out subTypes that we currently don't support in the stack
+ FourCharCode mediaSubType =
+ CMFormatDescriptionGetMediaSubType(format.formatDescription);
+ if (!IsMediaSubTypeSupported(mediaSubType)) {
+ continue;
+ }
+
+ // Filter out frame rate ranges that we currently don't support in the stack
+ for (AVFrameRateRange* frameRateRange in format.videoSupportedFrameRateRanges) {
+ if (IsFrameRateWithinRange(supportedFps, frameRateRange)) {
+ [eligibleDeviceFormats addObject:format];
+ break;
+ }
+ }
+ }
+
+ return [eligibleDeviceFormats copy];
+}
+
+// Mapping from cricket::VideoFormat to AVCaptureDeviceFormat.
+static AVCaptureDeviceFormat* GetDeviceFormatForVideoFormat(
+ const AVCaptureDevice* device,
+ const cricket::VideoFormat& videoFormat) {
+ AVCaptureDeviceFormat* desiredDeviceFormat = nil;
+ NSArray<AVCaptureDeviceFormat*>* eligibleFormats =
+ GetEligibleDeviceFormats(device, videoFormat.framerate());
+
+ for (AVCaptureDeviceFormat* deviceFormat in eligibleFormats) {
+ CMVideoDimensions dimension =
+ CMVideoFormatDescriptionGetDimensions(deviceFormat.formatDescription);
+ FourCharCode mediaSubType =
+ CMFormatDescriptionGetMediaSubType(deviceFormat.formatDescription);
+
+ if (videoFormat.width == dimension.width &&
+ videoFormat.height == dimension.height) {
+ if (mediaSubType == 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;
+}
+namespace webrtc {
+std::set<cricket::VideoFormat> GetSupportedVideoFormatsForDevice(
+ AVCaptureDevice* device) {
+ std::set<cricket::VideoFormat> supportedFormats;
+
+ NSArray<AVCaptureDeviceFormat*>* eligibleFormats =
+ GetEligibleDeviceFormats(device, kFramesPerSecond);
+
+ for (AVCaptureDeviceFormat* deviceFormat in eligibleFormats) {
+ CMVideoDimensions dimension =
+ CMVideoFormatDescriptionGetDimensions(deviceFormat.formatDescription);
+ cricket::VideoFormat format = cricket::VideoFormat(
+ dimension.width, dimension.height,
+ cricket::VideoFormat::FpsToInterval(kFramesPerSecond),
+ cricket::FOURCC_NV12);
+ supportedFormats.insert(format);
+ }
+
+ return supportedFormats;
+}
+
+bool SetFormatForCaptureDevice(AVCaptureDevice* device,
+ AVCaptureSession* session,
+ const cricket::VideoFormat& format) {
+ AVCaptureDeviceFormat* deviceFormat =
+ GetDeviceFormatForVideoFormat(device, format);
+ const int fps = cricket::VideoFormat::IntervalToFps(format.interval);
+
+ NSError* error = nil;
+ bool success = true;
+ [session beginConfiguration];
+ if ([device lockForConfiguration:&error]) {
+ @try {
+ device.activeFormat = deviceFormat;
+ device.activeVideoMinFrameDuration = CMTimeMake(1, fps);
+ } @catch (NSException* exception) {
+ RTCLogError(@"Failed to set active format!\n User info:%@",
+ exception.userInfo);
+ success = false;
+ }
+
+ [device unlockForConfiguration];
+ } else {
+ RTCLogError(@"Failed to lock device %@. Error: %@", device, error.userInfo);
+ success = false;
+ }
+ [session commitConfiguration];
+
+ return success;
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698