blob: e4f4f4e1476f7f9d64c41c31a824985610004cea [file] [log] [blame]
/*
* Copyright@ 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_TAG "ExynosCameraDualFrameSelector"
#include "ExynosCameraDualFrameSelector.h"
/* #define DUAL_DEBUG */
#define DUAL_SELECTOR_CALIB_TIME (2) // 2msec
/*
* ID : SyncId, S.State : Select State
* H.F : HAL FrameCount, D.F : Driver FrameCount, T : Timestamp, D.T : Diff Time
*/
#define ONE_SYNC_OBJ_ID "[CAM%d/HF%d/MF%d/T:%d/ID:%d/S.State:%d]"
#define TWO_SYNC_OBJ_ID "[D.T:%dms][CAM%d/H.F%d/M.F%d/T:%d/ID:%d/S.State:%d vs CAM%d/H.F%d/M.F%d/T:%d/ID:%d/S.State:%d]"
#define ONE_SYNC_OBJ_ARGS(syncObj) \
(syncObj)->getCameraId(), \
((syncObj)->getFrame() != NULL) ? (syncObj)->getFrame()->getFrameCount() : -1, \
((syncObj)->getFrame() != NULL) ? (syncObj)->getFrame()->getMetaFrameCount() : -1, \
(syncObj)->getTimeStamp(), \
(syncObj)->getSyncId(), \
(syncObj)->getSelectState()
#define SYNC_OBJ_DIFF_TIME_ARGS(syncObj, otherObj) \
(abs((syncObj)->getTimeStamp() - (otherObj)->getTimeStamp()))
#define TWO_SYNC_OBJ_ARGS(syncObj, otherObj) \
SYNC_OBJ_DIFF_TIME_ARGS(syncObj, otherObj), \
ONE_SYNC_OBJ_ARGS(syncObj), ONE_SYNC_OBJ_ARGS(otherObj)
/* define for dual selecot's log */
#ifdef DUAL_DEBUG
#define DUAL_LOGV(cameraId, fmt, ...) \
ALOGD(Paste2(CAM_ID"VERB" LOCATION_ID, fmt), cameraId, m_name, LOCATION_ID_PARM, ##__VA_ARGS__)
#else
#define DUAL_LOGV(cameraId, fmt, ...) \
ALOGV(Paste2(CAM_ID"VERB" LOCATION_ID, fmt), cameraId, m_name, LOCATION_ID_PARM, ##__VA_ARGS__)
#endif
#define DUAL_LOGD(cameraId, fmt, ...) \
ALOGD(Paste2(CAM_ID"DEBUG" LOCATION_ID, fmt), cameraId, m_name, LOCATION_ID_PARM, ##__VA_ARGS__)
#define DUAL_LOGW(cameraId, fmt, ...) \
ALOGW(Paste2(CAM_ID"WARN" LOCATION_ID, fmt), cameraId, m_name, LOCATION_ID_PARM, ##__VA_ARGS__)
#define DUAL_LOGE(cameraId, fmt, ...) \
ALOGE(Paste2(CAM_ID"ERR" LOCATION_ID, fmt), cameraId, m_name, LOCATION_ID_PARM, ##__VA_ARGS__)
#define DUAL_LOGI(cameraId, fmt, ...) \
ALOGI(Paste2(CAM_ID"INFO" LOCATION_ID, fmt), cameraId, m_name, LOCATION_ID_PARM, ##__VA_ARGS__)
#define DUAL_ASSERT(cameraId, fmt, ...) \
android_printAssert(NULL, LOG_TAG, Paste2(CAM_ID, fmt), cameraId, m_name, ##__VA_ARGS__)
/* for one syncObj */
#define ONE_SYNC_OBJ_LOGV(cameraId, syncObj, fmt, ...) \
DUAL_LOGV(cameraId, ONE_SYNC_OBJ_ID fmt, ONE_SYNC_OBJ_ARGS(syncObj), ##__VA_ARGS__)
#define ONE_SYNC_OBJ_LOGD(cameraId, syncObj, fmt, ...) \
DUAL_LOGD(cameraId, ONE_SYNC_OBJ_ID fmt, ONE_SYNC_OBJ_ARGS(syncObj), ##__VA_ARGS__)
#define ONE_SYNC_OBJ_LOGW(cameraId, syncObj, fmt, ...) \
DUAL_LOGW(cameraId, ONE_SYNC_OBJ_ID fmt, ONE_SYNC_OBJ_ARGS(syncObj), ##__VA_ARGS__)
#define ONE_SYNC_OBJ_LOGE(cameraId, syncObj, fmt, ...) \
DUAL_LOGE(cameraId, ONE_SYNC_OBJ_ID fmt, ONE_SYNC_OBJ_ARGS(syncObj), ##__VA_ARGS__)
/* for two syncObjs */
#define TWO_SYNC_OBJ_LOGV(cameraId, syncObj, otherObj, fmt, ...) \
DUAL_LOGV(cameraId, TWO_SYNC_OBJ_ID fmt, TWO_SYNC_OBJ_ARGS(syncObj, otherObj), ##__VA_ARGS__)
#define TWO_SYNC_OBJ_LOGD(cameraId, syncObj, otherObj, fmt, ...) \
DUAL_LOGD(cameraId, TWO_SYNC_OBJ_ID fmt, TWO_SYNC_OBJ_ARGS(syncObj, otherObj), ##__VA_ARGS__)
#define TWO_SYNC_OBJ_LOGW(cameraId, syncObj, otherObj, fmt, ...) \
DUAL_LOGW(cameraId, TWO_SYNC_OBJ_ID fmt, TWO_SYNC_OBJ_ARGS(syncObj, otherObj), ##__VA_ARGS__)
#define TWO_SYNC_OBJ_LOGE(cameraId, syncObj, otherObj, fmt, ...) \
DUAL_LOGE(cameraId, TWO_SYNC_OBJ_ID fmt, TWO_SYNC_OBJ_ARGS(syncObj, otherObj), ##__VA_ARGS__)
/*
* Class SyncObj
*/
ExynosCameraDualFrameSelector::SyncObj::SyncObj()
{
m_cameraId = -1;
m_frame = NULL;
m_pipeId = -1;
m_isSrc = false;
m_nodeIndex = -1;
m_timeStamp = 0;
m_selectState = SELECT_STATE_BASE;
memset(m_name, 0x00, sizeof(m_name));
m_syncId = -1;
}
ExynosCameraDualFrameSelector::SyncObj::~SyncObj()
{}
status_t ExynosCameraDualFrameSelector::SyncObj::create(int cameraId,
ExynosCameraFrameSP_sptr_t frame,
int pipeId,
bool isSrc,
int nodeIndex,
const char *name)
{
status_t ret = NO_ERROR;
m_cameraId = cameraId;
m_frame = frame;
m_pipeId = pipeId;
m_isSrc = isSrc;
m_nodeIndex = nodeIndex;
m_timeStamp = (int)(ns2ms(m_frame->getTimeStamp()));
m_selectState = SELECT_STATE_NO_SELECTED;
#ifdef DUAL_DEBUG
strncpy(m_name, name, EXYNOS_CAMERA_NAME_STR_SIZE - 1);
#endif
ONE_SYNC_OBJ_LOGV(m_cameraId, this, " pipe:%d, src:%d, nodeIndex:%d",
m_pipeId, m_isSrc, m_nodeIndex);
return ret;
}
status_t ExynosCameraDualFrameSelector::SyncObj::destroy(void)
{
m_frame = NULL;
ONE_SYNC_OBJ_LOGV(m_cameraId, this, "");
return NO_ERROR;
}
int ExynosCameraDualFrameSelector::SyncObj::getCameraId(void)
{
return m_cameraId;
}
ExynosCameraFrameSP_sptr_t ExynosCameraDualFrameSelector::SyncObj::getFrame(void)
{
return m_frame;
}
int ExynosCameraDualFrameSelector::SyncObj::getPipeId(void)
{
return m_pipeId;
}
bool ExynosCameraDualFrameSelector::SyncObj::getIsSrc(void)
{
return m_isSrc;
}
int ExynosCameraDualFrameSelector::SyncObj::getNodeIndex(void)
{
return m_nodeIndex;
}
int ExynosCameraDualFrameSelector::SyncObj::getTimeStamp(void)
{
return m_timeStamp;
}
int ExynosCameraDualFrameSelector::SyncObj::getSyncId(void)
{
return m_syncId;
}
void ExynosCameraDualFrameSelector::SyncObj::setSyncId(int syncId)
{
m_syncId = syncId;
}
status_t ExynosCameraDualFrameSelector::SyncObj::getBufferFromFrame(ExynosCameraBuffer *buffer)
{
status_t ret = NO_ERROR;
ExynosCameraBuffer selectedBuffer;
if (m_frame == NULL) {
ONE_SYNC_OBJ_LOGE(m_cameraId, this, "m_frame == NULL");
return BAD_VALUE;
}
if (buffer == NULL) {
ONE_SYNC_OBJ_LOGE(m_cameraId, this, "outBuffer == NULL");
return BAD_VALUE;
}
if (m_isSrc) {
ret = m_frame->getSrcBuffer(m_pipeId, &selectedBuffer);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(m_cameraId, this, "getSrcBuffer(pipeId %d) fail", m_pipeId);
} else {
if (m_nodeIndex < 0) {
ret = m_frame->getDstBuffer(m_pipeId, &selectedBuffer);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(m_cameraId, this, "getDstBuffer(pipeId %d) fail", m_pipeId);
} else {
ret = m_frame->getDstBuffer(m_pipeId, &selectedBuffer, m_nodeIndex);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(m_cameraId, this, "getDstBuffer(pipeId %d, dstPos %d) fail", m_pipeId, m_nodeIndex);
}
}
*buffer = selectedBuffer;
return ret;
}
bool ExynosCameraDualFrameSelector::SyncObj::isSimilarTimeStamp(SyncObj *other)
{
bool ret = false;
int diffTime = abs(other->getTimeStamp() - this->getTimeStamp());
/*
* This is close other than calib time.
* The diffTime(myself and other's timestamp) have not to be
* over than calib time.
* ex. If calib time is 16ms,
* (sysnObj's time - 16msec) <= (other's time) <= (sysnObj's time + 16msec)
* => consider sync
*/
if ((other->getTimeStamp() != 0) &&
(this->getTimeStamp() != 0) &&
(diffTime <= DUAL_SELECTOR_CALIB_TIME))
ret = true;
TWO_SYNC_OBJ_LOGV(m_cameraId, this, other, " %s", ret ? "matched" : "not matched");
return ret;
}
ExynosCameraDualFrameSelector::SyncObj::select_state_t ExynosCameraDualFrameSelector::SyncObj::getSelectState(void)
{
return m_selectState;
}
void ExynosCameraDualFrameSelector::SyncObj::setSelectState(ExynosCameraDualFrameSelector::SyncObj::select_state_t selectState)
{
m_selectState = selectState;
}
/*
* Class Message
*/
ExynosCameraDualFrameSelector::Message::Message()
{
m_cameraId = -1;
m_timeStamp = -1;
m_zoom = -1;
m_syncType = SYNC_TYPE_BASE;
m_frameType = FRAME_TYPE_INTERNAL;
}
ExynosCameraDualFrameSelector::Message::~Message()
{}
int ExynosCameraDualFrameSelector::Message::getCameraId(void)
{
return m_cameraId;
}
int ExynosCameraDualFrameSelector::Message::getTimeStamp(void)
{
return m_timeStamp;
}
int ExynosCameraDualFrameSelector::Message::getZoom(void)
{
return m_zoom;
}
sync_type_t ExynosCameraDualFrameSelector::Message::getSyncType(void)
{
return m_syncType;
}
uint32_t ExynosCameraDualFrameSelector::Message::getFrameType(void)
{
return m_frameType;
}
void ExynosCameraDualFrameSelector::Message::setCameraId(int cameraId)
{
m_cameraId = cameraId;
}
void ExynosCameraDualFrameSelector::Message::setZoom(int zoom)
{
m_zoom = zoom;
}
void ExynosCameraDualFrameSelector::Message::setTimeStamp(int timeStamp)
{
m_timeStamp = timeStamp;
}
void ExynosCameraDualFrameSelector::Message::setSyncType(sync_type_t syncType)
{
m_syncType = syncType;
}
void ExynosCameraDualFrameSelector::Message::setFrameType(uint32_t frameType)
{
m_frameType = frameType;
}
/*
* Class ExynosCameraDualSelector
*/
ExynosCameraDualFrameSelector::ExynosCameraDualFrameSelector()
{
init();
}
ExynosCameraDualFrameSelector::~ExynosCameraDualFrameSelector()
{}
status_t ExynosCameraDualFrameSelector::init(void)
{
status_t ret = NO_ERROR;
DUAL_LOGD(-1, "");
Mutex::Autolock lock(m_lock);
m_syncId = 0;
m_holdCount = 1;
m_prepareHoldCount = 0;
m_msgIndex = 0;
m_validCameraCnt = 0;
for (int i = 0; i < CAMERA_ID_MAX; i++) {
m_flagValidCameraId[i] = false;
m_bufMgr[i] = NULL;
m_param[i] = NULL;
m_flagNotifyRegister[i] = false;
m_flagRemoveFrameRegister[i] = false;
}
return ret;
}
status_t ExynosCameraDualFrameSelector::deinit(int cameraId)
{
int cameraCnt = 0;
status_t ret = NO_ERROR;
DUAL_LOGD(cameraId, "");
Mutex::Autolock lock(m_lock);
if (m_flagValidCameraId[cameraId] == true &&
m_validCameraCnt > 0) {
m_validCameraCnt--;
m_flagValidCameraId[cameraId] = false;
m_bufMgr[cameraId] = NULL;
m_param[cameraId] = NULL;
m_flagNotifyRegister[cameraId] = false;
m_flagRemoveFrameRegister[cameraId] = false;
m_notifyQ[cameraId].release();
m_removeFrameQ[cameraId].release();
if (m_validCameraCnt == 0) {
m_syncId = 0;
m_holdCount = 1;
m_prepareHoldCount = 0;
m_msgIndex = 0;
}
} else {
DUAL_LOGI(cameraId, "already deinited(%d, %d)",
m_flagValidCameraId[cameraId], m_validCameraCnt);
}
return ret;
}
status_t ExynosCameraDualFrameSelector::setInfo(int cameraId,
ExynosCameraParameters *param,
ExynosCameraBufferManager *bufMgr)
{
status_t ret = NO_ERROR;
int validCameraCnt = 0;
Mutex::Autolock lock(m_lock);
DUAL_LOGD(cameraId, "param:%p, bufMgr:%p, validCamera(%d)", param, bufMgr, m_validCameraCnt);
if (CAMERA_ID_MAX <= cameraId) {
DUAL_LOGE(cameraId, "invalid cameraId");
return INVALID_OPERATION;
}
m_bufMgr[cameraId] = bufMgr;
m_param[cameraId] = param;
m_validCameraCnt++;
m_flagValidCameraId[cameraId] = true;
/* when over than 2, assert */
if (m_validCameraCnt > 2)
DUAL_ASSERT(cameraId, "two more than cameras was set(%d)", validCameraCnt);
return ret;
}
status_t ExynosCameraDualFrameSelector::manageNormalFrameHoldList(int cameraId,
ExynosCameraFrameSP_sptr_t frame,
int pipeId, bool isSrc, int32_t nodeIndex)
{
#ifdef DUAL_DEBUG
//ExynosCameraAutoTimer autoTimer(__func__);
#endif
status_t ret = NO_ERROR;
bool flagAllCameraSync = false;
int prepareHoldCount = 0;
if (CAMERA_ID_MAX <= cameraId) {
DUAL_LOGE(cameraId, "invalid cameraId");
return INVALID_OPERATION;
}
if (frame == NULL) {
DUAL_LOGE(cameraId, "frame == NULL");
return INVALID_OPERATION;
}
/* create SyncObj */
SyncObj syncObj;
SyncObj otherSyncObj;
ret = syncObj.create(cameraId, frame, pipeId, isSrc, nodeIndex, m_name);
if (ret != NO_ERROR) {
DUAL_LOGE(cameraId, "[%dms] syncObj.create fail", m_getTimeStamp(frame));
return INVALID_OPERATION;
}
DUAL_LOGV(cameraId, "list size[%d, %d]",
m_prepareSyncObjList[cameraId].size(),
m_syncObjList[cameraId].size());
/* when smaller than 2, single stream is can be assume not synced frame. */
int otherCameraId = m_findOppositeCameraId(cameraId);
/* backup state for reprocessing */
frame->setReprocessingFrameType((frame_type_t)frame->getFrameType());
frame->setReprocessingZoom(frame->getZoom());
frame->setReprocessingSyncType(frame->getSyncType());
/* to SyncObjList */
Mutex::Autolock lock(m_lock);
/* case of not opening other camera */
if (otherCameraId < 0) {
DUAL_LOGW(cameraId, "There's no opposite camera");
/* push the syncObj to prepareSyncObjList */
m_pushList(cameraId, &m_prepareSyncObjList[cameraId], &syncObj);
} else {
/* check the timestamp */
if (m_checkSyncObjOnList(cameraId, &m_prepareSyncObjList[otherCameraId], &syncObj, &otherSyncObj))
flagAllCameraSync = true;
if (flagAllCameraSync) {
/* set the syncID for synced frames */
syncObj.setSyncId(m_syncId);
otherSyncObj.setSyncId(m_syncId++);
/* push the syncObj to syncObjList */
m_pushList(cameraId, &m_syncObjList[cameraId], &syncObj);
m_pushList(cameraId, &m_syncObjList[otherCameraId], &otherSyncObj);
/* pop the syncObj until holdCount */
m_clearListUntilMinSize(cameraId, &m_syncObjList[cameraId], m_holdCount);
m_clearListUntilMinSize(cameraId, &m_syncObjList[otherCameraId], m_holdCount);
/* flush the prepareSyncList until new SyncObj's timestamp */
m_clearListUntilTimeStamp(cameraId, &m_prepareSyncObjList[cameraId], syncObj.getTimeStamp());
m_clearListUntilTimeStamp(cameraId, &m_prepareSyncObjList[otherCameraId], otherSyncObj.getTimeStamp());
/* notify */
Message *msg;
msg = &m_msg[m_msgIndex++ % MESSAGE_MAX];
msg->setCameraId(syncObj.getCameraId());
msg->setTimeStamp(syncObj.getTimeStamp());
msg->setZoom(frame->getZoom());
msg->setSyncType((syncObj.getFrame())->getSyncType());
msg->setFrameType((syncObj.getFrame())->getFrameType());
for (int i = 0; i < CAMERA_ID_MAX; i++) {
if (!m_flagNotifyRegister[i])
continue;
m_notifyQ[i].pushProcessQ(msg);
}
} else {
/* push the syncObj to prepareSyncObjList */
m_pushList(cameraId, &m_prepareSyncObjList[cameraId], &syncObj);
}
}
if (m_prepareHoldCount > 0) {
/* manual prepareHoldCount setting */
prepareHoldCount = m_prepareHoldCount;
} else {
/*
* Automatic prepareHoldCount setting
*
* ex. Total Buffer Count (A) : 8
* Actual SyncObjList Size (B) : 2
* Diff Count (C) : A - B = 6
* prepareSyncObjList hold count (D) : C / 2 = 3 (if C is 1, D is 1)
*
* => Only 3 frame was remained in prepareSyncObjList
* => At least, 3 buffer can be run in Pre-MCPipe.
*/
int totalBufferCount = m_bufMgr[cameraId]->getNumOfAllowedMaxBuffer();
int diffCount = totalBufferCount - m_syncObjList[cameraId].size();
prepareHoldCount = diffCount > 1 ? (diffCount / 2) : 0;
}
/* forcely maintain the prepareSyncList's size to half of holdCount */
m_clearListUntilMinSize(cameraId, &m_prepareSyncObjList[cameraId], prepareHoldCount);
ONE_SYNC_OBJ_LOGV(cameraId, &syncObj, "pushed frame(prepare:%d)", prepareHoldCount);
return ret;
}
ExynosCameraFrameSP_sptr_t ExynosCameraDualFrameSelector::selectFrame(int cameraId)
{
#ifdef DUAL_DEBUG
//ExynosCameraAutoTimer autoTimer(__func__);
#endif
status_t ret = NO_ERROR;
int otherCameraId = m_findOppositeCameraId(cameraId);
if (otherCameraId < 0) {
DUAL_LOGE(cameraId, "There's no opposite camera");
return NULL;
}
if (getSizeOfSyncList(cameraId) <= 0)
return NULL;
bool flagSelectMaster = false;
bool flagSelectSlave = false;
int output_node_index = OUTPUT_NODE_1;
/* for master */
bool isSrc;
int pipeId;
int nodeIndex;
SyncObj syncObj;
ExynosCameraFrameSP_sptr_t selectedFrame = NULL;
sync_type_t syncType;
uint32_t frameType;
/* for slave */
bool otherIsSrc;
int otherPipeId;
int otherNodeIndex;
SyncObj otherSyncObj;
ExynosCameraBuffer otherBuffer;
ExynosCameraFrameSP_sptr_t selectedOtherFrame = NULL;
sync_type_t otherSyncType;
uint32_t otherFrameType;
/* we must protect list of various camera. */
Mutex::Autolock lock(m_lock);
/* check the integrity of SyncObjList */
if (m_syncObjList[cameraId].size() != m_syncObjList[otherCameraId].size()) {
DUAL_ASSERT(cameraId, "invalid size matching : syncObj size:%d/%d",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size());
}
/* pop from sync obj */
if (m_popList(cameraId, &m_syncObjList[cameraId], &syncObj) != NO_ERROR) {
DUAL_ASSERT(cameraId, "Nothing in popList : syncObj size:%d/%d",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size());
}
/* pop from opposite camera's sync obj */
if (m_popList(cameraId, &m_syncObjList[otherCameraId], &otherSyncObj) != NO_ERROR) {
DUAL_ASSERT(cameraId, "Nothing in otherPopList : syncObj size:%d/%d",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size());
}
/* for master */
pipeId = syncObj.getPipeId();
nodeIndex = syncObj.getNodeIndex();
isSrc = syncObj.getIsSrc();
selectedFrame = syncObj.getFrame();
syncType = selectedFrame->getSyncType();
frameType = selectedFrame->getFrameType();
/* for slave */
otherPipeId = otherSyncObj.getPipeId();
otherNodeIndex = otherSyncObj.getNodeIndex();
otherIsSrc = otherSyncObj.getIsSrc();
selectedOtherFrame = otherSyncObj.getFrame();
otherSyncType = selectedOtherFrame->getSyncType();
otherFrameType = selectedOtherFrame->getFrameType();
/*
* frame | camera[syncType][frameType ] + camera[syncType][frameType ]
* ---------------------------------------------------------------------------------
* case 1) Master[Bypass ][Normal ] + Slave [- ][- ] => select master
* case 2) Master[- ][- ] + Slave [Switch ][Normal ] => select slave
* case 3) Master[Sync ][- ] + Slave [Sync ][- ] => select master + slave
* case 4) Master[Bypass ][Transition] + Slave [- ][- ] => select master
* case 5) Master[- ][- ] + Slave [Switch ][Transition ] => select slave
* other ) => drop
*
* but if selected frame have "Internal" frame type, drop the both frame
*/
if (syncType == SYNC_TYPE_BYPASS &&
(frameType != FRAME_TYPE_INTERNAL && frameType != FRAME_TYPE_TRANSITION)) {
/* case 1 */
flagSelectMaster = true;
flagSelectSlave = false;
} else if (otherSyncType == SYNC_TYPE_SWITCH &&
(otherFrameType != FRAME_TYPE_INTERNAL && otherFrameType != FRAME_TYPE_TRANSITION)) {
/* case 2 */
flagSelectMaster = false;
flagSelectSlave = true;
} else if (syncType == SYNC_TYPE_SYNC && otherSyncType == SYNC_TYPE_SYNC &&
(frameType != FRAME_TYPE_INTERNAL && otherFrameType != FRAME_TYPE_INTERNAL)) {
/* case 3 */
flagSelectMaster = true;
flagSelectSlave = true;
/* change the output node_index */
output_node_index = OUTPUT_NODE_2;
} else if (syncType == SYNC_TYPE_BYPASS &&
frameType == FRAME_TYPE_TRANSITION) {
/* case 4 */
flagSelectMaster = true;
flagSelectSlave = false;
} else if (otherSyncType == SYNC_TYPE_SWITCH &&
otherFrameType == FRAME_TYPE_TRANSITION) {
/* case 5 */
flagSelectMaster = false;
flagSelectSlave = true;
} else {
/* drop */
flagSelectMaster = false;
flagSelectSlave = false;
TWO_SYNC_OBJ_LOGE(cameraId, &syncObj, &otherSyncObj, "this frame will be dropped (M:%d/%d)/(S:%d/%d)",
syncType, frameType,
otherSyncType, otherFrameType);
selectedFrame->setFrameState(FRAME_STATE_SKIPPED);
}
TWO_SYNC_OBJ_LOGV(cameraId, &syncObj, &otherSyncObj, "selected(%d, %d) M(%d,%d)/S(%d,%d)",
flagSelectMaster, flagSelectSlave,
syncType, frameType,
otherSyncType, otherFrameType);
/* release the buffer before overwritng by slave buffer */
if (flagSelectMaster == false && flagSelectSlave == true) {
ret = m_destroySyncObj(&syncObj, true, false);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, &syncObj, "removed fail");
}
/* select the frame */
if ((flagSelectMaster == true && flagSelectSlave == true) ||
(flagSelectMaster == false && flagSelectSlave == true)) {
/*
* 1) master + slave (set the slave's info to master)
* 2) slave (overwrite the frame info)
*/
/* get the slave's Buffer and setting */
ret = otherSyncObj.getBufferFromFrame(&otherBuffer);
if (ret != NO_ERROR) {
ONE_SYNC_OBJ_LOGE(cameraId, &otherSyncObj, "get%sBuffer fail(%d, %d)",
otherIsSrc ? "Src" : "Dst", otherPipeId, otherNodeIndex);
} else {
ret = selectedFrame->setSrcBufferState(pipeId, ENTITY_BUFFER_STATE_REQUESTED, output_node_index);
if (ret < 0) {
DUAL_LOGE(cameraId, "setSrcBufferState(ENTITY_BUFFER_STATE_REQUESTED, %d) fail, pipeId(%d), ret(%d) frame(%d)",
output_node_index,
pipeId, ret, selectedFrame->getFrameCount());
}
ret = selectedFrame->setSrcBuffer(pipeId, otherBuffer, output_node_index);
if (ret < 0) {
DUAL_LOGE(cameraId, "setSrcBuffer(%d) fail, pipeId(%d), index(%d) frame(%d) ret(%d)",
output_node_index,
pipeId, otherBuffer.index, selectedFrame->getFrameCount(), ret);
}
}
/* Node Group Setting */
struct camera2_node_group node_group;
for (int i = 0; i < PERFRAME_NODE_GROUP_MAX; i++) {
selectedOtherFrame->getNodeGroupInfo(&node_group, i);
selectedFrame->storeNodeGroupInfo(&node_group, i, output_node_index);
}
/* Meta Setting */
struct camera2_shot_ext shot;
selectedOtherFrame->getMetaData(&shot);
selectedFrame->setMetaData(&shot, output_node_index);
/* Zoom Setting */
selectedFrame->setZoom(selectedOtherFrame->getZoom(), output_node_index);
/* SyncType Setting */
selectedFrame->setSyncType(selectedOtherFrame->getSyncType());
/* FrameType Setting */
selectedFrame->setFrameType((frame_type_t)selectedOtherFrame->getFrameType());
/* FrameState Setting */
switch (selectedFrame->getFrameState()) {
case FRAME_STATE_SKIPPED:
case FRAME_STATE_INVALID:
selectedFrame->setFrameState(FRAME_STATE_READY);
break;
default:
break;
}
} else {
/* 3) master (don't do anything) */
}
/* release the unnecessary buffer */
if (flagSelectMaster == false && flagSelectSlave == false) {
ret = m_destroySyncObj(&syncObj, true, false);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, &syncObj, "removed fail");
}
if (flagSelectSlave == false) {
ret = m_destroySyncObj(&otherSyncObj, true, false);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, &otherSyncObj, "removed fail");
}
return selectedFrame;
}
ExynosCameraFrameSP_sptr_t ExynosCameraDualFrameSelector::selectSingleFrame(int cameraId)
{
#ifdef DUAL_DEBUG
//ExynosCameraAutoTimer autoTimer(__func__);
#endif
status_t ret = NO_ERROR;
bool popAllSyncObj = false;
SyncObj tempSyncObj;
SyncObj tempOtherSyncObj;
SyncObj *syncObj = NULL;
SyncObj *otherSyncObj = NULL;
int otherCameraId = m_findOppositeCameraId(cameraId);
if (otherCameraId < 0) {
DUAL_LOGE(cameraId, "There's no opposite camera");
return NULL;
}
if (getSizeOfSyncList(cameraId) <= 0) {
DUAL_LOGE(cameraId, "There's no synced frame");
return NULL;
}
/* to SyncObjList */
Mutex::Autolock lock(m_lock);
/* check the integrity of SyncObjList */
if (m_syncObjList[cameraId].size() != m_syncObjList[otherCameraId].size()) {
DUAL_ASSERT(cameraId, "invalid size matching : syncObj size:%d/%d, prepareSyncObj size:%d/%d)",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size(),
m_prepareSyncObjList[cameraId].size(),
m_prepareSyncObjList[otherCameraId].size());
}
/* peek syncObj from sync obj */
if (m_peekList(cameraId, &m_syncObjList[cameraId], &syncObj, SyncObj::SELECT_STATE_WILL_BE_SELECTED) != NO_ERROR) {
if (m_peekList(cameraId, &m_syncObjList[cameraId], &syncObj, SyncObj::SELECT_STATE_NO_SELECTED) != NO_ERROR) {
DUAL_LOGW(cameraId, "There's no synced frame");
return NULL;
}
}
/* peek other camera's syncObj from sync obj */
if (m_peekList(cameraId, &m_syncObjList[otherCameraId], &otherSyncObj, syncObj->getSyncId()) != NO_ERROR) {
DUAL_ASSERT(cameraId, "Nothing in peekList : syncObj size:%d/%d, noSyncObj size:%d/%d)",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size(),
m_prepareSyncObjList[cameraId].size(),
m_prepareSyncObjList[otherCameraId].size());
}
/* if both camera selected synced frame, we actually pop the syncObj */
if (otherSyncObj->getSelectState() == SyncObj::SELECT_STATE_SELECTED) {
/* pop from sync obj */
if (m_popList(cameraId, &m_syncObjList[cameraId], &tempSyncObj, syncObj->getSyncId()) != NO_ERROR) {
DUAL_ASSERT(cameraId, "Nothing in popList : syncObj size:%d/%d, prepareSyncObj size:%d/%d)",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size(),
m_prepareSyncObjList[cameraId].size(),
m_prepareSyncObjList[otherCameraId].size());
}
/* pop from opposite camera's sync obj */
if (m_popList(cameraId, &m_syncObjList[otherCameraId], &tempOtherSyncObj, otherSyncObj->getSyncId()) != NO_ERROR) {
DUAL_ASSERT(cameraId, "Nothing in otherPopList : syncObj size:%d/%d, prepareSyncObj size:%d/%d)",
m_syncObjList[cameraId].size(),
m_syncObjList[otherCameraId].size(),
m_prepareSyncObjList[cameraId].size(),
m_prepareSyncObjList[otherCameraId].size());
}
} else {
/* change the select_state for both camera */
syncObj->setSelectState(SyncObj::SELECT_STATE_SELECTED);
otherSyncObj->setSelectState(SyncObj::SELECT_STATE_WILL_BE_SELECTED);
TWO_SYNC_OBJ_LOGV(cameraId, syncObj, otherSyncObj, "changed");
}
TWO_SYNC_OBJ_LOGV(cameraId, syncObj, otherSyncObj, "selected");
return syncObj->getFrame();
}
status_t ExynosCameraDualFrameSelector::releaseBuffer(int cameraId, ExynosCameraBuffer *buffer)
{
status_t ret = NO_ERROR;
if ((buffer != NULL) && (buffer->index >= 0)) {
DUAL_LOGV(cameraId, "index : %d", buffer->index);
if (m_bufMgr[cameraId] == NULL) {
DUAL_LOGE(cameraId, "buffer manager is null");
ret = INVALID_OPERATION;
return ret;
} else {
ret = m_bufMgr[cameraId]->putBuffer(buffer->index, EXYNOS_CAMERA_BUFFER_POSITION_NONE);
if (ret < 0) {
DUAL_LOGE(cameraId, "putBuffer failed (Index : %d)", buffer->index);
m_bufMgr[cameraId]->printBufferState();
m_bufMgr[cameraId]->printBufferQState();
}
}
}
return ret;
}
status_t ExynosCameraDualFrameSelector::getBufferManager(int cameraId, ExynosCameraBufferManager **bufMgr)
{
status_t ret = NO_ERROR;
if (m_bufMgr[cameraId] == NULL) {
DUAL_LOGE(cameraId, "buffer manager is null");
ret = INVALID_OPERATION;
} else {
*bufMgr = m_bufMgr[cameraId];
}
return ret;
}
status_t ExynosCameraDualFrameSelector::getParameter(int cameraId, ExynosCameraParameters **param)
{
status_t ret = NO_ERROR;
if (m_param[cameraId] == NULL) {
DUAL_LOGE(cameraId, "parameters is null");
ret = INVALID_OPERATION;
} else {
*param = m_param[cameraId];
}
return ret;
}
status_t ExynosCameraDualFrameSelector::setFrameHoldCount(int cameraId, int count, int32_t prepareCount)
{
Mutex::Autolock lock(m_lock);
m_holdCount = count;
m_prepareHoldCount = prepareCount;
DUAL_LOGD(cameraId, "count:%d, prepareHoldCount:%d", m_holdCount, m_prepareHoldCount);
return NO_ERROR;
}
int ExynosCameraDualFrameSelector::getSizeOfSyncList(int cameraId)
{
Mutex::Autolock lock(m_lock);
return m_syncObjList[cameraId].size();
}
status_t ExynosCameraDualFrameSelector::registerNotifyQ(int cameraId, ExynosCameraList<Message> **notifyQ)
{
Mutex::Autolock lock(m_lock);
if (notifyQ == NULL) {
DUAL_LOGE(cameraId, "notifyQ == NULL");
return INVALID_OPERATION;
}
DUAL_LOGD(cameraId, "");
if (m_notifyQ[cameraId].getSizeOfProcessQ() > 0) {
DUAL_ASSERT(cameraId, "Old Notifications(%d) was already notifyQ",
m_notifyQ[cameraId].getSizeOfProcessQ());
}
*notifyQ = &m_notifyQ[cameraId];
m_flagNotifyRegister[cameraId] = true;
return NO_ERROR;
}
status_t ExynosCameraDualFrameSelector::registerRemoveFrameQ(int cameraId, ExynosCameraList<ExynosCameraFrameSP_sptr_t> **removeFrameQ)
{
Mutex::Autolock lock(m_lock);
if (removeFrameQ == NULL) {
DUAL_LOGE(cameraId, "removeFrameQ == NULL");
return INVALID_OPERATION;
}
DUAL_LOGD(cameraId, "");
if (m_removeFrameQ[cameraId].getSizeOfProcessQ() > 0) {
DUAL_ASSERT(cameraId, "Old Frames(%d) was already removeFrameQ",
m_removeFrameQ[cameraId].getSizeOfProcessQ());
}
*removeFrameQ = &m_removeFrameQ[cameraId];
m_flagRemoveFrameRegister[cameraId] = true;
return NO_ERROR;
}
status_t ExynosCameraDualFrameSelector::flushSyncList(int cameraId)
{
status_t ret = NO_ERROR;
Mutex::Autolock lock(m_lock);
m_notifyQ[cameraId].release();
m_removeFrameQ[cameraId].release();
m_clearListAll(cameraId, &m_prepareSyncObjList[cameraId]);
m_clearListAll(cameraId, &m_syncObjList[cameraId]);
return ret;
}
status_t ExynosCameraDualFrameSelector::flush(int cameraId)
{
status_t ret = NO_ERROR;
DUAL_LOGD(cameraId, "");
Mutex::Autolock lock(m_lock);
/* flush notify, removeQ */
for (int i = 0; i < CAMERA_ID_MAX; i++) {
if ((!m_flagValidCameraId[i]))
continue;
m_notifyQ[i].release();
m_removeFrameQ[i].release();
}
/* flush syncFrameQ */
for (int i = 0; i < CAMERA_ID_MAX; i++) {
if ((!m_flagValidCameraId[i]))
continue;
m_clearListAll(cameraId, &m_prepareSyncObjList[i]);
m_clearListAll(cameraId, &m_syncObjList[i]);
}
return ret;
}
void ExynosCameraDualFrameSelector::dump(int cameraId)
{
for (int i = 0; i < CAMERA_ID_MAX; i++) {
if ((!m_flagValidCameraId[i]))
continue;
DUAL_LOGD(i, "=== DUMP ===");
{
/* Sync List Dump */
Mutex::Autolock lock(m_lock);
DUAL_LOGD(i, "=== PrepareObjList ===");
m_printList(i, &m_prepareSyncObjList[i]);
DUAL_LOGD(i, "=== SyncObjList ===");
m_printList(i, &m_syncObjList[i]);
}
}
}
/*
* protected
*/
int ExynosCameraDualFrameSelector::m_findOppositeCameraId(int cameraId)
{
int otherCameraId = -1;
/* find opposite cameraId */
for (int i = 0; i < CAMERA_ID_MAX; i++) {
if ((!m_flagValidCameraId[i]) || (cameraId == i))
continue;
otherCameraId = i;
break;
}
return otherCameraId;
}
status_t ExynosCameraDualFrameSelector::m_destroySyncObj(SyncObj *syncObj, bool flagReleaseBuffer, bool notifyRemove)
{
status_t ret = NO_ERROR;
ExynosCameraBuffer buffer;
int cameraId = syncObj->getCameraId();
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj is NULL(%d)", flagReleaseBuffer);
return NO_ERROR;
}
if (syncObj->getFrame() == NULL) {
ONE_SYNC_OBJ_LOGE(cameraId, syncObj, "syncObj has no frame");
return NO_ERROR;
}
ExynosCameraFrameSP_sptr_t frame = syncObj->getFrame();
int timeStamp = syncObj->getTimeStamp();
int pipeId = syncObj->getPipeId();
int nodeIndex = syncObj->getNodeIndex();
bool isSrc = syncObj->getIsSrc();
ONE_SYNC_OBJ_LOGV(cameraId, syncObj, "removed(%d)", flagReleaseBuffer);
/* 1. push the frame to registered camera's list to remove from processList */
if (notifyRemove == true && m_flagRemoveFrameRegister[cameraId] == true) {
ONE_SYNC_OBJ_LOGD(cameraId, syncObj, "pushProcessQ");
m_removeFrameQ[cameraId].pushProcessQ(&frame);
}
/* 2. put the buffer to bufMgr */
if (frame->getFrameType() != FRAME_TYPE_INTERNAL &&
flagReleaseBuffer == true) {
if (isSrc == true)
ret = frame->getSrcBuffer(pipeId, &buffer, nodeIndex);
else
ret = frame->getDstBuffer(pipeId, &buffer, nodeIndex);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, syncObj, "get%sBuffer fail(%d, %d)",
isSrc ? "Src" : "Dst", pipeId, nodeIndex);
else
releaseBuffer(cameraId, &buffer);
}
/* 3. destroy the syncObj */
syncObj->destroy();
return ret;
}
status_t ExynosCameraDualFrameSelector::m_pushList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, SyncObj *syncObj)
{
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj == NULL");
return INVALID_OPERATION;
}
ONE_SYNC_OBJ_LOGV(cameraId, syncObj, "pushed");
list->push_back(*syncObj);
return NO_ERROR;
}
status_t ExynosCameraDualFrameSelector::m_peekList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, SyncObj **syncObj, SyncObj::select_state_t selectState)
{
bool found = false;
List<SyncObj>::iterator r;
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj == NULL");
return INVALID_OPERATION;
}
if (list->empty())
return NOT_ENOUGH_DATA;
r = list->begin()++;
do {
if (r->getSelectState() == selectState) {
*syncObj = &(*r);
found = true;
break;
}
r++;
} while (r != list->end());
if (found == false) {
if (selectState == SyncObj::SELECT_STATE_NO_SELECTED)
DUAL_LOGE(cameraId, "there's no selectState(%d)", selectState);
return NOT_ENOUGH_DATA;
} else {
ONE_SYNC_OBJ_LOGV(cameraId, *syncObj, "peeked");
}
return NO_ERROR;
};
status_t ExynosCameraDualFrameSelector::m_peekList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, SyncObj **syncObj, int syncId)
{
bool found = false;
List<SyncObj>::iterator r;
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj == NULL");
return INVALID_OPERATION;
}
if (list->empty())
return NOT_ENOUGH_DATA;
r = list->begin()++;
do {
if (r->getSyncId() == syncId) {
*syncObj = &(*r);
found = true;
break;
}
r++;
} while (r != list->end());
if (found == false) {
DUAL_LOGE(cameraId, "there's no syncId(%d)", syncId);
return NOT_ENOUGH_DATA;
} else {
ONE_SYNC_OBJ_LOGV(cameraId, *syncObj, "peeked");
}
return NO_ERROR;
};
status_t ExynosCameraDualFrameSelector::m_peekList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, SyncObj **syncObj)
{
List<SyncObj>::iterator r;
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj == NULL");
return INVALID_OPERATION;
}
if (list->empty())
return NOT_ENOUGH_DATA;
r = list->begin()++;
*syncObj = &(*r);
ONE_SYNC_OBJ_LOGV(cameraId, *syncObj, "peeked");
return NO_ERROR;
};
status_t ExynosCameraDualFrameSelector::m_popList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, SyncObj *syncObj, int syncId)
{
bool found = false;
List<SyncObj>::iterator r;
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj == NULL");
return INVALID_OPERATION;
}
if (list->empty())
return NOT_ENOUGH_DATA;
r = list->begin()++;
do {
if (r->getSyncId() == syncId) {
*syncObj = *r;
list->erase(r);
found = true;
break;
}
r++;
} while (r != list->end());
if (found == false) {
ONE_SYNC_OBJ_LOGE(cameraId, syncObj, "there's no syncId(%d)", syncId);
return NOT_ENOUGH_DATA;
}
ONE_SYNC_OBJ_LOGV(cameraId, syncObj, "poped");
return NO_ERROR;
};
status_t ExynosCameraDualFrameSelector::m_popList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, SyncObj *syncObj)
{
List<SyncObj>::iterator r;
if (syncObj == NULL) {
DUAL_LOGE(cameraId, "syncObj == NULL");
return INVALID_OPERATION;
}
if (list->empty())
return NOT_ENOUGH_DATA;
r = list->begin()++;
*syncObj = *r;
ONE_SYNC_OBJ_LOGV(cameraId, syncObj, "poped");
list->erase(r);
return NO_ERROR;
};
bool ExynosCameraDualFrameSelector::m_checkSyncObjOnList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *otherPrepareList, SyncObj *syncObj, SyncObj *resultSyncObj)
{
status_t ret = NO_ERROR;
List<SyncObj>::iterator r;
int size = otherPrepareList->size();
SyncObj otherSyncObj;
if (otherPrepareList->empty()) {
ONE_SYNC_OBJ_LOGV(cameraId, syncObj, "empty size");
return false;
}
r = otherPrepareList->begin()++;
do {
otherSyncObj = *r;
if (syncObj->isSimilarTimeStamp(&otherSyncObj)) {
*resultSyncObj = otherSyncObj;
return true;
}
r++;
} while (r != otherPrepareList->end());
return false;
};
status_t ExynosCameraDualFrameSelector::m_clearListAll(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list)
{
status_t ret = NO_ERROR;
List<SyncObj>::iterator r;
int size = list->size();
SyncObj curSyncObj;
if (list->empty()) {
DUAL_LOGV(cameraId, "List Size : %d", size);
return NO_ERROR;
}
DUAL_LOGV(cameraId, "delete List Size : %d", size);
r = list->begin()++;
do {
curSyncObj = *r;
ONE_SYNC_OBJ_LOGV(cameraId, &curSyncObj, "removed(%d) flag(%d)", size, m_flagRemoveFrameRegister[cameraId]);
list->erase(r);
/* release SyncObj with source buffer */
ret = m_destroySyncObj(&curSyncObj, true, true);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, &curSyncObj, "removed(%d)", size);
r++;
} while (r != list->end());
return NO_ERROR;
}
status_t ExynosCameraDualFrameSelector::m_clearListUntilMinSize(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, int minSize, bool flagReleaseBuffer)
{
status_t ret = NO_ERROR;
List<SyncObj>::iterator r;
int size = list->size();
SyncObj curSyncObj;
if (list->empty() || size <= minSize) {
DUAL_LOGV(cameraId, "List Size : %d/%d", size, minSize);
return NO_ERROR;
}
DUAL_LOGV(cameraId, "delete List Size : %d/%d, flagReleaseBuffer(%d)", size, minSize, flagReleaseBuffer);
r = list->begin()++;
do {
curSyncObj = *r;
if (size <= minSize)
break;
/* remove only "no_selected" frame */
if (curSyncObj.getSelectState() == SyncObj::SELECT_STATE_NO_SELECTED) {
ONE_SYNC_OBJ_LOGV(cameraId, &curSyncObj, "removed(%d/%d) flag(%d)", size, minSize, m_flagRemoveFrameRegister[cameraId]);
list->erase(r);
/* release SyncObj with source buffer */
ret = m_destroySyncObj(&curSyncObj, flagReleaseBuffer, true);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, &curSyncObj, "removed(%d/%d)", size, minSize);
size--;
} else {
ONE_SYNC_OBJ_LOGW(cameraId, &curSyncObj, "can't removed(%d/%d) flag(%d)", size, minSize, m_flagRemoveFrameRegister[cameraId]);
}
r++;
} while (r != list->end());
return NO_ERROR;
}
status_t ExynosCameraDualFrameSelector::m_clearListUntilTimeStamp(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list, int timeStamp, bool flagReleaseBuffer)
{
status_t ret = NO_ERROR;
List<SyncObj>::iterator r;
int size = list->size();
SyncObj curSyncObj;
bool notifyRemove = true;
if (list->empty()) {
DUAL_LOGV(cameraId, "List Size : %d", size);
return NO_ERROR;
}
DUAL_LOGV(cameraId, "delete List Size : %d, timeStamp(%d), flagReleaseBuffer(%d)", size, timeStamp, flagReleaseBuffer);
r = list->begin()++;
do {
curSyncObj = *r;
if (curSyncObj.getTimeStamp() > timeStamp) {
break;
} else if (curSyncObj.getTimeStamp() == timeStamp) {
/* reserve the frame */
notifyRemove = false;
flagReleaseBuffer = false;
} else {
/* remove the frame */
notifyRemove = true;
}
/* remove only "no_selected" frame */
if (curSyncObj.getSelectState() == SyncObj::SELECT_STATE_NO_SELECTED) {
ONE_SYNC_OBJ_LOGV(cameraId, &curSyncObj, "removed(%d/%d) flag(%d)", curSyncObj.getTimeStamp(), timeStamp, m_flagRemoveFrameRegister[cameraId]);
list->erase(r);
/* release SyncObj with source buffer */
ret = m_destroySyncObj(&curSyncObj, flagReleaseBuffer, notifyRemove);
if (ret != NO_ERROR)
ONE_SYNC_OBJ_LOGE(cameraId, &curSyncObj, "removed(%d)", timeStamp);
} else {
ONE_SYNC_OBJ_LOGW(cameraId, &curSyncObj, "can't removed(%d/%d) flag(%d)", curSyncObj.getTimeStamp(), timeStamp, m_flagRemoveFrameRegister[cameraId]);
}
r++;
} while (r != list->end());
return NO_ERROR;
}
void ExynosCameraDualFrameSelector::m_printList(int cameraId, List<ExynosCameraDualFrameSelector::SyncObj> *list)
{
List<SyncObj>::iterator r;
SyncObj curSyncObj;
if (m_flagValidCameraId[cameraId] == false) {
DUAL_LOGE(cameraId, "invalid cameraId");
return;
}
DUAL_LOGD(cameraId, " List Size : %d", list->size());
if (list->empty())
return;
r = list->begin()++;
do {
curSyncObj = *r;
ONE_SYNC_OBJ_LOGD(cameraId, &curSyncObj, "");
r++;
} while (r != list->end());
}
int ExynosCameraDualFrameSelector::m_getTimeStamp(ExynosCameraFrameSP_sptr_t frame)
{
return (int)(ns2ms(frame->getTimeStamp()));
}
/* for Preview Singleton in Sync Pipe */
ExynosCameraDualPreviewFrameSelector::ExynosCameraDualPreviewFrameSelector()
{
strncpy(m_name, "DualPreviewSelector", (EXYNOS_CAMERA_NAME_STR_SIZE - 1));
init();
}
ExynosCameraDualPreviewFrameSelector::~ExynosCameraDualPreviewFrameSelector()
{
}
/* for Reprocessing Singleton in Sync Pipe */
ExynosCameraDualCaptureFrameSelector::ExynosCameraDualCaptureFrameSelector()
{
strncpy(m_name, "DualCaptureSelector", (EXYNOS_CAMERA_NAME_STR_SIZE - 1));
init();
}
ExynosCameraDualCaptureFrameSelector::~ExynosCameraDualCaptureFrameSelector()
{
}
/* for Reprocessing Singleton in captureSelector */
ExynosCameraDualBayerFrameSelector::ExynosCameraDualBayerFrameSelector()
{
strncpy(m_name, "DualBayerSelector", (EXYNOS_CAMERA_NAME_STR_SIZE - 1));
init();
}
ExynosCameraDualBayerFrameSelector::~ExynosCameraDualBayerFrameSelector()
{
}