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:
parent
3d0019f09a
commit
d690eab54f
@ -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
69
webrtc/build/vie-webrtc.sh
Executable 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"
|
63
webrtc/modules/video_capture/ios/device_info_ios.h
Normal file
63
webrtc/modules/video_capture/ios/device_info_ios.h
Normal 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_
|
108
webrtc/modules/video_capture/ios/device_info_ios.mm
Normal file
108
webrtc/modules/video_capture/ios/device_info_ios.mm
Normal 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();
|
||||
}
|
25
webrtc/modules/video_capture/ios/device_info_ios_objc.h
Normal file
25
webrtc/modules/video_capture/ios/device_info_ios_objc.h
Normal 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_
|
49
webrtc/modules/video_capture/ios/device_info_ios_objc.mm
Normal file
49
webrtc/modules/video_capture/ios/device_info_ios_objc.mm
Normal 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
|
45
webrtc/modules/video_capture/ios/video_capture_ios.h
Normal file
45
webrtc/modules/video_capture/ios/video_capture_ios.h
Normal 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_
|
99
webrtc/modules/video_capture/ios/video_capture_ios.mm
Normal file
99
webrtc/modules/video_capture/ios/video_capture_ios.mm
Normal 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;
|
||||
}
|
40
webrtc/modules/video_capture/ios/video_capture_ios_objc.h
Normal file
40
webrtc/modules/video_capture/ios/video_capture_ios_objc.h
Normal 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_
|
287
webrtc/modules/video_capture/ios/video_capture_ios_objc.mm
Normal file
287
webrtc/modules/video_capture/ios/video_capture_ios_objc.mm
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user