android.scaler.streamConfigurationMap Key值的来源
android.scaler.streamConfigurationMap Key值的來源
一、背景
在開發camera app時,app獲取preview的YUV數據,當從KEY CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP的StreamConfigurationMap中獲取類型為SurfaceHolder.class的size時,發現它少于picture size,代碼如下:
CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = mCharacteristics.get(cameraId).get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); Size[] size = map.getOutputSizes(SurfaceHolder.class);獲取的outsize如果少于picture size,如果camera app選擇在app中對預覽數據進行處理而呈現給用戶的話,它將會造成成取景的窗口小于拍照生成圖片的窗口。
二、StreamConfigurationMap中數據的來源
StreamConfigurationMap包含有各種camera streamconfig的數據 ,一般我們只知道這些數據來源于camera metadata,從代碼看,我們能知道StreamConfigurationMap包含camera metadata中SCALER_AVAILABLE_STREAM_CONFIGURATIONS、SCALER_AVAILABLE_MIN_FRAME_DURATIONS、SCALER_AVAILABLE_STALL_DURATIONS、DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS、DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS、DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS、CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS和SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP這些鍵值。
LINUX/android/frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
三、SurfaceHolder.class類型output size的來源
frameworks/base/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
public <T> Size[] getOutputSizes(Class<T> klass) {if (isOutputSupportedFor(klass) == false) {return null;}return getInternalFormatSizes(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,HAL_DATASPACE_UNKNOWN,/*output*/true, /*highRes*/false); } private Size[] getInternalFormatSizes(int format, int dataspace,boolean output, boolean highRes) {// All depth formats are non-high-res.if (dataspace == HAL_DATASPACE_DEPTH && highRes) {return new Size[0];}SparseIntArray formatsMap =!output ? mInputFormats :dataspace == HAL_DATASPACE_DEPTH ? mDepthOutputFormats :highRes ? mHighResOutputFormats :mOutputFormats;int sizesCount = formatsMap.get(format);if ( ((!output || dataspace == HAL_DATASPACE_DEPTH) && sizesCount == 0) ||(output && dataspace != HAL_DATASPACE_DEPTH && mAllOutputFormats.get(format) == 0)) {// Only throw if this is really not supported at allthrow new IllegalArgumentException("format not available");}Size[] sizes = new Size[sizesCount];int sizeIndex = 0;StreamConfiguration[] configurations =(dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations;StreamConfigurationDuration[] minFrameDurations =(dataspace == HAL_DATASPACE_DEPTH) ? mDepthMinFrameDurations : mMinFrameDurations;for (StreamConfiguration config : configurations) {int fmt = config.getFormat();if (fmt == format && config.isOutput() == output) {if (output && mListHighResolution) {// Filter slow high-res output formats; include for// highRes, remove for !highReslong duration = 0;for (int i = 0; i < minFrameDurations.length; i++) {StreamConfigurationDuration d = minFrameDurations[i];if (d.getFormat() == fmt &&d.getWidth() == config.getSize().getWidth() &&d.getHeight() == config.getSize().getHeight()) {duration = d.getDuration();break;}}if (dataspace != HAL_DATASPACE_DEPTH &&highRes != (duration > DURATION_20FPS_NS)) {continue;}}sizes[sizeIndex++] = config.getSize();}}if (sizeIndex != sizesCount) {throw new AssertionError("Too few sizes (expected " + sizesCount + ", actual " + sizeIndex + ")");}return sizes; }從上面代碼我們不難看出SurfaceHolder.class類型的size來源于mConfigurations和mMinFrameDurations之間,這個size存在于mConfigurations,format為HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED(值為34),類型為output,然后它的最小幀率要大于20FPS(DURATION_20FPS_NS)。
public static final Key<android.hardware.camera2.params.StreamConfiguration[]> SCALER_AVAILABLE_STREAM_CONFIGURATIONS =new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.scaler.availableStreamConfigurations", android.hardware.camera2.params.StreamConfiguration[].class); public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> SCALER_AVAILABLE_MIN_FRAME_DURATIONS =new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.scaler.availableMinFrameDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);根據前面的分析,StreamConfigurationMap中的mConfigurations和mMinFrameDurations分別來源于Key SCALER_AVAILABLE_STREAM_CONFIGURATIONS和SCALER_AVAILABLE_MIN_FRAME_DURATIONS, dump出CameraService中的characteristics,我們可以得到此兩個Key中的值,下面只列舉format為34的部分值:
android.scaler.availableStreamConfigurations (d000a): int32[476]......[34 4160 3120 OUTPUT ][34 4160 3120 INPUT ][34 4000 3000 OUTPUT ][34 4000 3000 INPUT ][34 3264 2448 OUTPUT ][34 3264 2448 INPUT ][34 3200 2400 OUTPUT ][34 3200 2400 INPUT ][34 2976 2976 OUTPUT ][34 2976 2976 INPUT ][34 2592 1944 OUTPUT ][34 2592 1944 INPUT ][34 2688 1512 OUTPUT ][34 2688 1512 INPUT ][34 2048 1536 OUTPUT ][34 1920 1080 OUTPUT ][34 2560 800 OUTPUT ][34 1600 1200 OUTPUT ]......android.scaler.availableMinFrameDurations (d000b): int64[420]......[34 4160 ][3120 66666666 ][34 4000 ][3000 66666666 ][34 3264 ][2448 41666666 ][34 3200 ][2400 41666666 ][34 2976 ][2976 41666666 ][34 2592 ][1944 33333333 ][34 2688 ][1512 33333333 ][34 2048 ][1536 33333333 ][34 1920 ][1080 33333333 ][34 2560 ][800 33333333 ][34 1600 ][1200 33333333 ][34 1440 ][1080 33333333 ][34 1280 ][960 33333333 ][34 1280 ]......從上面的值我們不難發現,如果camera sensor支持類型為output,format為34的size最大可到4160x3120,但大于20fps的卻只能最大到3264x2448。
四、結語
從Framework中的大于20FPS的限定,猜測原因可能是如果camera app獲取的YUV數據來源就FPS很低,app后期處理這些數據或做一些視頻合成的處理,畫面會卡頓,影響用戶體驗。
總結
以上是生活随笔為你收集整理的android.scaler.streamConfigurationMap Key值的来源的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaBean实例9:获取汉字的拼音简
- 下一篇: WIN二种安装方式UEFI和BIOS方式