From: Vadim Pisarevsky Date: Wed, 22 Aug 2012 09:33:13 +0000 (+0400) Subject: fixed ios camera timing (patch by Eduard Feicho) X-Git-Tag: accepted/2.0/20130307.220821~364^2~215^2~50^2~4^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e95bc7d502ce74748cde30c48bc54e360e039fd1;p=profile%2Fivi%2Fopencv.git fixed ios camera timing (patch by Eduard Feicho) --- diff --git a/modules/highgui/include/opencv2/highgui/cap_ios.h b/modules/highgui/include/opencv2/highgui/cap_ios.h index cc6668a..26a28c0 100644 --- a/modules/highgui/include/opencv2/highgui/cap_ios.h +++ b/modules/highgui/include/opencv2/highgui/cap_ios.h @@ -80,7 +80,6 @@ @property (nonatomic, retain) UIView* parentView; -- (void)pause; - (void)start; - (void)stop; - (void)switchCameras; @@ -120,6 +119,8 @@ AVAssetWriterInput* recordAssetWriterInput; AVAssetWriterInputPixelBufferAdaptor* recordPixelBufferAdaptor; AVAssetWriter* recordAssetWriter; + + CMTime lastSampleTime; } @@ -134,6 +135,8 @@ - (void)adjustLayoutToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; - (void)layoutPreviewLayer; - (void)saveVideo; +- (NSURL *)videoFileURL; + @end diff --git a/modules/highgui/src/cap_ios_video_camera.mm b/modules/highgui/src/cap_ios_video_camera.mm index 6f7bfa2..0a162eb 100644 --- a/modules/highgui/src/cap_ios_video_camera.mm +++ b/modules/highgui/src/cap_ios_video_camera.mm @@ -98,90 +98,29 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; { [super start]; - if (self.recordVideo == YES) { -// [self.videoFileOutput startRecordingToOutputFileURL:[self tempFileURL] recordingDelegate:self]; - + if (self.recordVideo == YES) { NSError* error; - if ([[NSFileManager defaultManager] fileExistsAtPath:[self tempFileString]]) [[NSFileManager defaultManager] removeItemAtPath:[self tempFileString] error:&error]; + if ([[NSFileManager defaultManager] fileExistsAtPath:[self videoFileString]]) { + [[NSFileManager defaultManager] removeItemAtPath:[self videoFileString] error:&error]; + } if (error == nil) { - NSLog(@"[Camera] Delete file %@", [self tempFileString]); - } - - - BOOL started = [self.recordAssetWriter startWriting]; - [self.recordAssetWriter startSessionAtSourceTime:kCMTimeZero]; - - NSLog(@"[Camera] Session started? %d", started); - - if (self.recordAssetWriter.status == AVAssetWriterStatusUnknown) { - NSLog(@"AVAssetWriter status: unknown"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusWriting) { - NSLog(@"AVAssetWriter status: writing"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusCompleted) { - NSLog(@"AVAssetWriter status: completed"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusFailed) { - NSLog(@"AVAssetWriter status: failed"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusCancelled) { - NSLog(@"AVAssetWriter status: cancelled"); - } - - if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) { - NSLog(@"[Camera] Recording Error: asset writer status is not writing: %@", self.recordAssetWriter.error); - } else { - NSLog(@"[Camera] Recording started"); + NSLog(@"[Camera] Delete file %@", [self videoFileString]); } } } -- (void)pause; -{ - [super pause]; - if (self.recordVideo == YES) { -// [self.videoFileOutput stopRecording]; - - - if (self.recordAssetWriter.status == AVAssetWriterStatusUnknown) { - NSLog(@"AVAssetWriter status: unknown"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusWriting) { - NSLog(@"AVAssetWriter status: writing"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusCompleted) { - NSLog(@"AVAssetWriter status: completed"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusFailed) { - NSLog(@"AVAssetWriter status: failed"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusCancelled) { - NSLog(@"AVAssetWriter status: cancelled"); - } - - if (self.recordAssetWriter.status == AVAssetWriterStatusWriting) { - [self.recordAssetWriter finishWriting]; - NSLog(@"[Camera] recording stopped"); - } else { - NSLog(@"[Camera] Recording Error: asset writer status is not writing"); - } - } -} - - - (void)stop; { [super stop]; - if (self.recordVideo == YES) { - NSLog(@"recording stop"); - if (self.recordAssetWriter.status == AVAssetWriterStatusUnknown) { - NSLog(@"AVAssetWriter status: unknown"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusWriting) { - NSLog(@"AVAssetWriter status: writing"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusCompleted) { - NSLog(@"AVAssetWriter status: completed"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusFailed) { - NSLog(@"AVAssetWriter status: failed"); - } else if (self.recordAssetWriter.status == AVAssetWriterStatusCancelled) { - NSLog(@"AVAssetWriter status: cancelled"); - } - + self.videoDataOutput = nil; + if (videoDataOutputQueue) { + dispatch_release(videoDataOutputQueue); + } + + if (self.recordVideo == YES) { if (self.recordAssetWriter.status == AVAssetWriterStatusWriting) { [self.recordAssetWriter finishWriting]; @@ -194,11 +133,6 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; self.recordAssetWriterInput = nil; self.recordPixelBufferAdaptor = nil; } - - self.videoDataOutput = nil; - if (videoDataOutputQueue) { - dispatch_release(videoDataOutputQueue); - } [self.customPreviewLayer removeFromSuperlayer]; self.customPreviewLayer = nil; @@ -405,15 +339,6 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; - (void)createVideoFileOutput; { - /* - if (self.recordVideo == YES) { - self.videoFileOutput = [[AVCaptureMovieFileOutput alloc] init]; - if ( [self.captureSession canAddOutput:self.videoFileOutput] ) { - [self.captureSession addOutput:self.videoFileOutput]; - } - } - */ - /* Video File Output in H.264, via AVAsserWriter */ NSLog(@"Create Video with dimensions %dx%d", self.imageWidth, self.imageHeight); @@ -426,21 +351,18 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; self.recordAssetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:outputSettings]; - - /* I'm going to push pixel buffers to it, so will need a - AVAssetWriterPixelBufferAdaptor, to expect the same 32BGRA input as I've - asked the AVCaptureVideDataOutput to supply */ + int pixelBufferFormat = (self.grayscaleMode == YES) ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange : kCVPixelFormatType_32BGRA; self.recordPixelBufferAdaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:self.recordAssetWriterInput - sourcePixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:pixelBufferFormat], kCVPixelBufferPixelFormatTypeKey,nil]]; + sourcePixelBufferAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:pixelBufferFormat], kCVPixelBufferPixelFormatTypeKey, nil]]; NSError* error = nil; - NSLog(@"Create AVAssetWriter with url: %@", [self tempFileURL]); - self.recordAssetWriter = [AVAssetWriter assetWriterWithURL:[self tempFileURL] + NSLog(@"Create AVAssetWriter with url: %@", [self videoFileURL]); + self.recordAssetWriter = [AVAssetWriter assetWriterWithURL:[self videoFileURL] fileType:AVFileTypeMPEG4 error:&error]; if (error != nil) { @@ -448,10 +370,9 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; } [self.recordAssetWriter addInput:self.recordAssetWriterInput]; - self.recordAssetWriterInput.expectsMediaDataInRealTime = NO; + self.recordAssetWriterInput.expectsMediaDataInRealTime = YES; NSLog(@"[Camera] created AVAssetWriter"); - } @@ -580,8 +501,6 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; } - - // render buffer dispatch_sync(dispatch_get_main_queue(), ^{ self.customPreviewLayer.contents = (__bridge id)dstImage; @@ -589,16 +508,26 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; if (self.recordVideo == YES) { - // a very dense way to keep track of the time at which this frame - // occurs relative to the output stream, but it's just an example! + lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); +// CMTimeShow(lastSampleTime); + if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) { + [self.recordAssetWriter startWriting]; + [self.recordAssetWriter startSessionAtSourceTime:lastSampleTime]; + if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) { + NSLog(@"[Camera] Recording Error: asset writer status is not writing: %@", self.recordAssetWriter.error); + return; + } else { + NSLog(@"[Camera] Video recording started"); + } + } - // TODO reset frame number - static int64_t frameNumber = 0; if (self.recordAssetWriterInput.readyForMoreMediaData) { - [self.recordPixelBufferAdaptor appendPixelBuffer:imageBuffer - withPresentationTime:CMTimeMake(frameNumber, self.defaultFPS)]; + if (! [self.recordPixelBufferAdaptor appendPixelBuffer:imageBuffer + withPresentationTime:lastSampleTime] ) { + NSLog(@"Video Writing Error"); + } } - frameNumber++; + } @@ -627,14 +556,14 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; } ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; - if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:[self tempFileURL]]) { - [library writeVideoAtPathToSavedPhotosAlbum:[self tempFileURL] + if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:[self videoFileURL]]) { + [library writeVideoAtPathToSavedPhotosAlbum:[self videoFileURL] completionBlock:^(NSURL *assetURL, NSError *error){}]; } } -- (NSURL *)tempFileURL; +- (NSURL *)videoFileURL; { NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]; NSURL *outputURL = [NSURL fileURLWithPath:outputPath]; @@ -647,7 +576,7 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; -- (NSString *)tempFileString; +- (NSString *)videoFileString; { NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]; return outputPath;