• 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 {
            ......
        }
    }
    
  • 相关阅读:
    Python读取ini配置文件封装方法
    Python对Selenium调用浏览器进行封装包括启用无头浏览器,及对应的浏览器配置文件
    windows下 apache 二级域名相关配置
    Incorrect integer value: '' for column 'id' at row 1
    [Effective Java 读书笔记] 第二章 创建和销毁对象 第三 四条
    [Effective Java 读书笔记] 第二章 创建和销毁对象 第二条
    [Effective Java 读书笔记] 第二章 创建和销毁对象 第一条
    JAVA ReentrantLock的使用
    Thread类的interrupted方法和isInterrupted方法的区别
    [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
  • 原文地址:https://www.cnblogs.com/fanglongxiang/p/13781575.html
Copyright © 2020-2023  润新知