diff --git a/modules/highgui/include/opencv2/highgui/cap_ios.h b/modules/highgui/include/opencv2/highgui/cap_ios.h index 5bd5fe3c67..db3928f13b 100644 --- a/modules/highgui/include/opencv2/highgui/cap_ios.h +++ b/modules/highgui/include/opencv2/highgui/cap_ios.h @@ -1,6 +1,4 @@ -/* - * cap_ios.h - * For iOS video I/O +/* For iOS video I/O * by Eduard Feicho on 29/07/12 * Copyright 2012. All rights reserved. * @@ -90,6 +88,12 @@ - (void)createVideoPreviewLayer; - (void)updateOrientation; +- (void)lockFocus; +- (void)unlockFocus; +- (void)lockExposure; +- (void)unlockExposure; +- (void)lockBalance; +- (void)unlockBalance; @end @@ -116,6 +120,7 @@ BOOL grayscaleMode; BOOL recordVideo; + BOOL rotateVideo; AVAssetWriterInput* recordAssetWriterInput; AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor; AVAssetWriter* recordAssetWriter; @@ -128,6 +133,7 @@ @property (nonatomic, assign) BOOL grayscaleMode; @property (nonatomic, assign) BOOL recordVideo; +@property (nonatomic, assign) BOOL rotateVideo; @property (nonatomic, retain) AVAssetWriterInput* recordAssetWriterInput; @property (nonatomic, retain) AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor; @property (nonatomic, retain) AVAssetWriter* recordAssetWriter; diff --git a/modules/highgui/src/cap_ios_abstract_camera.mm b/modules/highgui/src/cap_ios_abstract_camera.mm index b6a7d944fa..38e1c12e68 100644 --- a/modules/highgui/src/cap_ios_abstract_camera.mm +++ b/modules/highgui/src/cap_ios_abstract_camera.mm @@ -2,6 +2,7 @@ * cap_ios_abstract_camera.mm * For iOS video I/O * by Eduard Feicho on 29/07/12 + * by Alexander Shishkov on 17/07/13 * Copyright 2012. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -405,4 +406,89 @@ } } +- (void)lockFocus; +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device isFocusModeSupported:AVCaptureFocusModeLocked]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.focusMode = AVCaptureFocusModeLocked; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for locked focus configuration %@", [error localizedDescription]); + } + } +} + +- (void) unlockFocus; +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.focusMode = AVCaptureFocusModeContinuousAutoFocus; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for autofocus configuration %@", [error localizedDescription]); + } + } +} + +- (void)lockExposure; +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device isExposureModeSupported:AVCaptureExposureModeLocked]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.exposureMode = AVCaptureExposureModeLocked; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for locked exposure configuration %@", [error localizedDescription]); + } + } +} + +- (void) unlockExposure; +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.exposureMode = AVCaptureExposureModeContinuousAutoExposure; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for autoexposure configuration %@", [error localizedDescription]); + } + } +} + +- (void)lockBalance; +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.whiteBalanceMode = AVCaptureWhiteBalanceModeLocked; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for locked white balance configuration %@", [error localizedDescription]); + } + } +} + +- (void) unlockBalance; +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) { + NSError *error = nil; + if ([device lockForConfiguration:&error]) { + device.whiteBalanceMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance; + [device unlockForConfiguration]; + } else { + NSLog(@"unable to lock device for auto white balance configuration %@", [error localizedDescription]); + } + } +} + @end + diff --git a/modules/highgui/src/cap_ios_video_camera.mm b/modules/highgui/src/cap_ios_video_camera.mm index 1f9ea14bf8..ac85f79ee5 100644 --- a/modules/highgui/src/cap_ios_video_camera.mm +++ b/modules/highgui/src/cap_ios_video_camera.mm @@ -2,6 +2,7 @@ * cap_ios_video_camera.mm * For iOS video I/O * by Eduard Feicho on 29/07/12 + * by Alexander Shishkov on 17/07/13 * Copyright 2012. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +31,6 @@ #import "opencv2/highgui/cap_ios.h" #include "precomp.hpp" - #import @@ -70,6 +70,7 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; @synthesize videoDataOutput; @synthesize recordVideo; +@synthesize rotateVideo; //@synthesize videoFileOutput; @synthesize recordAssetWriterInput; @synthesize recordPixelBufferAdaptor; @@ -85,6 +86,7 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; if (self) { self.useAVCaptureVideoPreviewLayer = NO; self.recordVideo = NO; + self.rotateVideo = NO; } return self; } @@ -269,13 +271,8 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; } - - - #pragma mark - Private Interface - - - (void)createVideoDataOutput; { // Make a video data output @@ -389,6 +386,38 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; [self.parentView.layer addSublayer:self.customPreviewLayer]; } +- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image +{ + + CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image)); + NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey, + [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey, + nil]; + CVPixelBufferRef pxbuffer = NULL; + CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, + frameSize.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) CFBridgingRetain(options), + &pxbuffer); + NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL); + + CVPixelBufferLockBaseAddress(pxbuffer, 0); + void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer); + + + CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width, + frameSize.height, 8, 4*frameSize.width, rgbColorSpace, + kCGImageAlphaPremultipliedFirst); + + CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), + CGImageGetHeight(image)), image); + CGColorSpaceRelease(rgbColorSpace); + CGContextRelease(context); + + CVPixelBufferUnlockBaseAddress(pxbuffer, 0); + + return pxbuffer; +} #pragma mark - Protocol AVCaptureVideoDataOutputSampleBufferDelegate @@ -522,7 +551,8 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; } if (self.recordAssetWriterInput.readyForMoreMediaData) { - if (! [self.recordPixelBufferAdaptor appendPixelBuffer:imageBuffer + CVImageBufferRef pixelBuffer = [self pixelBufferFromCGImage:dstImage]; + if (! [self.recordPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:lastSampleTime] ) { NSLog(@"Video Writing Error"); } @@ -543,9 +573,12 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; - (void)updateOrientation; { - NSLog(@"rotate.."); - self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height); - [self layoutPreviewLayer]; + if (self.rotateVideo == YES) + { + NSLog(@"rotate.."); + self.customPreviewLayer.bounds = CGRectMake(0, 0, self.parentView.frame.size.width, self.parentView.frame.size.height); + [self layoutPreviewLayer]; + } } @@ -583,3 +616,4 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; } @end +