blob: 92684b6a7da46cdbdb0d57994417bce36d779ff8 [file] [log] [blame]
/*
* Copyright (C) 2017, Samsung Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* #define LOG_NDEBUG 0 */
#define LOG_TAG "ExynosCameraRequestManagerSec"
#include "ExynosCameraRequestManager.h"
namespace android {
ExynosCameraRequestSP_sprt_t ExynosCameraRequestManager::registerToServiceList(camera3_capture_request_t *srcRequest)
{
status_t ret = NO_ERROR;
ExynosCameraRequestSP_sprt_t request = NULL;
CameraMetadata *meta;
uint32_t bufferCnt = 0;
camera3_stream_buffer_t *inputbuffer = NULL;
const camera3_stream_buffer_t *outputbuffer = NULL;
ExynosCameraStream *stream = NULL;
ExynosCameraFrameFactory *factory = NULL;
int32_t streamID = 0;
int32_t factoryID = 0;
int reqId;
bool isZslInput = false;
struct camera2_shot_ext *shot_ext = NULL;
int previewPortId = MCSC_PORT_NONE;
int yuvPortId = MCSC_PORT_NONE;
int tempPortId = MCSC_PORT_NONE;
int jpegPortId = MCSC_PORT_NONE;
int yuvStallPortId = MCSC_PORT_NONE;
/* Check whether the input buffer (ZSL input) is specified.
Use zslFramFactory in the following section if ZSL input is used
*/
request = new ExynosCameraRequest(srcRequest, m_previousMeta);
bufferCnt = request->getNumOfInputBuffer();
inputbuffer = request->getInputBuffer();
for(uint32_t i = 0 ; i < bufferCnt ; i++) {
stream = static_cast<ExynosCameraStream*>(inputbuffer[i].stream->priv);
stream->getID(&streamID);
factoryID = streamID % HAL_STREAM_ID_MAX;
/* Stream ID validity */
if(factoryID == HAL_STREAM_ID_ZSL_INPUT) {
isZslInput = true;
} else {
/* Ignore input buffer */
CLOGE("Invalid input streamID. streamID(%d)", streamID);
}
}
bufferCnt = request->getNumOfOutputBuffer();
outputbuffer = request->getOutputBuffers();
for(uint32_t i = 0 ; i < bufferCnt ; i++) {
stream = static_cast<ExynosCameraStream*>(outputbuffer[i].stream->priv);
stream->getID(&streamID);
factoryID = streamID % HAL_STREAM_ID_MAX;
/* If current request has ZSL Input stream buffer,
* CALLBACK stream must be processed by reprocessing stream.
*/
if (isZslInput == true && factoryID == HAL_STREAM_ID_CALLBACK) {
CLOGV("[R%d]CALLBACK stream will be replaced with CALLBACK_STALL stream", request->getKey());
factoryID = HAL_STREAM_ID_CALLBACK_STALL;
}
ret = m_getFactory(factoryID, &factory, &m_factoryMap, &m_factoryMapLock);
if (ret < 0) {
CLOGD("[R%d]m_getFactory is failed. streamID(%d)",
request->getKey(), streamID);
}
switch(factoryID % HAL_STREAM_ID_MAX) {
case HAL_STREAM_ID_PREVIEW:
stream->getOutputPortId(&tempPortId);
if (previewPortId < 0) {
previewPortId = tempPortId;
} else {
previewPortId = (previewPortId > tempPortId) ? tempPortId : previewPortId;
}
break;
case HAL_STREAM_ID_VIDEO:
case HAL_STREAM_ID_CALLBACK:
stream->getOutputPortId(&tempPortId);
if (yuvPortId < 0) {
yuvPortId = tempPortId;
} else {
yuvPortId = (yuvPortId > tempPortId) ? tempPortId : yuvPortId;
}
break;
case HAL_STREAM_ID_CALLBACK_STALL:
stream->getOutputPortId(&tempPortId);
if (yuvStallPortId < 0) {
yuvStallPortId = tempPortId;
yuvStallPortId = yuvStallPortId + MCSC_PORT_MAX;
} else {
yuvStallPortId = yuvStallPortId - MCSC_PORT_MAX;
yuvStallPortId = (yuvStallPortId > tempPortId) ? tempPortId : yuvStallPortId;
yuvStallPortId = yuvStallPortId + MCSC_PORT_MAX;
}
break;
case HAL_STREAM_ID_JPEG:
jpegPortId = MCSC_PORT_3 + MCSC_PORT_MAX;
break;
}
request->pushFrameFactory(streamID, factory);
request->pushRequestOutputStreams(streamID);
}
m_converter->setPreviousMeta(&m_previousMeta);
meta = request->getServiceMeta();
if (meta->isEmpty()) {
CLOGD("meta is EMPTY");
} else {
CLOGV("meta is NOT EMPTY");
}
CLOGV("m_currReqeustList size(%zu), fn(%d)",
m_serviceRequests.size(), request->getFrameCount());
ret = m_converter->convertRequestToShot(request, &reqId);
request->setRequestId(reqId);
m_previousMeta = *meta;
shot_ext = request->getServiceShot();
if (shot_ext->shot.ctl.stats.faceDetectMode == FACEDETECT_MODE_OFF) {
request->setDsInputPortId(MCSC_PORT_NONE);
} else {
if (previewPortId >= 0) {
request->setDsInputPortId(previewPortId);
} else if (yuvPortId >= 0) {
request->setDsInputPortId(yuvPortId);
} else if (jpegPortId >= 0) {
request->setDsInputPortId(jpegPortId);
} else {
request->setDsInputPortId(yuvStallPortId);
}
}
if (m_parameters->getRestartStream() == false) {
ret = m_pushBack(request, &m_serviceRequests, &m_requestLock);
if (ret < 0){
CLOGE("request m_pushBack is failed request(%d)", request->getFrameCount());
request = NULL;
return NULL;
}
} else {
CLOGD("restartStream flag checked, request[R%d]", request->getKey());
}
if (m_getFlushFlag() == false && m_resultCallbackThread->isRunning() == false) {
m_resultCallbackThread->run();
}
return request;
}
void ExynosCameraRequest::m_updateMetaDataU8(uint32_t tag, CameraMetadata &resultMeta)
{
camera_metadata_entry_t entry;
entry = m_serviceMeta.find(tag);
if (entry.count > 0) {
resultMeta.update(tag, entry.data.u8, entry.count);
for (size_t i = 0; i < entry.count; i++) {
CLOGV2("%s[%zu/%zu] is (%d)", get_camera_metadata_tag_name(tag), i, entry.count, entry.data.u8[i]);
}
}
}
void ExynosCameraRequest::m_updateMetaDataI32(uint32_t tag, CameraMetadata &resultMeta)
{
camera_metadata_entry_t entry;
entry = m_serviceMeta.find(tag);
if (entry.count > 0) {
resultMeta.update(tag, entry.data.i32, entry.count);
for (size_t i = 0; i < entry.count; i++) {
CLOGV2("%s[%zu/%zu] is (%d)", get_camera_metadata_tag_name(tag), i, entry.count, entry.data.i32[i]);
}
}
}
void ExynosCameraRequest::get3AAResultMetaVendor(CameraMetadata &minimal_resultMeta)
{
m_updateMetaDataU8(ANDROID_CONTROL_AE_MODE, minimal_resultMeta);
m_updateMetaDataU8(ANDROID_CONTROL_AF_TRIGGER, minimal_resultMeta);
m_updateMetaDataI32(ANDROID_CONTROL_AF_REGIONS, minimal_resultMeta);
m_updateMetaDataI32(ANDROID_CONTROL_AE_REGIONS, minimal_resultMeta);
m_updateMetaDataI32(ANDROID_CONTROL_AWB_REGIONS, minimal_resultMeta);
#ifdef SAMSUNG_CONTROL_METERING
m_updateMetaDataI32(SAMSUNG_ANDROID_CONTROL_TOUCH_AE_STATE, minimal_resultMeta);
#endif
#ifdef SAMSUNG_TN_FEATURE
m_updateMetaDataI32(SAMSUNG_ANDROID_LENS_INFO_CURRENTINFO, minimal_resultMeta);
m_updateMetaDataI32(SAMSUNG_ANDROID_CONTROL_DOF_SINGLE_DATA, minimal_resultMeta);
m_updateMetaDataI32(SAMSUNG_ANDROID_CONTROL_DOF_MULTI_INFO, minimal_resultMeta);
m_updateMetaDataI32(SAMSUNG_ANDROID_CONTROL_DOF_MULTI_DATA, minimal_resultMeta);
#endif
#ifdef SAMSUNG_OT
m_updateMetaDataI32(SAMSUNG_ANDROID_CONTROL_OBJECT_TRACKING_STATE, minimal_resultMeta);
#endif
return;
}
}; /* namespace android */