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 {
        ......
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM