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; 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.hardware.Camera; 26 import android.media.MediaPlayer; 27 import android.media.MediaRecorder; 28 import android.media.EncoderCapabilities; 29 import android.media.EncoderCapabilities.VideoEncoderCap; 30 import android.media.EncoderCapabilities.AudioEncoderCap; 31 import android.test.ActivityInstrumentationTestCase; 32 import android.util.Log; 33 import android.view.SurfaceHolder; 34 import android.view.SurfaceView; 35 import com.android.mediaframeworktest.MediaProfileReader; 36 37 import android.test.suitebuilder.annotation.LargeTest; 38 import android.test.suitebuilder.annotation.Suppress; 39 import java.util.List; 40 41 42 /** 43 * Junit / Instrumentation test case for the media recorder api 44 */ 45 public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> { 46 private String TAG = "MediaRecorderTest"; 47 private int mOutputDuration =0; 48 private int mOutputVideoWidth = 0; 49 private int mOutputVideoHeight= 0 ; 50 51 private SurfaceHolder mSurfaceHolder = null; 52 private MediaRecorder mRecorder; 53 54 private int MIN_VIDEO_FPS = 5; 55 56 Context mContext; 57 Camera mCamera; 58 59 public MediaRecorderTest() { 60 super("com.android.mediaframeworktest", MediaFrameworkTest.class); 61 62 } 63 64 protected void setUp() throws Exception { 65 super.setUp(); 66 Log.v(TAG,"create the media recorder"); 67 mRecorder = new MediaRecorder(); 68 } 69 70 private void recordVideo(int frameRate, int width, int height, 71 int videoFormat, int outFormat, String outFile, boolean videoOnly) { 72 Log.v(TAG,"startPreviewAndPrepareRecording"); 73 try { 74 if (!videoOnly) { 75 Log.v(TAG, "setAudioSource"); 76 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 77 } 78 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 79 mRecorder.setOutputFormat(outFormat); 80 Log.v(TAG, "output format " + outFormat); 81 mRecorder.setOutputFile(outFile); 82 mRecorder.setVideoFrameRate(frameRate); 83 mRecorder.setVideoSize(width, height); 84 Log.v(TAG, "setEncoder"); 85 mRecorder.setVideoEncoder(videoFormat); 86 if (!videoOnly) { 87 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 88 } 89 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 90 Log.v(TAG, "setPreview"); 91 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 92 Log.v(TAG, "prepare"); 93 mRecorder.prepare(); 94 Log.v(TAG, "start"); 95 mRecorder.start(); 96 Thread.sleep(MediaNames.RECORDED_TIME); 97 Log.v(TAG, "stop"); 98 mRecorder.stop(); 99 mRecorder.release(); 100 } catch (Exception e) { 101 Log.v("record video failed ", e.toString()); 102 mRecorder.release(); 103 } 104 } 105 106 private boolean recordVideoWithPara(VideoEncoderCap videoCap, AudioEncoderCap audioCap, boolean highQuality){ 107 boolean recordSuccess = false; 108 int videoEncoder = videoCap.mCodec; 109 int audioEncoder = audioCap.mCodec; 110 int videoWidth = highQuality? videoCap.mMaxFrameWidth: videoCap.mMinFrameWidth; 111 int videoHeight = highQuality? videoCap.mMaxFrameHeight: videoCap.mMinFrameHeight; 112 int videoFps = highQuality? videoCap.mMaxFrameRate: videoCap.mMinFrameRate; 113 int videoBitrate = highQuality? videoCap.mMaxBitRate: videoCap.mMinBitRate; 114 int audioBitrate = highQuality? audioCap.mMaxBitRate: audioCap.mMinBitRate; 115 int audioChannels = highQuality? audioCap.mMaxChannels: audioCap.mMinChannels ; 116 int audioSamplingRate = highQuality? audioCap.mMaxSampleRate: audioCap.mMinSampleRate; 117 118 if (videoFps < MIN_VIDEO_FPS) { 119 videoFps = MIN_VIDEO_FPS; 120 } 121 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 122 String filename = ("/sdcard/" + videoEncoder + "_" + audioEncoder + "_" + highQuality + ".3gp"); 123 try { 124 Log.v(TAG, "video encoder : " + videoEncoder); 125 Log.v(TAG, "audio encoder : " + audioEncoder); 126 Log.v(TAG, "quality : " + (highQuality?"high": "low")); 127 Log.v(TAG, "encoder : " + MediaProfileReader.getVideoCodecName(videoEncoder)); 128 Log.v(TAG, "audio : " + MediaProfileReader.getAudioCodecName(audioEncoder)); 129 Log.v(TAG, "videoWidth : " + videoWidth); 130 Log.v(TAG, "videoHeight : " + videoHeight); 131 Log.v(TAG, "videoFPS : " + videoFps); 132 Log.v(TAG, "videobitrate : " + videoBitrate); 133 Log.v(TAG, "audioBitrate : " + audioBitrate); 134 Log.v(TAG, "audioChannel : " + audioChannels); 135 Log.v(TAG, "AudioSampleRate : " + audioSamplingRate); 136 137 MediaRecorder mMediaRecorder = new MediaRecorder(); 138 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 139 mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 140 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 141 mMediaRecorder.setOutputFile(filename); 142 mMediaRecorder.setVideoFrameRate(videoFps); 143 mMediaRecorder.setVideoSize(videoWidth, videoHeight); 144 mMediaRecorder.setVideoEncodingBitRate(videoBitrate); 145 mMediaRecorder.setAudioEncodingBitRate(audioBitrate); 146 mMediaRecorder.setAudioChannels(audioChannels); 147 mMediaRecorder.setAudioSamplingRate(audioSamplingRate); 148 mMediaRecorder.setVideoEncoder(videoEncoder); 149 mMediaRecorder.setAudioEncoder(audioEncoder); 150 mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 151 mMediaRecorder.prepare(); 152 mMediaRecorder.start(); 153 Thread.sleep(MediaNames.RECORDED_TIME); 154 mMediaRecorder.stop(); 155 mMediaRecorder.release(); 156 recordSuccess = validateVideo(filename, videoWidth, videoHeight); 157 } catch (Exception e) { 158 Log.v(TAG, e.toString()); 159 return false; 160 } 161 return recordSuccess; 162 } 163 164 private boolean invalidRecordSetting(int frameRate, int width, int height, 165 int videoFormat, int outFormat, String outFile, boolean videoOnly) { 166 try { 167 if (!videoOnly) { 168 Log.v(TAG, "setAudioSource"); 169 mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 170 } 171 mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 172 mRecorder.setOutputFormat(outFormat); 173 Log.v(TAG, "output format " + outFormat); 174 mRecorder.setOutputFile(outFile); 175 mRecorder.setVideoFrameRate(frameRate); 176 mRecorder.setVideoSize(width, height); 177 Log.v(TAG, "setEncoder"); 178 mRecorder.setVideoEncoder(videoFormat); 179 if (!videoOnly) { 180 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 181 } 182 mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder(); 183 Log.v(TAG, "setPreview"); 184 mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 185 Log.v(TAG, "prepare"); 186 mRecorder.prepare(); 187 Log.v(TAG, "start"); 188 mRecorder.start(); 189 Thread.sleep(MediaNames.RECORDED_TIME); 190 Log.v(TAG, "stop"); 191 mRecorder.stop(); 192 mRecorder.release(); 193 } catch (Exception e) { 194 Log.v("record video failed ", e.toString()); 195 mRecorder.release(); 196 Log.v(TAG, "reset and release"); 197 return true; 198 } 199 return false; 200 } 201 202 203 204 private void getOutputVideoProperty(String outputFilePath) { 205 MediaPlayer mediaPlayer = new MediaPlayer(); 206 try { 207 mediaPlayer.setDataSource(outputFilePath); 208 Log.v(TAG, "file Path = " + outputFilePath); 209 mediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder()); 210 Log.v(TAG, "before player prepare"); 211 mediaPlayer.prepare(); 212 Log.v(TAG, "before getduration"); 213 mOutputDuration = mediaPlayer.getDuration(); 214 Log.v(TAG, "get video dimension"); 215 Thread.sleep(1000); 216 mOutputVideoHeight = mediaPlayer.getVideoHeight(); 217 mOutputVideoWidth = mediaPlayer.getVideoWidth(); 218 //mOutputVideoHeight = CodecTest.videoHeight(outputFilePath); 219 //mOutputVideoWidth = CodecTest.videoWidth(outputFilePath); 220 mediaPlayer.release(); 221 } catch (Exception e) { 222 Log.v(TAG, e.toString()); 223 mediaPlayer.release(); 224 } 225 } 226 227 private void removeFile(String filePath) { 228 File fileRemove = new File(filePath); 229 fileRemove.delete(); 230 } 231 232 private boolean validateVideo(String filePath, int width, int height) { 233 boolean validVideo = false; 234 getOutputVideoProperty(filePath); 235 if (mOutputVideoWidth == width && mOutputVideoHeight == height && 236 mOutputDuration > MediaNames.VALID_VIDEO_DURATION ) { 237 validVideo = true; 238 } 239 Log.v(TAG, "width = " + mOutputVideoWidth + " height = " + mOutputVideoHeight + " Duration = " + mOutputDuration); 240 //removeFile(filePath); 241 return validVideo; 242 } 243 244 245 //Format: HVGA h263 246 @Suppress 247 public void testHVGAH263() throws Exception { 248 boolean videoRecordedResult = false; 249 recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.H263, 250 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_HVGA_H263, false); 251 videoRecordedResult = validateVideo(MediaNames.RECORDED_HVGA_H263, 480, 320); 252 assertTrue("HVGAH263", videoRecordedResult); 253 } 254 255 //Format: QVGA h263 256 @LargeTest 257 public void testQVGAH263() throws Exception { 258 boolean videoRecordedResult = false; 259 recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.H263, 260 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_QVGA_H263, false); 261 videoRecordedResult = validateVideo(MediaNames.RECORDED_QVGA_H263, 320, 240); 262 assertTrue("QVGAH263", videoRecordedResult); 263 } 264 265 //Format: SQVGA h263 266 @LargeTest 267 public void testSQVGAH263() throws Exception { 268 boolean videoRecordedResult = false; 269 recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.H263, 270 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_SQVGA_H263, false); 271 videoRecordedResult = validateVideo(MediaNames.RECORDED_SQVGA_H263, 240, 160); 272 assertTrue("SQVGAH263", videoRecordedResult); 273 } 274 275 //Format: QCIF h263 276 @LargeTest 277 public void testQCIFH263() throws Exception { 278 boolean videoRecordedResult = false; 279 recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263, 280 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_QCIF_H263, false); 281 videoRecordedResult = validateVideo(MediaNames.RECORDED_QCIF_H263, 176, 144); 282 assertTrue("QCIFH263", videoRecordedResult); 283 } 284 285 //Format: CIF h263 286 @LargeTest 287 public void testCIFH263() throws Exception { 288 boolean videoRecordedResult = false; 289 recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263, 290 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_CIF_H263, false); 291 videoRecordedResult = validateVideo(MediaNames.RECORDED_CIF_H263, 352, 288); 292 assertTrue("CIFH263", videoRecordedResult); 293 } 294 295 296 297 @LargeTest 298 public void testVideoOnly() throws Exception { 299 boolean videoRecordedResult = false; 300 recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263, 301 MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true); 302 videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144); 303 assertTrue("QCIFH263 Video Only", videoRecordedResult); 304 } 305 306 @LargeTest 307 /* 308 * This test case set the camera in portrait mode. 309 * Verification: validate the video dimension and the duration. 310 */ 311 public void testPortraitH263() throws Exception { 312 boolean videoRecordedResult = false; 313 try { 314 mCamera = Camera.open(); 315 Camera.Parameters parameters = mCamera.getParameters(); 316 parameters.setPreviewSize(352, 288); 317 parameters.set("orientation", "portrait"); 318 mCamera.setParameters(parameters); 319 mCamera.unlock(); 320 mRecorder.setCamera(mCamera); 321 Thread.sleep(1000); 322 recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.H263, 323 MediaRecorder.OutputFormat.THREE_GPP, 324 MediaNames.RECORDED_PORTRAIT_H263, true); 325 mCamera.lock(); 326 mCamera.release(); 327 videoRecordedResult = 328 validateVideo(MediaNames.RECORDED_PORTRAIT_H263, 352, 288); 329 } catch (Exception e) { 330 Log.v(TAG, e.toString()); 331 } 332 assertTrue("PortraitH263", videoRecordedResult); 333 } 334 335 @Suppress 336 public void testHVGAMP4() throws Exception { 337 boolean videoRecordedResult = false; 338 recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.MPEG_4_SP, 339 MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_HVGA_MP4, false); 340 videoRecordedResult = validateVideo(MediaNames.RECORDED_HVGA_MP4, 480, 320); 341 assertTrue("HVGAMP4", videoRecordedResult); 342 } 343 344 @LargeTest 345 public void testQVGAMP4() throws Exception { 346 boolean videoRecordedResult = false; 347 recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.MPEG_4_SP, 348 MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_QVGA_MP4, false); 349 videoRecordedResult = validateVideo(MediaNames.RECORDED_QVGA_MP4, 320, 240); 350 assertTrue("QVGAMP4", videoRecordedResult); 351 } 352 353 @LargeTest 354 public void testSQVGAMP4() throws Exception { 355 boolean videoRecordedResult = false; 356 recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.MPEG_4_SP, 357 MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_SQVGA_MP4, false); 358 videoRecordedResult = validateVideo(MediaNames.RECORDED_SQVGA_MP4, 240, 160); 359 assertTrue("SQVGAMP4", videoRecordedResult); 360 } 361 362 //Format: QCIF MP4 363 @LargeTest 364 public void testQCIFMP4() throws Exception { 365 boolean videoRecordedResult = false; 366 recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.MPEG_4_SP, 367 MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_QCIF_MP4, false); 368 videoRecordedResult = validateVideo(MediaNames.RECORDED_QCIF_MP4, 176, 144); 369 assertTrue("QCIFMP4", videoRecordedResult); 370 } 371 372 373 //Format: CIF MP4 374 @LargeTest 375 public void testCIFMP4() throws Exception { 376 boolean videoRecordedResult = false; 377 recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP, 378 MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_CIF_MP4, false); 379 videoRecordedResult = validateVideo(MediaNames.RECORDED_CIF_MP4, 352, 288); 380 assertTrue("CIFMP4", videoRecordedResult); 381 } 382 383 384 //Format: CIF MP4 output format 3gpp 385 @LargeTest 386 public void testCIFMP43GPP() throws Exception { 387 boolean videoRecordedResult = false; 388 recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP, 389 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); 390 videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 352, 288); 391 assertTrue("CIFMP4 3GPP", videoRecordedResult); 392 } 393 394 @LargeTest 395 public void testQCIFH2633GPP() throws Exception { 396 boolean videoRecordedResult = false; 397 recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263, 398 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); 399 videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144); 400 assertTrue("QCIFH263 3GPP", videoRecordedResult); 401 } 402 403 @LargeTest 404 public void testInvalidVideoPath() throws Exception { 405 boolean isTestInvalidVideoPathSuccessful = false; 406 isTestInvalidVideoPathSuccessful = invalidRecordSetting(15, 176, 144, MediaRecorder.VideoEncoder.H263, 407 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.INVALD_VIDEO_PATH, false); 408 assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful); 409 } 410 411 @Suppress 412 public void testInvalidVideoSize() throws Exception { 413 boolean isTestInvalidVideoSizeSuccessful = false; 414 isTestInvalidVideoSizeSuccessful = invalidRecordSetting(15, 800, 600, MediaRecorder.VideoEncoder.H263, 415 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); 416 assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful); 417 } 418 419 @Suppress 420 @LargeTest 421 public void testInvalidFrameRate() throws Exception { 422 boolean isTestInvalidFrameRateSuccessful = false; 423 isTestInvalidFrameRateSuccessful = invalidRecordSetting(50, 176, 144, MediaRecorder.VideoEncoder.H263, 424 MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false); 425 assertTrue("Invalid FrameRate", isTestInvalidFrameRateSuccessful); 426 } 427 428 @LargeTest 429 //test cases for the new codec 430 public void testDeviceSpecificCodec() throws Exception { 431 int noOfFailure = 0; 432 boolean recordSuccess = false; 433 String deviceType = MediaProfileReader.getDeviceType(); 434 Log.v(TAG, "deviceType = " + deviceType); 435 List<VideoEncoderCap> videoEncoders = MediaProfileReader.getVideoEncoders(); 436 List<AudioEncoderCap> audioEncoders = MediaProfileReader.getAudioEncoders(); 437 for (int k = 0; k < 2; k++) { 438 for (VideoEncoderCap videoEncoder: videoEncoders) { 439 for (AudioEncoderCap audioEncoder: audioEncoders) { 440 if (k == 0) { 441 recordSuccess = recordVideoWithPara(videoEncoder, audioEncoder, true); 442 } else { 443 recordSuccess = recordVideoWithPara(videoEncoder, audioEncoder, false); 444 } 445 if (!recordSuccess) { 446 Log.v(TAG, "testDeviceSpecificCodec failed"); 447 Log.v(TAG, "Encoder = " + videoEncoder.mCodec + "Audio Encoder = " + audioEncoder.mCodec); 448 noOfFailure++; 449 } 450 } 451 } 452 } 453 if (noOfFailure != 0) { 454 assertTrue("testDeviceSpecificCodec", false); 455 } 456 } 457 } 458