Home | History | Annotate | Download | only in functional
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.mediaframeworktest.functional;
     18 
     19 
     20 
     21 //import android.content.Resources;
     22 import com.android.mediaframeworktest.MediaFrameworkTest;
     23 import com.android.mediaframeworktest.MediaNames;
     24 
     25 import android.content.res.AssetFileDescriptor;
     26 import android.graphics.Bitmap;
     27 import android.graphics.BitmapFactory;
     28 import android.media.MediaCodecInfo;
     29 import android.media.MediaCodecList;
     30 import android.media.MediaExtractor;
     31 import android.media.MediaFormat;
     32 import android.media.MediaMetadataRetriever;
     33 import android.media.MediaPlayer;
     34 import android.media.MediaRecorder;
     35 import android.os.Looper;
     36 import android.os.SystemClock;
     37 import android.util.Log;
     38 
     39 import java.io.File;
     40 import java.io.FileWriter;
     41 import java.io.IOException;
     42 import java.io.InputStream;
     43 import java.io.OutputStream;
     44 import java.io.Writer;
     45 import java.io.FileOutputStream;
     46 import java.util.HashSet;
     47 import java.util.Random;
     48 import java.util.Set;
     49 /**
     50  * Junit / Instrumentation test case for the media player api
     51 
     52  */
     53 public class CodecTest {
     54     private static String TAG = "CodecTest";
     55     private static MediaPlayer mMediaPlayer;
     56     private MediaPlayer.OnPreparedListener mOnPreparedListener;
     57 
     58     private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000;  //1 min max.
     59     private static boolean mInitialized = false;
     60     private static boolean mPrepareReset = false;
     61     private static Looper mLooper = null;
     62     private static final Object lock = new Object();
     63     private static final Object prepareDone = new Object();
     64     private static final Object videoSizeChanged = new Object();
     65     private static final Object onCompletion = new Object();
     66     private static boolean onPrepareSuccess = false;
     67     public static boolean onCompleteSuccess = false;
     68     public static boolean mPlaybackError = false;
     69     public static boolean mFailedToCompleteWithNoError = true;
     70     public static int mMediaInfoUnknownCount = 0;
     71     public static int mMediaInfoVideoTrackLaggingCount = 0;
     72     public static int mMediaInfoBadInterleavingCount = 0;
     73     public static int mMediaInfoNotSeekableCount = 0;
     74     public static int mMediaInfoMetdataUpdateCount = 0;
     75     private static Set<String> mSupportedTypes = new HashSet<>();
     76 
     77     public static String printCpuInfo(){
     78         String cm = "dumpsys cpuinfo";
     79         String cpuinfo =null;
     80         int ch;
     81         try{
     82             Process  p = Runtime.getRuntime().exec(cm);
     83             InputStream in = p.getInputStream();
     84             StringBuffer sb = new StringBuffer(512);
     85             while ( ( ch = in.read() ) != -1 ){
     86                 sb.append((char) ch);
     87             }
     88             cpuinfo = sb.toString();
     89         }catch (IOException e){
     90             Log.v(TAG, e.toString());
     91         }
     92         return cpuinfo;
     93     }
     94 
     95 
     96     public static int getDuration(String filePath) {
     97         Log.v(TAG, "getDuration - " + filePath);
     98         MediaPlayer mp = new MediaPlayer();
     99         try{
    100             mp.setDataSource(filePath);
    101             mp.prepare();
    102         }catch (Exception e){
    103             Log.v(TAG, e.toString());
    104         }
    105         int duration = mp.getDuration();
    106         Log.v(TAG, "Duration " + duration);
    107         mp.release();
    108         Log.v(TAG, "release");
    109         return duration;
    110     }
    111 
    112     public static boolean getCurrentPosition(String filePath){
    113         Log.v(TAG, "GetCurrentPosition - " + filePath);
    114         int currentPosition = 0;
    115         long t1=0;
    116         long t2 =0;
    117         MediaPlayer mp = new MediaPlayer();
    118         try{
    119             mp.setDataSource(filePath);
    120             Log.v(TAG, "start playback");
    121             mp.prepare();
    122             mp.start();
    123             t1=SystemClock.uptimeMillis();
    124             Thread.sleep(10000);
    125             mp.pause();
    126             Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
    127             t2=SystemClock.uptimeMillis();
    128         }catch (Exception e){
    129             Log.v(TAG, e.toString());
    130         }
    131         currentPosition = mp.getCurrentPosition();
    132         mp.stop();
    133         mp.release();
    134         Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1));
    135         //The currentposition should be within 10% of the sleep time
    136         //For the very short mp3, it should return the length instead of 10 seconds
    137         if (filePath.equals(MediaNames.SHORTMP3)){
    138             if (currentPosition < 1000 )
    139                 return true;
    140         }
    141         if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
    142             return true;
    143         else
    144             return false;
    145     }
    146 
    147     public static boolean seekTo(String filePath){
    148         Log.v(TAG, "seekTo " + filePath);
    149         int currentPosition = 0;
    150         MediaPlayer mp = new MediaPlayer();
    151         try{
    152             mp.setDataSource(filePath);
    153             mp.prepare();
    154             mp.start();
    155             mp.seekTo(MediaNames.SEEK_TIME);
    156             Thread.sleep(MediaNames.WAIT_TIME);
    157             currentPosition = mp.getCurrentPosition();
    158         }catch (Exception e){
    159             Log.v(TAG, e.getMessage());
    160         }
    161         mp.stop();
    162         mp.release();
    163         Log.v(TAG, "CurrentPosition = " + currentPosition);
    164         //The currentposition should be at least greater than the 80% of seek time
    165         if ((currentPosition > MediaNames.SEEK_TIME *0.8))
    166             return true;
    167         else
    168             return false;
    169     }
    170 
    171     public static boolean setLooping(String filePath){
    172         int currentPosition = 0;
    173         int duration = 0;
    174         long t1 =0;
    175         long t2 =0;
    176         Log.v (TAG, "SetLooping - " + filePath);
    177         MediaPlayer mp = new MediaPlayer();
    178         try{
    179             mp.setDataSource(filePath);
    180             mp.prepare();
    181             duration = mp.getDuration();
    182             Log.v(TAG, "setLooping duration " + duration);
    183             mp.setLooping(true);
    184             mp.start();
    185             Thread.sleep(5000);
    186             mp.seekTo(duration - 5000);
    187             t1=SystemClock.uptimeMillis();
    188             Thread.sleep(20000);
    189             t2=SystemClock.uptimeMillis();
    190             Log.v(TAG, "pause");
    191             //Bug# 1106852 - IllegalStateException will be thrown if pause is called
    192             //in here
    193             //mp.pause();
    194             currentPosition = mp.getCurrentPosition();
    195             Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1));
    196         }catch (Exception e){
    197             Log.v(TAG, "Exception : " + e.toString());
    198         }
    199         mp.stop();
    200         mp.release();
    201         //The current position should be within 20% of the sleep time
    202         //and should be greater than zero.
    203         if ((currentPosition < ((t2-t1-5000)*1.2)) && currentPosition > 0)
    204             return true;
    205         else
    206             return false;
    207     }
    208 
    209     public static boolean pause(String filePath) throws Exception {
    210         Log.v(TAG, "pause - " + filePath);
    211         boolean misPlaying = true;
    212         boolean pauseResult = false;
    213         long t1=0;
    214         long t2=0;
    215         MediaPlayer mp = new MediaPlayer();
    216         mp.setDataSource(filePath);
    217         mp.prepare();
    218         int duration = mp.getDuration();
    219         mp.start();
    220         t1=SystemClock.uptimeMillis();
    221         Thread.sleep(5000);
    222         mp.pause();
    223         Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
    224         t2=SystemClock.uptimeMillis();
    225         misPlaying = mp.isPlaying();
    226         int curPosition = mp.getCurrentPosition();
    227         Log.v(TAG, filePath + " pause currentPositon " + curPosition);
    228         Log.v(TAG, "isPlaying "+ misPlaying + " wait time " + (t2 - t1) );
    229         String cpuinfo = printCpuInfo();
    230         Log.v(TAG, cpuinfo);
    231         if ((curPosition>0) && (curPosition < ((t2-t1) * 1.3)) && (misPlaying == false))
    232             pauseResult = true;
    233         mp.stop();
    234         mp.release();
    235         return pauseResult;
    236     }
    237 
    238     public static void prepareStopRelease(String filePath) throws Exception {
    239         Log.v(TAG, "prepareStopRelease" + filePath);
    240         MediaPlayer mp = new MediaPlayer();
    241         mp.setDataSource(filePath);
    242         mp.prepare();
    243         mp.stop();
    244         mp.release();
    245     }
    246 
    247     public static void preparePauseRelease(String filePath) throws Exception {
    248         Log.v(TAG, "preparePauseRelease" + filePath);
    249         MediaPlayer mp = new MediaPlayer();
    250         mp.setDataSource(filePath);
    251         mp.prepare();
    252         mp.pause();
    253         mp.release();
    254     }
    255 
    256     static MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener =
    257         new MediaPlayer.OnVideoSizeChangedListener() {
    258             public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
    259                 synchronized (videoSizeChanged) {
    260                     Log.v(TAG, "sizechanged notification received ...");
    261                     videoSizeChanged.notify();
    262                 }
    263             }
    264     };
    265 
    266     //Register the videoSizeChanged listener
    267     public static int videoHeight(String filePath) throws Exception {
    268         Log.v(TAG, "videoHeight - " + filePath);
    269         int videoHeight = 0;
    270         synchronized (lock) {
    271             initializeMessageLooper();
    272             try {
    273                 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    274             } catch(Exception e) {
    275                 Log.v(TAG, "looper was interrupted.");
    276                 return 0;
    277             }
    278         }
    279         try {
    280             mMediaPlayer.setDataSource(filePath);
    281             mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
    282             mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
    283             synchronized (videoSizeChanged) {
    284                 try {
    285                     mMediaPlayer.prepare();
    286                     mMediaPlayer.start();
    287                     videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    288                 } catch (Exception e) {
    289                     Log.v(TAG, "wait was interrupted");
    290                 }
    291             }
    292             videoHeight = mMediaPlayer.getVideoHeight();
    293             terminateMessageLooper();
    294         } catch (Exception e) {
    295             Log.e(TAG, e.getMessage());
    296         }
    297 
    298         return videoHeight;
    299     }
    300 
    301     //Register the videoSizeChanged listener
    302     public static int videoWidth(String filePath) throws Exception {
    303         Log.v(TAG, "videoWidth - " + filePath);
    304         int videoWidth = 0;
    305 
    306         synchronized (lock) {
    307             initializeMessageLooper();
    308             try {
    309                 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    310             } catch(Exception e) {
    311                 Log.v(TAG, "looper was interrupted.");
    312                 return 0;
    313             }
    314         }
    315         try {
    316             mMediaPlayer.setDataSource(filePath);
    317             mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
    318             mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
    319             synchronized (videoSizeChanged) {
    320                 try {
    321                     mMediaPlayer.prepare();
    322                     mMediaPlayer.start();
    323                     videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    324                 } catch (Exception e) {
    325                     Log.v(TAG, "wait was interrupted");
    326                 }
    327             }
    328             videoWidth = mMediaPlayer.getVideoWidth();
    329             terminateMessageLooper();
    330         } catch (Exception e) {
    331             Log.e(TAG, e.getMessage());
    332         }
    333         return videoWidth;
    334     }
    335 
    336     //This also test the streaming video which may take a long
    337     //time to start the playback.
    338     public static boolean videoSeekTo(String filePath) throws Exception {
    339         Log.v(TAG, "videoSeekTo - " + filePath);
    340         int currentPosition = 0;
    341         int duration = 0;
    342         boolean videoResult = false;
    343         MediaPlayer mp = new MediaPlayer();
    344         mp.setDataSource(filePath);
    345         mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
    346         mp.prepare();
    347         mp.start();
    348         if (filePath.equals(MediaNames.VIDEO_SHORT_3GP)){
    349             mp.pause();
    350             Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
    351             mp.seekTo(0);
    352             mp.start();
    353             Thread.sleep(1000);
    354             currentPosition = mp.getCurrentPosition();
    355             Log.v(TAG,"short position " + currentPosition);
    356             if (currentPosition > 100 )
    357                 return true;
    358             else
    359                 return false;
    360         }
    361         Thread.sleep(5000);
    362         duration = mp.getDuration();
    363         Log.v(TAG, "video duration " + duration);
    364         mp.pause();
    365         Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
    366         mp.seekTo(duration - 20000 );
    367         mp.start();
    368         Thread.sleep(1000);
    369         mp.pause();
    370         Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
    371         mp.seekTo(duration/2);
    372         mp.start();
    373         Thread.sleep(10000);
    374         currentPosition = mp.getCurrentPosition();
    375         Log.v(TAG, "video currentPosition " + currentPosition);
    376         mp.release();
    377         if (currentPosition > (duration /2 )*0.9)
    378             return true;
    379         else
    380             return false;
    381 
    382     }
    383 
    384     public static boolean seekToEnd(String filePath){
    385         Log.v(TAG, "seekToEnd - " + filePath);
    386         int duration = 0;
    387         int currentPosition = 0;
    388         boolean isPlaying = false;
    389         MediaPlayer mp = new MediaPlayer();
    390         try{
    391             mp.setDataSource(filePath);
    392             Log.v(TAG, "start playback");
    393             mp.prepare();
    394             duration = mp.getDuration();
    395             mp.seekTo(duration - 3000);
    396             mp.start();
    397             Thread.sleep(6000);
    398         }catch (Exception e){}
    399         isPlaying = mp.isPlaying();
    400         currentPosition = mp.getCurrentPosition();
    401         Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
    402         mp.stop();
    403         mp.release();
    404         Log.v(TAG, "duration = " + duration);
    405         if (currentPosition < 0.9 * duration || isPlaying)
    406             return false;
    407         else
    408             return true;
    409     }
    410 
    411     public static boolean shortMediaStop(String filePath){
    412         Log.v(TAG, "shortMediaStop - " + filePath);
    413         //This test is only for the short media file
    414         int duration = 0;
    415         int currentPosition = 0;
    416         boolean isPlaying = false;
    417         MediaPlayer mp = new MediaPlayer();
    418         try{
    419             mp.setDataSource(filePath);
    420             Log.v(TAG, "start playback");
    421             mp.prepare();
    422             duration = mp.getDuration();
    423             mp.start();
    424             Thread.sleep(10000);
    425         }catch (Exception e){}
    426         isPlaying = mp.isPlaying();
    427         currentPosition = mp.getCurrentPosition();
    428         Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
    429         mp.stop();
    430         mp.release();
    431         Log.v(TAG, "duration = " + duration);
    432         if (currentPosition > duration || isPlaying)
    433             return false;
    434         else
    435             return true;
    436     }
    437 
    438     public static boolean playToEnd(String filePath){
    439         Log.v(TAG, "shortMediaStop - " + filePath);
    440         //This test is only for the short media file
    441         int duration = 200000;
    442         int updateDuration = 0;
    443         int currentPosition = 0;
    444         boolean isPlaying = false;
    445         MediaPlayer mp = new MediaPlayer();
    446         try{
    447             Thread.sleep(5000);
    448             mp.setDataSource(filePath);
    449             Log.v(TAG, "start playback");
    450             mp.prepare();
    451             //duration = mp.getDuration();
    452             mp.start();
    453             Thread.sleep(50000);
    454         }catch (Exception e){}
    455         isPlaying = mp.isPlaying();
    456         currentPosition = mp.getCurrentPosition();
    457         //updateDuration = mp.getDuration();
    458         Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
    459         mp.stop();
    460         mp.release();
    461         //Log.v(TAG, "duration = " + duration);
    462         //Log.v(TAG, "Update duration = " + updateDuration);
    463         if (currentPosition > duration || isPlaying)
    464             return false;
    465         else
    466             return true;
    467     }
    468 
    469     public static boolean seektoBeforeStart(String filePath){
    470         Log.v(TAG, "seektoBeforeStart - " + filePath);
    471         //This test is only for the short media file
    472         int duration = 0;
    473         int currentPosition = 0;
    474 
    475         MediaPlayer mp = new MediaPlayer();
    476         try{
    477             mp.setDataSource(filePath);
    478             mp.prepare();
    479             duration = mp.getDuration();
    480             mp.seekTo(duration - 10000);
    481             mp.start();
    482             currentPosition=mp.getCurrentPosition();
    483             mp.stop();
    484             mp.release();
    485         }catch (Exception e){}
    486         if (currentPosition < duration/2)
    487             return false;
    488         else
    489             return true;
    490     }
    491 
    492     public static boolean mediaRecorderRecord(String filePath){
    493         Log.v(TAG, "SoundRecording - " + filePath);
    494         //This test is only for the short media file
    495         int duration = 0;
    496         try{
    497             MediaRecorder mRecorder = new MediaRecorder();
    498             mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    499             mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    500             mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    501             mRecorder.setOutputFile(filePath);
    502             mRecorder.prepare();
    503             mRecorder.start();
    504             Thread.sleep(500);
    505             mRecorder.stop();
    506             Log.v(TAG, "sound recorded");
    507             mRecorder.release();
    508         }catch (Exception e){
    509             Log.v(TAG, e.toString());
    510         }
    511 
    512         //Verify the recorded file
    513         MediaPlayer mp = new MediaPlayer();
    514         try{
    515             mp.setDataSource(filePath);
    516             mp.prepare();
    517             duration = mp.getDuration();
    518             Log.v(TAG,"Duration " + duration);
    519             mp.release();
    520         }catch (Exception e){}
    521         //Check the record media file length is greate than zero
    522         if (duration > 0)
    523             return true;
    524         else
    525             return false;
    526 
    527     }
    528 
    529     //Test for mediaMeta Data Thumbnail
    530     public static boolean getThumbnail(String filePath, String goldenPath){
    531         Log.v(TAG, "getThumbnail - " + filePath);
    532 
    533         int goldenHeight = 0;
    534         int goldenWidth = 0;
    535         int outputWidth = 0;
    536         int outputHeight = 0;
    537 
    538         //This test is only for the short media file
    539         try{
    540             BitmapFactory mBitmapFactory = new BitmapFactory();
    541 
    542             MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever();
    543             try {
    544                 mMediaMetadataRetriever.setDataSource(filePath);
    545             } catch(Exception e) {
    546                 e.printStackTrace();
    547                 return false;
    548             }
    549             Bitmap outThumbnail = mMediaMetadataRetriever.getFrameAtTime(-1);
    550 
    551             //Verify the thumbnail
    552             Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath);
    553             outputWidth = outThumbnail.getWidth();
    554             outputHeight = outThumbnail.getHeight();
    555             goldenHeight = goldenBitmap.getHeight();
    556             goldenWidth = goldenBitmap.getWidth();
    557 
    558             //check the image dimension
    559             if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight))
    560                 return false;
    561 
    562             // Check half line of pixel
    563             int x = goldenHeight / 2;
    564             for (int j = 1; j < goldenWidth / 2; j++) {
    565                 if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)) {
    566                     Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j));
    567                     return false;
    568                 }
    569            }
    570         }catch (Exception e){
    571             Log.v(TAG, e.toString());
    572             return false;
    573         }
    574         return true;
    575     }
    576 
    577     //Load midi file from resources
    578     public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration){
    579         int duration = 0;
    580         try{
    581             MediaPlayer mp = new MediaPlayer();
    582             mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
    583             mp.prepare();
    584             mp.start();
    585             duration = mp.getDuration();
    586             Thread.sleep(5000);
    587             mp.release();
    588         }catch (Exception e){
    589             Log.v(TAG,e.getMessage());
    590         }
    591         if (duration > expectedDuration)
    592             return true;
    593         else
    594             return false;
    595     }
    596 
    597     public static boolean prepareAsyncReset(String filePath){
    598         //preparesAsync
    599         try{
    600             MediaPlayer mp = new MediaPlayer();
    601             mp.setDataSource(filePath);
    602             mp.prepareAsync();
    603             mp.reset();
    604             mp.release();
    605         }catch (Exception e){
    606             Log.v(TAG,e.getMessage());
    607             return false;
    608         }
    609         return true;
    610     }
    611 
    612 
    613     public static boolean isLooping(String filePath) {
    614         MediaPlayer mp = null;
    615 
    616         try {
    617             mp = new MediaPlayer();
    618             if (mp.isLooping()) {
    619                 Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor");
    620                 return false;
    621             }
    622             mp.setDataSource(filePath);
    623             mp.prepare();
    624 
    625             mp.setLooping(true);
    626             if (!mp.isLooping()) {
    627                 Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)");
    628                 return false;
    629             }
    630 
    631             mp.setLooping(false);
    632             if (mp.isLooping()) {
    633                 Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)");
    634                 return false;
    635             }
    636         }catch (Exception e){
    637             Log.v(TAG, "Exception : " + e.toString());
    638             return false;
    639         } finally {
    640             if (mp != null)
    641                 mp.release();
    642         }
    643 
    644         return true;
    645     }
    646 
    647     public static boolean isLoopingAfterReset(String filePath) {
    648         MediaPlayer mp = null;
    649         try {
    650             mp = new MediaPlayer();
    651             mp.setDataSource(filePath);
    652             mp.prepare();
    653 
    654             mp.setLooping(true);
    655             mp.reset();
    656             if (mp.isLooping()) {
    657                 Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()");
    658                 return false;
    659             }
    660         }catch (Exception e){
    661             Log.v(TAG, "Exception : " + e.toString());
    662             return false;
    663         } finally {
    664             if (mp != null)
    665                 mp.release();
    666         }
    667 
    668         return true;
    669     }
    670 
    671     /*
    672      * Initializes the message looper so that the mediaPlayer object can
    673      * receive the callback messages.
    674      */
    675     private static void initializeMessageLooper() {
    676         Log.v(TAG, "start looper");
    677         new Thread() {
    678             @Override
    679             public void run() {
    680                 // Set up a looper to be used by camera.
    681                 Looper.prepare();
    682                 Log.v(TAG, "start loopRun");
    683                 // Save the looper so that we can terminate this thread
    684                 // after we are done with it.
    685                 mLooper = Looper.myLooper();
    686                 mMediaPlayer = new MediaPlayer();
    687                 synchronized (lock) {
    688                     mInitialized = true;
    689                     lock.notify();
    690                 }
    691                 Looper.loop();  // Blocks forever until Looper.quit() is called.
    692                 Log.v(TAG, "initializeMessageLooper: quit.");
    693             }
    694         }.start();
    695     }
    696 
    697     /*
    698      * Terminates the message looper thread.
    699      */
    700     private static void terminateMessageLooper() {
    701         mLooper.quit();
    702         mMediaPlayer.release();
    703     }
    704 
    705     static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
    706         public void onPrepared(MediaPlayer mp) {
    707             synchronized (prepareDone) {
    708                 if(mPrepareReset){
    709                     Log.v(TAG, "call Reset");
    710                     mMediaPlayer.reset();
    711                 }
    712                 Log.v(TAG, "notify the prepare callback");
    713                 prepareDone.notify();
    714                 onPrepareSuccess = true;
    715             }
    716         }
    717     };
    718 
    719     public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception {
    720         //Added the PrepareReset flag which allow us to switch to different
    721         //test case.
    722         if (reset){
    723             mPrepareReset = true;
    724         }
    725 
    726         synchronized (lock) {
    727             initializeMessageLooper();
    728             try {
    729                 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    730             } catch(Exception e) {
    731                 Log.v(TAG, "looper was interrupted.");
    732                 return false;
    733             }
    734         }
    735         try{
    736             mMediaPlayer.setOnPreparedListener(mPreparedListener);
    737             mMediaPlayer.setDataSource(filePath);
    738             mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
    739             mMediaPlayer.prepareAsync();
    740             synchronized (prepareDone) {
    741                 try {
    742                     prepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    743                 } catch (Exception e) {
    744                     Log.v(TAG, "wait was interrupted.");
    745                 }
    746             }
    747             terminateMessageLooper();
    748         }catch (Exception e){
    749             Log.v(TAG,e.getMessage());
    750         }
    751        return onPrepareSuccess;
    752     }
    753 
    754     static MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
    755         public void onCompletion(MediaPlayer mp) {
    756             synchronized (onCompletion) {
    757                 Log.v(TAG, "notify the completion callback");
    758                 onCompletion.notify();
    759                 onCompleteSuccess = true;
    760             }
    761         }
    762     };
    763 
    764     static MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
    765         public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
    766             mPlaybackError = true;
    767             mp.reset();
    768             return true;
    769         }
    770     };
    771 
    772     static MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() {
    773         public boolean onInfo(MediaPlayer mp, int what, int extra) {
    774             switch (what){
    775                 case MediaPlayer.MEDIA_INFO_UNKNOWN:
    776                     mMediaInfoUnknownCount++;
    777                     break;
    778                 case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
    779                     mMediaInfoVideoTrackLaggingCount++;
    780                     break;
    781                 case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
    782                     mMediaInfoBadInterleavingCount++;
    783                     break;
    784                 case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
    785                     mMediaInfoNotSeekableCount++;
    786                     break;
    787                 case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
    788                     mMediaInfoMetdataUpdateCount++;
    789                     break;
    790             }
    791             return true;
    792         }
    793     };
    794 
    795     public static boolean playMediaSamples(String filePath) throws Exception {
    796         return playMediaSamples(filePath, 2000, false /* streamingTest */);
    797     }
    798 
    799     // For each media file, just play to the end
    800     public static boolean playMediaSamples(String filePath, int buffertime, boolean streamingTest)
    801             throws Exception {
    802         int duration = 0;
    803         int curPosition = 0;
    804         int nextPosition = 0;
    805         int waittime = 0;
    806         onCompleteSuccess = false;
    807         mMediaInfoUnknownCount = 0;
    808         mMediaInfoVideoTrackLaggingCount = 0;
    809         mMediaInfoBadInterleavingCount = 0;
    810         mMediaInfoNotSeekableCount = 0;
    811         mMediaInfoMetdataUpdateCount = 0;
    812         mPlaybackError = false;
    813         mFailedToCompleteWithNoError = true;
    814         String testResult;
    815 
    816         boolean hasSupportedVideo = false;
    817 
    818         if (!streamingTest) {
    819             if (mSupportedTypes.isEmpty()) {
    820                 final MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
    821                 for (MediaCodecInfo info : list.getCodecInfos()) {
    822                     for (String type : info.getSupportedTypes()) {
    823                         mSupportedTypes.add(type);
    824                     }
    825                 }
    826             }
    827             final MediaExtractor extractor = new MediaExtractor();
    828 
    829             try {
    830                 extractor.setDataSource(filePath);
    831 
    832                 for (int index = 0; index < extractor.getTrackCount(); ++index) {
    833                     MediaFormat format = extractor.getTrackFormat(index);
    834                     String type = format.getString(MediaFormat.KEY_MIME);
    835                     if (!type.startsWith("video/")) {
    836                         continue;
    837                     }
    838 
    839                     if (mSupportedTypes.contains(type)) {
    840                         hasSupportedVideo = true;
    841                         break;
    842                     }
    843                 }
    844             } finally {
    845                 extractor.release();
    846             }
    847         } else { // streamingTest
    848             hasSupportedVideo = true;
    849         }
    850 
    851         initializeMessageLooper();
    852         synchronized (lock) {
    853             try {
    854                 lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
    855             } catch(Exception e) {
    856                 Log.v(TAG, "looper was interrupted.");
    857                 return false;
    858             }
    859         }
    860         try {
    861             mMediaPlayer.setOnCompletionListener(mCompletionListener);
    862             mMediaPlayer.setOnErrorListener(mOnErrorListener);
    863             mMediaPlayer.setOnInfoListener(mInfoListener);
    864             Log.v(TAG, "playMediaSamples: sample file name " + filePath);
    865             mMediaPlayer.setDataSource(filePath);
    866             if (hasSupportedVideo) {
    867                 mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
    868             } else {
    869                 Log.i(TAG, "Set no display due to no (supported) video track.");
    870                 mMediaPlayer.setDisplay(null);
    871             }
    872             mMediaPlayer.prepare();
    873             duration = mMediaPlayer.getDuration();
    874             // start to play
    875             mMediaPlayer.start();
    876             if (duration < 0) {
    877                 Log.w(TAG, filePath + " has unknown duration, waiting until playback completes");
    878                 while (mMediaPlayer.isPlaying()) {
    879                     SystemClock.sleep(1000);
    880                 }
    881             } else {
    882                 waittime = duration - mMediaPlayer.getCurrentPosition();
    883                 synchronized(onCompletion){
    884                     try {
    885                         onCompletion.wait(waittime + buffertime);
    886                     } catch (Exception e) {
    887                         Log.v(TAG, "playMediaSamples are interrupted");
    888                         return false;
    889                     }
    890                 }
    891             }
    892             terminateMessageLooper();
    893         } catch (Exception e) {
    894             Log.v(TAG, "playMediaSamples:" + e.getMessage());
    895         }
    896         // Check if playback state is unknown (neither completed nor erroneous) unless
    897         // it's not interrupted in the middle. If true, that is an exceptional case to investigate.
    898         mFailedToCompleteWithNoError = !(onCompleteSuccess || mPlaybackError);
    899         return onCompleteSuccess;
    900     }
    901 }
    902