ifish/Ifish/controllers/IfishYooseeFile/IfishYooseeHelper/IfishYooseeP2PCore/CameraManager.m

274 lines
8.8 KiB
Objective-C

//
// CameraManager.m
// Yoosee
//
// Created by guojunyi on 14-4-18.
// Copyright (c) 2014年 guojunyi. All rights reserved.
//
#import "CameraManager.h"
#import "Constants.h"
#import "config.h"
@interface CameraManager ()
@end
@implementation CameraManager
+ (id)sharedManager
{
static CameraManager *manager = nil;
@synchronized([self class]){
if(manager==nil){
DLog(@"Alloc CameraManager");
manager = [[CameraManager alloc] init];
}
}
return manager;
}
#pragma mark - 寻找前置摄像头,没有则返回空
- (AVCaptureDevice *)frontFacingCamera {
return [self cameraWithPosition:AVCaptureDevicePositionFront];
}
#pragma mark - 寻找背置摄像头,没有则返回空
- (AVCaptureDevice *)backFacingCamera {
return [self cameraWithPosition:AVCaptureDevicePositionBack];
}
#pragma mark - 从指定AVCaptureDevice的位置获取设置
- (AVCaptureDevice *)cameraWithPosition:(AVCaptureDevicePosition) position {
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
if ([device position] == position) {
return device;
}
}
return nil;
}
- (NSUInteger)cameraCount {
return [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
}
#pragma mark - 前后摄像头切换
- (int)cameraChange {
if ([self cameraCount] > 1) {
NSError *error;
AVCaptureDevicePosition position = self.input.device.position;
[self.session beginConfiguration];
[self.session removeInput:self.input];
self.input = nil;
AVCaptureDeviceInput * newDeviceInput = nil;
if (position == AVCaptureDevicePositionBack) {
newDeviceInput =
[AVCaptureDeviceInput deviceInputWithDevice:[self frontFacingCamera] error:&error];
} else if (position == AVCaptureDevicePositionFront) {
newDeviceInput =
[AVCaptureDeviceInput deviceInputWithDevice:[self backFacingCamera] error:&error];
}
if (newDeviceInput != nil) {
if ([self.session canAddInput:newDeviceInput]) {
[self.session addInput:newDeviceInput];
self.input = newDeviceInput;
}
}
position = self.input.device.position;
[self setFrontCameraChangeOrientationToLandscapeRight];
[self.session commitConfiguration];
}
//自动对焦
//[self autoFocusAtPoint:CGPointMake(.5f, .5f)];
return self.input.device.position;
}
#pragma mark - 自动对焦
- (void)autoFocusAtPoint:(CGPoint)point {
AVCaptureDevice *device = self.input.device;
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
NSError *error;
if ([device lockForConfiguration:&error]) {
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeAutoFocus];
[device unlockForConfiguration];
}
}
}
- (void)setFrontCameraChangeOrientationToLandscapeRight {
for (AVCaptureConnection *connection in self.output.connections)
if (connection.supportsVideoOrientation && connection.videoOrientation != AVCaptureVideoOrientationLandscapeRight)
[connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
}
- (void)setFrameRate:(NSInteger)fRate {
DLog(@"setFrameRate");
if (fRate > 0)
{
for (AVCaptureConnection *connection in self.output.connections)
{
if ([connection respondsToSelector:@selector(setVideoMinFrameDuration:)])
connection.videoMinFrameDuration = CMTimeMake(1, fRate);
if ([connection respondsToSelector:@selector(setVideoMaxFrameDuration:)])
if ( connection.isVideoMaxFrameDurationSupported ) {
connection.videoMaxFrameDuration = CMTimeMake(1, fRate);
}
}
}
else
{
for (AVCaptureConnection *connection in self.output.connections)
{
if ([connection respondsToSelector:@selector(setVideoMinFrameDuration:)])
connection.videoMinFrameDuration = kCMTimeInvalid; // This sets videoMinFrameDuration back to default
if ([connection respondsToSelector:@selector(setVideoMaxFrameDuration:)])
connection.videoMaxFrameDuration = kCMTimeInvalid; // This sets videoMaxFrameDuration back to default
}
}
}
- (NSInteger)frameRate {
return self.frameRate;
}
- (void)addCameraView:(UIView *)view
{
UIView *bgView = [[UIView alloc] initWithFrame:view.bounds];
[bgView setBackgroundColor:[UIColor blackColor]];
[self.previewLayer setBackgroundColor:[UIColor blackColor].CGColor];
[self.previewLayer setFrame:view.bounds];
[bgView.layer addSublayer:self.previewLayer];
[view addSubview:bgView];
[view sendSubviewToBack:bgView];
[self.previewLayer setOrientation:AVCaptureVideoOrientationLandscapeRight];
}
-(void)startCamera:(BOOL)isFont{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
[session setSessionPreset:AVCaptureSessionPreset352x288];
AVCaptureVideoDataOutput * newVideoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
// 指定像素格式
newVideoDataOutput.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kCVPixelFormatType_32BGRA],
kCVPixelBufferPixelFormatTypeKey,nil];
newVideoDataOutput.alwaysDiscardsLateVideoFrames = YES;
// 配置图像输出
if ([session canAddOutput:newVideoDataOutput]) {
[session addOutput:newVideoDataOutput];
dispatch_queue_t queue = dispatch_queue_create("com.yige.cameraProcessingQueue", NULL);
[newVideoDataOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
self.output = newVideoDataOutput;
}
[newVideoDataOutput release];
// 设置预览祯率
self.frameRate = VIDEO_FRAME_RATE;
if(isFont){
AVCaptureDeviceInput * newDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:[self frontFacingCamera] error:nil];
if ([session canAddInput:newDeviceInput]) {
[session addInput:newDeviceInput];
self.input = newDeviceInput;
}
}else{
AVCaptureDeviceInput * newDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:[self backFacingCamera] error:nil];
if ([session canAddInput:newDeviceInput]) {
[session addInput:newDeviceInput];
self.input = newDeviceInput;
}
}
AVCaptureVideoPreviewLayer * newPreviewLayer =
[[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[newPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
self.previewLayer = newPreviewLayer;
[newPreviewLayer release];
for (AVCaptureConnection *connection in self.output.connections)
if (connection.supportsVideoOrientation && connection.videoOrientation != AVCaptureVideoOrientationLandscapeRight)
[connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
[session commitConfiguration];
[session startRunning];
self.session = session;
self.isRun = YES;
[session release];
}
-(void)stopCamera{
if([self session]){
self.isRun = NO;
[self.session stopRunning];
// [self.session release];
// [self.input release];
// [self.output release];
// [self.previewLayer release];
self.session = nil;
self.input = nil;
self.output = nil;
self.previewLayer = nil;
}
}
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
if(self.isRun){
@autoreleasepool {
self.isFinishCaptureOutput = NO;
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(imageBuffer,0);
uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer);
DWORD dwSize = CVPixelBufferGetDataSize(imageBuffer);
DWORD dwWidth = CVPixelBufferGetWidth(imageBuffer);
DWORD dwHeight = CVPixelBufferGetHeight(imageBuffer);
//设备端生成视频
if (self.session.sessionPreset == AVCaptureSessionPreset352x288) {
fgFillVideoRawFrame(baseAddress, dwSize, dwWidth, dwHeight, 0);
}else {
fgFillVideoRawFrame(baseAddress, dwSize, dwWidth, dwHeight, 1);
}
CVPixelBufferUnlockBaseAddress(imageBuffer, 0);
self.isFinishCaptureOutput = YES;
}
}
}
@end