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