GMS_Camera相关_完善修改中 若有建议欢迎提醒

前言

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要同时存在或者不存在。
在mtk平台正确的类似下面:

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的代码)。然后根据报错,找到问题点。
由于工具总是不断更新,有些地方可能和现有工程不一样,参考下面地址找到对应代码:
一个非常有用的网址(几乎包含了android相关的各种、各个版本源码):
https://android.googlesource.com/
如:
cts各个版本(Tags能直接看出来)源码在:https://android.googlesource.com/platform/cts/
VTS:https://android.googlesource.com/platform/test/vts/

部分工具没有源码,一般能通过反编译工具中的apk,基本也能看出逻辑,找出问题。

导出手机中camera参数

通过下面命令,可以导出手机中camera相关的参数。
查看文件,可以看出手机中的camera参数配置,检查时候生效,是否正常和报错一致。

adb shell dumpsys media.camera -v 1 > xxx.log

基本检查确认

一些camera的基本检查 配置。

16倍数

分辨率的配置一般是16的倍数,如720x1280,其中720 1280都是16的倍数。

基本支持的检查,每个摄像头最好单独确认下

  1. 是否支持闪光灯。
  2. 是否支持自动对焦AF,若支持AF 通过预览查看是否调好。
  3. 清楚camera的resolution,配置的分辨率长宽不要超过resolution的长宽。如gc5025 resolution是2592x1944,则分辨率最大为2592x1944。
  4. 预览、拍照是否正常,颜色正常。

通过比较

  1. 同一平台某个摄像头若过过GMS,基本可以直接拷贝过来使用(或跑前比较下)。
  2. 同一平台若某个摄像头没有过过,可以参考其他平台过过的该颗摄像头,也可以参考过过的类似的摄像头(如gc5035可以参考下gc5025)。

其他

几个常量记录

记录几个报错中的常量,方便通过报错直接了解, 而不需要再次从工程中查看后才知道。

profile ID

报错类似:
Test failed for camera 0: Video size 1280x720 for profile ID 5 must be one of the camera device supported video size!
这里的profile ID 5表示什么呢?
就是某个分辨率对应的录像质量等级,这里就是后摄1280x720对应的720P必须要支持。若缺少就添加上。

//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

报错类似:
Camera 0: Video duration doesn't match: recorded 2564.000000ms, expected [4640.000000,6960.000488]ms.
一般解决:
第一种修改media profiles对应Camera,对应fail项size的frameRate和drvier输出的帧率一致;
第二种修改drvier对应video size的帧率和media profiles一致。
另:media profiles的文件在手机中的位置(可以直接修改push验证,也可以确认修改是否正确生效):

/vendor/etc/media_profiles_V1_0.xml

看下源码:
下面以android.hardware.camera2.cts.RecordingTest#testBasicRecording为例:

//工程中的源码,应该是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 {
        ......
    }
}
posted @ 2020-10-08 22:28  流浪_归家  阅读(1938)  评论(1编辑  收藏  举报