-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[camera_avfoundation] fix stopVideoRecording waiting indefinitely and video lag at start #7065
base: main
Are you sure you want to change the base?
Conversation
1815a2a
to
83cef95
Compare
Btw integration tests fail on my side with flutter packages main branch because here
|
83cef95
to
ba64f20
Compare
@@ -69,6 +69,7 @@ @interface FLTCam () <AVCaptureVideoDataOutputSampleBufferDelegate, | |||
@property(strong, nonatomic) AVCaptureVideoDataOutput *videoOutput; | |||
@property(strong, nonatomic) AVCaptureAudioDataOutput *audioOutput; | |||
@property(strong, nonatomic) NSString *videoRecordingPath; | |||
@property(assign, nonatomic) BOOL firstSample; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: isFirstSample
@@ -845,19 +853,17 @@ - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, | |||
if (_isRecording) { | |||
_isRecording = NO; | |||
|
|||
if (_videoWriter.status != AVAssetWriterStatusUnknown) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this check removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where it was not sending completion (in false case) so a dart future never resolved. But now startWriting
is called at the same time as _isRecording
is set to YES
so finishWritingWithCompletionHandler
in stopVideoRecordingWithCompletion
can be called only after was called startWriting
which sets _videoWriter.status
to AVAssetWriterStatusWriting
so that check is redundant (and again it would just indicate false possibility of not calling completion).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually maybe it should check whether status is AVAssetWriterStatusWriting
and complete with error otherwise because it can be for example AVAssetWriterStatusFailed
here (I suppose finishWritingWithCompletionHandler
would just crash in that case). But this situation is nothing new introduced with this PR as before there was just check status != unknown
which would pass failed
to finishWritingWithCompletionHandler
.
I also noticed check for AVAssetWriterStatusFailed
in didOutputSampleBuffer
where is called [self reportErrorMessage]
but when I tried to force call reportErrorMessage
I did not see this error report anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding previous comment, seems finishWritingWithCompletionHandler
is ok with AVAssetWriterStatusFailed
it will just pass it to handler so there is no need to check whether is status not failed
before calling it, it only has problem with AVAssetWriterStatusCancelled
but there is no call to cancelWriting
, AVAssetWriterStatusCompleted
and AVAssetWriterStatusUnknown
but these two also cannot happen.
// YES but _videoWriter.status is AVAssetWriterStatusUnknown and video lag at start | ||
// https://github.com/flutter/flutter/issues/132016 | ||
// https://github.com/flutter/flutter/issues/151319 | ||
[_videoWriter startWriting]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you intend to remove startWriting
from didOutputSampleBuffer
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
Seems reasonable to allow both jpg and jpeg to pass |
# Conflicts: # packages/camera/camera_avfoundation/CHANGELOG.md # packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m # packages/camera/camera_avfoundation/ios/Classes/FLTCam.m # packages/camera/camera_avfoundation/pubspec.yaml
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's reasonable change. Just some nit to make it easier for future readers.
@@ -69,6 +69,7 @@ @interface FLTCam () <AVCaptureVideoDataOutputSampleBufferDelegate, | |||
@property(strong, nonatomic) AVCaptureVideoDataOutput *videoOutput; | |||
@property(strong, nonatomic) AVCaptureAudioDataOutput *audioOutput; | |||
@property(strong, nonatomic) NSString *videoRecordingPath; | |||
@property(assign, nonatomic) BOOL isFirstSample; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be isFirstVideoSample
?
@@ -830,6 +831,13 @@ - (void)startVideoRecordingWithCompletion:(void (^)(FlutterError *_Nullable))com | |||
details:nil]); | |||
return; | |||
} | |||
// do not call startWriting in didOutputSampleBuffer to prevent state in which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "do not move startWriting call to didOutputSampleBuffer... "
Because there should only be 1 place to call startWriting
.
@@ -830,6 +831,13 @@ - (void)startVideoRecordingWithCompletion:(void (^)(FlutterError *_Nullable))com | |||
details:nil]); | |||
return; | |||
} | |||
// do not call startWriting in didOutputSampleBuffer to prevent state in which | |||
// stopVideoRecordingWithCompletion does not send completion when _isRecording is | |||
// YES but _videoWriter.status is AVAssetWriterStatusUnknown and video lag at start |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you also explain that this happens when stop video is called immediately after start, before the first video sample is arrived (if i understand correctly)
@@ -849,19 +857,17 @@ - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, | |||
if (_isRecording) { | |||
_isRecording = NO; | |||
|
|||
if (_videoWriter.status != AVAssetWriterStatusUnknown) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a comment explaining that it's not necessary to check AVAssetWriterStatusUnknown
anymore since we call startWriting immediately, even before video sample callback (please rephrase this).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, but such a comment loses context here because in sources it is not visible that there was such a check, only in this diff
} | ||
// when _isRecording is YES startWriting was already called so _videoWriter.status | ||
// is always either AVAssetWriterStatusWriting or AVAssetWriterStatusFailed and | ||
// finishWritingWithCompletionHandler does not throw exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "so there's no need to check _videoWriter.status
before finish writing"
Btw does this also require a second review? |
Only first time contributors require a second review, so you are good to go. But feel free to tag more people as you see fit. |
Oh ok (there are comments in my 2nd and 3rd PR that second reviews are required, but I did my first some year ago). |
7c5ef79
to
fb3d713
Compare
Call to
startWriting
was moved tostartVideoRecordingWithCompletion
to fix situation when completion is not called when_isRecording
isYES
but_videoWriter.status
isAVAssetWriterStatusUnknown
instopVideoRecordingWithCompletion
which can happen ifstopVideoRecordingWithCompletion
is called right afterstartVideoRecordingWithCompletion
anddidOutputSampleBuffer
had no chance to callstartWriting
in meantime and to avoid lag which happens when is calledstartWriting
between first frame creation and its appending.Fixes flutter/flutter#132016
Fixes flutter/flutter#151319
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style, or this PR is exempt from CHANGELOG changes.///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.