The video capture module for iOS.

This CL is from https://webrtc-codereview.appspot.com/1339004.

Patch this CL, then run the trunk/webrtc/build/vie-webrtc.sh.

BUG=2105
R=fischman@webrtc.org, mallinath@webrtc.org, niklas.enbom@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1641004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4546 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
sjlee@webrtc.org 2013-08-14 22:07:04 +00:00
parent 3d0019f09a
commit d690eab54f
12 changed files with 797 additions and 16 deletions

View File

@ -133,10 +133,7 @@
'enable_android_opensl%': 0,
}],
['OS=="ios"', {
'enable_video%': 0,
'enable_protobuf%': 0,
'build_libjpeg%': 0,
'build_libyuv%': 0,
'include_tests%': 0,
}],
['target_arch=="arm"', {

69
webrtc/build/vie-webrtc.sh Executable file
View File

@ -0,0 +1,69 @@
#!/bin/sh
# Copyright (c) 2013 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.
set -e
# TODO(sjlee): remove this whole script file.
# (https://code.google.com/p/webrtc/issues/detail?id=2028)
function build_project() {
# make the target string
local target_string=""
if [[ -n "$2" ]]; then
target_string="-target $2"
fi
xcodebuild -project "$1" -sdk iphoneos -arch armv7 \
-configuration ${CONFIGURATION} \
-CONFIGURATION_BUILD_DIR=${CONFIGURATION_BUILD_DIR} $target_string
}
# change the working directory to trunk
cd "$( dirname "$0" )/../.."
# build setting
CONFIGURATION_BUILD_DIR=./xcodebuild
CONFIGURATION=Debug
export GYP_DEFINES="OS=ios target_arch=arm armv7=1 arm_neon=1"
# TODO(sjlee): remove this script.
# (https://webrtc-codereview.appspot.com/1874005)
# update gyp settings
echo '[Updating gyp settings...]'
gclient runhooks
./build/gyp_chromium --depth=. \
webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_components.gyp
./build/gyp_chromium --depth=. \
webrtc/modules/video_coding/utility/video_coding_utility.gyp
./build/gyp_chromium --depth=. third_party/opus/opus.gyp
./build/gyp_chromium --depth=. third_party/libyuv/libyuv.gyp
./build/gyp_chromium --depth=. third_party/libjpeg/libjpeg.gyp
# build the xcode projects
echo '[Building xcode projects...]'
build_project "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_components.xcodeproj"
build_project "webrtc/modules/video_coding/utility/video_coding_utility.xcodeproj"
build_project "third_party/opus/opus.xcodeproj" "opus"
build_project "third_party/libjpeg/libjpeg.xcodeproj"
build_project "third_party/libyuv/libyuv.xcodeproj"
# build the libvpx
cd third_party/libvpx/source/libvpx
./configure --target=armv7-darwin-gcc --disable-vp9 \
--libc=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk
make
cd -
cp third_party/libvpx/source/libvpx/libvpx.a \
${CONFIGURATION_BUILD_DIR}/${CONFIGURATION}-iphoneos
echo "[Building xcode projects is success...]\n"

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef WEBRTC_MODULES_VIDEO_CAPTURE_IOS_DEVICE_INFO_IOS_H_
#define WEBRTC_MODULES_VIDEO_CAPTURE_IOS_DEVICE_INFO_IOS_H_
#include "webrtc/modules/video_capture/device_info_impl.h"
namespace webrtc {
namespace videocapturemodule {
class DeviceInfoIos : public DeviceInfoImpl {
public:
explicit DeviceInfoIos(const int32_t device_id);
virtual ~DeviceInfoIos();
// Implementation of DeviceInfoImpl.
virtual int32_t Init() OVERRIDE;
virtual uint32_t NumberOfDevices() OVERRIDE;
virtual int32_t GetDeviceName(
uint32_t deviceNumber,
char* deviceNameUTF8,
uint32_t deviceNameLength,
char* deviceUniqueIdUTF8,
uint32_t deviceUniqueIdUTF8Length,
char* productUniqueIdUTF8 = 0,
uint32_t productUniqueIdUTF8Length = 0) OVERRIDE;
virtual int32_t NumberOfCapabilities(const char* deviceUniqueIdUTF8) OVERRIDE;
virtual int32_t GetCapability(const char* deviceUniqueIdUTF8,
const uint32_t deviceCapabilityNumber,
VideoCaptureCapability& capability) OVERRIDE;
virtual int32_t GetBestMatchedCapability(
const char* deviceUniqueIdUTF8,
const VideoCaptureCapability& requested,
VideoCaptureCapability& resulting) OVERRIDE;
virtual int32_t DisplayCaptureSettingsDialogBox(
const char* deviceUniqueIdUTF8,
const char* dialogTitleUTF8,
void* parentWindow,
uint32_t positionX,
uint32_t positionY) OVERRIDE;
virtual int32_t GetOrientation(const char* deviceUniqueIdUTF8,
VideoCaptureRotation& orientation) OVERRIDE;
virtual int32_t CreateCapabilityMap(
const char* device_unique_id_utf8) OVERRIDE;
};
} // namespace videocapturemodule
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CAPTURE_IOS_DEVICE_INFO_IOS_H_

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2013 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 "webrtc/modules/video_capture/ios/device_info_ios.h"
#include "webrtc/modules/video_capture/ios/device_info_ios_objc.h"
#include "webrtc/modules/video_capture/video_capture_impl.h"
#include "webrtc/system_wrappers/interface/trace.h"
using namespace webrtc;
using namespace videocapturemodule;
#define IOS_UNSUPPORTED() \
WEBRTC_TRACE(kTraceError, \
kTraceVideoCapture, \
_id, \
"%s is not supported on the iOS platform.", \
__FUNCTION__); \
return -1;
VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo(
const int32_t device_id) {
return new DeviceInfoIos(device_id);
}
DeviceInfoIos::DeviceInfoIos(const int32_t device_id)
: DeviceInfoImpl(device_id) {}
DeviceInfoIos::~DeviceInfoIos() {}
int32_t DeviceInfoIos::Init() { return 0; }
uint32_t DeviceInfoIos::NumberOfDevices() {
return [DeviceInfoIosObjC captureDeviceCount];
}
int32_t DeviceInfoIos::GetDeviceName(uint32_t deviceNumber,
char* deviceNameUTF8,
uint32_t deviceNameUTF8Length,
char* deviceUniqueIdUTF8,
uint32_t deviceUniqueIdUTF8Length,
char* productUniqueIdUTF8,
uint32_t productUniqueIdUTF8Length) {
NSString* deviceName = [DeviceInfoIosObjC deviceNameForIndex:deviceNumber];
NSString* deviceUniqueId =
[DeviceInfoIosObjC deviceUniqueIdForIndex:deviceNumber];
strncpy(deviceNameUTF8, [deviceName UTF8String], deviceNameUTF8Length);
deviceNameUTF8[deviceNameUTF8Length - 1] = '\0';
strncpy(deviceUniqueIdUTF8,
[deviceUniqueId UTF8String],
deviceUniqueIdUTF8Length);
deviceUniqueIdUTF8[deviceUniqueIdUTF8Length - 1] = '\0';
if (productUniqueIdUTF8) {
productUniqueIdUTF8[0] = '\0';
}
return 0;
}
int32_t DeviceInfoIos::NumberOfCapabilities(const char* deviceUniqueIdUTF8) {
IOS_UNSUPPORTED();
}
int32_t DeviceInfoIos::GetCapability(const char* deviceUniqueIdUTF8,
const uint32_t deviceCapabilityNumber,
VideoCaptureCapability& capability) {
IOS_UNSUPPORTED();
}
int32_t DeviceInfoIos::GetBestMatchedCapability(
const char* deviceUniqueIdUTF8,
const VideoCaptureCapability& requested,
VideoCaptureCapability& resulting) {
IOS_UNSUPPORTED();
}
int32_t DeviceInfoIos::DisplayCaptureSettingsDialogBox(
const char* deviceUniqueIdUTF8,
const char* dialogTitleUTF8,
void* parentWindow,
uint32_t positionX,
uint32_t positionY) {
IOS_UNSUPPORTED();
}
int32_t DeviceInfoIos::GetOrientation(const char* deviceUniqueIdUTF8,
VideoCaptureRotation& orientation) {
if (strcmp(deviceUniqueIdUTF8, "Front Camera") == 0) {
orientation = kCameraRotate0;
} else {
orientation = kCameraRotate90;
}
return orientation;
}
int32_t DeviceInfoIos::CreateCapabilityMap(const char* deviceUniqueIdUTF8) {
IOS_UNSUPPORTED();
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef WEBRTC_MODULES_VIDEO_CAPTURE_IOS_DEVICE_INFO_IOS_OBJC_H_
#define WEBRTC_MODULES_VIDEO_CAPTURE_IOS_DEVICE_INFO_IOS_OBJC_H_
#import <AVFoundation/AVFoundation.h>
@interface DeviceInfoIosObjC : NSObject
+ (int)captureDeviceCount;
+ (AVCaptureDevice*)captureDeviceForIndex:(int)index;
+ (AVCaptureDevice*)captureDeviceForUniqueId:(NSString*)uniqueId;
+ (NSString*)deviceNameForIndex:(int)index;
+ (NSString*)deviceUniqueIdForIndex:(int)index;
+ (NSString*)deviceNameForUniqueId:(NSString*)uniqueId;
@end
#endif // WEBRTC_MODULES_VIDEO_CAPTURE_IOS_DEVICE_INFO_IOS_OBJC_H_

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2013 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.
*/
#import <AVFoundation/AVFoundation.h>
#import "webrtc/modules/video_capture/ios/device_info_ios_objc.h"
@implementation DeviceInfoIosObjC
+ (int)captureDeviceCount {
return [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
}
+ (AVCaptureDevice*)captureDeviceForIndex:(int)index {
return [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]
objectAtIndex:index];
}
+ (AVCaptureDevice*)captureDeviceForUniqueId:(NSString*)uniqueId {
for (AVCaptureDevice* device in
[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
if ([uniqueId isEqual:device.uniqueID]) {
return device;
}
}
return nil;
}
+ (NSString*)deviceNameForIndex:(int)index {
return [DeviceInfoIosObjC captureDeviceForIndex:index].localizedName;
}
+ (NSString*)deviceUniqueIdForIndex:(int)index {
return [DeviceInfoIosObjC captureDeviceForIndex:index].uniqueID;
}
+ (NSString*)deviceNameForUniqueId:(NSString*)uniqueId {
return [[AVCaptureDevice deviceWithUniqueID:uniqueId] localizedName];
}
@end

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef WEBRTC_MODULES_VIDEO_CAPTURE_IOS_VIDEO_CAPTURE_IOS_H_
#define WEBRTC_MODULES_VIDEO_CAPTURE_IOS_VIDEO_CAPTURE_IOS_H_
#include "webrtc/modules/video_capture/video_capture_impl.h"
@class VideoCaptureIosObjC;
namespace webrtc {
namespace videocapturemodule {
class VideoCaptureIos : public VideoCaptureImpl {
public:
explicit VideoCaptureIos(const int32_t capture_id);
virtual ~VideoCaptureIos();
static VideoCaptureModule* Create(const int32_t capture_id,
const char* device_unique_id_utf8);
// Implementation of VideoCaptureImpl.
virtual int32_t StartCapture(
const VideoCaptureCapability& capability) OVERRIDE;
virtual int32_t StopCapture() OVERRIDE;
virtual bool CaptureStarted() OVERRIDE;
virtual int32_t CaptureSettings(VideoCaptureCapability& settings) OVERRIDE;
private:
VideoCaptureIosObjC* capture_device_;
bool is_capturing_;
int32_t id_;
VideoCaptureCapability capability_;
};
} // namespace videocapturemodule
} // namespace webrtc
#endif // WEBRTC_MODULES_VIDEO_CAPTURE_IOS_VIDEO_CAPTURE_IOS_H_

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2013 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 "webrtc/modules/video_capture/ios/device_info_ios_objc.h"
#include "webrtc/modules/video_capture/ios/video_capture_ios_objc.h"
#include "webrtc/system_wrappers/interface/ref_count.h"
#include "webrtc/system_wrappers/interface/scoped_refptr.h"
#include "webrtc/system_wrappers/interface/trace.h"
using namespace webrtc;
using namespace videocapturemodule;
VideoCaptureModule* VideoCaptureImpl::Create(const int32_t capture_id,
const char* deviceUniqueIdUTF8) {
return VideoCaptureIos::Create(capture_id, deviceUniqueIdUTF8);
}
VideoCaptureIos::VideoCaptureIos(const int32_t capture_id)
: VideoCaptureImpl(capture_id), is_capturing_(false), id_(capture_id) {
capability_.width = kDefaultWidth;
capability_.height = kDefaultHeight;
capability_.maxFPS = kDefaultFrameRate;
}
VideoCaptureIos::~VideoCaptureIos() {
if (capture_device_) {
[capture_device_ stopCapture];
}
}
VideoCaptureModule* VideoCaptureIos::Create(const int32_t capture_id,
const char* deviceUniqueIdUTF8) {
if (!deviceUniqueIdUTF8[0]) {
return NULL;
}
RefCountImpl<VideoCaptureIos>* capture_module =
new RefCountImpl<VideoCaptureIos>(capture_id);
const int32_t name_length = strlen(deviceUniqueIdUTF8);
if (name_length > kVideoCaptureUniqueNameLength)
return NULL;
capture_module->_deviceUniqueId = new char[name_length + 1];
strncpy(capture_module->_deviceUniqueId, deviceUniqueIdUTF8, name_length + 1);
capture_module->_deviceUniqueId[name_length] = '\0';
capture_module->capture_device_ =
[[VideoCaptureIosObjC alloc] initWithOwner:capture_module
captureId:capture_module->id_];
if (!capture_module->capture_device_) {
return NULL;
}
if (![capture_module->capture_device_ setCaptureDeviceByUniqueId:[
[NSString alloc] initWithCString:deviceUniqueIdUTF8
encoding:NSUTF8StringEncoding]]) {
return NULL;
}
return capture_module;
}
int32_t VideoCaptureIos::StartCapture(
const VideoCaptureCapability& capability) {
capability_ = capability;
if (![capture_device_ startCaptureWithCapability:capability]) {
return -1;
}
is_capturing_ = true;
return 0;
}
int32_t VideoCaptureIos::StopCapture() {
if (![capture_device_ stopCapture]) {
return -1;
}
is_capturing_ = false;
return 0;
}
bool VideoCaptureIos::CaptureStarted() { return is_capturing_; }
int32_t VideoCaptureIos::CaptureSettings(VideoCaptureCapability& settings) {
settings = capability_;
settings.rawType = kVideoNV12;
return 0;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2013 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.
*/
#ifndef WEBRTC_MODULES_VIDEO_CAPTURE_IOS_VIDEO_CAPTURE_IOS_OBJC_H_
#define WEBRTC_MODULES_VIDEO_CAPTURE_IOS_VIDEO_CAPTURE_IOS_OBJC_H_
#import <UIKit/UIKit.h>
#include "webrtc/modules/video_capture/ios/video_capture_ios.h"
@interface VideoCaptureIosObjC
: UIViewController<AVCaptureVideoDataOutputSampleBufferDelegate> {
@private
webrtc::videocapturemodule::VideoCaptureIos* _owner;
webrtc::VideoCaptureCapability _capability;
AVCaptureSession* _captureSession;
int _captureId;
}
@property webrtc::VideoCaptureRotation frameRotation;
// custom initializer. Instance of VideoCaptureIos is needed
// for callback purposes.
// default init methods have been overridden to return nil.
- (id)initWithOwner:(webrtc::videocapturemodule::VideoCaptureIos*)owner
captureId:(int)captureId;
- (BOOL)setCaptureDeviceByUniqueId:(NSString*)uniequeId;
- (BOOL)startCaptureWithCapability:
(const webrtc::VideoCaptureCapability&)capability;
- (BOOL)stopCapture;
@end
#endif // WEBRTC_MODULES_VIDEO_CAPTURE_IOS_VIDEO_CAPTURE_IOS_OBJC_H_

View File

@ -0,0 +1,287 @@
/*
* Copyright (c) 2013 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.
*/
#import "webrtc/modules/video_capture/ios/device_info_ios_objc.h"
#import "webrtc/modules/video_capture/ios/video_capture_ios_objc.h"
#include "webrtc/system_wrappers/interface/trace.h"
using namespace webrtc;
using namespace webrtc::videocapturemodule;
@interface VideoCaptureIosObjC (hidden)
- (int)changeCaptureInputWithName:(NSString*)captureDeviceName;
@end
@implementation VideoCaptureIosObjC
@synthesize frameRotation = _framRotation;
- (id)initWithOwner:(VideoCaptureIos*)owner captureId:(int)captureId {
if (self == [super init]) {
_owner = owner;
_captureId = captureId;
_captureSession = [[AVCaptureSession alloc] init];
if (!_captureSession) {
return nil;
}
// create and configure a new output (using callbacks)
AVCaptureVideoDataOutput* captureOutput =
[[AVCaptureVideoDataOutput alloc] init];
[captureOutput setSampleBufferDelegate:self
queue:dispatch_get_current_queue()];
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* val = [NSNumber
numberWithUnsignedInt:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];
NSDictionary* videoSettings =
[NSDictionary dictionaryWithObject:val forKey:key];
captureOutput.videoSettings = videoSettings;
// add new output
if ([_captureSession canAddOutput:captureOutput]) {
[_captureSession addOutput:captureOutput];
} else {
WEBRTC_TRACE(kTraceError,
kTraceVideoCapture,
_captureId,
"%s:%s:%d Could not add output to AVCaptureSession ",
__FILE__,
__FUNCTION__,
__LINE__);
}
NSNotificationCenter* notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(onVideoError:)
name:AVCaptureSessionRuntimeErrorNotification
object:_captureSession];
}
return self;
}
- (BOOL)setCaptureDeviceByUniqueId:(NSString*)uniqueId {
// check to see if the camera is already set
if (_captureSession) {
NSArray* currentInputs = [NSArray arrayWithArray:[_captureSession inputs]];
if ([currentInputs count] > 0) {
AVCaptureDeviceInput* currentInput = [currentInputs objectAtIndex:0];
if ([uniqueId isEqualToString:[currentInput.device localizedName]]) {
return YES;
}
}
}
return [self changeCaptureInputByUniqueId:uniqueId];
}
- (BOOL)startCaptureWithCapability:(const VideoCaptureCapability&)capability {
if (!_captureSession) {
return NO;
}
// check limits of the resolution
if (capability.maxFPS < 0 || capability.maxFPS > 60) {
return NO;
}
if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1920x1080]) {
if (capability.width > 1920 || capability.height > 1080) {
return NO;
}
} else if ([_captureSession
canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
if (capability.width > 1280 || capability.height > 720) {
return NO;
}
} else if ([_captureSession
canSetSessionPreset:AVCaptureSessionPreset640x480]) {
if (capability.width > 640 || capability.height > 480) {
return NO;
}
} else if ([_captureSession
canSetSessionPreset:AVCaptureSessionPreset352x288]) {
if (capability.width > 352 || capability.height > 288) {
return NO;
}
} else if (capability.width < 0 || capability.height < 0) {
return NO;
}
_capability = capability;
NSArray* currentOutputs = [_captureSession outputs];
if ([currentOutputs count] == 0) {
return NO;
}
NSString* captureQuality =
[NSString stringWithString:AVCaptureSessionPresetLow];
if (_capability.width >= 1920 || _capability.height >= 1080) {
captureQuality =
[NSString stringWithString:AVCaptureSessionPreset1920x1080];
} else if (_capability.width >= 1280 || _capability.height >= 720) {
captureQuality = [NSString stringWithString:AVCaptureSessionPreset1280x720];
} else if (_capability.width >= 640 || _capability.height >= 480) {
captureQuality = [NSString stringWithString:AVCaptureSessionPreset640x480];
} else if (_capability.width >= 352 || _capability.height >= 288) {
captureQuality = [NSString stringWithString:AVCaptureSessionPreset352x288];
}
AVCaptureVideoDataOutput* currentOutput =
(AVCaptureVideoDataOutput*)[currentOutputs objectAtIndex:0];
// begin configuration for the AVCaptureSession
[_captureSession beginConfiguration];
// picture resolution
[_captureSession setSessionPreset:captureQuality];
// take care of capture framerate now
AVCaptureConnection* connection =
[currentOutput connectionWithMediaType:AVMediaTypeVideo];
CMTime cm_time = {1, _capability.maxFPS, kCMTimeFlags_Valid, 0};
[connection setVideoMinFrameDuration:cm_time];
[connection setVideoMaxFrameDuration:cm_time];
// finished configuring, commit settings to AVCaptureSession.
[_captureSession commitConfiguration];
[_captureSession startRunning];
[captureQuality release];
return YES;
}
- (void)onVideoError {
// TODO(sjlee): make the specific error handling with this notification.
WEBRTC_TRACE(kTraceError,
kTraceVideoCapture,
_captureId,
"%s:%s:%d [AVCaptureSession startRunning] error.",
__FILE__,
__FUNCTION__,
__LINE__);
}
- (BOOL)stopCapture {
if (!_captureSession) {
return NO;
}
[_captureSession stopRunning];
return YES;
}
- (BOOL)changeCaptureInputByUniqueId:(NSString*)uniqueId {
NSArray* currentInputs = [_captureSession inputs];
// remove current input
if ([currentInputs count] > 0) {
AVCaptureInput* currentInput =
(AVCaptureInput*)[currentInputs objectAtIndex:0];
[_captureSession removeInput:currentInput];
}
// Look for input device with the name requested (as our input param)
// get list of available capture devices
int captureDeviceCount = [DeviceInfoIosObjC captureDeviceCount];
if (captureDeviceCount <= 0) {
return NO;
}
AVCaptureDevice* captureDevice =
[DeviceInfoIosObjC captureDeviceForUniqueId:uniqueId];
if (!captureDevice) {
return NO;
}
// now create capture session input out of AVCaptureDevice
NSError* deviceError = nil;
AVCaptureDeviceInput* newCaptureInput =
[AVCaptureDeviceInput deviceInputWithDevice:captureDevice
error:&deviceError];
if (!newCaptureInput) {
const char* errorMessage = [[deviceError localizedDescription] UTF8String];
WEBRTC_TRACE(kTraceError,
kTraceVideoCapture,
_captureId,
"%s:%s:%d deviceInputWithDevice error:%s",
__FILE__,
__FUNCTION__,
__LINE__,
errorMessage);
return NO;
}
// try to add our new capture device to the capture session
[_captureSession beginConfiguration];
BOOL addedCaptureInput = NO;
if ([_captureSession canAddInput:newCaptureInput]) {
[_captureSession addInput:newCaptureInput];
addedCaptureInput = YES;
} else {
addedCaptureInput = NO;
}
[_captureSession commitConfiguration];
return addedCaptureInput;
}
- (void)captureOutput:(AVCaptureOutput*)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection*)connection {
const int kFlags = 0;
CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
if (CVPixelBufferLockBaseAddress(videoFrame, kFlags) != kCVReturnSuccess) {
return;
}
const int kYPlaneIndex = 0;
const int kUVPlaneIndex = 1;
uint8_t* baseAddress =
(uint8_t*)CVPixelBufferGetBaseAddressOfPlane(videoFrame, kYPlaneIndex);
int yPlaneBytesPerRow =
CVPixelBufferGetBytesPerRowOfPlane(videoFrame, kYPlaneIndex);
int yPlaneHeight = CVPixelBufferGetHeightOfPlane(videoFrame, kYPlaneIndex);
int uvPlaneBytesPerRow =
CVPixelBufferGetBytesPerRowOfPlane(videoFrame, kUVPlaneIndex);
int uvPlaneHeight = CVPixelBufferGetHeightOfPlane(videoFrame, kUVPlaneIndex);
int frameSize =
yPlaneBytesPerRow * yPlaneHeight + uvPlaneBytesPerRow * uvPlaneHeight;
VideoCaptureCapability tempCaptureCapability;
tempCaptureCapability.width = CVPixelBufferGetWidth(videoFrame);
tempCaptureCapability.height = CVPixelBufferGetHeight(videoFrame);
tempCaptureCapability.maxFPS = _capability.maxFPS;
tempCaptureCapability.rawType = kVideoNV12;
_owner->IncomingFrame(baseAddress, frameSize, tempCaptureCapability, 0);
CVPixelBufferUnlockBaseAddress(videoFrame, kFlags);
}
@end

View File

@ -115,6 +115,18 @@
'android/video_capture_android.h',
],
}], # android
['OS=="ios"', {
'sources': [
'ios/device_info_ios.h',
'ios/device_info_ios.mm',
'ios/device_info_ios_objc.h',
'ios/device_info_ios_objc.mm',
'ios/video_capture_ios.h',
'ios/video_capture_ios.mm',
'ios/video_capture_ios_objc.h',
'ios/video_capture_ios_objc.mm',
],
}], # ios
], # conditions
}], # include_internal_video_capture
], # conditions

View File

@ -30,17 +30,4 @@ VideoCaptureModule::DeviceInfo* VideoCaptureFactory::CreateDeviceInfo(
return videocapturemodule::VideoCaptureImpl::CreateDeviceInfo(id);
}
// TODO(sjlee): land https://webrtc-codereview.appspot.com/1641004/
#ifdef WEBRTC_IOS
namespace videocapturemodule {
VideoCaptureModule* VideoCaptureImpl::Create(int32_t, const char*) {
return NULL;
}
VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo(int32_t) {
return NULL;
}
} // namespace videocaptureimpl
#endif
} // namespace webrtc