Block calls to FrameExtractor.release

Block calls to release() method, and handle
calls on the player looper or not.

PiperOrigin-RevId: 695697602
This commit is contained in:
dancho 2024-11-12 05:45:58 -08:00 committed by Copybara-Service
parent de0e08397e
commit 40f187e4b4
2 changed files with 24 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertThrows;
import android.app.Instrumentation;
import android.content.Context;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.ConditionVariable;
@ -29,6 +30,7 @@ import androidx.media3.exoplayer.ExoPlaybackException;
import androidx.media3.transformer.ExperimentalFrameExtractor.Frame;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@ -154,4 +156,13 @@ public class FrameExtractorTest {
assertThat(throwableAtomicReference.get()).isNull();
assertThat(frameAtomicReference.get().presentationTimeMs).isEqualTo(0);
}
@Test
public void frameExtractor_releaseOnPlayerLooper_returns() throws Exception {
frameExtractor = new ExperimentalFrameExtractor(context, MediaItem.fromUri(FILE_PATH));
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
instrumentation.runOnMainSync(frameExtractor::release);
frameExtractor = null;
}
}

View File

@ -25,6 +25,7 @@ import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.Nullable;
import androidx.media3.common.Effect;
import androidx.media3.common.GlObjectsProvider;
@ -32,6 +33,7 @@ import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.NullableType;
import androidx.media3.effect.GlEffect;
import androidx.media3.effect.GlShaderProgram;
@ -176,9 +178,18 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* longer required. The frame extractor must not be used after calling this method.
*/
public void release() {
// TODO: b/350498258 - Block the caller until exoPlayer.release() returns.
if (player.getApplicationLooper() == Looper.myLooper()) {
player.release();
return;
}
ConditionVariable waitForRelease = new ConditionVariable();
playerApplicationThreadHandler.removeCallbacksAndMessages(null);
playerApplicationThreadHandler.post(player::release);
playerApplicationThreadHandler.post(
() -> {
player.release();
waitForRelease.open();
});
waitForRelease.blockUninterruptible();
}
// AnalyticsListener