mirror of
https://github.com/samsonjs/media.git
synced 2026-04-09 11:55:46 +00:00
Merge widevine playback tests to v2.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=127825954
This commit is contained in:
parent
2ed55d97d1
commit
a61828a675
5 changed files with 481 additions and 45 deletions
|
|
@ -20,6 +20,8 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
|||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.RendererCapabilities;
|
||||
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.MediaCodecUtil;
|
||||
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
|
||||
|
|
@ -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.HostActivity;
|
||||
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.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
|
|
@ -45,6 +48,8 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.media.MediaDrm;
|
||||
import android.media.UnsupportedSchemeException;
|
||||
import android.net.Uri;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.Log;
|
||||
|
|
@ -53,6 +58,7 @@ import junit.framework.AssertionFailedError;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Tests DASH playbacks using {@link ExoPlayer}.
|
||||
|
|
@ -63,6 +69,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
private static final String VIDEO_TAG = TAG + ":Video";
|
||||
private static final String AUDIO_TAG = TAG + ":Audio";
|
||||
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 AUDIO_RENDERER_INDEX = 1;
|
||||
|
||||
|
|
@ -73,12 +80,22 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
|
||||
private static final String MANIFEST_URL_PREFIX = "https://storage.googleapis.com/exoplayer-test-"
|
||||
+ "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 H265_MANIFEST = "manifest-h265.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_24_MANIFEST = "manifest-h264-24.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 H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "avc-baseline-240";
|
||||
|
|
@ -129,6 +146,63 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
VP9_180P_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
|
||||
// if the device advertises support for them.
|
||||
private static final boolean ALLOW_ADDITIONAL_VIDEO_FORMATS = Util.SDK_INT >= 24;
|
||||
|
|
@ -184,7 +258,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_h264_fixed";
|
||||
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 {
|
||||
|
|
@ -193,8 +267,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
return;
|
||||
}
|
||||
String streamName = "test_h264_adaptive";
|
||||
testDashPlayback(getActivity(), streamName, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
|
||||
ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE);
|
||||
testDashPlayback(getActivity(), streamName, H264_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false,
|
||||
MimeTypes.VIDEO_H264, ALLOW_ADDITIONAL_VIDEO_FORMATS, H264_CDD_ADAPTIVE);
|
||||
}
|
||||
|
||||
public void testH264AdaptiveWithSeeking() throws DecoderQueryException {
|
||||
|
|
@ -204,7 +278,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_h264_adaptive_with_seeking";
|
||||
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 {
|
||||
|
|
@ -214,7 +289,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_h264_adaptive_with_renderer_disabling";
|
||||
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.
|
||||
|
|
@ -226,7 +302,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_h265_fixed";
|
||||
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 {
|
||||
|
|
@ -235,8 +311,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
return;
|
||||
}
|
||||
String streamName = "test_h265_adaptive";
|
||||
testDashPlayback(getActivity(), streamName, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID,
|
||||
ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE);
|
||||
testDashPlayback(getActivity(), streamName, H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false,
|
||||
MimeTypes.VIDEO_H265, ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE);
|
||||
}
|
||||
|
||||
public void testH265AdaptiveWithSeeking() throws DecoderQueryException {
|
||||
|
|
@ -246,7 +322,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_h265_adaptive_with_seeking";
|
||||
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 {
|
||||
|
|
@ -256,8 +333,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_h265_adaptive_with_renderer_disabling";
|
||||
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
|
||||
H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS,
|
||||
H265_CDD_ADAPTIVE);
|
||||
H265_MANIFEST, AAC_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_H265,
|
||||
ALLOW_ADDITIONAL_VIDEO_FORMATS, H265_CDD_ADAPTIVE);
|
||||
}
|
||||
|
||||
// VP9 (CDD).
|
||||
|
|
@ -269,7 +346,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_vp9_fixed_360p";
|
||||
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 {
|
||||
|
|
@ -278,8 +355,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
return;
|
||||
}
|
||||
String streamName = "test_vp9_adaptive";
|
||||
testDashPlayback(getActivity(), streamName, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID,
|
||||
ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE);
|
||||
testDashPlayback(getActivity(), streamName, VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, false,
|
||||
MimeTypes.VIDEO_VP9, ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE);
|
||||
}
|
||||
|
||||
public void testVp9AdaptiveWithSeeking() throws DecoderQueryException {
|
||||
|
|
@ -289,7 +366,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_vp9_adaptive_with_seeking";
|
||||
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 {
|
||||
|
|
@ -299,8 +377,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_vp9_adaptive_with_renderer_disabling";
|
||||
testDashPlayback(getActivity(), streamName, RENDERER_DISABLING_SCHEDULE, false,
|
||||
VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, ALLOW_ADDITIONAL_VIDEO_FORMATS,
|
||||
VP9_CDD_ADAPTIVE);
|
||||
VP9_MANIFEST, VORBIS_AUDIO_REPRESENTATION_ID, false, MimeTypes.VIDEO_VP9,
|
||||
ALLOW_ADDITIONAL_VIDEO_FORMATS, VP9_CDD_ADAPTIVE);
|
||||
}
|
||||
|
||||
// H264: Other frame-rates for output buffer count assertions.
|
||||
|
|
@ -313,7 +391,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_23fps_h264_fixed";
|
||||
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.
|
||||
|
|
@ -324,7 +402,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_24fps_h264_fixed";
|
||||
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.
|
||||
|
|
@ -335,39 +413,219 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
}
|
||||
String streamName = "test_29fps_h264_fixed";
|
||||
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.
|
||||
|
||||
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,
|
||||
canIncludeAdditionalVideoFormats, videoFormats);
|
||||
isWidevineEncrypted, videoMimeType, canIncludeAdditionalVideoFormats, videoFormats);
|
||||
}
|
||||
|
||||
private void testDashPlayback(HostActivity activity, String streamName,
|
||||
ActionSchedule actionSchedule, boolean fullPlaybackNoSeeking, String manifestFileName,
|
||||
String audioFormat, boolean canIncludeAdditionalVideoFormats, String... videoFormats) {
|
||||
Uri manifestUri = Uri.parse(MANIFEST_URL_PREFIX + manifestFileName);
|
||||
String audioFormat, boolean isWidevineEncrypted, String videoMimeType,
|
||||
boolean canIncludeAdditionalVideoFormats, String... videoFormats) {
|
||||
MetricsLogger metricsLogger = MetricsLogger.Factory.createDefault(getInstrumentation(), TAG,
|
||||
REPORT_NAME, streamName);
|
||||
DashHostedTest test = new DashHostedTest(streamName, manifestUri, metricsLogger,
|
||||
fullPlaybackNoSeeking, audioFormat, canIncludeAdditionalVideoFormats, false, actionSchedule,
|
||||
videoFormats);
|
||||
REPORT_NAME, REPORT_OBJECT_NAME);
|
||||
String manifestPath = MANIFEST_URL_PREFIX + manifestFileName;
|
||||
DashHostedTest test = new DashHostedTest(streamName, manifestPath, metricsLogger,
|
||||
fullPlaybackNoSeeking, audioFormat, isWidevineEncrypted, videoMimeType,
|
||||
canIncludeAdditionalVideoFormats, false, actionSchedule, videoFormats);
|
||||
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) {
|
||||
metricsLogger = MetricsLogger.Factory.createDefault(getInstrumentation(), TAG, REPORT_NAME,
|
||||
streamName + "_cdd_limited_retry");
|
||||
test = new DashHostedTest(streamName, manifestUri, metricsLogger, fullPlaybackNoSeeking,
|
||||
audioFormat, false, true, actionSchedule, videoFormats);
|
||||
REPORT_OBJECT_NAME);
|
||||
test = new DashHostedTest(streamName, manifestPath, metricsLogger, fullPlaybackNoSeeking,
|
||||
audioFormat, isWidevineEncrypted, videoMimeType, false, true, actionSchedule,
|
||||
videoFormats);
|
||||
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);
|
||||
assertNotNull(decoderInfo);
|
||||
if (decoderInfo.adaptive) {
|
||||
|
|
@ -381,34 +639,45 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
private static class DashHostedTest extends ExoHostedTest {
|
||||
|
||||
private final String streamName;
|
||||
private final Uri manifestUri;
|
||||
private final String videoMimeType;
|
||||
private final String manifestPath;
|
||||
private final MetricsLogger metricsLogger;
|
||||
private final boolean fullPlaybackNoSeeking;
|
||||
private final boolean isCddLimitedRetry;
|
||||
private final boolean isWidevineEncrypted;
|
||||
private final DashTestTrackSelector trackSelector;
|
||||
|
||||
private boolean needsCddLimitedRetry;
|
||||
private boolean needsSecureVideoDecoder;
|
||||
|
||||
/**
|
||||
* @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 fullPlaybackNoSeeking True if the test will play the entire source with no seeking.
|
||||
* False otherwise.
|
||||
* @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
|
||||
* 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 videoFormats The video formats.
|
||||
*/
|
||||
public DashHostedTest(String streamName, Uri manifestUri, MetricsLogger metricsLogger,
|
||||
boolean fullPlaybackNoSeeking, String audioFormat, boolean canIncludeAdditionalVideoFormats,
|
||||
boolean isCddLimitedRetry, ActionSchedule actionSchedule, String... videoFormats) {
|
||||
public DashHostedTest(String streamName, String manifestPath, MetricsLogger metricsLogger,
|
||||
boolean fullPlaybackNoSeeking, String audioFormat, boolean isWidevineEncrypted,
|
||||
String videoMimeType, boolean canIncludeAdditionalVideoFormats, boolean isCddLimitedRetry,
|
||||
ActionSchedule actionSchedule, String... videoFormats) {
|
||||
super(TAG, fullPlaybackNoSeeking);
|
||||
Assertions.checkArgument(!(isCddLimitedRetry && canIncludeAdditionalVideoFormats));
|
||||
this.streamName = streamName;
|
||||
this.manifestUri = manifestUri;
|
||||
this.manifestPath = manifestPath;
|
||||
this.metricsLogger = metricsLogger;
|
||||
this.fullPlaybackNoSeeking = fullPlaybackNoSeeking;
|
||||
this.isWidevineEncrypted = isWidevineEncrypted;
|
||||
this.videoMimeType = videoMimeType;
|
||||
this.isCddLimitedRetry = isCddLimitedRetry;
|
||||
trackSelector = new DashTestTrackSelector(new String[] {audioFormat},
|
||||
videoFormats, canIncludeAdditionalVideoFormats);
|
||||
if (actionSchedule != null) {
|
||||
|
|
@ -421,6 +690,37 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
return trackSelector;
|
||||
}
|
||||
|
||||
@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) {
|
||||
DataSource.Factory manifestDataSourceFactory = new DefaultDataSourceFactory(host, userAgent);
|
||||
|
|
@ -429,6 +729,10 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
bandwidthMeter);
|
||||
FormatEvaluator.Factory formatEvaluatorFactory = new AdaptiveEvaluator.Factory(
|
||||
bandwidthMeter);
|
||||
String manifestUrl = manifestPath;
|
||||
manifestUrl += isWidevineEncrypted ? (needsSecureVideoDecoder ? WIDEVINE_L1_SUFFIX
|
||||
: WIDEVINE_L3_SUFFIX) : "";
|
||||
Uri manifestUri = Uri.parse(manifestUrl);
|
||||
DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory(
|
||||
mediaDataSourceFactory, formatEvaluatorFactory);
|
||||
return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
||||
|
|
@ -438,6 +742,7 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
|||
@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,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@
|
|||
*/
|
||||
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.ExoPlayer;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
|
|
@ -22,18 +27,16 @@ import com.google.android.exoplayer2.Format;
|
|||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.audio.AudioTrack;
|
||||
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.source.MediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link HostedTest} for {@link ExoPlayer} playback tests.
|
||||
*/
|
||||
|
|
@ -120,7 +123,8 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
|
|||
public final void onStart(HostActivity host, Surface surface) {
|
||||
// Build the player.
|
||||
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.addListener(this);
|
||||
player.setDebugListener(this);
|
||||
|
|
@ -271,6 +275,11 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
|
|||
|
||||
// Internal logic
|
||||
|
||||
protected DrmSessionManager buildDrmSessionManager() {
|
||||
// Do nothing. Interested subclasses may override.
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected MappingTrackSelector buildTrackSelector(HostActivity host) {
|
||||
return new DefaultTrackSelector(null);
|
||||
|
|
@ -278,8 +287,9 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
protected SimpleExoPlayer buildExoPlayer(HostActivity host, Surface surface,
|
||||
MappingTrackSelector trackSelector) {
|
||||
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(host, trackSelector);
|
||||
MappingTrackSelector trackSelector, DrmSessionManager drmSessionManager) {
|
||||
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(host, trackSelector,
|
||||
new DefaultLoadControl(), drmSessionManager);
|
||||
player.setSurface(surface);
|
||||
return player;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@ public final class LogcatMetricsLogger implements MetricsLogger {
|
|||
Log.d(tag, key + ": " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logMetric(String key, boolean value) {
|
||||
Log.d(tag, key + ": " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// Do nothing.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public interface MetricsLogger {
|
|||
String KEY_FRAMES_SKIPPED_COUNT = "frames_skipped_count";
|
||||
String KEY_MAX_CONSECUTIVE_FRAMES_DROPPED_COUNT = "maximum_consecutive_frames_dropped_count";
|
||||
String KEY_TEST_NAME = "test_name";
|
||||
String KEY_IS_CDD_LIMITED_RETRY = "is_cdd_limited_retry";
|
||||
|
||||
/**
|
||||
* Logs an int metric provided from a test.
|
||||
|
|
@ -52,6 +53,14 @@ public interface MetricsLogger {
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue