Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互 联系客服

发布时间 : 星期三 文章Android Camera API2中采用CameraMetadata用于从APP到HAL的参数交互更新完毕开始阅读cd02a0ac27d3240c8547ef44

d .add_camera_metadata_entry完成全新的entry更新与写入,即这个TAG目前不存在于这个camera_metadata_t中;update_camera_metadata_entry则是直接完成数据的更新。

[cpp] view plaincopy

1. mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, 2. CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 3. mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, 4. CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); 5. session.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);

4. Java层中CameraMetadata.java和CameraMetadataNative.java 下面以API2中java层中设置AF的工作模式为例,来说明这个参数设置的过程:

[java] view plaincopy

1. mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, 2. CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 3. mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, 4. CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); 5. session.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);

其中CONTROL_AF_MODE定义在CaptureRequest,java中如下以一个Key的形式存在:

[cpp] view plaincopy

1. public static final Key CONTROL_AF_MODE = 2. new Key(\, int.class); [java] view plaincopy

1. public Key(String name, Class type) { 2. mKey = new CameraMetadataNative.Key(name, type); 3. } 在CameraMetadataNative.java中Key的构造 [java] view plaincopy

1. public Key(String name, Class type) { 2. if (name == null) { 3. throw new NullPointerException(\alid name\); 4. } else if (type == null) { 5. throw new NullPointerException(\ be non-null\); 6. } 7. mName = name; 8. mType = type; 9. mTypeReference = TypeReference.createSpecializedTypeReference(type); 10. mHash = mName.hashCode() ^ mTypeReference.hashCode(); 11. }

其中CONTROL_AF_MODE_CONTINUOUS_PICTURE定义在CameraMetadata.java中 [cpp] view plaincopy

1. public static final int CONTROL_AF_MODE_CONTINUOUS_PICTURE = 4; 逐一定位set的入口:

a. mPreviewBuilder是CaptureRequest.java的build类,其会构建一个CaptureRequest

[cpp] view plaincopy

1. public Builder(CameraMetadataNative template) { 2. mRequest = new CaptureRequest(template); 3. } [java] view plaincopy

1. private CaptureRequest() { 2. mSettings = new CameraMetadataNative(); 3. mSurfaceSet = new HashSet(); 4. } mSetting建立的是一个CameraMetadataNative对象,主要用于和Native层进行接口交互,构造如下

[java] view plaincopy

1. public CameraMetadataNative() { 2. super(); 3. mMetadataPtr = nativeAllocate(); 4. if (mMetadataPtr == 0) { 5. throw new OutOfMemoryError(\e CameraMetadata\); 6. } 7. }

b. CaptureRequest.Build.set() [cpp] view plaincopy

1. public void set(Key key, T value) { 2. mRequest.mSettings.set(key, value); 3. } [java] view plaincopy

1. public void set(CaptureRequest.Key key, T value) { 2. set(key.getNativeKey(), value); 3. } 考虑到CaptureRequest extend CameraMetadata,则CaptureRequest.java中getNativeKey

[java] view plaincopy

1. public CameraMetadataNative.Key getNativeKey() { 2. return mKey; 3. } mKey即为之前构造的CameraMetadataNative.Key. [java] view plaincopy

1. public void set(Key key, T value) { 2. SetCommand s = sSetCommandMap.get(key); 3. if (s != null) { 4. s.setValue(this, value); 5. return; 6. } 7. setBase(key, value); 8. } [java] view plaincopy

1. private void setBase(Key key, T value) { 2. int tag = key.getTag(); 3. 4. if (value == null) { 5. // Erase the entry 6. writeValues(tag, /*src*/null); 7. return; 8. } // else update the entry to a new value 9. 10. Marshaler marshaler = getMarshalerForKey(key); 11. int size = marshaler.calculateMarshalSize(value); 12. 13. // TODO: Optimization. Cache the byte[] and reuse if the size is big enough. 14. byte[] values = new byte[size]; 15. 16. ByteBuffer buffer = ByteBuffer.wrap(values).order(ByteOrder.nativeOrder()); 17. marshaler.marshal(value, buffer); 18. 19. writeValues(tag, values); 20. } 首先来看key.getTag()函数的实现,他是将这个key交由Native层后转为一个真正的在Java层中的tag值: [java] view plaincopy

1. public final int getTag() { 2. if (!mHasTag) { 3. mTag = CameraMetadataNative.getTag(mName); 4. mHasTag = true; 5. } 6. return mTag; 7. } [java] view plaincopy