mirror of
https://github.com/androidx/media.git
synced 2025-05-05 06:30:24 +08:00
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
This commit is contained in:
parent
2f8cf947c7
commit
f3fc4fb973
@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkState;
|
|||||||
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.MediaItem;
|
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.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
private final MediaItem mediaItem;
|
private final MediaItem mediaItem;
|
||||||
private final TransformationRequest originalTransformationRequest;
|
private final TransformationRequest originalTransformationRequest;
|
||||||
private final ListenerSet<Transformer.Listener> transformerListeners;
|
private final ListenerSet<Transformer.Listener> transformerListeners;
|
||||||
|
private final HandlerWrapper transformerListenerHandler;
|
||||||
|
|
||||||
private TransformationRequest fallbackTransformationRequest;
|
private TransformationRequest fallbackTransformationRequest;
|
||||||
private int trackCount;
|
private int trackCount;
|
||||||
@ -40,16 +42,20 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
* @param mediaItem The {@link MediaItem} to transform.
|
* @param mediaItem The {@link MediaItem} to transform.
|
||||||
* @param transformerListeners The {@linkplain Transformer.Listener listeners} to forward events
|
* @param transformerListeners The {@linkplain Transformer.Listener listeners} to call {@link
|
||||||
* to.
|
* Transformer.Listener#onFallbackApplied} on.
|
||||||
|
* @param transformerListenerHandler The {@link HandlerWrapper} to call {@link
|
||||||
|
* Transformer.Listener#onFallbackApplied} events on.
|
||||||
* @param originalTransformationRequest The original {@link TransformationRequest}.
|
* @param originalTransformationRequest The original {@link TransformationRequest}.
|
||||||
*/
|
*/
|
||||||
public FallbackListener(
|
public FallbackListener(
|
||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
ListenerSet<Transformer.Listener> transformerListeners,
|
ListenerSet<Transformer.Listener> transformerListeners,
|
||||||
|
HandlerWrapper transformerListenerHandler,
|
||||||
TransformationRequest originalTransformationRequest) {
|
TransformationRequest originalTransformationRequest) {
|
||||||
this.mediaItem = mediaItem;
|
this.mediaItem = mediaItem;
|
||||||
this.transformerListeners = transformerListeners;
|
this.transformerListeners = transformerListeners;
|
||||||
|
this.transformerListenerHandler = transformerListenerHandler;
|
||||||
this.originalTransformationRequest = originalTransformationRequest;
|
this.originalTransformationRequest = originalTransformationRequest;
|
||||||
this.fallbackTransformationRequest = originalTransformationRequest;
|
this.fallbackTransformationRequest = originalTransformationRequest;
|
||||||
}
|
}
|
||||||
@ -98,15 +104,19 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
if (transformationRequest.hdrMode != originalTransformationRequest.hdrMode) {
|
if (transformationRequest.hdrMode != originalTransformationRequest.hdrMode) {
|
||||||
fallbackRequestBuilder.setHdrMode(transformationRequest.hdrMode);
|
fallbackRequestBuilder.setHdrMode(transformationRequest.hdrMode);
|
||||||
}
|
}
|
||||||
fallbackTransformationRequest = fallbackRequestBuilder.build();
|
TransformationRequest newFallbackTransformationRequest = fallbackRequestBuilder.build();
|
||||||
|
fallbackTransformationRequest = newFallbackTransformationRequest;
|
||||||
|
|
||||||
if (trackCount == 0 && !originalTransformationRequest.equals(fallbackTransformationRequest)) {
|
if (trackCount == 0 && !originalTransformationRequest.equals(fallbackTransformationRequest)) {
|
||||||
transformerListeners.queueEvent(
|
transformerListenerHandler.post(
|
||||||
/* eventFlag= */ C.INDEX_UNSET,
|
() ->
|
||||||
listener ->
|
transformerListeners.sendEvent(
|
||||||
listener.onFallbackApplied(
|
/* eventFlag= */ C.INDEX_UNSET,
|
||||||
mediaItem, originalTransformationRequest, fallbackTransformationRequest));
|
listener ->
|
||||||
transformerListeners.flushEvents();
|
listener.onFallbackApplied(
|
||||||
|
mediaItem,
|
||||||
|
originalTransformationRequest,
|
||||||
|
newFallbackTransformationRequest)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,11 @@ public final class Transformer {
|
|||||||
TransformerInternalListener transformerInternalListener =
|
TransformerInternalListener transformerInternalListener =
|
||||||
new TransformerInternalListener(mediaItem);
|
new TransformerInternalListener(mediaItem);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(mediaItem, listeners, transformationRequest);
|
new FallbackListener(
|
||||||
|
mediaItem,
|
||||||
|
listeners,
|
||||||
|
clock.createHandler(looper, /* callback= */ null),
|
||||||
|
transformationRequest);
|
||||||
transformerInternal =
|
transformerInternal =
|
||||||
new TransformerInternal(
|
new TransformerInternal(
|
||||||
context,
|
context,
|
||||||
|
@ -26,10 +26,12 @@ import android.os.Looper;
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.MediaItem;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
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.ListenerSet;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.shadows.ShadowLooper;
|
||||||
|
|
||||||
/** Unit tests for {@link FallbackListener}. */
|
/** Unit tests for {@link FallbackListener}. */
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@ -41,7 +43,8 @@ public class FallbackListenerTest {
|
|||||||
public void onTransformationRequestFinalized_withoutTrackRegistration_throwsException() {
|
public void onTransformationRequestFinalized_withoutTrackRegistration_throwsException() {
|
||||||
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(PLACEHOLDER_MEDIA_ITEM, createListenerSet(), transformationRequest);
|
new FallbackListener(
|
||||||
|
PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest);
|
||||||
|
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
@ -52,10 +55,12 @@ public class FallbackListenerTest {
|
|||||||
public void onTransformationRequestFinalized_afterTrackRegistration_completesSuccessfully() {
|
public void onTransformationRequestFinalized_afterTrackRegistration_completesSuccessfully() {
|
||||||
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
TransformationRequest transformationRequest = new TransformationRequest.Builder().build();
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(PLACEHOLDER_MEDIA_ITEM, createListenerSet(), transformationRequest);
|
new FallbackListener(
|
||||||
|
PLACEHOLDER_MEDIA_ITEM, createListenerSet(), createHandler(), transformationRequest);
|
||||||
|
|
||||||
fallbackListener.registerTrack();
|
fallbackListener.registerTrack();
|
||||||
fallbackListener.onTransformationRequestFinalized(transformationRequest);
|
fallbackListener.onTransformationRequestFinalized(transformationRequest);
|
||||||
|
ShadowLooper.idleMainLooper();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -66,10 +71,14 @@ public class FallbackListenerTest {
|
|||||||
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM, createListenerSet(mockListener), originalRequest);
|
PLACEHOLDER_MEDIA_ITEM,
|
||||||
|
createListenerSet(mockListener),
|
||||||
|
createHandler(),
|
||||||
|
originalRequest);
|
||||||
|
|
||||||
fallbackListener.registerTrack();
|
fallbackListener.registerTrack();
|
||||||
fallbackListener.onTransformationRequestFinalized(unchangedRequest);
|
fallbackListener.onTransformationRequestFinalized(unchangedRequest);
|
||||||
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
verify(mockListener, never()).onFallbackApplied(any(), any(), any());
|
verify(mockListener, never()).onFallbackApplied(any(), any(), any());
|
||||||
}
|
}
|
||||||
@ -83,10 +92,14 @@ public class FallbackListenerTest {
|
|||||||
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new 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(audioFallbackRequest);
|
||||||
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
verify(mockListener)
|
verify(mockListener)
|
||||||
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, audioFallbackRequest);
|
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, audioFallbackRequest);
|
||||||
@ -109,12 +122,16 @@ public class FallbackListenerTest {
|
|||||||
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
Transformer.Listener mockListener = mock(Transformer.Listener.class);
|
||||||
FallbackListener fallbackListener =
|
FallbackListener fallbackListener =
|
||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
PLACEHOLDER_MEDIA_ITEM, createListenerSet(mockListener), originalRequest);
|
PLACEHOLDER_MEDIA_ITEM,
|
||||||
|
createListenerSet(mockListener),
|
||||||
|
createHandler(),
|
||||||
|
originalRequest);
|
||||||
|
|
||||||
fallbackListener.registerTrack();
|
fallbackListener.registerTrack();
|
||||||
fallbackListener.registerTrack();
|
fallbackListener.registerTrack();
|
||||||
fallbackListener.onTransformationRequestFinalized(audioFallbackRequest);
|
fallbackListener.onTransformationRequestFinalized(audioFallbackRequest);
|
||||||
fallbackListener.onTransformationRequestFinalized(videoFallbackRequest);
|
fallbackListener.onTransformationRequestFinalized(videoFallbackRequest);
|
||||||
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
verify(mockListener)
|
verify(mockListener)
|
||||||
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, mergedFallbackRequest);
|
.onFallbackApplied(PLACEHOLDER_MEDIA_ITEM, originalRequest, mergedFallbackRequest);
|
||||||
@ -130,4 +147,8 @@ public class FallbackListenerTest {
|
|||||||
private static ListenerSet<Transformer.Listener> createListenerSet() {
|
private static ListenerSet<Transformer.Listener> createListenerSet() {
|
||||||
return new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {});
|
return new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static HandlerWrapper createHandler() {
|
||||||
|
return Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ public final class VideoEncoderWrapperTest {
|
|||||||
new FallbackListener(
|
new FallbackListener(
|
||||||
MediaItem.fromUri(Uri.EMPTY),
|
MediaItem.fromUri(Uri.EMPTY),
|
||||||
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {}),
|
new ListenerSet<>(Looper.myLooper(), Clock.DEFAULT, (listener, flags) -> {}),
|
||||||
|
Clock.DEFAULT.createHandler(Looper.myLooper(), /* callback= */ null),
|
||||||
emptyTransformationRequest);
|
emptyTransformationRequest);
|
||||||
private final VideoTranscodingSamplePipeline.EncoderWrapper encoderWrapper =
|
private final VideoTranscodingSamplePipeline.EncoderWrapper encoderWrapper =
|
||||||
new VideoTranscodingSamplePipeline.EncoderWrapper(
|
new VideoTranscodingSamplePipeline.EncoderWrapper(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user