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 17 package com.android.mediaframeworktest.functional.mediarecorder; 18 19 import com.android.mediaframeworktest.MediaFrameworkTest; 20 import com.android.mediaframeworktest.MediaNames; 21 22 import java.io.*; 23 24 import android.content.Context; 25 import android.graphics.Canvas; 26 import android.graphics.Color; 27 import android.graphics.Paint; 28 import android.graphics.Typeface; 29 import android.hardware.Camera; 30 import android.media.MediaCodec; 31 import android.media.MediaMetadataRetriever; 32 import android.media.MediaPlayer; 33 import android.media.MediaRecorder; 34 import android.media.EncoderCapabilities; 35 import android.media.EncoderCapabilities.VideoEncoderCap; 36 import android.media.EncoderCapabilities.AudioEncoderCap; 37 import android.test.ActivityInstrumentationTestCase2; 38 import android.util.Log; 39 import android.view.Surface; 40 import android.view.SurfaceHolder; 41 import android.view.SurfaceView; 42 import com.android.mediaframeworktest.MediaProfileReader; 43 import com.android.mediaframeworktest.MediaFrameworkTestRunner; 44 45 import android.test.suitebuilder.annotation.LargeTest; 46 import android.test.suitebuilder.annotation.Suppress; 47 import java.util.List; 48 49 50 /** 51 * Junit / Instrumentation test case for the media recorder api 52 */ 53 public 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 MediaRecorderTest()70 public MediaRecorderTest() { 71 super(MediaFrameworkTest.class); 72 73 } 74 setUp()75 protected void setUp() throws Exception { 76 getActivity(); 77 mRecorder = new MediaRecorder(); 78 super.setUp(); 79 } 80 recordVideo(int frameRate, int width, int height, int videoFormat, int outFormat, String outFile, boolean videoOnly)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 validateGetSurface(boolean useSurface)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 recordVideoFromSurface( int frameRate, int captureRate, int width, int height, int videoFormat, int outFormat, String outFile, boolean videoOnly, Surface persistentSurface)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 recordVideoWithPara(VideoEncoderCap videoCap, AudioEncoderCap audioCap, boolean highQuality)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 invalidRecordSetting(int frameRate, int width, int height, int videoFormat, int outFormat, String outFile, boolean videoOnly)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 getOutputVideoProperty(String outputFilePath)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 validateVideo(String filePath, int width, int height)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 validateMetadata(String filePath, int captureRate)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 */ testPortraitH263()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 testInvalidVideoPath()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 testDeviceSpecificCodec()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 testGetSurfaceApi()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 testSurfaceRecording()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 testPersistentSurfaceRecording()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 testSurfaceRecordingTimeLapse()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