Invert DashHostedTest and inner class Builder to make the design more natural
Builder class was renamed to DashTestRunner and DashHostedTest moved into it as an inner class. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=150307988
This commit is contained in:
parent
9b0d24c909
commit
2fe478ad6a
@ -1,449 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2017 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.google.android.exoplayer2.playbacktests.gts;
|
|
||||||
|
|
||||||
import static com.google.android.exoplayer2.C.WIDEVINE_UUID;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Instrumentation;
|
|
||||||
import android.media.MediaDrm;
|
|
||||||
import android.media.UnsupportedSchemeException;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Surface;
|
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
|
||||||
import com.google.android.exoplayer2.Format;
|
|
||||||
import com.google.android.exoplayer2.RendererCapabilities;
|
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
|
||||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
|
||||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
|
||||||
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
|
||||||
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
|
||||||
import com.google.android.exoplayer2.drm.MediaDrmCallback;
|
|
||||||
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
|
|
||||||
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.ActionSchedule;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.DebugSimpleExoPlayer;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.HostActivity;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.HostActivity.HostedTest;
|
|
||||||
import com.google.android.exoplayer2.playbacktests.util.MetricsLogger;
|
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.TrackGroup;
|
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
|
||||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
|
|
||||||
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
|
|
||||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
|
||||||
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
|
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
|
||||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
|
||||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
|
||||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
|
||||||
import com.google.android.exoplayer2.util.Util;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import junit.framework.AssertionFailedError;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link HostedTest} for DASH playback tests.
|
|
||||||
*/
|
|
||||||
@TargetApi(16)
|
|
||||||
public final class DashHostedTest extends ExoHostedTest {
|
|
||||||
|
|
||||||
/** {@link DashHostedTest} builder. */
|
|
||||||
public static final class Builder {
|
|
||||||
|
|
||||||
private static final long TEST_TIMEOUT_MS = 5 * 60 * 1000;
|
|
||||||
|
|
||||||
private static final String REPORT_NAME = "GtsExoPlayerTestCases";
|
|
||||||
private static final String REPORT_OBJECT_NAME = "playbacktest";
|
|
||||||
|
|
||||||
// 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 >= 24;
|
|
||||||
|
|
||||||
private final String tag;
|
|
||||||
|
|
||||||
private String streamName;
|
|
||||||
private boolean fullPlaybackNoSeeking;
|
|
||||||
private String audioFormat;
|
|
||||||
private boolean canIncludeAdditionalVideoFormats;
|
|
||||||
private ActionSchedule actionSchedule;
|
|
||||||
private byte[] offlineLicenseKeySetId;
|
|
||||||
private String[] videoFormats;
|
|
||||||
private String manifestUrl;
|
|
||||||
private boolean useL1Widevine;
|
|
||||||
private String widevineLicenseUrl;
|
|
||||||
|
|
||||||
public Builder(String tag) {
|
|
||||||
this.tag = tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setStreamName(String streamName) {
|
|
||||||
this.streamName = streamName;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setFullPlaybackNoSeeking(boolean fullPlaybackNoSeeking) {
|
|
||||||
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setCanIncludeAdditionalVideoFormats(
|
|
||||||
boolean canIncludeAdditionalVideoFormats) {
|
|
||||||
this.canIncludeAdditionalVideoFormats = canIncludeAdditionalVideoFormats
|
|
||||||
&& ALLOW_ADDITIONAL_VIDEO_FORMATS;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setActionSchedule(ActionSchedule actionSchedule) {
|
|
||||||
this.actionSchedule = actionSchedule;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setOfflineLicenseKeySetId(byte[] offlineLicenseKeySetId) {
|
|
||||||
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setAudioVideoFormats(String audioFormat, String... videoFormats) {
|
|
||||||
this.audioFormat = audioFormat;
|
|
||||||
this.videoFormats = videoFormats;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setManifestUrl(String manifestUrl) {
|
|
||||||
this.manifestUrl = manifestUrl;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setWidevineMimeType(String mimeType) {
|
|
||||||
this.useL1Widevine = isL1WidevineAvailable(mimeType);
|
|
||||||
this.widevineLicenseUrl = getWidevineLicenseUrl(useL1Widevine);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DashHostedTest createDashHostedTest(boolean canIncludeAdditionalVideoFormats,
|
|
||||||
boolean isCddLimitedRetry, Instrumentation instrumentation) {
|
|
||||||
MetricsLogger metricsLogger = MetricsLogger.Factory.createDefault(instrumentation, tag,
|
|
||||||
REPORT_NAME, REPORT_OBJECT_NAME);
|
|
||||||
return new DashHostedTest(tag, streamName, manifestUrl, metricsLogger, fullPlaybackNoSeeking,
|
|
||||||
audioFormat, canIncludeAdditionalVideoFormats, isCddLimitedRetry, actionSchedule,
|
|
||||||
offlineLicenseKeySetId, widevineLicenseUrl, useL1Widevine, videoFormats);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runTest(HostActivity activity, Instrumentation instrumentation) {
|
|
||||||
DashHostedTest test = createDashHostedTest(canIncludeAdditionalVideoFormats, false,
|
|
||||||
instrumentation);
|
|
||||||
activity.runTest(test, TEST_TIMEOUT_MS);
|
|
||||||
// Retry test exactly once if adaptive test fails due to excessive dropped buffers when
|
|
||||||
// playing non-CDD required formats (b/28220076).
|
|
||||||
if (test.needsCddLimitedRetry) {
|
|
||||||
activity.runTest(createDashHostedTest(false, true, instrumentation), TEST_TIMEOUT_MS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String AUDIO_TAG_SUFFIX = ":Audio";
|
|
||||||
private static final String VIDEO_TAG_SUFFIX = ":Video";
|
|
||||||
static final int VIDEO_RENDERER_INDEX = 0;
|
|
||||||
static final int AUDIO_RENDERER_INDEX = 1;
|
|
||||||
|
|
||||||
private static final int MIN_LOADABLE_RETRY_COUNT = 10;
|
|
||||||
private static final int MAX_CONSECUTIVE_DROPPED_VIDEO_FRAMES = 10;
|
|
||||||
private static final float MAX_DROPPED_VIDEO_FRAME_FRACTION = 0.01f;
|
|
||||||
|
|
||||||
private static final String WIDEVINE_LICENSE_URL =
|
|
||||||
"https://proxy.uat.widevine.com/proxy?provider=widevine_test&video_id=";
|
|
||||||
private static final String WIDEVINE_SW_CRYPTO_CONTENT_ID = "exoplayer_test_1";
|
|
||||||
private static final String WIDEVINE_HW_SECURE_DECODE_CONTENT_ID = "exoplayer_test_2";
|
|
||||||
private static final String WIDEVINE_SECURITY_LEVEL_1 = "L1";
|
|
||||||
private static final String WIDEVINE_SECURITY_LEVEL_3 = "L3";
|
|
||||||
private static final String SECURITY_LEVEL_PROPERTY = "securityLevel";
|
|
||||||
|
|
||||||
private final String streamName;
|
|
||||||
private final String manifestUrl;
|
|
||||||
private final MetricsLogger metricsLogger;
|
|
||||||
private final boolean fullPlaybackNoSeeking;
|
|
||||||
private final boolean isCddLimitedRetry;
|
|
||||||
private final DashTestTrackSelector trackSelector;
|
|
||||||
private final byte[] offlineLicenseKeySetId;
|
|
||||||
private final String widevineLicenseUrl;
|
|
||||||
private final boolean useL1Widevine;
|
|
||||||
|
|
||||||
boolean needsCddLimitedRetry;
|
|
||||||
|
|
||||||
public static String getWidevineLicenseUrl(boolean useL1Widevine) {
|
|
||||||
return WIDEVINE_LICENSE_URL
|
|
||||||
+ (useL1Widevine ? WIDEVINE_HW_SECURE_DECODE_CONTENT_ID : WIDEVINE_SW_CRYPTO_CONTENT_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(18)
|
|
||||||
@SuppressWarnings("ResourceType")
|
|
||||||
public static boolean isL1WidevineAvailable(String mimeType) {
|
|
||||||
try {
|
|
||||||
// Force L3 if secure decoder is not available.
|
|
||||||
if (MediaCodecUtil.getDecoderInfo(mimeType, true) == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
|
|
||||||
String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
|
|
||||||
mediaDrm.release();
|
|
||||||
return WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty);
|
|
||||||
} catch (MediaCodecUtil.DecoderQueryException | UnsupportedSchemeException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param tag A tag to use for logging.
|
|
||||||
* @param streamName The name of the test stream for metric logging.
|
|
||||||
* @param manifestUrl The manifest url.
|
|
||||||
* @param metricsLogger Logger to log metrics from the test.
|
|
||||||
* @param fullPlaybackNoSeeking Whether the test will play the entire source with no seeking.
|
|
||||||
* @param audioFormat The audio format.
|
|
||||||
* @param canIncludeAdditionalVideoFormats Whether to use video formats in addition to those
|
|
||||||
* listed in the videoFormats argument, if the device is capable of playing them.
|
|
||||||
* @param isCddLimitedRetry Whether this is a CDD limited retry following a previous failure.
|
|
||||||
* @param actionSchedule The action schedule for the test.
|
|
||||||
* @param offlineLicenseKeySetId The key set id of the license to be used.
|
|
||||||
* @param widevineLicenseUrl If the video is Widevine encrypted, this is the license url
|
|
||||||
* otherwise null.
|
|
||||||
* @param useL1Widevine Whether to use L1 Widevine.
|
|
||||||
* @param videoFormats The video formats.
|
|
||||||
*/
|
|
||||||
private DashHostedTest(String tag, String streamName, String manifestUrl,
|
|
||||||
MetricsLogger metricsLogger, boolean fullPlaybackNoSeeking, String audioFormat,
|
|
||||||
boolean canIncludeAdditionalVideoFormats, boolean isCddLimitedRetry,
|
|
||||||
ActionSchedule actionSchedule, byte[] offlineLicenseKeySetId, String widevineLicenseUrl,
|
|
||||||
boolean useL1Widevine, String... videoFormats) {
|
|
||||||
super(tag, fullPlaybackNoSeeking);
|
|
||||||
Assertions.checkArgument(!(isCddLimitedRetry && canIncludeAdditionalVideoFormats));
|
|
||||||
this.streamName = streamName;
|
|
||||||
this.manifestUrl = manifestUrl;
|
|
||||||
this.metricsLogger = metricsLogger;
|
|
||||||
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
|
|
||||||
this.isCddLimitedRetry = isCddLimitedRetry;
|
|
||||||
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
|
|
||||||
this.widevineLicenseUrl = widevineLicenseUrl;
|
|
||||||
this.useL1Widevine = useL1Widevine;
|
|
||||||
trackSelector = new DashTestTrackSelector(tag, audioFormat, videoFormats,
|
|
||||||
canIncludeAdditionalVideoFormats);
|
|
||||||
if (actionSchedule != null) {
|
|
||||||
setSchedule(actionSchedule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MappingTrackSelector buildTrackSelector(HostActivity host,
|
|
||||||
BandwidthMeter bandwidthMeter) {
|
|
||||||
return trackSelector;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DefaultDrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManager(
|
|
||||||
final String userAgent) {
|
|
||||||
if (widevineLicenseUrl == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
MediaDrmCallback drmCallback = new HttpMediaDrmCallback(widevineLicenseUrl,
|
|
||||||
new DefaultHttpDataSourceFactory(userAgent));
|
|
||||||
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
|
|
||||||
DefaultDrmSessionManager.newWidevineInstance(drmCallback, null, null, null);
|
|
||||||
if (!useL1Widevine) {
|
|
||||||
drmSessionManager.setPropertyString(
|
|
||||||
SECURITY_LEVEL_PROPERTY, WIDEVINE_SECURITY_LEVEL_3);
|
|
||||||
}
|
|
||||||
if (offlineLicenseKeySetId != null) {
|
|
||||||
drmSessionManager.setMode(DefaultDrmSessionManager.MODE_PLAYBACK,
|
|
||||||
offlineLicenseKeySetId);
|
|
||||||
}
|
|
||||||
return drmSessionManager;
|
|
||||||
} catch (UnsupportedDrmException e) {
|
|
||||||
throw new IllegalStateException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface,
|
|
||||||
MappingTrackSelector trackSelector,
|
|
||||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
|
|
||||||
SimpleExoPlayer player = new DebugSimpleExoPlayer(host, trackSelector,
|
|
||||||
new DefaultLoadControl(), drmSessionManager);
|
|
||||||
player.setVideoSurface(surface);
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MediaSource buildSource(HostActivity host, String userAgent,
|
|
||||||
TransferListener<? super DataSource> mediaTransferListener) {
|
|
||||||
DataSource.Factory manifestDataSourceFactory = new DefaultDataSourceFactory(host, userAgent);
|
|
||||||
DataSource.Factory mediaDataSourceFactory = new DefaultDataSourceFactory(host, userAgent,
|
|
||||||
mediaTransferListener);
|
|
||||||
Uri manifestUri = Uri.parse(manifestUrl);
|
|
||||||
DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory(
|
|
||||||
mediaDataSourceFactory);
|
|
||||||
return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
|
||||||
MIN_LOADABLE_RETRY_COUNT, 0 /* livePresentationDelayMs */, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logMetrics(DecoderCounters audioCounters, DecoderCounters videoCounters) {
|
|
||||||
metricsLogger.logMetric(MetricsLogger.KEY_TEST_NAME, streamName);
|
|
||||||
metricsLogger.logMetric(MetricsLogger.KEY_IS_CDD_LIMITED_RETRY, isCddLimitedRetry);
|
|
||||||
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_DROPPED_COUNT,
|
|
||||||
videoCounters.droppedOutputBufferCount);
|
|
||||||
metricsLogger.logMetric(MetricsLogger.KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT,
|
|
||||||
videoCounters.maxConsecutiveDroppedOutputBufferCount);
|
|
||||||
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_SKIPPED_COUNT,
|
|
||||||
videoCounters.skippedOutputBufferCount);
|
|
||||||
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_RENDERED_COUNT,
|
|
||||||
videoCounters.renderedOutputBufferCount);
|
|
||||||
metricsLogger.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void assertPassed(DecoderCounters audioCounters, DecoderCounters videoCounters) {
|
|
||||||
if (fullPlaybackNoSeeking) {
|
|
||||||
// We shouldn't have skipped any output buffers.
|
|
||||||
DecoderCountersUtil.assertSkippedOutputBufferCount(tag + AUDIO_TAG_SUFFIX, audioCounters, 0);
|
|
||||||
DecoderCountersUtil.assertSkippedOutputBufferCount(tag + VIDEO_TAG_SUFFIX, videoCounters, 0);
|
|
||||||
// We allow one fewer output buffer due to the way that MediaCodecRenderer and the
|
|
||||||
// underlying decoders handle the end of stream. This should be tightened up in the future.
|
|
||||||
DecoderCountersUtil.assertTotalOutputBufferCount(tag + AUDIO_TAG_SUFFIX, audioCounters,
|
|
||||||
audioCounters.inputBufferCount - 1, audioCounters.inputBufferCount);
|
|
||||||
DecoderCountersUtil.assertTotalOutputBufferCount(tag + VIDEO_TAG_SUFFIX, videoCounters,
|
|
||||||
videoCounters.inputBufferCount - 1, videoCounters.inputBufferCount);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
int droppedFrameLimit = (int) Math.ceil(MAX_DROPPED_VIDEO_FRAME_FRACTION
|
|
||||||
* DecoderCountersUtil.getTotalOutputBuffers(videoCounters));
|
|
||||||
// Assert that performance is acceptable.
|
|
||||||
// Assert that total dropped frames were within limit.
|
|
||||||
DecoderCountersUtil.assertDroppedOutputBufferLimit(tag + VIDEO_TAG_SUFFIX, videoCounters,
|
|
||||||
droppedFrameLimit);
|
|
||||||
// Assert that consecutive dropped frames were within limit.
|
|
||||||
DecoderCountersUtil.assertConsecutiveDroppedOutputBufferLimit(tag + VIDEO_TAG_SUFFIX,
|
|
||||||
videoCounters, MAX_CONSECUTIVE_DROPPED_VIDEO_FRAMES);
|
|
||||||
} catch (AssertionFailedError e) {
|
|
||||||
if (trackSelector.includedAdditionalVideoFormats) {
|
|
||||||
// Retry limiting to CDD mandated formats (b/28220076).
|
|
||||||
Log.e(tag, "Too many dropped or consecutive dropped frames.", e);
|
|
||||||
needsCddLimitedRetry = true;
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class DashTestTrackSelector extends MappingTrackSelector {
|
|
||||||
|
|
||||||
private final String tag;
|
|
||||||
private final String audioFormatId;
|
|
||||||
private final String[] videoFormatIds;
|
|
||||||
private final boolean canIncludeAdditionalVideoFormats;
|
|
||||||
|
|
||||||
public boolean includedAdditionalVideoFormats;
|
|
||||||
|
|
||||||
private DashTestTrackSelector(String tag, String audioFormatId, String[] videoFormatIds,
|
|
||||||
boolean canIncludeAdditionalVideoFormats) {
|
|
||||||
this.tag = tag;
|
|
||||||
this.audioFormatId = audioFormatId;
|
|
||||||
this.videoFormatIds = videoFormatIds;
|
|
||||||
this.canIncludeAdditionalVideoFormats = canIncludeAdditionalVideoFormats;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TrackSelection[] selectTracks(RendererCapabilities[] rendererCapabilities,
|
|
||||||
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
|
|
||||||
throws ExoPlaybackException {
|
|
||||||
Assertions.checkState(rendererCapabilities[VIDEO_RENDERER_INDEX].getTrackType()
|
|
||||||
== C.TRACK_TYPE_VIDEO);
|
|
||||||
Assertions.checkState(rendererCapabilities[AUDIO_RENDERER_INDEX].getTrackType()
|
|
||||||
== C.TRACK_TYPE_AUDIO);
|
|
||||||
Assertions.checkState(rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].length == 1);
|
|
||||||
Assertions.checkState(rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].length == 1);
|
|
||||||
TrackSelection[] selections = new TrackSelection[rendererCapabilities.length];
|
|
||||||
selections[VIDEO_RENDERER_INDEX] = new RandomTrackSelection(
|
|
||||||
rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].get(0),
|
|
||||||
getVideoTrackIndices(rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].get(0),
|
|
||||||
rendererFormatSupports[VIDEO_RENDERER_INDEX][0], videoFormatIds,
|
|
||||||
canIncludeAdditionalVideoFormats),
|
|
||||||
0 /* seed */);
|
|
||||||
selections[AUDIO_RENDERER_INDEX] = new FixedTrackSelection(
|
|
||||||
rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].get(0),
|
|
||||||
getTrackIndex(rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].get(0), audioFormatId));
|
|
||||||
includedAdditionalVideoFormats =
|
|
||||||
selections[VIDEO_RENDERER_INDEX].length() > videoFormatIds.length;
|
|
||||||
return selections;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int[] getVideoTrackIndices(TrackGroup trackGroup, int[] formatSupport,
|
|
||||||
String[] formatIds, boolean canIncludeAdditionalFormats) {
|
|
||||||
List<Integer> trackIndices = new ArrayList<>();
|
|
||||||
|
|
||||||
// Always select explicitly listed representations.
|
|
||||||
for (String formatId : formatIds) {
|
|
||||||
int trackIndex = getTrackIndex(trackGroup, formatId);
|
|
||||||
Log.d(tag, "Adding base video format: "
|
|
||||||
+ Format.toLogString(trackGroup.getFormat(trackIndex)));
|
|
||||||
trackIndices.add(trackIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select additional video representations, if supported by the device.
|
|
||||||
if (canIncludeAdditionalFormats) {
|
|
||||||
for (int i = 0; i < trackGroup.length; i++) {
|
|
||||||
if (!trackIndices.contains(i) && isFormatHandled(formatSupport[i])) {
|
|
||||||
Log.d(tag, "Adding extra video format: "
|
|
||||||
+ Format.toLogString(trackGroup.getFormat(i)));
|
|
||||||
trackIndices.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] trackIndicesArray = Util.toArray(trackIndices);
|
|
||||||
Arrays.sort(trackIndicesArray);
|
|
||||||
return trackIndicesArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getTrackIndex(TrackGroup trackGroup, String formatId) {
|
|
||||||
for (int i = 0; i < trackGroup.length; i++) {
|
|
||||||
if (trackGroup.getFormat(i).id.equals(formatId)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Format " + formatId + " not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isFormatHandled(int formatSupport) {
|
|
||||||
return (formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK)
|
|
||||||
== RendererCapabilities.FORMAT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -40,40 +40,54 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.build();
|
.build();
|
||||||
private static final ActionSchedule RENDERER_DISABLING_SCHEDULE = new ActionSchedule.Builder(TAG)
|
private static final ActionSchedule RENDERER_DISABLING_SCHEDULE = new ActionSchedule.Builder(TAG)
|
||||||
// Wait 10 seconds, disable the video renderer, wait another 10 seconds and enable it again.
|
// Wait 10 seconds, disable the video renderer, wait another 10 seconds and enable it again.
|
||||||
.delay(10000).disableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.delay(10000).disableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.delay(10000).enableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.delay(10000).enableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
// Ditto for the audio renderer.
|
// Ditto for the audio renderer.
|
||||||
.delay(10000).disableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.delay(10000).disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.delay(10000).enableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.delay(10000).enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
// Wait 10 seconds, then disable and enable the video renderer 5 times in quick succession.
|
// Wait 10 seconds, then disable and enable the video renderer 5 times in quick succession.
|
||||||
.delay(10000).disableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.delay(10000).disableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.VIDEO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.VIDEO_RENDERER_INDEX)
|
||||||
// Ditto for the audio renderer.
|
// Ditto for the audio renderer.
|
||||||
.delay(10000).disableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.delay(10000).disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.disableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.disableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.enableRenderer(DashHostedTest.AUDIO_RENDERER_INDEX)
|
.enableRenderer(DashTestRunner.AUDIO_RENDERER_INDEX)
|
||||||
.delay(10000).seek(120000)
|
.delay(10000).seek(120000)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
private DashTestRunner testRunner;
|
||||||
|
|
||||||
public DashTest() {
|
public DashTest() {
|
||||||
super(HostActivity.class);
|
super(HostActivity.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
testRunner = new DashTestRunner(TAG, getActivity(), getInstrumentation());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
testRunner = null;
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
// H264 CDD.
|
// H264 CDD.
|
||||||
|
|
||||||
public void testH264Fixed() {
|
public void testH264Fixed() {
|
||||||
@ -81,13 +95,13 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_h264_fixed")
|
.setStreamName("test_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.H264_MANIFEST)
|
.setManifestUrl(DashTestData.H264_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID, DashTestData.H264_CDD_FIXED)
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID, DashTestData.H264_CDD_FIXED)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testH264Adaptive() throws DecoderQueryException {
|
public void testH264Adaptive() throws DecoderQueryException {
|
||||||
@ -95,14 +109,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_h264_adaptive")
|
.setStreamName("test_h264_adaptive")
|
||||||
.setManifestUrl(DashTestData.H264_MANIFEST)
|
.setManifestUrl(DashTestData.H264_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(true)
|
.setCanIncludeAdditionalVideoFormats(true)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H264_CDD_ADAPTIVE)
|
DashTestData.H264_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testH264AdaptiveWithSeeking() throws DecoderQueryException {
|
public void testH264AdaptiveWithSeeking() throws DecoderQueryException {
|
||||||
@ -111,7 +125,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String streamName = "test_h264_adaptive_with_seeking";
|
final String streamName = "test_h264_adaptive_with_seeking";
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName(streamName)
|
.setStreamName(streamName)
|
||||||
.setManifestUrl(DashTestData.H264_MANIFEST)
|
.setManifestUrl(DashTestData.H264_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(false)
|
.setFullPlaybackNoSeeking(false)
|
||||||
@ -119,7 +133,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(SEEKING_SCHEDULE)
|
.setActionSchedule(SEEKING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H264_CDD_ADAPTIVE)
|
DashTestData.H264_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
public void testH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
||||||
@ -128,7 +142,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String streamName = "test_h264_adaptive_with_renderer_disabling";
|
final String streamName = "test_h264_adaptive_with_renderer_disabling";
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName(streamName)
|
.setStreamName(streamName)
|
||||||
.setManifestUrl(DashTestData.H264_MANIFEST)
|
.setManifestUrl(DashTestData.H264_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(false)
|
.setFullPlaybackNoSeeking(false)
|
||||||
@ -136,7 +150,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H264_CDD_ADAPTIVE)
|
DashTestData.H264_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// H265 CDD.
|
// H265 CDD.
|
||||||
@ -146,13 +160,13 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_h265_fixed")
|
.setStreamName("test_h265_fixed")
|
||||||
.setManifestUrl(DashTestData.H265_MANIFEST)
|
.setManifestUrl(DashTestData.H265_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID, DashTestData.H265_CDD_FIXED)
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID, DashTestData.H265_CDD_FIXED)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testH265Adaptive() throws DecoderQueryException {
|
public void testH265Adaptive() throws DecoderQueryException {
|
||||||
@ -160,14 +174,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_h265_adaptive")
|
.setStreamName("test_h265_adaptive")
|
||||||
.setManifestUrl(DashTestData.H265_MANIFEST)
|
.setManifestUrl(DashTestData.H265_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(true)
|
.setCanIncludeAdditionalVideoFormats(true)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H265_CDD_ADAPTIVE)
|
DashTestData.H265_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testH265AdaptiveWithSeeking() throws DecoderQueryException {
|
public void testH265AdaptiveWithSeeking() throws DecoderQueryException {
|
||||||
@ -175,7 +189,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_h265_adaptive_with_seeking")
|
.setStreamName("test_h265_adaptive_with_seeking")
|
||||||
.setManifestUrl(DashTestData.H265_MANIFEST)
|
.setManifestUrl(DashTestData.H265_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(false)
|
.setFullPlaybackNoSeeking(false)
|
||||||
@ -183,7 +197,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(SEEKING_SCHEDULE)
|
.setActionSchedule(SEEKING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H265_CDD_ADAPTIVE)
|
DashTestData.H265_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testH265AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
public void testH265AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
||||||
@ -191,7 +205,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_h265_adaptive_with_renderer_disabling")
|
.setStreamName("test_h265_adaptive_with_renderer_disabling")
|
||||||
.setManifestUrl(DashTestData.H265_MANIFEST)
|
.setManifestUrl(DashTestData.H265_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(false)
|
.setFullPlaybackNoSeeking(false)
|
||||||
@ -199,7 +213,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H265_CDD_ADAPTIVE)
|
DashTestData.H265_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// VP9 (CDD).
|
// VP9 (CDD).
|
||||||
@ -209,14 +223,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_vp9_fixed_360p")
|
.setStreamName("test_vp9_fixed_360p")
|
||||||
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.VP9_CDD_FIXED)
|
DashTestData.VP9_CDD_FIXED)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testVp9Adaptive() throws DecoderQueryException {
|
public void testVp9Adaptive() throws DecoderQueryException {
|
||||||
@ -224,14 +238,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_vp9_adaptive")
|
.setStreamName("test_vp9_adaptive")
|
||||||
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(true)
|
.setCanIncludeAdditionalVideoFormats(true)
|
||||||
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.VP9_CDD_ADAPTIVE)
|
DashTestData.VP9_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testVp9AdaptiveWithSeeking() throws DecoderQueryException {
|
public void testVp9AdaptiveWithSeeking() throws DecoderQueryException {
|
||||||
@ -239,7 +253,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_vp9_adaptive_with_seeking")
|
.setStreamName("test_vp9_adaptive_with_seeking")
|
||||||
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(false)
|
.setFullPlaybackNoSeeking(false)
|
||||||
@ -247,7 +261,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(SEEKING_SCHEDULE)
|
.setActionSchedule(SEEKING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.VP9_CDD_ADAPTIVE)
|
DashTestData.VP9_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testVp9AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
public void testVp9AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
||||||
@ -255,7 +269,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_vp9_adaptive_with_renderer_disabling")
|
.setStreamName("test_vp9_adaptive_with_renderer_disabling")
|
||||||
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
.setManifestUrl(DashTestData.VP9_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(false)
|
.setFullPlaybackNoSeeking(false)
|
||||||
@ -263,7 +277,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.VP9_VORBIS_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.VP9_CDD_ADAPTIVE)
|
DashTestData.VP9_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// H264: Other frame-rates for output buffer count assertions.
|
// H264: Other frame-rates for output buffer count assertions.
|
||||||
@ -274,14 +288,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_23fps_h264_fixed")
|
.setStreamName("test_23fps_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.H264_23_MANIFEST)
|
.setManifestUrl(DashTestData.H264_23_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID)
|
DashTestData.H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24 fps.
|
// 24 fps.
|
||||||
@ -290,14 +304,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_24fps_h264_fixed")
|
.setStreamName("test_24fps_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.H264_24_MANIFEST)
|
.setManifestUrl(DashTestData.H264_24_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID)
|
DashTestData.H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 29.97 fps.
|
// 29.97 fps.
|
||||||
@ -306,14 +320,14 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_29fps_h264_fixed")
|
.setStreamName("test_29fps_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.H264_29_MANIFEST)
|
.setManifestUrl(DashTestData.H264_29_MANIFEST)
|
||||||
.setFullPlaybackNoSeeking(true)
|
.setFullPlaybackNoSeeking(true)
|
||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID)
|
DashTestData.H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Widevine encrypted media tests.
|
// Widevine encrypted media tests.
|
||||||
@ -324,7 +338,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h264_fixed")
|
.setStreamName("test_widevine_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -332,7 +346,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_CDD_FIXED)
|
DashTestData.WIDEVINE_H264_CDD_FIXED)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineH264Adaptive() throws DecoderQueryException {
|
public void testWidevineH264Adaptive() throws DecoderQueryException {
|
||||||
@ -340,7 +354,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h264_adaptive")
|
.setStreamName("test_widevine_h264_adaptive")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -348,7 +362,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(true)
|
.setCanIncludeAdditionalVideoFormats(true)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_H264_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineH264AdaptiveWithSeeking() throws DecoderQueryException {
|
public void testWidevineH264AdaptiveWithSeeking() throws DecoderQueryException {
|
||||||
@ -356,7 +370,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h264_adaptive_with_seeking")
|
.setStreamName("test_widevine_h264_adaptive_with_seeking")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -365,7 +379,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(SEEKING_SCHEDULE)
|
.setActionSchedule(SEEKING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_H264_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
public void testWidevineH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
||||||
@ -373,7 +387,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h264_adaptive_with_renderer_disabling")
|
.setStreamName("test_widevine_h264_adaptive_with_renderer_disabling")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -382,7 +396,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_H264_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// H265 CDD.
|
// H265 CDD.
|
||||||
@ -392,7 +406,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h265_fixed")
|
.setStreamName("test_widevine_h265_fixed")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
||||||
@ -400,7 +414,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H265_CDD_FIXED)
|
DashTestData.WIDEVINE_H265_CDD_FIXED)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineH265Adaptive() throws DecoderQueryException {
|
public void testWidevineH265Adaptive() throws DecoderQueryException {
|
||||||
@ -408,7 +422,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h265_adaptive")
|
.setStreamName("test_widevine_h265_adaptive")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
||||||
@ -416,7 +430,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(true)
|
.setCanIncludeAdditionalVideoFormats(true)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H265_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_H265_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineH265AdaptiveWithSeeking() throws DecoderQueryException {
|
public void testWidevineH265AdaptiveWithSeeking() throws DecoderQueryException {
|
||||||
@ -424,7 +438,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h265_adaptive_with_seeking")
|
.setStreamName("test_widevine_h265_adaptive_with_seeking")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
||||||
@ -433,7 +447,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(SEEKING_SCHEDULE)
|
.setActionSchedule(SEEKING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H265_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_H265_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineH265AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
public void testWidevineH265AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
||||||
@ -441,7 +455,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_h265_adaptive_with_renderer_disabling")
|
.setStreamName("test_widevine_h265_adaptive_with_renderer_disabling")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H265_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
.setWidevineMimeType(MimeTypes.VIDEO_H265)
|
||||||
@ -450,7 +464,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H265_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_H265_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// VP9 (CDD).
|
// VP9 (CDD).
|
||||||
@ -460,7 +474,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_vp9_fixed_360p")
|
.setStreamName("test_widevine_vp9_fixed_360p")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
||||||
@ -468,7 +482,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_VP9_CDD_FIXED)
|
DashTestData.WIDEVINE_VP9_CDD_FIXED)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineVp9Adaptive() throws DecoderQueryException {
|
public void testWidevineVp9Adaptive() throws DecoderQueryException {
|
||||||
@ -476,7 +490,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_vp9_adaptive")
|
.setStreamName("test_widevine_vp9_adaptive")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
||||||
@ -484,7 +498,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(true)
|
.setCanIncludeAdditionalVideoFormats(true)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_VP9_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_VP9_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineVp9AdaptiveWithSeeking() throws DecoderQueryException {
|
public void testWidevineVp9AdaptiveWithSeeking() throws DecoderQueryException {
|
||||||
@ -492,7 +506,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_vp9_adaptive_with_seeking")
|
.setStreamName("test_widevine_vp9_adaptive_with_seeking")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
||||||
@ -501,7 +515,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(SEEKING_SCHEDULE)
|
.setActionSchedule(SEEKING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_VP9_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_VP9_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineVp9AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
public void testWidevineVp9AdaptiveWithRendererDisabling() throws DecoderQueryException {
|
||||||
@ -509,7 +523,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_vp9_adaptive_with_renderer_disabling")
|
.setStreamName("test_widevine_vp9_adaptive_with_renderer_disabling")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_VP9_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
.setWidevineMimeType(MimeTypes.VIDEO_VP9)
|
||||||
@ -518,7 +532,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
.setActionSchedule(RENDERER_DISABLING_SCHEDULE)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_VP9_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_VP9_CDD_ADAPTIVE)
|
DashTestData.WIDEVINE_VP9_CDD_ADAPTIVE)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// H264: Other frame-rates for output buffer count assertions.
|
// H264: Other frame-rates for output buffer count assertions.
|
||||||
@ -529,7 +543,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_23fps_h264_fixed")
|
.setStreamName("test_widevine_23fps_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_23_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_23_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -537,7 +551,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID)
|
DashTestData.WIDEVINE_H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24 fps.
|
// 24 fps.
|
||||||
@ -546,7 +560,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_24fps_h264_fixed")
|
.setStreamName("test_widevine_24fps_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_24_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_24_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -554,7 +568,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID)
|
DashTestData.WIDEVINE_H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 29.97 fps.
|
// 29.97 fps.
|
||||||
@ -563,7 +577,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
// Pass.
|
// Pass.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
new DashHostedTest.Builder(TAG)
|
testRunner
|
||||||
.setStreamName("test_widevine_29fps_h264_fixed")
|
.setStreamName("test_widevine_29fps_h264_fixed")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_29_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_29_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -571,7 +585,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||||||
.setCanIncludeAdditionalVideoFormats(false)
|
.setCanIncludeAdditionalVideoFormats(false)
|
||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID)
|
DashTestData.WIDEVINE_H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID)
|
||||||
.runTest(getActivity(), getInstrumentation());
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal.
|
// Internal.
|
||||||
|
@ -137,6 +137,16 @@ public final class DashTestData {
|
|||||||
WIDEVINE_VP9_180P_VIDEO_REPRESENTATION_ID,
|
WIDEVINE_VP9_180P_VIDEO_REPRESENTATION_ID,
|
||||||
WIDEVINE_VP9_360P_VIDEO_REPRESENTATION_ID};
|
WIDEVINE_VP9_360P_VIDEO_REPRESENTATION_ID};
|
||||||
|
|
||||||
|
private static final String WIDEVINE_LICENSE_URL =
|
||||||
|
"https://proxy.uat.widevine.com/proxy?provider=widevine_test&video_id=";
|
||||||
|
private static final String WIDEVINE_SW_CRYPTO_CONTENT_ID = "exoplayer_test_1";
|
||||||
|
private static final String WIDEVINE_HW_SECURE_DECODE_CONTENT_ID = "exoplayer_test_2";
|
||||||
|
|
||||||
|
public static String getWidevineLicenseUrl(boolean useL1Widevine) {
|
||||||
|
return WIDEVINE_LICENSE_URL
|
||||||
|
+ (useL1Widevine ? WIDEVINE_HW_SECURE_DECODE_CONTENT_ID : WIDEVINE_SW_CRYPTO_CONTENT_ID);
|
||||||
|
}
|
||||||
|
|
||||||
private DashTestData() {
|
private DashTestData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,459 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.playbacktests.gts;
|
||||||
|
|
||||||
|
import static com.google.android.exoplayer2.C.WIDEVINE_UUID;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Instrumentation;
|
||||||
|
import android.media.MediaDrm;
|
||||||
|
import android.media.UnsupportedSchemeException;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.DefaultLoadControl;
|
||||||
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
|
import com.google.android.exoplayer2.Format;
|
||||||
|
import com.google.android.exoplayer2.RendererCapabilities;
|
||||||
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
|
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||||
|
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
||||||
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
|
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
||||||
|
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
||||||
|
import com.google.android.exoplayer2.drm.MediaDrmCallback;
|
||||||
|
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
|
||||||
|
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.ActionSchedule;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.DebugSimpleExoPlayer;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.HostActivity;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.HostActivity.HostedTest;
|
||||||
|
import com.google.android.exoplayer2.playbacktests.util.MetricsLogger;
|
||||||
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
|
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
||||||
|
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
|
||||||
|
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
|
||||||
|
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
||||||
|
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
|
||||||
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
|
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||||
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||||
|
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import junit.framework.AssertionFailedError;
|
||||||
|
|
||||||
|
/** {@link DashHostedTest} builder. */
|
||||||
|
public final class DashTestRunner {
|
||||||
|
|
||||||
|
static final int VIDEO_RENDERER_INDEX = 0;
|
||||||
|
static final int AUDIO_RENDERER_INDEX = 1;
|
||||||
|
|
||||||
|
private static final long TEST_TIMEOUT_MS = 5 * 60 * 1000;
|
||||||
|
|
||||||
|
private static final String REPORT_NAME = "GtsExoPlayerTestCases";
|
||||||
|
private static final String REPORT_OBJECT_NAME = "playbacktest";
|
||||||
|
|
||||||
|
// 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 >= 24;
|
||||||
|
|
||||||
|
private static final String AUDIO_TAG_SUFFIX = ":Audio";
|
||||||
|
private static final String VIDEO_TAG_SUFFIX = ":Video";
|
||||||
|
|
||||||
|
private static final int MIN_LOADABLE_RETRY_COUNT = 10;
|
||||||
|
private static final int MAX_CONSECUTIVE_DROPPED_VIDEO_FRAMES = 10;
|
||||||
|
private static final float MAX_DROPPED_VIDEO_FRAME_FRACTION = 0.01f;
|
||||||
|
|
||||||
|
private static final String WIDEVINE_SECURITY_LEVEL_1 = "L1";
|
||||||
|
private static final String WIDEVINE_SECURITY_LEVEL_3 = "L3";
|
||||||
|
private static final String SECURITY_LEVEL_PROPERTY = "securityLevel";
|
||||||
|
|
||||||
|
private final String tag;
|
||||||
|
private final HostActivity activity;
|
||||||
|
private final Instrumentation instrumentation;
|
||||||
|
|
||||||
|
private String streamName;
|
||||||
|
private boolean fullPlaybackNoSeeking;
|
||||||
|
private String audioFormat;
|
||||||
|
private boolean canIncludeAdditionalVideoFormats;
|
||||||
|
private ActionSchedule actionSchedule;
|
||||||
|
private byte[] offlineLicenseKeySetId;
|
||||||
|
private String[] videoFormats;
|
||||||
|
private String manifestUrl;
|
||||||
|
private boolean useL1Widevine;
|
||||||
|
private String widevineLicenseUrl;
|
||||||
|
private DataSource.Factory dataSourceFactory;
|
||||||
|
|
||||||
|
@TargetApi(18)
|
||||||
|
@SuppressWarnings("ResourceType")
|
||||||
|
public static boolean isL1WidevineAvailable(String mimeType) {
|
||||||
|
try {
|
||||||
|
// Force L3 if secure decoder is not available.
|
||||||
|
if (MediaCodecUtil.getDecoderInfo(mimeType, true) == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
|
||||||
|
String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
|
||||||
|
mediaDrm.release();
|
||||||
|
return WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty);
|
||||||
|
} catch (MediaCodecUtil.DecoderQueryException | UnsupportedSchemeException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner(String tag, HostActivity activity, Instrumentation instrumentation) {
|
||||||
|
this.tag = tag;
|
||||||
|
this.activity = activity;
|
||||||
|
this.instrumentation = instrumentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setStreamName(String streamName) {
|
||||||
|
this.streamName = streamName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setFullPlaybackNoSeeking(boolean fullPlaybackNoSeeking) {
|
||||||
|
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setCanIncludeAdditionalVideoFormats(
|
||||||
|
boolean canIncludeAdditionalVideoFormats) {
|
||||||
|
this.canIncludeAdditionalVideoFormats = canIncludeAdditionalVideoFormats
|
||||||
|
&& ALLOW_ADDITIONAL_VIDEO_FORMATS;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setActionSchedule(ActionSchedule actionSchedule) {
|
||||||
|
this.actionSchedule = actionSchedule;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setOfflineLicenseKeySetId(byte[] offlineLicenseKeySetId) {
|
||||||
|
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setAudioVideoFormats(String audioFormat, String... videoFormats) {
|
||||||
|
this.audioFormat = audioFormat;
|
||||||
|
this.videoFormats = videoFormats;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setManifestUrl(String manifestUrl) {
|
||||||
|
this.manifestUrl = manifestUrl;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setWidevineMimeType(String mimeType) {
|
||||||
|
this.useL1Widevine = isL1WidevineAvailable(mimeType);
|
||||||
|
this.widevineLicenseUrl = DashTestData.getWidevineLicenseUrl(useL1Widevine);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DashTestRunner setDataSourceFactory(DataSource.Factory dataSourceFactory) {
|
||||||
|
this.dataSourceFactory = dataSourceFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
DashHostedTest test = createDashHostedTest(canIncludeAdditionalVideoFormats, false,
|
||||||
|
instrumentation);
|
||||||
|
activity.runTest(test, TEST_TIMEOUT_MS);
|
||||||
|
// Retry test exactly once if adaptive test fails due to excessive dropped buffers when
|
||||||
|
// playing non-CDD required formats (b/28220076).
|
||||||
|
if (test.needsCddLimitedRetry) {
|
||||||
|
activity.runTest(createDashHostedTest(false, true, instrumentation), TEST_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DashHostedTest createDashHostedTest(boolean canIncludeAdditionalVideoFormats,
|
||||||
|
boolean isCddLimitedRetry, Instrumentation instrumentation) {
|
||||||
|
MetricsLogger metricsLogger = MetricsLogger.Factory.createDefault(instrumentation, tag,
|
||||||
|
REPORT_NAME, REPORT_OBJECT_NAME);
|
||||||
|
return new DashHostedTest(tag, streamName, manifestUrl, metricsLogger, fullPlaybackNoSeeking,
|
||||||
|
audioFormat, canIncludeAdditionalVideoFormats, isCddLimitedRetry, actionSchedule,
|
||||||
|
offlineLicenseKeySetId, widevineLicenseUrl, useL1Widevine, dataSourceFactory,
|
||||||
|
videoFormats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link HostedTest} for DASH playback tests.
|
||||||
|
*/
|
||||||
|
@TargetApi(16)
|
||||||
|
private static final class DashHostedTest extends ExoHostedTest {
|
||||||
|
|
||||||
|
private final String streamName;
|
||||||
|
private final String manifestUrl;
|
||||||
|
private final MetricsLogger metricsLogger;
|
||||||
|
private final boolean fullPlaybackNoSeeking;
|
||||||
|
private final boolean isCddLimitedRetry;
|
||||||
|
private final DashTestTrackSelector trackSelector;
|
||||||
|
private final byte[] offlineLicenseKeySetId;
|
||||||
|
private final String widevineLicenseUrl;
|
||||||
|
private final boolean useL1Widevine;
|
||||||
|
private final DataSource.Factory dataSourceFactory;
|
||||||
|
|
||||||
|
private boolean needsCddLimitedRetry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tag A tag to use for logging.
|
||||||
|
* @param streamName The name of the test stream for metric logging.
|
||||||
|
* @param manifestUrl The manifest url.
|
||||||
|
* @param metricsLogger Logger to log metrics from the test.
|
||||||
|
* @param fullPlaybackNoSeeking Whether the test will play the entire source with no seeking.
|
||||||
|
* @param audioFormat The audio format.
|
||||||
|
* @param canIncludeAdditionalVideoFormats Whether to use video formats in addition to those
|
||||||
|
* listed in the videoFormats argument, if the device is capable of playing them.
|
||||||
|
* @param isCddLimitedRetry Whether this is a CDD limited retry following a previous failure.
|
||||||
|
* @param actionSchedule The action schedule for the test.
|
||||||
|
* @param offlineLicenseKeySetId The key set id of the license to be used.
|
||||||
|
* @param widevineLicenseUrl If the video is Widevine encrypted, this is the license url
|
||||||
|
* otherwise null.
|
||||||
|
* @param useL1Widevine Whether to use L1 Widevine.
|
||||||
|
* @param dataSourceFactory If not null, used to load manifest and media.
|
||||||
|
* @param videoFormats The video formats.
|
||||||
|
*/
|
||||||
|
private DashHostedTest(String tag, String streamName, String manifestUrl,
|
||||||
|
MetricsLogger metricsLogger, boolean fullPlaybackNoSeeking, String audioFormat,
|
||||||
|
boolean canIncludeAdditionalVideoFormats, boolean isCddLimitedRetry,
|
||||||
|
ActionSchedule actionSchedule, byte[] offlineLicenseKeySetId, String widevineLicenseUrl,
|
||||||
|
boolean useL1Widevine, DataSource.Factory dataSourceFactory, String... videoFormats) {
|
||||||
|
super(tag, fullPlaybackNoSeeking);
|
||||||
|
Assertions.checkArgument(!(isCddLimitedRetry && canIncludeAdditionalVideoFormats));
|
||||||
|
this.streamName = streamName;
|
||||||
|
this.manifestUrl = manifestUrl;
|
||||||
|
this.metricsLogger = metricsLogger;
|
||||||
|
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
|
||||||
|
this.isCddLimitedRetry = isCddLimitedRetry;
|
||||||
|
this.offlineLicenseKeySetId = offlineLicenseKeySetId;
|
||||||
|
this.widevineLicenseUrl = widevineLicenseUrl;
|
||||||
|
this.useL1Widevine = useL1Widevine;
|
||||||
|
this.dataSourceFactory = dataSourceFactory;
|
||||||
|
trackSelector = new DashTestTrackSelector(tag, audioFormat, videoFormats,
|
||||||
|
canIncludeAdditionalVideoFormats);
|
||||||
|
if (actionSchedule != null) {
|
||||||
|
setSchedule(actionSchedule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MappingTrackSelector buildTrackSelector(HostActivity host,
|
||||||
|
BandwidthMeter bandwidthMeter) {
|
||||||
|
return trackSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DefaultDrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManager(
|
||||||
|
final String userAgent) {
|
||||||
|
if (widevineLicenseUrl == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
MediaDrmCallback drmCallback = new HttpMediaDrmCallback(widevineLicenseUrl,
|
||||||
|
new DefaultHttpDataSourceFactory(userAgent));
|
||||||
|
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager =
|
||||||
|
DefaultDrmSessionManager.newWidevineInstance(drmCallback, null, null, null);
|
||||||
|
if (!useL1Widevine) {
|
||||||
|
drmSessionManager.setPropertyString(
|
||||||
|
SECURITY_LEVEL_PROPERTY, WIDEVINE_SECURITY_LEVEL_3);
|
||||||
|
}
|
||||||
|
if (offlineLicenseKeySetId != null) {
|
||||||
|
drmSessionManager.setMode(DefaultDrmSessionManager.MODE_PLAYBACK,
|
||||||
|
offlineLicenseKeySetId);
|
||||||
|
}
|
||||||
|
return drmSessionManager;
|
||||||
|
} catch (UnsupportedDrmException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface,
|
||||||
|
MappingTrackSelector trackSelector,
|
||||||
|
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
|
||||||
|
SimpleExoPlayer player = new DebugSimpleExoPlayer(host, trackSelector,
|
||||||
|
new DefaultLoadControl(), drmSessionManager);
|
||||||
|
player.setVideoSurface(surface);
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MediaSource buildSource(HostActivity host, String userAgent,
|
||||||
|
TransferListener<? super DataSource> mediaTransferListener) {
|
||||||
|
DataSource.Factory manifestDataSourceFactory = dataSourceFactory != null
|
||||||
|
? dataSourceFactory : new DefaultDataSourceFactory(host, userAgent);
|
||||||
|
DataSource.Factory mediaDataSourceFactory = dataSourceFactory != null
|
||||||
|
? dataSourceFactory
|
||||||
|
: new DefaultDataSourceFactory(host, userAgent, mediaTransferListener);
|
||||||
|
Uri manifestUri = Uri.parse(manifestUrl);
|
||||||
|
DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory(
|
||||||
|
mediaDataSourceFactory);
|
||||||
|
return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
||||||
|
MIN_LOADABLE_RETRY_COUNT, 0 /* livePresentationDelayMs */, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void logMetrics(DecoderCounters audioCounters, DecoderCounters videoCounters) {
|
||||||
|
metricsLogger.logMetric(MetricsLogger.KEY_TEST_NAME, streamName);
|
||||||
|
metricsLogger.logMetric(MetricsLogger.KEY_IS_CDD_LIMITED_RETRY, isCddLimitedRetry);
|
||||||
|
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_DROPPED_COUNT,
|
||||||
|
videoCounters.droppedOutputBufferCount);
|
||||||
|
metricsLogger.logMetric(MetricsLogger.KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT,
|
||||||
|
videoCounters.maxConsecutiveDroppedOutputBufferCount);
|
||||||
|
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_SKIPPED_COUNT,
|
||||||
|
videoCounters.skippedOutputBufferCount);
|
||||||
|
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_RENDERED_COUNT,
|
||||||
|
videoCounters.renderedOutputBufferCount);
|
||||||
|
metricsLogger.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assertPassed(DecoderCounters audioCounters, DecoderCounters videoCounters) {
|
||||||
|
if (fullPlaybackNoSeeking) {
|
||||||
|
// We shouldn't have skipped any output buffers.
|
||||||
|
DecoderCountersUtil
|
||||||
|
.assertSkippedOutputBufferCount(tag + AUDIO_TAG_SUFFIX, audioCounters, 0);
|
||||||
|
DecoderCountersUtil
|
||||||
|
.assertSkippedOutputBufferCount(tag + VIDEO_TAG_SUFFIX, videoCounters, 0);
|
||||||
|
// We allow one fewer output buffer due to the way that MediaCodecRenderer and the
|
||||||
|
// underlying decoders handle the end of stream. This should be tightened up in the future.
|
||||||
|
DecoderCountersUtil.assertTotalOutputBufferCount(tag + AUDIO_TAG_SUFFIX, audioCounters,
|
||||||
|
audioCounters.inputBufferCount - 1, audioCounters.inputBufferCount);
|
||||||
|
DecoderCountersUtil.assertTotalOutputBufferCount(tag + VIDEO_TAG_SUFFIX, videoCounters,
|
||||||
|
videoCounters.inputBufferCount - 1, videoCounters.inputBufferCount);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int droppedFrameLimit = (int) Math.ceil(MAX_DROPPED_VIDEO_FRAME_FRACTION
|
||||||
|
* DecoderCountersUtil.getTotalOutputBuffers(videoCounters));
|
||||||
|
// Assert that performance is acceptable.
|
||||||
|
// Assert that total dropped frames were within limit.
|
||||||
|
DecoderCountersUtil.assertDroppedOutputBufferLimit(tag + VIDEO_TAG_SUFFIX, videoCounters,
|
||||||
|
droppedFrameLimit);
|
||||||
|
// Assert that consecutive dropped frames were within limit.
|
||||||
|
DecoderCountersUtil.assertConsecutiveDroppedOutputBufferLimit(tag + VIDEO_TAG_SUFFIX,
|
||||||
|
videoCounters, MAX_CONSECUTIVE_DROPPED_VIDEO_FRAMES);
|
||||||
|
} catch (AssertionFailedError e) {
|
||||||
|
if (trackSelector.includedAdditionalVideoFormats) {
|
||||||
|
// Retry limiting to CDD mandated formats (b/28220076).
|
||||||
|
Log.e(tag, "Too many dropped or consecutive dropped frames.", e);
|
||||||
|
needsCddLimitedRetry = true;
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class DashTestTrackSelector extends MappingTrackSelector {
|
||||||
|
|
||||||
|
private final String tag;
|
||||||
|
private final String audioFormatId;
|
||||||
|
private final String[] videoFormatIds;
|
||||||
|
private final boolean canIncludeAdditionalVideoFormats;
|
||||||
|
|
||||||
|
public boolean includedAdditionalVideoFormats;
|
||||||
|
|
||||||
|
private DashTestTrackSelector(String tag, String audioFormatId, String[] videoFormatIds,
|
||||||
|
boolean canIncludeAdditionalVideoFormats) {
|
||||||
|
this.tag = tag;
|
||||||
|
this.audioFormatId = audioFormatId;
|
||||||
|
this.videoFormatIds = videoFormatIds;
|
||||||
|
this.canIncludeAdditionalVideoFormats = canIncludeAdditionalVideoFormats;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TrackSelection[] selectTracks(RendererCapabilities[] rendererCapabilities,
|
||||||
|
TrackGroupArray[] rendererTrackGroupArrays, int[][][] rendererFormatSupports)
|
||||||
|
throws ExoPlaybackException {
|
||||||
|
Assertions.checkState(rendererCapabilities[VIDEO_RENDERER_INDEX].getTrackType()
|
||||||
|
== C.TRACK_TYPE_VIDEO);
|
||||||
|
Assertions.checkState(rendererCapabilities[AUDIO_RENDERER_INDEX].getTrackType()
|
||||||
|
== C.TRACK_TYPE_AUDIO);
|
||||||
|
Assertions.checkState(rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].length == 1);
|
||||||
|
Assertions.checkState(rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].length == 1);
|
||||||
|
TrackSelection[] selections = new TrackSelection[rendererCapabilities.length];
|
||||||
|
selections[VIDEO_RENDERER_INDEX] = new RandomTrackSelection(
|
||||||
|
rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].get(0),
|
||||||
|
getVideoTrackIndices(rendererTrackGroupArrays[VIDEO_RENDERER_INDEX].get(0),
|
||||||
|
rendererFormatSupports[VIDEO_RENDERER_INDEX][0], videoFormatIds,
|
||||||
|
canIncludeAdditionalVideoFormats),
|
||||||
|
0 /* seed */);
|
||||||
|
selections[AUDIO_RENDERER_INDEX] = new FixedTrackSelection(
|
||||||
|
rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].get(0),
|
||||||
|
getTrackIndex(rendererTrackGroupArrays[AUDIO_RENDERER_INDEX].get(0), audioFormatId));
|
||||||
|
includedAdditionalVideoFormats =
|
||||||
|
selections[VIDEO_RENDERER_INDEX].length() > videoFormatIds.length;
|
||||||
|
return selections;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] getVideoTrackIndices(TrackGroup trackGroup, int[] formatSupport,
|
||||||
|
String[] formatIds, boolean canIncludeAdditionalFormats) {
|
||||||
|
List<Integer> trackIndices = new ArrayList<>();
|
||||||
|
|
||||||
|
// Always select explicitly listed representations.
|
||||||
|
for (String formatId : formatIds) {
|
||||||
|
int trackIndex = getTrackIndex(trackGroup, formatId);
|
||||||
|
Log.d(tag, "Adding base video format: "
|
||||||
|
+ Format.toLogString(trackGroup.getFormat(trackIndex)));
|
||||||
|
trackIndices.add(trackIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select additional video representations, if supported by the device.
|
||||||
|
if (canIncludeAdditionalFormats) {
|
||||||
|
for (int i = 0; i < trackGroup.length; i++) {
|
||||||
|
if (!trackIndices.contains(i) && isFormatHandled(formatSupport[i])) {
|
||||||
|
Log.d(tag, "Adding extra video format: "
|
||||||
|
+ Format.toLogString(trackGroup.getFormat(i)));
|
||||||
|
trackIndices.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] trackIndicesArray = Util.toArray(trackIndices);
|
||||||
|
Arrays.sort(trackIndicesArray);
|
||||||
|
return trackIndicesArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getTrackIndex(TrackGroup trackGroup, String formatId) {
|
||||||
|
for (int i = 0; i < trackGroup.length; i++) {
|
||||||
|
if (trackGroup.getFormat(i).id.equals(formatId)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Format " + formatId + " not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFormatHandled(int formatSupport) {
|
||||||
|
return (formatSupport & RendererCapabilities.FORMAT_SUPPORT_MASK)
|
||||||
|
== RendererCapabilities.FORMAT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -37,7 +37,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
private static final String TAG = "DashWidevineOfflineTest";
|
private static final String TAG = "DashWidevineOfflineTest";
|
||||||
private static final String USER_AGENT = "ExoPlayerPlaybackTests";
|
private static final String USER_AGENT = "ExoPlayerPlaybackTests";
|
||||||
|
|
||||||
private DashHostedTest.Builder builder;
|
private DashTestRunner testRunner;
|
||||||
private DefaultHttpDataSourceFactory httpDataSourceFactory;
|
private DefaultHttpDataSourceFactory httpDataSourceFactory;
|
||||||
private OfflineLicenseHelper<FrameworkMediaCrypto> offlineLicenseHelper;
|
private OfflineLicenseHelper<FrameworkMediaCrypto> offlineLicenseHelper;
|
||||||
private byte[] offlineLicenseKeySetId;
|
private byte[] offlineLicenseKeySetId;
|
||||||
@ -49,7 +49,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
builder = new DashHostedTest.Builder(TAG)
|
testRunner = new DashTestRunner(TAG, getActivity(), getInstrumentation())
|
||||||
.setStreamName("test_widevine_h264_fixed_offline")
|
.setStreamName("test_widevine_h264_fixed_offline")
|
||||||
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
.setManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST)
|
||||||
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
.setWidevineMimeType(MimeTypes.VIDEO_H264)
|
||||||
@ -58,8 +58,8 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
|
||||||
DashTestData.WIDEVINE_H264_CDD_FIXED);
|
DashTestData.WIDEVINE_H264_CDD_FIXED);
|
||||||
|
|
||||||
boolean useL1Widevine = DashHostedTest.isL1WidevineAvailable(MimeTypes.VIDEO_H264);
|
boolean useL1Widevine = DashTestRunner.isL1WidevineAvailable(MimeTypes.VIDEO_H264);
|
||||||
String widevineLicenseUrl = DashHostedTest.getWidevineLicenseUrl(useL1Widevine);
|
String widevineLicenseUrl = DashTestData.getWidevineLicenseUrl(useL1Widevine);
|
||||||
httpDataSourceFactory = new DefaultHttpDataSourceFactory(USER_AGENT);
|
httpDataSourceFactory = new DefaultHttpDataSourceFactory(USER_AGENT);
|
||||||
offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(widevineLicenseUrl,
|
offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(widevineLicenseUrl,
|
||||||
httpDataSourceFactory);
|
httpDataSourceFactory);
|
||||||
@ -67,12 +67,15 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
|
testRunner = null;
|
||||||
if (offlineLicenseKeySetId != null) {
|
if (offlineLicenseKeySetId != null) {
|
||||||
releaseLicense();
|
releaseLicense();
|
||||||
}
|
}
|
||||||
if (offlineLicenseHelper != null) {
|
if (offlineLicenseHelper != null) {
|
||||||
offlineLicenseHelper.releaseResources();
|
offlineLicenseHelper.releaseResources();
|
||||||
}
|
}
|
||||||
|
offlineLicenseHelper = null;
|
||||||
|
httpDataSourceFactory = null;
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +86,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
return; // Pass.
|
return; // Pass.
|
||||||
}
|
}
|
||||||
downloadLicense();
|
downloadLicense();
|
||||||
builder.runTest(getActivity(), getInstrumentation());
|
testRunner.run();
|
||||||
|
|
||||||
// Renew license after playback should still work
|
// Renew license after playback should still work
|
||||||
offlineLicenseKeySetId = offlineLicenseHelper.renew(offlineLicenseKeySetId);
|
offlineLicenseKeySetId = offlineLicenseHelper.renew(offlineLicenseKeySetId);
|
||||||
@ -98,7 +101,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
releaseLicense(); // keySetId no longer valid.
|
releaseLicense(); // keySetId no longer valid.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
builder.runTest(getActivity(), getInstrumentation());
|
testRunner.run();
|
||||||
fail("Playback should fail because the license has been released.");
|
fail("Playback should fail because the license has been released.");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// Get the root cause
|
// Get the root cause
|
||||||
@ -138,7 +141,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultDrmSessionManager should renew the license and stream play fine
|
// DefaultDrmSessionManager should renew the license and stream play fine
|
||||||
builder.runTest(getActivity(), getInstrumentation());
|
testRunner.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWidevineOfflineLicenseExpiresOnPause() throws Exception {
|
public void testWidevineOfflineLicenseExpiresOnPause() throws Exception {
|
||||||
@ -157,9 +160,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
.delay(3000).pause().delay(licenseDuration * 1000 + 2000).play().build();
|
.delay(3000).pause().delay(licenseDuration * 1000 + 2000).play().build();
|
||||||
|
|
||||||
// DefaultDrmSessionManager should renew the license and stream play fine
|
// DefaultDrmSessionManager should renew the license and stream play fine
|
||||||
builder
|
testRunner.setActionSchedule(schedule).run();
|
||||||
.setActionSchedule(schedule)
|
|
||||||
.runTest(getActivity(), getInstrumentation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadLicense() throws InterruptedException, DrmSessionException, IOException {
|
private void downloadLicense() throws InterruptedException, DrmSessionException, IOException {
|
||||||
@ -167,7 +168,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
|
|||||||
httpDataSourceFactory.createDataSource(), DashTestData.WIDEVINE_H264_MANIFEST);
|
httpDataSourceFactory.createDataSource(), DashTestData.WIDEVINE_H264_MANIFEST);
|
||||||
Assert.assertNotNull(offlineLicenseKeySetId);
|
Assert.assertNotNull(offlineLicenseKeySetId);
|
||||||
Assert.assertTrue(offlineLicenseKeySetId.length > 0);
|
Assert.assertTrue(offlineLicenseKeySetId.length > 0);
|
||||||
builder.setOfflineLicenseKeySetId(offlineLicenseKeySetId);
|
testRunner.setOfflineLicenseKeySetId(offlineLicenseKeySetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void releaseLicense() throws DrmSessionException {
|
private void releaseLicense() throws DrmSessionException {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user