blob: 1df50112d6b4c4728d9af76ba564fb5030bc261b [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.cts;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
import android.test.AndroidTestCase;
import android.util.Log;
import java.util.List;
public class CamcorderProfileTest extends AndroidTestCase {
private static final String TAG = "CamcorderProfileTest";
// 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(profile.quality == CamcorderProfile.QUALITY_LOW ||
profile.quality == CamcorderProfile.QUALITY_HIGH ||
profile.quality == CamcorderProfile.QUALITY_QCIF ||
profile.quality == CamcorderProfile.QUALITY_CIF ||
profile.quality == CamcorderProfile.QUALITY_480P ||
profile.quality == CamcorderProfile.QUALITY_720P ||
profile.quality == CamcorderProfile.QUALITY_1080P ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_LOW ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_HIGH ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_QCIF ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_CIF ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_480P ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_720P ||
profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_1080P);
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 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;
}
}
// 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) {
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);
final List<Size> videoSizes = getSupportedVideoSizes(cameraId);
CamcorderProfile lowProfile =
getWithOptionalId(CamcorderProfile.QUALITY_LOW, cameraId);
CamcorderProfile highProfile =
getWithOptionalId(CamcorderProfile.QUALITY_HIGH, cameraId);
checkProfile(lowProfile, videoSizes);
checkProfile(highProfile, videoSizes);
CamcorderProfile lowTimeLapseProfile =
getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_LOW, cameraId);
CamcorderProfile highTimeLapseProfile =
getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH, cameraId);
checkProfile(lowTimeLapseProfile, null);
checkProfile(highTimeLapseProfile, null);
int[] specificProfileQualities = {CamcorderProfile.QUALITY_QCIF,
CamcorderProfile.QUALITY_QVGA,
CamcorderProfile.QUALITY_CIF,
CamcorderProfile.QUALITY_480P,
CamcorderProfile.QUALITY_720P,
CamcorderProfile.QUALITY_1080P};
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};
checkSpecificProfiles(cameraId, lowProfile, highProfile,
specificProfileQualities, videoSizes);
checkSpecificProfiles(cameraId, lowTimeLapseProfile, highTimeLapseProfile,
specificTimeLapseProfileQualities, null);
}
public void testGet() {
/*
* 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.
*/
PackageManager pm = mContext.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return;
}
checkGet(-1);
}
public void testGetWithId() {
int nCamera = Camera.getNumberOfCameras();
for (int cameraId = 0; cameraId < nCamera; cameraId++) {
checkGet(cameraId);
}
}
private List<Size> getSupportedVideoSizes(int cameraId) {
Camera camera = (cameraId == -1)? Camera.open(): Camera.open(cameraId);
Parameters parameters = camera.getParameters();
List<Size> videoSizes = parameters.getSupportedVideoSizes();
if (videoSizes == null) {
videoSizes = parameters.getSupportedPreviewSizes();
assertNotNull(videoSizes);
}
camera.release();
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;
}
}