| /* |
| ** |
| ** Copyright 2014, 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 "ExynosCameraFrameManager" |
| #include <cutils/log.h> |
| |
| #include "ExynosCameraFrameManager.h" |
| |
| namespace android { |
| |
| FrameWorker::FrameWorker(const char* name, int cameraid, FRAMEMGR_OPER::MODE operMode) |
| { |
| m_cameraId = cameraid; |
| strncpy(m_name, name, EXYNOS_CAMERA_NAME_STR_SIZE - 1); |
| m_operMode = operMode; |
| m_init(); |
| } |
| |
| FrameWorker::~FrameWorker() |
| { |
| m_deinit(); |
| } |
| |
| status_t FrameWorker::m_init() |
| { |
| return 0; |
| } |
| |
| status_t FrameWorker::m_deinit() |
| { |
| return 0; |
| } |
| |
| uint32_t FrameWorker::getKey() |
| { |
| return m_key; |
| } |
| |
| status_t FrameWorker::setKey(uint32_t key) |
| { |
| m_key = key; |
| return 0; |
| } |
| |
| status_t FrameWorker::m_setEnable(bool enable) |
| { |
| Mutex::Autolock lock(m_enableLock); |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| m_enable = enable; |
| return ret; |
| } |
| |
| bool FrameWorker::m_getEnable() |
| { |
| Mutex::Autolock lock(m_enableLock); |
| return m_enable; |
| } |
| |
| status_t FrameWorker::m_delete(ExynosCameraFrame *frame) |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| delete frame; |
| frame = NULL; |
| |
| return ret; |
| } |
| |
| CreateWorker::CreateWorker(const char* name, int cameraid, FRAMEMGR_OPER::MODE operMode, int32_t margin):FrameWorker(name, cameraid, operMode) |
| { |
| CLOGD("DEBUG(%s): Worker CREATE(name(%s) cameraid(%d) mode(%d) margin(%d) ", __FUNCTION__, name, cameraid, operMode, margin); |
| m_init(); |
| m_setMargin(margin); |
| } |
| CreateWorker::~CreateWorker() |
| { |
| CLOGD("DEBUG(%s): Worker DELETE(name(%s) cameraid(%d) mode(%d) ", __FUNCTION__, m_name, m_cameraId, m_operMode); |
| m_deinit(); |
| } |
| |
| status_t CreateWorker::m_deinit() |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| ExynosCameraFrame *frame = NULL; |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_setEnable(false); |
| if (m_worklist != NULL) { |
| delete m_worklist; |
| m_worklist = NULL; |
| } |
| |
| if (m_lock != NULL) { |
| delete m_lock; |
| m_lock = NULL; |
| } |
| |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_setEnable(false); |
| m_thread->requestExitAndWait(); |
| m_setMargin(0); |
| if (m_worklist != NULL) { |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| m_worklist->popProcessQ(&frame); |
| m_delete(frame); |
| frame = NULL; |
| } |
| |
| delete m_worklist; |
| m_worklist = NULL; |
| } |
| |
| if (m_lock != NULL) { |
| delete m_lock; |
| m_lock = NULL; |
| } |
| |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| |
| return ret; |
| } |
| |
| Mutex* CreateWorker::getLock() |
| { |
| return m_lock; |
| } |
| |
| status_t CreateWorker::execute(__unused ExynosCameraFrame* inframe, ExynosCameraFrame** outframe) |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| if (m_getEnable() == false) { |
| CLOGE("ERR(%s[%d]): invalid state, Need to start Worker before execute", __FUNCTION__, __LINE__); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| return ret; |
| } |
| |
| *outframe = m_execute(); |
| if (*outframe == NULL) { |
| CLOGE("ERR(%s[%d]): m_execute is invalid (outframe = NULL)", __FUNCTION__, __LINE__); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| } |
| return ret; |
| } |
| |
| status_t CreateWorker::start() |
| { |
| if (m_worklist->getSizeOfProcessQ() > 0) { |
| CLOGD("(%s[%d]): previous worklist size(%d)", __FUNCTION__, __LINE__, m_worklist->getSizeOfProcessQ()); |
| m_worklist->release(); |
| } |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_setEnable(true); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_setEnable(true); |
| |
| if (m_thread->isRunning() == false) |
| m_thread->run(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| return 0; |
| } |
| |
| status_t CreateWorker::stop() |
| { |
| ExynosCameraFrame *frame = NULL; |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_setEnable(false); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_setEnable(false); |
| m_thread->requestExitAndWait(); |
| CLOGD("DEBUG(%s[%d]): worker stopped remove ths remained frames(%d)", __FUNCTION__, __LINE__, m_worklist->getSizeOfProcessQ()); |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| m_worklist->popProcessQ(&frame); |
| m_delete(frame); |
| frame = NULL; |
| } |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| |
| return 0; |
| } |
| |
| status_t CreateWorker::m_setMargin(int32_t numOfMargin) |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| m_numOfMargin = numOfMargin; |
| return ret; |
| } |
| |
| int32_t CreateWorker::m_getMargin() |
| { |
| return m_numOfMargin; |
| } |
| |
| |
| ExynosCameraFrame* CreateWorker::m_execute() |
| { |
| ExynosCameraFrame *frame = NULL; |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| frame = new ExynosCameraFrame(); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_worklist->popProcessQ(&frame); |
| if (frame == NULL) { |
| m_thread->run(); |
| m_worklist->waitAndPopProcessQ(&frame); |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]): getframe failed", __FUNCTION__, __LINE__); |
| } |
| |
| m_thread->run(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| return frame; |
| } |
| |
| status_t CreateWorker::m_init() |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_worklist = new frame_queue_t; |
| m_lock = new Mutex(); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_thread = new FrameManagerThread(this, static_cast<func_ptr_t_>(&CreateWorker::workerMain), "Create Frame Thread", PRIORITY_URGENT_DISPLAY); |
| m_worklist = new frame_queue_t; |
| m_lock = new Mutex(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| m_worklist = NULL; |
| m_lock = NULL; |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| bool CreateWorker::workerMain() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| bool loop = true; |
| ExynosCameraFrame *frame = NULL; |
| |
| if (m_getEnable() == false) { |
| loop = false; |
| CLOGD("DEBUG(%s[%d]): Create worker stopped delete current frame(%d)", __FUNCTION__, __LINE__, m_worklist->getSizeOfProcessQ()); |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| frame = NULL; |
| ret = m_worklist->waitAndPopProcessQ(&frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| continue; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| continue; |
| } |
| m_delete(frame); |
| } |
| |
| return loop; |
| } |
| |
| while (m_worklist->getSizeOfProcessQ() < m_getMargin()) { |
| frame = NULL; |
| frame = new ExynosCameraFrame(); |
| m_worklist->pushProcessQ(&frame); |
| } |
| |
| // HACK, 2014.10.04 |
| // This sleep is added to prevent high CPU laod as busy wating. |
| // But this sleep must be deleted. |
| usleep(1000); |
| |
| if (m_worklist->getSizeOfProcessQ() < m_getMargin() ) |
| loop = true; |
| |
| return loop; |
| |
| } |
| |
| DeleteWorker::DeleteWorker(const char* name, int cameraid, FRAMEMGR_OPER::MODE operMode):FrameWorker(name, cameraid, operMode) |
| { |
| CLOGD("DEBUG(%s): Worker CREATE(name(%s) cameraid(%d) mode(%d) ", __FUNCTION__, name, cameraid, operMode); |
| m_operMode = operMode; |
| m_init(); |
| } |
| |
| DeleteWorker::~DeleteWorker() |
| { |
| CLOGD("DEBUG(%s): Worker DELETE(name(%s) cameraid(%d) mode(%d) ", __FUNCTION__, m_name, m_cameraId, m_operMode); |
| m_deinit(); |
| } |
| |
| status_t DeleteWorker::m_deinit() |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| ExynosCameraFrame *frame = NULL; |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_setEnable(false); |
| if (m_worklist != NULL) { |
| delete m_worklist; |
| m_worklist = NULL; |
| } |
| |
| if (m_lock != NULL) { |
| delete m_lock; |
| m_lock = NULL; |
| } |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_setEnable(false); |
| m_thread->requestExitAndWait(); |
| |
| if (m_worklist != NULL) { |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| m_worklist->popProcessQ(&frame); |
| m_delete(frame); |
| } |
| |
| delete m_worklist; |
| m_worklist = NULL; |
| } |
| |
| if (m_lock != NULL) { |
| delete m_lock; |
| m_lock = NULL; |
| } |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| |
| return ret; |
| } |
| |
| Mutex* DeleteWorker::getLock() |
| { |
| return m_lock; |
| } |
| |
| status_t DeleteWorker::execute(ExynosCameraFrame* inframe, __unused ExynosCameraFrame** outframe) |
| { |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| if (m_getEnable() == false) { |
| CLOGE("ERR(%s[%d]): invalid state, Need to start Worker before execute", __FUNCTION__, __LINE__); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| return ret; |
| } |
| |
| ret = m_execute(inframe); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): m_execute is invalid ret(%d)", __FUNCTION__, __LINE__, ret); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| } |
| |
| return ret; |
| } |
| |
| status_t DeleteWorker::start() |
| { |
| if (m_worklist->getSizeOfProcessQ() > 0) { |
| CLOGD("(%s[%d]): previous worklist size(%d), clear worklist", __FUNCTION__, __LINE__, m_worklist->getSizeOfProcessQ()); |
| m_worklist->release(); |
| } |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_setEnable(true); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_setEnable(true); |
| |
| if (m_thread->isRunning() == false) |
| m_thread->run(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| return 0; |
| } |
| |
| status_t DeleteWorker::stop() |
| { |
| ExynosCameraFrame *frame = NULL; |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_setEnable(false); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_setEnable(false); |
| m_thread->requestExitAndWait(); |
| CLOGD("DEBUG(%s[%d]): worker stopped remove ths remained frames(%d)", __FUNCTION__, __LINE__, m_worklist->getSizeOfProcessQ()); |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| m_worklist->popProcessQ(&frame); |
| m_delete(frame); |
| frame = NULL; |
| } |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| |
| return 0; |
| } |
| |
| status_t DeleteWorker::m_execute(ExynosCameraFrame* frame) |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_delete(frame); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_worklist->pushProcessQ(&frame); |
| m_thread->run(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| ret = FRAMEMGR_ERRCODE::ERR; |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| return ret; |
| } |
| |
| status_t DeleteWorker::m_init() |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| m_worklist = new frame_queue_t; |
| m_lock = new Mutex(); |
| break; |
| case FRAMEMGR_OPER::SLIENT: |
| m_thread = new FrameManagerThread(this, static_cast<func_ptr_t_>(&DeleteWorker::workerMain), "Delete Frame Thread", PRIORITY_URGENT_DISPLAY); |
| m_worklist = new frame_queue_t; |
| m_lock = new Mutex(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| m_worklist = NULL; |
| m_lock = NULL; |
| ret = FRAMEMGR_ERRCODE::ERR; |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| |
| return ret; |
| } |
| |
| bool DeleteWorker::workerMain() |
| { |
| #ifdef DEBUG |
| ExynosCameraAutoTimer autoTimer(__FUNCTION__); |
| #endif |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| bool loop = true; |
| ExynosCameraFrame *frame = NULL; |
| |
| if (m_getEnable() == false) { |
| loop = false; |
| CLOGD("DEBUG(%s[%d]): Delete worker stopped delete current frame(%d)", __FUNCTION__, __LINE__, m_worklist->getSizeOfProcessQ()); |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| frame = NULL; |
| ret = m_worklist->waitAndPopProcessQ(&frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| m_delete(frame); |
| } |
| return loop; |
| } |
| |
| while (m_worklist->getSizeOfProcessQ() > 0) { |
| frame = NULL; |
| ret = m_worklist->waitAndPopProcessQ(&frame); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]):wait and pop fail, ret(%d)", __FUNCTION__, __LINE__, ret); |
| goto func_exit; |
| } |
| |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]):frame is NULL", __FUNCTION__, __LINE__); |
| goto func_exit; |
| } |
| |
| m_delete(frame); |
| } |
| func_exit: |
| |
| // HACK, 2014.10.04 |
| // This sleep is added to prevent high CPU laod as busy wating. |
| // But this sleep must be deleted. |
| usleep(2000); |
| |
| if (m_worklist->getSizeOfProcessQ() > 0) |
| loop = true; |
| |
| return loop; |
| |
| } |
| |
| ExynosCameraFrameManager::ExynosCameraFrameManager(const char* name, int cameraid, FRAMEMGR_OPER::MODE operMode, uint32_t dumpmargin, uint32_t dumpmarginCount) |
| { |
| ALOGD("DEBUG(%s): FrameManager CREATE(name(%s) cameraid(%d) mode(%d)", __FUNCTION__, name, cameraid, operMode); |
| m_cameraId = cameraid; |
| m_dumpMargin = dumpmargin; |
| m_dumpMarginCount = dumpmarginCount; |
| strncpy(m_name, name, EXYNOS_CAMERA_NAME_STR_SIZE - 1); |
| m_setOperMode(operMode); |
| m_init(); |
| } |
| |
| ExynosCameraFrameManager::~ExynosCameraFrameManager() |
| { |
| CLOGD("DEBUG(%s): FrameManager DELETE(name(%s) cameraid(%d) mode(%d)", __FUNCTION__, m_name, m_cameraId, m_operMode); |
| m_deinit(); |
| } |
| |
| ExynosCameraFrame* ExynosCameraFrameManager::createFrame(ExynosCameraParameters *param, uint32_t framecnt, uint32_t frametype) |
| { |
| return m_createFrame(param, framecnt, frametype); |
| } |
| |
| status_t ExynosCameraFrameManager::deleteFrame(ExynosCameraFrame* frame) |
| { |
| return m_deleteFrame(frame); |
| } |
| |
| status_t ExynosCameraFrameManager::setKeybox(sp<KeyBox> keybox) |
| { |
| Mutex::Autolock lock(m_stateLock); |
| m_keybox = keybox; |
| return 0; |
| } |
| |
| sp<KeyBox> ExynosCameraFrameManager::getKeybox() |
| { |
| Mutex::Autolock lock(m_stateLock); |
| return m_keybox; |
| } |
| |
| status_t ExynosCameraFrameManager::setWorker(int key, sp<FrameWorker> worker) |
| { |
| Mutex::Autolock lock(m_stateLock); |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| pair<map<uint32_t, sp<FrameWorker> >::iterator,bool> workerRet; |
| pair<map<uint32_t, Mutex*>::iterator,bool> mutexRet; |
| |
| Mutex* locker = NULL; |
| |
| iter = m_workerList.find(key); |
| if (iter != m_workerList.end()) { |
| CLOGE("ERR(%s[%d]): already worker is EXIST(%d)", __FUNCTION__, __LINE__, key); |
| } else { |
| m_setupWorkerInfo(key, worker); |
| } |
| |
| return 0; |
| } |
| |
| status_t ExynosCameraFrameManager::setOperMode(FRAMEMGR_OPER::MODE mode) |
| { |
| return m_setOperMode(mode); |
| } |
| |
| int ExynosCameraFrameManager::getOperMode() |
| { |
| return m_getOperMode(); |
| } |
| |
| status_t ExynosCameraFrameManager::m_init() |
| { |
| int ret = FRAMEMGR_ERRCODE::OK; |
| |
| m_keybox = NULL; |
| |
| m_lock = new Mutex(); |
| m_setEnable(false); |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::m_setupWorkerInfo(int key, sp<FrameWorker> worker) |
| { |
| int ret = FRAMEMGR_ERRCODE::OK; |
| pair<map<uint32_t, sp<FrameWorker> >::iterator,bool> workerRet; |
| pair<map<uint32_t, Mutex*>::iterator,bool> mutexRet; |
| Mutex* locker = NULL; |
| |
| workerRet = m_workerList.insert( pair<uint32_t, sp<FrameWorker> >(key, worker)); |
| if (workerRet.second == false) { |
| ret = FRAMEMGR_ERRCODE::ERR; |
| CLOGE("ERR(%s[%d]): work insert failed(%d)", __FUNCTION__, __LINE__, key); |
| } |
| return ret; |
| } |
| |
| sp<FrameWorker> ExynosCameraFrameManager::getWorker(int key) |
| { |
| Mutex::Autolock lock(m_stateLock); |
| sp<FrameWorker> ret; |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| |
| iter = m_workerList.find(key); |
| if (iter != m_workerList.end()) { |
| ret = iter->second; |
| } else { |
| CLOGE("ERR(%s[%d]): worker is not EXIST(%d)", __FUNCTION__, __LINE__, key); |
| ret = NULL; |
| } |
| |
| return ret; |
| } |
| |
| sp<FrameWorker> ExynosCameraFrameManager::eraseWorker(int key) |
| { |
| Mutex::Autolock lock(m_stateLock); |
| sp<FrameWorker> ret; |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| |
| iter = m_workerList.find(key); |
| if (iter != m_workerList.end()) { |
| ret = iter->second; |
| m_workerList.erase(iter); |
| } else { |
| CLOGE("ERR(%s[%d]): worker is not EXIST(%d)", __FUNCTION__, __LINE__, key); |
| ret = NULL; |
| } |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::start() |
| { |
| Mutex::Autolock lock(m_stateLock); |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| sp<FrameWorker> worker = NULL; |
| |
| if (m_getEnable() == true) { |
| CLOGD("%s(%d): frameManager already start!!", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| { |
| Mutex::Autolock _l(m_lock); |
| if (m_runningFrameList.size() > 0) { |
| CLOGD("(%s[%d]): previous runningFrameList size(%d), clear list", |
| __FUNCTION__, __LINE__, (int)m_runningFrameList.size()); |
| m_runningFrameList.clear(); |
| } |
| } |
| |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| for (iter = m_workerList.begin() ; iter != m_workerList.end() ; ++iter) { |
| worker = iter->second; |
| ret = worker->start(); |
| } |
| |
| m_setEnable(true); |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::stop() |
| { |
| Mutex::Autolock lock(m_stateLock); |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| sp<FrameWorker> worker; |
| |
| if (m_getEnable() == false) { |
| CLOGD("%s(%d): frameManager already stop!!", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| m_setEnable(false); |
| |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| for (iter = m_workerList.begin() ; iter != m_workerList.end() ; ++iter) { |
| worker = iter->second; |
| ret = worker->stop(); |
| } |
| |
| return ret; |
| } |
| |
| int ExynosCameraFrameManager::deleteAllFrame() |
| { |
| Mutex::Autolock lock(m_stateLock); |
| status_t ret = NO_ERROR; |
| ExynosCameraFrame *frame = NULL; |
| |
| if (m_getEnable() == true) { |
| CLOGE("ERR(%s[%d]): invalid state, module state enabled, state must disabled", __FUNCTION__, __LINE__); |
| return ret; |
| } |
| |
| map<uint32_t, ExynosCameraFrame*>::iterator frameIter; |
| |
| m_lock->lock(); |
| |
| int runningFrameListSize = m_runningFrameList.size(); |
| |
| if (runningFrameListSize == 0) |
| CLOGD("DEBUG(%s[%d]):No memory leak detected m_runningFrameList.size()(%d)", __FUNCTION__, __LINE__, runningFrameListSize); |
| else |
| CLOGW("WARN(%s[%d]):%d memory leak detected m_runningFrameList.size()(%d)", __FUNCTION__, __LINE__, runningFrameListSize, runningFrameListSize); |
| |
| for (frameIter = m_runningFrameList.begin() ; frameIter != m_runningFrameList.end() ;) { |
| frame = frameIter->second; |
| |
| CLOGW("WARN(%s[%d]):delete memory leak detected FrameKey(%d) HAL-FrameCnt(%d) FrameType(%u)", |
| __FUNCTION__, __LINE__, frame->getUniqueKey(), frame->getFrameCount(), frame->getFrameType()); |
| |
| m_runningFrameList.erase(frameIter++); |
| SAFE_DELETE(frame); |
| } |
| |
| m_runningFrameList.clear(); |
| |
| m_lock->unlock(); |
| |
| return ret; |
| } |
| |
| ExynosCameraFrame* ExynosCameraFrameManager::m_createFrame(ExynosCameraParameters *param, uint32_t framecnt, uint32_t frametype) |
| { |
| int ret = FRAMEMGR_ERRCODE::OK; |
| uint32_t key = 0; |
| ExynosCameraFrame *frame = NULL; |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| sp<FrameWorker> worker = NULL; |
| if (m_getEnable() == false) { |
| CLOGE("ERR(%s[%d]): module state disabled", __FUNCTION__, __LINE__); |
| return frame; |
| } |
| |
| iter = m_workerList.find(FRAMEMGR_WORKER::CREATE); |
| worker = iter->second; |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| case FRAMEMGR_OPER::SLIENT: |
| worker->execute(NULL, &frame); |
| if (frame == NULL) { |
| CLOGE("ERR(%s[%d]): Frame is NULL", __FUNCTION__, __LINE__); |
| return frame; |
| } |
| frame->setUniqueKey(m_keybox->createKey()); |
| frame->setFrameInfo(param ,framecnt, frametype); |
| ret = m_insertFrame(frame, &m_runningFrameList, m_lock); |
| if (ret < 0) { |
| CLOGE("ERR(%s[%d]): m_insertFrame is Failed ", __FUNCTION__, __LINE__); |
| return NULL; |
| } |
| m_dumpFrameMargin(); |
| break; |
| } |
| |
| return frame; |
| } |
| |
| status_t ExynosCameraFrameManager::m_deleteFrame(ExynosCameraFrame* frame) |
| { |
| int ret = FRAMEMGR_ERRCODE::OK; |
| ExynosCameraFrame* removeFrame = NULL; |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| sp<FrameWorker> worker; |
| |
| if (m_getEnable() == false) { |
| CLOGE("ERR(%s[%d]): module state disabled", __FUNCTION__, __LINE__); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| return ret; |
| } |
| |
| iter = m_workerList.find(FRAMEMGR_WORKER::DELETE); |
| worker = iter->second; |
| |
| switch (m_operMode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| case FRAMEMGR_OPER::SLIENT: |
| removeFrame = m_removeFrame(frame, &m_runningFrameList, m_lock); |
| if (removeFrame == NULL) { |
| #ifndef USE_FRAME_REFERENCE_COUNT |
| CLOGE("ERR(%s[%d]): Frame is NULL", __FUNCTION__, __LINE__); |
| #else |
| /* in case of ths USE_FRAME_REFERENCE_COUNT function */ |
| /* The frame must delete that refcount is ZERO */ |
| #endif |
| ret = FRAMEMGR_ERRCODE::ERR; |
| |
| return ret; |
| } |
| worker->execute(frame, NULL); |
| m_dumpFrameMargin(); |
| break; |
| case FRAMEMGR_OPER::NONE: |
| default: |
| ret = FRAMEMGR_ERRCODE::ERR; |
| break; |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::dump() |
| { |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| m_dumpFrame(); |
| return ret; |
| } |
| |
| void ExynosCameraFrameManager::m_dumpFrameMargin() |
| { |
| int32_t frameCount = 0; |
| static uint32_t count = 0; ; |
| |
| |
| frameCount = m_runningFrameList.size(); |
| |
| if (m_dumpMargin < frameCount) |
| { |
| count++; |
| if (count % m_dumpMarginCount == 0) { |
| CLOGW("WARN(%s[%d]):Suspect memory leak of Frame. m_dumpMargin(%d) m_dumpMarginCount(%d) m_runningFrameList.size()(%zu)", |
| __FUNCTION__, __LINE__, m_dumpMargin, m_dumpMarginCount, m_runningFrameList.size()); |
| |
| m_dumpFrame(); |
| } |
| } |
| |
| } |
| |
| status_t ExynosCameraFrameManager::m_dumpFrame() |
| { |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| map<uint32_t, ExynosCameraFrame*>::iterator frameIter; |
| ExynosCameraFrame *frame = NULL; |
| |
| m_lock->lock(); |
| CLOGD("DEBUG(%s[%d]):(%s) ++++++++++++++++++++", __FUNCTION__, __LINE__, m_name); |
| |
| CLOGD("DEBUG(%s[%d]):m_dumpMargin(%d) m_dumpMarginCount(%d) m_runningFrameList.size()(%zu)", |
| __FUNCTION__, __LINE__, m_dumpMargin, m_dumpMarginCount, m_runningFrameList.size()); |
| int testCount = 0; |
| for (frameIter = m_runningFrameList.begin() ; frameIter != m_runningFrameList.end() ; ++frameIter) { |
| frame = frameIter->second; |
| CLOGD("DEBUG(%s[%d]): RunningFrame UniqueKey(%d)", __FUNCTION__, __LINE__, frame->getUniqueKey()); |
| if (++testCount >= 5) |
| break; |
| } |
| |
| CLOGD("DEBUG(%s[%d]):(%s) ------------------------------", __FUNCTION__, __LINE__, m_name); |
| m_lock->unlock(); |
| |
| /* HACK FOR DEBUGGING : ANR DETECTION */ |
| if (m_runningFrameList.size() > 300) { |
| android_printAssert(NULL, LOG_TAG, "HACK For ANR DEBUGGING"); |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::m_deinit() |
| { |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| ExynosCameraFrame *frame = NULL; |
| sp<FrameWorker> worker; |
| |
| map<uint32_t, sp<FrameWorker> >::iterator iter; |
| for (iter = m_workerList.begin() ; iter != m_workerList.end() ; ++iter) { |
| worker = iter->second; |
| m_workerList.erase(iter++); |
| worker = NULL; |
| } |
| |
| m_workerList.clear(); |
| |
| map<uint32_t, ExynosCameraFrame*>::iterator frameIter; |
| |
| if (m_lock == NULL) { |
| CLOGE("ERR(%s[%d]): lock is NULL", __FUNCTION__, __LINE__); |
| ret = FRAMEMGR_ERRCODE::ERR; |
| return ret; |
| } |
| |
| m_lock->lock(); |
| for (frameIter = m_runningFrameList.begin() ; frameIter != m_runningFrameList.end() ;) { |
| frame = frameIter->second; |
| m_runningFrameList.erase(frameIter++); |
| delete frame; |
| frame = NULL; |
| } |
| m_runningFrameList.clear(); |
| m_lock->unlock(); |
| |
| CLOGD("DEBUG(%s[%d]): delete m_lock", __FUNCTION__, __LINE__); |
| delete m_lock; |
| m_lock = NULL; |
| |
| if (m_keybox != NULL) { |
| CLOGD("DEBUG(%s[%d]): delete m_keybox", __FUNCTION__, __LINE__); |
| m_keybox = NULL; |
| } |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::m_insertFrame(ExynosCameraFrame* frame, map<uint32_t, ExynosCameraFrame*> *list, Mutex *lock) |
| { |
| lock->lock(); |
| pair<map<uint32_t, ExynosCameraFrame*>::iterator,bool> listRet; |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| |
| listRet = list->insert( pair<uint32_t, ExynosCameraFrame*>(frame->getUniqueKey(), frame)); |
| if (listRet.second == false) { |
| ret = FRAMEMGR_ERRCODE::ERR; |
| CLOGE("ERR(%s[%d]): insertFrame fail frame already exist!! HAL frameCnt( %d ) UniqueKey ( %u ) ", __FUNCTION__, __LINE__, frame->getFrameCount(), frame->getUniqueKey()); |
| } |
| lock->unlock(); |
| return ret; |
| } |
| |
| ExynosCameraFrame* ExynosCameraFrameManager::m_removeFrame(ExynosCameraFrame* frame, map<uint32_t, ExynosCameraFrame*> *list, Mutex *lock) |
| { |
| map<uint32_t, ExynosCameraFrame*>::iterator iter; |
| pair<map<uint32_t, ExynosCameraFrame*>::iterator,bool> listRet; |
| ExynosCameraFrame *ret = NULL; |
| |
| lock->lock(); |
| iter = list->find(frame->getUniqueKey()); |
| if (iter != list->end()) { |
| ret = iter->second; |
| #ifdef USE_FRAME_REFERENCE_COUNT |
| if (ret->getRef() != 0) { |
| lock->unlock(); |
| return NULL; |
| } |
| #endif |
| list->erase( iter ); |
| } else { |
| CLOGE("ERR(%s[%d]): frame is not EXIST HAL-FrameCnt(%d) UniqueKey(%d)", __FUNCTION__, __LINE__, frame->getFrameCount(), frame->getUniqueKey()); |
| } |
| lock->unlock(); |
| |
| return ret; |
| } |
| |
| status_t ExynosCameraFrameManager::m_setOperMode(FRAMEMGR_OPER::MODE mode) |
| { |
| int32_t ret = FRAMEMGR_ERRCODE::OK; |
| switch (mode) { |
| case FRAMEMGR_OPER::ONDEMAND: |
| case FRAMEMGR_OPER::SLIENT: |
| m_operMode = mode; |
| break; |
| default: |
| m_operMode = -1; |
| ret = FRAMEMGR_ERRCODE::ERR; |
| CLOGE("ERR(%s[%d]): operMode is invalid operMode(%d)", __FUNCTION__, __LINE__, m_operMode); |
| break; |
| } |
| |
| return ret; |
| } |
| |
| int ExynosCameraFrameManager::m_getOperMode() |
| { |
| return m_operMode; |
| } |
| |
| status_t ExynosCameraFrameManager::m_setEnable(bool enable) |
| { |
| Mutex::Autolock lock(m_enableLock); |
| status_t ret = FRAMEMGR_ERRCODE::OK; |
| m_enable = enable; |
| return ret; |
| } |
| |
| bool ExynosCameraFrameManager::m_getEnable() |
| { |
| Mutex::Autolock lock(m_enableLock); |
| return m_enable; |
| } |
| |
| |
| |
| |
| //************FrameManager END *************************// |
| |
| |
| |
| |
| }; /* namespace android */ |