From 616cb943f0858fe8981b3b6e405a4112cc5788bb Mon Sep 17 00:00:00 2001 From: huangdarwin Date: Thu, 18 Jan 2024 05:17:48 -0800 Subject: [PATCH] Previewing: Allow inputColorInfo to change, from SDR to HDR. This also fixes issue introduced by frames being released from a prior version of a GlShaderProgram Tested by seeking within a playlist with one SDR then one HDR video. PiperOrigin-RevId: 599475959 --- .../androidx/media3/effect/BaseGlShaderProgram.java | 8 ++++++++ .../androidx/media3/effect/BitmapTextureManager.java | 1 + .../media3/effect/DefaultVideoFrameProcessor.java | 5 ----- .../media3/effect/ExternalTextureManager.java | 1 + .../java/androidx/media3/effect/TextureManager.java | 2 -- .../main/java/androidx/media3/effect/TexturePool.java | 5 +++++ .../exoplayer/video/CompositingVideoSinkProvider.java | 11 ++++------- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libraries/effect/src/main/java/androidx/media3/effect/BaseGlShaderProgram.java b/libraries/effect/src/main/java/androidx/media3/effect/BaseGlShaderProgram.java index 2dc4dd337f..c6f5fa8f3e 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/BaseGlShaderProgram.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/BaseGlShaderProgram.java @@ -165,6 +165,14 @@ public abstract class BaseGlShaderProgram implements GlShaderProgram { @Override public void releaseOutputFrame(GlTextureInfo outputTexture) { + if (!outputTexturePool.isUsingTexture(outputTexture)) { + // This allows us to ignore outputTexture instances not associated with this + // BaseGlShaderProgram instance. This may happen if a BaseGlShaderProgram is introduced into + // the GlShaderProgram chain after frames already exist in the pipeline. + // TODO - b/320481157: Consider removing this if condition and disallowing disconnecting a + // GlShaderProgram while it still has in-use frames. + return; + } outputTexturePool.freeTexture(outputTexture); inputListener.onReadyToAcceptInputFrame(); } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java index 28c60d42d5..3fe3dabe90 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java @@ -76,6 +76,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public void setSamplingGlShaderProgram(GlShaderProgram samplingGlShaderProgram) { + downstreamShaderProgramCapacity = 0; this.shaderProgram = samplingGlShaderProgram; } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java b/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java index c934a96997..c6fcaa4039 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java @@ -447,12 +447,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { *

If either {@link FrameInfo#colorInfo} or {@code outputColorInfo} {@linkplain * ColorInfo#isTransferHdr} are HDR}, color transfers must {@linkplain * Factory.Builder#setEnableColorTransfers be enabled}. - * - *

The {@link FrameInfo}'s {@link ColorInfo} must not change between different calls to this - * method. */ - // TODO: b/307952514: After updating frameInfo.colorInfo works with flushing, remove relevant - // javadoc. @Override public void registerInputStream( @InputType int inputType, List effects, FrameInfo frameInfo) { diff --git a/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java index cf7d98fce2..876ff2ed12 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java @@ -140,6 +140,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @Override public void setSamplingGlShaderProgram(GlShaderProgram samplingGlShaderProgram) { checkState(samplingGlShaderProgram instanceof ExternalShaderProgram); + externalShaderProgramInputCapacity.set(0); this.externalShaderProgram = (ExternalShaderProgram) samplingGlShaderProgram; } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java index 47a61f9c4e..0505b77cc4 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java @@ -69,8 +69,6 @@ import androidx.media3.common.util.TimestampIterator; * *

Must be called before any method that queues input or {@link * #signalEndOfCurrentInputStream()}. - * - *

This must only be called once. */ public abstract void setSamplingGlShaderProgram(GlShaderProgram samplingGlShaderProgram); diff --git a/libraries/effect/src/main/java/androidx/media3/effect/TexturePool.java b/libraries/effect/src/main/java/androidx/media3/effect/TexturePool.java index 2b666504b9..f7d125c2ff 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/TexturePool.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/TexturePool.java @@ -105,6 +105,11 @@ import java.util.Queue; freeTextures.add(textureInfo); } + /** Returns whether the texture represented by {@code textureInfo} is in use. */ + public boolean isUsingTexture(GlTextureInfo textureInfo) { + return inUseTextures.contains(textureInfo); + } + /** * Frees the oldest in-use texture. * diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java index 7a454e3fb1..3c7b606661 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java @@ -560,7 +560,6 @@ public final class CompositingVideoSinkProvider @Nullable private Effect rotationEffect; @Nullable private Format inputFormat; - private @MonotonicNonNull ColorInfo firstInputColorInfo; private @InputType int inputType; private long inputStreamOffsetUs; private boolean pendingInputStreamOffsetChange; @@ -778,15 +777,13 @@ public final class CompositingVideoSinkProvider } effects.addAll(videoEffects); Format inputFormat = checkNotNull(this.inputFormat); - if (firstInputColorInfo == null) { - // TODO: b/307952514 - Get inputColorInfo from inputFormat for each stream, after this value - // can change per-stream. - firstInputColorInfo = getAdjustedInputColorInfo(inputFormat.colorInfo); - } videoFrameProcessor.registerInputStream( inputType, effects, - new FrameInfo.Builder(firstInputColorInfo, inputFormat.width, inputFormat.height) + new FrameInfo.Builder( + getAdjustedInputColorInfo(inputFormat.colorInfo), + inputFormat.width, + inputFormat.height) .setPixelWidthHeightRatio(inputFormat.pixelWidthHeightRatio) .build()); }