blob: de17b4f347c06bc37a4fca2cf61b885810d5dc01 [file] [log] [blame]
/*
**
** Copyright 2013, 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 "ExynosCameraFrameSelector"
#include "ExynosCameraFrameSelector.h"
#define FLASHED_LLS_COUNT 4
namespace android {
#ifdef USE_FRAMEMANAGER
ExynosCameraFrameSelector::ExynosCameraFrameSelector(ExynosCameraParameters *param,
ExynosCameraBufferManager *bufMgr,
ExynosCameraFrameManager *manager
#ifdef SUPPORT_DEPTH_MAP
, depth_callback_queue_t *depthCallbackQ
, ExynosCameraBufferManager *depthMapbufMgr
#endif
)
#else
ExynosCameraFrameSelector::ExynosCameraFrameSelector(ExynosCameraParameters *param,
ExynosCameraBufferManager *bufMgr)
#endif
{
#ifdef USE_FRAMEMANAGER
m_frameMgr = manager;
#endif
m_parameters = param;
m_bufMgr= bufMgr;
m_activityControl = m_parameters->getActivityControl();
m_frameHoldList.setWaitTime(2000000000);
#ifdef OIS_CAPTURE
m_OISFrameHoldList.setWaitTime(130000000);
#endif
#ifdef RAWDUMP_CAPTURE
m_RawFrameHoldList.setWaitTime(2000000000);
#endif
m_reprocessingCount = 0;
m_frameHoldCount = 1;
m_isFirstFrame = true;
isCanceled = false;
#ifdef OIS_CAPTURE
removeFlags = false;
#endif
#ifdef LLS_REPROCESSING
LLSCaptureFrame = NULL;
m_isLastFrame = true;
m_isConvertingMeta = true;
m_LLSCaptureCount = 0;
#endif
#ifdef SAMSUNG_LBP
m_lbpFrameCounter = 0;
m_LBPFrameNum = 0;
#endif
#ifdef SAMSUNG_DNG
m_DNGFrameCount = 0;
m_preDNGFrameCount = 0;
m_preDNGFrame = NULL;
#endif
m_CaptureCount = 0;
#ifdef SUPPORT_DEPTH_MAP
m_depthCallbackQ = depthCallbackQ;
m_depthMapbufMgr = depthMapbufMgr;
#endif
}
ExynosCameraFrameSelector::~ExynosCameraFrameSelector()
{
}
status_t ExynosCameraFrameSelector::m_release(ExynosCameraList<ExynosCameraFrame *> *list)
{
int ret = 0;
ExynosCameraFrame *frame = NULL;
while (list->getSizeOfProcessQ() > 0) {
ret = m_popQ(list, &frame, true, 1);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):getBufferToManageQ fail", __FUNCTION__, __LINE__);
m_bufMgr->printBufferState();
m_bufMgr->printBufferQState();
} else {
m_frameComplete(frame, true);
}
}
return ret;
}
status_t ExynosCameraFrameSelector::manageFrameHoldListForDynamicBayer(ExynosCameraFrame *frame)
{
int ret = 0;
if (frame == NULL) {
ALOGE("ERR(%s[%d]): frame is NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
#ifdef USE_FRAME_REFERENCE_COUNT
frame->incRef();
#endif
m_pushQ(&m_frameHoldList, frame, true);
ALOGI("INFO(%s[%d]): frameCount(%d) m_frameHoldList size(%d)",
__FUNCTION__, __LINE__, frame->getFrameCount(), m_frameHoldList.getSizeOfProcessQ());
return ret;
}
status_t ExynosCameraFrameSelector::m_manageHdrFrameHoldList(ExynosCameraFrame *frame,
int pipeID,
bool isSrc,
int32_t dstPos)
{
int ret = 0;
ExynosCameraBuffer buffer;
ExynosCameraFrame *newFrame = NULL;
ExynosCameraActivitySpecialCapture *m_sCaptureMgr = NULL;
unsigned int hdrFcount = 0;
unsigned int fliteFcount = 0;
newFrame = frame;
m_sCaptureMgr = m_activityControl->getSpecialCaptureMgr();
hdrFcount = m_sCaptureMgr->getHdrDropFcount();
hdrFcount += m_parameters->getHDRDelay();
ret = m_getBufferFromFrame(newFrame, pipeID, isSrc, &buffer, dstPos);
if( ret != NO_ERROR ) {
ALOGE("ERR(%s[%d]):m_getBufferFromFrame fail pipeID(%d) BufferType(%s)",
__FUNCTION__, __LINE__, pipeID, (isSrc)?"Src":"Dst");
}
if (m_parameters->getUsePureBayerReprocessing() == true) {
camera2_shot_ext *shot_ext = NULL;
shot_ext = (camera2_shot_ext *)(buffer.addr[1]);
if (shot_ext != NULL)
fliteFcount = shot_ext->shot.dm.request.frameCount;
else
ALOGE("ERR(%s[%d]):fliteReprocessingBuffer is null", __FUNCTION__, __LINE__);
} else {
camera2_stream *shot_stream = NULL;
shot_stream = (camera2_stream *)(buffer.addr[1]);
if (shot_stream != NULL)
fliteFcount = shot_stream->fcount;
else
ALOGE("ERR(%s[%d]):fliteReprocessingBuffer is null", __FUNCTION__, __LINE__);
}
if (hdrFcount + 1 == fliteFcount || hdrFcount + 2 == fliteFcount || hdrFcount + 3 == fliteFcount) {
ALOGI("INFO(%s[%d]):hdrFcount %d, fliteFcount %d", __FUNCTION__, __LINE__, hdrFcount, fliteFcount);
m_pushQ(&m_hdrFrameHoldList, newFrame, true);
} else {
m_frameComplete(newFrame, false, pipeID, isSrc, dstPos, true);
newFrame = NULL;
}
return ret;
}
/* It's for dynamic bayer */
ExynosCameraFrame* ExynosCameraFrameSelector::selectDynamicFrames(__unused int count,
int pipeID,
bool isSrc,
int tryCount,
int32_t dstPos)
{
return m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
}
ExynosCameraFrame* ExynosCameraFrameSelector::selectCaptureFrames(int count,
uint32_t frameCount,
int pipeID,
bool isSrc,
int tryCount,
int32_t dstPos)
{
ExynosCameraFrame* selectedFrame = NULL;
ExynosCameraActivityFlash *m_flashMgr = NULL;
m_reprocessingCount = count;
m_flashMgr = m_activityControl->getFlashMgr();
if (m_flashMgr->getNeedCaptureFlash() == true) {
selectedFrame = m_selectFlashFrameV2(pipeID, isSrc, tryCount, dstPos);
if (selectedFrame == NULL) {
ALOGE("ERR(%s[%d]):Failed to selectFlashFrame", __FUNCTION__, __LINE__);
selectedFrame = m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
}
} else {
selectedFrame = m_selectCaptureFrame(frameCount, pipeID, isSrc, tryCount, dstPos);
if (selectedFrame == NULL) {
ALOGE("ERR(%s[%d]):Failed to selectCaptureFrame", __FUNCTION__, __LINE__);
selectedFrame = m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
}
}
return selectedFrame;
}
ExynosCameraFrame* ExynosCameraFrameSelector::m_selectFocusedFrame(int pipeID, bool isSrc, int tryCount, int32_t dstPos)
{
int ret = 0;
ExynosCameraFrame* selectedFrame = NULL;
struct camera2_shot_ext shot_ext;
memset(&shot_ext, 0x00, sizeof(struct camera2_shot_ext));
for (int i = 0; i < CAPTURE_WAITING_COUNT; i++) {
selectedFrame = m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
if (selectedFrame == NULL) {
ALOGE("ERR(%s[%d]):selectedFrame is NULL", __FUNCTION__, __LINE__);
break;
}
/* get dynamic metadata for af state */
if (selectedFrame->getMetaDataEnable() == false)
ALOGD("DEBUG(%s[%d]):Waiting for update metadata failed (%d) ", __FUNCTION__, __LINE__, ret);
selectedFrame->getDynamicMeta(&shot_ext);
/* Skip focusing frame */
if (m_activityControl->flagFocusing(&shot_ext, m_parameters->getFocusMode()) == true) {
ALOGD("DEBUG(%s[%d]):skip focusing frame(count %d)",
__FUNCTION__, __LINE__, selectedFrame->getFrameCount());
if (m_bufMgr == NULL) {
ALOGE("ERR(%s[%d]):m_bufMgr is NULL", __FUNCTION__, __LINE__);
return NULL;
} else {
m_frameComplete(selectedFrame, false, pipeID, isSrc, dstPos, true);
selectedFrame = NULL;
}
} else {
ALOGD("DEBUG(%s[%d]):focusing complete (count %d)",
__FUNCTION__, __LINE__, selectedFrame->getFrameCount());
break;
}
usleep(DM_WAITING_TIME);
}
return selectedFrame;
}
ExynosCameraFrame* ExynosCameraFrameSelector::m_selectFlashFrame(int pipeID, bool isSrc, int tryCount, int32_t dstPos)
{
int ret = 0;
ExynosCameraFrame* selectedFrame = NULL;
ExynosCameraBuffer selectedBuffer;
int bufferFcount = 0;
int waitFcount = 0;
int totalWaitingCount = 0;
/* Choose bayerBuffer to process reprocessing */
while (totalWaitingCount <= (FLASH_MAIN_TIMEOUT_COUNT + m_parameters->getReprocessingBayerHoldCount())) {
/* Start main flash & Get best frame count for flash */
if (waitFcount == 0) {
waitFcount = m_activityControl->startMainFlash() + 1;
ALOGD("DEBUG(%s):best frame count for flash capture : %d", __FUNCTION__, waitFcount);
}
ret = m_waitAndpopQ(&m_frameHoldList, &selectedFrame, false, tryCount);
if (ret < 0 || selectedFrame == NULL) {
ALOGD("DEBUG(%s[%d]):getFrame Fail ret(%d)", __FUNCTION__, __LINE__, ret);
return NULL;
} else if (isCanceled == true) {
ALOGD("DEBUG(%s[%d]):isCanceled", __FUNCTION__, __LINE__);
if (selectedFrame != NULL) {
m_LockedFrameComplete(selectedFrame, pipeID, isSrc, dstPos);
}
return NULL;
}
ALOGD("DEBUG(%s[%d]):Frame Count(%d)", __FUNCTION__, __LINE__, selectedFrame->getFrameCount());
/* Handling exception cases : like preflash is not processed */
if (waitFcount < 0) {
ALOGW("WARN(%s[%d]):waitFcount is negative : preflash is not processed", __FUNCTION__, __LINE__);
return NULL;
}
if (isCanceled == true) {
ALOGD("DEBUG(%s[%d]):isCanceled", __FUNCTION__, __LINE__);
return NULL;
}
ret = m_getBufferFromFrame(selectedFrame, pipeID, isSrc, &selectedBuffer, dstPos);
if (ret != NO_ERROR) {
ALOGE("ERR(%s[%d]):m_getBufferFromFrame fail pipeID(%d) BufferType(%s) bufferPtr(%p)",
__FUNCTION__, __LINE__, pipeID, (isSrc)?"Src":"Dst", selectedBuffer);
}
if (m_isFrameMetaTypeShotExt() == true) {
camera2_shot_ext *shot_ext = NULL;
shot_ext = (camera2_shot_ext *)(selectedBuffer.addr[1]);
if (shot_ext != NULL)
bufferFcount = shot_ext->shot.dm.request.frameCount;
else
ALOGE("ERR(%s[%d]):selectedBuffer is null", __FUNCTION__, __LINE__);
} else {
camera2_stream *shot_stream = NULL;
shot_stream = (camera2_stream *)(selectedBuffer.addr[1]);
if (shot_stream != NULL)
bufferFcount = shot_stream->fcount;
else
ALOGE("ERR(%s[%d]):selectedBuffer is null", __FUNCTION__, __LINE__);
}
/* Put mismatched buffer */
if (waitFcount != bufferFcount) {
if (m_bufMgr == NULL) {
ALOGE("ERR(%s[%d]):m_bufMgr is NULL", __FUNCTION__, __LINE__);
return NULL;
} else {
m_frameComplete(selectedFrame, false, pipeID, isSrc, dstPos, true);
selectedFrame = NULL;
}
}
if (waitFcount <= bufferFcount) {
break;
}
totalWaitingCount++;
ALOGD("DEBUG(%s[%d]) (totalWaitingCount %d)", __FUNCTION__, __LINE__, totalWaitingCount);
}
if (totalWaitingCount > FLASH_MAIN_TIMEOUT_COUNT) {
ALOGW("WARN(%s[%d]):fail to get bayer frame count for flash capture (totalWaitingCount %d)",
__FUNCTION__, __LINE__, totalWaitingCount);
}
ALOGD("DEBUG(%s[%d]):waitFcount : %d, bufferFcount : %d",
__FUNCTION__, __LINE__, waitFcount, bufferFcount);
/* Stop main flash */
m_activityControl->stopMainFlash();
return selectedFrame;
}
ExynosCameraFrame* ExynosCameraFrameSelector::m_selectHdrFrame(__unused int pipeID, __unused bool isSrc, int tryCount, __unused int32_t dstPos)
{
int ret = 0;
ExynosCameraFrame* selectedFrame = NULL;
ret = m_waitAndpopQ(&m_hdrFrameHoldList, &selectedFrame, false, tryCount);
if( ret < 0 || selectedFrame == NULL ) {
ALOGD("DEBUG(%s[%d]):getFrame Fail ret(%d)", __FUNCTION__, __LINE__, ret);
return NULL;
}
return selectedFrame;
}
ExynosCameraFrame* ExynosCameraFrameSelector::m_selectBurstFrame(int pipeID, bool isSrc, int tryCount, int32_t dstPos)
{
int ret = 0;
ExynosCameraFrame* selectedFrame = NULL;
ExynosCameraActivityFlash *m_flashMgr = m_activityControl->getFlashMgr();
for (int i = 0; i < TOTAL_WAITING_TIME; i += DM_WAITING_TIME) {
if (m_isFirstFrame == true) {
selectedFrame = m_selectFocusedFrame(pipeID, isSrc, tryCount, dstPos);
if (selectedFrame == NULL) {
ALOGE("ERR(%s[%d]):selectedFrame is NULL", __FUNCTION__, __LINE__);
selectedFrame = m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
}
} else {
selectedFrame = m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
}
/* Skip flash frame */
if (m_flashMgr->checkPreFlash() == true) {
if (m_flashMgr->checkFlashOff() == false) {
ALOGD("DEBUG(%s[%d]):skip flash frame(count %d)",
__FUNCTION__, __LINE__, selectedFrame->getFrameCount());
if (m_bufMgr == NULL) {
ALOGE("ERR(%s[%d]):m_bufMgr is NULL", __FUNCTION__, __LINE__);
return NULL;
} else {
m_frameComplete(selectedFrame, false, pipeID, isSrc, dstPos, true);
selectedFrame = NULL;
}
} else {
ALOGD("DEBUG(%s[%d]):flash off done (count %d)",
__FUNCTION__, __LINE__, selectedFrame->getFrameCount());
break;
}
} else {
ALOGD("DEBUG(%s[%d]):pre-flash off", __FUNCTION__, __LINE__);
break;
}
usleep(DM_WAITING_TIME);
}
return selectedFrame;
}
ExynosCameraFrame* ExynosCameraFrameSelector::m_selectCaptureFrame(uint32_t frameCount, int pipeID, bool isSrc, int tryCount, int32_t dstPos)
{
int ret = 0;
ExynosCameraFrame *selectedFrame = NULL;
for (int i = 0; i < CAPTURE_WAITING_COUNT; i++) {
selectedFrame = m_selectNormalFrame(pipeID, isSrc, tryCount, dstPos);
if (selectedFrame == NULL) {
ALOGE("ERR(%s[%d]):selectedFrame is NULL", __FUNCTION__, __LINE__);
break;
}
if (selectedFrame->getFrameCount() < frameCount) {
ALOGD("DEBUG(%s[%d]):skip capture frame(count %d), waiting frame(count %d)",
__FUNCTION__, __LINE__, selectedFrame->getFrameCount(), frameCount);
if (m_bufMgr == NULL) {
ALOGE("ERR(%s[%d]):m_bufMgr is NULL", __FUNCTION__, __LINE__);
return NULL;
} else {
m_frameComplete(selectedFrame, false, pipeID, isSrc, dstPos, true);
selectedFrame = NULL;
}
} else {
ALOGD("DEBUG(%s[%d]):capture frame (count %d)",
__FUNCTION__, __LINE__, selectedFrame->getFrameCount());
break;
}
}
return selectedFrame;
}
status_t ExynosCameraFrameSelector::m_getBufferFromFrame(ExynosCameraFrame *frame,
int pipeID,
bool isSrc,
ExynosCameraBuffer *outBuffer,
int32_t dstPos)
{
status_t ret = NO_ERROR;
ExynosCameraBuffer selectedBuffer;
if (frame == NULL) {
ALOGE("ERR(%s[%d]):frame == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (outBuffer == NULL) {
ALOGE("ERR(%s[%d]):outBuffer == NULL", __FUNCTION__, __LINE__);
return BAD_VALUE;
}
if (isSrc) {
ret = frame->getSrcBuffer(pipeID, &selectedBuffer);
if (ret != NO_ERROR)
ALOGE("ERR(%s[%d]):getSrcBuffer(pipeID %d) fail", __FUNCTION__, __LINE__, pipeID);
} else {
if (dstPos < 0) {
ret = frame->getDstBuffer(pipeID, &selectedBuffer);
if (ret != NO_ERROR)
ALOGE("ERR(%s[%d]):getDstBuffer(pipeID %d) fail", __FUNCTION__, __LINE__, pipeID);
} else {
ret = frame->getDstBuffer(pipeID, &selectedBuffer, dstPos);
if (ret != NO_ERROR)
ALOGE("ERR(%s[%d]):getDstBuffer(pipeID %d, dstPos %d) fail", __FUNCTION__, __LINE__, pipeID, dstPos);
}
}
*outBuffer = selectedBuffer;
return ret;
}
status_t ExynosCameraFrameSelector::m_pushQ(ExynosCameraList<ExynosCameraFrame *> *list,
ExynosCameraFrame* inframe,
bool lockflag)
{
status_t ret = NO_ERROR;
if( lockflag ) {
inframe->frameLock();
}
list->pushProcessQ(&inframe);
return ret;
}
status_t ExynosCameraFrameSelector::m_popQ(ExynosCameraList<ExynosCameraFrame *> *list,
ExynosCameraFrame** outframe,
bool unlockflag,
int tryCount)
{
status_t ret = NO_ERROR;
int iter = 0;
do {
ret = list->popProcessQ(outframe);
if( ret < 0 ) {
if( ret == TIMED_OUT ) {
ALOGD("DEBUG(%s[%d]):PopQ Time out -> retry[max cur](%d %d)",
__FUNCTION__, __LINE__, tryCount, iter);
iter++;
continue;
}
}
} while (ret != OK && tryCount > iter);
if( ret != OK ) {
ALOGE("ERR(%s[%d]):popQ fail(%d)", __FUNCTION__, __LINE__, ret);
return ret;
}
if( *outframe == NULL ) {
ALOGE("ERR(%s[%d]):popQ frame = NULL frame(%p)", __FUNCTION__, __LINE__, *outframe);
return ret;
}
if( unlockflag ) {
(*outframe)->frameUnlock();
}
return ret;
}
#ifdef USE_FRAMEMANAGER
status_t ExynosCameraFrameSelector::m_frameComplete(ExynosCameraFrame *frame, bool isForcelyDelete,
int pipeID, bool isSrc, int32_t dstPos, bool flagReleaseBuf)
{
int ret = OK;
if(flagReleaseBuf) {
m_releaseBuffer(frame, pipeID, isSrc, dstPos);
}
if (isForcelyDelete == true) {
ALOGD("DEBUG(%s[%d]):frame deleted forcely : isComplete(%d) count(%d) LockState(%d)",
__FUNCTION__, __LINE__,
frame->isComplete(),
frame->getFrameCount(),
frame->getFrameLockState());
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
#endif
m_frameMgr->deleteFrame(frame);
} else {
ALOGE("ERR(%s[%d]):m_frameMgr is NULL (%d)", __FUNCTION__, __LINE__, frame->getFrameCount());
}
frame = NULL;
} else {
ALOGV("DEBUG(%s[%d]):frame complete, count(%d)", __FUNCTION__, __LINE__, frame->getFrameCount());
#ifndef USE_FRAME_REFERENCE_COUNT
if (frame->isComplete() == true) {
if (frame->getFrameLockState() == false) {
ALOGV("DEBUG(%s[%d]):frame complete, count(%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
#endif
m_frameMgr->deleteFrame(frame);
} else {
ALOGE("ERR(%s[%d]):m_frameMgr is NULL (%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
}
frame = NULL;
} else {
ALOGV("DEBUG(%s[%d]):frame is locked : isComplete(%d) count(%d) LockState(%d)",
__FUNCTION__, __LINE__,
frame->isComplete(),
frame->getFrameCount(),
frame->getFrameLockState());
}
} else {
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
ALOGE("ERR(%s[%d]):frame deleted : key(%d) refCnt(%d)",
__FUNCTION__, __LINE__, frame->getUniqueKey(), frame->getRef());
#endif
m_frameMgr->deleteFrame(frame);
} else {
ALOGE("ERR(%s[%d]):m_frameMgr is NULL (%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
}
frame = NULL;
}
#else /* USE_FRAME_REFERENCE_COUNT */
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
#endif
m_frameMgr->deleteFrame(frame);
} else {
ALOGE("ERR(%s[%d]):m_frameMgr is NULL (%d)", __FUNCTION__, __LINE__, frame->getFrameCount());
}
#endif
frame = NULL;
}
return ret;
}
#else /* USE_FRAMEMANAGER */
status_t ExynosCameraFrameSelector::m_frameComplete(ExynosCameraFrame *frame, bool isForcelyDelete, int pipeID,
int pipeID, bool isSrc, int32_t dstPos, bool flagReleaseBuf)
{
int ret = OK;
if(flagReleaseBuf) {
m_releaseBuffer(frame, pipeID, isSrc, dstPos);
}
if (isForcelyDelete == true) {
ALOGD("DEBUG(%s[%d]):frame deleted forcely : isComplete(%d) count(%d) LockState(%d)",
__FUNCTION__, __LINE__,
frame->isComplete(),
frame->getFrameCount(),
frame->getFrameLockState());
delete frame;
frame = NULL;
} else {
if (frame->isComplete() == true) {
if (frame->getFrameLockState() == false) {
ALOGV("DEBUG(%s[%d]):frame complete, count(%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
delete frame;
frame = NULL;
} else {
ALOGV("DEBUG(%s[%d]):frame is locked : isComplete(%d) count(%d) LockState(%d)",
__FUNCTION__, __LINE__,
frame->isComplete(),
frame->getFrameCount(),
frame->getFrameLockState());
}
} else {
ALOGV("DEBUG(%s[%d]):frame is not completed : isComplete(%d) count(%d) LockState(%d)",
__FUNCTION__, __LINE__,
frame->isComplete(),
frame->getFrameCount(),
frame->getFrameLockState());
}
}
return ret;
}
#endif
/*
* Check complete flag of the Frame and deallocate it if it is completed.
* This function ignores lock flag of the frame(Lock flag is usually set to protect
* the frame from deallocation), so please use with caution.
* This function is required to remove a frame from frameHoldingList.
*/
#ifdef USE_FRAMEMANAGER
status_t ExynosCameraFrameSelector::m_LockedFrameComplete(ExynosCameraFrame *frame, int pipeID,
bool isSrc, int32_t dstPos)
{
int ret = OK;
m_releaseBuffer(frame, pipeID, isSrc, dstPos);
#ifndef USE_FRAME_REFERENCE_COUNT
if (frame->isComplete() == true) {
if (frame->getFrameLockState() == true)
{
ALOGV("DEBUG(%s[%d]):Deallocating locked frame, count(%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
}
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
#endif
m_frameMgr->deleteFrame(frame);
}
frame = NULL;
}
#else
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
#endif
m_frameMgr->deleteFrame(frame);
} else {
ALOGE("ERR(%s[%d]):m_frameMgr is NULL (%d)", __FUNCTION__, __LINE__, frame->getFrameCount());
}
#endif
return ret;
}
#else
status_t ExynosCameraFrameSelector::m_LockedFrameComplete(ExynosCameraFrame *frame, int pipeID,
bool isSrc, int32_t dstPos)
{
int ret = OK;
m_releaseBuffer(frame, pipeID, isSrc, dstPos);
if (frame->isComplete() == true) {
if (frame->getFrameLockState() == true)
{
ALOGV("DEBUG(%s[%d]):Deallocating locked frame, count(%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
ALOGV("DEBUG(%s[%d]):frame is locked : isComplete(%d) count(%d) LockState(%d)",
__FUNCTION__, __LINE__,
frame->isComplete(),
frame->getFrameCount(),
frame->getFrameLockState());
}
delete frame;
frame = NULL;
}
return ret;
}
#endif
status_t ExynosCameraFrameSelector::wakeupQ(void)
{
m_frameHoldList.sendCmd(WAKE_UP);
return NO_ERROR;
}
status_t ExynosCameraFrameSelector::cancelPicture(bool flagCancel)
{
isCanceled = flagCancel;
return NO_ERROR;
}
status_t ExynosCameraFrameSelector::m_clearList(ExynosCameraList<ExynosCameraFrame *> *list,int pipeID, bool isSrc, int32_t dstPos)
{
int ret = 0;
ExynosCameraFrame *frame = NULL;
ExynosCameraBuffer buffer;
while (list->getSizeOfProcessQ() > 0) {
if( m_popQ(list, &frame, false, 1) != NO_ERROR ) {
ALOGE("ERR(%s[%d]):getBufferToManageQ fail", __FUNCTION__, __LINE__);
m_bufMgr->printBufferState();
m_bufMgr->printBufferQState();
} else {
ret = m_getBufferFromFrame(frame, pipeID, isSrc, &buffer, dstPos);
if( ret != NO_ERROR ) {
ALOGE("ERR(%s[%d]):m_getBufferFromFrame fail pipeID(%d) BufferType(%s)",
__FUNCTION__, __LINE__, pipeID, (isSrc)?"Src":"Dst");
}
if (m_bufMgr == NULL) {
ALOGE("ERR(%s[%d]):m_bufMgr is NULL", __FUNCTION__, __LINE__);
return INVALID_OPERATION;
} else {
if (buffer.index >= 0)
ret = m_bufMgr->putBuffer(buffer.index, EXYNOS_CAMERA_BUFFER_POSITION_NONE);
if (ret < 0) {
ALOGE("ERR(%s[%d]):putIndex is %d", __FUNCTION__, __LINE__, buffer.index);
m_bufMgr->printBufferState();
m_bufMgr->printBufferQState();
}
/*
Frames in m_frameHoldList and m_hdrFrameHoldList are locked when they are inserted
on the list. So we need to use m_LockedFrameComplete() to remove those frames.
Please beware that the frame might be deleted in elsewhere, epically on erroneous
conditions. So if the program encounters memory fault here, please check the other
frame deallocation(delete) routines.
*/
/* Rather than blindly deleting frame in m_LockedFrameComplete(), we do following:
* 1. Check whether frame is complete. Delete the frame if it is complete.
* 2. If the frame is not complete, unlock it. mainThread will delete this frame.
*/
//m_LockedFrameComplete(frame);
#ifdef USE_FRAMEMANAGER
#ifndef USE_FRAME_REFERENCE_COUNT
if (frame->isComplete() == true) {
if (frame->getFrameLockState() == true)
ALOGV("DEBUG(%s[%d]):Deallocating locked frame, count(%d)",
__FUNCTION__, __LINE__, frame->getFrameCount());
#else
{
#endif
if (m_frameMgr != NULL) {
#ifdef USE_FRAME_REFERENCE_COUNT
frame->decRef();
#endif
m_frameMgr->deleteFrame(frame);
} else {
ALOGE("ERR(%s[%d]):m_frameMgr is NULL (%d)", __FUNCTION__, __LINE__, frame->getFrameCount());
}
}
#else
if (frame->isComplete() == true) {
delete frame;
frame = NULL;
} else {
if (frame->getFrameLockState() == true)
frame->frameUnlock();
}
#endif
}
}
}
return ret;
}
status_t ExynosCameraFrameSelector::setFrameHoldCount(int32_t count)
{
if (count < 0) {
ALOGE("ERR(%s[%d]):frame hold count cannot be negative value, current value(%d)",
__FUNCTION__, __LINE__, count);
return BAD_VALUE;
}
m_frameHoldCount = count;
return NO_ERROR;
}
bool ExynosCameraFrameSelector::m_isFrameMetaTypeShotExt(void)
{
bool isShotExt = true;
if (m_parameters->isSccCapture() == true) {
if (m_parameters->isReprocessing() == true)
isShotExt = true;
else
isShotExt = false;
} else {
if (m_parameters->getUsePureBayerReprocessing() == false)
isShotExt = false;
}
return isShotExt;
}
void ExynosCameraFrameSelector::setWaitTime(uint64_t waitTime)
{
m_frameHoldList.setWaitTime(waitTime);
}
void ExynosCameraFrameSelector::setIsFirstFrame(bool isFirstFrame)
{
m_isFirstFrame = isFirstFrame;
}
bool ExynosCameraFrameSelector::getIsFirstFrame()
{
return m_isFirstFrame;
}
void ExynosCameraFrameSelector::wakeselectDynamicFrames(void)
{
isCanceled = true;
m_frameHoldList.wakeupAll();
}
}