@interface CvVideoCamera () {
NSString* mediaPath;
+ int recordCountDown;
+ CMTime _lastSampleTime;
+ int64_t _timestampMs;
+ dispatch_queue_t movieWriterQueue;
+
}
@property (nonatomic, retain) CALayer *customPreviewLayer;
@property (nonatomic, retain) AVCaptureVideoDataOutput *videoDataOutput;
@property (nonatomic, retain) AVCaptureMovieFileOutput *movieFileOutput;
+@property (nonatomic, retain) dispatch_queue_t movieWriterQueue;
@end
@synthesize recordPixelBufferAdaptor;
@synthesize recordAssetWriter;
+@synthesize timestampMs = _timestampMs;
+
+
- (id)initWithParentView:(UIView*)parent;
{
+ recordCountDown = 1000000000;
self = [super initWithParentView:parent];
if (self) {
self.useAVCaptureVideoPreviewLayer = NO;
self.recordVideo = NO;
self.rotateVideo = NO;
}
+ movieWriterQueue = nil;
return self;
}
- (void)start;
{
+ recordCountDown = 5;
+ movieWriterQueue = nil;
[super start];
if (self.recordVideo == YES) {
if (error == nil) {
NSLog(@"[Camera] Delete file %@", [self videoFileString]);
}
-
- if ([[NSFileManager defaultManager] fileExistsAtPath:[self mediaFileString]]) {
- [[NSFileManager defaultManager] removeItemAtPath:[self mediaFileString] error:&error];
- }
}
+
}
self.recordAssetWriter = nil;
self.recordAssetWriterInput = nil;
self.recordPixelBufferAdaptor = nil;
+ if (movieWriterQueue)
+ dispatch_release(movieWriterQueue);
+ self.movieWriterQueue = nil;
}
[self.customPreviewLayer removeFromSuperlayer];
[self.videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
+ if (self.recordVideo == YES && movieWriterQueue == nil) {
+ movieWriterQueue = dispatch_queue_create("opencv_movieWriter", DISPATCH_QUEUE_SERIAL);
+ }
NSLog(@"[Camera] created AVCaptureVideoDataOutput at %d FPS", self.defaultFPS);
}
}
#pragma mark - Protocol AVCaptureVideoDataOutputSampleBufferDelegate
+- (void)captureOutput:(AVCaptureOutput *)captureOutput didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
+{
+ if (connection == self.audioCaptureConnection) {
+ NSLog(@"Audio sample did drop ");
+ return;
+ }
+ NSLog(@"Video Frame did drop ");
+}
+
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
(void)connection;
if (connection == self.audioCaptureConnection) {
- NSLog(@"Audio Sample came in ");
+ //NSLog(@"Audio Sample came in ");
return;
}
}
+
+ CMTime lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
+ int64_t msec = lastSampleTime.value / (lastSampleTime.timescale / 1000);
+ _timestampMs = msec;
+ //NSLog(@"Timestamp %u / %u, msec = %lu ", lastSampleTime.value, lastSampleTime.timescale, msec);
+
+
// delegate image processing to the delegate
cv::Mat image((int)height, (int)width, format_opencv, bufferAddress, bytesPerRow);
- CGImage* dstImage;
-
if ([self.delegate respondsToSelector:@selector(processImage:)]) {
[self.delegate processImage:image];
}
+ CGImage* dstImage;
+
// check if matrix data pointer or dimensions were changed by the delegate
bool iOSimage = false;
if (height == (size_t)image.rows && width == (size_t)image.cols && format_opencv == image.type() && bufferAddress == image.data && bytesPerRow == image.step) {
// render buffer
+ //dispatch_sync(dispatch_get_main_queue(), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
self.customPreviewLayer.contents = (__bridge id)dstImage;
});
+ if (recordCountDown > 0)
+ recordCountDown--;
+
+ if (self.recordVideo == YES && recordCountDown <= 0) {
+ //CMTimeShow(lastSampleTime);
- if (self.recordVideo == YES) {
- lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
-// CMTimeShow(lastSampleTime);
if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) {
[self.recordAssetWriter startWriting];
- [self.recordAssetWriter startSessionAtSourceTime:lastSampleTime];
+ [self.recordAssetWriter startSessionAtSourceTime:_lastSampleTime];
if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) {
NSLog(@"[Camera] Recording Error: asset writer status is not writing: %@", self.recordAssetWriter.error);
return;
if (pixelBuffer != nullptr)
CVPixelBufferRelease(pixelBuffer);
}
-
}
-
// cleanup
CGImageRelease(dstImage);