/* * Copyright (C) Texas Instruments - http://www.ti.com/ * * 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. */ /** * @file CameraHalUtilClasses.cpp * * This file maps the CameraHardwareInterface to the Camera interfaces on OMAP4 (mainly OMX). * */ #include "CameraHal.h" namespace Ti { namespace Camera { /*--------------------FrameProvider Class STARTS here-----------------------------*/ int FrameProvider::enableFrameNotification(int32_t frameTypes) { LOG_FUNCTION_NAME; status_t ret = NO_ERROR; ///Enable the frame notification to CameraAdapter (which implements FrameNotifier interface) mFrameNotifier->enableMsgType(frameTypes<<MessageNotifier::FRAME_BIT_FIELD_POSITION , mFrameCallback , NULL , mCookie ); LOG_FUNCTION_NAME_EXIT; return ret; } int FrameProvider::disableFrameNotification(int32_t frameTypes) { LOG_FUNCTION_NAME; status_t ret = NO_ERROR; mFrameNotifier->disableMsgType(frameTypes<<MessageNotifier::FRAME_BIT_FIELD_POSITION , mCookie ); LOG_FUNCTION_NAME_EXIT; return ret; } int FrameProvider::returnFrame(CameraBuffer *frameBuf, CameraFrame::FrameType frameType) { status_t ret = NO_ERROR; mFrameNotifier->returnFrame(frameBuf, frameType); return ret; } void FrameProvider::addFramePointers(CameraBuffer *frameBuf, void *buf) { mFrameNotifier->addFramePointers(frameBuf, buf); return; } void FrameProvider::removeFramePointers() { mFrameNotifier->removeFramePointers(); return; } /*--------------------FrameProvider Class ENDS here-----------------------------*/ /*--------------------EventProvider Class STARTS here-----------------------------*/ int EventProvider::enableEventNotification(int32_t frameTypes) { LOG_FUNCTION_NAME; status_t ret = NO_ERROR; ///Enable the frame notification to CameraAdapter (which implements FrameNotifier interface) mEventNotifier->enableMsgType(frameTypes<<MessageNotifier::EVENT_BIT_FIELD_POSITION , NULL , mEventCallback , mCookie ); LOG_FUNCTION_NAME_EXIT; return ret; } int EventProvider::disableEventNotification(int32_t frameTypes) { LOG_FUNCTION_NAME; status_t ret = NO_ERROR; mEventNotifier->disableMsgType(frameTypes<<MessageNotifier::EVENT_BIT_FIELD_POSITION , mCookie ); LOG_FUNCTION_NAME_EXIT; return ret; } /*--------------------EventProvider Class ENDS here-----------------------------*/ /*--------------------CameraArea Class STARTS here-----------------------------*/ status_t CameraArea::transfrom(size_t width, size_t height, size_t &top, size_t &left, size_t &areaWidth, size_t &areaHeight) { status_t ret = NO_ERROR; size_t hRange, vRange; double hScale, vScale; LOG_FUNCTION_NAME hRange = CameraArea::RIGHT - CameraArea::LEFT; vRange = CameraArea::BOTTOM - CameraArea::TOP; hScale = ( double ) width / ( double ) hRange; vScale = ( double ) height / ( double ) vRange; top = ( mTop + vRange / 2 ) * vScale; left = ( mLeft + hRange / 2 ) * hScale; areaHeight = ( mBottom + vRange / 2 ) * vScale; areaHeight -= top; areaWidth = ( mRight + hRange / 2) * hScale; areaWidth -= left; LOG_FUNCTION_NAME_EXIT return ret; } status_t CameraArea::checkArea(ssize_t top, ssize_t left, ssize_t bottom, ssize_t right, ssize_t weight) { //Handles the invalid regin corner case. if ( ( 0 == top ) && ( 0 == left ) && ( 0 == bottom ) && ( 0 == right ) && ( 0 == weight ) ) { return NO_ERROR; } if ( ( CameraArea::WEIGHT_MIN > weight ) || ( CameraArea::WEIGHT_MAX < weight ) ) { CAMHAL_LOGEB("Camera area weight is invalid %d", weight); return -EINVAL; } if ( ( CameraArea::TOP > top ) || ( CameraArea::BOTTOM < top ) ) { CAMHAL_LOGEB("Camera area top coordinate is invalid %d", top ); return -EINVAL; } if ( ( CameraArea::TOP > bottom ) || ( CameraArea::BOTTOM < bottom ) ) { CAMHAL_LOGEB("Camera area bottom coordinate is invalid %d", bottom ); return -EINVAL; } if ( ( CameraArea::LEFT > left ) || ( CameraArea::RIGHT < left ) ) { CAMHAL_LOGEB("Camera area left coordinate is invalid %d", left ); return -EINVAL; } if ( ( CameraArea::LEFT > right ) || ( CameraArea::RIGHT < right ) ) { CAMHAL_LOGEB("Camera area right coordinate is invalid %d", right ); return -EINVAL; } if ( left >= right ) { CAMHAL_LOGEA("Camera area left larger than right"); return -EINVAL; } if ( top >= bottom ) { CAMHAL_LOGEA("Camera area top larger than bottom"); return -EINVAL; } return NO_ERROR; } status_t CameraArea::parseAreas(const char *area, size_t areaLength, android::Vector<android::sp<CameraArea> > &areas) { status_t ret = NO_ERROR; char *ctx; char *pArea = NULL; char *pStart = NULL; char *pEnd = NULL; const char *startToken = "("; const char endToken = ')'; const char sep = ','; ssize_t top, left, bottom, right, weight; char *tmpBuffer = NULL; android::sp<CameraArea> currentArea; LOG_FUNCTION_NAME if ( ( NULL == area ) || ( 0 >= areaLength ) ) { return -EINVAL; } tmpBuffer = ( char * ) malloc(areaLength); if ( NULL == tmpBuffer ) { return -ENOMEM; } memcpy(tmpBuffer, area, areaLength); pArea = strtok_r(tmpBuffer, startToken, &ctx); do { pStart = pArea; if ( NULL == pStart ) { CAMHAL_LOGEA("Parsing of the left area coordinate failed!"); ret = -EINVAL; break; } else { left = static_cast<ssize_t>(strtol(pStart, &pEnd, 10)); } if ( sep != *pEnd ) { CAMHAL_LOGEA("Parsing of the top area coordinate failed!"); ret = -EINVAL; break; } else { top = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10)); } if ( sep != *pEnd ) { CAMHAL_LOGEA("Parsing of the right area coordinate failed!"); ret = -EINVAL; break; } else { right = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10)); } if ( sep != *pEnd ) { CAMHAL_LOGEA("Parsing of the bottom area coordinate failed!"); ret = -EINVAL; break; } else { bottom = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10)); } if ( sep != *pEnd ) { CAMHAL_LOGEA("Parsing of the weight area coordinate failed!"); ret = -EINVAL; break; } else { weight = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10)); } if ( endToken != *pEnd ) { CAMHAL_LOGEA("Malformed area!"); ret = -EINVAL; break; } ret = checkArea(top, left, bottom, right, weight); if ( NO_ERROR != ret ) { break; } currentArea = new CameraArea(top, left, bottom, right, weight); CAMHAL_LOGDB("Area parsed [%dx%d, %dx%d] %d", ( int ) top, ( int ) left, ( int ) bottom, ( int ) right, ( int ) weight); if ( NULL != currentArea.get() ) { areas.add(currentArea); } else { ret = -ENOMEM; break; } pArea = strtok_r(NULL, startToken, &ctx); } while ( NULL != pArea ); if ( NULL != tmpBuffer ) { free(tmpBuffer); } LOG_FUNCTION_NAME_EXIT return ret; } bool CameraArea::areAreasDifferent(android::Vector< android::sp<CameraArea> > &area1, android::Vector< android::sp<CameraArea> > &area2) { if (area1.size() != area2.size()) { return true; } // not going to care about sorting order for now for (int i = 0; i < area1.size(); i++) { if (!area1.itemAt(i)->compare(area2.itemAt(i))) { return true; } } return false; } bool CameraArea::compare(const android::sp<CameraArea> &area) { return ((mTop == area->mTop) && (mLeft == area->mLeft) && (mBottom == area->mBottom) && (mRight == area->mRight) && (mWeight == area->mWeight)); } /*--------------------CameraArea Class ENDS here-----------------------------*/ } // namespace Camera } // namespace Ti