145 lines
5.2 KiB
Text
145 lines
5.2 KiB
Text
|
#include <vector>
|
||
|
#include <string>
|
||
|
#include "Core/Config.h"
|
||
|
#import "CameraHelper.h"
|
||
|
#import <UIKit/UIKit.h>
|
||
|
|
||
|
@interface CameraHelper() {
|
||
|
AVCaptureSession *captureSession;
|
||
|
AVCaptureVideoPreviewLayer *previewLayer;
|
||
|
}
|
||
|
@end
|
||
|
|
||
|
@implementation CameraHelper
|
||
|
|
||
|
std::vector<std::string> __cameraGetDeviceList() {
|
||
|
std::vector<std::string> deviceList;
|
||
|
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
|
||
|
deviceList.push_back([device.localizedName UTF8String]);
|
||
|
}
|
||
|
return deviceList;
|
||
|
}
|
||
|
|
||
|
NSString *getSelectedCamera() {
|
||
|
NSString *selectedCamera = [NSString stringWithCString:g_Config.sCameraDevice.c_str() encoding:[NSString defaultCStringEncoding]];
|
||
|
return selectedCamera;
|
||
|
}
|
||
|
|
||
|
-(int) checkPermission {
|
||
|
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
||
|
NSLog(@"CameraHelper::checkPermission %ld", (long)status);
|
||
|
|
||
|
switch (status) {
|
||
|
case AVAuthorizationStatusNotDetermined: {
|
||
|
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
|
||
|
if (granted) {
|
||
|
NSLog(@"camera permission granted");
|
||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||
|
[self startVideo];
|
||
|
});
|
||
|
} else {
|
||
|
NSLog(@"camera permission denied");
|
||
|
}
|
||
|
}];
|
||
|
return 1;
|
||
|
}
|
||
|
case AVAuthorizationStatusRestricted:
|
||
|
case AVAuthorizationStatusDenied: {
|
||
|
NSLog(@"camera permission denied");
|
||
|
return 1;
|
||
|
}
|
||
|
case AVAuthorizationStatusAuthorized: {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-(void) startVideo {
|
||
|
NSLog(@"CameraHelper::startVideo");
|
||
|
if ([self checkPermission]) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||
|
NSError *error = nil;
|
||
|
|
||
|
captureSession = [[AVCaptureSession alloc] init];
|
||
|
captureSession.sessionPreset = AVCaptureSessionPresetMedium;
|
||
|
|
||
|
AVCaptureDeviceInput *videoInput = nil;
|
||
|
NSString *selectedCamera = getSelectedCamera();
|
||
|
for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
|
||
|
if ([device.localizedName isEqualToString:selectedCamera]) {
|
||
|
videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
|
||
|
}
|
||
|
}
|
||
|
if (videoInput == nil || error) {
|
||
|
NSLog(@"selectedCamera error; try default device");
|
||
|
|
||
|
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||
|
if (videoDevice == nil) {
|
||
|
NSLog(@"videoDevice error");
|
||
|
return;
|
||
|
}
|
||
|
videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
|
||
|
if (videoInput == nil) {
|
||
|
NSLog(@"videoInput error");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
[captureSession addInput:videoInput];
|
||
|
|
||
|
AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
|
||
|
videoOutput.videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey: (id)kCVPixelBufferPixelFormatTypeKey];
|
||
|
|
||
|
[captureSession addOutput:videoOutput];
|
||
|
|
||
|
dispatch_queue_t queue = dispatch_queue_create("cameraQueue", NULL);
|
||
|
[videoOutput setSampleBufferDelegate:self queue:queue];
|
||
|
|
||
|
previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
|
||
|
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
|
||
|
|
||
|
[previewLayer setFrame:CGRectMake(0, 0, 480, 272)];
|
||
|
|
||
|
[captureSession startRunning];
|
||
|
});
|
||
|
}
|
||
|
|
||
|
-(void) stopVideo {
|
||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||
|
[captureSession stopRunning];
|
||
|
});
|
||
|
}
|
||
|
|
||
|
- (void) captureOutput:(AVCaptureOutput *)captureOutput
|
||
|
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
|
||
|
fromConnection:(AVCaptureConnection *)connection {
|
||
|
CGImageRef cgImage = [self imageFromSampleBuffer:sampleBuffer];
|
||
|
UIImage *theImage = [UIImage imageWithCGImage: cgImage];
|
||
|
CGImageRelease(cgImage);
|
||
|
NSData *imageData = UIImageJPEGRepresentation(theImage, 0.6);
|
||
|
|
||
|
[self.delegate PushCameraImageIOS:imageData.length buffer:(unsigned char*)imageData.bytes];
|
||
|
}
|
||
|
|
||
|
- (CGImageRef) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer {
|
||
|
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
||
|
CVPixelBufferLockBaseAddress(imageBuffer,0);
|
||
|
void* baseAddress = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0);
|
||
|
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
|
||
|
size_t width = CVPixelBufferGetWidth(imageBuffer);
|
||
|
size_t height = CVPixelBufferGetHeight(imageBuffer);
|
||
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
||
|
|
||
|
CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
|
||
|
CGImageRef newImage = CGBitmapContextCreateImage(newContext);
|
||
|
CGContextRelease(newContext);
|
||
|
|
||
|
CGColorSpaceRelease(colorSpace);
|
||
|
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
|
||
|
return newImage;
|
||
|
}
|
||
|
|
||
|
@end
|