Home | History | Annotate | Download | only in stress
      1 /*
      2  * Copyright (C) 2009 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.stress;
     18 
     19 
     20 import com.android.mediaframeworktest.MediaFrameworkTest;
     21 
     22 import java.io.BufferedWriter;
     23 import java.io.File;
     24 import java.io.FileWriter;
     25 import java.io.IOException;
     26 import java.io.Writer;
     27 import java.util.concurrent.Semaphore;
     28 import java.util.concurrent.TimeUnit;
     29 
     30 import android.hardware.Camera;
     31 import android.media.CamcorderProfile;
     32 import android.media.MediaPlayer;
     33 import android.media.MediaRecorder;
     34 import android.os.Handler;
     35 import android.os.Looper;
     36 import android.test.ActivityInstrumentationTestCase2;
     37 import android.test.suitebuilder.annotation.LargeTest;
     38 import android.util.Log;
     39 import android.view.SurfaceHolder;
     40 import com.android.mediaframeworktest.MediaRecorderStressTestRunner;
     41 
     42 /**
     43  * Junit / Instrumentation test case for the media player api
     44  */
     45 public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
     46 
     47     private String TAG = "MediaRecorderStressTest";
     48     private MediaRecorder mRecorder;
     49     private Camera mCamera;
     50 
     51     private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 100;
     52     private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 100;
     53     private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 50;
     54     private static final int NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER = 200;
     55     private static final int NUMBER_OF_TIME_LAPSE_LOOPS = 25;
     56     private static final int TIME_LAPSE_PLAYBACK_WAIT_TIME = 5* 1000; // 5 seconds
     57     private static final long WAIT_TIME_CAMERA_TEST = 3 * 1000; // 3 seconds
     58     private static final long WAIT_TIME_RECORDER_TEST = 6 * 1000; // 6 seconds
     59     private static final String OUTPUT_FILE = "/sdcard/temp";
     60     private static final String OUTPUT_FILE_EXT = ".3gp";
     61     private static final String MEDIA_STRESS_OUTPUT =
     62         "/sdcard/mediaStressOutput.txt";
     63     private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
     64     private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
     65 
     66     private final static int WAIT_TIMEOUT = 10 * 1000; // 10 seconds
     67     private Thread mLooperThread;
     68     private Handler mHandler;
     69 
     70     public MediaRecorderStressTest() {
     71         super("com.android.mediaframeworktest", MediaFrameworkTest.class);
     72     }
     73 
     74     protected void setUp() throws Exception {
     75         final Semaphore sem = new Semaphore(0);
     76         mLooperThread = new Thread() {
     77             @Override
     78             public void run() {
     79                 Log.v(TAG, "starting looper");
     80                 Looper.prepare();
     81                 mHandler = new Handler();
     82                 sem.release();
     83                 Looper.loop();
     84                 Log.v(TAG, "quit looper");
     85             }
     86         };
     87         mLooperThread.start();
     88         if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
     89             fail("Failed to start the looper.");
     90         }
     91 
     92         getActivity();
     93         super.setUp();
     94     }
     95 
     96     @Override
     97     protected void tearDown() throws Exception {
     98         if (mHandler != null) {
     99             mHandler.getLooper().quit();
    100             mHandler = null;
    101         }
    102         if (mLooperThread != null) {
    103             mLooperThread.join(WAIT_TIMEOUT);
    104             if (mLooperThread.isAlive()) {
    105                 fail("Failed to stop the looper.");
    106             }
    107             mLooperThread = null;
    108         }
    109 
    110         super.tearDown();
    111     }
    112 
    113     private void runOnLooper(final Runnable command) throws InterruptedException {
    114         final Semaphore sem = new Semaphore(0);
    115         mHandler.post(new Runnable() {
    116             @Override
    117             public void run() {
    118                 try {
    119                     command.run();
    120                 } finally {
    121                     sem.release();
    122                 }
    123             }
    124         });
    125         if (! sem.tryAcquire(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) {
    126             fail("Failed to run the command on the looper.");
    127         }
    128     }
    129 
    130     private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
    131         public void onError(int error, android.hardware.Camera camera) {
    132             if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
    133                 assertTrue("Camera test mediaserver died", false);
    134             }
    135         }
    136     }
    137 
    138     private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener {
    139         public void onError(MediaRecorder mr, int what, int extra) {
    140             // fail the test case no matter what error come up
    141             assertTrue("mediaRecorder error", false);
    142         }
    143     }
    144 
    145     //Test case for stressing the camera preview.
    146     @LargeTest
    147     public void testStressCamera() throws Exception {
    148         SurfaceHolder mSurfaceHolder;
    149         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    150         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
    151         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
    152         output.write("Camera start preview stress:\n");
    153         output.write("Total number of loops:" +
    154                 NUMBER_OF_CAMERA_STRESS_LOOPS + "\n");
    155         try {
    156             Log.v(TAG, "Start preview");
    157             output.write("No of loop: ");
    158 
    159             for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++) {
    160                 runOnLooper(new Runnable() {
    161                     @Override
    162                     public void run() {
    163                         mCamera = Camera.open();
    164                     }
    165                 });
    166                 mCamera.setErrorCallback(mCameraErrorCallback);
    167                 mCamera.setPreviewDisplay(mSurfaceHolder);
    168                 mCamera.startPreview();
    169                 Thread.sleep(WAIT_TIME_CAMERA_TEST);
    170                 mCamera.stopPreview();
    171                 mCamera.release();
    172                 output.write(" ," + i);
    173             }
    174         } catch (Exception e) {
    175             assertTrue("CameraStressTest", false);
    176             Log.v(TAG, e.toString());
    177         }
    178         output.write("\n\n");
    179         output.close();
    180     }
    181 
    182     //Test case for stressing the camera preview.
    183     @LargeTest
    184     public void testStressRecorder() throws Exception {
    185         String filename;
    186         SurfaceHolder mSurfaceHolder;
    187         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    188         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
    189         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
    190         output.write("H263 video record- reset after prepare Stress test\n");
    191         output.write("Total number of loops:" +
    192                 NUMBER_OF_RECORDER_STRESS_LOOPS + "\n");
    193         try {
    194             output.write("No of loop: ");
    195             Log.v(TAG, "Start preview");
    196             for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++) {
    197                 runOnLooper(new Runnable() {
    198                     @Override
    199                     public void run() {
    200                         mRecorder = new MediaRecorder();
    201                     }
    202                 });
    203                 Log.v(TAG, "counter = " + i);
    204                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
    205                 Log.v(TAG, filename);
    206                 mRecorder.setOnErrorListener(mRecorderErrorCallback);
    207                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    208                 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    209                 mRecorder.setOutputFile(filename);
    210                 mRecorder.setVideoFrameRate(MediaRecorderStressTestRunner.mFrameRate);
    211                 mRecorder.setVideoSize(176,144);
    212                 Log.v(TAG, "setEncoder");
    213                 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
    214                 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    215                 Log.v(TAG, "setPreview");
    216                 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    217                 Log.v(TAG, "prepare");
    218                 mRecorder.prepare();
    219                 Log.v(TAG, "before release");
    220                 Thread.sleep(WAIT_TIME_RECORDER_TEST);
    221                 mRecorder.reset();
    222                 mRecorder.release();
    223                 output.write(", " + i);
    224             }
    225         } catch (Exception e) {
    226             assertTrue("Recorder Stress test", false);
    227             Log.v(TAG, e.toString());
    228         }
    229         output.write("\n\n");
    230         output.close();
    231     }
    232 
    233     //Stress test case for switching camera and video recorder preview.
    234     @LargeTest
    235     public void testStressCameraSwitchRecorder() throws Exception {
    236         String filename;
    237         SurfaceHolder mSurfaceHolder;
    238         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    239         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
    240         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
    241         output.write("Camera and video recorder preview switching\n");
    242         output.write("Total number of loops:"
    243                 + NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER + "\n");
    244         try {
    245             Log.v(TAG, "Start preview");
    246             output.write("No of loop: ");
    247             for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++) {
    248                 runOnLooper(new Runnable() {
    249                     @Override
    250                     public void run() {
    251                         mCamera = Camera.open();
    252                     }
    253                 });
    254                 mCamera.setErrorCallback(mCameraErrorCallback);
    255                 mCamera.setPreviewDisplay(mSurfaceHolder);
    256                 mCamera.startPreview();
    257                 Thread.sleep(WAIT_TIME_CAMERA_TEST);
    258                 mCamera.stopPreview();
    259                 mCamera.release();
    260                 mCamera = null;
    261                 Log.v(TAG, "release camera");
    262                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
    263                 Log.v(TAG, filename);
    264                 runOnLooper(new Runnable() {
    265                     @Override
    266                     public void run() {
    267                         mRecorder = new MediaRecorder();
    268                     }
    269                 });
    270                 mRecorder.setOnErrorListener(mRecorderErrorCallback);
    271                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    272                 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    273                 mRecorder.setOutputFile(filename);
    274                 mRecorder.setVideoFrameRate(MediaRecorderStressTestRunner.mFrameRate);
    275                 mRecorder.setVideoSize(176,144);
    276                 Log.v(TAG, "Media recorder setEncoder");
    277                 mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
    278                 Log.v(TAG, "mediaRecorder setPreview");
    279                 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    280                 Log.v(TAG, "prepare");
    281                 mRecorder.prepare();
    282                 Log.v(TAG, "before release");
    283                 Thread.sleep(WAIT_TIME_CAMERA_TEST);
    284                 mRecorder.release();
    285                 Log.v(TAG, "release video recorder");
    286                 output.write(", " + i);
    287             }
    288         } catch (Exception e) {
    289             assertTrue("Camer and recorder switch mode", false);
    290                 Log.v(TAG, e.toString());
    291         }
    292         output.write("\n\n");
    293         output.close();
    294     }
    295 
    296     public void validateRecordedVideo(String recorded_file) {
    297         try {
    298             MediaPlayer mp = new MediaPlayer();
    299             mp.setDataSource(recorded_file);
    300             mp.prepare();
    301             int duration = mp.getDuration();
    302             if (duration <= 0){
    303                 assertTrue("stressRecordAndPlayback", false);
    304             }
    305             mp.release();
    306         } catch (Exception e) {
    307             assertTrue("stressRecordAndPlayback", false);
    308         }
    309     }
    310 
    311     public void removeRecordedVideo(String filename){
    312         File video = new File(filename);
    313         Log.v(TAG, "remove recorded video " + filename);
    314         video.delete();
    315     }
    316 
    317     //Stress test case for record a video and play right away.
    318     @LargeTest
    319     public void testStressRecordVideoAndPlayback() throws Exception {
    320         int iterations = MediaRecorderStressTestRunner.mIterations;
    321         int video_encoder = MediaRecorderStressTestRunner.mVideoEncoder;
    322         int audio_encoder = MediaRecorderStressTestRunner.mAudioEncdoer;
    323         int frame_rate = MediaRecorderStressTestRunner.mFrameRate;
    324         int video_width = MediaRecorderStressTestRunner.mVideoWidth;
    325         int video_height = MediaRecorderStressTestRunner.mVideoHeight;
    326         int bit_rate = MediaRecorderStressTestRunner.mBitRate;
    327         boolean remove_video = MediaRecorderStressTestRunner.mRemoveVideo;
    328         int record_duration = MediaRecorderStressTestRunner.mDuration;
    329 
    330         String filename;
    331         SurfaceHolder mSurfaceHolder;
    332         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    333         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
    334         Writer output = new BufferedWriter(
    335                 new FileWriter(stressOutFile, true));
    336         output.write("Video record and play back stress test:\n");
    337         output.write("Total number of loops:"
    338                 + NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS + "\n");
    339         try {
    340             output.write("No of loop: ");
    341             for (int i = 0; i < iterations; i++){
    342                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
    343                 Log.v(TAG, filename);
    344                 runOnLooper(new Runnable() {
    345                     @Override
    346                     public void run() {
    347                         mRecorder = new MediaRecorder();
    348                     }
    349                 });
    350                 Log.v(TAG, "iterations : " + iterations);
    351                 Log.v(TAG, "video_encoder : " + video_encoder);
    352                 Log.v(TAG, "audio_encoder : " + audio_encoder);
    353                 Log.v(TAG, "frame_rate : " + frame_rate);
    354                 Log.v(TAG, "video_width : " + video_width);
    355                 Log.v(TAG, "video_height : " + video_height);
    356                 Log.v(TAG, "bit rate : " + bit_rate);
    357                 Log.v(TAG, "record_duration : " + record_duration);
    358 
    359                 mRecorder.setOnErrorListener(mRecorderErrorCallback);
    360                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    361                 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    362                 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    363                 mRecorder.setOutputFile(filename);
    364                 mRecorder.setVideoFrameRate(frame_rate);
    365                 mRecorder.setVideoSize(video_width, video_height);
    366                 mRecorder.setVideoEncoder(video_encoder);
    367                 mRecorder.setAudioEncoder(audio_encoder);
    368                 mRecorder.setVideoEncodingBitRate(bit_rate);
    369                 Log.v(TAG, "mediaRecorder setPreview");
    370                 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    371                 mRecorder.prepare();
    372                 mRecorder.start();
    373                 Thread.sleep(record_duration);
    374                 Log.v(TAG, "Before stop");
    375                 mRecorder.stop();
    376                 mRecorder.release();
    377                 //start the playback
    378                 MediaPlayer mp = new MediaPlayer();
    379                 mp.setDataSource(filename);
    380                 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
    381                 mp.prepare();
    382                 mp.start();
    383                 Thread.sleep(record_duration);
    384                 mp.release();
    385                 validateRecordedVideo(filename);
    386                 if (remove_video) {
    387                     removeRecordedVideo(filename);
    388                 }
    389                 output.write(", " + i);
    390             }
    391         } catch (Exception e) {
    392             Log.v(TAG, e.toString());
    393             assertTrue("record and playback", false);
    394         }
    395         output.write("\n\n");
    396         output.close();
    397     }
    398 
    399     // Test case for stressing time lapse
    400     @LargeTest
    401     public void testStressTimeLapse() throws Exception {
    402         SurfaceHolder mSurfaceHolder;
    403         mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
    404         int record_duration = MediaRecorderStressTestRunner.mTimeLapseDuration;
    405         boolean remove_video = MediaRecorderStressTestRunner.mRemoveVideo;
    406         double captureRate = MediaRecorderStressTestRunner.mCaptureRate;
    407         String filename;
    408         File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
    409         Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
    410         output.write("Start camera time lapse stress:\n");
    411         output.write("Total number of loops: " + NUMBER_OF_TIME_LAPSE_LOOPS + "\n");
    412 
    413         try {
    414             output.write("No of loop: ");
    415             for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) {
    416                 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
    417                 Log.v(TAG, filename);
    418                 runOnLooper(new Runnable() {
    419                     @Override
    420                     public void run() {
    421                         mRecorder = new MediaRecorder();
    422                     }
    423                 });
    424 
    425                 // Set callback
    426                 mRecorder.setOnErrorListener(mRecorderErrorCallback);
    427 
    428                 // Set video source
    429                 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    430 
    431                 // Set camcorder profile for time lapse
    432                 CamcorderProfile profile =
    433                         CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
    434                 mRecorder.setProfile(profile);
    435 
    436                 // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc.
    437                 // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video
    438                 mRecorder.setCaptureRate(captureRate);
    439 
    440                 // Set output file
    441                 mRecorder.setOutputFile(filename);
    442 
    443                 // Set the preview display
    444                 Log.v(TAG, "mediaRecorder setPreviewDisplay");
    445                 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    446 
    447                 mRecorder.prepare();
    448                 mRecorder.start();
    449                 Thread.sleep(record_duration);
    450                 Log.v(TAG, "Before stop");
    451                 mRecorder.stop();
    452                 mRecorder.release();
    453 
    454                 // Start the playback
    455                 MediaPlayer mp = new MediaPlayer();
    456                 mp.setDataSource(filename);
    457                 mp.setDisplay(mSurfaceHolder);
    458                 mp.prepare();
    459                 mp.start();
    460                 Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME);
    461                 mp.release();
    462                 validateRecordedVideo(filename);
    463                 if(remove_video) {
    464                   removeRecordedVideo(filename);
    465                 }
    466                 output.write(", " + i);
    467             }
    468         }
    469         catch (IllegalStateException e) {
    470             assertTrue("Camera time lapse stress test IllegalStateException", false);
    471             Log.v(TAG, e.toString());
    472         }
    473         catch (IOException e) {
    474             assertTrue("Camera time lapse stress test IOException", false);
    475             Log.v(TAG, e.toString());
    476         }
    477         catch (Exception e) {
    478             assertTrue("Camera time lapse stress test Exception", false);
    479             Log.v(TAG, e.toString());
    480         }
    481         output.write("\n\n");
    482         output.close();
    483     }
    484 }
    485