我们使用TextureView显示相机预览数据,Camera2的预览和拍照数据都是使用CameraCaptureSession会话来请求的
private void startPreview() {
SurfaceTexture mSurfaceTexture = mTextureView.getSurfaceTexture();
mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
//通过view创建surface对象
Surface previewSurface = new Surface(mSurfaceTexture);
try {
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//绑定请求和surface
mCaptureRequestBuilder.addTarget(previewSurface);
//预览数据会同时输出到previewSurface和mImageReader
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new
CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
//创建请求
mCaptureRequest = mCaptureRequestBuilder.build();
//保存相机会话对象
mCameraCaptureSession = session;
//开始预览
mCameraCaptureSession.setRepeatingRequest(mCaptureRequest, null, mCameraHandler);
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, mCameraHandler);
}
}
alps/frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
public CaptureRequest.Builder createCaptureRequest(int templateType) {
synchronized(mInterfaceLock) {
CameraMetadataNative templatedRequest = null;
templatedRequest = mRemoteDevice.createDefaultRequest(templateType);//创建default metadata
// If app target SDK is older than O, or it's not a still capture template, enableZsl
// must be false in the default request.
if (mAppTargetSdkVersion < Build.VERSION_CODES.O ||
templateType != TEMPLATE_STILL_CAPTURE) {
overrideEnableZsl(templatedRequest, false);
}
CaptureRequest.Builder builder = new CaptureRequest.Builder(
templatedRequest, /*reprocess*/false, CameraCaptureSession.SESSION_ID_NONE,
getId(), /*physicalCameraIdSet*/ null);
return builder;
}
}
创建CameraMetadataNative对象,内在是创建CameraMetadata对象(CameraMetadata.cpp),对CameraMetadataNative对象的操作本质上都是操作CameraMetadata对象,即camera_metadata_t * mBuffer。至此我们就创建了CameraMetadata对象,其管理着一块buffer,buffer中保存的是某个场景预览、录像或拍照的默认metadata。
-----------------------------------------------------------------------------------------------------------------------------------
Builder的实现
public Builder(CameraMetadataNative template, boolean reprocess,
int reprocessableSessionId, String logicalCameraId,
Set
mRequest = new CaptureRequest(template, reprocess, reprocessableSessionId,
logicalCameraId, physicalCameraIdSet);
}
private CaptureRequest(CameraMetadataNative settings, boolean isReprocess,
int reprocessableSessionId, String logicalCameraId, Set
mLogicalCameraId = logicalCameraId;
mLogicalCameraSettings = CameraMetadataNative.move(settings);//保存camera_metadata_t
mPhysicalCameraSettings.put(mLogicalCameraId, mLogicalCameraSettings);
setNativeInstance(mLogicalCameraSettings);//保存mLogicalCameraSettings
mIsReprocess = isReprocess;
if (isReprocess) {
if (reprocessableSessionId == CameraCaptureSession.SESSION_ID_NONE) {
throw new IllegalArgumentException("Create a reprocess capture request with an " +
"invalid session ID: " + reprocessableSessionId);
}
mReprocessableSessionId = reprocessableSessionId;
} else {
mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE;
}
}
-----------------------------------------------------------------------------------------------------------------------------------
alps/frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
typedef CameraMetadata CameraMetadataNative;
binder::Status CameraDeviceClient::createDefaultRequest(int templateId,
/*out*/
hardware::camera2::impl::CameraMetadataNative* request)
{
CameraMetadata metadata;
status_t err;
if ( (err = mDevice->createDefaultRequest(templateId, &metadata) ) == OK &&
request != NULL) {
request->swap(metadata);//保存CameraMetadata对象的camera_metadata_t变量
}
return res;
}
-----------------------------------------------------------------------------------------------------------------------------------
swap的实现
void CameraMetadata::swap(CameraMetadata& other) {
camera_metadata* thisBuf = mBuffer;
camera_metadata* otherBuf = other.mBuffer;
other.mBuffer = thisBuf;
mBuffer = otherBuf;
}
-----------------------------------------------------------------------------------------------------------------------------------
alps/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
status_t Camera3Device::createDefaultRequest(int templateId,
CameraMetadata *request) {
{
Mutex::Autolock l(mLock);
switch (mStatus) {
case STATUS_ERROR:
CLOGE("Device has encountered a serious error");
return INVALID_OPERATION;
case STATUS_UNINITIALIZED:
CLOGE("Device is not initialized!");
return INVALID_OPERATION;
case STATUS_UNCONFIGURED:
case STATUS_CONFIGURED:
case STATUS_ACTIVE:
// OK
break;
}
if (!mRequestTemplateCache[templateId].isEmpty()) {
*request = mRequestTemplateCache[templateId];
mLastTemplateId = templateId;
return OK;
}
}
camera_metadata_t *rawRequest;
status_t res = mInterface->constructDefaultRequestSettings(
(camera3_request_template_t) templateId, &rawRequest);
{
set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
mRequestTemplateCache[templateId].acquire(rawRequest);//保存camera_metadata_t
*request = mRequestTemplateCache[templateId];
mLastTemplateId = templateId;
}
return OK;
}
-----------------------------------------------------------------------------------------------------------------------------------
acquire的实现
CameraMetadata mRequestTemplateCache[CAMERA3_TEMPLATE_COUNT];
CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
mLocked(false)
{
mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
}
void CameraMetadata::acquire(camera_metadata_t *buffer) {
clear();
mBuffer = buffer;
}
-----------------------------------------------------------------------------------------------------------------------------------
status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
camera3_request_template_t templateId,
/*out*/ camera_metadata_t **requestTemplate) {
//定义回调函数,其中返回值为status和requestTemplate
auto requestCallback = [&status, &requestTemplate]
(common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
status = s;
if (status == common::V1_0::Status::OK) {
const camera_metadata *r =
reinterpret_cast
size_t expectedSize = request.size();
int ret = validate_camera_metadata_structure(r, &expectedSize);
if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
*requestTemplate = clone_camera_metadata(r);//拷贝返回值的内容
}
}
};
hardware::Return
RequestTemplate id;
switch (templateId) {
case CAMERA3_TEMPLATE_PREVIEW:
id = RequestTemplate::PREVIEW;
break;
case CAMERA3_TEMPLATE_STILL_CAPTURE:
id = RequestTemplate::STILL_CAPTURE;
break;
case CAMERA3_TEMPLATE_VIDEO_RECORD:
id = RequestTemplate::VIDEO_RECORD;
break;
case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
id = RequestTemplate::VIDEO_SNAPSHOT;
break;
case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
id = RequestTemplate::ZERO_SHUTTER_LAG;
break;
case CAMERA3_TEMPLATE_MANUAL:
id = RequestTemplate::MANUAL;
break;
default:
// Unknown template ID, or this HAL is too old to support it
return BAD_VALUE;
}
err = mHidlSession->constructDefaultRequestSettings(id, requestCallback);//通过回调函数返回requestTemplate
return res;
}
alps/vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/device/3.x/device/CameraDevice3SessionImpl.cpp
ThisNamespace::
constructDefaultRequestSettings(RequestTemplate type, constructDefaultRequestSettings_cb _hidl_cb){
ITemplateRequest* obj = NSTemplateRequestManager::valueFor(getInstanceId());
if (obj == nullptr) {
obj = ITemplateRequest::getInstance(getInstanceId());
NSTemplateRequestManager::add(getInstanceId(), obj);
}
CameraMetadata metadata;
{
camera_metadata const* p_camera_metadata = obj->getData(static_cast
size_t size = mStaticInfo.mMetadataConverter->getCameraMetadataSize(p_camera_metadata);
metadata.setToExternal((uint8_t *)p_camera_metadata, size, false/*shouldOwn*/);//转换格式
}
_hidl_cb(Status::OK, metadata);//返回metadata
return Void();
}
alps/vendor/mediatek/proprietary/hardware/mtkcam/utils/metastore/templateRequest/TemplateRequest.cpp
ITemplateRequest*
ITemplateRequest::
getInstance(int iOpenId){
TemplateRequest* p = new TemplateRequest();
if(p != NULL) {
p->onCreate(iOpenId);
}
return p;
}
TemplateRequest::
onCreate(int iOpenId){
auto pHalDeviceList = MAKE_HalLogicalDeviceList();
IHalSensorList* pHalSensorList = MAKE_HalSensorList();
// get main sensor from logical device list.
auto sensorIdList = pHalDeviceList->getSensorId(iOpenId);
// check 4cell type
MUINT32 sensorDev = (MUINT32)pHalSensorList->querySensorDevIdx(sensorIdList[0]);
NSCam::SensorStaticInfo sensorStaticInfo;
pHalSensorList->querySensorStaticInfo(sensorDev, &sensorStaticInfo);
uint32_t u4RawFmtType = sensorStaticInfo.rawFmtType;
bool is4CellSensor = (( u4RawFmtType == SENSOR_RAW_4CELL ||
u4RawFmtType == SENSOR_RAW_4CELL_BAYER ||
u4RawFmtType == SENSOR_RAW_4CELL_HW_BAYER) ? true : false);
int32_t sensorType = pHalSensorList->queryType(sensorIdList[0]);
const char* sensorDrvName = pHalDeviceList->queryDriverName(iOpenId);
mInfo = Info(iOpenId, sensorType, sensorDrvName, is4CellSensor);
// Standard template types
for (int type = CAMERA3_TEMPLATE_PREVIEW; type < CAMERA3_TEMPLATE_COUNT; type++)
{
camera_metadata* metadata = NULL;
IMetadata mtkMetadata;
status_t status = constructRequestMetadata(type, metadata, mtkMetadata);
mMapRequestTemplate.add(type, metadata);
mMapRequestTemplateMetadata.add(type, mtkMetadata);
}
return OK;
}
TemplateRequest::
constructRequestMetadata(
int const requestType,
camera_metadata*& rpMetadata,
IMetadata& rMtkMetadata
){
//-----(1)-----//
//get static informtation from customization (with camera_metadata format)
//calculate its entry count and data count
if ( OK != (status = impConstructRequestMetadata(rMtkMetadata, requestType)) ) {
MY_LOGE("Unable evaluate the size for camera static info - status[%s(%d)]\n", ::strerror(-status), -status);
return status;
}
//calculate its entry count and data count
// init converter
IMetadataTagSet tagInfo;
setTagInfo(tagInfo);
sp
size_t entryCount = 0;
size_t dataCount = 0;
MBOOL ret = pConverter->get_data_count(rMtkMetadata, entryCount, dataCount);
//-----(2)-----//
// overwrite
updateData(rMtkMetadata);
//-----(3)-----//
// convert to android metadata
pConverter->convert(rMtkMetadata, rpMetadata);
::sort_camera_metadata(rpMetadata);
return status;
}