From 8e95bb6232dcdb6f528637ae0006a17631596075 Mon Sep 17 00:00:00 2001 From: Patrick Piemonte Date: Thu, 8 Aug 2013 23:39:13 -0700 Subject: [PATCH] PBJVision: addressed issues effecting rapid pause/resume from working properly fixes GH-8 --- Source/PBJVision.m | 99 +++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/Source/PBJVision.m b/Source/PBJVision.m index 42064e0..70435d8 100644 --- a/Source/PBJVision.m +++ b/Source/PBJVision.m @@ -93,7 +93,6 @@ @interface PBJVision () < unsigned int recording:1; unsigned int isPaused:1; unsigned int interrupted:1; - unsigned int videoWritten:1; } __block _flags; } @@ -900,7 +899,6 @@ - (void)startVideoCapture _flags.interrupted = NO; _flags.readyForAudio = NO; _flags.readyForVideo = NO; - _flags.videoWritten = NO; NSError *error = nil; _assetWriter = [[AVAssetWriter alloc] initWithURL:_outputURL fileType:(NSString *)kUTTypeQuickTimeMovie error:&error]; @@ -934,7 +932,6 @@ - (void)pauseVideoCapture _flags.isPaused = YES; _flags.interrupted = YES; - _flags.videoWritten = NO; [self _enqueueBlockOnMainQueue:^{ if ([_delegate respondsToSelector:@selector(visionDidPauseVideoCapture:)]) @@ -1226,63 +1223,60 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM BOOL isReadyToRecord = (_flags.readyForAudio && _flags.readyForVideo); - if (isVideo && isReadyToRecord) { - - if (!_flags.interrupted) { - - CMSampleBufferRef bufferToWrite = NULL; - - if (_timeOffset.value > 0) { - bufferToWrite = [self _createOffsetSampleBuffer:sampleBuffer withTimeOffset:_timeOffset]; - if (!bufferToWrite) { - DLog(@"error subtracting the timeoffset from the sampleBuffer"); - } - } else { - bufferToWrite = sampleBuffer; - CFRetain(bufferToWrite); - } + // calculate the length of the interruption + if (_flags.interrupted && isAudio) { + _flags.interrupted = NO; - if (bufferToWrite) { - // update the last video timestamp - CMTime time = CMSampleBufferGetPresentationTimeStamp(bufferToWrite); - CMTime duration = CMSampleBufferGetDuration(bufferToWrite); - if (duration.value > 0) - time = CMTimeAdd(time, duration); - - if (time.value > _videoTimestamp.value) { - [self _writeSampleBuffer:bufferToWrite ofType:AVMediaTypeVideo]; - _videoTimestamp = time; - _flags.videoWritten = YES; - } - CFRelease(bufferToWrite); + CMTime time = isVideo ? _videoTimestamp : _audioTimestamp; + // calculate the appropriate time offset + if (CMTIME_IS_VALID(time)) { + CMTime pTimestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); + if (CMTIME_IS_VALID(_timeOffset)) { + pTimestamp = CMTimeSubtract(pTimestamp, _timeOffset); } + + CMTime offset = CMTimeSubtract(pTimestamp, _audioTimestamp); + _timeOffset = (_timeOffset.value == 0) ? offset : CMTimeAdd(_timeOffset, offset); + DLog(@"new calculated offset %f valid (%d)", CMTimeGetSeconds(_timeOffset), CMTIME_IS_VALID(_timeOffset)); + } else { + DLog(@"invalid audio timestamp, no offset update"); } - } else if (isAudio && isReadyToRecord) { + _audioTimestamp.flags = 0; + _videoTimestamp.flags = 0; - // calculate the length of the interruption - if (_flags.interrupted) { - - // calculate the appropriate time offset - if (CMTIME_IS_VALID(_audioTimestamp)) { - CMTime pTimestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); - if (CMTIME_IS_VALID(_timeOffset)) { - pTimestamp = CMTimeSubtract(pTimestamp, _timeOffset); - } - - CMTime offset = CMTimeSubtract(pTimestamp, _audioTimestamp); - _timeOffset = (_timeOffset.value == 0) ? offset : CMTimeAdd(_timeOffset, offset); - DLog(@"new calculated offset %f valid (%d)", CMTimeGetSeconds(_timeOffset), CMTIME_IS_VALID(_timeOffset)); - } else { - DLog(@"invalid audio timestamp, no offset update"); + } + + if (isVideo && isReadyToRecord && !_flags.interrupted) { + + CMSampleBufferRef bufferToWrite = NULL; + + if (_timeOffset.value > 0) { + bufferToWrite = [self _createOffsetSampleBuffer:sampleBuffer withTimeOffset:_timeOffset]; + if (!bufferToWrite) { + DLog(@"error subtracting the timeoffset from the sampleBuffer"); } + } else { + bufferToWrite = sampleBuffer; + CFRetain(bufferToWrite); + } + + if (bufferToWrite) { + // update the last video timestamp + CMTime time = CMSampleBufferGetPresentationTimeStamp(bufferToWrite); + CMTime duration = CMSampleBufferGetDuration(bufferToWrite); + if (duration.value > 0) + time = CMTimeAdd(time, duration); - _flags.interrupted = NO; - _audioTimestamp.flags = 0; - _videoTimestamp.flags = 0; - + if (time.value > _videoTimestamp.value) { + [self _writeSampleBuffer:bufferToWrite ofType:AVMediaTypeVideo]; + _videoTimestamp = time; + } + CFRelease(bufferToWrite); } + } else if (isAudio && isReadyToRecord && !_flags.interrupted) { + CMSampleBufferRef bufferToWrite = NULL; if (_timeOffset.value > 0) { @@ -1295,8 +1289,7 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CM CFRetain(bufferToWrite); } - // once we've initially written a video frame, then we can start recording audio - if (_flags.videoWritten && bufferToWrite) { + if (bufferToWrite) { // update the last audio timestamp CMTime time = CMSampleBufferGetPresentationTimeStamp(bufferToWrite); CMTime duration = CMSampleBufferGetDuration(bufferToWrite);