(1)测试项源码简介
//cts/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
/**
* Test that the available stream configurations contain a few required formats and sizes.
*/
@CddTest(requirement="7.5.1/C-1-2")
@Test
public void testAvailableStreamConfigs() throws Exception {
boolean firstBackFacingCamera = true;
for (int i = 0; i < mAllCameraIds.length; i++) {
CameraCharacteristics c = mCharacteristics.get(i);
StreamConfigurationMap config =
c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
assertNotNull(String.format("No stream configuration map found for: ID %s",
mAllCameraIds[i]), config);
int[] outputFormats = config.getOutputFormats();
int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
assertNotNull("android.request.availableCapabilities must never be null",
actualCapabilities);
// Check required formats exist (JPEG, and YUV_420_888).
if (!arrayContains(actualCapabilities, BC)) {
Log.i(TAG, "Camera " + mAllCameraIds[i] +
": BACKWARD_COMPATIBLE capability not supported, skipping test");
continue;
}
boolean isMonochromeWithY8 = arrayContains(actualCapabilities, MONOCHROME)
&& arrayContains(outputFormats, ImageFormat.Y8);
boolean isHiddenPhysicalCamera = !arrayContains(mCameraIdsUnderTest, mAllCameraIds[i]);
boolean supportHeic = arrayContains(outputFormats, ImageFormat.HEIC);
assertArrayContains(
String.format("No valid YUV_420_888 preview formats found for: ID %s",
mAllCameraIds[i]), outputFormats, ImageFormat.YUV_420_888);
if (isMonochromeWithY8) {
assertArrayContains(
String.format("No valid Y8 preview formats found for: ID %s",
mAllCameraIds[i]), outputFormats, ImageFormat.Y8);
}
assertArrayContains(String.format("No JPEG image format for: ID %s",
mAllCameraIds[i]), outputFormats, ImageFormat.JPEG);
Size[] yuvSizes = config.getOutputSizes(ImageFormat.YUV_420_888);
Size[] y8Sizes = config.getOutputSizes(ImageFormat.Y8);
Size[] jpegSizes = config.getOutputSizes(ImageFormat.JPEG);
Size[] heicSizes = config.getOutputSizes(ImageFormat.HEIC);
Size[] privateSizes = config.getOutputSizes(ImageFormat.PRIVATE);
CameraTestUtils.assertArrayNotEmpty(yuvSizes,
String.format("No sizes for preview format %x for: ID %s",
ImageFormat.YUV_420_888, mAllCameraIds[i]));
if (isMonochromeWithY8) {
CameraTestUtils.assertArrayNotEmpty(y8Sizes,
String.format("No sizes for preview format %x for: ID %s",
ImageFormat.Y8, mAllCameraIds[i]));
}
Rect activeRect = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
Size pixelArraySize = CameraTestUtils.getValueNotNull(
c, CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);
int activeArrayHeight = activeRect.height();
int activeArrayWidth = activeRect.width();
long sensorResolution = pixelArraySize.getHeight() * pixelArraySize.getWidth() ;
Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
assertNotNull("Can't get lens facing info for camera id: " + mAllCameraIds[i],
lensFacing);
// Check that the sensor sizes are atleast what the CDD specifies
switch(lensFacing) {
case CameraCharacteristics.LENS_FACING_FRONT:
assertTrue("Front Sensor resolution should be at least " +
MIN_FRONT_SENSOR_RESOLUTION + " pixels, is "+ sensorResolution,
sensorResolution >= MIN_FRONT_SENSOR_RESOLUTION);
break;
case CameraCharacteristics.LENS_FACING_BACK:
if (firstBackFacingCamera) {
assertTrue("Back Sensor resolution should be at least "
+ MIN_BACK_SENSOR_RESOLUTION +
" pixels, is "+ sensorResolution,
sensorResolution >= MIN_BACK_SENSOR_RESOLUTION);
firstBackFacingCamera = false;
}
break;
default:
break;
}
...
这一项主要是测试可用的流配置是否包含一些必需的格式和大小,而今天我们主要看这块的逻辑:
private static final Size VGA = new Size(640, 480);
private static final long MIN_BACK_SENSOR_RESOLUTION = 2000000; //后摄最小Sensor大小
private static final long MIN_FRONT_SENSOR_RESOLUTION = VGA.getHeight() * VGA.getWidth(); //前摄最小Sensor大小
// Check that the sensor sizes are atleast what the CDD specifies
switch(lensFacing) {
case CameraCharacteristics.LENS_FACING_FRONT:
//这里要求前摄不能小于640x480像素
assertTrue("Front Sensor resolution should be at least " +
MIN_FRONT_SENSOR_RESOLUTION + " pixels, is "+ sensorResolution,
sensorResolution >= MIN_FRONT_SENSOR_RESOLUTION);
break;
case CameraCharacteristics.LENS_FACING_BACK:
if (firstBackFacingCamera) {
//这里要求后摄不能小于2000000像素
assertTrue("Back Sensor resolution should be at least "
+ MIN_BACK_SENSOR_RESOLUTION +
" pixels, is "+ sensorResolution,
sensorResolution >= MIN_BACK_SENSOR_RESOLUTION);
firstBackFacingCamera = false;
}
break;
default:
break;
}
(2)Demo Failed
CtsCameraTestCases
android.hardware.camera2.cts.ExtendedCameraCharacteristicsTest#testAvailableStreamConfigs[1]
Fail原因:
junit.framework.AssertionFailedError: Back Sensor resolution should be at least 2000000 pixels, is 1920000
at junit.framework.Assert.fail(Assert.java:50)
at junit.framework.Assert.assertTrue(Assert.java:20)
at android.hardware.camera2.cts.ExtendedCameraCharacteristicsTest.testAvailableStreamConfigs(ExtendedCameraCharacteristicsTest.java:239)
at java.lang.reflect.Method.invoke(Native Method)
由此可知,是由于后摄配置的是1600x1200 = 1920000导致问题的发生,现在Google已经不允许后摄低于200万像素了,而常用的200万摄像头都是1600x1200。
(3)Mtk平台的解法
在如下文件中添加相应的patch
//vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.buildStaticInfo.cpp
lbLoadDone:
/*METEDATA Ref //system/media/camera/docs/docs.html*/
//using full size
{
IMetadata::IEntry entryA(MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION);
MRect region1(MPoint(pSensorStaticInfo->SensorGrabStartX_CAP,pSensorStaticInfo->SensorGrabStartY_CAP), MSize(pSensorStaticInfo->captureWidth,pSensorStaticInfo->captureHeight));
entryA.push_back(region1, Type2Type<MRect>());
rMetadata.update(MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION, entryA);
MY_LOGD("MTK_SENSOR_INFO_ACTIVE_ARRAY_REGION(%d, %d, %d, %d)", pSensorStaticInfo->SensorGrabStartX_CAP, pSensorStaticInfo->SensorGrabStartY_CAP,
pSensorStaticInfo->captureWidth, pSensorStaticInfo->captureHeight);
}
//using full size(No correction)
{
IMetadata::IEntry entryA(MTK_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
entryA.push_back(pSensorStaticInfo->SensorGrabStartX_CAP, Type2Type<MINT32>());
entryA.push_back(pSensorStaticInfo->SensorGrabStartY_CAP, Type2Type<MINT32>());
entryA.push_back(pSensorStaticInfo->captureWidth, Type2Type<MINT32>());
entryA.push_back(pSensorStaticInfo->captureHeight, Type2Type<MINT32>());
rMetadata.update(MTK_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, entryA);
MY_LOGD("MTK_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE(%d, %d, %d, %d)", pSensorStaticInfo->SensorGrabStartX_CAP, pSensorStaticInfo->SensorGrabStartY_CAP,
pSensorStaticInfo->captureWidth, pSensorStaticInfo->captureHeight);
}
//Pixel arry
{
SensorDrv *const pSensorDrv = SensorDrv::get();
MUINT32 scenario = MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG; /*capture mode*/
SensorCropWinInfo rSensorCropInfo;
::memset(&rSensorCropInfo, 0, sizeof(SensorCropWinInfo));
pSensorDrv->sendCommand((IMGSENSOR_SENSOR_IDX) rInfo.getDeviceId(),
CMD_SENSOR_GET_SENSOR_CROP_WIN_INFO,
(MUINTPTR)&scenario,
(MUINTPTR)&rSensorCropInfo,
0);
IMetadata::IEntry entryA(MTK_SENSOR_INFO_PIXEL_ARRAY_SIZE);
+ if(rSensorCropInfo.full_w == 1600 && rSensorCropInfo.full_h == 1200){
+ rSensorCropInfo.full_w = 1640;
+ rSensorCropInfo.full_h = 1230;
+ }
MSize Size1(rSensorCropInfo.full_w, rSensorCropInfo.full_h);
entryA.push_back(Size1, Type2Type<MSize>());
rMetadata.update(MTK_SENSOR_INFO_PIXEL_ARRAY_SIZE, entryA);
}