Add Media Player Streaming Tests
Change-Id: I4bb78b0487d158f4ea57349b591f66eda6b325d2
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index 38d7e3e..86c23c7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -25,6 +25,9 @@
public class MediaNames {
// A directory to hold all kinds of media files
public static final String MEDIA_SAMPLE_POOL = "/sdcard/media_api/samples/";
+ // A file to hold all streaming URLs
+ public static final String MEDIA_STREAMING_SRC = "/sdcard/media_api/streaming.txt";
+
// Audio files
public static final String MP3CBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_CBR.mp3";
public static final String MP3VBR = "/sdcard/media_api/music/MP3_48KHz_128kbps_s_1_17_VBR.mp3";
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
index e84f762..66ed933 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
@@ -42,13 +42,13 @@
import java.util.Random;
/**
* Junit / Instrumentation test case for the media player api
-
- */
-public class CodecTest {
+
+ */
+public class CodecTest {
private static String TAG = "CodecTest";
private static MediaPlayer mMediaPlayer;
private MediaPlayer.OnPreparedListener mOnPreparedListener;
-
+
private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000; //1 min max.
private static boolean mInitialized = false;
private static boolean mPrepareReset = false;
@@ -66,18 +66,18 @@
public static int mMediaInfoNotSeekableCount = 0;
public static int mMediaInfoMetdataUpdateCount = 0;
- public static String printCpuInfo(){
+ public static String printCpuInfo(){
String cm = "dumpsys cpuinfo";
String cpuinfo =null;
int ch;
try{
Process p = Runtime.getRuntime().exec(cm);
- InputStream in = p.getInputStream();
+ InputStream in = p.getInputStream();
StringBuffer sb = new StringBuffer(512);
- while ( ( ch = in.read() ) != -1 ){
- sb.append((char) ch);
+ while ( ( ch = in.read() ) != -1 ){
+ sb.append((char) ch);
}
- cpuinfo = sb.toString();
+ cpuinfo = sb.toString();
}catch (IOException e){
Log.v(TAG, e.toString());
}
@@ -90,14 +90,14 @@
MediaPlayer mp = new MediaPlayer();
try{
mp.setDataSource(filePath);
- mp.prepare();
+ mp.prepare();
}catch (Exception e){
Log.v(TAG, e.toString());
}
int duration = mp.getDuration();
Log.v(TAG, "Duration " + duration);
mp.release();
- Log.v(TAG, "release");
+ Log.v(TAG, "release");
return duration;
}
@@ -122,7 +122,7 @@
}
currentPosition = mp.getCurrentPosition();
mp.stop();
- mp.release();
+ mp.release();
Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1));
//The currentposition should be within 10% of the sleep time
//For the very short mp3, it should return the length instead of 10 seconds
@@ -130,11 +130,11 @@
if (currentPosition < 1000 )
return true;
}
- if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
+ if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
return true;
else
return false;
- }
+ }
public static boolean seekTo(String filePath){
Log.v(TAG, "seekTo " + filePath);
@@ -149,12 +149,12 @@
currentPosition = mp.getCurrentPosition();
}catch (Exception e){
Log.v(TAG, e.getMessage());
- }
+ }
mp.stop();
mp.release();
Log.v(TAG, "CurrentPosition = " + currentPosition);
//The currentposition should be at least greater than the 80% of seek time
- if ((currentPosition > MediaNames.SEEK_TIME *0.8))
+ if ((currentPosition > MediaNames.SEEK_TIME *0.8))
return true;
else
return false;
@@ -170,7 +170,7 @@
try{
mp.setDataSource(filePath);
mp.prepare();
- duration = mp.getDuration();
+ duration = mp.getDuration();
Log.v(TAG, "setLooping duration " + duration);
mp.setLooping(true);
mp.start();
@@ -180,14 +180,14 @@
Thread.sleep(20000);
t2=SystemClock.uptimeMillis();
Log.v(TAG, "pause");
- //Bug# 1106852 - IllegalStateException will be thrown if pause is called
+ //Bug# 1106852 - IllegalStateException will be thrown if pause is called
//in here
//mp.pause();
currentPosition = mp.getCurrentPosition();
Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1));
}catch (Exception e){
Log.v(TAG, "Exception : " + e.toString());
- }
+ }
mp.stop();
mp.release();
//The current position should be within 20% of the sleep time
@@ -196,7 +196,7 @@
return true;
else
return false;
- }
+ }
public static boolean pause(String filePath) throws Exception {
Log.v(TAG, "pause - " + filePath);
@@ -206,7 +206,7 @@
long t2=0;
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(filePath);
- mp.prepare();
+ mp.prepare();
int duration = mp.getDuration();
mp.start();
t1=SystemClock.uptimeMillis();
@@ -244,7 +244,7 @@
mp.pause();
mp.release();
}
-
+
static MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener =
new MediaPlayer.OnVideoSizeChangedListener() {
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
@@ -258,7 +258,7 @@
//Register the videoSizeChanged listener
public static int videoHeight(String filePath) throws Exception {
Log.v(TAG, "videoHeight - " + filePath);
- int videoHeight = 0;
+ int videoHeight = 0;
synchronized (lock) {
initializeMessageLooper();
try {
@@ -286,7 +286,7 @@
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
-
+
return videoHeight;
}
@@ -321,12 +321,12 @@
terminateMessageLooper();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
- }
+ }
return videoWidth;
}
//This also test the streaming video which may take a long
- //time to start the playback.
+ //time to start the playback.
public static boolean videoSeekTo(String filePath) throws Exception {
Log.v(TAG, "videoSeekTo - " + filePath);
int currentPosition = 0;
@@ -392,12 +392,12 @@
currentPosition = mp.getCurrentPosition();
Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
mp.stop();
- mp.release();
+ mp.release();
Log.v(TAG, "duration = " + duration);
if (currentPosition < 0.9 * duration || isPlaying)
return false;
else
- return true;
+ return true;
}
public static boolean shortMediaStop(String filePath){
@@ -419,12 +419,12 @@
currentPosition = mp.getCurrentPosition();
Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
mp.stop();
- mp.release();
+ mp.release();
Log.v(TAG, "duration = " + duration);
if (currentPosition > duration || isPlaying)
return false;
else
- return true;
+ return true;
}
public static boolean playToEnd(String filePath){
@@ -449,13 +449,13 @@
//updateDuration = mp.getDuration();
Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
mp.stop();
- mp.release();
+ mp.release();
//Log.v(TAG, "duration = " + duration);
//Log.v(TAG, "Update duration = " + updateDuration);
if (currentPosition > duration || isPlaying)
return false;
else
- return true;
+ return true;
}
public static boolean seektoBeforeStart(String filePath){
@@ -478,7 +478,7 @@
if (currentPosition < duration/2)
return false;
else
- return true;
+ return true;
}
public static boolean mediaRecorderRecord(String filePath){
@@ -499,7 +499,7 @@
mRecorder.release();
}catch (Exception e){
Log.v(TAG, e.toString());
- }
+ }
//Verify the recorded file
MediaPlayer mp = new MediaPlayer();
@@ -540,7 +540,7 @@
}
Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1);
- //Verify the thumbnail
+ //Verify the thumbnail
Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath);
outputWidth = outThumbnail.getWidth();
outputHeight = outThumbnail.getHeight();
@@ -586,8 +586,8 @@
return false;
}
- public static boolean prepareAsyncReset(String filePath){
- //preparesAsync
+ public static boolean prepareAsyncReset(String filePath){
+ //preparesAsync
try{
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(filePath);
@@ -602,9 +602,9 @@
}
- public static boolean isLooping(String filePath) {
+ public static boolean isLooping(String filePath) {
MediaPlayer mp = null;
-
+
try {
mp = new MediaPlayer();
if (mp.isLooping()) {
@@ -619,7 +619,7 @@
Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)");
return false;
}
-
+
mp.setLooping(false);
if (mp.isLooping()) {
Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)");
@@ -659,9 +659,9 @@
return true;
}
-
+
/*
- * Initializes the message looper so that the mediaPlayer object can
+ * Initializes the message looper so that the mediaPlayer object can
* receive the callback messages.
*/
private static void initializeMessageLooper() {
@@ -672,10 +672,10 @@
// Set up a looper to be used by camera.
Looper.prepare();
Log.v(TAG, "start loopRun");
- // Save the looper so that we can terminate this thread
+ // Save the looper so that we can terminate this thread
// after we are done with it.
- mLooper = Looper.myLooper();
- mMediaPlayer = new MediaPlayer();
+ mLooper = Looper.myLooper();
+ mMediaPlayer = new MediaPlayer();
synchronized (lock) {
mInitialized = true;
lock.notify();
@@ -685,7 +685,7 @@
}
}.start();
}
-
+
/*
* Terminates the message looper thread.
*/
@@ -693,7 +693,7 @@
mLooper.quit();
mMediaPlayer.release();
}
-
+
static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
synchronized (prepareDone) {
@@ -707,14 +707,14 @@
}
}
};
-
+
public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception {
//Added the PrepareReset flag which allow us to switch to different
//test case.
if (reset){
mPrepareReset = true;
}
-
+
synchronized (lock) {
initializeMessageLooper();
try {
@@ -728,18 +728,18 @@
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
- mMediaPlayer.prepareAsync();
+ mMediaPlayer.prepareAsync();
synchronized (prepareDone) {
try {
prepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
} catch (Exception e) {
Log.v(TAG, "wait was interrupted.");
}
- }
+ }
terminateMessageLooper();
}catch (Exception e){
Log.v(TAG,e.getMessage());
- }
+ }
return onPrepareSuccess;
}
@@ -784,8 +784,12 @@
}
};
- // For each media file, forward twice and backward once, then play to the end
public static boolean playMediaSamples(String filePath) throws Exception {
+ return playMediaSamples(filePath, 2000);
+ }
+
+ // For each media file, forward twice and backward once, then play to the end
+ public static boolean playMediaSamples(String filePath, int buffertime) throws Exception {
int duration = 0;
int curPosition = 0;
int nextPosition = 0;
@@ -822,14 +826,14 @@
waittime = duration - mMediaPlayer.getCurrentPosition();
synchronized(onCompletion){
try {
- onCompletion.wait(waittime + 2000);
+ onCompletion.wait(waittime + buffertime);
}catch (Exception e) {
Log.v(TAG, "playMediaSamples are interrupted");
return false;
}
}
terminateMessageLooper();
- }catch (Exception e) {
+ } catch (Exception e) {
Log.v(TAG, "playMediaSamples:" + e.getMessage());
}
return onCompleteSuccess;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
new file mode 100644
index 0000000..d92c857
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStreamingStressTest.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 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.android.mediaframeworktest.stress;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaPlayerStressTestRunner;
+
+import android.os.Bundle;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaNames;
+import com.android.mediaframeworktest.functional.CodecTest;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Junit / Instrumentation test case for the media player
+ */
+public class MediaPlayerStreamingStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private String TAG = "MediaPlayerStreamingStressTest";
+ private String mStreamingSrc;
+
+ public MediaPlayerStreamingStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ //Insert a 2 second before launching the test activity. This is
+ //the workaround for the race condition of requesting the updated surface.
+ Thread.sleep(2000);
+ getActivity();
+ MediaPlayerStressTestRunner mRunner = (MediaPlayerStressTestRunner)getInstrumentation();
+ Bundle arguments = mRunner.getArguments();
+ mStreamingSrc = arguments.getString("streaming-source");
+ if (mStreamingSrc == null) {
+ mStreamingSrc = MediaNames.MEDIA_STREAMING_SRC;
+ }
+ super.setUp();
+ }
+
+ private int mTotalPlaybackError = 0;
+ private int mTotalComplete = 0;
+ private int mTotalInfoUnknown = 0;
+ private int mTotalVideoTrackLagging = 0;
+ private int mTotalBadInterleaving = 0;
+ private int mTotalNotSeekable = 0;
+ private int mTotalMetaDataUpdate = 0;
+
+ //Test result output file
+ private static final String PLAYBACK_RESULT = "StreamingTestResult.txt";
+
+ private void writeTestOutput(String filename, Writer output) throws Exception{
+ output.write("URL: " + filename);
+ output.write(" Complete: " + CodecTest.onCompleteSuccess);
+ output.write(" Error: " + CodecTest.mPlaybackError);
+ output.write(" Unknown Info: " + CodecTest.mMediaInfoUnknownCount);
+ output.write(" Track Lagging: " + CodecTest.mMediaInfoVideoTrackLaggingCount);
+ output.write(" Bad Interleaving: " + CodecTest.mMediaInfoBadInterleavingCount);
+ output.write(" Not Seekable: " + CodecTest.mMediaInfoNotSeekableCount);
+ output.write(" Info Meta data update: " + CodecTest.mMediaInfoMetdataUpdateCount);
+ output.write("\n");
+ }
+
+ private void writeTestSummary(Writer output) throws Exception{
+ output.write("Total Result:\n");
+ output.write("Total Complete: " + mTotalComplete + "\n");
+ output.write("Total Error: " + mTotalPlaybackError + "\n");
+ output.write("Total Unknown Info: " + mTotalInfoUnknown + "\n");
+ output.write("Total Track Lagging: " + mTotalVideoTrackLagging + "\n" );
+ output.write("Total Bad Interleaving: " + mTotalBadInterleaving + "\n");
+ output.write("Total Not Seekable: " + mTotalNotSeekable + "\n");
+ output.write("Total Info Meta data update: " + mTotalMetaDataUpdate + "\n");
+ output.write("\n");
+ }
+
+ private void updateTestResult(){
+ if (CodecTest.onCompleteSuccess){
+ mTotalComplete++;
+ }
+ else if (CodecTest.mPlaybackError){
+ mTotalPlaybackError++;
+ }
+ mTotalInfoUnknown += CodecTest.mMediaInfoUnknownCount;
+ mTotalVideoTrackLagging += CodecTest.mMediaInfoVideoTrackLaggingCount;
+ mTotalBadInterleaving += CodecTest.mMediaInfoBadInterleavingCount;
+ mTotalNotSeekable += CodecTest.mMediaInfoNotSeekableCount;
+ mTotalMetaDataUpdate += CodecTest.mMediaInfoMetdataUpdateCount;
+ }
+
+ //Test that will start the playback for all the videos
+ //under the samples folder
+ @LargeTest
+ public void testVideoPlayback() throws Exception {
+ String fileWithError = "Filename:\n";
+ File playbackOutput = new File(Environment.getExternalStorageDirectory(), PLAYBACK_RESULT);
+ Writer output = new BufferedWriter(new FileWriter(playbackOutput, true));
+
+ boolean testResult = true;
+ // load directory files
+ boolean onCompleteSuccess = false;
+
+
+ Log.i(TAG, "Streaming src file: " + mStreamingSrc);
+ //TODO: add try catch
+
+ File f = new File(mStreamingSrc);
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ List<String> urls = new ArrayList<String>();
+ String line;
+ while ((line = br.readLine()) != null) {
+ urls.add(line.trim());
+ }
+ br.close();
+ if (urls == null) {
+ Log.v("MediaPlayerStreamingTest:testVideoPlayback", "no url found");
+ return;
+ } else {
+ for (int i = 0; i < urls.size(); i++) {
+ //Get url
+ String filename = urls.get(i);
+ onCompleteSuccess =
+ CodecTest.playMediaSamples(filename, 60000);
+ if (!onCompleteSuccess){
+ //Don't fail the test right away, print out the failure file.
+ fileWithError += filename + '\n';
+ Log.v(TAG, "Failure File : " + fileWithError);
+ testResult = false;
+ }
+ Thread.sleep(3000);
+ //Write test result to an output file
+ writeTestOutput(filename,output);
+ //Get the summary
+ updateTestResult();
+ }
+ writeTestSummary(output);
+ output.close();
+ assertTrue("testMediaSamples", testResult);
+ }
+ }
+}