1/* 2 * Copyright (C) 2008 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.functional.mediarecorder; 18 19import com.android.mediaframeworktest.MediaFrameworkTest; 20import com.android.mediaframeworktest.MediaNames; 21 22import java.io.*; 23 24import android.content.Context; 25import android.graphics.Canvas; 26import android.graphics.Color; 27import android.graphics.Paint; 28import android.graphics.Typeface; 29import android.hardware.Camera; 30import android.media.MediaCodec; 31import android.media.MediaMetadataRetriever; 32import android.media.MediaPlayer; 33import android.media.MediaRecorder; 34import android.media.EncoderCapabilities; 35import android.media.EncoderCapabilities.VideoEncoderCap; 36import android.media.EncoderCapabilities.AudioEncoderCap; 37import android.test.ActivityInstrumentationTestCase2; 38import android.util.Log; 39import android.view.Surface; 40import android.view.SurfaceHolder; 41import android.view.SurfaceView; 42import com.android.mediaframeworktest.MediaProfileReader; 43import com.android.mediaframeworktest.MediaFrameworkTestRunner; 44 45import android.test.suitebuilder.annotation.LargeTest; 46import android.test.suitebuilder.annotation.Suppress; 47import java.util.List; 48 49 50/** 51 * Junit / Instrumentation test case for the media recorder api 52 */ 53public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { 54 private String TAG = "MediaRecorderTest"; 55 private int mOutputDuration =0; 56 private int mOutputVideoWidth = 0; 57 private int mOutputVideoHeight= 0 ; 58 59 private SurfaceHolder mSurfaceHolder = null; 60 private MediaRecorder mRecorder; 61 62 private int MIN_VIDEO_FPS = 5; 63 private int HIGH_SPEED_FPS = 120; 64 65 private static final int CAMERA_ID = 0; 66 67 Context mContext; 68 Camera mCamera; 69 70 public MediaRecorderTest() { 71 super(MediaFrameworkTest.class); 72 73 } 74 75 protected void setUp() throws Exception { 76 getActivity(); 77 mRecorder = new MediaRecorder(); 78 super.setUp(); 79 } 80 81 private void recordVideo(int frameRate, int width, int height, 82 int videoFormat, int outFormat, String outFile, boolean videoOnly) { 83 Log.v(TAG,"startPreviewAndPrepareRecording"); 84 try { 85 if (!videoOnly) { 86 Log.v(TAG, "setAudioSource"); 87 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 88 } 89 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 90 mRecorder.setOutputFormat(outFormat); 91 Log.v(TAG, "output format " + outFormat); 92 mRecorder.setOutputFile(outFile); 93 mRecorder.setVideoFrameRate(frameRate); 94 mRecorder.setVideoSize(width, height); 95 Log.v(TAG, "setEncoder"); 96 mRecorder.setVideoEncoder(videoFormat); 97 if (!videoOnly) { 98 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 99 } 100 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 101 Log.v(TAG, "setPreview"); 102 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 103 Log.v(TAG, "prepare"); 104 mRecorder.prepare(); 105 Log.v(TAG, "start"); 106 mRecorder.start(); 107 Thread.sleep(MediaNames.RECORDED_TIME); 108 Log.v(TAG, "stop"); 109 mRecorder.stop(); 110 mRecorder.release(); 111 } catch (Exception e) { 112 Log.v("record video failed ", e.toString()); 113 mRecorder.release(); 114 } 115 } 116 117 private boolean validateGetSurface(boolean useSurface) { 118 Log.v(TAG,"validateGetSurface, useSurface=" + useSurface); 119 MediaRecorder recorder = new MediaRecorder(); 120 Surface surface; 121 boolean success = true; 122 try { 123 /* initialization */ 124 if (!useSurface) { 125 mCamera = Camera.open(CAMERA_ID); 126 Camera.Parameters parameters = mCamera.getParameters(); 127 parameters.setPreviewSize(352, 288); 128 parameters.set("orientation", "portrait"); 129 mCamera.setParameters(parameters); 130 mCamera.unlock(); 131 recorder.setCamera(mCamera); 132 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 133 recorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 134 } 135 136 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 137 int videoSource = useSurface ? 138 MediaRecorder.VideoSource.SURFACE : 139 MediaRecorder.VideoSource.CAMERA; 140 recorder.setVideoSource(videoSource); 141 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 142 recorder.setOutputFile(MediaNames.RECORDED_SURFACE_3GP); 143 recorder.setVideoFrameRate(30); 144 recorder.setVideoSize(352, 288); 145 recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); 146 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 147 148 /* Test: getSurface() before prepare() 149 * should throw IllegalStateException 150 */ 151 try { 152 surface = recorder.getSurface(); 153 throw new Exception("getSurface failed to throw IllegalStateException"); 154 } catch (IllegalStateException e) { 155 // OK 156 } 157 158 recorder.prepare(); 159 160 /* Test: getSurface() after prepare() 161 * should succeed for surface source 162 * should fail for camera source 163 */ 164 try { 165 surface = recorder.getSurface(); 166 if (!useSurface) { 167 throw new Exception("getSurface failed to throw IllegalStateException"); 168 } 169 } catch (IllegalStateException e) { 170 if (useSurface) { 171 throw new Exception("getSurface failed to throw IllegalStateException"); 172 } 173 } 174 175 recorder.start(); 176 177 /* Test: getSurface() after start() 178 * should succeed for surface source 179 * should fail for camera source 180 */ 181 try { 182 surface = recorder.getSurface(); 183 if (!useSurface) { 184 throw new Exception("getSurface failed to throw IllegalStateException"); 185 } 186 } catch (IllegalStateException e) { 187 if (useSurface) { 188 throw new Exception("getSurface failed to throw IllegalStateException"); 189 } 190 } 191 192 try { 193 recorder.stop(); 194 } catch (Exception e) { 195 // stop() could fail if the recording is empty, as we didn't render anything. 196 // ignore any failure in stop, we just want it stopped. 197 } 198 199 /* Test: getSurface() after stop() 200 * should throw IllegalStateException 201 */ 202 try { 203 surface = recorder.getSurface(); 204 throw new Exception("getSurface failed to throw IllegalStateException"); 205 } catch (IllegalStateException e) { 206 // OK 207 } 208 } catch (Exception e) { 209 // fail 210 success = false; 211 } 212 213 try { 214 if (mCamera != null) { 215 mCamera.lock(); 216 mCamera.release(); 217 mCamera = null; 218 } 219 recorder.release(); 220 } catch (Exception e) { 221 success = false; 222 } 223 224 return success; 225 } 226 227 private boolean recordVideoFromSurface( 228 int frameRate, int captureRate, int width, int height, 229 int videoFormat, int outFormat, String outFile, boolean videoOnly, 230 Surface persistentSurface) { 231 Log.v(TAG,"recordVideoFromSurface"); 232 MediaRecorder recorder = new MediaRecorder(); 233 int sleepTime = 33; // normal capture at 33ms / frame 234 Surface surface = null; 235 try { 236 if (!videoOnly) { 237 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 238 } 239 recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); 240 recorder.setOutputFormat(outFormat); 241 recorder.setOutputFile(outFile); 242 recorder.setVideoFrameRate(frameRate); 243 if (captureRate > 0) { 244 recorder.setCaptureRate(captureRate); 245 sleepTime = 1000 / captureRate; 246 } 247 recorder.setVideoSize(width, height); 248 recorder.setVideoEncoder(videoFormat); 249 if (!videoOnly) { 250 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 251 } 252 if (persistentSurface != null) { 253 Log.v(TAG, "using persistent surface"); 254 surface = persistentSurface; 255 recorder.setInputSurface(surface); 256 } 257 recorder.prepare(); 258 if (persistentSurface == null) { 259 surface = recorder.getSurface(); 260 } 261 262 Paint paint = new Paint(); 263 paint.setTextSize(16); 264 paint.setColor(Color.RED); 265 int i; 266 267 /* Test: draw 10 frames at 30fps before start 268 * these should be dropped and not causing malformed stream. 269 */ 270 for(i = 0; i < 10; i++) { 271 Canvas canvas = surface.lockCanvas(null); 272 int background = (i * 255 / 99); 273 canvas.drawARGB(255, background, background, background); 274 String text = "Frame #" + i; 275 canvas.drawText(text, 100, 100, paint); 276 surface.unlockCanvasAndPost(canvas); 277 Thread.sleep(sleepTime); 278 } 279 280 Log.v(TAG, "start"); 281 recorder.start(); 282 283 /* Test: draw another 90 frames at 30fps after start */ 284 for(i = 10; i < 100; i++) { 285 Canvas canvas = surface.lockCanvas(null); 286 int background = (i * 255 / 99); 287 canvas.drawARGB(255, background, background, background); 288 String text = "Frame #" + i; 289 canvas.drawText(text, 100, 100, paint); 290 surface.unlockCanvasAndPost(canvas); 291 Thread.sleep(sleepTime); 292 } 293 294 Log.v(TAG, "stop"); 295 recorder.stop(); 296 } catch (Exception e) { 297 Log.v(TAG, "record video failed: " + e.toString()); 298 return false; 299 } finally { 300 recorder.release(); 301 // release surface if not using persistent surface 302 if (persistentSurface == null && surface != null) { 303 surface.release(); 304 } 305 } 306 return true; 307 } 308 309 private boolean recordVideoWithPara(VideoEncoderCap videoCap, AudioEncoderCap audioCap, boolean highQuality){ 310 boolean recordSuccess = false; 311 int videoEncoder = videoCap.mCodec; 312 int audioEncoder = audioCap.mCodec; 313 int videoWidth = highQuality? videoCap.mMaxFrameWidth: videoCap.mMinFrameWidth; 314 int videoHeight = highQuality? videoCap.mMaxFrameHeight: videoCap.mMinFrameHeight; 315 int videoFps = highQuality? videoCap.mMaxFrameRate: videoCap.mMinFrameRate; 316 int videoBitrate = highQuality? videoCap.mMaxBitRate: videoCap.mMinBitRate; 317 int audioBitrate = highQuality? audioCap.mMaxBitRate: audioCap.mMinBitRate; 318 int audioChannels = highQuality? audioCap.mMaxChannels: audioCap.mMinChannels ; 319 int audioSamplingRate = highQuality? audioCap.mMaxSampleRate: audioCap.mMinSampleRate; 320 321 //Overide the fps if the min_camera_fps is set 322 if (MediaFrameworkTestRunner.mMinCameraFps != 0 && 323 MediaFrameworkTestRunner.mMinCameraFps > videoFps){ 324 videoFps = MediaFrameworkTestRunner.mMinCameraFps; 325 } 326 327 if (videoFps < MIN_VIDEO_FPS) { 328 videoFps = MIN_VIDEO_FPS; 329 } 330 331 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 332 String filename = ("/sdcard/" + videoEncoder + "_" + audioEncoder + "_" + highQuality + ".3gp"); 333 try { 334 Log.v(TAG, "video encoder : " + videoEncoder); 335 Log.v(TAG, "audio encoder : " + audioEncoder); 336 Log.v(TAG, "quality : " + (highQuality?"high": "low")); 337 Log.v(TAG, "encoder : " + MediaProfileReader.getVideoCodecName(videoEncoder)); 338 Log.v(TAG, "audio : " + MediaProfileReader.getAudioCodecName(audioEncoder)); 339 Log.v(TAG, "videoWidth : " + videoWidth); 340 Log.v(TAG, "videoHeight : " + videoHeight); 341 Log.v(TAG, "videoFPS : " + videoFps); 342 Log.v(TAG, "videobitrate : " + videoBitrate); 343 Log.v(TAG, "audioBitrate : " + audioBitrate); 344 Log.v(TAG, "audioChannel : " + audioChannels); 345 Log.v(TAG, "AudioSampleRate : " + audioSamplingRate); 346 347 MediaRecorder mMediaRecorder = new MediaRecorder(); 348 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 349 mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 350 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 351 mMediaRecorder.setOutputFile(filename); 352 mMediaRecorder.setVideoFrameRate(videoFps); 353 mMediaRecorder.setVideoSize(videoWidth, videoHeight); 354 mMediaRecorder.setVideoEncodingBitRate(videoBitrate); 355 mMediaRecorder.setAudioEncodingBitRate(audioBitrate); 356 mMediaRecorder.setAudioChannels(audioChannels); 357 mMediaRecorder.setAudioSamplingRate(audioSamplingRate); 358 mMediaRecorder.setVideoEncoder(videoEncoder); 359 mMediaRecorder.setAudioEncoder(audioEncoder); 360 mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 361 mMediaRecorder.prepare(); 362 mMediaRecorder.start(); 363 Thread.sleep(MediaNames.RECORDED_TIME); 364 mMediaRecorder.stop(); 365 mMediaRecorder.release(); 366 recordSuccess = validateVideo(filename, videoWidth, videoHeight); 367 } catch (Exception e) { 368 Log.v(TAG, e.toString()); 369 return false; 370 } 371 return recordSuccess; 372 } 373 374 private boolean invalidRecordSetting(int frameRate, int width, int height, 375 int videoFormat, int outFormat, String outFile, boolean videoOnly) { 376 try { 377 if (!videoOnly) { 378 Log.v(TAG, "setAudioSource"); 379 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 380 } 381 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 382 mRecorder.setOutputFormat(outFormat); 383 Log.v(TAG, "output format " + outFormat); 384 mRecorder.setOutputFile(outFile); 385 mRecorder.setVideoFrameRate(frameRate); 386 mRecorder.setVideoSize(width, height); 387 Log.v(TAG, "setEncoder"); 388 mRecorder.setVideoEncoder(videoFormat); 389 if (!videoOnly) { 390 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 391 } 392 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 393 Log.v(TAG, "setPreview"); 394 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 395 Log.v(TAG, "prepare"); 396 mRecorder.prepare(); 397 Log.v(TAG, "start"); 398 mRecorder.start(); 399 Thread.sleep(MediaNames.RECORDED_TIME); 400 Log.v(TAG, "stop"); 401 mRecorder.stop(); 402 mRecorder.release(); 403 } catch (Exception e) { 404 Log.v("record video failed ", e.toString()); 405 mRecorder.release(); 406 Log.v(TAG, "reset and release"); 407 return true; 408 } 409 return false; 410 } 411 412 private void getOutputVideoProperty(String outputFilePath) { 413 MediaPlayer mediaPlayer = new MediaPlayer(); 414 try { 415 mediaPlayer.setDataSource(outputFilePath); 416 Log.v(TAG, "file Path = " + outputFilePath); 417 mediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 418 Log.v(TAG, "before player prepare"); 419 mediaPlayer.prepare(); 420 Log.v(TAG, "before getduration"); 421 mOutputDuration = mediaPlayer.getDuration(); 422 Log.v(TAG, "get video dimension"); 423 Thread.sleep(1000); 424 mOutputVideoHeight = mediaPlayer.getVideoHeight(); 425 mOutputVideoWidth = mediaPlayer.getVideoWidth(); 426 mediaPlayer.release(); 427 } catch (Exception e) { 428 Log.v(TAG, e.toString()); 429 mediaPlayer.release(); 430 } 431 } 432 433 private boolean validateVideo(String filePath, int width, int height) { 434 boolean validVideo = false; 435 getOutputVideoProperty(filePath); 436 if (mOutputVideoWidth == width && mOutputVideoHeight == height && 437 mOutputDuration > MediaNames.VALID_VIDEO_DURATION ) { 438 validVideo = true; 439 } 440 Log.v(TAG, "width = " + mOutputVideoWidth + " height = " + mOutputVideoHeight + " Duration = " + mOutputDuration); 441 return validVideo; 442 } 443 444 private boolean validateMetadata(String filePath, int captureRate) { 445 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 446 447 retriever.setDataSource(filePath); 448 449 // verify capture rate meta key is present and correct 450 String captureFps = retriever.extractMetadata( 451 MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE); 452 453 if (captureFps == null) { 454 Log.d(TAG, "METADATA_KEY_CAPTURE_FRAMERATE is missing"); 455 return false; 456 } 457 458 if (Math.abs(Float.parseFloat(captureFps) - captureRate) > 0.001) { 459 Log.d(TAG, "METADATA_KEY_CAPTURE_FRAMERATE is incorrect: " 460 + captureFps + "vs. " + captureRate); 461 return false; 462 } 463 464 // verify other meta keys here if necessary 465 return true; 466 } 467 @LargeTest 468 /* 469 * This test case set the camera in portrait mode. 470 * Verification: validate the video dimension and the duration. 471 */ 472 public void testPortraitH263() throws Exception { 473 boolean videoRecordedResult = false; 474 try { 475 mCamera = Camera.open(CAMERA_ID); 476 Camera.Parameters parameters = mCamera.getParameters(); 477 parameters.setPreviewSize(352, 288); 478 parameters.set("orientation", "portrait"); 479 mCamera.setParameters(parameters); 480 mCamera.unlock(); 481 mRecorder.setCamera(mCamera); 482 Thread.sleep(1000); 483 int codec = MediaRecorder.VideoEncoder.H263; 484 int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec); 485 recordVideo(frameRate, 352, 288, codec, 486 MediaRecorder.OutputFormat.THREE_GPP, 487 MediaNames.RECORDED_PORTRAIT_H263, true); 488 mCamera.lock(); 489 mCamera.release(); 490 videoRecordedResult = 491 validateVideo(MediaNames.RECORDED_PORTRAIT_H263, 352, 288); 492 } catch (Exception e) { 493 Log.v(TAG, e.toString()); 494 } 495 assertTrue("PortraitH263", videoRecordedResult); 496 } 497 498 @LargeTest 499 public void testInvalidVideoPath() throws Exception { 500 boolean isTestInvalidVideoPathSuccessful = false; 501 isTestInvalidVideoPathSuccessful = invalidRecordSetting(15, 176, 144, MediaRecorder.VideoEncoder.H263, 502 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.INVALD_VIDEO_PATH, false); 503 assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful); 504 } 505 506 @LargeTest 507 //test cases for the new codec 508 public void testDeviceSpecificCodec() throws Exception { 509 int noOfFailure = 0; 510 boolean recordSuccess = false; 511 String deviceType = MediaProfileReader.getDeviceType(); 512 Log.v(TAG, "deviceType = " + deviceType); 513 List<VideoEncoderCap> videoEncoders = MediaProfileReader.getVideoEncoders(); 514 List<AudioEncoderCap> audioEncoders = MediaProfileReader.getAudioEncoders(); 515 for (int k = 0; k < 2; k++) { 516 for (VideoEncoderCap videoEncoder: videoEncoders) { 517 for (AudioEncoderCap audioEncoder: audioEncoders) { 518 if (k == 0) { 519 recordSuccess = recordVideoWithPara(videoEncoder, audioEncoder, true); 520 } else { 521 recordSuccess = recordVideoWithPara(videoEncoder, audioEncoder, false); 522 } 523 if (!recordSuccess) { 524 Log.v(TAG, "testDeviceSpecificCodec failed"); 525 Log.v(TAG, "Encoder = " + videoEncoder.mCodec + "Audio Encoder = " + audioEncoder.mCodec); 526 noOfFailure++; 527 } 528 } 529 } 530 } 531 if (noOfFailure != 0) { 532 assertTrue("testDeviceSpecificCodec", false); 533 } 534 } 535 536 // Test MediaRecorder.getSurface() api with surface or camera source 537 public void testGetSurfaceApi() { 538 boolean success = false; 539 int noOfFailure = 0; 540 try { 541 for (int k = 0; k < 2; k++) { 542 success = validateGetSurface( 543 k == 0 ? true : false /* useSurface */); 544 if (!success) { 545 noOfFailure++; 546 } 547 } 548 } catch (Exception e) { 549 Log.v(TAG, e.toString()); 550 } 551 assertTrue("testGetSurfaceApi", noOfFailure == 0); 552 } 553 554 // Test recording from surface source with/without audio 555 public void testSurfaceRecording() { 556 boolean success = false; 557 int noOfFailure = 0; 558 try { 559 int codec = MediaRecorder.VideoEncoder.H264; 560 int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec); 561 for (int k = 0; k < 2; k++) { 562 String filename = "/sdcard/surface_" + 563 (k==0?"video_only":"with_audio") + ".3gp"; 564 565 success = recordVideoFromSurface(frameRate, 0, 352, 288, codec, 566 MediaRecorder.OutputFormat.THREE_GPP, filename, 567 k == 0 ? true : false /* videoOnly */, null); 568 if (success) { 569 success = validateVideo(filename, 352, 288); 570 } 571 if (!success) { 572 noOfFailure++; 573 } 574 } 575 } catch (Exception e) { 576 Log.v(TAG, e.toString()); 577 } 578 assertTrue("testSurfaceRecording", noOfFailure == 0); 579 } 580 581 public void testPersistentSurfaceRecording() { 582 boolean success = false; 583 int noOfFailure = 0; 584 Surface surface = null; 585 try { 586 int codec = MediaRecorder.VideoEncoder.H264; 587 int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec); 588 surface = MediaCodec.createPersistentInputSurface(); 589 for (int k = 0; k < 2; k++) { 590 String filename = "/sdcard/surface_persistent" + k + ".3gp"; 591 592 Log.v(TAG, "test persistent surface - round " + k); 593 success = recordVideoFromSurface(frameRate, 0, 352, 288, codec, 594 MediaRecorder.OutputFormat.THREE_GPP, filename, 595 true /* videoOnly */, surface); 596 if (success) { 597 success = validateVideo(filename, 352, 288); 598 } 599 if (!success) { 600 noOfFailure++; 601 } 602 } 603 } catch (Exception e) { 604 Log.v(TAG, e.toString()); 605 } finally { 606 if (surface != null) { 607 Log.v(TAG, "releasing persistent surface"); 608 surface.release(); 609 surface = null; 610 } 611 } 612 assertTrue("testPersistentSurfaceRecording", noOfFailure == 0); 613 } 614 615 // Test recording from surface source with/without audio 616 public void testSurfaceRecordingTimeLapse() { 617 boolean success = false; 618 int noOfFailure = 0; 619 try { 620 int codec = MediaRecorder.VideoEncoder.H264; 621 int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec); 622 for (int k = 0; k < 2; k++) { 623 // k==0: time lapse test, set capture rate to MIN_VIDEO_FPS 624 // k==1: slow motion test, set capture rate to HIGH_SPEED_FPS 625 String filename = "/sdcard/surface_" + 626 (k==0 ? "time_lapse" : "slow_motion") + ".3gp"; 627 628 // always set videoOnly=false, MediaRecorder should disable 629 // audio automatically with time lapse/slow motion 630 int captureRate = k==0 ? MIN_VIDEO_FPS : HIGH_SPEED_FPS; 631 success = recordVideoFromSurface( 632 frameRate, captureRate, 352, 288, codec, 633 MediaRecorder.OutputFormat.THREE_GPP, 634 filename, false /* videoOnly */, null); 635 if (success) { 636 success = validateVideo(filename, 352, 288); 637 if (success) { 638 success = validateMetadata(filename, captureRate); 639 } 640 } 641 if (!success) { 642 noOfFailure++; 643 } 644 } 645 } catch (Exception e) { 646 Log.v(TAG, e.toString()); 647 noOfFailure++; 648 } 649 assertTrue("testSurfaceRecordingTimeLapse", noOfFailure == 0); 650 } 651 652} 653