Commit c92bc3e6 by Oliver Woodman

Enhance DASH playback tests

parent e65f7264
...@@ -25,6 +25,7 @@ import com.google.android.exoplayer.TrackRenderer; ...@@ -25,6 +25,7 @@ import com.google.android.exoplayer.TrackRenderer;
import com.google.android.exoplayer.chunk.ChunkSampleSource; import com.google.android.exoplayer.chunk.ChunkSampleSource;
import com.google.android.exoplayer.chunk.ChunkSource; import com.google.android.exoplayer.chunk.ChunkSource;
import com.google.android.exoplayer.chunk.FormatEvaluator; import com.google.android.exoplayer.chunk.FormatEvaluator;
import com.google.android.exoplayer.chunk.VideoFormatSelectorUtil;
import com.google.android.exoplayer.dash.DashChunkSource; import com.google.android.exoplayer.dash.DashChunkSource;
import com.google.android.exoplayer.dash.DashTrackSelector; import com.google.android.exoplayer.dash.DashTrackSelector;
import com.google.android.exoplayer.dash.mpd.AdaptationSet; import com.google.android.exoplayer.dash.mpd.AdaptationSet;
...@@ -48,9 +49,11 @@ import android.annotation.TargetApi; ...@@ -48,9 +49,11 @@ import android.annotation.TargetApi;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.os.Handler; import android.os.Handler;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.Surface; import android.view.Surface;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
...@@ -68,21 +71,40 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -68,21 +71,40 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private static final String MANIFEST_URL_PREFIX = "https://storage.googleapis.com/exoplayer-test-" private static final String MANIFEST_URL_PREFIX = "https://storage.googleapis.com/exoplayer-test-"
+ "media-1/gen-2/screens/dash-vod-single-segment/"; + "media-1/gen-2/screens/dash-vod-single-segment/";
private static final String H264_BASELINE_MANIFEST = "manifest-baseline.mpd"; private static final String H264_MANIFEST = "manifest-h264.mpd";
private static final String H264_MAIN_MANIFEST = "manifest-main.mpd";
private static final String VP9_MANIFEST = "manifest-vp9.mpd"; private static final String VP9_MANIFEST = "manifest-vp9.mpd";
private static final int AAC_AUDIO_FRAME_COUNT = 5524; private static final int AAC_AUDIO_FRAME_COUNT = 5524;
private static final int H264_VIDEO_FRAME_COUNT = 3841; private static final int H264_VIDEO_FRAME_COUNT = 3841;
private static final int VORBIS_AUDIO_FRAME_COUNT = 7773; private static final int VORBIS_AUDIO_FRAME_COUNT = 7773;
private static final int VP9_VIDEO_FRAME_COUNT = 3841; private static final int VP9_VIDEO_FRAME_COUNT = 3841;
private static final String AAC_AUDIO_REPRESENTATION_ID = "141";
private static final String H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "avc-baseline-240"; private static final String H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "avc-baseline-240";
private static final String H264_BASELINE_480P_VIDEO_REPRESENTATION_ID = "avc-baseline-480"; private static final String H264_BASELINE_480P_VIDEO_REPRESENTATION_ID = "avc-baseline-480";
private static final String H264_MAIN_240P_VIDEO_REPRESENTATION_ID = "avc-main-240"; private static final String H264_MAIN_240P_VIDEO_REPRESENTATION_ID = "avc-main-240";
private static final String H264_MAIN_480P_VIDEO_REPRESENTATION_ID = "avc-main-480"; private static final String H264_MAIN_480P_VIDEO_REPRESENTATION_ID = "avc-main-480";
private static final String AAC_AUDIO_REPRESENTATION_ID = "141"; // The highest quality H264 format mandated by the Android CDD.
private static final String H264_CDD_FIXED = Util.SDK_INT < 23
? H264_BASELINE_480P_VIDEO_REPRESENTATION_ID : H264_MAIN_480P_VIDEO_REPRESENTATION_ID;
// Multiple H264 formats mandated by the Android CDD.
private static final String[] H264_CDD_ADAPTIVE = Util.SDK_INT < 23
? new String[] {
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
H264_BASELINE_480P_VIDEO_REPRESENTATION_ID}
: new String[] {
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
H264_BASELINE_480P_VIDEO_REPRESENTATION_ID,
H264_MAIN_240P_VIDEO_REPRESENTATION_ID,
H264_MAIN_480P_VIDEO_REPRESENTATION_ID};
private static final String VORBIS_AUDIO_REPRESENTATION_ID = "2";
private static final String VP9_180P_VIDEO_REPRESENTATION_ID = "0"; private static final String VP9_180P_VIDEO_REPRESENTATION_ID = "0";
private static final String VP9_360P_VIDEO_REPRESENTATION_ID = "1"; private static final String VP9_360P_VIDEO_REPRESENTATION_ID = "1";
private static final String VORBIS_AUDIO_REPRESENTATION_ID = "2";
// Whether adaptive tests should enable video formats beyond those mandated by the Android CDD
// if the device advertises support for them.
private static final boolean ALLOW_ADDITIONAL_VIDEO_FORMATS = Util.SDK_INT >= 21;
private static final ActionSchedule SEEKING_SCHEDULE = new ActionSchedule.Builder(TAG) private static final ActionSchedule SEEKING_SCHEDULE = new ActionSchedule.Builder(TAG)
.delay(10000).seek(15000) .delay(10000).seek(15000)
.delay(10000).seek(30000).seek(31000).seek(32000).seek(33000).seek(34000) .delay(10000).seek(30000).seek(31000).seek(32000).seek(33000).seek(34000)
...@@ -124,84 +146,48 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -124,84 +146,48 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
super(HostActivity.class); super(HostActivity.class);
} }
public void testH264FixedBaseline480p() throws IOException { // H264 CDD.
if (Util.SDK_INT < 16) {
// Pass.
return;
}
testDashPlayback(getActivity(), AAC_AUDIO_FRAME_COUNT, H264_VIDEO_FRAME_COUNT,
H264_BASELINE_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
H264_BASELINE_480P_VIDEO_REPRESENTATION_ID);
}
public void testH264FixedMain480p() throws IOException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
testDashPlayback(getActivity(), AAC_AUDIO_FRAME_COUNT, H264_VIDEO_FRAME_COUNT,
H264_MAIN_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, H264_MAIN_480P_VIDEO_REPRESENTATION_ID);
}
public void testH264BaselineAdaptive() throws IOException { public void testH264Fixed() throws IOException {
if (Util.SDK_INT < 16) { if (Util.SDK_INT < 16) {
// Pass. // Pass.
return; return;
} }
testDashPlayback(getActivity(), AAC_AUDIO_FRAME_COUNT, H264_VIDEO_FRAME_COUNT, testDashPlayback(getActivity(), AAC_AUDIO_FRAME_COUNT, H264_VIDEO_FRAME_COUNT,
H264_BASELINE_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false, H264_CDD_FIXED);
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID, H264_BASELINE_480P_VIDEO_REPRESENTATION_ID);
} }
public void testH264MainAdaptive() throws IOException { public void testH264Adaptive() throws IOException {
if (Util.SDK_INT < 23) { if (Util.SDK_INT < 16) {
// Pass. // Pass.
return; return;
} }
testDashPlayback(getActivity(), AAC_AUDIO_FRAME_COUNT, H264_VIDEO_FRAME_COUNT, testDashPlayback(getActivity(), AAC_AUDIO_FRAME_COUNT, H264_VIDEO_FRAME_COUNT,
H264_MAIN_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, H264_MAIN_240P_VIDEO_REPRESENTATION_ID, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS,
H264_MAIN_480P_VIDEO_REPRESENTATION_ID); H264_CDD_ADAPTIVE);
} }
public void testH264BaselineAdaptiveWithSeeking() throws IOException { public void testH264AdaptiveWithSeeking() throws IOException {
if (Util.SDK_INT < 16) { if (Util.SDK_INT < 16) {
// Pass. // Pass.
return; return;
} }
testDashPlayback(getActivity(), SEEKING_SCHEDULE, false, AAC_AUDIO_FRAME_COUNT, testDashPlayback(getActivity(), SEEKING_SCHEDULE, false, AAC_AUDIO_FRAME_COUNT,
H264_VIDEO_FRAME_COUNT, H264_BASELINE_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, H264_VIDEO_FRAME_COUNT, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID, H264_BASELINE_480P_VIDEO_REPRESENTATION_ID); ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE);
} }
public void testH264MainAdaptiveWithSeeking() throws IOException { public void testH264AdaptiveWithRendererDisabling() throws IOException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
testDashPlayback(getActivity(), SEEKING_SCHEDULE, false, AAC_AUDIO_FRAME_COUNT,
H264_VIDEO_FRAME_COUNT, H264_MAIN_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
H264_MAIN_240P_VIDEO_REPRESENTATION_ID, H264_MAIN_480P_VIDEO_REPRESENTATION_ID);
}
public void testH264BaselineAdaptiveWithRendererDisabling() throws IOException {
if (Util.SDK_INT < 16) { if (Util.SDK_INT < 16) {
// Pass. // Pass.
return; return;
} }
testDashPlayback(getActivity(), RENDERER_DISABLING_SCHEDULE, false, AAC_AUDIO_FRAME_COUNT, testDashPlayback(getActivity(), RENDERER_DISABLING_SCHEDULE, false, AAC_AUDIO_FRAME_COUNT,
H264_VIDEO_FRAME_COUNT, H264_BASELINE_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, H264_VIDEO_FRAME_COUNT, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID, H264_BASELINE_480P_VIDEO_REPRESENTATION_ID); ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE);
} }
public void testH264MainAdaptiveWithRendererDisabling() throws IOException { // VP9 (CDD).
if (Util.SDK_INT < 23) {
// Pass.
return;
}
testDashPlayback(getActivity(), RENDERER_DISABLING_SCHEDULE, false, AAC_AUDIO_FRAME_COUNT,
H264_VIDEO_FRAME_COUNT, H264_MAIN_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
H264_MAIN_240P_VIDEO_REPRESENTATION_ID, H264_MAIN_480P_VIDEO_REPRESENTATION_ID);
}
public void testVp9Fixed360p() throws IOException { public void testVp9Fixed360p() throws IOException {
if (Util.SDK_INT < 16) { if (Util.SDK_INT < 16) {
...@@ -209,7 +195,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -209,7 +195,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
return; return;
} }
testDashPlayback(getActivity(), VORBIS_AUDIO_FRAME_COUNT, VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST, testDashPlayback(getActivity(), VORBIS_AUDIO_FRAME_COUNT, VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST,
VORBIS_AUDIO_REPRESENTATION_ID, VP9_360P_VIDEO_REPRESENTATION_ID); VORBIS_AUDIO_REPRESENTATION_ID, false, VP9_360P_VIDEO_REPRESENTATION_ID);
} }
public void testVp9Adaptive() throws IOException { public void testVp9Adaptive() throws IOException {
...@@ -218,8 +204,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -218,8 +204,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
return; return;
} }
testDashPlayback(getActivity(), VORBIS_AUDIO_FRAME_COUNT, VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST, testDashPlayback(getActivity(), VORBIS_AUDIO_FRAME_COUNT, VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST,
VORBIS_AUDIO_REPRESENTATION_ID, VP9_180P_VIDEO_REPRESENTATION_ID, VORBIS_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS,
VP9_360P_VIDEO_REPRESENTATION_ID); VP9_180P_VIDEO_REPRESENTATION_ID, VP9_360P_VIDEO_REPRESENTATION_ID);
} }
public void testVp9AdaptiveWithSeeking() throws IOException { public void testVp9AdaptiveWithSeeking() throws IOException {
...@@ -229,7 +215,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -229,7 +215,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
testDashPlayback(getActivity(), SEEKING_SCHEDULE, false, VORBIS_AUDIO_FRAME_COUNT, testDashPlayback(getActivity(), SEEKING_SCHEDULE, false, VORBIS_AUDIO_FRAME_COUNT,
VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID,
VP9_180P_VIDEO_REPRESENTATION_ID, VP9_360P_VIDEO_REPRESENTATION_ID); ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_180P_VIDEO_REPRESENTATION_ID,
VP9_360P_VIDEO_REPRESENTATION_ID);
} }
public void testVp9AdaptiveWithRendererDisabling() throws IOException { public void testVp9AdaptiveWithRendererDisabling() throws IOException {
...@@ -239,24 +226,28 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -239,24 +226,28 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
testDashPlayback(getActivity(), RENDERER_DISABLING_SCHEDULE, false, VORBIS_AUDIO_FRAME_COUNT, testDashPlayback(getActivity(), RENDERER_DISABLING_SCHEDULE, false, VORBIS_AUDIO_FRAME_COUNT,
VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, VP9_VIDEO_FRAME_COUNT, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID,
VP9_180P_VIDEO_REPRESENTATION_ID, VP9_360P_VIDEO_REPRESENTATION_ID); ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_180P_VIDEO_REPRESENTATION_ID,
VP9_360P_VIDEO_REPRESENTATION_ID);
} }
// Internal.
private static void testDashPlayback(HostActivity activity, int sourceAudioFrameCount, private static void testDashPlayback(HostActivity activity, int sourceAudioFrameCount,
int sourceVideoFrameCount, String manifestFileName, String audioRepresentationId, int sourceVideoFrameCount, String manifestFileName, String audioFormat,
String... videoRepresentationIds) throws IOException { boolean includeAdditionalVideoFormats, String... videoFormats) throws IOException {
testDashPlayback(activity, null, true, sourceAudioFrameCount, sourceVideoFrameCount, testDashPlayback(activity, null, true, sourceAudioFrameCount, sourceVideoFrameCount,
manifestFileName, audioRepresentationId, videoRepresentationIds); manifestFileName, audioFormat, includeAdditionalVideoFormats, videoFormats);
} }
private static void testDashPlayback(HostActivity activity, ActionSchedule actionSchedule, private static void testDashPlayback(HostActivity activity, ActionSchedule actionSchedule,
boolean fullPlaybackNoSeeking, int sourceAudioFrameCount, int sourceVideoFrameCount, boolean fullPlaybackNoSeeking, int sourceAudioFrameCount, int sourceVideoFrameCount,
String manifestFileName, String audioRepresentationId, String... videoRepresentationIds) String manifestFileName, String audioFormat, boolean includeAdditionalVideoFormats,
throws IOException { String... videoFormats) throws IOException {
MediaPresentationDescription mpd = TestUtil.loadManifest(activity, MediaPresentationDescription mpd = TestUtil.loadManifest(activity,
MANIFEST_URL_PREFIX + manifestFileName, new MediaPresentationDescriptionParser()); MANIFEST_URL_PREFIX + manifestFileName, new MediaPresentationDescriptionParser());
DashHostedTest test = new DashHostedTest(mpd, fullPlaybackNoSeeking, sourceAudioFrameCount, DashHostedTest test = new DashHostedTest(mpd, fullPlaybackNoSeeking, sourceAudioFrameCount,
sourceVideoFrameCount, audioRepresentationId, videoRepresentationIds); sourceVideoFrameCount, audioFormat, includeAdditionalVideoFormats,
videoFormats);
if (actionSchedule != null) { if (actionSchedule != null) {
test.setSchedule(actionSchedule); test.setSchedule(actionSchedule);
} }
...@@ -284,6 +275,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -284,6 +275,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private final int sourceAudioFrameCount; private final int sourceAudioFrameCount;
private final int sourceVideoFrameCount; private final int sourceVideoFrameCount;
private String[] audioFormats; private String[] audioFormats;
private boolean includeAdditionalVideoFormats;
private String[] videoFormats; private String[] videoFormats;
private CodecCounters videoCounters; private CodecCounters videoCounters;
...@@ -296,17 +288,20 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -296,17 +288,20 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
* @param sourceAudioFrameCount The number of audio frames in the source. * @param sourceAudioFrameCount The number of audio frames in the source.
* @param sourceVideoFrameCount The number of video frames in the source. * @param sourceVideoFrameCount The number of video frames in the source.
* @param audioFormat The audio format. * @param audioFormat The audio format.
* @param includeAdditionalVideoFormats Whether to use video formats in addition to
* those listed in the videoFormats argument, if the device is capable of playing them.
* @param videoFormats The video formats. * @param videoFormats The video formats.
*/ */
public DashHostedTest(MediaPresentationDescription mpd, boolean fullPlaybackNoSeeking, public DashHostedTest(MediaPresentationDescription mpd, boolean fullPlaybackNoSeeking,
int sourceAudioFrameCount, int sourceVideoFrameCount, String audioFormat, int sourceAudioFrameCount, int sourceVideoFrameCount, String audioFormat,
String... videoFormats) { boolean includeAdditionalVideoFormats, String... videoFormats) {
super(RENDERER_COUNT); super(RENDERER_COUNT);
this.mpd = Assertions.checkNotNull(mpd); this.mpd = Assertions.checkNotNull(mpd);
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking; this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
this.sourceAudioFrameCount = sourceAudioFrameCount; this.sourceAudioFrameCount = sourceAudioFrameCount;
this.sourceVideoFrameCount = sourceVideoFrameCount; this.sourceVideoFrameCount = sourceVideoFrameCount;
this.audioFormats = new String[] {audioFormat}; this.audioFormats = new String[] {audioFormat};
this.includeAdditionalVideoFormats = includeAdditionalVideoFormats;
this.videoFormats = videoFormats; this.videoFormats = videoFormats;
} }
...@@ -319,7 +314,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -319,7 +314,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
// Build the video renderer. // Build the video renderer.
DataSource videoDataSource = new DefaultUriDataSource(host, null, userAgent); DataSource videoDataSource = new DefaultUriDataSource(host, null, userAgent);
TrackSelector videoTrackSelector = new TrackSelector(AdaptationSet.TYPE_VIDEO, videoFormats); TrackSelector videoTrackSelector = new TrackSelector(AdaptationSet.TYPE_VIDEO,
includeAdditionalVideoFormats, videoFormats);
ChunkSource videoChunkSource = new DashChunkSource(mpd, videoTrackSelector, videoDataSource, ChunkSource videoChunkSource = new DashChunkSource(mpd, videoTrackSelector, videoDataSource,
new FormatEvaluator.RandomEvaluator(0)); new FormatEvaluator.RandomEvaluator(0));
ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl, ChunkSampleSource videoSampleSource = new ChunkSampleSource(videoChunkSource, loadControl,
...@@ -332,7 +328,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -332,7 +328,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
// Build the audio renderer. // Build the audio renderer.
DataSource audioDataSource = new DefaultUriDataSource(host, null, userAgent); DataSource audioDataSource = new DefaultUriDataSource(host, null, userAgent);
TrackSelector audioTrackSelector = new TrackSelector(AdaptationSet.TYPE_AUDIO, audioFormats); TrackSelector audioTrackSelector = new TrackSelector(AdaptationSet.TYPE_AUDIO, false,
audioFormats);
ChunkSource audioChunkSource = new DashChunkSource(mpd, audioTrackSelector, audioDataSource, ChunkSource audioChunkSource = new DashChunkSource(mpd, audioTrackSelector, audioDataSource,
null); null);
ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl, ChunkSampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
...@@ -357,7 +354,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -357,7 +354,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
CodecCountersUtil.assertOutputFormatChangedCount(AUDIO_TAG, audioCounters, 1); CodecCountersUtil.assertOutputFormatChangedCount(AUDIO_TAG, audioCounters, 1);
CodecCountersUtil.assertOutputBuffersChangedLimit(AUDIO_TAG, audioCounters, 1); CodecCountersUtil.assertOutputBuffersChangedLimit(AUDIO_TAG, audioCounters, 1);
if (videoFormats.length == 1) { if (videoFormats != null && videoFormats.length == 1) {
// Video is not adaptive, so the decoder output format should have changed exactly once. // Video is not adaptive, so the decoder output format should have changed exactly once.
// The output buffers should have changed 0 or 1 times. // The output buffers should have changed 0 or 1 times.
CodecCountersUtil.assertOutputFormatChangedCount(VIDEO_TAG, videoCounters, 1); CodecCountersUtil.assertOutputFormatChangedCount(VIDEO_TAG, videoCounters, 1);
...@@ -395,9 +392,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -395,9 +392,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private final int adaptationSetType; private final int adaptationSetType;
private final String[] representationIds; private final String[] representationIds;
private final boolean includeAdditionalVideoRepresentations;
private TrackSelector(int adaptationSetType, String[] representationIds) { private TrackSelector(int adaptationSetType, boolean includeAdditionalVideoRepresentations,
String[] representationIds) {
Assertions.checkState(!includeAdditionalVideoRepresentations
|| adaptationSetType == AdaptationSet.TYPE_VIDEO);
this.adaptationSetType = adaptationSetType; this.adaptationSetType = adaptationSetType;
this.includeAdditionalVideoRepresentations = includeAdditionalVideoRepresentations;
this.representationIds = representationIds; this.representationIds = representationIds;
} }
...@@ -407,7 +409,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -407,7 +409,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
Period period = manifest.getPeriod(periodIndex); Period period = manifest.getPeriod(periodIndex);
int adaptationSetIndex = period.getAdaptationSetIndex(adaptationSetType); int adaptationSetIndex = period.getAdaptationSetIndex(adaptationSetType);
AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex); AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
int[] representationIndices = getRepresentationIndices(representationIds, adaptationSet); int[] representationIndices = getRepresentationIndices(adaptationSet, representationIds,
includeAdditionalVideoRepresentations);
if (adaptationSetType == AdaptationSet.TYPE_VIDEO) { if (adaptationSetType == AdaptationSet.TYPE_VIDEO) {
output.adaptiveTrack(manifest, periodIndex, adaptationSetIndex, representationIndices); output.adaptiveTrack(manifest, periodIndex, adaptationSetIndex, representationIndices);
} }
...@@ -416,16 +419,19 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -416,16 +419,19 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
} }
private static int[] getRepresentationIndices(String[] representationIds, private static int[] getRepresentationIndices(AdaptationSet adaptationSet,
AdaptationSet adaptationSet) { String[] representationIds, boolean includeAdditionalVideoRepresentations)
List<Representation> representations = adaptationSet.representations; throws IOException {
int[] representationIndices = new int[representationIds.length]; List<Representation> availableRepresentations = adaptationSet.representations;
List<Integer> selectedRepresentationIndices = new ArrayList<>();
// Always select explicitly listed representations, failing if they're missing.
for (int i = 0; i < representationIds.length; i++) { for (int i = 0; i < representationIds.length; i++) {
String representationId = representationIds[i]; String representationId = representationIds[i];
boolean foundIndex = false; boolean foundIndex = false;
for (int j = 0; j < representations.size() && !foundIndex; j++) { for (int j = 0; j < availableRepresentations.size() && !foundIndex; j++) {
if (representations.get(j).format.id.equals(representationId)) { if (availableRepresentations.get(j).format.id.equals(representationId)) {
representationIndices[i] = j; selectedRepresentationIndices.add(j);
foundIndex = true; foundIndex = true;
} }
} }
...@@ -433,11 +439,25 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -433,11 +439,25 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
throw new IllegalStateException("Representation " + representationId + " not found."); throw new IllegalStateException("Representation " + representationId + " not found.");
} }
} }
return representationIndices;
}
} // Select additional video representations, if supported by the device.
if (includeAdditionalVideoRepresentations) {
int[] supportedVideoRepresentationIndices = VideoFormatSelectorUtil.selectVideoFormats(
availableRepresentations, null, false, true, -1, -1);
for (int i = 0; i < supportedVideoRepresentationIndices.length; i++) {
int representationIndex = supportedVideoRepresentationIndices[i];
if (!selectedRepresentationIndices.contains(representationIndex)) {
Log.d(TAG, "Adding video format: " + availableRepresentations.get(i).format.id);
selectedRepresentationIndices.add(representationIndex);
}
}
}
return Util.toArray(selectedRepresentationIndices);
}
}
} }
} }
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