接着上一篇CTS-Camera本地测试(无需科学上网)及Android13高通平台部分fail项修改-CSDN博客,有几个提了case高通也分析了很久的fail项,其中最离谱的是问题1,第一个接手case的人反反复复处理、内部排查踢皮球、要求log,折腾了很久,最终就给出个解不了的结论。后面还是靠着自己发现了一些蛛丝马迹,并且换了个case接手人才最终解决。

1、android.hardware.camera2.cts.PerformanceTest#testReprocessingCaptureStall

问题描述:这个测试是拍照后再预览取20帧的图片,把出图间隔和fps标准进行比较,这里就是有间隔大于了要求值109。

java.lang.AssertionError: max capture stall duration should be no larger than 109.99999890000001

at org.junit.Assert.fail(Assert.java:89)

at org.junit.Assert.assertTrue(Assert.java:42)

at android.hardware.camera2.cts.PerformanceTest.reprocessingCaptureStallTestByCamera(PerformanceTest.java:965)

at android.hardware.camera2.cts.PerformanceTest.testReprocessingCaptureStall(PerformanceTest.java:854)

前面和第一个case负责人扯皮踩坑的过程就不赘述了,直接从问题有解决方向开始。(解决办法在问题最后、仅仅是修改两个值)

因为这个问题是跟fps和间隔相关,所以首先想到在最底层出图的地方加log看下间隔,发现每一帧间的间隔是没错的。

其次想看看目前间隔超出109,究竟是超出了多少。所以在cts测试代码中加了log:

private void reprocessingCaptureStallTestByCamera(int reprocessInputFormat) throws Exception {

...

// Need look longer time, as the stutter could happen after the reprocessing

// output frame is received.

long[] timestampGap = new long[MAX_REPROCESS_RETURN_FRAME_COUNT + 1];

Arrays.fill(timestampGap, 0);

CaptureResult[] results = new CaptureResult[timestampGap.length];

long[] frameDurationsNs = new long[timestampGap.length];

for (int j = 0; j < results.length; j++) {

results[j] = mZslResultListener.getCaptureResult(

CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);

if (j > 0) {

timestampGap[j] = results[j].get(CaptureResult.SENSOR_TIMESTAMP) -

results[j - 1].get(CaptureResult.SENSOR_TIMESTAMP);

assertTrue("Time stamp should be monotonically increasing",

timestampGap[j] > 0);

}

frameDurationsNs[j] = results[j].get(CaptureResult.SENSOR_FRAME_DURATION);

}

Log.i(TAG, "timestampGap: " + Arrays.toString(timestampGap));

Log.i(TAG, "frameDurationsNs: " + Arrays.toString(frameDurationsNs));

if (VERBOSE) {

}

// Get the number of candidate results, calculate the average frame duration

// and max timestamp gap.

...

结果如下:注意这里timestampGap的第8个值,很明显这个值有大问题。

从这里大部分数据看,就是30fps的出图速度,最多丢1帧,变成66666666,而这第8个值的数量级都不一样,可以说问题就出在这里。

06-08 01:44:05.599 31085 31102 I PerformanceTest: timestampGap: [0, 33291823, 66583645, 33291823, 33291823, 33291771, 33291823, 1597191040, 33291823, 33291823, 33291823, 43291823, 33291823, 33291823, 33291823, 56583646, 33291770, 33291823, 33291823, 33291823, 33291823]

06-08 01:44:05.599 31085 31102 I PerformanceTest: frameDurationsNs: [33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333]

06-08 01:44:08.005 31085 31102 I PerformanceTest: timestampGap: [0, 33291823, 33291823, 33291823, 33291771, 33291823, 33291822, 1654413698, 33291823, 66583646, 33291823, 33291823, 33291823, 33291823, 66583593, 66583646, 33291823, 33291823, 33291823, 33291823, 33291823]

06-08 01:44:08.006 31085 31102 I PerformanceTest: frameDurationsNs: [33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333]

06-08 01:44:10.288 31085 31102 I PerformanceTest: timestampGap: [0, 33291771, 33291822, 33291823, 33291823, 33291823, 33291823, 1571471977, 33291771, 33291823, 33291823, 33291823, 33291823, 33291823, 33291823, 66583646, 33291823, 33291770, 33291823, 33291823, 33291823]

06-08 01:44:10.288 31085 31102 I PerformanceTest: frameDurationsNs: [33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333, 33333333]

那么为什么会出现这么异常的一个值?

还记得上面提到这个测试是拍照后再取20帧的数据,与标准比较。按理来说frame的number应该是0-20。但是,对比Performance的log和底层,发现并不一一对应,而是底层的34-40加上下一轮的0-13,对应了Performance中的0-20。而上一轮的40到下轮的0这个过程,是重新配流(类似重新打开相机),很耗费时间,这就是第八个值非常大的原因。(这里年代有点久远,找不到抓底层的log了)

把这个发现反馈给高通,高通那边分析提供的log最终就锁定到了这样一个错误信息:

06-07 22:07:02.464 1010 1453 E CamX : [ERROR][META ] camxmetabuffer.cpp:2753 SetTag() Cannot set 805d000d size 4 max 1

这里报错可能会引起重新configure_streams,而重新配流相比30fps间隔就是很长的时间了,也就是这个数量级异常值产生的原因。

metadata抓取方式:

adb shell dumpsys media.camera > cameraservice_dump.txt

在metadata dump查找805d000d,对应的就是这项配置:

org.codeaurora.qcamera3.sessionParameters.enableMCTFwithReferenceFrame (805d000d): byte[4]

接下来就是去源码中找,找到这两个位置,当前值确实是1,将其改成上面错误信息中的4,可以通过测试了。

Camxvendortagdefines.h

{ "enableMCTFwithReferenceFrame", TYPE_BYTE, 1 },

Chivendortagdefines.h

{ "enableMCTFwithReferenceFrame", TYPE_BYTE, 1 }

复测pass

总结来说,这个问题就是配置错误导致重新配流,进而引起的间隔时间异常

2、android.hardware.cts.CameraGLTest#testCameraToSurfaceTextureMetadata

问题描述:对各个分辨率下各个帧率出图是否满足帧率进行测试。100帧允许出现4帧间隔超出fps限制。

java.lang.AssertionError: Too many frame intervals out of frame rate bounds: 13, limit 4

at org.junit.Assert.fail(Assert.java:89)

at org.junit.Assert.assertTrue(Assert.java:42)

at android.hardware.cts.CameraGLTest$6.run(CameraGLTest.java:665)

at android.hardware.cts.CameraGLTest.runForAllCameras(CameraGLTest.java:346)

at android.hardware.cts.CameraGLTest.testCameraToSurfaceTextureMetadata(CameraGLTest.java:532)

当出图不稳定就会出现Fail(帧间隔太大),每次测试结果不同。(出现丢帧,log中的时间间隔,错误情况下都是正常情况下的二倍,说明最差也就丢了1帧) 属于性能相关问题,经过反复测试,后摄阶段运行800s可以通过,前摄12- >4 相差较大,先考虑了sensor的问题,与三星FAE沟通,降低一些frameLengthLines进行尝试。 降低至4000x3000时有极地概率通过测试,降低至3280X2160时中等概率过测试。基本能判断这就是处理速度不达标导致的问题。

那产生这个问题的根本原因是什么呢?

首先确认平台所支持的预览分辨率最大为1920x1080。在配置文件中,确实是如此配置的,但经过同高通沟通,根据他们之前的经验,CTS并不直接走配置的部分,而是在代码文件中动态配置。

经过查看sys info,确认了确实有大于1920x1080的分辨率部分被测试到,其值是在framework层计算的,计算的根据是:availableStreamConfigurations & availableMinFrameDurations,进而去修改availableMinFrameDurations的计算产生逻辑,更正大于支持部分的fps

In function InitializeScalerStaticCaps() (src/core/camxhwenvironment.cpp):

supportedFPS = ClosestMaxFps(supportedFPS, sensorIndex);

+ if ((width > 1920 || height > 1080) && (supportedFPS > 24))

+ supportedFPS = 24;

...

SetAvailableMinFrameDuration();

复测pass

还有一些能找到case记录,但是已经不完全了,也记不太清具体处理了,能整理出来的就目前这些问题了。

参考文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。

大家都在找:

android:android wear