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