Commit e98bee61 by olly Committed by Oliver Woodman

Add surface attach/detach to *WithRendererDisabling tests

This will cause the test to exercise the code path of
instantiating a DummySurface, rendering to it for 10
seconds, then re-targeting the real surface again. For
secure content tests the code path is only exercised if
DummySurface.SECURE_SUPPORTED is true. The logic for
checking this is within MediaCodecVideoRenderer itself,
rather than being part of the test.

Issue: #677

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=157833026
parent ba9114c9
...@@ -653,10 +653,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -653,10 +653,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
private boolean shouldUseDummySurface(boolean codecIsSecure) { private boolean shouldUseDummySurface(boolean codecIsSecure) {
// TODO: Work out when we can safely uncomment the secure case below. This case is currently return Util.SDK_INT >= 23 && !tunneling && (!codecIsSecure
// broken on Galaxy S8 [Internal: b/37197802]. || (DummySurface.SECURE_SUPPORTED && !deviceNeedsSecureDummySurfaceWorkaround()));
return Util.SDK_INT >= 23 && !tunneling
&& (!codecIsSecure /* || DummySurface.SECURE_SUPPORTED */);
} }
private void setJoiningDeadlineMs() { private void setJoiningDeadlineMs() {
...@@ -924,6 +922,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -924,6 +922,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
} }
/** /**
* Returns whether the device is known to fail outputting from a secure decoder to a secure
* surface texture.
* <p>
* If true is returned then use of {@link DummySurface} is disabled for secure playbacks.
*/
private static boolean deviceNeedsSecureDummySurfaceWorkaround() {
// See [Internal: b/37197802].
return Util.SDK_INT == 24
&& (Util.MODEL.startsWith("SM-G950") || Util.MODEL.startsWith("SM-G955"));
}
/**
* Returns whether the device is known to enable frame-rate conversion logic that negatively * Returns whether the device is known to enable frame-rate conversion logic that negatively
* impacts ExoPlayer. * impacts ExoPlayer.
* <p> * <p>
......
...@@ -67,6 +67,10 @@ public final class DashStreamingTest extends ActivityInstrumentationTestCase2<Ho ...@@ -67,6 +67,10 @@ public final class DashStreamingTest extends ActivityInstrumentationTestCase2<Ho
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX) .enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
.disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX) .disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX) .enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
// Wait 10 seconds, detach the surface, wait another 10 seconds and attach it again.
.delay(10000).clearVideoSurface()
.delay(10000).setVideoSurface()
// Wait 10 seconds, then seek to near end.
.delay(10000).seek(120000) .delay(10000).seek(120000)
.build(); .build();
......
...@@ -16,7 +16,9 @@ ...@@ -16,7 +16,9 @@
package com.google.android.exoplayer2.playbacktests.util; package com.google.android.exoplayer2.playbacktests.util;
import android.util.Log; import android.util.Log;
import android.view.Surface;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
/** /**
...@@ -41,19 +43,24 @@ public abstract class Action { ...@@ -41,19 +43,24 @@ public abstract class Action {
* *
* @param player The player to which the action should be applied. * @param player The player to which the action should be applied.
* @param trackSelector The track selector to which the action should be applied. * @param trackSelector The track selector to which the action should be applied.
* @param surface The surface to use when applying actions.
*/ */
public final void doAction(ExoPlayer player, MappingTrackSelector trackSelector) { public final void doAction(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
Log.i(tag, description); Log.i(tag, description);
doActionImpl(player, trackSelector); doActionImpl(player, trackSelector, surface);
} }
/** /**
* Called by {@link #doAction(ExoPlayer, MappingTrackSelector)} do actually perform the action. * Called by {@link #doAction(SimpleExoPlayer, MappingTrackSelector, Surface)} do perform the
* action.
* *
* @param player The player to which the action should be applied. * @param player The player to which the action should be applied.
* @param trackSelector The track selector to which the action should be applied. * @param trackSelector The track selector to which the action should be applied.
* @param surface The surface to use when applying actions.
*/ */
protected abstract void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector); protected abstract void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface);
/** /**
* Calls {@link ExoPlayer#seekTo(long)}. * Calls {@link ExoPlayer#seekTo(long)}.
...@@ -72,7 +79,8 @@ public abstract class Action { ...@@ -72,7 +79,8 @@ public abstract class Action {
} }
@Override @Override
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) { protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
player.seekTo(positionMs); player.seekTo(positionMs);
} }
...@@ -91,7 +99,8 @@ public abstract class Action { ...@@ -91,7 +99,8 @@ public abstract class Action {
} }
@Override @Override
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) { protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
player.stop(); player.stop();
} }
...@@ -114,7 +123,8 @@ public abstract class Action { ...@@ -114,7 +123,8 @@ public abstract class Action {
} }
@Override @Override
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) { protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
player.setPlayWhenReady(playWhenReady); player.setPlayWhenReady(playWhenReady);
} }
...@@ -140,10 +150,52 @@ public abstract class Action { ...@@ -140,10 +150,52 @@ public abstract class Action {
} }
@Override @Override
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) { protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
trackSelector.setRendererDisabled(rendererIndex, disabled); trackSelector.setRendererDisabled(rendererIndex, disabled);
} }
} }
/**
* Calls {@link SimpleExoPlayer#clearVideoSurface()}.
*/
public static final class ClearVideoSurface extends Action {
/**
* @param tag A tag to use for logging.
*/
public ClearVideoSurface(String tag) {
super(tag, "ClearVideoSurface");
}
@Override
protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
player.clearVideoSurface();
}
}
/**
* Calls {@link SimpleExoPlayer#setVideoSurface(Surface)}.
*/
public static final class SetVideoSurface extends Action {
/**
* @param tag A tag to use for logging.
*/
public SetVideoSurface(String tag) {
super(tag, "SetVideoSurface");
}
@Override
protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
player.setVideoSurface(surface);
}
}
} }
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
package com.google.android.exoplayer2.playbacktests.util; package com.google.android.exoplayer2.playbacktests.util;
import android.os.Handler; import android.os.Handler;
import com.google.android.exoplayer2.ExoPlayer; import android.view.Surface;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.playbacktests.util.Action.ClearVideoSurface;
import com.google.android.exoplayer2.playbacktests.util.Action.Seek; import com.google.android.exoplayer2.playbacktests.util.Action.Seek;
import com.google.android.exoplayer2.playbacktests.util.Action.SetPlayWhenReady; import com.google.android.exoplayer2.playbacktests.util.Action.SetPlayWhenReady;
import com.google.android.exoplayer2.playbacktests.util.Action.SetRendererDisabled; import com.google.android.exoplayer2.playbacktests.util.Action.SetRendererDisabled;
import com.google.android.exoplayer2.playbacktests.util.Action.SetVideoSurface;
import com.google.android.exoplayer2.playbacktests.util.Action.Stop; import com.google.android.exoplayer2.playbacktests.util.Action.Stop;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
...@@ -42,11 +45,12 @@ public final class ActionSchedule { ...@@ -42,11 +45,12 @@ public final class ActionSchedule {
* *
* @param player The player to which actions should be applied. * @param player The player to which actions should be applied.
* @param trackSelector The track selector to which actions should be applied. * @param trackSelector The track selector to which actions should be applied.
* @param surface The surface to use when applying actions.
* @param mainHandler A handler associated with the main thread of the host activity. * @param mainHandler A handler associated with the main thread of the host activity.
*/ */
/* package */ void start(ExoPlayer player, MappingTrackSelector trackSelector, /* package */ void start(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Handler mainHandler) { Surface surface, Handler mainHandler) {
rootNode.schedule(player, trackSelector, mainHandler); rootNode.schedule(player, trackSelector, surface, mainHandler);
} }
/** /**
...@@ -149,6 +153,24 @@ public final class ActionSchedule { ...@@ -149,6 +153,24 @@ public final class ActionSchedule {
return apply(new SetRendererDisabled(tag, index, true)); return apply(new SetRendererDisabled(tag, index, true));
} }
/**
* Schedules a clear video surface action to be executed.
*
* @return The builder, for convenience.
*/
public Builder clearVideoSurface() {
return apply(new ClearVideoSurface(tag));
}
/**
* Schedules a set video surface action to be executed.
*
* @return The builder, for convenience.
*/
public Builder setVideoSurface() {
return apply(new SetVideoSurface(tag));
}
public ActionSchedule build() { public ActionSchedule build() {
return new ActionSchedule(rootNode); return new ActionSchedule(rootNode);
} }
...@@ -165,8 +187,9 @@ public final class ActionSchedule { ...@@ -165,8 +187,9 @@ public final class ActionSchedule {
private ActionNode next; private ActionNode next;
private ExoPlayer player; private SimpleExoPlayer player;
private MappingTrackSelector trackSelector; private MappingTrackSelector trackSelector;
private Surface surface;
private Handler mainHandler; private Handler mainHandler;
/** /**
...@@ -193,21 +216,23 @@ public final class ActionSchedule { ...@@ -193,21 +216,23 @@ public final class ActionSchedule {
* *
* @param player The player to which actions should be applied. * @param player The player to which actions should be applied.
* @param trackSelector The track selector to which actions should be applied. * @param trackSelector The track selector to which actions should be applied.
* @param surface The surface to use when applying actions.
* @param mainHandler A handler associated with the main thread of the host activity. * @param mainHandler A handler associated with the main thread of the host activity.
*/ */
public void schedule(ExoPlayer player, MappingTrackSelector trackSelector, public void schedule(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Handler mainHandler) { Surface surface, Handler mainHandler) {
this.player = player; this.player = player;
this.trackSelector = trackSelector; this.trackSelector = trackSelector;
this.surface = surface;
this.mainHandler = mainHandler; this.mainHandler = mainHandler;
mainHandler.postDelayed(this, delayMs); mainHandler.postDelayed(this, delayMs);
} }
@Override @Override
public void run() { public void run() {
action.doAction(player, trackSelector); action.doAction(player, trackSelector, surface);
if (next != null) { if (next != null) {
next.schedule(player, trackSelector, mainHandler); next.schedule(player, trackSelector, surface, mainHandler);
} }
} }
...@@ -223,7 +248,8 @@ public final class ActionSchedule { ...@@ -223,7 +248,8 @@ public final class ActionSchedule {
} }
@Override @Override
protected void doActionImpl(ExoPlayer player, MappingTrackSelector trackSelector) { protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
Surface surface) {
// Do nothing. // Do nothing.
} }
......
...@@ -76,6 +76,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -76,6 +76,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
private Handler actionHandler; private Handler actionHandler;
private MappingTrackSelector trackSelector; private MappingTrackSelector trackSelector;
private SimpleExoPlayer player; private SimpleExoPlayer player;
private Surface surface;
private ExoPlaybackException playerError; private ExoPlaybackException playerError;
private boolean playerWasPrepared; private boolean playerWasPrepared;
private boolean playerFinished; private boolean playerFinished;
...@@ -124,7 +125,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -124,7 +125,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
if (player == null) { if (player == null) {
pendingSchedule = schedule; pendingSchedule = schedule;
} else { } else {
schedule.start(player, trackSelector, actionHandler); schedule.start(player, trackSelector, surface, actionHandler);
} }
} }
...@@ -132,6 +133,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -132,6 +133,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
@Override @Override
public final void onStart(HostActivity host, Surface surface) { public final void onStart(HostActivity host, Surface surface) {
this.surface = surface;
// Build the player. // Build the player.
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
trackSelector = buildTrackSelector(host, bandwidthMeter); trackSelector = buildTrackSelector(host, bandwidthMeter);
...@@ -146,7 +148,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -146,7 +148,7 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
actionHandler = new Handler(); actionHandler = new Handler();
// Schedule any pending actions. // Schedule any pending actions.
if (pendingSchedule != null) { if (pendingSchedule != null) {
pendingSchedule.start(player, trackSelector, actionHandler); pendingSchedule.start(player, trackSelector, surface, actionHandler);
pendingSchedule = null; pendingSchedule = null;
} }
} }
......
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