CodecTest.java revision c1b80cb7e30102b304d62beb9649f84c798e00e9
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
17package com.android.mediaframeworktest.functional;
18
19
20
21//import android.content.Resources;
22import com.android.mediaframeworktest.MediaFrameworkTest;
23import com.android.mediaframeworktest.MediaNames;
24
25import android.content.res.AssetFileDescriptor;
26import android.graphics.Bitmap;
27import android.graphics.BitmapFactory;
28import android.media.MediaMetadataRetriever;
29import android.media.MediaPlayer;
30import android.media.MediaRecorder;
31import android.os.Looper;
32import android.os.SystemClock;
33import android.util.Log;
34
35import java.io.IOException;
36import java.io.InputStream;
37/**
38 * Junit / Instrumentation test case for the media player api
39
40 */
41public class CodecTest {
42    private static String TAG = "MediaPlayerApiTest";
43    private static MediaPlayer mMediaPlayer;
44    private MediaPlayer.OnPreparedListener mOnPreparedListener;
45
46    private static int WAIT_FOR_COMMAND_TO_COMPLETE = 60000;  //1 min max.
47    private static boolean mInitialized = false;
48    private static boolean mPrepareReset = false;
49    private static Looper mLooper = null;
50    private static final Object lock = new Object();
51    private static final Object prepareDone = new Object();
52    private static final Object videoSizeChanged = new Object();
53    private static boolean onPrepareSuccess = false;
54
55
56    public static String printCpuInfo(){
57        String cm = "dumpsys cpuinfo";
58        String cpuinfo =null;
59        int ch;
60        try{
61            Process  p = Runtime.getRuntime().exec(cm);
62            InputStream in = p.getInputStream();
63            StringBuffer sb = new StringBuffer(512);
64            while ( ( ch = in.read() ) != -1 ){
65                sb.append((char) ch);
66            }
67            cpuinfo = sb.toString();
68        }catch (IOException e){
69            Log.v(TAG, e.toString());
70        }
71        return cpuinfo;
72    }
73
74
75    public static int getDuration(String filePath) {
76        Log.v(TAG, "getDuration - " + filePath);
77        MediaPlayer mp = new MediaPlayer();
78        try{
79            mp.setDataSource(filePath);
80            mp.prepare();
81        }catch (Exception e){}
82        int duration = mp.getDuration();
83        Log.v(TAG, "Duration " + duration);
84        mp.release();
85        Log.v(TAG, "release");
86        return duration;
87    }
88
89    public static boolean getCurrentPosition(String filePath){
90        Log.v(TAG, "GetCurrentPosition - " + filePath);
91        int currentPosition = 0;
92        long t1=0;
93        long t2 =0;
94        MediaPlayer mp = new MediaPlayer();
95        try{
96            mp.setDataSource(filePath);
97            Log.v(TAG, "start playback");
98            mp.prepare();
99            mp.start();
100            t1=SystemClock.uptimeMillis();
101            Thread.sleep(10000);
102            mp.pause();
103            Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
104            t2=SystemClock.uptimeMillis();
105        }catch (Exception e){
106            Log.v(TAG, e.toString());
107        }
108        currentPosition = mp.getCurrentPosition();
109        mp.stop();
110        mp.release();
111        Log.v(TAG, "mp currentPositon = " + currentPosition + " play duration = " + (t2-t1));
112        //The currentposition should be within 10% of the sleep time
113        //For the very short mp3, it should return the length instead of 10 seconds
114        if (filePath.equals(MediaNames.SHORTMP3)){
115            if (currentPosition < 1000 )
116                return true;
117        }
118        if ((currentPosition < ((t2-t1) *1.2)) && (currentPosition > 0))
119            return true;
120        else
121            return false;
122    }
123
124    public static boolean seekTo(String filePath){
125        Log.v(TAG, "seekTo " + filePath);
126        int currentPosition = 0;
127        MediaPlayer mp = new MediaPlayer();
128        try{
129            mp.setDataSource(filePath);
130            mp.prepare();
131            mp.start();
132            mp.seekTo(MediaNames.SEEK_TIME);
133            Thread.sleep(MediaNames.WAIT_TIME);
134            currentPosition = mp.getCurrentPosition();
135        }catch (Exception e){
136            Log.v(TAG, e.getMessage());
137        }
138        mp.stop();
139        mp.release();
140        Log.v(TAG, "CurrentPosition = " + currentPosition);
141        //The currentposition should be at least greater than the 80% of seek time
142        if ((currentPosition > MediaNames.SEEK_TIME *0.8))
143            return true;
144        else
145            return false;
146    }
147
148    public static boolean setLooping(String filePath){
149        int currentPosition = 0;
150        int duration = 0;
151        long t1 =0;
152        long t2 =0;
153        Log.v (TAG, "SetLooping - " + filePath);
154        MediaPlayer mp = new MediaPlayer();
155        try{
156            mp.setDataSource(filePath);
157            mp.prepare();
158            duration = mp.getDuration();
159            Log.v(TAG, "setLooping duration " + duration);
160            mp.setLooping(true);
161            mp.start();
162            Thread.sleep(5000);
163            mp.seekTo(duration - 5000);
164            t1=SystemClock.uptimeMillis();
165            Thread.sleep(20000);
166            t2=SystemClock.uptimeMillis();
167            Log.v(TAG, "pause");
168            //Bug# 1106852 - IllegalStateException will be thrown if pause is called
169            //in here
170            //mp.pause();
171            currentPosition = mp.getCurrentPosition();
172            Log.v(TAG, "looping position " + currentPosition + "duration = " + (t2-t1));
173        }catch (Exception e){
174            Log.v(TAG, "Exception : " + e.toString());
175        }
176        mp.stop();
177        mp.release();
178        //The current position should be within 20% of the sleep time
179        //and should be greater than zero.
180        if ((currentPosition < ((t2-t1-5000)*1.2)) && currentPosition > 0)
181            return true;
182        else
183            return false;
184    }
185
186    public static boolean pause(String filePath) throws Exception {
187        Log.v(TAG, "pause - " + filePath);
188        boolean misPlaying = true;
189        boolean pauseResult = false;
190        long t1=0;
191        long t2=0;
192        MediaPlayer mp = new MediaPlayer();
193        mp.setDataSource(filePath);
194        mp.prepare();
195        int duration = mp.getDuration();
196        mp.start();
197        t1=SystemClock.uptimeMillis();
198        Thread.sleep(5000);
199        mp.pause();
200        Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
201        t2=SystemClock.uptimeMillis();
202        misPlaying = mp.isPlaying();
203        int curPosition = mp.getCurrentPosition();
204        Log.v(TAG, filePath + " pause currentPositon " + curPosition);
205        Log.v(TAG, "isPlaying "+ misPlaying + " wait time " + (t2 - t1) );
206        String cpuinfo = printCpuInfo();
207        Log.v(TAG, cpuinfo);
208        if ((curPosition>0) && (curPosition < ((t2-t1) * 1.3)) && (misPlaying == false))
209            pauseResult = true;
210        mp.stop();
211        mp.release();
212        return pauseResult;
213    }
214
215    public static void prepareStopRelease(String filePath) throws Exception {
216        Log.v(TAG, "prepareStopRelease" + filePath);
217        MediaPlayer mp = new MediaPlayer();
218        mp.setDataSource(filePath);
219        mp.prepare();
220        mp.stop();
221        mp.release();
222    }
223
224    public static void preparePauseRelease(String filePath) throws Exception {
225        Log.v(TAG, "preparePauseRelease" + filePath);
226        MediaPlayer mp = new MediaPlayer();
227        mp.setDataSource(filePath);
228        mp.prepare();
229        mp.pause();
230        mp.release();
231    }
232
233    static MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener =
234        new MediaPlayer.OnVideoSizeChangedListener() {
235            public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
236                synchronized (videoSizeChanged) {
237                    Log.v(TAG, "sizechanged notification received ...");
238                    videoSizeChanged.notify();
239                }
240            }
241    };
242
243    //Register the videoSizeChanged listener
244    public static int videoHeight(String filePath) throws Exception {
245        Log.v(TAG, "videoHeight - " + filePath);
246        int videoHeight = 0;
247        synchronized (lock) {
248            initializeMessageLooper();
249            try {
250                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
251            } catch(Exception e) {
252                Log.v(TAG, "looper was interrupted.");
253                return 0;
254            }
255        }
256        try {
257            mMediaPlayer.setDataSource(filePath);
258            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
259            mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
260            synchronized (videoSizeChanged) {
261                try {
262                    mMediaPlayer.prepare();
263                    mMediaPlayer.start();
264                    videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
265                } catch (Exception e) {
266                    Log.v(TAG, "wait was interrupted");
267                }
268            }
269            videoHeight = mMediaPlayer.getVideoHeight();
270            terminateMessageLooper();
271        } catch (Exception e) {
272            Log.e(TAG, e.getMessage());
273        }
274
275        return videoHeight;
276    }
277
278    //Register the videoSizeChanged listener
279    public static int videoWidth(String filePath) throws Exception {
280        Log.v(TAG, "videoWidth - " + filePath);
281        int videoWidth = 0;
282
283        synchronized (lock) {
284            initializeMessageLooper();
285            try {
286                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
287            } catch(Exception e) {
288                Log.v(TAG, "looper was interrupted.");
289                return 0;
290            }
291        }
292        try {
293            mMediaPlayer.setDataSource(filePath);
294            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
295            mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
296            synchronized (videoSizeChanged) {
297                try {
298                    mMediaPlayer.prepare();
299                    mMediaPlayer.start();
300                    videoSizeChanged.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
301                } catch (Exception e) {
302                    Log.v(TAG, "wait was interrupted");
303                }
304            }
305            videoWidth = mMediaPlayer.getVideoWidth();
306            terminateMessageLooper();
307        } catch (Exception e) {
308            Log.e(TAG, e.getMessage());
309        }
310        return videoWidth;
311    }
312
313    //This also test the streaming video which may take a long
314    //time to start the playback.
315    public static boolean videoSeekTo(String filePath) throws Exception {
316        Log.v(TAG, "videoSeekTo - " + filePath);
317        int currentPosition = 0;
318        int duration = 0;
319        boolean videoResult = false;
320        MediaPlayer mp = new MediaPlayer();
321        mp.setDataSource(filePath);
322        mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
323        mp.prepare();
324        mp.start();
325        if (filePath.equals(MediaNames.VIDEO_SHORT_3GP)){
326            mp.pause();
327            Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
328            mp.seekTo(0);
329            mp.start();
330            Thread.sleep(1000);
331            currentPosition = mp.getCurrentPosition();
332            Log.v(TAG,"short position " + currentPosition);
333            if (currentPosition > 100 )
334                return true;
335            else
336                return false;
337        }
338        Thread.sleep(5000);
339        duration = mp.getDuration();
340        Log.v(TAG, "video duration " + duration);
341        mp.pause();
342        Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
343        mp.seekTo(duration - 20000 );
344        mp.start();
345        Thread.sleep(1000);
346        mp.pause();
347        Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
348        mp.seekTo(duration/2);
349        mp.start();
350        Thread.sleep(10000);
351        currentPosition = mp.getCurrentPosition();
352        Log.v(TAG, "video currentPosition " + currentPosition);
353        mp.release();
354        if (currentPosition > (duration /2 )*0.9)
355            return true;
356        else
357            return false;
358
359    }
360
361    public static boolean seekToEnd(String filePath){
362        Log.v(TAG, "seekToEnd - " + filePath);
363        int duration = 0;
364        int currentPosition = 0;
365        boolean isPlaying = false;
366        MediaPlayer mp = new MediaPlayer();
367        try{
368            mp.setDataSource(filePath);
369            Log.v(TAG, "start playback");
370            mp.prepare();
371            duration = mp.getDuration();
372            mp.seekTo(duration - 3000);
373            mp.start();
374            Thread.sleep(6000);
375        }catch (Exception e){}
376        isPlaying = mp.isPlaying();
377        currentPosition = mp.getCurrentPosition();
378        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
379        mp.stop();
380        mp.release();
381        Log.v(TAG, "duration = " + duration);
382        if (currentPosition < 0.9 * duration || isPlaying)
383            return false;
384        else
385            return true;
386    }
387
388    public static boolean shortMediaStop(String filePath){
389        Log.v(TAG, "shortMediaStop - " + filePath);
390        //This test is only for the short media file
391        int duration = 0;
392        int currentPosition = 0;
393        boolean isPlaying = false;
394        MediaPlayer mp = new MediaPlayer();
395        try{
396            mp.setDataSource(filePath);
397            Log.v(TAG, "start playback");
398            mp.prepare();
399            duration = mp.getDuration();
400            mp.start();
401            Thread.sleep(10000);
402        }catch (Exception e){}
403        isPlaying = mp.isPlaying();
404        currentPosition = mp.getCurrentPosition();
405        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
406        mp.stop();
407        mp.release();
408        Log.v(TAG, "duration = " + duration);
409        if (currentPosition > duration || isPlaying)
410            return false;
411        else
412            return true;
413    }
414
415    public static boolean playToEnd(String filePath){
416        Log.v(TAG, "shortMediaStop - " + filePath);
417        //This test is only for the short media file
418        int duration = 200000;
419        int updateDuration = 0;
420        int currentPosition = 0;
421        boolean isPlaying = false;
422        MediaPlayer mp = new MediaPlayer();
423        try{
424            Thread.sleep(5000);
425            mp.setDataSource(filePath);
426            Log.v(TAG, "start playback");
427            mp.prepare();
428            //duration = mp.getDuration();
429            mp.start();
430            Thread.sleep(50000);
431        }catch (Exception e){}
432        isPlaying = mp.isPlaying();
433        currentPosition = mp.getCurrentPosition();
434        //updateDuration = mp.getDuration();
435        Log.v(TAG, "seekToEnd currentPosition= " + currentPosition + " isPlaying = " + isPlaying);
436        mp.stop();
437        mp.release();
438        //Log.v(TAG, "duration = " + duration);
439        //Log.v(TAG, "Update duration = " + updateDuration);
440        if (currentPosition > duration || isPlaying)
441            return false;
442        else
443            return true;
444    }
445
446    public static boolean seektoBeforeStart(String filePath){
447        Log.v(TAG, "seektoBeforeStart - " + filePath);
448        //This test is only for the short media file
449        int duration = 0;
450        int currentPosition = 0;
451
452        MediaPlayer mp = new MediaPlayer();
453        try{
454            mp.setDataSource(filePath);
455            mp.prepare();
456            duration = mp.getDuration();
457            mp.seekTo(duration - 10000);
458            mp.start();
459            currentPosition=mp.getCurrentPosition();
460            mp.stop();
461            mp.release();
462        }catch (Exception e){}
463        if (currentPosition < duration/2)
464            return false;
465        else
466            return true;
467    }
468
469    public static boolean mediaRecorderRecord(String filePath){
470        Log.v(TAG, "SoundRecording - " + filePath);
471        //This test is only for the short media file
472        int duration = 0;
473        try{
474            MediaRecorder mRecorder = new MediaRecorder();
475            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
476            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
477            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
478            mRecorder.setOutputFile(filePath);
479            mRecorder.prepare();
480            mRecorder.start();
481            Thread.sleep(500);
482            mRecorder.stop();
483            Log.v(TAG, "sound recorded");
484            mRecorder.release();
485        }catch (Exception e){
486            Log.v(TAG, e.toString());
487        }
488
489        //Verify the recorded file
490        MediaPlayer mp = new MediaPlayer();
491        try{
492            mp.setDataSource(filePath);
493            mp.prepare();
494            duration = mp.getDuration();
495            Log.v(TAG,"Duration " + duration);
496            mp.release();
497        }catch (Exception e){}
498        //Check the record media file length is greate than zero
499        if (duration > 0)
500            return true;
501        else
502            return false;
503
504    }
505
506    //Test for mediaMeta Data Thumbnail
507    public static boolean getThumbnail(String filePath, String goldenPath){
508        Log.v(TAG, "getThumbnail - " + filePath);
509
510        int goldenHeight = 0;
511        int goldenWidth = 0;
512        int outputWidth = 0;
513        int outputHeight = 0;
514
515        //This test is only for the short media file
516        try{
517            BitmapFactory mBitmapFactory = new BitmapFactory();
518
519            MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever();
520            try {
521                mMediaMetadataRetriever.setDataSource(filePath);
522            } catch(Exception e) {
523                e.printStackTrace();
524                return false;
525            }
526            Bitmap outThumbnail = mMediaMetadataRetriever.captureFrame();
527
528            //Verify the thumbnail
529            Bitmap goldenBitmap = mBitmapFactory.decodeFile(goldenPath);
530
531            outputWidth = outThumbnail.getWidth();
532            outputHeight = outThumbnail.getHeight();
533            goldenHeight = goldenBitmap.getHeight();
534            goldenWidth = goldenBitmap.getWidth();
535
536            //check the image dimension
537            if ((outputWidth != goldenWidth) || (outputHeight != goldenHeight))
538                return false;
539
540            //Check one line of pixel
541            int x = goldenHeight/2;
542            for (int j=0; j<goldenWidth; j++){
543                if (goldenBitmap.getPixel(x, j) != outThumbnail.getPixel(x, j)){
544                    Log.v(TAG, "pixel = " + goldenBitmap.getPixel(x, j));
545                    return false;
546                }
547            }
548        }catch (Exception e){}
549        return true;
550    }
551
552    //Load midi file from resources
553    public static boolean resourcesPlayback(AssetFileDescriptor afd, int expectedDuration){
554        int duration = 0;
555        try{
556            MediaPlayer mp = new MediaPlayer();
557            mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
558            mp.prepare();
559            mp.start();
560            duration = mp.getDuration();
561            Thread.sleep(5000);
562            mp.release();
563        }catch (Exception e){
564            Log.v(TAG,e.getMessage());
565        }
566        if (duration > expectedDuration)
567            return true;
568        else
569            return false;
570    }
571
572    public static boolean prepareAsyncReset(String filePath){
573        //preparesAsync
574        try{
575            MediaPlayer mp = new MediaPlayer();
576            mp.setDataSource(filePath);
577            mp.prepareAsync();
578            mp.reset();
579            mp.release();
580        }catch (Exception e){
581            Log.v(TAG,e.getMessage());
582            return false;
583        }
584        return true;
585    }
586
587
588    public static boolean isLooping(String filePath) {
589        MediaPlayer mp = null;
590
591        try {
592            mp = new MediaPlayer();
593            if (mp.isLooping()) {
594                Log.v(TAG, "MediaPlayer.isLooping() returned true after ctor");
595                return false;
596            }
597            mp.setDataSource(filePath);
598            mp.prepare();
599
600            mp.setLooping(true);
601            if (!mp.isLooping()) {
602                Log.v(TAG, "MediaPlayer.isLooping() returned false after setLooping(true)");
603                return false;
604            }
605
606            mp.setLooping(false);
607            if (mp.isLooping()) {
608                Log.v(TAG, "MediaPlayer.isLooping() returned true after setLooping(false)");
609                return false;
610            }
611        }catch (Exception e){
612            Log.v(TAG, "Exception : " + e.toString());
613            return false;
614        } finally {
615            if (mp != null)
616                mp.release();
617        }
618
619        return true;
620    }
621
622    public static boolean isLoopingAfterReset(String filePath) {
623        MediaPlayer mp = null;
624        try {
625            mp = new MediaPlayer();
626            mp.setDataSource(filePath);
627            mp.prepare();
628
629            mp.setLooping(true);
630            mp.reset();
631            if (mp.isLooping()) {
632                Log.v(TAG, "MediaPlayer.isLooping() returned true after reset()");
633                return false;
634            }
635        }catch (Exception e){
636            Log.v(TAG, "Exception : " + e.toString());
637            return false;
638        } finally {
639            if (mp != null)
640                mp.release();
641        }
642
643        return true;
644    }
645
646    /*
647     * Initializes the message looper so that the mediaPlayer object can
648     * receive the callback messages.
649     */
650    private static void initializeMessageLooper() {
651        Log.v(TAG, "start looper");
652        new Thread() {
653            @Override
654            public void run() {
655                // Set up a looper to be used by camera.
656                Looper.prepare();
657                Log.v(TAG, "start loopRun");
658                // Save the looper so that we can terminate this thread
659                // after we are done with it.
660                mLooper = Looper.myLooper();
661                mMediaPlayer = new MediaPlayer();
662                synchronized (lock) {
663                    mInitialized = true;
664                    lock.notify();
665                }
666                Looper.loop();  // Blocks forever until Looper.quit() is called.
667                Log.v(TAG, "initializeMessageLooper: quit.");
668            }
669        }.start();
670    }
671
672    /*
673     * Terminates the message looper thread.
674     */
675    private static void terminateMessageLooper() {
676        mLooper.quit();
677        mMediaPlayer.release();
678    }
679
680    static MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
681        public void onPrepared(MediaPlayer mp) {
682            synchronized (prepareDone) {
683                if(mPrepareReset){
684                    Log.v(TAG, "call Reset");
685                    mMediaPlayer.reset();
686                }
687                Log.v(TAG, "notify the prepare callback");
688                prepareDone.notify();
689                onPrepareSuccess = true;
690            }
691        }
692    };
693
694    public static boolean prepareAsyncCallback(String filePath, boolean reset) throws Exception {
695        //Added the PrepareReset flag which allow us to switch to different
696        //test case.
697        if (reset){
698            mPrepareReset = true;
699        }
700
701        synchronized (lock) {
702            initializeMessageLooper();
703            try {
704                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
705            } catch(Exception e) {
706                Log.v(TAG, "looper was interrupted.");
707                return false;
708            }
709        }
710        try{
711            mMediaPlayer.setOnPreparedListener(mPreparedListener);
712            mMediaPlayer.setDataSource(filePath);
713            mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
714            mMediaPlayer.prepareAsync();
715            synchronized (prepareDone) {
716                try {
717                    prepareDone.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
718                } catch (Exception e) {
719                    Log.v(TAG, "wait was interrupted.");
720                }
721            }
722            terminateMessageLooper();
723        }catch (Exception e){
724            Log.v(TAG,e.getMessage());
725        }
726       return onPrepareSuccess;
727    }
728
729
730
731}
732
733