-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Migrate video_player/android
from SurfaceTexture
->SurfaceProducer
.
#6456
Conversation
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.
woo hoo
Due to a release hiccup, the |
@@ -186,7 +186,7 @@ public void onCancel(Object o) { | |||
} | |||
}); | |||
|
|||
surface = new Surface(textureEntry.surfaceTexture()); | |||
surface = surfaceProducer.getSurface(); |
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.
Note, the returned Surface may become invalid after a suspend / resume. Is there a place in the plugin that will be notified when we resume? We should update the video surface in that callback.
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.
Need to look at this still.
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've made this activity aware. It now tears down the exoplayer on pause and recreates on reusme.
@@ -48,16 +48,16 @@ final class VideoPlayer { | |||
|
|||
private ExoPlayer exoPlayer; | |||
|
|||
private Surface surface; |
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.
don't need to cache surface.
} | ||
|
||
public void pauseSurface() { | ||
eventChannel.setStreamHandler(null); |
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 tried just calling exoPlayer.setSurface again with a new surface, however the old surface being disposed seems to break some internal state, so I have to recreate the exo instance. This might imply some loss of state.
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 agree but I'm not sure because I'm not deeply familiar with ExoPlayer. Does the case where a video is playing and then the app is moved to the background and brought back get impacted by this, i.e. the video is no longer playing from the point it was stopped?
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.
Let me investigate 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.
I looked at this and it seems like the video state is reset. I'm going to see if there is a way to restore 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.
I added logic to restore all of the visible exo state when re-creating exo player.
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.
LGTM!
@jonahwilliams Just flagging that if we decide to back out our fix that forces ImageReaders to be recreated, we should revert parts of the PR. |
flutter/packages@31d3329...910fabb 2024-05-29 58529443+srujzs@users.noreply.github.com Amend package:web tweaks to allow package:web roll (flutter/packages#6793) 2024-05-29 matanlurey@users.noreply.github.com Migrate `video_player/android` from `SurfaceTexture`->`SurfaceProducer`. (flutter/packages#6456) 2024-05-29 joonas.kerttula@codemate.com [google_maps_flutter] Undeprecate BitmapDescriptor methods (flutter/packages#6832) 2024-05-29 matanlurey@users.noreply.github.com Migrate CameraX from SurfaceTexture to SurfaceProducer. (flutter/packages#6462) 2024-05-29 matanlurey@users.noreply.github.com Migrate `camera/android` from `SurfaceTexture`->`SurfaceProducer`. (flutter/packages#6461) 2024-05-29 katelovett@google.com [dynamic_layouts] Remove the dynamic_layouts package (flutter/packages#6830) 2024-05-29 43054281+camsim99@users.noreply.github.com [camerax] Add notes about Android permissions (flutter/packages#6741) 2024-05-29 43054281+camsim99@users.noreply.github.com [Re-land] Bump legacy all_packages project AGP version to 7.0.0, Gradle version to 7.0.2 (flutter/packages#6742) 2024-05-29 engine-flutter-autoroll@skia.org Roll Flutter from a1a33e6 to c85fa6a (20 revisions) (flutter/packages#6829) 2024-05-29 katelovett@google.com [rfw] Migrate deprecated doc references (flutter/packages#6744) 2024-05-29 katelovett@google.com [flutter_adaptive_scaffold] Migrate MaterialStateProperty to WidgetStateProperty (flutter/packages#6743) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/packages@31d3329...910fabb 2024-05-29 58529443+srujzs@users.noreply.github.com Amend package:web tweaks to allow package:web roll (flutter/packages#6793) 2024-05-29 matanlurey@users.noreply.github.com Migrate `video_player/android` from `SurfaceTexture`->`SurfaceProducer`. (flutter/packages#6456) 2024-05-29 joonas.kerttula@codemate.com [google_maps_flutter] Undeprecate BitmapDescriptor methods (flutter/packages#6832) 2024-05-29 matanlurey@users.noreply.github.com Migrate CameraX from SurfaceTexture to SurfaceProducer. (flutter/packages#6462) 2024-05-29 matanlurey@users.noreply.github.com Migrate `camera/android` from `SurfaceTexture`->`SurfaceProducer`. (flutter/packages#6461) 2024-05-29 katelovett@google.com [dynamic_layouts] Remove the dynamic_layouts package (flutter/packages#6830) 2024-05-29 43054281+camsim99@users.noreply.github.com [camerax] Add notes about Android permissions (flutter/packages#6741) 2024-05-29 43054281+camsim99@users.noreply.github.com [Re-land] Bump legacy all_packages project AGP version to 7.0.0, Gradle version to 7.0.2 (flutter/packages#6742) 2024-05-29 engine-flutter-autoroll@skia.org Roll Flutter from a1a33e6 to c85fa6a (20 revisions) (flutter/packages#6829) 2024-05-29 katelovett@google.com [rfw] Migrate deprecated doc references (flutter/packages#6744) 2024-05-29 katelovett@google.com [flutter_adaptive_scaffold] Migrate MaterialStateProperty to WidgetStateProperty (flutter/packages#6743) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…#6908) Part of flutter/flutter#148417. I'm working on re-landing #6456, this time without using the `ActivityAware` interface (see flutter/flutter#148417). As part of that work, I'll need to better control the `ExoPlayer` lifecycle and save/restore internal state. These are some proposed refactors to limit how much work `VideoPlayer` is doing, so I can better understand what needs to be reset (or not) internally. Specifically, `VideoPlayer` no longer knows what an `EventChannel` or `EventSink` is, and does not need to manage the lifecycle (it stores a `private final VideoPlayerCallbacks` instead), and instead there is a `VideoPlayerCallbacks` interface that does all that. I'm totally open to: - Landing this as-is (+/- nits) and making minor improvements in follow-up PRs - Making more significant changes to this PR and then landing it - Not landing this PR at all because it doesn't follow the approach the folks who maintain the plugin prefer Also happy to chat in VC/person about any of the changes.
…`. (#6922) Similar to #6908, as part of flutter/flutter#148417. I'm working on re-landing #6456, this time without using the `ActivityAware` interface (see flutter/flutter#148417). As part of that work, I'll need to better control the `ExoPlayer` lifecycle and save/restore internal state. In this PR, I've removed the concept of the class being "initialized" or not - the only thing "initialized" means is "for a given instance of `ExoPlayer`, has received the `'initialized'` event. As a result I removed the quasi-public API that was used for testing only and replaced it with observing what the real production instance does (`Player.STATE_READY`). After this PR, I'll likely do one more pass around the constructors - the constructor that takes an `ExoPlayer` that is marked `@VisibleForTesting` _also_ doesn't make sense once we'll support suspending/resuming video players, so it will need to get reworked (probably into taking a factory method).
…r`. (flutter#6456) _**WIP**: We do not plan to land this PR until the next stable release (>= April 3rd 2024)_. Work towards flutter/flutter#145930. ## Details Migrates uses of `createSurfaceTexture` to `createSurfaceProducer`, which is intended to have no change in behavior, but _does_ change the backend rendering path, so it will require more testing (and we're also open to minor API renames or changes before it becomes stable). ## Background Android plugins previously requested a `SurfaceTexture` from the Android embedder, and used that to produce a `Surface` to render external textures on (i.e. `video_player`). This worked because 100% of Flutter applications on Android used OpenGLES (via our Skia backend), and `SurfaceTexture` is actually an (opaque) OpenGLES-texture. Starting soon (roughly ~Q3, this is not a guarantee and just an estimate), Flutter on Android will start to use our new Impeller graphics backend, which on newer devices (`>= API_VERSION_28`), will default to the Vulkan, _not_ OpenGLES. In other words, `SurfaceTexture` will cease to work (it is possible, but non-trivial, to map an OpenGLES texture over to Vulkan). After consultation with the Android team, they helped us understand that vending `SurfaceTexture` (the _consumer-side_ API) was never the right abstraction, and we should have been vending the _producer-side_ API, or `Surface` directly. The new `SurfaceProducer` API is exactly that - it generates a `Surface`, and similar to our platform view strategy, picks the "right" _consumer-side_ implementation details _for_ the user/plugin packages. The new `SurfaceProducer` API has 2 possible rendering types (as an implementation detail): - `SurfaceTexture`, for older OpenGLES devices, which works exactly as it does today. - `ImageReader`, for newer OpenGLES _or_ Vulkan devices. These are some subtle nuances in how these two APIs work differently (one example: flutter/flutter#144407), but our theory at this point is we don't expect these changes to be observed by any users, and we have other ideas if necessary. > [!NOTE] > These invariants are [tested on CI in `flutter/engine`](https://github.com/flutter/engine/tree/main/testing/scenario_app/android#ci-configuration). Points of contact: - @matanlurey or @jonahwilliams (Flutter Engine) - @johnmccutchan or @reidbaker (Flutter on Android)
…eProducer`." (flutter#6882) Reverts flutter#6456
…flutter#6908) Part of flutter/flutter#148417. I'm working on re-landing flutter#6456, this time without using the `ActivityAware` interface (see flutter/flutter#148417). As part of that work, I'll need to better control the `ExoPlayer` lifecycle and save/restore internal state. These are some proposed refactors to limit how much work `VideoPlayer` is doing, so I can better understand what needs to be reset (or not) internally. Specifically, `VideoPlayer` no longer knows what an `EventChannel` or `EventSink` is, and does not need to manage the lifecycle (it stores a `private final VideoPlayerCallbacks` instead), and instead there is a `VideoPlayerCallbacks` interface that does all that. I'm totally open to: - Landing this as-is (+/- nits) and making minor improvements in follow-up PRs - Making more significant changes to this PR and then landing it - Not landing this PR at all because it doesn't follow the approach the folks who maintain the plugin prefer Also happy to chat in VC/person about any of the changes.
…`. (flutter#6922) Similar to flutter#6908, as part of flutter/flutter#148417. I'm working on re-landing flutter#6456, this time without using the `ActivityAware` interface (see flutter/flutter#148417). As part of that work, I'll need to better control the `ExoPlayer` lifecycle and save/restore internal state. In this PR, I've removed the concept of the class being "initialized" or not - the only thing "initialized" means is "for a given instance of `ExoPlayer`, has received the `'initialized'` event. As a result I removed the quasi-public API that was used for testing only and replaced it with observing what the real production instance does (`Player.STATE_READY`). After this PR, I'll likely do one more pass around the constructors - the constructor that takes an `ExoPlayer` that is marked `@VisibleForTesting` _also_ doesn't make sense once we'll support suspending/resuming video players, so it will need to get reworked (probably into taking a factory method).
…allback`. (#6982) I'm working on re-landing #6456, this time without using the `ActivityAware` interface (see flutter/flutter#148417). As part of that work, I'll need to better control the `ExoPlayer` lifecycle and save/restore internal state. Follows the patterns of some of the previous PRs, i.e. - #6922 - #6908 The changes in this PR are _mostly_ tests, it was extremely difficult to just add more tests to the already very leaky `VideoPlayer` abstraction which had lots of `@VisibleForTesting` methods and other "holes" to observe state. This PR removes all of that, and adds test coverage where it was missing. Namely it: - Adds a new class, `VideoAsset`, that builds and configures the media that `ExoPlayer` uses. - Removes all "testing" state from `VidePlayer`, keeping it nearly immutable. - Added tests for most of the classes I've added since, which were mostly missing. That being said, this is a large change. I'm happy to sit down with either of you and walk through it. --- Opening as a draft for the moment, since there is a pubspec change needing I want to handle first.
…allback`. (flutter#6982) I'm working on re-landing flutter#6456, this time without using the `ActivityAware` interface (see flutter/flutter#148417). As part of that work, I'll need to better control the `ExoPlayer` lifecycle and save/restore internal state. Follows the patterns of some of the previous PRs, i.e. - flutter#6922 - flutter#6908 The changes in this PR are _mostly_ tests, it was extremely difficult to just add more tests to the already very leaky `VideoPlayer` abstraction which had lots of `@VisibleForTesting` methods and other "holes" to observe state. This PR removes all of that, and adds test coverage where it was missing. Namely it: - Adds a new class, `VideoAsset`, that builds and configures the media that `ExoPlayer` uses. - Removes all "testing" state from `VidePlayer`, keeping it nearly immutable. - Added tests for most of the classes I've added since, which were mostly missing. That being said, this is a large change. I'm happy to sit down with either of you and walk through it. --- Opening as a draft for the moment, since there is a pubspec change needing I want to handle first.
…`setCallback` for suspend/resume lifecycles. (#6989) _ð��« BLOCKED: I guess this can't land until the new API makes it into stable in a week or two?_ --- Effectively enough towards flutter/flutter#148417, but we still need to document it on flutter.dev. This is the last _technical_ PR I'll work on towards the plugin work (assuming we don't find additional bugs/issues). /cc @jonahwilliams @chinmaygarde @johnmccutchan.
…this time with `setCallback` for suspend/resume lifecycles. (flutter#6989)" This reverts commit 62b4cb0.
… with setCallback for suspend/resume lifecycles" (#7497) Reverts #6989 Fixes flutter/flutter#154054 , flutter/flutter#154050
…ucer, this time with setCallback for suspend/resume lifecycles" (flutter#7497)" This reverts commit f61a98a.
WIP: We do not plan to land this PR until the next stable release (>= April 3rd 2024).
Work towards flutter/flutter#145930.
Details
Migrates uses of
createSurfaceTexture
tocreateSurfaceProducer
, which is intended to have no change in behavior, but does change the backend rendering path, so it will require more testing (and we're also open to minor API renames or changes before it becomes stable).Background
Android plugins previously requested a
SurfaceTexture
from the Android embedder, and used that to produce aSurface
to render external textures on (i.e.video_player
). This worked because 100% of Flutter applications on Android used OpenGLES (via our Skia backend), andSurfaceTexture
is actually an (opaque) OpenGLES-texture.Starting soon (roughly ~Q3, this is not a guarantee and just an estimate), Flutter on Android will start to use our new Impeller graphics backend, which on newer devices (
>= API_VERSION_28
), will default to the Vulkan, not OpenGLES. In other words,SurfaceTexture
will cease to work (it is possible, but non-trivial, to map an OpenGLES texture over to Vulkan).After consultation with the Android team, they helped us understand that vending
SurfaceTexture
(the consumer-side API) was never the right abstraction, and we should have been vending the producer-side API, orSurface
directly. The newSurfaceProducer
API is exactly that - it generates aSurface
, and similar to our platform view strategy, picks the "right" consumer-side implementation details for the user/plugin packages.The new
SurfaceProducer
API has 2 possible rendering types (as an implementation detail):SurfaceTexture
, for older OpenGLES devices, which works exactly as it does today.ImageReader
, for newer OpenGLES or Vulkan devices.These are some subtle nuances in how these two APIs work differently (one example: flutter/flutter#144407), but our theory at this point is we don't expect these changes to be observed by any users, and we have other ideas if necessary.
Note
These invariants are tested on CI in
flutter/engine
.Points of contact: