MediaRecorderStressTest.java revision 27c8d9ba169aa85127fac65d6df25e4335ee2fca
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.IOException; 26import java.io.Writer; 27import java.util.concurrent.Semaphore; 28import java.util.concurrent.TimeUnit; 29 30import android.hardware.Camera; 31import android.media.CamcorderProfile; 32import android.media.MediaPlayer; 33import android.media.MediaRecorder; 34import android.os.Handler; 35import android.os.Looper; 36import android.test.ActivityInstrumentationTestCase2; 37import android.test.suitebuilder.annotation.LargeTest; 38import android.util.Log; 39import android.view.SurfaceHolder; 40import com.android.mediaframeworktest.MediaRecorderStressTestRunner; 41 42/** 43 * Junit / Instrumentation test case for the media player api 44 */ 45public 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 Log.v(TAG, "mediaRecorder setPreview"); 369 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 370 mRecorder.prepare(); 371 mRecorder.start(); 372 Thread.sleep(record_duration); 373 Log.v(TAG, "Before stop"); 374 mRecorder.stop(); 375 mRecorder.release(); 376 //start the playback 377 MediaPlayer mp = new MediaPlayer(); 378 mp.setDataSource(filename); 379 mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 380 mp.prepare(); 381 mp.start(); 382 Thread.sleep(record_duration); 383 mp.release(); 384 validateRecordedVideo(filename); 385 if (remove_video) { 386 removeRecordedVideo(filename); 387 } 388 output.write(", " + i); 389 } 390 } catch (Exception e) { 391 Log.v(TAG, e.toString()); 392 assertTrue("record and playback", false); 393 } 394 output.write("\n\n"); 395 output.close(); 396 } 397 398 // Test case for stressing time lapse 399 @LargeTest 400 public void testStressTimeLapse() throws Exception { 401 SurfaceHolder mSurfaceHolder; 402 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 403 int record_duration = MediaRecorderStressTestRunner.mTimeLapseDuration; 404 boolean remove_video = MediaRecorderStressTestRunner.mRemoveVideo; 405 double captureRate = MediaRecorderStressTestRunner.mCaptureRate; 406 String filename; 407 File stressOutFile = new File(MEDIA_STRESS_OUTPUT); 408 Writer output = new BufferedWriter(new FileWriter(stressOutFile, true)); 409 output.write("Start camera time lapse stress:\n"); 410 output.write("Total number of loops: " + NUMBER_OF_TIME_LAPSE_LOOPS + "\n"); 411 412 try { 413 output.write("No of loop: "); 414 for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) { 415 filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT; 416 Log.v(TAG, filename); 417 runOnLooper(new Runnable() { 418 @Override 419 public void run() { 420 mRecorder = new MediaRecorder(); 421 } 422 }); 423 424 // Set callback 425 mRecorder.setOnErrorListener(mRecorderErrorCallback); 426 427 // Set video source 428 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 429 430 // Set camcorder profile for time lapse 431 CamcorderProfile profile = 432 CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH); 433 mRecorder.setProfile(profile); 434 435 // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc. 436 // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video 437 mRecorder.setCaptureRate(captureRate); 438 439 // Set output file 440 mRecorder.setOutputFile(filename); 441 442 // Set the preview display 443 Log.v(TAG, "mediaRecorder setPreviewDisplay"); 444 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 445 446 mRecorder.prepare(); 447 mRecorder.start(); 448 Thread.sleep(record_duration); 449 Log.v(TAG, "Before stop"); 450 mRecorder.stop(); 451 mRecorder.release(); 452 453 // Start the playback 454 MediaPlayer mp = new MediaPlayer(); 455 mp.setDataSource(filename); 456 mp.setDisplay(mSurfaceHolder); 457 mp.prepare(); 458 mp.start(); 459 Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME); 460 mp.release(); 461 validateRecordedVideo(filename); 462 if(remove_video) { 463 removeRecordedVideo(filename); 464 } 465 output.write(", " + i); 466 } 467 } 468 catch (IllegalStateException e) { 469 assertTrue("Camera time lapse stress test IllegalStateException", false); 470 Log.v(TAG, e.toString()); 471 } 472 catch (IOException e) { 473 assertTrue("Camera time lapse stress test IOException", false); 474 Log.v(TAG, e.toString()); 475 } 476 catch (Exception e) { 477 assertTrue("Camera time lapse stress test Exception", false); 478 Log.v(TAG, e.toString()); 479 } 480 output.write("\n\n"); 481 output.close(); 482 } 483} 484