Commit a61828a6 by mishragaurav Committed by Oliver Woodman

Merge widevine playback tests to v2.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127825954
parent 2ed55d97
...@@ -20,6 +20,8 @@ import com.google.android.exoplayer2.ExoPlaybackException; ...@@ -20,6 +20,8 @@ import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo; import com.google.android.exoplayer2.mediacodec.MediaCodecInfo;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
...@@ -28,6 +30,7 @@ import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil; ...@@ -28,6 +30,7 @@ import com.google.android.exoplayer2.playbacktests.util.DecoderCountersUtil;
import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest; import com.google.android.exoplayer2.playbacktests.util.ExoHostedTest;
import com.google.android.exoplayer2.playbacktests.util.HostActivity; import com.google.android.exoplayer2.playbacktests.util.HostActivity;
import com.google.android.exoplayer2.playbacktests.util.MetricsLogger; import com.google.android.exoplayer2.playbacktests.util.MetricsLogger;
import com.google.android.exoplayer2.playbacktests.util.TestMediaDrmCallback;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
...@@ -45,6 +48,8 @@ import com.google.android.exoplayer2.util.MimeTypes; ...@@ -45,6 +48,8 @@ import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.media.MediaDrm;
import android.media.UnsupportedSchemeException;
import android.net.Uri; import android.net.Uri;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import android.util.Log; import android.util.Log;
...@@ -53,6 +58,7 @@ import junit.framework.AssertionFailedError; ...@@ -53,6 +58,7 @@ import junit.framework.AssertionFailedError;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID;
/** /**
* Tests DASH playbacks using {@link ExoPlayer}. * Tests DASH playbacks using {@link ExoPlayer}.
...@@ -63,6 +69,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -63,6 +69,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private static final String VIDEO_TAG = TAG + ":Video"; private static final String VIDEO_TAG = TAG + ":Video";
private static final String AUDIO_TAG = TAG + ":Audio"; private static final String AUDIO_TAG = TAG + ":Audio";
private static final String REPORT_NAME = "GtsExoPlayerTestCases"; private static final String REPORT_NAME = "GtsExoPlayerTestCases";
private static final String REPORT_OBJECT_NAME = "playbacktest";
private static final int VIDEO_RENDERER_INDEX = 0; private static final int VIDEO_RENDERER_INDEX = 0;
private static final int AUDIO_RENDERER_INDEX = 1; private static final int AUDIO_RENDERER_INDEX = 1;
...@@ -73,12 +80,22 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -73,12 +80,22 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private static final String MANIFEST_URL_PREFIX = "https://storage.googleapis.com/exoplayer-test-" private static final String MANIFEST_URL_PREFIX = "https://storage.googleapis.com/exoplayer-test-"
+ "media-1/gen-3/screens/dash-vod-single-segment/"; + "media-1/gen-3/screens/dash-vod-single-segment/";
// Clear content manifests.
private static final String H264_MANIFEST = "manifest-h264.mpd"; private static final String H264_MANIFEST = "manifest-h264.mpd";
private static final String H265_MANIFEST = "manifest-h265.mpd"; private static final String H265_MANIFEST = "manifest-h265.mpd";
private static final String VP9_MANIFEST = "manifest-vp9.mpd"; private static final String VP9_MANIFEST = "manifest-vp9.mpd";
private static final String H264_23_MANIFEST = "manifest-h264-23.mpd"; private static final String H264_23_MANIFEST = "manifest-h264-23.mpd";
private static final String H264_24_MANIFEST = "manifest-h264-24.mpd"; private static final String H264_24_MANIFEST = "manifest-h264-24.mpd";
private static final String H264_29_MANIFEST = "manifest-h264-29.mpd"; private static final String H264_29_MANIFEST = "manifest-h264-29.mpd";
// Widevine encrypted content manifests.
private static final String WIDEVINE_H264_MANIFEST_PREFIX = "manifest-h264-enc";
private static final String WIDEVINE_H265_MANIFEST_PREFIX = "manifest-h265-enc";
private static final String WIDEVINE_VP9_MANIFEST_PREFIX = "manifest-vp9-enc";
private static final String WIDEVINE_H264_23_MANIFEST_PREFIX = "manifest-h264-23-enc";
private static final String WIDEVINE_H264_24_MANIFEST_PREFIX = "manifest-h264-24-enc";
private static final String WIDEVINE_H264_29_MANIFEST_PREFIX = "manifest-h264-29-enc";
private static final String WIDEVINE_L1_SUFFIX = "-hw.mpd";
private static final String WIDEVINE_L3_SUFFIX = "-sw.mpd";
private static final String AAC_AUDIO_REPRESENTATION_ID = "141"; private static final String AAC_AUDIO_REPRESENTATION_ID = "141";
private static final String H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "avc-baseline-240"; private static final String H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "avc-baseline-240";
...@@ -129,6 +146,63 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -129,6 +146,63 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
VP9_180P_VIDEO_REPRESENTATION_ID, VP9_180P_VIDEO_REPRESENTATION_ID,
VP9_360P_VIDEO_REPRESENTATION_ID}; VP9_360P_VIDEO_REPRESENTATION_ID};
// Widevine encrypted content representation ids.
private static final String WIDEVINE_AAC_AUDIO_REPRESENTATION_ID = "0";
private static final String WIDEVINE_H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "1";
private static final String WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID = "2";
private static final String WIDEVINE_H264_MAIN_240P_VIDEO_REPRESENTATION_ID = "3";
private static final String WIDEVINE_H264_MAIN_480P_VIDEO_REPRESENTATION_ID = "4";
// The highest quality H264 format mandated by the Android CDD.
private static final String WIDEVINE_H264_CDD_FIXED = Util.SDK_INT < 23
? WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID
: WIDEVINE_H264_MAIN_480P_VIDEO_REPRESENTATION_ID;
// Multiple H264 formats mandated by the Android CDD. Note: The CDD actually mandated main profile
// support from API level 23, but we opt to test only from 24 due to known issues on API level 23
// when switching between baseline and main profiles on certain devices.
private static final String[] WIDEVINE_H264_CDD_ADAPTIVE = Util.SDK_INT < 24
? new String[] {
WIDEVINE_H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID}
: new String[] {
WIDEVINE_H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_MAIN_240P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_MAIN_480P_VIDEO_REPRESENTATION_ID};
private static final String WIDEVINE_H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID = "2";
private static final String WIDEVINE_H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID = "2";
private static final String WIDEVINE_H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID = "2";
private static final String WIDEVINE_H265_BASELINE_288P_VIDEO_REPRESENTATION_ID = "1";
private static final String WIDEVINE_H265_BASELINE_360P_VIDEO_REPRESENTATION_ID = "2";
// The highest quality H265 format mandated by the Android CDD.
private static final String WIDEVINE_H265_CDD_FIXED =
WIDEVINE_H265_BASELINE_360P_VIDEO_REPRESENTATION_ID;
// Multiple H265 formats mandated by the Android CDD.
private static final String[] WIDEVINE_H265_CDD_ADAPTIVE =
new String[] {
WIDEVINE_H265_BASELINE_288P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H265_BASELINE_360P_VIDEO_REPRESENTATION_ID};
private static final String WIDEVINE_VORBIS_AUDIO_REPRESENTATION_ID = "0";
private static final String WIDEVINE_VP9_180P_VIDEO_REPRESENTATION_ID = "1";
private static final String WIDEVINE_VP9_360P_VIDEO_REPRESENTATION_ID = "2";
// The highest quality VP9 format mandated by the Android CDD.
private static final String WIDEVINE_VP9_CDD_FIXED = VP9_360P_VIDEO_REPRESENTATION_ID;
// Multiple VP9 formats mandated by the Android CDD.
private static final String[] WIDEVINE_VP9_CDD_ADAPTIVE =
new String[] {
WIDEVINE_VP9_180P_VIDEO_REPRESENTATION_ID,
WIDEVINE_VP9_360P_VIDEO_REPRESENTATION_ID};
private static final String WIDEVINE_PROVIDER = "widevine_test";
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 UUID WIDEVINE_UUID = new UUID(0xEDEF8BA979D64ACEL, 0xA3C827DCD51D21EDL);
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";
// Whether adaptive tests should enable video formats beyond those mandated by the Android CDD // Whether adaptive tests should enable video formats beyond those mandated by the Android CDD
// if the device advertises support for them. // if the device advertises support for them.
private static final boolean ALLOW_ADDITIONAL_VIDEO_FORMATS = Util.SDK_INT >= 24; private static final boolean ALLOW_ADDITIONAL_VIDEO_FORMATS = Util.SDK_INT >= 24;
...@@ -184,7 +258,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -184,7 +258,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_h264_fixed"; String streamName = "test_h264_fixed";
testDashPlayback(getActivity(), streamName, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false, testDashPlayback(getActivity(), streamName, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false,
H264_CDD_FIXED); MimeTypes.VIDEO_H264, false, H264_CDD_FIXED);
} }
public void testH264Adaptive() throws DecoderQueryException { public void testH264Adaptive() throws DecoderQueryException {
...@@ -193,8 +267,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -193,8 +267,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
return; return;
} }
String streamName = "test_h264_adaptive"; String streamName = "test_h264_adaptive";
testDashPlayback(getActivity(), streamName, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, testDashPlayback(getActivity(), streamName, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false,
ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE); MimeTypes.VIDEO_H264, ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE);
} }
public void testH264AdaptiveWithSeeking() throws DecoderQueryException { public void testH264AdaptiveWithSeeking() throws DecoderQueryException {
...@@ -204,7 +278,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -204,7 +278,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_h264_adaptive_with_seeking"; String streamName = "test_h264_adaptive_with_seeking";
testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false, H264_MANIFEST, testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false, H264_MANIFEST,
AAC_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE); AAC_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_H264, ALLOW_ADDITIONAL_VIDEO_FORMATS,
H264_CDD_ADAPTIVE);
} }
public void testH264AdaptiveWithRendererDisabling() throws DecoderQueryException { public void testH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
...@@ -214,7 +289,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -214,7 +289,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_h264_adaptive_with_renderer_disabling"; String streamName = "test_h264_adaptive_with_renderer_disabling";
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false, H264_MANIFEST, testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false, H264_MANIFEST,
AAC_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE); AAC_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_H264, ALLOW_ADDITIONAL_VIDEO_FORMATS,
H264_CDD_ADAPTIVE);
} }
// H265 CDD. // H265 CDD.
...@@ -226,7 +302,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -226,7 +302,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_h265_fixed"; String streamName = "test_h265_fixed";
testDashPlayback(getActivity(), streamName, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false, testDashPlayback(getActivity(), streamName, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false,
H265_CDD_FIXED); MimeTypes.VIDEO_H265, false, H265_CDD_FIXED);
} }
public void testH265Adaptive() throws DecoderQueryException { public void testH265Adaptive() throws DecoderQueryException {
...@@ -235,8 +311,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -235,8 +311,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
return; return;
} }
String streamName = "test_h265_adaptive"; String streamName = "test_h265_adaptive";
testDashPlayback(getActivity(), streamName, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, testDashPlayback(getActivity(), streamName, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false,
ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE); MimeTypes.VIDEO_H265, ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE);
} }
public void testH265AdaptiveWithSeeking() throws DecoderQueryException { public void testH265AdaptiveWithSeeking() throws DecoderQueryException {
...@@ -246,7 +322,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -246,7 +322,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_h265_adaptive_with_seeking"; String streamName = "test_h265_adaptive_with_seeking";
testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false, H265_MANIFEST, testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false, H265_MANIFEST,
AAC_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE); AAC_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_H265, ALLOW_ADDITIONAL_VIDEO_FORMATS,
H265_CDD_ADAPTIVE);
} }
public void testH265AdaptiveWithRendererDisabling() throws DecoderQueryException { public void testH265AdaptiveWithRendererDisabling() throws DecoderQueryException {
...@@ -256,8 +333,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -256,8 +333,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_h265_adaptive_with_renderer_disabling"; String streamName = "test_h265_adaptive_with_renderer_disabling";
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false, testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_H265,
H265_CDD_ADAPTIVE); ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE);
} }
// VP9 (CDD). // VP9 (CDD).
...@@ -269,7 +346,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -269,7 +346,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_vp9_fixed_360p"; String streamName = "test_vp9_fixed_360p";
testDashPlayback(getActivity(), streamName, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, false, testDashPlayback(getActivity(), streamName, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, false,
VP9_CDD_FIXED); MimeTypes.VIDEO_VP9, false, VP9_CDD_FIXED);
} }
public void testVp9Adaptive() throws DecoderQueryException { public void testVp9Adaptive() throws DecoderQueryException {
...@@ -278,8 +355,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -278,8 +355,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
return; return;
} }
String streamName = "test_vp9_adaptive"; String streamName = "test_vp9_adaptive";
testDashPlayback(getActivity(), streamName, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, testDashPlayback(getActivity(), streamName, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, false,
ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE); MimeTypes.VIDEO_VP9, ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE);
} }
public void testVp9AdaptiveWithSeeking() throws DecoderQueryException { public void testVp9AdaptiveWithSeeking() throws DecoderQueryException {
...@@ -289,7 +366,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -289,7 +366,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_vp9_adaptive_with_seeking"; String streamName = "test_vp9_adaptive_with_seeking";
testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false, VP9_MANIFEST, testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false, VP9_MANIFEST,
VORBIS_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE); VORBIS_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_VP9, ALLOW_ADDITIONAL_VIDEO_FORMATS,
VP9_CDD_ADAPTIVE);
} }
public void testVp9AdaptiveWithRendererDisabling() throws DecoderQueryException { public void testVp9AdaptiveWithRendererDisabling() throws DecoderQueryException {
...@@ -299,8 +377,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -299,8 +377,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_vp9_adaptive_with_renderer_disabling"; String streamName = "test_vp9_adaptive_with_renderer_disabling";
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false, testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_VP9,
VP9_CDD_ADAPTIVE); ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE);
} }
// H264: Other frame-rates for output buffer count assertions. // H264: Other frame-rates for output buffer count assertions.
...@@ -313,7 +391,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -313,7 +391,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_23fps_h264_fixed"; String streamName = "test_23fps_h264_fixed";
testDashPlayback(getActivity(), streamName, H264_23_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, testDashPlayback(getActivity(), streamName, H264_23_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
false, H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID); false, MimeTypes.VIDEO_H264, false, H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID);
} }
// 24 fps. // 24 fps.
...@@ -324,7 +402,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -324,7 +402,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_24fps_h264_fixed"; String streamName = "test_24fps_h264_fixed";
testDashPlayback(getActivity(), streamName, H264_24_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, testDashPlayback(getActivity(), streamName, H264_24_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
false, H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID); false, MimeTypes.VIDEO_H264, false, H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID);
} }
// 29.97 fps. // 29.97 fps.
...@@ -335,39 +413,219 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -335,39 +413,219 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
String streamName = "test_29fps_h264_fixed"; String streamName = "test_29fps_h264_fixed";
testDashPlayback(getActivity(), streamName, H264_29_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, testDashPlayback(getActivity(), streamName, H264_29_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
false, H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID); false, MimeTypes.VIDEO_H264, false, H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID);
}
// Widevine encrypted media tests.
// H264 CDD.
public void testWidevineH264Fixed() throws DecoderQueryException {
if (Util.SDK_INT < 18) {
// Pass.
return;
}
String streamName = "test_widevine_h264_fixed";
testDashPlayback(getActivity(), streamName, WIDEVINE_H264_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H264, false,
WIDEVINE_H264_CDD_FIXED);
}
public void testWidevineH264Adaptive() throws DecoderQueryException {
if (Util.SDK_INT < 18 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
// Pass.
return;
}
String streamName = "test_widevine_h264_adaptive";
testDashPlayback(getActivity(), streamName, WIDEVINE_H264_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H264,
ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_H264_CDD_ADAPTIVE);
}
public void testWidevineH264AdaptiveWithSeeking() throws DecoderQueryException {
if (Util.SDK_INT < 18 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
// Pass.
return;
}
String streamName = "test_widevine_h264_adaptive_with_seeking";
testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false,
WIDEVINE_H264_MANIFEST_PREFIX, WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true,
MimeTypes.VIDEO_H264, ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_H264_CDD_ADAPTIVE);
}
public void testWidevineH264AdaptiveWithRendererDisabling() throws DecoderQueryException {
if (Util.SDK_INT < 18 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H264)) {
// Pass.
return;
}
String streamName = "test_widevine_h264_adaptive_with_renderer_disabling";
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
WIDEVINE_H264_MANIFEST_PREFIX, WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true,
MimeTypes.VIDEO_H264, ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_H264_CDD_ADAPTIVE);
}
// H265 CDD.
public void testWidevineH265Fixed() throws DecoderQueryException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
String streamName = "test_widevine_h265_fixed";
testDashPlayback(getActivity(), streamName, WIDEVINE_H265_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H265, false,
WIDEVINE_H265_CDD_FIXED);
}
public void testWidevineH265Adaptive() throws DecoderQueryException {
if (Util.SDK_INT < 24 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H265)) {
// Pass.
return;
}
String streamName = "test_widevine_h265_adaptive";
testDashPlayback(getActivity(), streamName, WIDEVINE_H265_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H265,
ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_H265_CDD_ADAPTIVE);
}
public void testWidevineH265AdaptiveWithSeeking() throws DecoderQueryException {
if (Util.SDK_INT < 24 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H265)) {
// Pass.
return;
}
String streamName = "test_widevine_h265_adaptive_with_seeking";
testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false,
WIDEVINE_H265_MANIFEST_PREFIX, WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true,
MimeTypes.VIDEO_H265, ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_H265_CDD_ADAPTIVE);
}
public void testWidevineH265AdaptiveWithRendererDisabling() throws DecoderQueryException {
if (Util.SDK_INT < 24 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_H265)) {
// Pass.
return;
}
String streamName = "test_widevine_h265_adaptive_with_renderer_disabling";
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
WIDEVINE_H265_MANIFEST_PREFIX, WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true,
MimeTypes.VIDEO_H265, ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_H265_CDD_ADAPTIVE);
}
// VP9 (CDD).
public void testWidevineVp9Fixed360p() throws DecoderQueryException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
String streamName = "test_widevine_vp9_fixed_360p";
testDashPlayback(getActivity(), streamName, WIDEVINE_VP9_MANIFEST_PREFIX,
WIDEVINE_VORBIS_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_VP9, false,
WIDEVINE_VP9_CDD_FIXED);
}
public void testWidevineVp9Adaptive() throws DecoderQueryException {
if (Util.SDK_INT < 24 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_VP9)) {
// Pass.
return;
}
String streamName = "test_widevine_vp9_adaptive";
testDashPlayback(getActivity(), streamName, WIDEVINE_VP9_MANIFEST_PREFIX,
WIDEVINE_VORBIS_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_VP9,
ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_VP9_CDD_ADAPTIVE);
}
public void testWidevineVp9AdaptiveWithSeeking() throws DecoderQueryException {
if (Util.SDK_INT < 24 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_VP9)) {
// Pass.
return;
}
String streamName = "test_widevine_vp9_adaptive_with_seeking";
testDashPlayback(getActivity(), streamName, SEEKING_SCHEDULE, false,
WIDEVINE_VP9_MANIFEST_PREFIX, WIDEVINE_VORBIS_AUDIO_REPRESENTATION_ID, true,
MimeTypes.VIDEO_VP9, ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_VP9_CDD_ADAPTIVE);
}
public void testWidevineVp9AdaptiveWithRendererDisabling() throws DecoderQueryException {
if (Util.SDK_INT < 24 || shouldSkipAdaptiveTest(MimeTypes.VIDEO_VP9)) {
// Pass.
return;
}
String streamName = "test_widevine_vp9_adaptive_with_renderer_disabling";
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
WIDEVINE_VP9_MANIFEST_PREFIX, WIDEVINE_VORBIS_AUDIO_REPRESENTATION_ID, true,
MimeTypes.VIDEO_VP9, ALLOW_ADDITIONAL_VIDEO_FORMATS, WIDEVINE_VP9_CDD_ADAPTIVE);
}
// H264: Other frame-rates for output buffer count assertions.
// 23.976 fps.
public void testWidevine23FpsH264Fixed() throws DecoderQueryException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
String streamName = "test_widevine_23fps_h264_fixed";
testDashPlayback(getActivity(), streamName, WIDEVINE_H264_23_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H264, false,
WIDEVINE_H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID);
}
// 24 fps.
public void testWidevine24FpsH264Fixed() throws DecoderQueryException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
String streamName = "test_widevine_24fps_h264_fixed";
testDashPlayback(getActivity(), streamName, WIDEVINE_H264_24_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H264, false,
WIDEVINE_H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID);
}
// 29.97 fps.
public void testWidevine29FpsH264Fixed() throws DecoderQueryException {
if (Util.SDK_INT < 23) {
// Pass.
return;
}
String streamName = "test_widevine_29fps_h264_fixed";
testDashPlayback(getActivity(), streamName, WIDEVINE_H264_29_MANIFEST_PREFIX,
WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, true, MimeTypes.VIDEO_H264, false,
WIDEVINE_H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID);
} }
// Internal. // Internal.
private void testDashPlayback(HostActivity activity, String streamName, String manifestFileName, private void testDashPlayback(HostActivity activity, String streamName, String manifestFileName,
String audioFormat, boolean canIncludeAdditionalVideoFormats, String... videoFormats) { String audioFormat, boolean isWidevineEncrypted, String videoMimeType,
boolean canIncludeAdditionalVideoFormats, String... videoFormats) {
testDashPlayback(activity, streamName, null, true, manifestFileName, audioFormat, testDashPlayback(activity, streamName, null, true, manifestFileName, audioFormat,
canIncludeAdditionalVideoFormats, videoFormats); isWidevineEncrypted, videoMimeType, canIncludeAdditionalVideoFormats, videoFormats);
} }
private void testDashPlayback(HostActivity activity, String streamName, private void testDashPlayback(HostActivity activity, String streamName,
ActionSchedule actionSchedule, boolean fullPlaybackNoSeeking, String manifestFileName, ActionSchedule actionSchedule, boolean fullPlaybackNoSeeking, String manifestFileName,
String audioFormat, boolean canIncludeAdditionalVideoFormats, String... videoFormats) { String audioFormat, boolean isWidevineEncrypted, String videoMimeType,
Uri manifestUri = Uri.parse(MANIFEST_URL_PREFIX + manifestFileName); boolean canIncludeAdditionalVideoFormats, String... videoFormats) {
MetricsLogger metricsLogger = MetricsLogger.Factory.createDefault(getInstrumentation(), TAG, MetricsLogger metricsLogger = MetricsLogger.Factory.createDefault(getInstrumentation(), TAG,
REPORT_NAME, streamName); REPORT_NAME, REPORT_OBJECT_NAME);
DashHostedTest test = new DashHostedTest(streamName, manifestUri, metricsLogger, String manifestPath = MANIFEST_URL_PREFIX + manifestFileName;
fullPlaybackNoSeeking, audioFormat, canIncludeAdditionalVideoFormats, false, actionSchedule, DashHostedTest test = new DashHostedTest(streamName, manifestPath, metricsLogger,
videoFormats); fullPlaybackNoSeeking, audioFormat, isWidevineEncrypted, videoMimeType,
canIncludeAdditionalVideoFormats, false, actionSchedule, videoFormats);
activity.runTest(test, TEST_TIMEOUT_MS); activity.runTest(test, TEST_TIMEOUT_MS);
// Retry test exactly once if adaptive test fails due to excessive dropped buffers when playing // Retry test exactly once if adaptive test fails due to excessive dropped buffers when playing
// non-CDD required formats (b/28220076). // non-CDD required formats (b/28220076).
if (test.needsCddLimitedRetry) { if (test.needsCddLimitedRetry) {
metricsLogger = MetricsLogger.Factory.createDefault(getInstrumentation(), TAG, REPORT_NAME, metricsLogger = MetricsLogger.Factory.createDefault(getInstrumentation(), TAG, REPORT_NAME,
streamName + "_cdd_limited_retry"); REPORT_OBJECT_NAME);
test = new DashHostedTest(streamName, manifestUri, metricsLogger, fullPlaybackNoSeeking, test = new DashHostedTest(streamName, manifestPath, metricsLogger, fullPlaybackNoSeeking,
audioFormat, false, true, actionSchedule, videoFormats); audioFormat, isWidevineEncrypted, videoMimeType, false, true, actionSchedule,
videoFormats);
activity.runTest(test, TEST_TIMEOUT_MS); activity.runTest(test, TEST_TIMEOUT_MS);
} }
} }
private boolean shouldSkipAdaptiveTest(String mimeType) throws DecoderQueryException { private static boolean shouldSkipAdaptiveTest(String mimeType) throws DecoderQueryException {
MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, false); MediaCodecInfo decoderInfo = MediaCodecUtil.getDecoderInfo(mimeType, false);
assertNotNull(decoderInfo); assertNotNull(decoderInfo);
if (decoderInfo.adaptive) { if (decoderInfo.adaptive) {
...@@ -381,34 +639,45 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -381,34 +639,45 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
private static class DashHostedTest extends ExoHostedTest { private static class DashHostedTest extends ExoHostedTest {
private final String streamName; private final String streamName;
private final Uri manifestUri; private final String videoMimeType;
private final String manifestPath;
private final MetricsLogger metricsLogger; private final MetricsLogger metricsLogger;
private final boolean fullPlaybackNoSeeking; private final boolean fullPlaybackNoSeeking;
private final boolean isCddLimitedRetry;
private final boolean isWidevineEncrypted;
private final DashTestTrackSelector trackSelector; private final DashTestTrackSelector trackSelector;
private boolean needsCddLimitedRetry; private boolean needsCddLimitedRetry;
private boolean needsSecureVideoDecoder;
/** /**
* @param streamName The name of the test stream for metric logging. * @param streamName The name of the test stream for metric logging.
* @param manifestUri The manifest uri. * @param manifestPath The manifest path.
* @param metricsLogger Logger to log metrics from the test. * @param metricsLogger Logger to log metrics from the test.
* @param fullPlaybackNoSeeking True if the test will play the entire source with no seeking. * @param fullPlaybackNoSeeking True if the test will play the entire source with no seeking.
* False otherwise. * False otherwise.
* @param audioFormat The audio format. * @param audioFormat The audio format.
* @param isWidevineEncrypted Whether the video is Widevine encrypted.
* @param videoMimeType The video mime type.
* @param canIncludeAdditionalVideoFormats Whether to use video formats in addition to those * @param canIncludeAdditionalVideoFormats Whether to use video formats in addition to those
* listed in the videoFormats argument, if the device is capable of playing them. * 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 isCddLimitedRetry Whether this is a CDD limited retry following a previous failure.
* @param actionSchedule The action schedule for the test.
* @param videoFormats The video formats. * @param videoFormats The video formats.
*/ */
public DashHostedTest(String streamName, Uri manifestUri, MetricsLogger metricsLogger, public DashHostedTest(String streamName, String manifestPath, MetricsLogger metricsLogger,
boolean fullPlaybackNoSeeking, String audioFormat, boolean canIncludeAdditionalVideoFormats, boolean fullPlaybackNoSeeking, String audioFormat, boolean isWidevineEncrypted,
boolean isCddLimitedRetry, ActionSchedule actionSchedule, String... videoFormats) { String videoMimeType, boolean canIncludeAdditionalVideoFormats, boolean isCddLimitedRetry,
ActionSchedule actionSchedule, String... videoFormats) {
super(TAG, fullPlaybackNoSeeking); super(TAG, fullPlaybackNoSeeking);
Assertions.checkArgument(!(isCddLimitedRetry && canIncludeAdditionalVideoFormats)); Assertions.checkArgument(!(isCddLimitedRetry && canIncludeAdditionalVideoFormats));
this.streamName = streamName; this.streamName = streamName;
this.manifestUri = manifestUri; this.manifestPath = manifestPath;
this.metricsLogger = metricsLogger; this.metricsLogger = metricsLogger;
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking; this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
this.isWidevineEncrypted = isWidevineEncrypted;
this.videoMimeType = videoMimeType;
this.isCddLimitedRetry = isCddLimitedRetry;
trackSelector = new DashTestTrackSelector(new String[] {audioFormat}, trackSelector = new DashTestTrackSelector(new String[] {audioFormat},
videoFormats, canIncludeAdditionalVideoFormats); videoFormats, canIncludeAdditionalVideoFormats);
if (actionSchedule != null) { if (actionSchedule != null) {
...@@ -422,6 +691,37 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -422,6 +691,37 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
} }
@Override @Override
@TargetApi(18)
protected final StreamingDrmSessionManager buildDrmSessionManager() {
StreamingDrmSessionManager drmSessionManager = null;
if (isWidevineEncrypted) {
try {
// Force L3 if secure decoder is not available.
boolean forceL3Widevine = MediaCodecUtil.getDecoderInfo(videoMimeType, true) == null;
MediaDrm mediaDrm = new MediaDrm(WIDEVINE_UUID);
String securityProperty = mediaDrm.getPropertyString(SECURITY_LEVEL_PROPERTY);
String widevineContentId = forceL3Widevine ? WIDEVINE_SW_CRYPTO_CONTENT_ID
: WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty)
? WIDEVINE_HW_SECURE_DECODE_CONTENT_ID : WIDEVINE_SW_CRYPTO_CONTENT_ID;
TestMediaDrmCallback drmCallback = TestMediaDrmCallback.newWidevineInstance(
widevineContentId, WIDEVINE_PROVIDER);
drmSessionManager = StreamingDrmSessionManager.newWidevineInstance(drmCallback, null,
null, null);
if (forceL3Widevine && !WIDEVINE_SECURITY_LEVEL_3.equals(securityProperty)) {
drmSessionManager.setPropertyString(SECURITY_LEVEL_PROPERTY, WIDEVINE_SECURITY_LEVEL_3);
}
// Check if secure video decoder is required.
securityProperty = drmSessionManager.getPropertyString(SECURITY_LEVEL_PROPERTY);
needsSecureVideoDecoder = WIDEVINE_SECURITY_LEVEL_1.equals(securityProperty);
} catch (MediaCodecUtil.DecoderQueryException | UnsupportedSchemeException
| UnsupportedDrmException e) {
throw new IllegalStateException(e);
}
}
return drmSessionManager;
}
@Override
public MediaSource buildSource(HostActivity host, String userAgent) { public MediaSource buildSource(HostActivity host, String userAgent) {
DataSource.Factory manifestDataSourceFactory = new DefaultDataSourceFactory(host, userAgent); DataSource.Factory manifestDataSourceFactory = new DefaultDataSourceFactory(host, userAgent);
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
...@@ -429,6 +729,10 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -429,6 +729,10 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
bandwidthMeter); bandwidthMeter);
FormatEvaluator.Factory formatEvaluatorFactory = new AdaptiveEvaluator.Factory( FormatEvaluator.Factory formatEvaluatorFactory = new AdaptiveEvaluator.Factory(
bandwidthMeter); bandwidthMeter);
String manifestUrl = manifestPath;
manifestUrl += isWidevineEncrypted ? (needsSecureVideoDecoder ? WIDEVINE_L1_SUFFIX
: WIDEVINE_L3_SUFFIX) : "";
Uri manifestUri = Uri.parse(manifestUrl);
DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory( DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory(
mediaDataSourceFactory, formatEvaluatorFactory); mediaDataSourceFactory, formatEvaluatorFactory);
return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory, return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
...@@ -438,6 +742,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit ...@@ -438,6 +742,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
@Override @Override
protected void logMetrics(DecoderCounters audioCounters, DecoderCounters videoCounters) { protected void logMetrics(DecoderCounters audioCounters, DecoderCounters videoCounters) {
metricsLogger.logMetric(MetricsLogger.KEY_TEST_NAME, streamName); metricsLogger.logMetric(MetricsLogger.KEY_TEST_NAME, streamName);
metricsLogger.logMetric(MetricsLogger.KEY_IS_CDD_LIMITED_RETRY, isCddLimitedRetry);
metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_DROPPED_COUNT, metricsLogger.logMetric(MetricsLogger.KEY_FRAMES_DROPPED_COUNT,
videoCounters.droppedOutputBufferCount); videoCounters.droppedOutputBufferCount);
metricsLogger.logMetric(MetricsLogger.KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT, metricsLogger.logMetric(MetricsLogger.KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT,
......
...@@ -15,6 +15,11 @@ ...@@ -15,6 +15,11 @@
*/ */
package com.google.android.exoplayer2.playbacktests.util; package com.google.android.exoplayer2.playbacktests.util;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.ExoPlayerFactory;
...@@ -22,18 +27,16 @@ import com.google.android.exoplayer2.Format; ...@@ -22,18 +27,16 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioTrack; import com.google.android.exoplayer2.audio.AudioTrack;
import com.google.android.exoplayer2.decoder.DecoderCounters; import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.playbacktests.util.HostActivity.HostedTest; import com.google.android.exoplayer2.playbacktests.util.HostActivity.HostedTest;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import junit.framework.Assert; import junit.framework.Assert;
/** /**
* A {@link HostedTest} for {@link ExoPlayer} playback tests. * A {@link HostedTest} for {@link ExoPlayer} playback tests.
*/ */
...@@ -120,7 +123,8 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -120,7 +123,8 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
public final void onStart(HostActivity host, Surface surface) { public final void onStart(HostActivity host, Surface surface) {
// Build the player. // Build the player.
trackSelector = buildTrackSelector(host); trackSelector = buildTrackSelector(host);
player = buildExoPlayer(host, surface, trackSelector); DrmSessionManager drmSessionManager = buildDrmSessionManager();
player = buildExoPlayer(host, surface, trackSelector, drmSessionManager);
player.setMediaSource(buildSource(host, Util.getUserAgent(host, "ExoPlayerPlaybackTests"))); player.setMediaSource(buildSource(host, Util.getUserAgent(host, "ExoPlayerPlaybackTests")));
player.addListener(this); player.addListener(this);
player.setDebugListener(this); player.setDebugListener(this);
...@@ -271,6 +275,11 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -271,6 +275,11 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
// Internal logic // Internal logic
protected DrmSessionManager buildDrmSessionManager() {
// Do nothing. Interested subclasses may override.
return null;
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected MappingTrackSelector buildTrackSelector(HostActivity host) { protected MappingTrackSelector buildTrackSelector(HostActivity host) {
return new DefaultTrackSelector(null); return new DefaultTrackSelector(null);
...@@ -278,8 +287,9 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen ...@@ -278,8 +287,9 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
@SuppressWarnings("unused") @SuppressWarnings("unused")
protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface, protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface,
MappingTrackSelector trackSelector) { MappingTrackSelector trackSelector, DrmSessionManager drmSessionManager) {
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(host, trackSelector); SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(host, trackSelector,
new DefaultLoadControl(), drmSessionManager);
player.setSurface(surface); player.setSurface(surface);
return player; return player;
} }
......
...@@ -44,6 +44,11 @@ public final class LogcatMetricsLogger implements MetricsLogger { ...@@ -44,6 +44,11 @@ public final class LogcatMetricsLogger implements MetricsLogger {
} }
@Override @Override
public void logMetric(String key, boolean value) {
Log.d(tag, key + ": " + value);
}
@Override
public void close() { public void close() {
// Do nothing. // Do nothing.
} }
......
...@@ -27,6 +27,7 @@ public interface MetricsLogger { ...@@ -27,6 +27,7 @@ public interface MetricsLogger {
String KEY_FRAMES_SKIPPED_COUNT = "frames_skipped_count"; String KEY_FRAMES_SKIPPED_COUNT = "frames_skipped_count";
String KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT = "maximum_consecutive_frames_dropped_count"; String KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT = "maximum_consecutive_frames_dropped_count";
String KEY_TEST_NAME = "test_name"; String KEY_TEST_NAME = "test_name";
String KEY_IS_CDD_LIMITED_RETRY = "is_cdd_limited_retry";
/** /**
* Logs an int metric provided from a test. * Logs an int metric provided from a test.
...@@ -53,6 +54,14 @@ public interface MetricsLogger { ...@@ -53,6 +54,14 @@ public interface MetricsLogger {
void logMetric(String key, String value); void logMetric(String key, String value);
/** /**
* Logs a boolean metric provided from a test.
*
* @param key The key of the metric to be logged.
* @param value The value of the metric to be logged.
*/
void logMetric(String key, boolean value);
/**
* Closes the logger. * Closes the logger.
*/ */
void close(); void close();
......
/*
* Copyright (C) 2016 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.util;
import android.annotation.TargetApi;
import android.media.MediaDrm;
import android.text.TextUtils;
import com.google.android.exoplayer2.drm.MediaDrmCallback;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.UUID;
/**
* A {@link MediaDrmCallback} for Widevine test content.
*/
@TargetApi(18)
public final class TestMediaDrmCallback implements MediaDrmCallback {
private static final String WIDEVINE_BASE_URL = "https://proxy.uat.widevine.com/proxy";
private final String defaultUrl;
private final Map<String, String> keyRequestProperties;
public static TestMediaDrmCallback newWidevineInstance(String contentId, String provider) {
String defaultUrl = WIDEVINE_BASE_URL + "?video_id=" + contentId + "&provider=" + provider;
return new TestMediaDrmCallback(defaultUrl, null);
}
private TestMediaDrmCallback(String defaultUrl, Map<String, String> keyRequestProperties) {
this.defaultUrl = defaultUrl;
this.keyRequestProperties = keyRequestProperties;
}
@Override
public byte[] executeProvisionRequest(UUID uuid, MediaDrm.ProvisionRequest request)
throws IOException {
String url = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData(),
Charset.defaultCharset());
return executePost(url, null, null);
}
@Override
public byte[] executeKeyRequest(UUID uuid, MediaDrm.KeyRequest request) throws Exception {
String url = request.getDefaultUrl();
if (TextUtils.isEmpty(url)) {
url = defaultUrl;
}
return executePost(url, request.getData(), keyRequestProperties);
}
private static byte[] executePost(String url, byte[] data, Map<String, String> requestProperties)
throws IOException {
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(data != null);
urlConnection.setDoInput(true);
if (requestProperties != null) {
for (Map.Entry<String, String> requestProperty : requestProperties.entrySet()) {
urlConnection.setRequestProperty(requestProperty.getKey(), requestProperty.getValue());
}
}
// Write the request body, if there is one.
if (data != null) {
OutputStream out = urlConnection.getOutputStream();
try {
out.write(data);
} finally {
out.close();
}
}
// Read and return the response body.
InputStream inputStream = urlConnection.getInputStream();
try {
return Util.toByteArray(inputStream);
} finally {
inputStream.close();
}
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment