Skip to content

[Impeller] Support Vulkan YUV texture sampling for composition of video player frames. #142082

@matanlurey

Description

@matanlurey

I'm toying with migrating video_player_android to the new consumer-agnostic SurfaceProducer API.

Patch
diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java
index 57fc1037c..f9557a494 100644
--- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java
+++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java
@@ -50,7 +50,7 @@ final class VideoPlayer {
 
   private Surface surface;
 
-  private final TextureRegistry.SurfaceTextureEntry textureEntry;
+  private final TextureRegistry.SurfaceProducer textureProducer;
 
   private QueuingEventSink eventSink;
 
@@ -67,13 +67,13 @@ final class VideoPlayer {
   VideoPlayer(
       Context context,
       EventChannel eventChannel,
-      TextureRegistry.SurfaceTextureEntry textureEntry,
+      TextureRegistry.SurfaceProducer textureProducer,
       String dataSource,
       String formatHint,
       @NonNull Map<String, String> httpHeaders,
       VideoPlayerOptions options) {
     this.eventChannel = eventChannel;
-    this.textureEntry = textureEntry;
+    this.textureProducer = textureProducer;
     this.options = options;
 
     ExoPlayer exoPlayer = new ExoPlayer.Builder(context).build();
@@ -96,12 +96,12 @@ final class VideoPlayer {
   VideoPlayer(
       ExoPlayer exoPlayer,
       EventChannel eventChannel,
-      TextureRegistry.SurfaceTextureEntry textureEntry,
+      TextureRegistry.SurfaceProducer textureProducer,
       VideoPlayerOptions options,
       QueuingEventSink eventSink,
       DefaultHttpDataSource.Factory httpDataSourceFactory) {
     this.eventChannel = eventChannel;
-    this.textureEntry = textureEntry;
+    this.textureProducer = textureProducer;
     this.options = options;
     this.httpDataSourceFactory = httpDataSourceFactory;
 
@@ -186,7 +186,7 @@ final class VideoPlayer {
           }
         });
 
-    surface = new Surface(textureEntry.surfaceTexture());
+    surface = textureProducer.getSurface();
     exoPlayer.setVideoSurface(surface);
     setAudioAttributes(exoPlayer, options.mixWithOthers);
 
@@ -330,7 +330,7 @@ final class VideoPlayer {
     if (isInitialized) {
       exoPlayer.stop();
     }
-    textureEntry.release();
+    textureProducer.release();
     eventChannel.setStreamHandler(null);
     if (surface != null) {
       surface.release();
diff --git a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java
index c0c602793..41f48731d 100644
--- a/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java
+++ b/packages/video_player/video_player_android/android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java
@@ -119,11 +119,10 @@ public class VideoPlayerPlugin implements FlutterPlugin, AndroidVideoPlayerApi {
   }
 
   public @NonNull TextureMessage create(@NonNull CreateMessage arg) {
-    TextureRegistry.SurfaceTextureEntry handle =
-        flutterState.textureRegistry.createSurfaceTexture();
+    TextureRegistry.SurfaceProducer producer = flutterState.textureRegistry.createSurfaceProducer();
     EventChannel eventChannel =
         new EventChannel(
-            flutterState.binaryMessenger, "flutter.io/videoPlayer/videoEvents" + handle.id());
+            flutterState.binaryMessenger, "flutter.io/videoPlayer/videoEvents" + producer.id());
 
     VideoPlayer player;
     if (arg.getAsset() != null) {
@@ -138,7 +137,7 @@ public class VideoPlayerPlugin implements FlutterPlugin, AndroidVideoPlayerApi {
           new VideoPlayer(
               flutterState.applicationContext,
               eventChannel,
-              handle,
+              producer,
               "asset:///" + assetLookupKey,
               null,
               new HashMap<>(),
@@ -149,15 +148,15 @@ public class VideoPlayerPlugin implements FlutterPlugin, AndroidVideoPlayerApi {
           new VideoPlayer(
               flutterState.applicationContext,
               eventChannel,
-              handle,
+              producer,
               arg.getUri(),
               arg.getFormatHint(),
               httpHeaders,
               options);
     }
-    videoPlayers.put(handle.id(), player);
+    videoPlayers.put(producer.id(), player);
 
-    return new TextureMessage.Builder().setTextureId(handle.id()).build();
+    return new TextureMessage.Builder().setTextureId(producer.id()).build();
   }
 
   public void dispose(@NonNull TextureMessage arg) {

While I'm not currently focused on the HardwareBuffer/ImageReader code path, it crashes at HEAD:

E/flutter (17339): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(java.lang.IllegalArgumentException: The image dimensions must be positive, IllegalArgumentException, Cause: null, Stacktrace: java.lang.IllegalArgumentException: The image dimensions must be positive
E/flutter (17339):      at android.media.ImageReader.initializeImageReader(ImageReader.java:319)
E/flutter (17339):      at android.media.ImageReader.<init>(ImageReader.java:363)
E/flutter (17339):      at android.media.ImageReader.<init>(Unknown Source:0)
E/flutter (17339):      at android.media.ImageReader$Builder.build(ImageReader.java:1093)
E/flutter (17339):      at io.flutter.embedding.engine.renderer.FlutterRenderer$ImageReaderSurfaceProducer.createImageReader33(FlutterRenderer.java:658)
E/flutter (17339):      at io.flutter.embedding.engine.renderer.FlutterRenderer$ImageReaderSurfaceProducer.createImageReader(FlutterRenderer.java:678)
E/flutter (17339):      at io.flutter.embedding.engine.renderer.FlutterRenderer$ImageReaderSurfaceProducer.maybeCreateReader(FlutterRenderer.java:568)
E/flutter (17339):      at io.flutter.embedding.engine.renderer.FlutterRenderer$ImageReaderSurfaceProducer.getSurface(FlutterRenderer.java:519)
E/flutter (17339):      at io.flutter.plugins.videoplayer.VideoPlayer.setUpVideoPlayer(VideoPlayer.java:189)

I'm going to overlook this for the moment and focus on the surface-texture code path, but filing for posterity.

/cc @johnmccutchan

Metadata

Metadata

Assignees

Labels

P1High-priority issues at the top of the work liste: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.fyi-androidFor the attention of Android platform teamplatform-androidAndroid applications specificallyteam-engineOwned by Engine teamtriaged-engineTriaged by Engine teamwaiting for PR to land (fixed)A fix is in flight

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions