diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index 5012f7d965b4..3417432a0547 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.16+1 + +* Fixes sample times not being numeric after pause/resume. + ## 0.9.16 * Converts Dart-to-host communcation to Pigeon. diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m index cba488dfe5b4..8932f639d1d1 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m @@ -130,4 +130,68 @@ - (void)testDidOutputSampleBufferIgnoreAudioSamplesBeforeVideoSamples { CFRelease(audioSample); } +- (void)testSampleTimesAreNumericAfterPauseResume { + FLTCam *cam = FLTCreateCamWithCaptureSessionQueue(dispatch_queue_create("testing", NULL)); + CMSampleBufferRef videoSample = FLTCreateTestSampleBuffer(); + CMSampleBufferRef audioSample = FLTCreateTestAudioSampleBuffer(); + + id connectionMock = OCMClassMock([AVCaptureConnection class]); + + id writerMock = OCMClassMock([AVAssetWriter class]); + OCMStub([writerMock alloc]).andReturn(writerMock); + OCMStub([writerMock initWithURL:OCMOCK_ANY fileType:OCMOCK_ANY error:[OCMArg setTo:nil]]) + .andReturn(writerMock); + __block AVAssetWriterStatus status = AVAssetWriterStatusUnknown; + OCMStub([writerMock startWriting]).andDo(^(NSInvocation *invocation) { + status = AVAssetWriterStatusWriting; + }); + OCMStub([writerMock status]).andDo(^(NSInvocation *invocation) { + [invocation setReturnValue:&status]; + }); + + id videoMock = OCMClassMock([AVAssetWriterInputPixelBufferAdaptor class]); + OCMStub([videoMock assetWriterInputPixelBufferAdaptorWithAssetWriterInput:OCMOCK_ANY + sourcePixelBufferAttributes:OCMOCK_ANY]) + .andReturn(videoMock); + OCMStub([videoMock appendPixelBuffer:[OCMArg anyPointer] withPresentationTime:kCMTimeZero]) + .ignoringNonObjectArgs() + .andDo(^(NSInvocation *invocation) { + CMTime presentationTime; + [invocation getArgument:&presentationTime atIndex:3]; + XCTAssert(CMTIME_IS_NUMERIC(presentationTime)); + }); + + id audioMock = OCMClassMock([AVAssetWriterInput class]); + OCMStub([audioMock assetWriterInputWithMediaType:[OCMArg isEqual:AVMediaTypeAudio] + outputSettings:OCMOCK_ANY]) + .andReturn(audioMock); + OCMStub([audioMock isReadyForMoreMediaData]).andReturn(YES); + OCMStub([audioMock appendSampleBuffer:[OCMArg anyPointer]]).andDo(^(NSInvocation *invocation) { + CMSampleBufferRef sampleBuffer; + [invocation getArgument:&sampleBuffer atIndex:2]; + CMTime sampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); + XCTAssert(CMTIME_IS_NUMERIC(sampleTime)); + }); + + [cam + startVideoRecordingWithCompletion:^(FlutterError *_Nullable error) { + } + messengerForStreaming:nil]; + + [cam pauseVideoRecording]; + [cam resumeVideoRecording]; + + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + [cam captureOutput:nil didOutputSampleBuffer:audioSample fromConnection:connectionMock]; + [cam captureOutput:cam.captureVideoOutput + didOutputSampleBuffer:videoSample + fromConnection:connectionMock]; + [cam captureOutput:nil didOutputSampleBuffer:audioSample fromConnection:connectionMock]; + + CFRelease(videoSample); + CFRelease(audioSample); +} + @end diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m b/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m index 45ab3e08e667..db564da49bec 100644 --- a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m +++ b/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m @@ -672,6 +672,10 @@ - (void)captureOutput:(AVCaptureOutput *)output if (_videoWriter.status != AVAssetWriterStatusWriting) { [_videoWriter startWriting]; [_videoWriter startSessionAtSourceTime:currentSampleTime]; + // fix sample times not being numeric after pause/resume + // https://github.com/flutter/flutter/issues/132014 + _lastVideoSampleTime = currentSampleTime; + _lastAudioSampleTime = currentSampleTime; } if (output == _captureVideoOutput) { diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index b91fe76ae3f3..004ddcd9b51d 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.16 +version: 0.9.16+1 environment: sdk: ^3.2.3