半年前在做gms认证,其他部分多多少少能找到一些资料,camera这部分卡的时间比较久,主要涉及到几个文件的修改 xxxx_sensor.xml camxtitan17context.cpp camxsettings.xml 错误多为某些配置项缺失或错误配置导致。
目录
1、android.hardware.camera2.cts.CameraDeviceTest#testSessionParametersStateLeak[1]
2、android.hardware.camera2.cts.CaptureRequestTest#testAeModeAndLock[1]
3、android.hardware.camera2.cts.CaptureRequestTest#testColorCorrectionControl[1]
4、android.hardware.camera2.cts.BurstCaptureRawTest#testManualAutoSwitch[1]
5、android.hardware.camera2.cts.BurstCaptureRawTest#testMetadataRoundDown[1]
6、android.hardware.camera2.cts.BurstCaptureRawTest#testTimestamp[1]
7、android.hardware.camera2.cts.MultiViewTest#testDualCameraPreview[1]
8、android.hardware.camera2.cts.NativeImageReaderTest#testHeic
本地测试方法
1、在源码包的cts文件夹下含有各个cts测试的源码,camera通过如下命令编译:
mmm cts/tests/camera
其他的模块大部分也可以通过这种方式本地初测。搜索下test项函数,看下在哪个包里,编译对应的包就可以了。
2、编译完成生成的是 CtsCameraTestCases.apk,执行
adb install CtsCameraTestCases.apk
3、进入到设置里,赋予这个apk所需的权限。
4、查看install 的cts_test包
adb shell
pm list instrumentation
#显示如下
#instrumentation:android.camera.cts/androidx.test.runner.AndroidJUnitRunner (target=android.camera.cts)
5、运行测试
adb shell am instrument -r -e class android.hardware.camera2.cts.CameraDeviceTest#testSessionParametersStateLeak[1] -w android.camera.cts/androidx.test.runner.AndroidJUnitRunner
android.hardware.camera2.cts.CameraDeviceTest#testSessionParametersStateLeak[1]这个就是fail项,也可以运行一个类,android.hardware.camera2.cts.CameraDeviceTest。
部分fail项修改
过的时间比较久了,报告找不到了,但问题有一些简要记录。
1、android.hardware.camera2.cts.CameraDeviceTest#testSessionParametersStateLeak[1]
报错信息:setup的设备有两个,teardown的只有一个。
这说明有crash,抓了log分析,判断为aec错误导致session dump最终导致crash,检查是否有自定义的aec相关feature。判断依据如下:
> 06-02 18:43:08.350 8136 8161 W CamX : [ WARN][STATS_AEC] caecxcontrol.cpp:541: process error pre-processing stats; marking stats as invalid
> 06-02 18:43:08.351 8136 8161 E CamX : [ERROR][STATS_AEC] caecxmodarbitration.cpp:60: UtilQuantities2Exposure exposure calculated as zero; check gain 1.0 time 0 corr 1.0
> 06-02 18:43:08.351 8136 8161 I CamX : [ DUMP][CORE ] camxsession.cpp:7648 DumpDebugInfo() + Stuck on Sequence Id: 0 Request Id: 1
提case,高通检查后提出查看是否有参数minlineout,文件位置:
/A13_HOLI/vendor/qcom/proprietary/chi-cdk/oem/qcom/sensor/xxxsensor
#这里换成项目使用的sensor
检查后发现,缺失是缺少了minlineout,加入如下位置:
<exposureControlInfo>
+ <!--Maximum analog again supported by sensor -->
+ <maxAnalogGain>16</maxAnalogGain>
+ <!--Maximum digital again supported by sensor -->
+ <maxDigitalGain>1</maxDigitalGain>
+ <!--Minimum offset to be maintained between line count and frame length lines -->
+ <verticalOffset>2</verticalOffset>
+ <!--Minimum line count supported by sensor -->
+ <minLineCount>2</minLineCount>
+ <!--Maximum line count supported by sensor -->
+ <maxLineCount>65533</maxLineCount>
+ <!--Conversion factor to convert real digital gain to register digital gain -->
+ <realToRegDigitalGainConversionFactor>256</realToRegDigitalGainConversionFactor>
+ <!--Real gain to register gain equation
+ The equation must contain "realGain" in its equation
+ Ex:= 512 - (512 / realGain) -->
+ <realToRegGain></realToRegGain>
+ <!--Register gain to real gain equation
+ The equation must contain "regGain" in its equation
+ Ex:= 512 / (512 - regGain) -->
+ <regToRealGain></regToRealGain>
+ </exposureControlInfo>
加入后复测pass
2、android.hardware.camera2.cts.CaptureRequestTest#testAeModeAndLock[1]
3、android.hardware.camera2.cts.CaptureRequestTest#testColorCorrectionControl[1]
4、android.hardware.camera2.cts.BurstCaptureRawTest#testManualAutoSwitch[1]
5、android.hardware.camera2.cts.BurstCaptureRawTest#testMetadataRoundDown[1]
6、android.hardware.camera2.cts.BurstCaptureRawTest#testTimestamp[1]
以上2-6fail项原因均与1相同,log中可以看到如下错误:
06-06 09:47:54.106 17820 17837 I Camera2ParameterizedTestCase: Camera ids in setup:[0, 1]
06-06 09:47:54.107 17820 17837 I Camera2ParameterizedTestCase: Camera ids in tearDown:[]
7、android.hardware.camera2.cts.MultiViewTest#testDualCameraPreview[1]
此项测试的是同时打开前后摄,在高通的文档中,有针对此项的说明:
//80-P9301-61.pdf
Ensure that both the front camera and rear camera
have different CCI bus. ISP bubble issues are seen
if they are on the same bus due to system load.
问题原因:资源冲突
检查前后摄挂载的cci总线,文件位于:
//A13_HOLI/vendor/qcom/proprietary/camera-devicetree/holi-camera-sensor-mtp.dtsi
...
&cam_cci0
...
&cam_cci1
...
以上是cci两条总线,经过检查,前摄挂在1上,后摄和副摄挂在0上,并不冲突
抓log分析如下:
06-07 22:38:41.909 0 0 I CAM_ERR : CAM-ISP: cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl: 1462 Can not acquire tfe csid pixel resource
06-07 22:38:41.909 0 0 I CAM_ERR : CAM-ISP: cam_tfe_mgr_acquire_hw_for_ctx: 1795 Acquire TFE CSID IPP resource Failed dual:1
06-07 22:38:41.909 0 0 I CAM_ERR : CAM-ISP: cam_tfe_mgr_acquire_hw: 2217 can not acquire resource
说明TFE资源冲突,我们用的两个sensor一个占用两个TFE,另一个也占用两个TFE,而总共就三个TFE,所以冲突。
修改点:
//A13_HOLI/vendor/qcom/proprietary/chi-cdk/oem/qcom/sensor/xxxsensor
#这里换成项目使用的sensor
...
<resolutionInfo>
<resolutionData>
...
<lineLengthPixelClock>2512</lineLengthPixelClock>
<frameLengthLines>3197</frameLengthLines>
...
<outputPixelClock>480000000</outputPixelClock>
...
<frameRate>30</frameRate>
...
<resSettings>
<regSetting>
<registerAddr>0x0340</registerAddr>
<registerData>0x0C7D</registerData>
<regAddrType range="[1,4]">2</regAddrType>
<regDataType range="[1,4]">2</regDataType>
<operation>WRITE</operation>
<delayUs>0x00</delayUs>
</regSetting>
<regSetting>
<registerAddr>0x0342</registerAddr>
<registerData>0x09D0</registerData>
<regAddrType range="[1,4]">2</regAddrType>
<regDataType range="[1,4]">2</regDataType>
<operation>WRITE</operation>
<delayUs>0x00</delayUs>
</regSetting>
</resolutionData>
<resolutionData>
...
<outputPixelClock>xxxx</outputPixelClock>
...
</resolutionData>
...
</resolutionInfo>
其中,lineLengthPixelClock以及frameLengthLines的值对应的是寄存器0x0342以及0x0340位置的值
修改值时,对应寄存器位置的值也要修改
重点关注上面的outputPixelClock,简单来说,这个值大,占用的TFE资源就多。
第一步:验证问题点 将所有大数值对应的<resolutionData>删掉,看CTS测试是否通过,如果通过,则向sensor厂商的FAE要相关配置文件的更新。
验证结果:确实可以pass测试,但是相机无法使用。说明问题确实出现在这里,那么接下来就是向厂商要符合TFE数量要求的配置了。
第二步:加入对1920x1080分辨率占用1TFE的正确配置
加入后复测pass
8、android.hardware.camera2.cts.NativeImageReaderTest#testHeic
项目没有支持Heic图片的需求,disable本地的heic:
//vendor/qcom/proprietary/camx/build/infrastructure/android/built/settings/mannar/camxoverridesettingsprivate.txt
; Enable Native HEIF
;
; Enable/Disable native HEIF
;
; Type: BOOL
;
; 0xBDFF08B8=FALSE
; enableNativeHEIF=FALSE
//vendor/qcom/proprietary/camx/src/settings/common/camxsettings.xml
<setting>
<Name>Enable Native HEIF</Name>
<Help>Enable/Disable native HEIF</Help>
<VariableName>enableNativeHEIF</VariableName>
<VariableType>BOOL</VariableType>
<SetpropKey>persist.vendor.camera.enableNativeHEIF</SetpropKey>
<DefaultValue>FALSE</DefaultValue>
<Dynamic>FALSE</Dynamic>
</setting>
//vendor/qcom/proprietary/camx/src/settings/mannar/g_camxsettings.xml
<setting>
<Name>Enable Native HEIF</Name>
<Help>Enable/Disable native HEIF</Help>
<VariableName>enableNativeHEIF</VariableName>
<VariableType>BOOL</VariableType>
<SetpropKey>persist.vendor.camera.enableNativeHEIF</SetpropKey>
<DefaultValue>FALSE</DefaultValue>
<Dynamic>FALSE</Dynamic>
</setting>
加入后复测pass
9、android.hardware.camera2.cts.ZoomCaptureTest#testRawZoomCapture[1] & android.hardware.camera2.cts.ZoomCaptureTest#testJpegZoomCapture[1]
问题描述:Camera 0 result metadata must contain ACTIVE_PHYSICAL_ID
ACTIVE_PHYSICAL_ID全称为LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,是A10之后加入的配置,作用为当前logic camera使用了哪些pysical camera
配置位于:
///vendor/qcom/proprietary/camx/src/hwl/titan17x/camxtitan17xcontext.cpp
如下位置:
static const CameraMetadataTag SupportedResultKeys[] =
...
LogicalMultiCameraActivePhysicalId //disable for android.hardware.camera2.cts.ZoomCaptureTest#testRawZoomCapture[1] & android.hardware.camera2.cts.ZoomCaptureTest#testJpegZoomCapture[1]
...
改为
//LogicalMultiCameraActivePhysicalId
在这个位置,定义了TAG支持的key,对应CaptureResult.java以及CaptureCharacteristicsKeys.java中Available的key,这里去掉,对应java文件中的key就不会再被使用。
加入后复测pass
10、android.hardware.camera2.cts.StillCaptureTest#testFullRawCapture[1] & android.hardware.camera2.cts.StillCaptureTest#testFullRawZSLCapture[1]
问题描述:错误为NoiseProfile中的S值和O值范围错误,要求:S>0 O≥0,而目前都是零
java.lang.Throwable(Test failed for camera 0: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 0: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 0: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 0: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 1: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 1: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 1: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
java.lang.Throwable(Test failed for camera 1: NoiseProfile coefficients Pair{0.0 0.0} must have: S > 0, O >= 0)
找到如下文件:
//CaptureResult.java(HOLI vendor下)
public static final Key<android.util.Pair<Double,Double>[]> SENSOR_NOISE_PROFILE =
new Key<android.util.Pair<Double,Double>[]>("android.sensor.noiseProfile", new TypeReference<android.util.Pair<Double,Double>[]>() {{ }});
对应get方法在如下文件:
//camxsensornode.cpp 以及//camxtpgnode.cpp(HOLI vendor下)
// Channels * 2 to sensor amplification (S) and sensor readout noise (O) on each channel
DOUBLE noiseProfile[NumChannels * 2] = { 0 };
GetSensorDataObject()->GetNoiseProfile(noiseProfile, colorFilterArrangement,
sensitivity, ISO100Gain);
进而找到:
VOID ImageSensorData::GetNoiseProfile(
DOUBLE* pNoiseProfile,
ColorFilterArrangement colorFilterArrangement,
INT32 sensitivity,
FLOAT ISO100Gain)
{
switch (colorFilterArrangement)
{
case ColorFilterArrangement::BAYER_BGGR:
pNoiseProfile[0] = GetNoiseModelEntryS(sensitivity, NoiseCoefficientChannel::BAYER_B);
pNoiseProfile[1] = GetNoiseModelEntryO(sensitivity, ISO100Gain, NoiseCoefficientChannel::BAYER_B);
pNoiseProfile[2] = GetNoiseModelEntryS(sensitivity, NoiseCoefficientChannel::BAYER_Gb);
pNoiseProfile[3] = GetNoiseModelEntryO(sensitivity, ISO100Gain, NoiseCoefficientChannel::BAYER_Gb);
pNoiseProfile[4] = GetNoiseModelEntryS(sensitivity, NoiseCoefficientChannel::BAYER_Gr);
pNoiseProfile[5] = GetNoiseModelEntryO(sensitivity, ISO100Gain, NoiseCoefficientChannel::BAYER_Gr);
pNoiseProfile[6] = GetNoiseModelEntryS(sensitivity, NoiseCoefficientChannel::BAYER_R);
pNoiseProfile[7] = GetNoiseModelEntryO(sensitivity, ISO100Gain, NoiseCoefficientChannel::BAYER_R);
break;
...
}
}
以及
//camximagesensordata.cpp(HOLI vendor下)
DOUBLE ImageSensorData::GetNoiseModelEntryO(
INT32 sensitivity,
FLOAT ISO100Gain,
NoiseCoefficientChannel channel)
{
NoiseCoefficent noiseCoeff = {0.0};
GetNoiseCoeff(&noiseCoeff, channel);
DOUBLE maxAnalogSensitvity = m_pSensorData->exposureControlInfo.maxAnalogGain * (100.0f / ISO100Gain);
DOUBLE digitalGain = sensitivity / maxAnalogSensitvity;
digitalGain = (digitalGain < 1.0) ? 1.0 : digitalGain;
CAMX_LOG_VERBOSE(CamxLogGroupSensor, "sensitivity:%d, ISO100Gain: %f, digitalGain:%lf",
sensitivity, ISO100Gain, digitalGain);
DOUBLE noiseModelEntryO = (noiseCoeff.gradient_O * sensitivity * sensitivity) +
(noiseCoeff.offset_O * digitalGain * digitalGain);
return ((noiseModelEntryO < 0.0) ? 0.0 : noiseModelEntryO);
}
由channel追踪
//A13_HOLI/vendor/qcom/proprietary/chi-cdk/api/sensor/camxsensordriver.xsd
<xs:simpleType name="NoiseCoefficientChannel">
<xs:annotation>
<xs:documentation>Noise Coefficient Channels</xs:documentation>
<xs:documentation>Channel are in R=0, GR=1, GB=2, B=3 order</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="BAYER_R"/>
<xs:enumeration value="BAYER_Gr"/>
<xs:enumeration value="BAYER_Gb"/>
<xs:enumeration value="BAYER_B"/>
</xs:restriction>
</xs:simpleType>
以及NoiseCoefficent
<xs:complexType name="NoiseCoefficent">
<xs:sequence>
<!-- element for gradient_S -->
<xs:element name="gradient_S" type="xs:double">
<xs:annotation>
<xs:documentation>gradient_s Sensor amplification</xs:documentation>
</xs:annotation>
</xs:element>
<!-- element for offset_S -->
<xs:element name="offset_S" type="xs:double">
<xs:annotation>
<xs:documentation>offset_S Sensor amplification</xs:documentation>
</xs:annotation>
</xs:element>
<!-- element for gradient_O -->
<xs:element name="gradient_O" type="xs:double">
<xs:annotation>
<xs:documentation>gradient_O sensor readout noise</xs:documentation>
</xs:annotation>
</xs:element>
<!-- element for offset_O -->
<xs:element name="offset_O" type="xs:double">
<xs:annotation>
<xs:documentation>offset_O sensor readout noise</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
进而通过element值搜索,找到sensor的配置文件 位于:
/4350_A13_HOLI/vendor/qcom/proprietary/chi-cdk/oem/qcom/sensor/xxxsensor
#换成项目使用的sensor
发现没有对gradient_S进行设置。修改xxx_sensor.xml,加入
...
<noiseCoefficent>
<gradient_S>1.504952e-06</gradient_S>
<offset_S>1.444901e-05</offset_S>
<gradient_O>6.742849e-12</gradient_O>
<offset_O>6.392815e-07</offset_O>
</noiseCoefficent>
</sensorDriverData>//加入位置为</sensorDriverData>前
可以发现,虽然追踪过程比较复杂,但修改只涉及到了配置文件的修改,前面的几个问题也大多如此,可以看到camera这部分大多数的fail项还是由于sensor或项目的配置引起的,遇到问题要首先考虑这点。
加入后复测pass
还有几个比较顽固的fail项,提case高通也分析了很久,后面找下case记录整理后再发出来。