-
Notifications
You must be signed in to change notification settings - Fork 3.6k
[camera_windows] Restore image streaming support #8234
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
Conversation
stuartmorgan-g
left a comment
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.
Thanks for the contribution!
I haven't reviewed the entire PR yet, but one high-level note about the overall PR structure, carried over from my comment on the original PR.
…#8307) Add API support query, supportsImageStreaming for checking if the camera platform supports image streaming. As requested on this comment: #8234 (comment) Step 3 from the [changing federated plugins guide](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins), split off from #8250 with a new Dart test added.
Add API support query, `supportsImageStreaming` for checking if the camera platform supports image streaming. As requested on this comment: #8234 (comment) Attempting to follow the [contribution guide wrt. changing federated plugins](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins). There is no issue to link to, but should I create one?
|
From triage: This was waiting on the streaming support query API, so was blocked on that. I believe it's now unblocked. |
1bdbe66 to
46f38a6
Compare
|
Rebased on main and added the support query. |
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 a shared_ptr rather than a unique_ptr. This class controls Camera lifetimes; in what scenario would the task runner need to outlive it?
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.
The instance is shared with the cameras and ultimately with the CaptureController.
In terms of lifetime, I guess there might be a small window where IMF is still running the callback when the plugin is being disposed, though I’m not really sure if that’s actually possible.
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.
The instance is shared with the cameras
Whose lifetime is, as I mentioned in my comment defined by CameraPlugin.
and ultimately with the
CaptureController.
Whose lifetime is controlled by Camera (and thus also CameraPlugin).
I'm still not seeing where any of the instances of this shared_ptr can outlive CameraPlugin.
In terms of lifetime, I guess there might be a small window where IMF is still running the callback when the plugin is being disposed, though I’m not really sure if that’s actually possible.
If the callback you linked to can be called on a deallocated capture controller, then this PR is introducing undefined behavior that is extremely likely to cause racy crashes. Please re-check the logic and make sure the threading is demonstrably correct; if you don't know whether that can happen, this this PR's threading isn't demonstrably correct yet.
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.
Rather than using raw method channels, can you use CameraApi::GetCodec as the codec, and use a Pigeon-defined class here, to get strong typing?
(We've done something very similar with plugins that use platform view arguments, where we define a class in Pigeon that's not used in the Pigeon-managed APIs, and then use that class in other places where things are serialized via channel codecs.)
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 point to an example where you’ve done this? It seems like I’d have to switch to using a BasicMessageChannel to take advantage of CameraApi::GetCodec.
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 point to an example where you’ve done this?
There aren't any C++ examples, so I don't think they would be very helpful.
It seems like I’d have to switch to using a
BasicMessageChannelto take advantage ofCameraApi::GetCodec.
Why? The codec is passed when creating the event channel.
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 this use a unique_ptr with a custom destructor, instead of managing the reference manually?
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.
Added a UniqueHWND typedef for dealing with 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.
Please don't use "we" in comments, as it's often ambiguous who "we" is (e.g., here, "we" is very vague... it seems to be a personification of the code, but which part?)
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.
Updated the comment.
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 the queue staying locked for the entire execution of the task? Isn't it only the draining of the queue that needs the lock?
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.
The lock scope extended too far indeed, fixed, thanks.
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.
It doesn't look like any of the new capture controller logic has tests.
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.
Added test cases for the start/stop logic.
ef2acaa to
653b574
Compare
|
Attempted to address some of the review issues, will continue with the remaining stuff later. |
653b574 to
68ad6b0
Compare
…tform (flutter#7951)" This reverts commit b3a5e33.
The logic is synchronous, so there is no need to have the `@async` annotation here. Addresses: flutter#7067 (comment)
When image stream frames are being received from Media Foundation,
it appears to use a separate thread when calling the `OnSample`
callback, which results in this error from:
The 'plugins.flutter.io/camera_windows/imageStream' channel sent a
message from native to Flutter on a non-platform thread. Platform
channel messages must be sent on the platform thread. Failure to do
so may result in data loss or crashes, and must be fixed in the
plugin or application code creating that channel.
In order to ensure that we are only ever using the `EventChannel` from
a platform thread, create a `TaskRunner` that is backed by a hidden
window to submit the frames to the image stream.
Based on the suggestion in this comment:
flutter/flutter#134346 (comment)
Instead of a global `EventSink` that is re-used for each stream, create a dedicated `EventChannel` for each capture stream. The channel gets an unique name like `plugins.flutter.io/camera_android/imageStream/<cameraId>` for each camera instance. Addresses: flutter#7067 (comment)
We don’t really need to keep track of the subscription and controller in instance variables.
Given that subscribing to the `EventChannel` tells the capture controller to start the image stream and cancelling the subscription tells it to stop, we don’t actually need a separate method in `CameraPlatform` for stopping the stream.
68ad6b0 to
ef16b4a
Compare
ef16b4a to
9326ab2
Compare
stuartmorgan-g
left a comment
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.
(Updating my review state to correctly reflect the open questions from the last round of reviews.)
|
From triage: @liff Are you still planning on updating this PR based on the review feedback? |
Yes—though I don’t know when, I’ve been preoccupied with other stuff lately. |
…flutter#8307) Add API support query, supportsImageStreaming for checking if the camera platform supports image streaming. As requested on this comment: flutter#8234 (comment) Step 3 from the [changing federated plugins guide](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins), split off from flutter#8250 with a new Dart test added.
Add API support query, `supportsImageStreaming` for checking if the camera platform supports image streaming. As requested on this comment: flutter#8234 (comment) Attempting to follow the [contribution guide wrt. changing federated plugins](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins). There is no issue to link to, but should I create one?
…flutter#8307) Add API support query, supportsImageStreaming for checking if the camera platform supports image streaming. As requested on this comment: flutter#8234 (comment) Step 3 from the [changing federated plugins guide](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins), split off from flutter#8250 with a new Dart test added.
Add API support query, `supportsImageStreaming` for checking if the camera platform supports image streaming. As requested on this comment: flutter#8234 (comment) Attempting to follow the [contribution guide wrt. changing federated plugins](https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins). There is no issue to link to, but should I create one?
|
Thank you for your contribution. I'm going to close this PR for now since there are outstanding comments, just to get this off our PR review queue. Please don't hesitate to re-open or submit a new PR if you have the time to address the review comments. Thanks! |
Restores support for streaming images from the camera(s) in Windows.
I reverted #7951 as a starting point and attempted to resolve the issues that were raised:
startImageStreamandstopImageStreammethods are no longerasync.EventSinkfor the images. Each camera gets a dedicatedEventChannelfor the image data.In addition, the images are submitted to the
EventChannels from a dedicated hidden window -based task runner, based on flutter/engine#24232.Implemented with assistance from @jokerttu.
Fixes flutter/flutter#97542.
Pre-launch Checklist
dart format.)[shared_preferences]pubspec.yamlwith an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.mdto 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.