mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Add camera/location support for iOS
Add front camera support for Android Allow to change the active camera in-game
This commit is contained in:
1 parent
1d6d66ac43
commit
5fbf2d7713
24 files changed
+409
-44
No files matched your search
@@ -0,0 +1,144 @@
|
||||
#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
|
||||
Reference in new issue
Block a user