blob: a28095f08427119b9341728452cef760ec0bad82 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media.misc.cts;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.hardware.cts.helpers.CameraUtils;
import android.media.CamcorderProfile;
import android.media.EncoderProfiles;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaRecorder;
import android.media.cts.NonMediaMainlineTest;
import android.test.AndroidTestCase;
import android.test.InstrumentationTestCase;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.List;
@NonMediaMainlineTest
@RunWith(AndroidJUnit4.class)
public class CamcorderProfileTest {
private static final String TAG = "CamcorderProfileTest";
private static final int MIN_HIGH_SPEED_FPS = 100;
private static final Integer[] ALL_SUPPORTED_QUALITIES = {
CamcorderProfile.QUALITY_LOW,
CamcorderProfile.QUALITY_HIGH,
CamcorderProfile.QUALITY_QCIF,
CamcorderProfile.QUALITY_CIF,
CamcorderProfile.QUALITY_480P,
CamcorderProfile.QUALITY_720P,
CamcorderProfile.QUALITY_1080P,
CamcorderProfile.QUALITY_QVGA,
CamcorderProfile.QUALITY_2160P,
CamcorderProfile.QUALITY_VGA,
CamcorderProfile.QUALITY_4KDCI,
CamcorderProfile.QUALITY_QHD,
CamcorderProfile.QUALITY_2K,
CamcorderProfile.QUALITY_8KUHD,
CamcorderProfile.QUALITY_TIME_LAPSE_LOW,
CamcorderProfile.QUALITY_TIME_LAPSE_HIGH,
CamcorderProfile.QUALITY_TIME_LAPSE_QCIF,
CamcorderProfile.QUALITY_TIME_LAPSE_CIF,
CamcorderProfile.QUALITY_TIME_LAPSE_480P,
CamcorderProfile.QUALITY_TIME_LAPSE_720P,
CamcorderProfile.QUALITY_TIME_LAPSE_1080P,
CamcorderProfile.QUALITY_TIME_LAPSE_QVGA,
CamcorderProfile.QUALITY_TIME_LAPSE_2160P,
CamcorderProfile.QUALITY_TIME_LAPSE_VGA,
CamcorderProfile.QUALITY_TIME_LAPSE_4KDCI,
CamcorderProfile.QUALITY_TIME_LAPSE_QHD,
CamcorderProfile.QUALITY_TIME_LAPSE_2K,
CamcorderProfile.QUALITY_TIME_LAPSE_8KUHD,
CamcorderProfile.QUALITY_HIGH_SPEED_LOW,
CamcorderProfile.QUALITY_HIGH_SPEED_HIGH,
CamcorderProfile.QUALITY_HIGH_SPEED_480P,
CamcorderProfile.QUALITY_HIGH_SPEED_720P,
CamcorderProfile.QUALITY_HIGH_SPEED_1080P,
CamcorderProfile.QUALITY_HIGH_SPEED_2160P,
CamcorderProfile.QUALITY_HIGH_SPEED_CIF,
CamcorderProfile.QUALITY_HIGH_SPEED_VGA,
CamcorderProfile.QUALITY_HIGH_SPEED_4KDCI,
};
private static final int LAST_QUALITY = CamcorderProfile.QUALITY_8KUHD;
private static final int LAST_TIMELAPSE_QUALITY = CamcorderProfile.QUALITY_TIME_LAPSE_8KUHD;
private static final int LAST_HIGH_SPEED_QUALITY = CamcorderProfile.QUALITY_HIGH_SPEED_4KDCI;
private static final Integer[] UNKNOWN_QUALITIES = {
LAST_QUALITY + 1, // Unknown normal profile quality
LAST_TIMELAPSE_QUALITY + 1, // Unknown timelapse profile quality
LAST_HIGH_SPEED_QUALITY + 1 // Unknown high speed timelapse profile quality
};
// Uses get without id if cameraId == -1 and get with id otherwise.
private CamcorderProfile getWithOptionalId(int quality, int cameraId) {
if (cameraId == -1) {
return CamcorderProfile.get(quality);
} else {
return CamcorderProfile.get(cameraId, quality);
}
}
private void checkProfile(CamcorderProfile profile, List<Size> videoSizes) {
Log.v(TAG, String.format("profile: duration=%d, quality=%d, " +
"fileFormat=%d, videoCodec=%d, videoBitRate=%d, videoFrameRate=%d, " +
"videoFrameWidth=%d, videoFrameHeight=%d, audioCodec=%d, " +
"audioBitRate=%d, audioSampleRate=%d, audioChannels=%d",
profile.duration,
profile.quality,
profile.fileFormat,
profile.videoCodec,
profile.videoBitRate,
profile.videoFrameRate,
profile.videoFrameWidth,
profile.videoFrameHeight,
profile.audioCodec,
profile.audioBitRate,
profile.audioSampleRate,
profile.audioChannels));
assertTrue(profile.duration > 0);
assertTrue(Arrays.asList(ALL_SUPPORTED_QUALITIES).contains(profile.quality));
assertTrue(profile.videoBitRate > 0);
assertTrue(profile.videoFrameRate > 0);
assertTrue(profile.videoFrameWidth > 0);
assertTrue(profile.videoFrameHeight > 0);
assertTrue(profile.audioBitRate > 0);
assertTrue(profile.audioSampleRate > 0);
assertTrue(profile.audioChannels > 0);
assertTrue(isSizeSupported(profile.videoFrameWidth,
profile.videoFrameHeight,
videoSizes));
}
private void checkAllProfiles(EncoderProfiles allProfiles, CamcorderProfile profile,
List<Size> videoSizes) {
Log.v(TAG, String.format("profile: duration=%d, quality=%d, " +
"fileFormat=%d, videoCodec=%d, videoBitRate=%d, videoFrameRate=%d, " +
"videoFrameWidth=%d, videoFrameHeight=%d, audioCodec=%d, " +
"audioBitRate=%d, audioSampleRate=%d, audioChannels=%d",
profile.duration,
profile.quality,
profile.fileFormat,
profile.videoCodec,
profile.videoBitRate,
profile.videoFrameRate,
profile.videoFrameWidth,
profile.videoFrameHeight,
profile.audioCodec,
profile.audioBitRate,
profile.audioSampleRate,
profile.audioChannels));
// generic fields must match the corresponding CamcorderProfile
assertEquals(profile.duration, allProfiles.getDefaultDurationSeconds());
assertEquals(profile.fileFormat, allProfiles.getRecommendedFileFormat());
boolean first = true;
for (EncoderProfiles.VideoProfile videoProfile : allProfiles.getVideoProfiles()) {
if (first) {
// the first profile must be the default profile which must match
// the corresponding CamcorderProfile
assertEquals(profile.videoCodec, videoProfile.getCodec());
assertEquals(profile.videoBitRate, videoProfile.getBitrate());
assertEquals(profile.videoFrameRate, videoProfile.getFrameRate());
first = false;
// The first video profile must be a basic profile: YUV 4:2:0 8-bit SDR.
// This is to ensure backward compatibility with the corresponding
// CamcorderProfile, which is always a basic profile.
assertEquals(EncoderProfiles.VideoProfile.YUV_420,
videoProfile.getChromaSubsampling());
assertEquals(EncoderProfiles.VideoProfile.HDR_NONE, videoProfile.getHdrFormat());
assertEquals(8, videoProfile.getBitDepth());
}
// all profiles must be the same size
assertEquals(profile.videoFrameWidth, videoProfile.getWidth());
assertEquals(profile.videoFrameHeight, videoProfile.getHeight());
assertTrue(videoProfile.getMediaType() != null);
switch (videoProfile.getCodec()) {
// don't validate profile for regular codecs as vendors may use vendor specific profile
case MediaRecorder.VideoEncoder.H263:
assertEquals(MediaFormat.MIMETYPE_VIDEO_H263, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.H264:
assertEquals(MediaFormat.MIMETYPE_VIDEO_AVC, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.MPEG_4_SP:
assertEquals(MediaFormat.MIMETYPE_VIDEO_MPEG4, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.VP8:
assertEquals(MediaFormat.MIMETYPE_VIDEO_VP8, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.HEVC:
assertEquals(MediaFormat.MIMETYPE_VIDEO_HEVC, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.VP9:
assertEquals(MediaFormat.MIMETYPE_VIDEO_VP9, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.DOLBY_VISION:
assertEquals(MediaFormat.MIMETYPE_VIDEO_DOLBY_VISION, videoProfile.getMediaType());
break;
case MediaRecorder.VideoEncoder.AV1:
assertEquals(MediaFormat.MIMETYPE_VIDEO_AV1, videoProfile.getMediaType());
break;
}
// Cannot validate profile as vendors may use vendor specific profile. Just read it.
int codecProfile = videoProfile.getProfile();
}
// there must have been at least one video profile
assertFalse("no video profiles in getAll()", first);
first = true;
for (EncoderProfiles.AudioProfile audioProfile : allProfiles.getAudioProfiles()) {
if (first) {
// the first profile must be the default profile which must match
// the corresponding CamcorderProfile
assertEquals(profile.audioCodec, audioProfile.getCodec());
assertEquals(profile.audioBitRate, audioProfile.getBitrate());
assertEquals(profile.audioSampleRate, audioProfile.getSampleRate());
assertEquals(profile.audioChannels, audioProfile.getChannels());
first = false;
}
assertTrue(audioProfile.getMediaType() != null);
switch (audioProfile.getCodec()) {
// don't validate profile for regular codecs as vendors may use vendor specific profile
case MediaRecorder.AudioEncoder.AMR_NB:
assertEquals(MediaFormat.MIMETYPE_AUDIO_AMR_NB, audioProfile.getMediaType());
break;
case MediaRecorder.AudioEncoder.AMR_WB:
assertEquals(MediaFormat.MIMETYPE_AUDIO_AMR_WB, audioProfile.getMediaType());
break;
case MediaRecorder.AudioEncoder.AAC:
assertEquals(MediaFormat.MIMETYPE_AUDIO_AAC, audioProfile.getMediaType());
break;
case MediaRecorder.AudioEncoder.HE_AAC:
assertEquals(MediaFormat.MIMETYPE_AUDIO_AAC, audioProfile.getMediaType());
assertEquals(MediaCodecInfo.CodecProfileLevel.AACObjectHE,
audioProfile.getProfile());
break;
case MediaRecorder.AudioEncoder.AAC_ELD:
assertEquals(MediaFormat.MIMETYPE_AUDIO_AAC, audioProfile.getMediaType());
assertEquals(MediaCodecInfo.CodecProfileLevel.AACObjectELD,
audioProfile.getProfile());
break;
case MediaRecorder.AudioEncoder.VORBIS:
assertEquals(MediaFormat.MIMETYPE_AUDIO_VORBIS, audioProfile.getMediaType());
break;
case MediaRecorder.AudioEncoder.OPUS:
assertEquals(MediaFormat.MIMETYPE_AUDIO_OPUS, audioProfile.getMediaType());
break;
default:
// there may be some extended profiles we don't know about and that's OK
break;
}
}
}
private void assertProfileEquals(CamcorderProfile expectedProfile,
CamcorderProfile actualProfile) {
assertEquals(expectedProfile.duration, actualProfile.duration);
assertEquals(expectedProfile.fileFormat, actualProfile.fileFormat);
assertEquals(expectedProfile.videoCodec, actualProfile.videoCodec);
assertEquals(expectedProfile.videoBitRate, actualProfile.videoBitRate);
assertEquals(expectedProfile.videoFrameRate, actualProfile.videoFrameRate);
assertEquals(expectedProfile.videoFrameWidth, actualProfile.videoFrameWidth);
assertEquals(expectedProfile.videoFrameHeight, actualProfile.videoFrameHeight);
assertEquals(expectedProfile.audioCodec, actualProfile.audioCodec);
assertEquals(expectedProfile.audioBitRate, actualProfile.audioBitRate);
assertEquals(expectedProfile.audioSampleRate, actualProfile.audioSampleRate);
assertEquals(expectedProfile.audioChannels, actualProfile.audioChannels);
}
private void checkSpecificProfileDimensions(CamcorderProfile profile, int quality) {
Log.v(TAG, String.format("specific profile: quality=%d, width = %d, height = %d",
profile.quality, profile.videoFrameWidth, profile.videoFrameHeight));
switch (quality) {
case CamcorderProfile.QUALITY_QCIF:
case CamcorderProfile.QUALITY_TIME_LAPSE_QCIF:
assertEquals(176, profile.videoFrameWidth);
assertEquals(144, profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_CIF:
case CamcorderProfile.QUALITY_TIME_LAPSE_CIF:
assertEquals(352, profile.videoFrameWidth);
assertEquals(288, profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_480P:
case CamcorderProfile.QUALITY_TIME_LAPSE_480P:
assertTrue(720 == profile.videoFrameWidth || // SMPTE 293M/ITU-R Rec. 601
640 == profile.videoFrameWidth || // ATSC/NTSC (square sampling)
704 == profile.videoFrameWidth); // ATSC/NTSC (non-square sampling)
assertEquals(480, profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_720P:
case CamcorderProfile.QUALITY_TIME_LAPSE_720P:
assertEquals(1280, profile.videoFrameWidth);
assertEquals(720, profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_1080P:
case CamcorderProfile.QUALITY_TIME_LAPSE_1080P:
// 1080p could be either 1920x1088 or 1920x1080.
assertEquals(1920, profile.videoFrameWidth);
assertTrue(1088 == profile.videoFrameHeight ||
1080 == profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_2K:
case CamcorderProfile.QUALITY_TIME_LAPSE_2K:
// 2K could be either 2048x1088 or 2048x1080
assertEquals(2048, profile.videoFrameWidth);
assertTrue(1088 == profile.videoFrameHeight ||
1080 == profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_QHD:
case CamcorderProfile.QUALITY_TIME_LAPSE_QHD:
assertEquals(2560, profile.videoFrameWidth);
assertEquals(1440, profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_2160P:
case CamcorderProfile.QUALITY_TIME_LAPSE_2160P:
assertEquals(3840, profile.videoFrameWidth);
assertEquals(2160, profile.videoFrameHeight);
break;
case CamcorderProfile.QUALITY_HIGH_SPEED_480P:
assertTrue(720 == profile.videoFrameWidth || // SMPTE 293M/ITU-R Rec. 601
640 == profile.videoFrameWidth || // ATSC/NTSC (square sampling)
704 == profile.videoFrameWidth); // ATSC/NTSC (non-square sampling)
assertEquals(480, profile.videoFrameHeight);
assertTrue(profile.videoFrameRate >= MIN_HIGH_SPEED_FPS);
break;
case CamcorderProfile.QUALITY_HIGH_SPEED_720P:
assertEquals(1280, profile.videoFrameWidth);
assertEquals(720, profile.videoFrameHeight);
assertTrue(profile.videoFrameRate >= MIN_HIGH_SPEED_FPS);
break;
case CamcorderProfile.QUALITY_HIGH_SPEED_1080P:
// 1080p could be either 1920x1088 or 1920x1080.
assertEquals(1920, profile.videoFrameWidth);
assertTrue(1088 == profile.videoFrameHeight ||
1080 == profile.videoFrameHeight);
assertTrue(profile.videoFrameRate >= MIN_HIGH_SPEED_FPS);
break;
}
}
// Checks if the existing specific profiles have the correct dimensions.
// Also checks that the mimimum quality specific profile matches the low profile and
// similarly that the maximum quality specific profile matches the high profile.
private void checkSpecificProfiles(
int cameraId,
CamcorderProfile low,
CamcorderProfile high,
int[] specificQualities,
List<Size> videoSizes) {
// For high speed levels, low and high quality are optional,skip the test if
// they are missing.
if (low == null && high == null) {
// No profile should be available if low and high are unavailable.
for (int quality : specificQualities) {
assertFalse(CamcorderProfile.hasProfile(cameraId, quality));
}
return;
}
CamcorderProfile minProfile = null;
CamcorderProfile maxProfile = null;
for (int i = 0; i < specificQualities.length; i++) {
int quality = specificQualities[i];
if ((cameraId != -1 && CamcorderProfile.hasProfile(cameraId, quality)) ||
(cameraId == -1 && CamcorderProfile.hasProfile(quality))) {
CamcorderProfile profile = getWithOptionalId(quality, cameraId);
checkSpecificProfileDimensions(profile, quality);
assertTrue(isSizeSupported(profile.videoFrameWidth,
profile.videoFrameHeight,
videoSizes));
if (minProfile == null) {
minProfile = profile;
}
maxProfile = profile;
}
}
assertNotNull(minProfile);
assertNotNull(maxProfile);
Log.v(TAG, String.format("min profile: quality=%d, width = %d, height = %d",
minProfile.quality, minProfile.videoFrameWidth, minProfile.videoFrameHeight));
Log.v(TAG, String.format("max profile: quality=%d, width = %d, height = %d",
maxProfile.quality, maxProfile.videoFrameWidth, maxProfile.videoFrameHeight));
assertProfileEquals(low, minProfile);
assertProfileEquals(high, maxProfile);
}
private void checkGet(int cameraId) {
Log.v(TAG, (cameraId == -1)
? "Checking get without id"
: "Checking get with id = " + cameraId);
Camera camera = null;
if (cameraId == -1) {
camera = Camera.open();
assumeTrue("Device does not have a back-facing camera", camera != null);
} else {
camera = Camera.open(cameraId);
assertNotNull("failed to open CameraId " + cameraId, camera);
}
final List<Size> videoSizes = getSupportedVideoSizes(camera);
camera.release();
camera = null;
/**
* Check all possible supported profiles: get profile should work, and the profile
* should be sane. Note that, timelapse and high speed video sizes may not be listed
* as supported video sizes from camera, skip the size check.
*/
for (Integer quality : ALL_SUPPORTED_QUALITIES) {
if (CamcorderProfile.hasProfile(cameraId, quality) || isProfileMandatory(quality)) {
List<Size> videoSizesToCheck = null;
if (quality >= CamcorderProfile.QUALITY_LOW &&
quality <= CamcorderProfile.QUALITY_2K) {
videoSizesToCheck = videoSizes;
}
CamcorderProfile profile = getWithOptionalId(quality, cameraId);
checkProfile(profile, videoSizesToCheck);
if (cameraId >= 0) {
EncoderProfiles allProfiles =
CamcorderProfile.getAll(String.valueOf(cameraId), quality);
checkAllProfiles(allProfiles, profile, videoSizesToCheck);
}
}
}
/**
* Check unknown profiles: hasProfile() should return false.
*/
for (Integer quality : UNKNOWN_QUALITIES) {
assertFalse("Unknown profile quality " + quality + " shouldn't be supported by camera "
+ cameraId, CamcorderProfile.hasProfile(cameraId, quality));
}
// High speed low and high profile are optional,
// but they should be both present or missing.
CamcorderProfile lowHighSpeedProfile = null;
CamcorderProfile highHighSpeedProfile = null;
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_HIGH_SPEED_LOW)) {
lowHighSpeedProfile =
getWithOptionalId(CamcorderProfile.QUALITY_HIGH_SPEED_LOW, cameraId);
}
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_HIGH_SPEED_HIGH)) {
highHighSpeedProfile =
getWithOptionalId(CamcorderProfile.QUALITY_HIGH_SPEED_HIGH, cameraId);
}
if (lowHighSpeedProfile != null) {
assertNotNull("high speed high quality profile should be supported if low" +
" is supported ",
highHighSpeedProfile);
checkProfile(lowHighSpeedProfile, null);
checkProfile(highHighSpeedProfile, null);
} else {
assertNull("high speed high quality profile shouldn't be supported if " +
"low is unsupported ", highHighSpeedProfile);
}
int[] specificProfileQualities = {CamcorderProfile.QUALITY_QCIF,
CamcorderProfile.QUALITY_QVGA,
CamcorderProfile.QUALITY_CIF,
CamcorderProfile.QUALITY_480P,
CamcorderProfile.QUALITY_720P,
CamcorderProfile.QUALITY_1080P,
CamcorderProfile.QUALITY_2K,
CamcorderProfile.QUALITY_QHD,
CamcorderProfile.QUALITY_2160P};
int[] specificTimeLapseProfileQualities = {CamcorderProfile.QUALITY_TIME_LAPSE_QCIF,
CamcorderProfile.QUALITY_TIME_LAPSE_QVGA,
CamcorderProfile.QUALITY_TIME_LAPSE_CIF,
CamcorderProfile.QUALITY_TIME_LAPSE_480P,
CamcorderProfile.QUALITY_TIME_LAPSE_720P,
CamcorderProfile.QUALITY_TIME_LAPSE_1080P,
CamcorderProfile.QUALITY_TIME_LAPSE_2K,
CamcorderProfile.QUALITY_TIME_LAPSE_QHD,
CamcorderProfile.QUALITY_TIME_LAPSE_2160P};
int[] specificHighSpeedProfileQualities = {CamcorderProfile.QUALITY_HIGH_SPEED_480P,
CamcorderProfile.QUALITY_HIGH_SPEED_720P,
CamcorderProfile.QUALITY_HIGH_SPEED_1080P,
CamcorderProfile.QUALITY_HIGH_SPEED_2160P};
CamcorderProfile lowProfile =
getWithOptionalId(CamcorderProfile.QUALITY_LOW, cameraId);
CamcorderProfile highProfile =
getWithOptionalId(CamcorderProfile.QUALITY_HIGH, cameraId);
CamcorderProfile lowTimeLapseProfile =
getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_LOW, cameraId);
CamcorderProfile highTimeLapseProfile =
getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH, cameraId);
checkSpecificProfiles(cameraId, lowProfile, highProfile,
specificProfileQualities, videoSizes);
checkSpecificProfiles(cameraId, lowTimeLapseProfile, highTimeLapseProfile,
specificTimeLapseProfileQualities, null);
checkSpecificProfiles(cameraId, lowHighSpeedProfile, highHighSpeedProfile,
specificHighSpeedProfileQualities, null);
}
@Test
public void testGetFirstBackCamera() {
/*
* Device may not have rear camera for checkGet(-1).
* Checking PackageManager.FEATURE_CAMERA is included or not to decide the flow.
* Continue if the feature is included.
* Otherwise, exit test.
*/
Context context = InstrumentationRegistry.getContext();
assertNotNull("did not find context", context);
PackageManager pm = context.getPackageManager();
assertNotNull("did not find package manager", pm);
if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return;
}
checkGet(-1);
}
@Test
public void testGetWithId() {
int nCamera = Camera.getNumberOfCameras();
Context context = InstrumentationRegistry.getContext();
assertNotNull("did not find context", context);
for (int cameraId = 0; cameraId < nCamera; cameraId++) {
boolean isExternal = false;
try {
isExternal = CameraUtils.isExternal(context, cameraId);
} catch (Exception e) {
Log.e(TAG, "Unable to query external camera: " + e);
}
if (!isExternal) {
checkGet(cameraId);
}
}
}
private List<Size> getSupportedVideoSizes(Camera camera) {
Parameters parameters = camera.getParameters();
assertNotNull("Camera did not provide parameters", parameters);
List<Size> videoSizes = parameters.getSupportedVideoSizes();
if (videoSizes == null) {
videoSizes = parameters.getSupportedPreviewSizes();
assertNotNull(videoSizes);
}
return videoSizes;
}
private boolean isSizeSupported(int width, int height, List<Size> sizes) {
if (sizes == null) return true;
for (Size size: sizes) {
if (size.width == width && size.height == height) {
return true;
}
}
Log.e(TAG, "Size (" + width + "x" + height + ") is not supported");
return false;
}
private boolean isProfileMandatory(int quality) {
return (quality == CamcorderProfile.QUALITY_LOW) ||
(quality == CamcorderProfile.QUALITY_HIGH) ||
(quality == CamcorderProfile.QUALITY_TIME_LAPSE_LOW) ||
(quality == CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
}
}