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