Commit 5fd6ce5e by tonihei Committed by christosts

Fix threading of onFallbackApplied callback

The callback is currently triggered on the ExoPlayer playback thread
instead of the app thread that added the listener.

PiperOrigin-RevId: 492474405
(cherry picked from commit f3fc4fb9)
parent fec7b1b5
......@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkState;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.util.HandlerWrapper;
import com.google.android.exoplayer2.util.ListenerSet;
import com.google.android.exoplayer2.util.Util;
......@@ -32,6 +33,7 @@ import com.google.android.exoplayer2.util.Util;
private final MediaItem mediaItem;
private final TransformationRequest originalTransformationRequest;
private final ListenerSet<Transformer.Listener> transformerListeners;
private final HandlerWrapper transformerListenerHandler;
private TransformationRequest fallbackTransformationRequest;
private int trackCount;
......@@ -40,16 +42,20 @@ import com.google.android.exoplayer2.util.Util;
* Creates a new instance.
*
* @param mediaItem The {@link MediaItem} to transform.
* @param transformerListeners The {@linkplain Transformer.Listener listeners} to forward events
* to.
* @param transformerListeners The {@linkplain Transformer.Listener listeners} to call {@link
* Transformer.Listener#onFallbackApplied} on.
* @param transformerListenerHandler The {@link HandlerWrapper} to call {@link
* Transformer.Listener#onFallbackApplied} events on.
* @param originalTransformationRequest The original {@link TransformationRequest}.
*/
public FallbackListener(
MediaItem mediaItem,
ListenerSet<Transformer.Listener> transformerListeners,
HandlerWrapper transformerListenerHandler,
TransformationRequest originalTransformationRequest) {
this.mediaItem = mediaItem;
this.transformerListeners = transformerListeners;
this.transformerListenerHandler = transformerListenerHandler;
this.originalTransformationRequest = originalTransformationRequest;
this.fallbackTransformationRequest = originalTransformationRequest;
}
......@@ -104,15 +110,19 @@ import com.google.android.exoplayer2.util.Util;
fallbackRequestBuilder.setEnableRequestSdrToneMapping(
transformationRequest.enableRequestSdrToneMapping);
}
fallbackTransformationRequest = fallbackRequestBuilder.build();
TransformationRequest newFallbackTransformationRequest = fallbackRequestBuilder.build();
fallbackTransformationRequest = newFallbackTransformationRequest;
if (trackCount == 0 && !originalTransformationRequest.equals(fallbackTransformationRequest)) {
transformerListeners.queueEvent(
/* eventFlag= */ C.INDEX_UNSET,
listener ->
listener.onFallbackApplied(
mediaItem, originalTransformationRequest, fallbackTransformationRequest));
transformerListeners.flushEvents();
transformerListenerHandler.post(
() ->
transformerListeners.sendEvent(
/* eventFlag= */ C.INDEX_UNSET,
listener ->
listener.onFallbackApplied(
mediaItem,
originalTransformationRequest,
newFallbackTransformationRequest)));
}
}
}
......@@ -727,7 +727,11 @@ public final class Transformer {
/* asyncErrorListener= */ componentListener);
this.muxerWrapper = muxerWrapper;
FallbackListener fallbackListener =
new FallbackListener(mediaItem, listeners, transformationRequest);
new FallbackListener(
mediaItem,
listeners,
clock.createHandler(looper, /* callback= */ null),
transformationRequest);
exoPlayerAssetLoader.start(
mediaItem,
muxerWrapper,
......
......@@ -26,10 +26,12 @@ import android.os.Looper;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.util.Clock;
import com.google.android.exoplayer2.util.HandlerWrapper;
import com.google.android.exoplayer2.util.ListenerSet;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.shadows.ShadowLooper;
/** Unit tests for {@link FallbackListener}. */
@RunWith(AndroidJUnit4.class)
......@@ -41,7 +43,8 @@ public class FallbackListenerTest {
public void onTransformationRequestFinalized_withoutTrackRegistration_throwsException() {
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
FallbackListener fallbackListener =
new FallbackListener(PLACEHOLDER_MEDIA_ITEM, createListenerSet(), transformationRequest);
new FallbackListener(
PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest);
assertThrows(
IllegalStateException.class,
......@@ -52,10 +55,12 @@ public class FallbackListenerTest {
public void onTransformationRequestFinalized_afterTrackRegistration_completesSuccessfully() {
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
FallbackListener fallbackListener =
new FallbackListener(PLACEHOLDER_MEDIA_ITEM, createListenerSet(), transformationRequest);
new FallbackListener(
PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest);
fallbackListener.registerTrack();
fallbackListener.onTransformationRequestFinalized(transformationRequest);
ShadowLooper.idleMainLooper();
}
@Test
......@@ -66,10 +71,14 @@ public class FallbackListenerTest {
Transformer.Listener mockListener = mock(Transformer.Listener.class);
FallbackListener fallbackListener =
new FallbackListener(
PLACEHOLDER_MEDIA_ITEM, createListenerSet(mockListener), originalRequest);
PLACEHOLDER_MEDIA_ITEM,
createListenerSet(mockListener),
createHandler(),
originalRequest);
fallbackListener.registerTrack();
fallbackListener.onTransformationRequestFinalized(unchangedRequest);
ShadowLooper.idleMainLooper();
verify(mockListener, never()).onFallbackApplied(any(), any(), any());
}
......@@ -83,10 +92,14 @@ public class FallbackListenerTest {
Transformer.Listener mockListener = mock(Transformer.Listener.class);
FallbackListener fallbackListener =
new FallbackListener(
PLACEHOLDER_MEDIA_ITEM, createListenerSet(mockListener), originalRequest);
PLACEHOLDER_MEDIA_ITEM,
createListenerSet(mockListener),
createHandler(),
originalRequest);
fallbackListener.registerTrack();
fallbackListener.onTransformationRequestFinalized(audioFallbackRequest);
ShadowLooper.idleMainLooper();
verify(mockListener)
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, audioFallbackRequest);
......@@ -109,12 +122,16 @@ public class FallbackListenerTest {
Transformer.Listener mockListener = mock(Transformer.Listener.class);
FallbackListener fallbackListener =
new FallbackListener(
PLACEHOLDER_MEDIA_ITEM, createListenerSet(mockListener), originalRequest);
PLACEHOLDER_MEDIA_ITEM,
createListenerSet(mockListener),
createHandler(),
originalRequest);
fallbackListener.registerTrack();
fallbackListener.registerTrack();
fallbackListener.onTransformationRequestFinalized(audioFallbackRequest);
fallbackListener.onTransformationRequestFinalized(videoFallbackRequest);
ShadowLooper.idleMainLooper();
verify(mockListener)
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, mergedFallbackRequest);
......@@ -130,4 +147,8 @@ public class FallbackListenerTest {
private static ListenerSet<Transformer.Listener> createListenerSet() {
return new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {});
}
private static HandlerWrapper createHandler() {
return Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null);
}
}
......@@ -45,6 +45,7 @@ public final class VideoEncoderWrapperTest {
new FallbackListener(
MediaItem.fromUri(Uri.EMPTY),
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {}),
Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null),
emptyTransformationRequest);
private final VideoTranscodingSamplePipeline.EncoderWrapper encoderWrapper =
new VideoTranscodingSamplePipeline.EncoderWrapper(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment