1 /* 2 * Copyright (C) 2010 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 android.media.cts; 18 19 import android.content.pm.PackageManager; 20 import android.hardware.Camera; 21 import android.hardware.Camera.Parameters; 22 import android.hardware.Camera.Size; 23 import android.hardware.cts.helpers.CameraUtils; 24 import android.media.CamcorderProfile; 25 import android.media.EncoderProfiles; 26 import android.media.MediaCodecInfo; 27 import android.media.MediaFormat; 28 import android.media.MediaRecorder; 29 import android.test.AndroidTestCase; 30 import android.util.Log; 31 32 import java.util.Arrays; 33 import java.util.List; 34 35 @NonMediaMainlineTest 36 public class CamcorderProfileTest extends AndroidTestCase { 37 38 private static final String TAG = "CamcorderProfileTest"; 39 private static final int MIN_HIGH_SPEED_FPS = 100; 40 private static final Integer[] ALL_SUPPORTED_QUALITIES = { 41 CamcorderProfile.QUALITY_LOW, 42 CamcorderProfile.QUALITY_HIGH, 43 CamcorderProfile.QUALITY_QCIF, 44 CamcorderProfile.QUALITY_CIF, 45 CamcorderProfile.QUALITY_480P, 46 CamcorderProfile.QUALITY_720P, 47 CamcorderProfile.QUALITY_1080P, 48 CamcorderProfile.QUALITY_QVGA, 49 CamcorderProfile.QUALITY_2160P, 50 CamcorderProfile.QUALITY_VGA, 51 CamcorderProfile.QUALITY_4KDCI, 52 CamcorderProfile.QUALITY_QHD, 53 CamcorderProfile.QUALITY_2K, 54 CamcorderProfile.QUALITY_8KUHD, 55 56 CamcorderProfile.QUALITY_TIME_LAPSE_LOW, 57 CamcorderProfile.QUALITY_TIME_LAPSE_HIGH, 58 CamcorderProfile.QUALITY_TIME_LAPSE_QCIF, 59 CamcorderProfile.QUALITY_TIME_LAPSE_CIF, 60 CamcorderProfile.QUALITY_TIME_LAPSE_480P, 61 CamcorderProfile.QUALITY_TIME_LAPSE_720P, 62 CamcorderProfile.QUALITY_TIME_LAPSE_1080P, 63 CamcorderProfile.QUALITY_TIME_LAPSE_QVGA, 64 CamcorderProfile.QUALITY_TIME_LAPSE_2160P, 65 CamcorderProfile.QUALITY_TIME_LAPSE_VGA, 66 CamcorderProfile.QUALITY_TIME_LAPSE_4KDCI, 67 CamcorderProfile.QUALITY_TIME_LAPSE_QHD, 68 CamcorderProfile.QUALITY_TIME_LAPSE_2K, 69 CamcorderProfile.QUALITY_TIME_LAPSE_8KUHD, 70 71 CamcorderProfile.QUALITY_HIGH_SPEED_LOW, 72 CamcorderProfile.QUALITY_HIGH_SPEED_HIGH, 73 CamcorderProfile.QUALITY_HIGH_SPEED_480P, 74 CamcorderProfile.QUALITY_HIGH_SPEED_720P, 75 CamcorderProfile.QUALITY_HIGH_SPEED_1080P, 76 CamcorderProfile.QUALITY_HIGH_SPEED_2160P, 77 CamcorderProfile.QUALITY_HIGH_SPEED_CIF, 78 CamcorderProfile.QUALITY_HIGH_SPEED_VGA, 79 CamcorderProfile.QUALITY_HIGH_SPEED_4KDCI, 80 }; 81 private static final int LAST_QUALITY = CamcorderProfile.QUALITY_8KUHD; 82 private static final int LAST_TIMELAPSE_QUALITY = CamcorderProfile.QUALITY_TIME_LAPSE_8KUHD; 83 private static final int LAST_HIGH_SPEED_QUALITY = CamcorderProfile.QUALITY_HIGH_SPEED_4KDCI; 84 private static final Integer[] UNKNOWN_QUALITIES = { 85 LAST_QUALITY + 1, // Unknown normal profile quality 86 LAST_TIMELAPSE_QUALITY + 1, // Unknown timelapse profile quality 87 LAST_HIGH_SPEED_QUALITY + 1 // Unknown high speed timelapse profile quality 88 }; 89 90 // Uses get without id if cameraId == -1 and get with id otherwise. getWithOptionalId(int quality, int cameraId)91 private CamcorderProfile getWithOptionalId(int quality, int cameraId) { 92 if (cameraId == -1) { 93 return CamcorderProfile.get(quality); 94 } else { 95 return CamcorderProfile.get(cameraId, quality); 96 } 97 } 98 checkProfile(CamcorderProfile profile, List<Size> videoSizes)99 private void checkProfile(CamcorderProfile profile, List<Size> videoSizes) { 100 Log.v(TAG, String.format("profile: duration=%d, quality=%d, " + 101 "fileFormat=%d, videoCodec=%d, videoBitRate=%d, videoFrameRate=%d, " + 102 "videoFrameWidth=%d, videoFrameHeight=%d, audioCodec=%d, " + 103 "audioBitRate=%d, audioSampleRate=%d, audioChannels=%d", 104 profile.duration, 105 profile.quality, 106 profile.fileFormat, 107 profile.videoCodec, 108 profile.videoBitRate, 109 profile.videoFrameRate, 110 profile.videoFrameWidth, 111 profile.videoFrameHeight, 112 profile.audioCodec, 113 profile.audioBitRate, 114 profile.audioSampleRate, 115 profile.audioChannels)); 116 assertTrue(profile.duration > 0); 117 assertTrue(Arrays.asList(ALL_SUPPORTED_QUALITIES).contains(profile.quality)); 118 assertTrue(profile.videoBitRate > 0); 119 assertTrue(profile.videoFrameRate > 0); 120 assertTrue(profile.videoFrameWidth > 0); 121 assertTrue(profile.videoFrameHeight > 0); 122 assertTrue(profile.audioBitRate > 0); 123 assertTrue(profile.audioSampleRate > 0); 124 assertTrue(profile.audioChannels > 0); 125 assertTrue(isSizeSupported(profile.videoFrameWidth, 126 profile.videoFrameHeight, 127 videoSizes)); 128 } 129 checkAllProfiles(EncoderProfiles allProfiles, CamcorderProfile profile, List<Size> videoSizes)130 private void checkAllProfiles(EncoderProfiles allProfiles, CamcorderProfile profile, 131 List<Size> videoSizes) { 132 Log.v(TAG, String.format("profile: duration=%d, quality=%d, " + 133 "fileFormat=%d, videoCodec=%d, videoBitRate=%d, videoFrameRate=%d, " + 134 "videoFrameWidth=%d, videoFrameHeight=%d, audioCodec=%d, " + 135 "audioBitRate=%d, audioSampleRate=%d, audioChannels=%d", 136 profile.duration, 137 profile.quality, 138 profile.fileFormat, 139 profile.videoCodec, 140 profile.videoBitRate, 141 profile.videoFrameRate, 142 profile.videoFrameWidth, 143 profile.videoFrameHeight, 144 profile.audioCodec, 145 profile.audioBitRate, 146 profile.audioSampleRate, 147 profile.audioChannels)); 148 // generic fields must match the corresponding CamcorderProfile 149 assertEquals(profile.duration, allProfiles.getDefaultDurationSeconds()); 150 assertEquals(profile.fileFormat, allProfiles.getRecommendedFileFormat()); 151 boolean first = true; 152 for (EncoderProfiles.VideoProfile videoProfile : allProfiles.getVideoProfiles()) { 153 if (first) { 154 // the first profile must be the default profile which must match 155 // the corresponding CamcorderProfile 156 assertEquals(profile.videoCodec, videoProfile.getCodec()); 157 assertEquals(profile.videoBitRate, videoProfile.getBitrate()); 158 assertEquals(profile.videoFrameRate, videoProfile.getFrameRate()); 159 first = false; 160 } 161 // all profiles must be the same size 162 assertEquals(profile.videoFrameWidth, videoProfile.getWidth()); 163 assertEquals(profile.videoFrameHeight, videoProfile.getHeight()); 164 assertTrue(videoProfile.getMediaType() != null); 165 switch (videoProfile.getCodec()) { 166 // don't validate profile for regular codecs as vendors may use vendor specific profile 167 case MediaRecorder.VideoEncoder.H263: 168 assertEquals(MediaFormat.MIMETYPE_VIDEO_H263, videoProfile.getMediaType()); 169 break; 170 case MediaRecorder.VideoEncoder.H264: 171 assertEquals(MediaFormat.MIMETYPE_VIDEO_AVC, videoProfile.getMediaType()); 172 break; 173 case MediaRecorder.VideoEncoder.MPEG_4_SP: 174 assertEquals(MediaFormat.MIMETYPE_VIDEO_MPEG4, videoProfile.getMediaType()); 175 break; 176 case MediaRecorder.VideoEncoder.VP8: 177 assertEquals(MediaFormat.MIMETYPE_VIDEO_VP8, videoProfile.getMediaType()); 178 break; 179 case MediaRecorder.VideoEncoder.HEVC: 180 assertEquals(MediaFormat.MIMETYPE_VIDEO_HEVC, videoProfile.getMediaType()); 181 break; 182 } 183 // Cannot validate profile as vendors may use vendor specific profile. Just read it. 184 int codecProfile = videoProfile.getProfile(); 185 } 186 first = true; 187 for (EncoderProfiles.AudioProfile audioProfile : allProfiles.getAudioProfiles()) { 188 if (first) { 189 // the first profile must be the default profile which must match 190 // the corresponding CamcorderProfile 191 assertEquals(profile.audioCodec, audioProfile.getCodec()); 192 assertEquals(profile.audioBitRate, audioProfile.getBitrate()); 193 assertEquals(profile.audioSampleRate, audioProfile.getSampleRate()); 194 assertEquals(profile.audioChannels, audioProfile.getChannels()); 195 first = false; 196 } 197 assertTrue(audioProfile.getMediaType() != null); 198 switch (audioProfile.getCodec()) { 199 // don't validate profile for regular codecs as vendors may use vendor specific profile 200 case MediaRecorder.AudioEncoder.AMR_NB: 201 assertEquals(MediaFormat.MIMETYPE_AUDIO_AMR_NB, audioProfile.getMediaType()); 202 break; 203 case MediaRecorder.AudioEncoder.AMR_WB: 204 assertEquals(MediaFormat.MIMETYPE_AUDIO_AMR_WB, audioProfile.getMediaType()); 205 break; 206 case MediaRecorder.AudioEncoder.AAC: 207 assertEquals(MediaFormat.MIMETYPE_AUDIO_AAC, audioProfile.getMediaType()); 208 break; 209 case MediaRecorder.AudioEncoder.HE_AAC: 210 assertEquals(MediaFormat.MIMETYPE_AUDIO_AAC, audioProfile.getMediaType()); 211 assertEquals(MediaCodecInfo.CodecProfileLevel.AACObjectHE, 212 audioProfile.getProfile()); 213 break; 214 case MediaRecorder.AudioEncoder.AAC_ELD: 215 assertEquals(MediaFormat.MIMETYPE_AUDIO_AAC, audioProfile.getMediaType()); 216 assertEquals(MediaCodecInfo.CodecProfileLevel.AACObjectELD, 217 audioProfile.getProfile()); 218 break; 219 case MediaRecorder.AudioEncoder.VORBIS: 220 assertEquals(MediaFormat.MIMETYPE_AUDIO_VORBIS, audioProfile.getMediaType()); 221 break; 222 case MediaRecorder.AudioEncoder.OPUS: 223 assertEquals(MediaFormat.MIMETYPE_AUDIO_OPUS, audioProfile.getMediaType()); 224 break; 225 default: 226 // there may be some extended profiles we don't know about and that's OK 227 break; 228 } 229 } 230 } 231 assertProfileEquals(CamcorderProfile expectedProfile, CamcorderProfile actualProfile)232 private void assertProfileEquals(CamcorderProfile expectedProfile, 233 CamcorderProfile actualProfile) { 234 assertEquals(expectedProfile.duration, actualProfile.duration); 235 assertEquals(expectedProfile.fileFormat, actualProfile.fileFormat); 236 assertEquals(expectedProfile.videoCodec, actualProfile.videoCodec); 237 assertEquals(expectedProfile.videoBitRate, actualProfile.videoBitRate); 238 assertEquals(expectedProfile.videoFrameRate, actualProfile.videoFrameRate); 239 assertEquals(expectedProfile.videoFrameWidth, actualProfile.videoFrameWidth); 240 assertEquals(expectedProfile.videoFrameHeight, actualProfile.videoFrameHeight); 241 assertEquals(expectedProfile.audioCodec, actualProfile.audioCodec); 242 assertEquals(expectedProfile.audioBitRate, actualProfile.audioBitRate); 243 assertEquals(expectedProfile.audioSampleRate, actualProfile.audioSampleRate); 244 assertEquals(expectedProfile.audioChannels, actualProfile.audioChannels); 245 } 246 checkSpecificProfileDimensions(CamcorderProfile profile, int quality)247 private void checkSpecificProfileDimensions(CamcorderProfile profile, int quality) { 248 Log.v(TAG, String.format("specific profile: quality=%d, width = %d, height = %d", 249 profile.quality, profile.videoFrameWidth, profile.videoFrameHeight)); 250 251 switch (quality) { 252 case CamcorderProfile.QUALITY_QCIF: 253 case CamcorderProfile.QUALITY_TIME_LAPSE_QCIF: 254 assertEquals(176, profile.videoFrameWidth); 255 assertEquals(144, profile.videoFrameHeight); 256 break; 257 258 case CamcorderProfile.QUALITY_CIF: 259 case CamcorderProfile.QUALITY_TIME_LAPSE_CIF: 260 assertEquals(352, profile.videoFrameWidth); 261 assertEquals(288, profile.videoFrameHeight); 262 break; 263 264 case CamcorderProfile.QUALITY_480P: 265 case CamcorderProfile.QUALITY_TIME_LAPSE_480P: 266 assertTrue(720 == profile.videoFrameWidth || // SMPTE 293M/ITU-R Rec. 601 267 640 == profile.videoFrameWidth || // ATSC/NTSC (square sampling) 268 704 == profile.videoFrameWidth); // ATSC/NTSC (non-square sampling) 269 assertEquals(480, profile.videoFrameHeight); 270 break; 271 272 case CamcorderProfile.QUALITY_720P: 273 case CamcorderProfile.QUALITY_TIME_LAPSE_720P: 274 assertEquals(1280, profile.videoFrameWidth); 275 assertEquals(720, profile.videoFrameHeight); 276 break; 277 278 case CamcorderProfile.QUALITY_1080P: 279 case CamcorderProfile.QUALITY_TIME_LAPSE_1080P: 280 // 1080p could be either 1920x1088 or 1920x1080. 281 assertEquals(1920, profile.videoFrameWidth); 282 assertTrue(1088 == profile.videoFrameHeight || 283 1080 == profile.videoFrameHeight); 284 break; 285 case CamcorderProfile.QUALITY_2K: 286 case CamcorderProfile.QUALITY_TIME_LAPSE_2K: 287 // 2K could be either 2048x1088 or 2048x1080 288 assertEquals(2048, profile.videoFrameWidth); 289 assertTrue(1088 == profile.videoFrameHeight || 290 1080 == profile.videoFrameHeight); 291 break; 292 case CamcorderProfile.QUALITY_QHD: 293 case CamcorderProfile.QUALITY_TIME_LAPSE_QHD: 294 assertEquals(2560, profile.videoFrameWidth); 295 assertEquals(1440, profile.videoFrameHeight); 296 break; 297 case CamcorderProfile.QUALITY_2160P: 298 case CamcorderProfile.QUALITY_TIME_LAPSE_2160P: 299 assertEquals(3840, profile.videoFrameWidth); 300 assertEquals(2160, profile.videoFrameHeight); 301 break; 302 case CamcorderProfile.QUALITY_HIGH_SPEED_480P: 303 assertTrue(720 == profile.videoFrameWidth || // SMPTE 293M/ITU-R Rec. 601 304 640 == profile.videoFrameWidth || // ATSC/NTSC (square sampling) 305 704 == profile.videoFrameWidth); // ATSC/NTSC (non-square sampling) 306 assertEquals(480, profile.videoFrameHeight); 307 assertTrue(profile.videoFrameRate >= MIN_HIGH_SPEED_FPS); 308 break; 309 case CamcorderProfile.QUALITY_HIGH_SPEED_720P: 310 assertEquals(1280, profile.videoFrameWidth); 311 assertEquals(720, profile.videoFrameHeight); 312 assertTrue(profile.videoFrameRate >= MIN_HIGH_SPEED_FPS); 313 break; 314 case CamcorderProfile.QUALITY_HIGH_SPEED_1080P: 315 // 1080p could be either 1920x1088 or 1920x1080. 316 assertEquals(1920, profile.videoFrameWidth); 317 assertTrue(1088 == profile.videoFrameHeight || 318 1080 == profile.videoFrameHeight); 319 assertTrue(profile.videoFrameRate >= MIN_HIGH_SPEED_FPS); 320 break; 321 } 322 } 323 324 // Checks if the existing specific profiles have the correct dimensions. 325 // Also checks that the mimimum quality specific profile matches the low profile and 326 // similarly that the maximum quality specific profile matches the high profile. checkSpecificProfiles( int cameraId, CamcorderProfile low, CamcorderProfile high, int[] specificQualities, List<Size> videoSizes)327 private void checkSpecificProfiles( 328 int cameraId, 329 CamcorderProfile low, 330 CamcorderProfile high, 331 int[] specificQualities, 332 List<Size> videoSizes) { 333 334 // For high speed levels, low and high quality are optional,skip the test if 335 // they are missing. 336 if (low == null && high == null) { 337 // No profile should be available if low and high are unavailable. 338 for (int quality : specificQualities) { 339 assertFalse(CamcorderProfile.hasProfile(cameraId, quality)); 340 } 341 return; 342 } 343 344 CamcorderProfile minProfile = null; 345 CamcorderProfile maxProfile = null; 346 347 for (int i = 0; i < specificQualities.length; i++) { 348 int quality = specificQualities[i]; 349 if ((cameraId != -1 && CamcorderProfile.hasProfile(cameraId, quality)) || 350 (cameraId == -1 && CamcorderProfile.hasProfile(quality))) { 351 CamcorderProfile profile = getWithOptionalId(quality, cameraId); 352 checkSpecificProfileDimensions(profile, quality); 353 354 assertTrue(isSizeSupported(profile.videoFrameWidth, 355 profile.videoFrameHeight, 356 videoSizes)); 357 358 if (minProfile == null) { 359 minProfile = profile; 360 } 361 maxProfile = profile; 362 } 363 } 364 365 assertNotNull(minProfile); 366 assertNotNull(maxProfile); 367 368 Log.v(TAG, String.format("min profile: quality=%d, width = %d, height = %d", 369 minProfile.quality, minProfile.videoFrameWidth, minProfile.videoFrameHeight)); 370 Log.v(TAG, String.format("max profile: quality=%d, width = %d, height = %d", 371 maxProfile.quality, maxProfile.videoFrameWidth, maxProfile.videoFrameHeight)); 372 373 assertProfileEquals(low, minProfile); 374 assertProfileEquals(high, maxProfile); 375 376 } 377 checkGet(int cameraId)378 private void checkGet(int cameraId) { 379 Log.v(TAG, (cameraId == -1) 380 ? "Checking get without id" 381 : "Checking get with id = " + cameraId); 382 383 final List<Size> videoSizes = getSupportedVideoSizes(cameraId); 384 385 /** 386 * Check all possible supported profiles: get profile should work, and the profile 387 * should be sane. Note that, timelapse and high speed video sizes may not be listed 388 * as supported video sizes from camera, skip the size check. 389 */ 390 for (Integer quality : ALL_SUPPORTED_QUALITIES) { 391 if (CamcorderProfile.hasProfile(cameraId, quality) || isProfileMandatory(quality)) { 392 List<Size> videoSizesToCheck = null; 393 if (quality >= CamcorderProfile.QUALITY_LOW && 394 quality <= CamcorderProfile.QUALITY_2K) { 395 videoSizesToCheck = videoSizes; 396 } 397 CamcorderProfile profile = getWithOptionalId(quality, cameraId); 398 checkProfile(profile, videoSizesToCheck); 399 if (cameraId >= 0) { 400 EncoderProfiles allProfiles = 401 CamcorderProfile.getAll(String.valueOf(cameraId), quality); 402 checkAllProfiles(allProfiles, profile, videoSizesToCheck); 403 } 404 } 405 } 406 407 /** 408 * Check unknown profiles: hasProfile() should return false. 409 */ 410 for (Integer quality : UNKNOWN_QUALITIES) { 411 assertFalse("Unknown profile quality " + quality + " shouldn't be supported by camera " 412 + cameraId, CamcorderProfile.hasProfile(cameraId, quality)); 413 } 414 415 // High speed low and high profile are optional, 416 // but they should be both present or missing. 417 CamcorderProfile lowHighSpeedProfile = null; 418 CamcorderProfile highHighSpeedProfile = null; 419 if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_HIGH_SPEED_LOW)) { 420 lowHighSpeedProfile = 421 getWithOptionalId(CamcorderProfile.QUALITY_HIGH_SPEED_LOW, cameraId); 422 } 423 if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_HIGH_SPEED_HIGH)) { 424 highHighSpeedProfile = 425 getWithOptionalId(CamcorderProfile.QUALITY_HIGH_SPEED_HIGH, cameraId); 426 } 427 if (lowHighSpeedProfile != null) { 428 assertNotNull("high speed high quality profile should be supported if low" + 429 " is supported ", 430 highHighSpeedProfile); 431 checkProfile(lowHighSpeedProfile, null); 432 checkProfile(highHighSpeedProfile, null); 433 } else { 434 assertNull("high speed high quality profile shouldn't be supported if " + 435 "low is unsupported ", highHighSpeedProfile); 436 } 437 438 int[] specificProfileQualities = {CamcorderProfile.QUALITY_QCIF, 439 CamcorderProfile.QUALITY_QVGA, 440 CamcorderProfile.QUALITY_CIF, 441 CamcorderProfile.QUALITY_480P, 442 CamcorderProfile.QUALITY_720P, 443 CamcorderProfile.QUALITY_1080P, 444 CamcorderProfile.QUALITY_2K, 445 CamcorderProfile.QUALITY_QHD, 446 CamcorderProfile.QUALITY_2160P}; 447 448 int[] specificTimeLapseProfileQualities = {CamcorderProfile.QUALITY_TIME_LAPSE_QCIF, 449 CamcorderProfile.QUALITY_TIME_LAPSE_QVGA, 450 CamcorderProfile.QUALITY_TIME_LAPSE_CIF, 451 CamcorderProfile.QUALITY_TIME_LAPSE_480P, 452 CamcorderProfile.QUALITY_TIME_LAPSE_720P, 453 CamcorderProfile.QUALITY_TIME_LAPSE_1080P, 454 CamcorderProfile.QUALITY_TIME_LAPSE_2K, 455 CamcorderProfile.QUALITY_TIME_LAPSE_QHD, 456 CamcorderProfile.QUALITY_TIME_LAPSE_2160P}; 457 458 int[] specificHighSpeedProfileQualities = {CamcorderProfile.QUALITY_HIGH_SPEED_480P, 459 CamcorderProfile.QUALITY_HIGH_SPEED_720P, 460 CamcorderProfile.QUALITY_HIGH_SPEED_1080P, 461 CamcorderProfile.QUALITY_HIGH_SPEED_2160P}; 462 463 CamcorderProfile lowProfile = 464 getWithOptionalId(CamcorderProfile.QUALITY_LOW, cameraId); 465 CamcorderProfile highProfile = 466 getWithOptionalId(CamcorderProfile.QUALITY_HIGH, cameraId); 467 CamcorderProfile lowTimeLapseProfile = 468 getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_LOW, cameraId); 469 CamcorderProfile highTimeLapseProfile = 470 getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH, cameraId); 471 checkSpecificProfiles(cameraId, lowProfile, highProfile, 472 specificProfileQualities, videoSizes); 473 checkSpecificProfiles(cameraId, lowTimeLapseProfile, highTimeLapseProfile, 474 specificTimeLapseProfileQualities, null); 475 checkSpecificProfiles(cameraId, lowHighSpeedProfile, highHighSpeedProfile, 476 specificHighSpeedProfileQualities, null); 477 } 478 testGet()479 public void testGet() { 480 /* 481 * Device may not have rear camera for checkGet(-1). 482 * Checking PackageManager.FEATURE_CAMERA is included or not to decide the flow. 483 * Continue if the feature is included. 484 * Otherwise, exit test. 485 */ 486 PackageManager pm = mContext.getPackageManager(); 487 if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 488 return; 489 } 490 checkGet(-1); 491 } 492 testGetWithId()493 public void testGetWithId() { 494 int nCamera = Camera.getNumberOfCameras(); 495 for (int cameraId = 0; cameraId < nCamera; cameraId++) { 496 boolean isExternal = false; 497 try { 498 isExternal = CameraUtils.isExternal(mContext, cameraId); 499 } catch (Exception e) { 500 Log.e(TAG, "Unable to query external camera: " + e); 501 } 502 503 if (!isExternal) { 504 checkGet(cameraId); 505 } 506 } 507 } 508 getSupportedVideoSizes(int cameraId)509 private List<Size> getSupportedVideoSizes(int cameraId) { 510 Camera camera = (cameraId == -1)? Camera.open(): Camera.open(cameraId); 511 Parameters parameters = camera.getParameters(); 512 List<Size> videoSizes = parameters.getSupportedVideoSizes(); 513 if (videoSizes == null) { 514 videoSizes = parameters.getSupportedPreviewSizes(); 515 assertNotNull(videoSizes); 516 } 517 camera.release(); 518 return videoSizes; 519 } 520 isSizeSupported(int width, int height, List<Size> sizes)521 private boolean isSizeSupported(int width, int height, List<Size> sizes) { 522 if (sizes == null) return true; 523 524 for (Size size: sizes) { 525 if (size.width == width && size.height == height) { 526 return true; 527 } 528 } 529 Log.e(TAG, "Size (" + width + "x" + height + ") is not supported"); 530 return false; 531 } 532 isProfileMandatory(int quality)533 private boolean isProfileMandatory(int quality) { 534 return (quality == CamcorderProfile.QUALITY_LOW) || 535 (quality == CamcorderProfile.QUALITY_HIGH) || 536 (quality == CamcorderProfile.QUALITY_TIME_LAPSE_LOW) || 537 (quality == CamcorderProfile.QUALITY_TIME_LAPSE_HIGH); 538 } 539 } 540