前言Camera架构本身内容就很多,因此在GMS中关于Camera的测试项很多,CTS/CTSV/ITS(ctsv中)/GTS/CTS-ON-GSI/VTS中都存在相关测试模块。测试了与Camera相关的所有功能。 一时总结不全,不断完善中 经验camera问题可能功能问题、也可能效果,大部分是配置问题。camera参数非常多而且很多之间存在相互关联,某处参数修改可能影响与之关联的参数。 简单记录下一般如何处理 根据报错直接修改有些报错很明显的,直接看报错就能定位到问题,如果camera相关比较熟悉的话 直接修改。 The static info key 'android.hotPixel.availableHotPixelModes' FAST and HIGH_QUALITY mode must both present or both not present android.hotPixel.availableHotPixelModes这个配置中FAST和HIGH_QUALITY要同时存在或者不存在。 CONFIG_METADATA_BEGIN(MTK_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES) CONFIG_ENTRY_VALUE(MTK_HOT_PIXEL_MODE_FAST, MUINT8) CONFIG_ENTRY_VALUE(MTK_HOT_PIXEL_MODE_HIGH_QUALITY, MUINT8) CONFIG_METADATA_END() 查看相关代码CTS源码在工程目录下的cts/目录中(不过这里的一般比较老,主要参考下面网址查看),很容易找到源码(CTS-ON-GSI也基本可以参考CTS的代码)。然后根据报错,找到问题点。 部分工具没有源码,一般能通过反编译工具中的apk,基本也能看出逻辑,找出问题。 导出手机中camera参数通过下面命令,可以导出手机中camera相关的参数。 adb shell dumpsys media.camera -v 1 > xxx.log 基本检查确认一些camera的基本检查 配置。 16倍数分辨率的配置一般是16的倍数,如720x1280,其中720 1280都是16的倍数。 基本支持的检查,每个摄像头最好单独确认下
通过比较
其他几个常量记录记录几个报错中的常量,方便通过报错直接了解, 而不需要再次从工程中查看后才知道。 profile ID报错类似: //AndroidQ: cts/ RecordingTest.java private static final int[] mCamcorderProfileList = { CamcorderProfile.QUALITY_HIGH, //1 CamcorderProfile.QUALITY_2160P,//8 CamcorderProfile.QUALITY_1080P,//6 CamcorderProfile.QUALITY_720P,//5 CamcorderProfile.QUALITY_480P,//4 CamcorderProfile.QUALITY_CIF,//3 CamcorderProfile.QUALITY_QCIF,//2 CamcorderProfile.QUALITY_QVGA,//7 CamcorderProfile.QUALITY_LOW,//0 }; //framework/base CamcorderProfile.java public static final int QUALITY_HIGH = 1; /** * Quality level corresponding to the 2160p (3840x2160) resolution. */ public static final int QUALITY_2160P = 8; /** * Quality level corresponding to the 1080p (1920 x 1080) resolution. * Note that the vertical resolution for 1080p can also be 1088, * instead of 1080 (used by some vendors to avoid cropping during * video playback). */ public static final int QUALITY_1080P = 6; /** * Quality level corresponding to the 720p (1280 x 720) resolution. */ public static final int QUALITY_720P = 5; /** * Quality level corresponding to the 480p (720 x 480) resolution. * Note that the horizontal resolution for 480p can also be other * values, such as 640 or 704, instead of 720. */ public static final int QUALITY_480P = 4; /** * Quality level corresponding to the cif (352 x 288) resolution. */ public static final int QUALITY_CIF = 3; /** * Quality level corresponding to the qcif (176 x 144) resolution. */ public static final int QUALITY_QCIF = 2; /** * Quality level corresponding to the QVGA (320x240) resolution. */ public static final int QUALITY_QVGA = 7; /** * Quality level corresponding to the lowest available resolution. */ public static final int QUALITY_LOW = 0; format报错类似: //framework/base ImageFormat.java public static final int YUY2 = 0x14;//20 public static final int RAW_SENSOR = 0x20;//32 public static final int PRIVATE = 0x22;//34 public static final int YUV_420_888 = 0x23;//35 public static final int RAW_PRIVATE = 0x24;//36 public static final int YUV_422_888 = 0x27;//39 public static final int YUV_444_888 = 0x28;//40 public static final int JPEG = 0x100;//256 关于metadata中配置的格式定义(与上述报错对应参考): //framework/base StreamConfigurationMap.java // from system/core/include/system/graphics.h private static final int HAL_PIXEL_FORMAT_RAW16 = 0x20;//32 private static final int HAL_PIXEL_FORMAT_BLOB = 0x21;//33 private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22;//34 private static final int HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23;//35 private static final int HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24;//36 private static final int HAL_PIXEL_FORMAT_RAW10 = 0x25;//37 private static final int HAL_PIXEL_FORMAT_RAW12 = 0x26;//38 static int imageFormatToInternal(int format) { switch (format) { case ImageFormat.JPEG: case ImageFormat.DEPTH_POINT_CLOUD: case ImageFormat.DEPTH_JPEG: case ImageFormat.HEIC: return HAL_PIXEL_FORMAT_BLOB; case ImageFormat.DEPTH16: return HAL_PIXEL_FORMAT_Y16; case ImageFormat.RAW_DEPTH: return HAL_PIXEL_FORMAT_RAW16; default: return format; } } public static int imageFormatToPublic(int format) { switch (format) { case HAL_PIXEL_FORMAT_BLOB: return ImageFormat.JPEG; case ImageFormat.JPEG: throw new IllegalArgumentException( "ImageFormat.JPEG is an unknown internal format"); default: return format; } } 几个camera常见报错记录android.hardware.camera2.cts.RecordingTest#xxxxx报错类似: /vendor/etc/media_profiles_V1_0.xml 看下源码: //工程中的源码,应该是10_R1的 public void testBasicRecording() throws Exception { doBasicRecording(/*useVideoStab*/false); } private void doBasicRecording(boolean useVideoStab) throws Exception { doBasicRecording(useVideoStab, false); } private void doBasicRecording(boolean useVideoStab, boolean useIntermediateSurface) throws Exception { for (int i = 0; i < mCameraIds.length; i ) { ...... basicRecordingTestByCamera(mCamcorderProfileList, useVideoStab, useIntermediateSurface); ...... } } private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab, boolean useIntermediateSurface) throws Exception { ...... for (int profileId : camcorderProfileList) { ...... float frameDurationMs = 1000.0f / profile.videoFrameRate;//注意这里 float durationMs = 0.f; if (useIntermediateSurface) { durationMs = mQueuer.getQueuedCount() * frameDurationMs; } else { durationMs = resultListener.getTotalNumFrames() * frameDurationMs;//走这,here } ...... // Validation. validateRecording(videoSz, durationMs, frameDurationMs, FRMDRP_RATE_TOLERANCE); } ...... } private void validateRecording( Size sz, float expectedDurationMs, float expectedFrameDurationMs, float frameDropTolerance) throws Exception { validateRecording(sz, expectedDurationMs, /*fixed FPS recording*/0.f, expectedFrameDurationMs, /*fixed FPS recording*/0.f, frameDropTolerance); } private void validateRecording( Size sz, float expectedDurationMinMs, // Min duration (maxFps) float expectedDurationMaxMs, // Max duration (minFps). 0.f for fixed fps recording float expectedFrameDurationMinMs, // maxFps float expectedFrameDurationMaxMs, // minFps. 0.f for fixed fps recording float frameDropTolerance) throws Exception { ...... if (expectedDurationMaxMs == 0.f) { expectedDurationMaxMs = expectedDurationMinMs; } MediaExtractor extractor = new MediaExtractor(); try { ...... // TODO: Don't skip this one for video snapshot on LEGACY assertTrue(String.format( "Camera %s: Video duration doesn't match: recorded %fms, expected [%f,%f]ms.", mCamera.getId(), duration, expectedDurationMinMs * (1.f - DURATION_MARGIN), expectedDurationMaxMs * (1.f DURATION_MARGIN)), duration > expectedDurationMinMs * (1.f - DURATION_MARGIN) && duration < expectedDurationMaxMs * (1.f DURATION_MARGIN)); ...... } finally { ...... } } |
|