MediaRecorderStressTest.java revision 48584d7b8f5e56b73bb13180bf6546b2647c1b28
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
17package com.android.mediaframeworktest.stress;
18
19
20import com.android.mediaframeworktest.MediaFrameworkTest;
21
22import java.io.BufferedWriter;
23import java.io.File;
24import java.io.FileWriter;
25import java.io.Writer;
26
27import android.hardware.Camera;
28import android.media.MediaPlayer;
29import android.media.MediaRecorder;
30import android.os.Looper;
31import android.test.ActivityInstrumentationTestCase2;
32import android.test.suitebuilder.annotation.LargeTest;
33import android.util.Log;
34import android.view.SurfaceHolder;
35import com.android.mediaframeworktest.MediaRecorderStressTestRunner;
36
37/**
38 * Junit / Instrumentation test case for the media player api
39
40 */
41public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
42
43
44    private String TAG = "MediaRecorderStressTest";
45    private MediaRecorder mRecorder;
46    private Camera mCamera;
47
48    private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 100;
49    private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 100;
50    private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 50;
51    private static final int NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER = 200;
52    private static final long WAIT_TIME_CAMERA_TEST = 3000;  // 3 second
53    private static final long WAIT_TIME_RECORDER_TEST = 6000;  // 6 second
54    private static final long WAIT_TIME_RECORD = 10000;  // 10 seconds
55    private static final long WAIT_TIME_PLAYBACK = 6000;  // 6 second
56    private static final String OUTPUT_FILE = "/sdcard/temp";
57    private static final String OUTPUT_FILE_EXT = ".3gp";
58    private static final String MEDIA_STRESS_OUTPUT =
59        "/sdcard/mediaStressOutput.txt";
60    private Looper mCameraLooper = null;
61    private Looper mRecorderLooper = null;
62    private final Object lock = new Object();
63    private final Object recorderlock = new Object();
64    private static int WAIT_FOR_COMMAND_TO_COMPLETE = 10000;  // Milliseconds.
65    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
66    private final RecorderErrorCallback mRecorderErrorCallback = new RecorderErrorCallback();
67
68    public MediaRecorderStressTest() {
69        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
70    }
71
72    protected void setUp() throws Exception {
73        getActivity();
74        super.setUp();
75    }
76
77    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {
78        public void onError(int error, android.hardware.Camera camera) {
79            if (error == android.hardware.Camera.CAMERA_ERROR_SERVER_DIED) {
80                assertTrue("Camera test mediaserver died", false);
81            }
82        }
83    }
84
85    private final class RecorderErrorCallback implements MediaRecorder.OnErrorListener {
86        public void onError(MediaRecorder mr, int what, int extra) {
87            // fail the test case no matter what error come up
88            assertTrue("mediaRecorder error", false);
89        }
90    }
91
92    private void initializeCameraMessageLooper() {
93        Log.v(TAG, "start looper");
94        new Thread() {
95            @Override
96            public void run() {
97                // Set up a looper to be used by camera.
98                Looper.prepare();
99                Log.v(TAG, "start loopRun");
100                mCameraLooper = Looper.myLooper();
101                mCamera = Camera.open();
102                synchronized (lock) {
103                    lock.notify();
104                }
105                Looper.loop();
106                Log.v(TAG, "initializeMessageLooper: quit.");
107            }
108        }.start();
109    }
110
111    private void initializeRecorderMessageLooper() {
112        Log.v(TAG, "start looper");
113        new Thread() {
114            @Override
115            public void run() {
116                Looper.prepare();
117                Log.v(TAG, "start loopRun");
118                mRecorderLooper = Looper.myLooper();
119                mRecorder = new MediaRecorder();
120                synchronized (recorderlock) {
121                    recorderlock.notify();
122                }
123                Looper.loop();  // Blocks forever until Looper.quit() is called.
124                Log.v(TAG, "initializeMessageLooper: quit.");
125            }
126        }.start();
127    }
128
129    /*
130     * Terminates the message looper thread.
131     */
132    private void terminateCameraMessageLooper() {
133        mCameraLooper.quit();
134        try {
135            Thread.sleep(1000);
136        } catch (Exception e){
137            Log.v(TAG, e.toString());
138        }
139        mCamera.release();
140    }
141
142    /*
143     * Terminates the message looper thread.
144     */
145    private void terminateRecorderMessageLooper() {
146        mRecorderLooper.quit();
147        try {
148            Thread.sleep(1000);
149        } catch (Exception e){
150            Log.v(TAG, e.toString());
151        }
152        mRecorder.release();
153    }
154
155    //Test case for stressing the camera preview.
156    @LargeTest
157    public void testStressCamera() throws Exception {
158        SurfaceHolder mSurfaceHolder;
159        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
160        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
161        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
162        output.write("Camera start preview stress:\n");
163        output.write("Total number of loops:" +
164                NUMBER_OF_CAMERA_STRESS_LOOPS + "\n");
165        try {
166            Log.v(TAG, "Start preview");
167            output.write("No of loop: ");
168
169            for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++){
170                synchronized (lock) {
171                    initializeCameraMessageLooper();
172                    try {
173                        lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
174                    } catch(Exception e) {
175                        Log.v(TAG, "wait was interrupted.");
176                    }
177                }
178                mCamera.setErrorCallback(mCameraErrorCallback);
179                mCamera.setPreviewDisplay(mSurfaceHolder);
180                mCamera.startPreview();
181                Thread.sleep(WAIT_TIME_CAMERA_TEST);
182                mCamera.stopPreview();
183                terminateCameraMessageLooper();
184                output.write(" ," + i);
185            }
186        } catch (Exception e) {
187            assertTrue("CameraStressTest", false);
188            Log.v(TAG, e.toString());
189        }
190        output.write("\n\n");
191        output.close();
192    }
193
194    //Test case for stressing the camera preview.
195    @LargeTest
196    public void testStressRecorder() throws Exception {
197        String filename;
198        SurfaceHolder mSurfaceHolder;
199        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
200        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
201        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
202        output.write("H263 video record- reset after prepare Stress test\n");
203        output.write("Total number of loops:" +
204                NUMBER_OF_RECORDER_STRESS_LOOPS + "\n");
205        try {
206            output.write("No of loop: ");
207            Log.v(TAG, "Start preview");
208            for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++){
209                synchronized (recorderlock) {
210                    initializeRecorderMessageLooper();
211                    try {
212                        recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
213                    } catch(Exception e) {
214                        Log.v(TAG, "wait was interrupted.");
215                    }
216                }
217                Log.v(TAG, "counter = " + i);
218                filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
219                Log.v(TAG, filename);
220                mRecorder.setOnErrorListener(mRecorderErrorCallback);
221                mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
222                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
223                mRecorder.setOutputFile(filename);
224                mRecorder.setVideoFrameRate(20);
225                mRecorder.setVideoSize(176,144);
226                Log.v(TAG, "setEncoder");
227                mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
228                mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
229                Log.v(TAG, "setPreview");
230                mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
231                Log.v(TAG, "prepare");
232                mRecorder.prepare();
233                Log.v(TAG, "before release");
234                Thread.sleep(WAIT_TIME_RECORDER_TEST);
235                mRecorder.reset();
236                terminateRecorderMessageLooper();
237                output.write(", " + i);
238            }
239        } catch (Exception e) {
240            assertTrue("Recorder Stress test", false);
241            Log.v(TAG, e.toString());
242        }
243        output.write("\n\n");
244        output.close();
245    }
246
247    //Stress test case for switching camera and video recorder preview.
248    @LargeTest
249    public void testStressCameraSwitchRecorder() throws Exception {
250        String filename;
251        SurfaceHolder mSurfaceHolder;
252        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
253        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
254        Writer output = new BufferedWriter(new FileWriter(stressOutFile, true));
255        output.write("Camera and video recorder preview switching\n");
256        output.write("Total number of loops:"
257                + NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER + "\n");
258        try {
259            Log.v(TAG, "Start preview");
260            output.write("No of loop: ");
261            for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++){
262                synchronized (lock) {
263                    initializeCameraMessageLooper();
264                    try {
265                        lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
266                    } catch(Exception e) {
267                        Log.v(TAG, "wait was interrupted.");
268                    }
269                }
270                mCamera.setErrorCallback(mCameraErrorCallback);
271                mCamera.setPreviewDisplay(mSurfaceHolder);
272                mCamera.startPreview();
273                Thread.sleep(WAIT_TIME_CAMERA_TEST);
274                mCamera.stopPreview();
275                terminateCameraMessageLooper();
276                mCamera = null;
277                Log.v(TAG, "release camera");
278                filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
279                Log.v(TAG, filename);
280                synchronized (recorderlock) {
281                    initializeRecorderMessageLooper();
282                    try {
283                        recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
284                    } catch(Exception e) {
285                        Log.v(TAG, "wait was interrupted.");
286                    }
287                }
288                mRecorder.setOnErrorListener(mRecorderErrorCallback);
289                mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
290                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
291                mRecorder.setOutputFile(filename);
292                mRecorder.setVideoFrameRate(20);
293                mRecorder.setVideoSize(176,144);
294                Log.v(TAG, "Media recorder setEncoder");
295                mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
296                Log.v(TAG, "mediaRecorder setPreview");
297                mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
298                Log.v(TAG, "prepare");
299                mRecorder.prepare();
300                Log.v(TAG, "before release");
301                Thread.sleep(WAIT_TIME_CAMERA_TEST);
302                terminateRecorderMessageLooper();
303                Log.v(TAG, "release video recorder");
304                output.write(", " + i);
305            }
306        } catch (Exception e) {
307            assertTrue("Camer and recorder switch mode", false);
308                Log.v(TAG, e.toString());
309        }
310        output.write("\n\n");
311        output.close();
312    }
313
314    public void validateRecordedVideo(String recorded_file) {
315        try {
316            MediaPlayer mp = new MediaPlayer();
317            mp.setDataSource(recorded_file);
318            mp.prepare();
319            int duration = mp.getDuration();
320            if (duration <= 0){
321                assertTrue("stressRecordAndPlayback", false);
322            }
323        } catch (Exception e) {
324            assertTrue("stressRecordAndPlayback", false);
325        }
326    }
327
328    public void removeRecodedVideo(String filename){
329        File video = new File(filename);
330        Log.v(TAG, "remove recorded video " + filename);
331        video.delete();
332    }
333
334    //Stress test case for record a video and play right away.
335    @LargeTest
336    public void testStressRecordVideoAndPlayback() throws Exception {
337        int iterations = MediaRecorderStressTestRunner.mIterations;
338        int video_encoder = MediaRecorderStressTestRunner.mVideoEncoder;
339        int audio_encoder = MediaRecorderStressTestRunner.mAudioEncdoer;
340        int frame_rate = MediaRecorderStressTestRunner.mFrameRate;
341        int video_width = MediaRecorderStressTestRunner.mVideoWidth;
342        int video_height = MediaRecorderStressTestRunner.mVideoHeight;
343        int bit_rate = MediaRecorderStressTestRunner.mBitRate;
344        boolean remove_video = MediaRecorderStressTestRunner.mRemoveVideo;
345        int record_duration = MediaRecorderStressTestRunner.mDuration;
346
347        String filename;
348        SurfaceHolder mSurfaceHolder;
349        mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
350        File stressOutFile = new File(MEDIA_STRESS_OUTPUT);
351        Writer output = new BufferedWriter(
352                new FileWriter(stressOutFile, true));
353        output.write("Video record and play back stress test:\n");
354        output.write("Total number of loops:"
355                + NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS + "\n");
356        try {
357            output.write("No of loop: ");
358            for (int i = 0; i < iterations; i++){
359                filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
360                Log.v(TAG, filename);
361                synchronized (recorderlock) {
362                    initializeRecorderMessageLooper();
363                    try {
364                        recorderlock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
365                    } catch(Exception e) {
366                        Log.v(TAG, "wait was interrupted.");
367                    }
368                }
369                Log.v(TAG, "iterations : " + iterations);
370                Log.v(TAG, "video_encoder : " + video_encoder);
371                Log.v(TAG, "audio_encoder : " + audio_encoder);
372                Log.v(TAG, "frame_rate : " + frame_rate);
373                Log.v(TAG, "video_width : " + video_width);
374                Log.v(TAG, "video_height : " + video_height);
375                Log.v(TAG, "bit rate : " + bit_rate);
376                Log.v(TAG, "record_duration : " + record_duration);
377
378                mRecorder.setOnErrorListener(mRecorderErrorCallback);
379                mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
380                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
381                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
382                mRecorder.setOutputFile(filename);
383                mRecorder.setVideoFrameRate(frame_rate);
384                mRecorder.setVideoSize(video_width, video_height);
385                mRecorder.setVideoEncoder(video_encoder);
386                mRecorder.setAudioEncoder(audio_encoder);
387                Log.v(TAG, "mediaRecorder setPreview");
388                mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
389                mRecorder.prepare();
390                mRecorder.start();
391                Thread.sleep(record_duration);
392                Log.v(TAG, "Before stop");
393                mRecorder.stop();
394                terminateRecorderMessageLooper();
395                //start the playback
396                MediaPlayer mp = new MediaPlayer();
397                mp.setDataSource(filename);
398                mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
399                mp.prepare();
400                mp.start();
401                Thread.sleep(record_duration);
402                mp.release();
403                validateRecordedVideo(filename);
404                if (remove_video) {
405                    removeRecodedVideo(filename);
406                }
407                output.write(", " + i);
408            }
409        } catch (Exception e) {
410            assertTrue("record and playback", false);
411                Log.v(TAG, e.toString());
412        }
413        output.write("\n\n");
414        output.close();
415    }
416}
417