diff options
author | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2011-10-21 16:23:12 +0159 |
---|---|---|
committer | Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org> | 2011-10-21 16:23:12 +0159 |
commit | be09a8100c7479ca6e416638d49fbf317d680be0 (patch) | |
tree | 9eec5187b15b9efd1a9ea6992d91f007ae0384cc | |
parent | 7caaadf7a48c0322693f226d7a78b78f853d51c0 (diff) | |
download | mmtest-be09a8100c7479ca6e416638d49fbf317d680be0.tar.gz |
mmtest: Various improvements
This adds encoding (by calling ffmpeg), a status display,
sample content to be encoded/played, and a few fixes.
Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | assets/big_buck_bunny_1080p_H264_AAC_25fps_7200K_short.mp4 | bin | 0 -> 3714474 bytes | |||
-rw-r--r-- | res/layout/main.xml | 12 | ||||
-rw-r--r-- | src/org/linaro/mmtest/MultimediaTest.java | 154 |
4 files changed, 139 insertions, 28 deletions
@@ -3,6 +3,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-subdir-java-files) +LOCAL_ASSET_FILES := $(call find-subdir-assets assets) LOCAL_PACKAGE_NAME := mmtest LOCAL_CERTIFICATE := shared diff --git a/assets/big_buck_bunny_1080p_H264_AAC_25fps_7200K_short.mp4 b/assets/big_buck_bunny_1080p_H264_AAC_25fps_7200K_short.mp4 Binary files differnew file mode 100644 index 0000000..c724dba --- /dev/null +++ b/assets/big_buck_bunny_1080p_H264_AAC_25fps_7200K_short.mp4 diff --git a/res/layout/main.xml b/res/layout/main.xml new file mode 100644 index 0000000..e270712 --- /dev/null +++ b/res/layout/main.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + <EditText android:id="@+id/status" + android:layout_width="fill_parent" + android:layout_height="wrap_content"/> + <SurfaceView android:id="@+id/surface_view" + android:layout_width="fill_parent" + android:layout_height="fill_parent"/> +</LinearLayout> diff --git a/src/org/linaro/mmtest/MultimediaTest.java b/src/org/linaro/mmtest/MultimediaTest.java index 3dcb750..57587a9 100644 --- a/src/org/linaro/mmtest/MultimediaTest.java +++ b/src/org/linaro/mmtest/MultimediaTest.java @@ -11,13 +11,23 @@ import android.media.MediaPlayer.OnCompletionListener; import android.os.Process; import android.view.SurfaceView; import android.app.AlertDialog; +import android.content.res.AssetManager; +import android.content.Context; +import android.widget.EditText; import java.io.RandomAccessFile; +import java.io.InputStream; +import java.io.FileOutputStream; +import java.io.File; import java.lang.Math; +import java.lang.Runtime; import java.util.List; public class MultimediaTest extends Activity implements android.media.MediaPlayer.OnCompletionListener,android.media.MediaPlayer.OnErrorListener,android.media.MediaPlayer.OnInfoListener { + private EditText status; + private SurfaceView surfaceView; private static final String TAG = "MultimediaTest"; + private int currentEncodingTest = -1; private int currentTest = -1; private boolean ranAnyTest = false; private MediaPlayer mp; @@ -27,73 +37,140 @@ public class MultimediaTest extends Activity implements android.media.MediaPlaye private int expectedDuration; private final Test[] tests = { // Audio Codecs - new Test("test-AAC-Stereo-96k.m4a", "AAC Stereo 96k", false), - new Test("test-AAC-Mono-8k.m4a", "AAC Mono 8k", false), - new Test("test-AMR-NB.3gp", "AMR-NB", false), - new Test("test-flac.flac", "FLAC", false, 12 /*android.os.Build.HONEYCOMB_MR1*/), - new Test("test-MP3.mp3", "MP3", false), - new Test("test-Vorbis.ogg", "Ogg Vorbis", false), - new Test("test-PCM8.wav", "PCM 8-Bit", false), - new Test("test-PCM16.wav", "PCM 16-Bit", false), + new Test("test-AAC-Stereo-96k.m4a", "AAC Stereo 96k", "-vn -acodec aac -strict experimental -ab 160k -ar 48000 -ac 2", false), + new Test("test-AAC-Mono-8k.m4a", "AAC Mono 8k", "-vn -acodec aac -strict experimental -ab 32k -ar 8000 -ac 1", false), + // AMR disabled because of licensing issues + // new Test("test-AMR-NB.3gp", "AMR-NB", "", false), + new Test("test-flac.flac", "FLAC", "-vn -acodec flac -ac 2 -ar 44100", false, 12 /*android.os.Build.HONEYCOMB_MR1*/), + new Test("test-MP3.mp3", "MP3", "-vn -acodec libmp3lame -ab 64k", false), + new Test("test-Vorbis.ogg", "Ogg Vorbis", "-vn -acodec libvorbis -f ogg -ab 64k", false), + // no ffmpegParameters specified for the wav files because ffmpeg can't create those + // A way to create them could be e.g. + // mplayer $IN -benchmark -vc null -vo null -ao pcm:fast:waveheader:file=test-PCM.wav + // sox -S test-PCM.wav -b 8 test-PCM8.wav + // sox -S test-PCM.wav -b 16 test-PCM16.wav + // But mplayer and sox are not (yet) available on Android, so we limit this to pre-existing files + new Test("test-PCM8.wav", "PCM 8-Bit", "", false), + new Test("test-PCM16.wav", "PCM 16-Bit", "", false), // Video Codecs - new Test("test-H.263.3gp", "H.263"), - new Test("test-H.264.m4v", "H.264"), - new Test("test-MPEG4_SP.mp4", "MPEG-4 SP"), - new Test("test-VP8.webm", "VP8"), + new Test("test-H.263.3gp", "H.263", "-vcodec h263 -s cif -r 25 -vb 768000 -an -f 3gp"), + new Test("test-H.264.m4v", "H.264", "-vcodec libx264 -vb 1024000 -vpre libx264-baseline -an -f mp4"), + new Test("test-MPEG4_SP.mp4", "MPEG-4 SP", "-vcodec mpeg4 -vb 768000 -an -f mp4"), + new Test("test-VP8.webm", "VP8", "-vcodec libvpx -vb 768000 -an -f webm"), // Mixed A/V - new Test("test-H.263-AAC.3gp", "3GP(H.263/AAC)"), - new Test("test-H.264-AAC.mp4", "MP4(H.264/AAC)"), - new Test("test-H.264-AAC-HD.mp4", "HD-MP4(H.264/AAC)"), - new Test("test-MPEG4-MP3.mp4", "MP4(MPEG4/MP3)"), - new Test("test-VP8-Vorbis.webm", "WebM(VP8/Vorbis)", true, 10 /*android.os.Build.GINGERBREAD_MR1*/) + new Test("test-H.263-AAC.3gp", "3GP(H.263/AAC)", "-vcodec h263 -s cif -r 25 -vb 768000 -acodec libfaac -ac 1 -ar 8000 -ab 32000 -f 3gp"), + new Test("test-H.264-AAC.mp4", "MP4(H.264/AAC)", "-vcodec libx264 -vb 1024000 -vpre libx264-baseline -acodec aac -strict experimental -ab 96000 -f mp4"), + new Test("test-H.264-AAC-HD.mp4", "HD-MP4(H.264/AAC)", "-s hd1080 -vcodec libx264 -vb 2048000 -vpre libx264-baseline -acodec aac -strict experimental -ab 96000 -f mp4"), + new Test("test-MPEG4-MP3.mp4", "MP4(MPEG4/MP3)", "-vcodec mpeg4 -vb 768000 -acodec libmp3lame -ab 64000 -f mp4"), + new Test("test-VP8-Vorbis.webm", "WebM(VP8/Vorbis)", "-vcodec libvpx -vb 1024000 -vpre libvpx-360p -f webm -acodec libvorbis -ab 48000", true, 10 /*android.os.Build.GINGERBREAD_MR1*/) }; class Test { public String filename; public String name; + public String ffmpegParameters; public boolean hasVideo; public int minVersion; - public Test(String pFilename, String pName, boolean pHasVideo, int pMinVersion) { + public Test(String pFilename, String pName, String pFfmpeg, boolean pHasVideo, int pMinVersion) { filename = pFilename; name = pName; + ffmpegParameters = pFfmpeg; hasVideo = pHasVideo; minVersion = pMinVersion; } - public Test(String pFilename, String pName, boolean pHasVideo) { - this(pFilename, pName, pHasVideo, 0); + public Test(String pFilename, String pName, String pFfmpeg, boolean pHasVideo) { + this(pFilename, pName, pFfmpeg, pHasVideo, 0); + } + + public Test(String pFilename, String pName, String pFfmpeg) { + this(pFilename, pName, pFfmpeg, true, 0); } public Test(String pFilename, String pName) { - this(pFilename, pName, true, 0); + this(pFilename, pName, "", true, 0); } } + public void status(String s) { + Log.v(TAG, s); + status.setText(s); + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Log.v(TAG, "Starting tests"); + setContentView(R.layout.main); + status = (EditText) findViewById(R.id.status); + surfaceView = (SurfaceView) findViewById(R.id.surface_view); + + status("Extracting sample video from assets"); + if(!copySampleToFilesystem()) { + status("FAILED copying sample video from assets"); + AlertDialog dlg=new AlertDialog.Builder(this).setTitle("Error").setMessage("An error occurred while trying to extract the sample video from assets").create(); + dlg.show(); + finish(); + } - SurfaceView sv=new SurfaceView(this); - setContentView(sv); + status("Starting encoding tests"); + status("Starting playback tests"); mp=new MediaPlayer(); mp.setOnCompletionListener(this); mp.setOnErrorListener(this); mp.setOnInfoListener(this); mp.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC); - mp.setDisplay(sv.getHolder()); + mp.setDisplay(surfaceView.getHolder()); runNextTest(); } public void runNextTest() { failure = ""; + if(++currentEncodingTest <= tests.length) { + Test t=tests[currentEncodingTest]; + status("Running encoding test: " + t.name); + if(t.ffmpegParameters.length() == 0) { + status("skipped, no encoder available"); + runNextTest(); + return; + } + Runtime rt = Runtime.getRuntime(); + try { + timestamp = System.currentTimeMillis(); + String[] codecArgs = t.ffmpegParameters.split(" "); + String[] ffmpegArgs = new String[codecArgs.length+5]; + ffmpegArgs[0] = "/system/bin/ffmpeg"; + ffmpegArgs[1] = "-y"; + ffmpegArgs[2] = "-i"; + ffmpegArgs[3] = getFilesDir().toString() + "/test-H.264-AAC-HD.mp4"; + System.arraycopy(codecArgs, 0, ffmpegArgs, 4, codecArgs.length); + ffmpegArgs[4+codecArgs.length] = getFilesDir().toString() + "/" + t.filename; + java.lang.Process ffmpeg = rt.exec(ffmpegArgs); + // FIXME parse ffmpeg output instead of discarding it + ffmpeg.getErrorStream().close(); + ffmpeg.getOutputStream().close(); + ffmpeg.getInputStream().close(); + ffmpeg.waitFor(); + long elapsedTime = System.currentTimeMillis() - timestamp; + File f = new File(getFilesDir().toString() + "/" + t.filename); + if(f.exists()) + Log.i(TAG, "PASS:" + t.name + ":encode"); + else + Log.i(TAG, "FAIL:" + t.name + ":encode"); + f = null; + Log.i(TAG, "PERF:Enc" + t.name + ":" + Long.toString(elapsedTime) + " ms"); + } catch(Throwable e) { + status("FAILED: " + e.getMessage()); + } + runNextTest(); + return; + } if(++currentTest > tests.length) { - Log.v(TAG, "Tests completed"); + status("Tests completed"); if(!ranAnyTest) { AlertDialog dlg=new AlertDialog.Builder(this).setTitle("Files not found").setMessage("Multimedia files to be tested could not be found on the SD card. Please put the files (generated by the creator script) into the /mmtest directory of the SD card and try again.").create(); dlg.show(); @@ -106,7 +183,7 @@ public class MultimediaTest extends Activity implements android.media.MediaPlaye runNextTest(); return; } - Log.v(TAG, "Running test " + t.name); + status("Running playback test " + t.name); mp.reset(); try { mp.setDataSource("/sdcard/mmtest/" + t.filename); @@ -144,7 +221,7 @@ public class MultimediaTest extends Activity implements android.media.MediaPlaye // an educated guess on whether or not a codec is hardware // accelerated. // Will require some testing on different hardware... - Log.i(TAG, "PERF:" + tests[currentTest].name + Long.toString(elapsedCpuTime) + " jiffies used"); + Log.i(TAG, "PERF:" + tests[currentTest].name + ":" + Long.toString(elapsedCpuTime) + " jiffies used"); runNextTest(); } @@ -178,4 +255,25 @@ public class MultimediaTest extends Activity implements android.media.MediaPlaye } return usedTime; } + + public boolean copySampleToFilesystem() { + try { + AssetManager a = getAssets(); + FileOutputStream out = openFileOutput("test-H.264-AAC-HD.mp4", Context.MODE_WORLD_READABLE); + InputStream in = a.open("big_buck_bunny_1080p_H264_AAC_25fps_7200K_short.mp4"); + byte[] buf = new byte[8192]; + int len; + while((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + return true; + } catch(java.io.FileNotFoundException e) { + Log.e(TAG, "ERR:Can't read sample video from assets:" + e.getMessage()); + } catch(java.io.IOException e) { + Log.e(TAG, "ERR:Can't copy sample video from assets:" + e.getMessage()); + } + return false; + } } |