blob: 56197fc83238e4dd62d327b8ad8aa93cf1bf70e9 [file] [log] [blame]
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* 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 android.media.cts;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaCasException;
import android.media.MediaCodecList;
import android.media.MediaCryptoException;
import android.media.MediaFormat;
import android.net.Uri;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.Surface;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MediaCodecPlayerTestBase<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
private static final String TAG = MediaCodecPlayerTestBase.class.getSimpleName();
private static final int CONNECTION_RETRIES = 10;
private static final int SLEEP_TIME_MS = 1000;
private static final long PLAY_TIME_MS = TimeUnit.MILLISECONDS.convert(25, TimeUnit.SECONDS);
protected Context mContext;
protected MediaCodecClearKeyPlayer mMediaCodecPlayer;
public MediaCodecPlayerTestBase(Class<T> clz) {
super(clz);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = getInstrumentation().getTargetContext();
}
/**
* Tests clear content playback.
*/
protected void testPlayback(
String videoMime, String[] videoFeatures,
Uri audioUrl,
Uri videoUrl,
int videoWidth, int videoHeight,
List<Surface> surfaces) throws Exception {
if (isWatchDevice()) {
return;
}
if (!preparePlayback(videoMime, videoFeatures,
audioUrl, false /* audioEncrypted */,
videoUrl, false /* videoEncrypted */, videoWidth, videoHeight,
false /* scrambled */, null /* sessionId */, surfaces)) {
return;
}
// starts video playback
playUntilEnd();
}
protected boolean isWatchDevice() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
}
protected boolean preparePlayback(String videoMime, String[] videoFeatures, Uri audioUrl,
boolean audioEncrypted, Uri videoUrl, boolean videoEncrypted, int videoWidth,
int videoHeight, boolean scrambled, byte[] sessionId, List<Surface> surfaces)
throws IOException, MediaCryptoException, MediaCasException {
if (false == playbackPreCheck(videoMime, videoFeatures, videoUrl,
videoWidth, videoHeight)) {
Log.e(TAG, "Failed playback precheck");
return false;
}
mMediaCodecPlayer = new MediaCodecClearKeyPlayer(
surfaces,
sessionId, scrambled,
mContext);
mMediaCodecPlayer.setAudioDataSource(audioUrl, null, audioEncrypted);
mMediaCodecPlayer.setVideoDataSource(videoUrl, null, videoEncrypted);
mMediaCodecPlayer.start();
mMediaCodecPlayer.prepare();
return true;
}
protected void playUntilEnd() throws InterruptedException {
mMediaCodecPlayer.startThread();
long timeOut = System.currentTimeMillis() + PLAY_TIME_MS;
while (timeOut > System.currentTimeMillis() && !mMediaCodecPlayer.isEnded()) {
Thread.sleep(SLEEP_TIME_MS);
if (mMediaCodecPlayer.getCurrentPosition() >= mMediaCodecPlayer.getDuration() ) {
Log.d(TAG, "current pos = " + mMediaCodecPlayer.getCurrentPosition() +
">= duration = " + mMediaCodecPlayer.getDuration());
break;
}
}
Log.d(TAG, "playVideo player.reset()");
mMediaCodecPlayer.reset();
}
// Verify if we can support playback resolution and has network connection.
protected boolean playbackPreCheck(String videoMime, String[] videoFeatures,
Uri videoUrl, int videoWidth, int videoHeight) {
if (!isResolutionSupported(videoMime, videoFeatures, videoWidth, videoHeight)) {
Log.i(TAG, "Device does not support " +
videoWidth + "x" + videoHeight + " resolution for " + videoMime);
return false;
}
IConnectionStatus connectionStatus = new ConnectionStatus(mContext);
if (!connectionStatus.isAvailable()) {
throw new Error("Network is not available, reason: " +
connectionStatus.getNotConnectedReason());
}
// If device is not online, recheck the status a few times.
int retries = 0;
while (!connectionStatus.isConnected()) {
if (retries++ >= CONNECTION_RETRIES) {
throw new Error("Device is not online, reason: " +
connectionStatus.getNotConnectedReason());
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
connectionStatus.testConnection(videoUrl);
return true;
}
protected boolean isResolutionSupported(String mime, String[] features,
int videoWidth, int videoHeight) {
MediaFormat format = MediaFormat.createVideoFormat(mime, videoWidth, videoHeight);
for (String feature: features) {
format.setFeatureEnabled(feature, true);
}
MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS);
if (mcl.findDecoderForFormat(format) == null) {
Log.i(TAG, "could not find codec for " + format);
return false;
}
return true;
}
}