diff --git a/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/ColorLut.java b/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/ColorLut.java index 20072f575c..de2f9022d0 100644 --- a/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/ColorLut.java +++ b/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/ColorLut.java @@ -17,6 +17,7 @@ package androidx.media3.effect; import android.content.Context; +import androidx.annotation.WorkerThread; import androidx.media3.common.FrameProcessingException; import com.google.android.exoplayer2.util.GlUtil; @@ -38,7 +39,9 @@ public interface ColorLut extends GlEffect { /** Releases the OpenGL texture of the LUT. */ void release() throws GlUtil.GlException; + /** This method must be executed on the same thread as other GL commands. */ @Override + @WorkerThread default ColorLutProcessor toGlTextureProcessor(Context context, boolean useHdr) throws FrameProcessingException { return new ColorLutProcessor(context, /* colorLut= */ this, useHdr); diff --git a/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/SingleColorLut.java b/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/SingleColorLut.java index 8c9bdc0a1a..7db7ca243b 100644 --- a/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/SingleColorLut.java +++ b/google3/third_party/java_src/android_libs/media/libraries/effect/src/main/java/androidx/media3/effect/SingleColorLut.java @@ -24,13 +24,14 @@ import android.graphics.Bitmap; import android.opengl.GLES20; import android.opengl.GLUtils; import androidx.media3.common.FrameProcessingException; +import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.util.GlUtil; import com.google.android.exoplayer2.util.Util; /** Transforms the colors of a frame by applying the same color lookup table to each frame. */ public class SingleColorLut implements ColorLut { - private final int lutTextureId; - private final int length; + private final Bitmap lut; + private int lutTextureId; /** * Creates a new instance. @@ -38,7 +39,7 @@ public class SingleColorLut implements ColorLut { *

{@code lutCube} needs to be a {@code N x N x N} cube and each element is an integer * representing a color using the {@link Bitmap.Config#ARGB_8888} format. */ - public static SingleColorLut createFromCube(int[][][] lutCube) throws GlUtil.GlException { + public static SingleColorLut createFromCube(int[][][] lutCube) { checkArgument( lutCube.length > 0 && lutCube[0].length > 0 && lutCube[0][0].length > 0, "LUT must have three dimensions."); @@ -58,7 +59,7 @@ public class SingleColorLut implements ColorLut { * N^2}. Each element must be an integer representing a color using the {@link * Bitmap.Config#ARGB_8888} format. */ - public static SingleColorLut createFromBitmap(Bitmap lut) throws GlUtil.GlException { + public static SingleColorLut createFromBitmap(Bitmap lut) { checkArgument( lut.getWidth() * lut.getWidth() == lut.getHeight(), Util.formatInvariant( @@ -70,18 +71,9 @@ public class SingleColorLut implements ColorLut { return new SingleColorLut(lut); } - private SingleColorLut(Bitmap lut) throws GlUtil.GlException { - length = lut.getWidth(); - lutTextureId = storeLutAsTexture(lut); - } - - private static int storeLutAsTexture(Bitmap bitmap) throws GlUtil.GlException { - int lutTextureId = - GlUtil.createTexture( - bitmap.getWidth(), bitmap.getHeight(), /* useHighPrecisionColorComponents= */ false); - GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, /* level= */ 0, bitmap, /* border= */ 0); - GlUtil.checkGlError(); - return lutTextureId; + private SingleColorLut(Bitmap lut) { + this.lut = lut; + lutTextureId = Format.NO_VALUE; } /** @@ -134,14 +126,19 @@ public class SingleColorLut implements ColorLut { Bitmap.Config.ARGB_8888); } + /** Must be called after {@link #toGlTextureProcessor(Context, boolean)}. */ @Override public int getLutTextureId(long presentationTimeUs) { + checkState( + lutTextureId != Format.NO_VALUE, + "The LUT has not been stored as a texture in OpenGL yet. You must to call" + + " #toGlTextureProcessor() first."); return lutTextureId; } @Override public int getLength(long presentationTimeUs) { - return length; + return lut.getWidth(); } @Override @@ -153,6 +150,22 @@ public class SingleColorLut implements ColorLut { public ColorLutProcessor toGlTextureProcessor(Context context, boolean useHdr) throws FrameProcessingException { checkState(!useHdr, "HDR is currently not supported."); + + try { + lutTextureId = storeLutAsTexture(lut); + } catch (GlUtil.GlException e) { + throw new FrameProcessingException("Could not store the LUT as a texture.", e); + } + return new ColorLutProcessor(context, /* colorLut= */ this, useHdr); } + + private static int storeLutAsTexture(Bitmap bitmap) throws GlUtil.GlException { + int lutTextureId = + GlUtil.createTexture( + bitmap.getWidth(), bitmap.getHeight(), /* useHighPrecisionColorComponents= */ false); + GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, /* level= */ 0, bitmap, /* border= */ 0); + GlUtil.checkGlError(); + return lutTextureId; + } } diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java b/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java index 7cc12fe2e6..b0fc5feed6 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/GlUtil.java @@ -355,12 +355,15 @@ public final class GlUtil { // TODO(b/201293185): Consider handling adjustments for sizes > GL_MAX_TEXTURE_SIZE // (ex. downscaling appropriately) in a texture processor instead of asserting incorrect // values. - // For valid GL sizes, see: // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glTexImage2D.xml int[] maxTextureSizeBuffer = new int[1]; GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeBuffer, 0); int maxTextureSize = maxTextureSizeBuffer[0]; + checkState( + maxTextureSize > 0, + "Create a OpenGL context first or run the GL methods on an OpenGL thread."); + if (width < 0 || height < 0) { throw new GlException("width or height is less than 0"); }