Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2015, The Linux Foundataion. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 #define ATRACE_TAG ATRACE_TAG_CAMERA
     30 #define MEMLOG_THRESH 102400
     31 #define LOG_TAG "QCameraHWI_Mem"
     32 
     33 #include <string.h>
     34 #include <fcntl.h>
     35 #include <sys/mman.h>
     36 #include <utils/Errors.h>
     37 #include <utils/Trace.h>
     38 #include <utils/Log.h>
     39 #include <gralloc_priv.h>
     40 #include <media/hardware/HardwareAPI.h>
     41 #include "QCamera2HWI.h"
     42 #include "QCameraMem.h"
     43 #include "QCameraParameters.h"
     44 
     45 extern "C" {
     46 #include <mm_camera_interface.h>
     47 }
     48 
     49 using namespace android;
     50 
     51 namespace qcamera {
     52 
     53 // QCaemra2Memory base class
     54 
     55 /*===========================================================================
     56  * FUNCTION   : QCameraMemory
     57  *
     58  * DESCRIPTION: default constructor of QCameraMemory
     59  *
     60  * PARAMETERS :
     61  *   @cached  : flag indicates if using cached memory
     62  *
     63  * RETURN     : None
     64  *==========================================================================*/
     65 QCameraMemory::QCameraMemory(bool cached,
     66         QCameraMemoryPool *pool,
     67         cam_stream_type_t streamType, cam_stream_buf_type bufType)
     68     :m_bCached(cached),
     69      mMemoryPool(pool),
     70      mStreamType(streamType),
     71      mBufType(bufType)
     72 {
     73     mBufferCount = 0;
     74     reset();
     75 }
     76 
     77 /*===========================================================================
     78  * FUNCTION   : ~QCameraMemory
     79  *
     80  * DESCRIPTION: deconstructor of QCameraMemory
     81  *
     82  * PARAMETERS : none
     83  *
     84  * RETURN     : None
     85  *==========================================================================*/
     86 QCameraMemory::~QCameraMemory()
     87 {
     88 }
     89 
     90 /*===========================================================================
     91  * FUNCTION   : cacheOpsInternal
     92  *
     93  * DESCRIPTION: ion related memory cache operations
     94  *
     95  * PARAMETERS :
     96  *   @index   : index of the buffer
     97  *   @cmd     : cache ops command
     98  *   @vaddr   : ptr to the virtual address
     99  *
    100  * RETURN     : int32_t type of status
    101  *              NO_ERROR  -- success
    102  *              none-zero failure code
    103  *==========================================================================*/
    104 int QCameraMemory::cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr)
    105 {
    106     if (!m_bCached) {
    107         // Memory is not cached, no need for cache ops
    108         CDBG("%s: No cache ops here for uncached memory", __func__);
    109         return OK;
    110     }
    111 
    112     struct ion_flush_data cache_inv_data;
    113     struct ion_custom_data custom_data;
    114     int ret = OK;
    115 
    116     if (index >= mBufferCount) {
    117         ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount);
    118         return BAD_INDEX;
    119     }
    120 
    121     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
    122     memset(&custom_data, 0, sizeof(custom_data));
    123     cache_inv_data.vaddr = vaddr;
    124     cache_inv_data.fd = mMemInfo[index].fd;
    125     cache_inv_data.handle = mMemInfo[index].handle;
    126     cache_inv_data.length =
    127             ( /* FIXME: Should remove this after ION interface changes */ unsigned int)
    128             mMemInfo[index].size;
    129     custom_data.cmd = cmd;
    130     custom_data.arg = (unsigned long)&cache_inv_data;
    131 
    132     CDBG_HIGH("%s: addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
    133          __func__, cache_inv_data.vaddr, cache_inv_data.fd,
    134          (unsigned long)cache_inv_data.handle, cache_inv_data.length,
    135          mMemInfo[index].main_ion_fd);
    136     ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
    137     if (ret < 0)
    138         ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
    139 
    140     return ret;
    141 }
    142 
    143 /*===========================================================================
    144  * FUNCTION   : getFd
    145  *
    146  * DESCRIPTION: return file descriptor of the indexed buffer
    147  *
    148  * PARAMETERS :
    149  *   @index   : index of the buffer
    150  *
    151  * RETURN     : file descriptor
    152  *==========================================================================*/
    153 int QCameraMemory::getFd(uint32_t index) const
    154 {
    155     if (index >= mBufferCount)
    156         return BAD_INDEX;
    157 
    158     return mMemInfo[index].fd;
    159 }
    160 
    161 /*===========================================================================
    162  * FUNCTION   : getSize
    163  *
    164  * DESCRIPTION: return buffer size of the indexed buffer
    165  *
    166  * PARAMETERS :
    167  *   @index   : index of the buffer
    168  *
    169  * RETURN     : buffer size
    170  *==========================================================================*/
    171 ssize_t QCameraMemory::getSize(uint32_t index) const
    172 {
    173     if (index >= mBufferCount)
    174         return BAD_INDEX;
    175 
    176     return (ssize_t)mMemInfo[index].size;
    177 }
    178 
    179 /*===========================================================================
    180  * FUNCTION   : getCnt
    181  *
    182  * DESCRIPTION: query number of buffers allocated
    183  *
    184  * PARAMETERS : none
    185  *
    186  * RETURN     : number of buffers allocated
    187  *==========================================================================*/
    188 uint8_t QCameraMemory::getCnt() const
    189 {
    190     return mBufferCount;
    191 }
    192 
    193 /*===========================================================================
    194  * FUNCTION   : reset
    195  *
    196  * DESCRIPTION: reset member variables
    197  *
    198  * PARAMETERS : none
    199  *
    200  * RETURN     : none
    201  *==========================================================================*/
    202 void QCameraMemory::reset()
    203 {
    204     size_t i, count;
    205 
    206     memset(mMemInfo, 0, sizeof(mMemInfo));
    207 
    208     count = sizeof(mMemInfo) / sizeof(mMemInfo[0]);
    209     for (i = 0; i < count; i++) {
    210         mMemInfo[i].fd = -1;
    211         mMemInfo[i].main_ion_fd = -1;
    212     }
    213 
    214     return;
    215 }
    216 
    217 /*===========================================================================
    218  * FUNCTION   : getBufDef
    219  *
    220  * DESCRIPTION: query detailed buffer information
    221  *
    222  * PARAMETERS :
    223  *   @offset  : [input] frame buffer offset
    224  *   @bufDef  : [output] reference to struct to store buffer definition
    225  *   @index   : [input] index of the buffer
    226  *
    227  * RETURN     : none
    228  *==========================================================================*/
    229 void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset,
    230         mm_camera_buf_def_t &bufDef, uint32_t index) const
    231 {
    232     if (!mBufferCount) {
    233         ALOGE("Memory not allocated");
    234         return;
    235     }
    236     bufDef.fd = mMemInfo[index].fd;
    237     bufDef.buf_type = CAM_STREAM_BUF_TYPE_MPLANE;
    238     bufDef.frame_len = offset.frame_len;
    239     bufDef.mem_info = (void *)this;
    240     bufDef.planes_buf.num_planes = (int8_t)offset.num_planes;
    241     bufDef.buffer = getPtr(index);
    242     bufDef.buf_idx = index;
    243 
    244     /* Plane 0 needs to be set separately. Set other planes in a loop */
    245     bufDef.planes_buf.planes[0].length = offset.mp[0].len;
    246     bufDef.planes_buf.planes[0].m.userptr = (long unsigned int)mMemInfo[index].fd;
    247     bufDef.planes_buf.planes[0].data_offset = offset.mp[0].offset;
    248     bufDef.planes_buf.planes[0].reserved[0] = 0;
    249     for (int i = 1; i < bufDef.planes_buf.num_planes; i++) {
    250          bufDef.planes_buf.planes[i].length = offset.mp[i].len;
    251          bufDef.planes_buf.planes[i].m.userptr = (long unsigned int)mMemInfo[i].fd;
    252          bufDef.planes_buf.planes[i].data_offset = offset.mp[i].offset;
    253          bufDef.planes_buf.planes[i].reserved[0] =
    254                  bufDef.planes_buf.planes[i-1].reserved[0] +
    255                  bufDef.planes_buf.planes[i-1].length;
    256     }
    257 }
    258 
    259 /*===========================================================================
    260  * FUNCTION   : getUserBufDef
    261  *
    262  * DESCRIPTION: Fill Buffer structure with user buffer information
    263                            This also fills individual stream buffers inside batch baffer strcuture
    264  *
    265  * PARAMETERS :
    266  *   @buf_info : user buffer information
    267  *   @bufDef  : Buffer strcuture to fill user buf info
    268  *   @index   : index of the buffer
    269  *   @plane_offset : plane buffer information
    270  *   @planeBufDef  : [input] frame buffer offset
    271  *   @bufs    : Stream Buffer object
    272  *
    273  * RETURN     : int32_t type of status
    274  *              NO_ERROR  -- success
    275  *              none-zero failure code
    276  *==========================================================================*/
    277 int32_t QCameraMemory::getUserBufDef(const cam_stream_user_buf_info_t &buf_info,
    278         mm_camera_buf_def_t &bufDef,
    279         uint32_t index,
    280         const cam_frame_len_offset_t &plane_offset,
    281         mm_camera_buf_def_t *planeBufDef,
    282         QCameraMemory *bufs) const
    283 {
    284     struct msm_camera_user_buf_cont_t *cont_buf = NULL;
    285     uint32_t plane_idx = (index * buf_info.frame_buf_cnt);
    286 
    287     if (!mBufferCount) {
    288         ALOGE("Memory not allocated");
    289         return INVALID_OPERATION;
    290     }
    291 
    292     for (int count = 0; count < mBufferCount; count++) {
    293         bufDef.fd = mMemInfo[count].fd;
    294         bufDef.buf_type = CAM_STREAM_BUF_TYPE_USERPTR;
    295         bufDef.frame_len = buf_info.size;
    296         bufDef.mem_info = (void *)this;
    297         bufDef.buffer = (void *)((uint8_t *)getPtr(count)
    298                 + (index * buf_info.size));
    299         bufDef.buf_idx = index;
    300         bufDef.user_buf.num_buffers = (int8_t)buf_info.frame_buf_cnt;
    301         bufDef.user_buf.bufs_used = (int8_t)buf_info.frame_buf_cnt;
    302 
    303         //Individual plane buffer structure to be filled
    304         cont_buf = (struct msm_camera_user_buf_cont_t *)bufDef.buffer;
    305         cont_buf->buf_cnt = bufDef.user_buf.num_buffers;
    306 
    307         for (int i = 0; i < bufDef.user_buf.num_buffers; i++) {
    308             bufs->getBufDef(plane_offset, planeBufDef[plane_idx], plane_idx);
    309             bufDef.user_buf.buf_idx[i] = -1;
    310             cont_buf->buf_idx[i] = planeBufDef[plane_idx].buf_idx;
    311             plane_idx++;
    312         }
    313         bufDef.user_buf.plane_buf = planeBufDef;
    314 
    315         CDBG("%s: num_buf = %d index = %d plane_idx = %d",
    316                 __func__, bufDef.user_buf.num_buffers, index, plane_idx);
    317     }
    318     return NO_ERROR;
    319 }
    320 
    321 
    322 /*===========================================================================
    323  * FUNCTION   : traceLogAllocStart
    324  *
    325  * DESCRIPTION: query detailed buffer information
    326  *
    327  * PARAMETERS :
    328  *   @size  : [input] alloc
    329  *   @count  : [input] number of buffers
    330  *   @allocName   : [input] name for the alloc
    331  *
    332  * RETURN     : none
    333  *==========================================================================*/
    334 inline void QCameraMemory::traceLogAllocStart(size_t size, int count, const char *allocName)
    335 {
    336     ALOGD("%s : alloc E count=%d size=%zu", __func__, count, size);
    337 #ifdef ATRACE_TAG_CAMERA
    338     char atracer[30];
    339     if ((size * (size_t)count) > MEMLOG_THRESH) {
    340         snprintf(atracer,sizeof(atracer), "%s %zu",allocName, size);
    341         ATRACE_BEGIN(atracer);
    342         ALOGE("%s:%s", __func__, atracer);
    343     } else {
    344         ATRACE_CALL();
    345     }
    346 #endif
    347 }
    348 
    349 /*===========================================================================
    350  * FUNCTION   : traceLogAllocEnd
    351  *
    352  * DESCRIPTION: query detailed buffer information
    353  *
    354  * PARAMETERS :
    355  *   @size  : [input] alloc
    356  *   @count  : [input] number of buffers
    357  *
    358  * RETURN     : none
    359  *==========================================================================*/
    360 inline void QCameraMemory::traceLogAllocEnd(size_t size)
    361 {
    362     ALOGD(" %s : X", __func__);
    363 #ifdef ATRACE_TAG_CAMERA
    364     if (size > MEMLOG_THRESH) {
    365         ATRACE_END();
    366         ALOGE("%s %zu", __func__, size);
    367     }
    368 #endif
    369 }
    370 
    371 /*===========================================================================
    372  * FUNCTION   : alloc
    373  *
    374  * DESCRIPTION: allocate requested number of buffers of certain size
    375  *
    376  * PARAMETERS :
    377  *   @count   : number of buffers to be allocated
    378  *   @size    : lenght of the buffer to be allocated
    379  *   @heap_id : heap id to indicate where the buffers will be allocated from
    380  *
    381  * RETURN     : int32_t type of status
    382  *              NO_ERROR  -- success
    383  *              none-zero failure code
    384  *==========================================================================*/
    385 int QCameraMemory::alloc(int count, size_t size, unsigned int heap_id,
    386         uint32_t secure_mode)
    387 {
    388     int rc = OK;
    389 
    390     int new_bufCnt = mBufferCount + count;
    391     traceLogAllocStart(size, count, "Memsize");
    392 
    393     if (new_bufCnt > MM_CAMERA_MAX_NUM_FRAMES) {
    394         ALOGE("%s: Buffer count %d out of bound. Max is %d",
    395               __func__, new_bufCnt, MM_CAMERA_MAX_NUM_FRAMES);
    396         return BAD_INDEX;
    397     }
    398 
    399     for (int i = mBufferCount; i < new_bufCnt; i ++) {
    400         if ( NULL == mMemoryPool ) {
    401             CDBG_HIGH("%s : No memory pool available, allocating now", __func__);
    402             rc = allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached,
    403                      secure_mode);
    404             if (rc < 0) {
    405                 ALOGE("%s: AllocateIonMemory failed", __func__);
    406                 for (int j = i-1; j >= 0; j--)
    407                     deallocOneBuffer(mMemInfo[j]);
    408                 break;
    409             }
    410         } else {
    411             rc = mMemoryPool->allocateBuffer(mMemInfo[i],
    412                                              heap_id,
    413                                              size,
    414                                              m_bCached,
    415                                              mStreamType,
    416                                              secure_mode);
    417             if (rc < 0) {
    418                 ALOGE("%s: Memory pool allocation failed", __func__);
    419                 for (int j = i-1; j >= 0; j--)
    420                     mMemoryPool->releaseBuffer(mMemInfo[j],
    421                                                mStreamType);
    422                 break;
    423             }
    424         }
    425 
    426     }
    427     traceLogAllocEnd (size * (size_t)count);
    428     return rc;
    429 }
    430 
    431 /*===========================================================================
    432  * FUNCTION   : dealloc
    433  *
    434  * DESCRIPTION: deallocate buffers
    435  *
    436  * PARAMETERS : none
    437  *
    438  * RETURN     : none
    439  *==========================================================================*/
    440 void QCameraMemory::dealloc()
    441 {
    442     for (int i = 0; i < mBufferCount; i++) {
    443         if ( NULL == mMemoryPool ) {
    444             deallocOneBuffer(mMemInfo[i]);
    445         } else {
    446             mMemoryPool->releaseBuffer(mMemInfo[i], mStreamType);
    447         }
    448     }
    449 }
    450 
    451 /*===========================================================================
    452  * FUNCTION   : allocOneBuffer
    453  *
    454  * DESCRIPTION: impl of allocating one buffers of certain size
    455  *
    456  * PARAMETERS :
    457  *   @memInfo : [output] reference to struct to store additional memory allocation info
    458  *   @heap    : [input] heap id to indicate where the buffers will be allocated from
    459  *   @size    : [input] lenght of the buffer to be allocated
    460  *   @cached  : [input] flag whether buffer needs to be cached
    461  *
    462  * RETURN     : int32_t type of status
    463  *              NO_ERROR  -- success
    464  *              none-zero failure code
    465  *==========================================================================*/
    466 int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo,
    467         unsigned int heap_id, size_t size, bool cached, uint32_t secure_mode)
    468 {
    469     int rc = OK;
    470     struct ion_handle_data handle_data;
    471     struct ion_allocation_data alloc;
    472     struct ion_fd_data ion_info_fd;
    473     int main_ion_fd = -1;
    474 
    475     main_ion_fd = open("/dev/ion", O_RDONLY);
    476     if (main_ion_fd < 0) {
    477         ALOGE("Ion dev open failed: %s\n", strerror(errno));
    478         goto ION_OPEN_FAILED;
    479     }
    480 
    481     memset(&alloc, 0, sizeof(alloc));
    482     alloc.len = size;
    483     /* to make it page size aligned */
    484     alloc.len = (alloc.len + 4095U) & (~4095U);
    485     alloc.align = 4096;
    486     if (cached) {
    487         alloc.flags = ION_FLAG_CACHED;
    488     }
    489     alloc.heap_id_mask = heap_id;
    490     if (secure_mode == SECURE) {
    491         ALOGD("%s: Allocate secure buffer\n", __func__);
    492         alloc.flags = ION_SECURE;
    493         alloc.heap_id_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
    494         alloc.align = 1048576; // 1 MiB alignment to be able to protect later
    495         alloc.len = (alloc.len + 1048575U) & (~1048575U);
    496     }
    497 
    498     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
    499     if (rc < 0) {
    500         ALOGE("ION allocation failed: %s\n", strerror(errno));
    501         goto ION_ALLOC_FAILED;
    502     }
    503 
    504     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    505     ion_info_fd.handle = alloc.handle;
    506     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
    507     if (rc < 0) {
    508         ALOGE("ION map failed %s\n", strerror(errno));
    509         goto ION_MAP_FAILED;
    510     }
    511 
    512     memInfo.main_ion_fd = main_ion_fd;
    513     memInfo.fd = ion_info_fd.fd;
    514     memInfo.handle = ion_info_fd.handle;
    515     memInfo.size = alloc.len;
    516     memInfo.cached = cached;
    517     memInfo.heap_id = heap_id;
    518 
    519     ALOGD("%s : ION buffer %lx with size %d allocated",
    520                 __func__, (unsigned long)memInfo.handle, alloc.len);
    521     return OK;
    522 
    523 ION_MAP_FAILED:
    524     memset(&handle_data, 0, sizeof(handle_data));
    525     handle_data.handle = ion_info_fd.handle;
    526     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
    527 ION_ALLOC_FAILED:
    528     close(main_ion_fd);
    529 ION_OPEN_FAILED:
    530     return NO_MEMORY;
    531 }
    532 
    533 /*===========================================================================
    534  * FUNCTION   : deallocOneBuffer
    535  *
    536  * DESCRIPTION: impl of deallocating one buffers
    537  *
    538  * PARAMETERS :
    539  *   @memInfo : reference to struct that stores additional memory allocation info
    540  *
    541  * RETURN     : none
    542  *==========================================================================*/
    543 void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo)
    544 {
    545     struct ion_handle_data handle_data;
    546 
    547     if (memInfo.fd >= 0) {
    548         close(memInfo.fd);
    549         memInfo.fd = -1;
    550     }
    551 
    552     if (memInfo.main_ion_fd >= 0) {
    553         memset(&handle_data, 0, sizeof(handle_data));
    554         handle_data.handle = memInfo.handle;
    555         ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
    556         close(memInfo.main_ion_fd);
    557         memInfo.main_ion_fd = -1;
    558     }
    559     memInfo.handle = 0;
    560     memInfo.size = 0;
    561 }
    562 
    563 /*===========================================================================
    564  * FUNCTION   : QCameraMemoryPool
    565  *
    566  * DESCRIPTION: default constructor of QCameraMemoryPool
    567  *
    568  * PARAMETERS : None
    569  *
    570  * RETURN     : None
    571  *==========================================================================*/
    572 QCameraMemoryPool::QCameraMemoryPool()
    573 {
    574     pthread_mutex_init(&mLock, NULL);
    575 }
    576 
    577 
    578 /*===========================================================================
    579  * FUNCTION   : ~QCameraMemoryPool
    580  *
    581  * DESCRIPTION: deconstructor of QCameraMemoryPool
    582  *
    583  * PARAMETERS : None
    584  *
    585  * RETURN     : None
    586  *==========================================================================*/
    587 QCameraMemoryPool::~QCameraMemoryPool()
    588 {
    589     clear();
    590     pthread_mutex_destroy(&mLock);
    591 }
    592 
    593 /*===========================================================================
    594  * FUNCTION   : releaseBuffer
    595  *
    596  * DESCRIPTION: release one cached buffers
    597  *
    598  * PARAMETERS :
    599  *   @memInfo : reference to struct that stores additional memory allocation info
    600  *   @streamType: Type of stream the buffers belongs to
    601  *
    602  * RETURN     : none
    603  *==========================================================================*/
    604 void QCameraMemoryPool::releaseBuffer(
    605         struct QCameraMemory::QCameraMemInfo &memInfo,
    606         cam_stream_type_t streamType)
    607 {
    608     pthread_mutex_lock(&mLock);
    609 
    610     mPools[streamType].push_back(memInfo);
    611 
    612     pthread_mutex_unlock(&mLock);
    613 }
    614 
    615 /*===========================================================================
    616  * FUNCTION   : clear
    617  *
    618  * DESCRIPTION: clears all cached buffers
    619  *
    620  * PARAMETERS : none
    621  *
    622  * RETURN     : none
    623  *==========================================================================*/
    624 void QCameraMemoryPool::clear()
    625 {
    626     pthread_mutex_lock(&mLock);
    627 
    628     for (int i = CAM_STREAM_TYPE_DEFAULT; i < CAM_STREAM_TYPE_MAX; i++ ) {
    629         List<struct QCameraMemory::QCameraMemInfo>::iterator it;
    630         it = mPools[i].begin();
    631         for( ; it != mPools[i].end() ; it++) {
    632             QCameraMemory::deallocOneBuffer(*it);
    633         }
    634 
    635         mPools[i].clear();
    636     }
    637 
    638     pthread_mutex_unlock(&mLock);
    639 }
    640 
    641 /*===========================================================================
    642  * FUNCTION   : findBufferLocked
    643  *
    644  * DESCRIPTION: search for a appropriate cached buffer
    645  *
    646  * PARAMETERS :
    647  *   @memInfo : reference to struct that stores additional memory allocation info
    648  *   @heap_id : type of heap
    649  *   @size    : size of the buffer
    650  *   @cached  : whether the buffer should be cached
    651  *   @streaType: type of stream this buffer belongs to
    652  *
    653  * RETURN     : int32_t type of status
    654  *              NO_ERROR  -- success
    655  *              none-zero failure code
    656  *==========================================================================*/
    657 int QCameraMemoryPool::findBufferLocked(
    658         struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id,
    659         size_t size, bool cached, cam_stream_type_t streamType)
    660 {
    661     int rc = NAME_NOT_FOUND;
    662 
    663     if (mPools[streamType].empty()) {
    664         return NAME_NOT_FOUND;
    665     }
    666 
    667     List<struct QCameraMemory::QCameraMemInfo>::iterator it;
    668     it = mPools[streamType].begin();
    669     for ( ; it != mPools[streamType].end() ; it++) {
    670         if ( ((*it).size >= size) &&
    671             ((*it).heap_id == heap_id) &&
    672             ((*it).cached == cached) ) {
    673             memInfo = *it;
    674             mPools[streamType].erase(it);
    675             rc = NO_ERROR;
    676             break;
    677         }
    678     }
    679 
    680     return rc;
    681 }
    682 
    683 /*===========================================================================
    684  * FUNCTION   : allocateBuffer
    685  *
    686  * DESCRIPTION: allocates a buffer from the memory pool,
    687  *              it will re-use cached buffers if possible
    688  *
    689  * PARAMETERS :
    690  *   @memInfo : reference to struct that stores additional memory allocation info
    691  *   @heap_id : type of heap
    692  *   @size    : size of the buffer
    693  *   @cached  : whether the buffer should be cached
    694  *   @streaType: type of stream this buffer belongs to
    695  *
    696  * RETURN     : int32_t type of status
    697  *              NO_ERROR  -- success
    698  *              none-zero failure code
    699  *==========================================================================*/
    700 int QCameraMemoryPool::allocateBuffer(
    701         struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id,
    702         size_t size, bool cached, cam_stream_type_t streamType,
    703         uint32_t secure_mode)
    704 {
    705     int rc = NO_ERROR;
    706 
    707     pthread_mutex_lock(&mLock);
    708 
    709     rc = findBufferLocked(memInfo, heap_id, size, cached, streamType);
    710     if (NAME_NOT_FOUND == rc ) {
    711         CDBG_HIGH("%s : Buffer not found!", __func__);
    712         rc = QCameraMemory::allocOneBuffer(memInfo, heap_id, size, cached,
    713                  secure_mode);
    714     }
    715 
    716     pthread_mutex_unlock(&mLock);
    717 
    718     return rc;
    719 }
    720 
    721 /*===========================================================================
    722  * FUNCTION   : QCameraHeapMemory
    723  *
    724  * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL
    725  *
    726  * PARAMETERS :
    727  *   @cached  : flag indicates if using cached memory
    728  *
    729  * RETURN     : none
    730  *==========================================================================*/
    731 QCameraHeapMemory::QCameraHeapMemory(bool cached)
    732     : QCameraMemory(cached)
    733 {
    734     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
    735         mPtr[i] = NULL;
    736 }
    737 
    738 /*===========================================================================
    739  * FUNCTION   : ~QCameraHeapMemory
    740  *
    741  * DESCRIPTION: deconstructor of QCameraHeapMemory
    742  *
    743  * PARAMETERS : none
    744  *
    745  * RETURN     : none
    746  *==========================================================================*/
    747 QCameraHeapMemory::~QCameraHeapMemory()
    748 {
    749 }
    750 
    751 /*===========================================================================
    752  * FUNCTION   : getPtr
    753  *
    754  * DESCRIPTION: return buffer pointer
    755  *
    756  * PARAMETERS :
    757  *   @index   : index of the buffer
    758  *
    759  * RETURN     : buffer ptr
    760  *==========================================================================*/
    761 void *QCameraHeapMemory::getPtr(uint32_t index) const
    762 {
    763     if (index >= mBufferCount) {
    764         ALOGE("index out of bound");
    765         return (void *)BAD_INDEX;
    766     }
    767     return mPtr[index];
    768 }
    769 
    770 /*===========================================================================
    771  * FUNCTION   : allocate
    772  *
    773  * DESCRIPTION: allocate requested number of buffers of certain size
    774  *
    775  * PARAMETERS :
    776  *   @count   : number of buffers to be allocated
    777  *   @size    : lenght of the buffer to be allocated
    778  *
    779  * RETURN     : int32_t type of status
    780  *              NO_ERROR  -- success
    781  *              none-zero failure code
    782  *==========================================================================*/
    783 int QCameraHeapMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
    784 {
    785     int rc = -1;
    786     traceLogAllocStart(size, count, "HeapMemsize");
    787     uint32_t heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
    788     if (isSecure == SECURE) {
    789         rc = alloc(count, size, heap_id_mask, SECURE);
    790         if (rc < 0)
    791             return rc;
    792     } else {
    793         rc = alloc(count, size, heap_id_mask, NON_SECURE);
    794         if (rc < 0)
    795             return rc;
    796 
    797         for (int i = 0; i < count; i ++) {
    798             void *vaddr = mmap(NULL,
    799                         mMemInfo[i].size,
    800                         PROT_READ | PROT_WRITE,
    801                         MAP_SHARED,
    802                         mMemInfo[i].fd, 0);
    803             if (vaddr == MAP_FAILED) {
    804                 for (int j = i-1; j >= 0; j --) {
    805                     munmap(mPtr[j], mMemInfo[j].size);
    806                     mPtr[j] = NULL;
    807                     deallocOneBuffer(mMemInfo[j]);
    808                 }
    809                 return NO_MEMORY;
    810             } else
    811                 mPtr[i] = vaddr;
    812         }
    813     }
    814     if (rc == 0) {
    815         mBufferCount = count;
    816     }
    817     traceLogAllocEnd((size * count));
    818     return OK;
    819 }
    820 
    821 /*===========================================================================
    822  * FUNCTION   : allocateMore
    823  *
    824  * DESCRIPTION: allocate more requested number of buffers of certain size
    825  *
    826  * PARAMETERS :
    827  *   @count   : number of buffers to be allocated
    828  *   @size    : lenght of the buffer to be allocated
    829  *
    830  * RETURN     : int32_t type of status
    831  *              NO_ERROR  -- success
    832  *              none-zero failure code
    833  *==========================================================================*/
    834 int QCameraHeapMemory::allocateMore(uint8_t count, size_t size)
    835 {
    836     traceLogAllocStart(size, count, "HeapMemsize");
    837     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
    838     int rc = alloc(count, size, heap_id_mask, NON_SECURE);
    839     if (rc < 0)
    840         return rc;
    841 
    842     for (int i = mBufferCount; i < count + mBufferCount; i ++) {
    843         void *vaddr = mmap(NULL,
    844                     mMemInfo[i].size,
    845                     PROT_READ | PROT_WRITE,
    846                     MAP_SHARED,
    847                     mMemInfo[i].fd, 0);
    848         if (vaddr == MAP_FAILED) {
    849             for (int j = i-1; j >= mBufferCount; j --) {
    850                 munmap(mPtr[j], mMemInfo[j].size);
    851                 mPtr[j] = NULL;
    852                 deallocOneBuffer(mMemInfo[j]);
    853             }
    854             return NO_MEMORY;
    855         } else {
    856             mPtr[i] = vaddr;
    857         }
    858     }
    859     mBufferCount = (uint8_t)(mBufferCount + count);
    860     traceLogAllocEnd((size * count));
    861     return OK;
    862 }
    863 
    864 /*===========================================================================
    865  * FUNCTION   : deallocate
    866  *
    867  * DESCRIPTION: deallocate buffers
    868  *
    869  * PARAMETERS : none
    870  *
    871  * RETURN     : none
    872  *==========================================================================*/
    873 void QCameraHeapMemory::deallocate()
    874 {
    875     for (int i = 0; i < mBufferCount; i++) {
    876         munmap(mPtr[i], mMemInfo[i].size);
    877         mPtr[i] = NULL;
    878     }
    879     dealloc();
    880     mBufferCount = 0;
    881 }
    882 
    883 /*===========================================================================
    884  * FUNCTION   : cacheOps
    885  *
    886  * DESCRIPTION: ion related memory cache operations
    887  *
    888  * PARAMETERS :
    889  *   @index   : index of the buffer
    890  *   @cmd     : cache ops command
    891  *
    892  * RETURN     : int32_t type of status
    893  *              NO_ERROR  -- success
    894  *              none-zero failure code
    895  *==========================================================================*/
    896 int QCameraHeapMemory::cacheOps(uint32_t index, unsigned int cmd)
    897 {
    898     if (index >= mBufferCount)
    899         return BAD_INDEX;
    900     return cacheOpsInternal(index, cmd, mPtr[index]);
    901 }
    902 
    903 /*===========================================================================
    904  * FUNCTION   : getRegFlags
    905  *
    906  * DESCRIPTION: query initial reg flags
    907  *
    908  * PARAMETERS :
    909  *   @regFlags: initial reg flags of the allocated buffers
    910  *
    911  * RETURN     : int32_t type of status
    912  *              NO_ERROR  -- success
    913  *              none-zero failure code
    914  *==========================================================================*/
    915 int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const
    916 {
    917     return INVALID_OPERATION;
    918 }
    919 
    920 /*===========================================================================
    921  * FUNCTION   : getMemory
    922  *
    923  * DESCRIPTION: get camera memory
    924  *
    925  * PARAMETERS :
    926  *   @index   : buffer index
    927  *   @metadata: flag if it's metadata
    928  *
    929  * RETURN     : camera memory ptr
    930  *              NULL if not supported or failed
    931  *==========================================================================*/
    932 camera_memory_t *QCameraHeapMemory::getMemory(uint32_t /*index*/, bool /*metadata*/) const
    933 {
    934     return NULL;
    935 }
    936 
    937 /*===========================================================================
    938  * FUNCTION   : getMatchBufIndex
    939  *
    940  * DESCRIPTION: query buffer index by opaque ptr
    941  *
    942  * PARAMETERS :
    943  *   @opaque  : opaque ptr
    944  *   @metadata: flag if it's metadata
    945  *
    946  * RETURN     : buffer index if match found,
    947  *              -1 if failed
    948  *==========================================================================*/
    949 int QCameraHeapMemory::getMatchBufIndex(const void *opaque,
    950                                         bool metadata) const
    951 {
    952     int index = -1;
    953     if (metadata) {
    954         return -1;
    955     }
    956     for (int i = 0; i < mBufferCount; i++) {
    957         if (mPtr[i] == opaque) {
    958             index = i;
    959             break;
    960         }
    961     }
    962     return index;
    963 }
    964 
    965 /*===========================================================================
    966  * FUNCTION   : QCameraStreamMemory
    967  *
    968  * DESCRIPTION: constructor of QCameraStreamMemory
    969  *              ION memory allocated directly from /dev/ion and shared with framework
    970  *
    971  * PARAMETERS :
    972  *   @memory    : camera memory request ops table
    973  *   @cached    : flag indicates if using cached memory
    974  *
    975  * RETURN     : none
    976  *==========================================================================*/
    977 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory memory,
    978         void* cbCookie,
    979         bool cached,
    980         QCameraMemoryPool *pool,
    981         cam_stream_type_t streamType, cam_stream_buf_type bufType)
    982     :QCameraMemory(cached, pool, streamType),
    983      mGetMemory(memory),
    984      mCallbackCookie(cbCookie)
    985 {
    986     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
    987         mCameraMemory[i] = NULL;
    988 }
    989 
    990 /*===========================================================================
    991  * FUNCTION   : ~QCameraStreamMemory
    992  *
    993  * DESCRIPTION: deconstructor of QCameraStreamMemory
    994  *
    995  * PARAMETERS : none
    996  *
    997  * RETURN     : none
    998  *==========================================================================*/
    999 QCameraStreamMemory::~QCameraStreamMemory()
   1000 {
   1001 }
   1002 
   1003 /*===========================================================================
   1004  * FUNCTION   : allocate
   1005  *
   1006  * DESCRIPTION: allocate requested number of buffers of certain size
   1007  *
   1008  * PARAMETERS :
   1009  *   @count   : number of buffers to be allocated
   1010  *   @size    : lenght of the buffer to be allocated
   1011  *
   1012  * RETURN     : int32_t type of status
   1013  *              NO_ERROR  -- success
   1014  *              none-zero failure code
   1015  *==========================================================================*/
   1016 int QCameraStreamMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
   1017 {
   1018     traceLogAllocStart(size, count, "StreamMemsize");
   1019     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
   1020     int rc = alloc(count, size, heap_id_mask, isSecure);
   1021     if (rc < 0)
   1022         return rc;
   1023 
   1024     for (int i = 0; i < count; i ++) {
   1025         if (isSecure == SECURE) {
   1026             mCameraMemory[i] = 0;
   1027         } else {
   1028             mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, mCallbackCookie);
   1029         }
   1030     }
   1031     mBufferCount = count;
   1032     traceLogAllocEnd((size * count));
   1033     return NO_ERROR;
   1034 }
   1035 
   1036 /*===========================================================================
   1037  * FUNCTION   : allocateMore
   1038  *
   1039  * DESCRIPTION: allocate more requested number of buffers of certain size
   1040  *
   1041  * PARAMETERS :
   1042  *   @count   : number of buffers to be allocated
   1043  *   @size    : lenght of the buffer to be allocated
   1044  *
   1045  * RETURN     : int32_t type of status
   1046  *              NO_ERROR  -- success
   1047  *              none-zero failure code
   1048  *==========================================================================*/
   1049 int QCameraStreamMemory::allocateMore(uint8_t count, size_t size)
   1050 {
   1051     traceLogAllocStart(size, count, "StreamMemsize");
   1052     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
   1053     int rc = alloc(count, size, heap_id_mask, NON_SECURE);
   1054     if (rc < 0)
   1055         return rc;
   1056 
   1057     for (int i = mBufferCount; i < mBufferCount + count; i++) {
   1058         mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, mCallbackCookie);
   1059     }
   1060     mBufferCount = (uint8_t)(mBufferCount + count);
   1061     traceLogAllocEnd((size * count));
   1062     return NO_ERROR;
   1063 }
   1064 
   1065 /*===========================================================================
   1066  * FUNCTION   : deallocate
   1067  *
   1068  * DESCRIPTION: deallocate buffers
   1069  *
   1070  * PARAMETERS : none
   1071  *
   1072  * RETURN     : none
   1073  *==========================================================================*/
   1074 void QCameraStreamMemory::deallocate()
   1075 {
   1076     for (int i = 0; i < mBufferCount; i ++) {
   1077         if (mCameraMemory[i])
   1078             mCameraMemory[i]->release(mCameraMemory[i]);
   1079         mCameraMemory[i] = NULL;
   1080     }
   1081     dealloc();
   1082     mBufferCount = 0;
   1083 }
   1084 
   1085 /*===========================================================================
   1086  * FUNCTION   : cacheOps
   1087  *
   1088  * DESCRIPTION: ion related memory cache operations
   1089  *
   1090  * PARAMETERS :
   1091  *   @index   : index of the buffer
   1092  *   @cmd     : cache ops command
   1093  *
   1094  * RETURN     : int32_t type of status
   1095  *              NO_ERROR  -- success
   1096  *              none-zero failure code
   1097  *==========================================================================*/
   1098 int QCameraStreamMemory::cacheOps(uint32_t index, unsigned int cmd)
   1099 {
   1100     if (index >= mBufferCount)
   1101         return BAD_INDEX;
   1102     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
   1103 }
   1104 
   1105 /*===========================================================================
   1106  * FUNCTION   : getRegFlags
   1107  *
   1108  * DESCRIPTION: query initial reg flags
   1109  *
   1110  * PARAMETERS :
   1111  *   @regFlags: initial reg flags of the allocated buffers
   1112  *
   1113  * RETURN     : int32_t type of status
   1114  *              NO_ERROR  -- success
   1115  *              none-zero failure code
   1116  *==========================================================================*/
   1117 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
   1118 {
   1119     for (int i = 0; i < mBufferCount; i ++)
   1120         regFlags[i] = 1;
   1121     return NO_ERROR;
   1122 }
   1123 
   1124 /*===========================================================================
   1125  * FUNCTION   : getMemory
   1126  *
   1127  * DESCRIPTION: get camera memory
   1128  *
   1129  * PARAMETERS :
   1130  *   @index   : buffer index
   1131  *   @metadata: flag if it's metadata
   1132  *
   1133  * RETURN     : camera memory ptr
   1134  *              NULL if not supported or failed
   1135  *==========================================================================*/
   1136 camera_memory_t *QCameraStreamMemory::getMemory(uint32_t index,
   1137         bool metadata) const
   1138 {
   1139     if (index >= mBufferCount || metadata)
   1140         return NULL;
   1141     return mCameraMemory[index];
   1142 }
   1143 
   1144 /*===========================================================================
   1145  * FUNCTION   : getMatchBufIndex
   1146  *
   1147  * DESCRIPTION: query buffer index by opaque ptr
   1148  *
   1149  * PARAMETERS :
   1150  *   @opaque  : opaque ptr
   1151  *   @metadata: flag if it's metadata
   1152  *
   1153  * RETURN     : buffer index if match found,
   1154  *              -1 if failed
   1155  *==========================================================================*/
   1156 int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
   1157                                           bool metadata) const
   1158 {
   1159     int index = -1;
   1160     if (metadata) {
   1161         return -1;
   1162     }
   1163     for (int i = 0; i < mBufferCount; i++) {
   1164         if (mCameraMemory[i]->data == opaque) {
   1165             index = i;
   1166             break;
   1167         }
   1168     }
   1169     return index;
   1170 }
   1171 
   1172 /*===========================================================================
   1173  * FUNCTION   : getPtr
   1174  *
   1175  * DESCRIPTION: return buffer pointer
   1176  *
   1177  * PARAMETERS :
   1178  *   @index   : index of the buffer
   1179  *
   1180  * RETURN     : buffer ptr
   1181  *==========================================================================*/
   1182 void *QCameraStreamMemory::getPtr(uint32_t index) const
   1183 {
   1184     if (index >= mBufferCount) {
   1185         ALOGE("index out of bound");
   1186         return (void *)BAD_INDEX;
   1187     }
   1188     if (mCameraMemory[index] == 0) {
   1189         return NULL;
   1190     }
   1191     return mCameraMemory[index]->data;
   1192 }
   1193 
   1194 /*===========================================================================
   1195  * FUNCTION   : QCameraVideoMemory
   1196  *
   1197  * DESCRIPTION: constructor of QCameraVideoMemory
   1198  *              VideoStream buffers also include metadata buffers
   1199  *
   1200  * PARAMETERS :
   1201  *   @memory    : camera memory request ops table
   1202  *   @cached    : flag indicates if using cached ION memory
   1203  *
   1204  * RETURN     : none
   1205  *==========================================================================*/
   1206 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory,
   1207                                        void* cbCookie,
   1208                                        bool cached, cam_stream_buf_type bufType)
   1209     : QCameraStreamMemory(memory, cbCookie, cached)
   1210 {
   1211     memset(mMetadata, 0, sizeof(mMetadata));
   1212     mMetaBufCount = 0;
   1213     mBufType = bufType;
   1214 }
   1215 
   1216 /*===========================================================================
   1217  * FUNCTION   : ~QCameraVideoMemory
   1218  *
   1219  * DESCRIPTION: deconstructor of QCameraVideoMemory
   1220  *
   1221  * PARAMETERS : none
   1222  *
   1223  * RETURN     : none
   1224  *==========================================================================*/
   1225 QCameraVideoMemory::~QCameraVideoMemory()
   1226 {
   1227 }
   1228 
   1229 /*===========================================================================
   1230  * FUNCTION   : allocate
   1231  *
   1232  * DESCRIPTION: allocate requested number of buffers of certain size
   1233  *
   1234  * PARAMETERS :
   1235  *   @count   : number of buffers to be allocated
   1236  *   @size    : lenght of the buffer to be allocated
   1237  *
   1238  * RETURN     : int32_t type of status
   1239  *              NO_ERROR  -- success
   1240  *              none-zero failure code
   1241  *==========================================================================*/
   1242 int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
   1243 {
   1244     traceLogAllocStart(size, count, "VideoMemsize");
   1245     int rc = QCameraStreamMemory::allocate(count, size, isSecure);
   1246     if (rc < 0)
   1247         return rc;
   1248 
   1249     if (mBufType != CAM_STREAM_BUF_TYPE_USERPTR) {
   1250         rc = allocateMeta(count);
   1251         if (rc != NO_ERROR) {
   1252             return rc;
   1253         }
   1254 
   1255         for (int i = 0; i < count; i ++) {
   1256             VideoNativeHandleMetadata *packet =
   1257                     static_cast<VideoNativeHandleMetadata *> (mMetadata[i]->data);
   1258             //1     fd, 1 offset, 1 size, 1 color transform
   1259             mNativeHandles[i] = native_handle_create(1, 3);
   1260             packet->pHandle =  mNativeHandles[i];
   1261             packet->eType = kMetadataBufferTypeNativeHandleSource;
   1262             native_handle_t * nh = packet->pHandle;
   1263             if (!nh) {
   1264                 ALOGE("%s: Error in getting video native handle", __func__);
   1265                 return NO_MEMORY;
   1266             }
   1267             nh->data[0] = mMemInfo[i].fd;
   1268             nh->data[1] = 0;
   1269             nh->data[2] = (int)mMemInfo[i].size;
   1270             nh->data[3] = private_handle_t::PRIV_FLAGS_ITU_R_709;
   1271         }
   1272     }
   1273     mBufferCount = count;
   1274     traceLogAllocEnd((size * count));
   1275     return NO_ERROR;
   1276 }
   1277 
   1278 /*===========================================================================
   1279  * FUNCTION   : allocateMore
   1280  *
   1281  * DESCRIPTION: allocate more requested number of buffers of certain size
   1282  *
   1283  * PARAMETERS :
   1284  *   @count   : number of buffers to be allocated
   1285  *   @size    : lenght of the buffer to be allocated
   1286  *
   1287  * RETURN     : int32_t type of status
   1288  *              NO_ERROR  -- success
   1289  *              none-zero failure code
   1290  *==========================================================================*/
   1291 int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
   1292 {
   1293     traceLogAllocStart(size, count, "VideoMemsize");
   1294     int rc = QCameraStreamMemory::allocateMore(count, size);
   1295     if (rc < 0)
   1296         return rc;
   1297 
   1298     if (mBufType != CAM_STREAM_BUF_TYPE_USERPTR) {
   1299         for (int i = mBufferCount; i < count + mBufferCount; i ++) {
   1300             mMetadata[i] = mGetMemory(-1,
   1301                     sizeof(struct VideoNativeHandleMetadata), 1, mCallbackCookie);
   1302             if (!mMetadata[i]) {
   1303                 ALOGE("allocation of video metadata failed.");
   1304                 for (int j = mBufferCount; j <= i-1; j ++) {
   1305                     mMetadata[j]->release(mMetadata[j]);
   1306                     mCameraMemory[j]->release(mCameraMemory[j]);
   1307                     mCameraMemory[j] = NULL;
   1308                     deallocOneBuffer(mMemInfo[j]);;
   1309                 }
   1310                 return NO_MEMORY;
   1311             }
   1312             VideoNativeHandleMetadata *packet =
   1313                     static_cast<VideoNativeHandleMetadata *>(mMetadata[i]->data);
   1314             mNativeHandles[i] = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
   1315             packet->pHandle = mNativeHandles[i];
   1316             packet->eType = kMetadataBufferTypeNativeHandleSource;
   1317             native_handle_t * nh = packet->pHandle;
   1318             if (!nh) {
   1319                 ALOGE("%s: Error in getting video native handle", __func__);
   1320                 return NO_MEMORY;
   1321             }
   1322             nh->data[0] = mMemInfo[i].fd;
   1323             nh->data[1] = 0;
   1324             nh->data[2] = (int)mMemInfo[i].size;
   1325         }
   1326     }
   1327     mBufferCount = (uint8_t)(mBufferCount + count);
   1328     mMetaBufCount = mBufferCount;
   1329     traceLogAllocEnd((size * count));
   1330     return NO_ERROR;
   1331 }
   1332 
   1333 /*===========================================================================
   1334  * FUNCTION   : allocateMeta
   1335  *
   1336  * DESCRIPTION: allocate video encoder metadata structure
   1337  *
   1338  * PARAMETERS :
   1339  *   @fd_cnt : Total FD count
   1340  *
   1341  * RETURN     : int32_t type of status
   1342  *              NO_ERROR  -- success
   1343  *              none-zero failure code
   1344  *==========================================================================*/
   1345 int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt)
   1346 {
   1347     int rc = NO_ERROR;
   1348 
   1349     for (int i = 0; i < buf_cnt; i++) {
   1350         mMetadata[i] = mGetMemory(-1,
   1351                 sizeof(struct VideoNativeHandleMetadata), 1, mCallbackCookie);
   1352         if (!mMetadata[i]) {
   1353             ALOGE("allocation of video metadata failed.");
   1354             for (int j = (i - 1); j >= 0; j--) {
   1355                 mMetadata[j]->release(mMetadata[j]);
   1356             }
   1357             return NO_MEMORY;
   1358         }
   1359     }
   1360     mMetaBufCount = buf_cnt;
   1361     return rc;
   1362 }
   1363 
   1364 /*===========================================================================
   1365  * FUNCTION   : deallocateMeta
   1366  *
   1367  * DESCRIPTION: deallocate video metadata buffers
   1368  *
   1369  * PARAMETERS : none
   1370  *
   1371  * RETURN     : none
   1372  *==========================================================================*/
   1373 void QCameraVideoMemory::deallocateMeta()
   1374 {
   1375     for (int i = 0; i < mMetaBufCount; i ++) {
   1376         mMetadata[i]->release(mMetadata[i]);
   1377         mMetadata[i] = NULL;
   1378     }
   1379     mMetaBufCount = 0;
   1380 }
   1381 
   1382 
   1383 /*===========================================================================
   1384  * FUNCTION   : deallocate
   1385  *
   1386  * DESCRIPTION: deallocate buffers
   1387  *
   1388  * PARAMETERS : none
   1389  *
   1390  * RETURN     : none
   1391  *==========================================================================*/
   1392 void QCameraVideoMemory::deallocate()
   1393 {
   1394     if (mBufType != CAM_STREAM_BUF_TYPE_USERPTR) {
   1395         for (int i = 0; i < mBufferCount; i ++) {
   1396             native_handle_t * nh = mNativeHandles[i];
   1397             if (NULL != nh) {
   1398                if (native_handle_delete(nh)) {
   1399                    ALOGE("Unable to delete native handle");
   1400                }
   1401             } else {
   1402                ALOGE("native handle not available");
   1403             }
   1404         }
   1405     }
   1406 
   1407     deallocateMeta();
   1408 
   1409     QCameraStreamMemory::deallocate();
   1410     mBufferCount = 0;
   1411     mMetaBufCount = 0;
   1412 }
   1413 
   1414 /*===========================================================================
   1415  * FUNCTION   : getMemory
   1416  *
   1417  * DESCRIPTION: get camera memory
   1418  *
   1419  * PARAMETERS :
   1420  *   @index   : buffer index
   1421  *   @metadata: flag if it's metadata
   1422  *
   1423  * RETURN     : camera memory ptr
   1424  *              NULL if not supported or failed
   1425  *==========================================================================*/
   1426 camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index,
   1427         bool metadata) const
   1428 {
   1429     if (index >= mMetaBufCount || (!metadata && index >= mBufferCount))
   1430         return NULL;
   1431 
   1432     if (metadata) {
   1433         VideoNativeHandleMetadata *packet =
   1434                 static_cast<VideoNativeHandleMetadata *> (mMetadata[index]->data);
   1435         packet->pHandle =  mNativeHandles[index];
   1436         return mMetadata[index];
   1437     } else {
   1438         return mCameraMemory[index];
   1439     }
   1440 }
   1441 
   1442 /*===========================================================================
   1443  * FUNCTION   : getMatchBufIndex
   1444  *
   1445  * DESCRIPTION: query buffer index by opaque ptr
   1446  *
   1447  * PARAMETERS :
   1448  *   @opaque  : opaque ptr
   1449  *   @metadata: flag if it's metadata
   1450  *
   1451  * RETURN     : buffer index if match found,
   1452  *              -1 if failed
   1453  *==========================================================================*/
   1454 int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
   1455                                          bool metadata) const
   1456 {
   1457     int index = -1;
   1458 
   1459     if (metadata) {
   1460         for (int i = 0; i < mMetaBufCount; i++) {
   1461             if (mMetadata[i]->data == opaque) {
   1462                 index = i;
   1463                 break;
   1464             }
   1465         }
   1466     } else {
   1467         for (int i = 0; i < mBufferCount; i++) {
   1468             if (mCameraMemory[i]->data == opaque) {
   1469                 index = i;
   1470                 break;
   1471             }
   1472         }
   1473     }
   1474     return index;
   1475 }
   1476 
   1477 /*===========================================================================
   1478  * FUNCTION   : QCameraGrallocMemory
   1479  *
   1480  * DESCRIPTION: constructor of QCameraGrallocMemory
   1481  *              preview stream buffers are allocated from gralloc native_windoe
   1482  *
   1483  * PARAMETERS :
   1484  *   @memory    : camera memory request ops table
   1485  *
   1486  * RETURN     : none
   1487  *==========================================================================*/
   1488 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory memory, void* cbCookie)
   1489         : QCameraMemory(true), mColorSpace(ITU_R_601_FR)
   1490 {
   1491     mMinUndequeuedBuffers = 0;
   1492     mWindow = NULL;
   1493     mWidth = mHeight = mStride = mScanline = 0;
   1494     mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
   1495     mGetMemory = memory;
   1496     mCallbackCookie = cbCookie;
   1497     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
   1498         mBufferHandle[i] = NULL;
   1499         mLocalFlag[i] = BUFFER_NOT_OWNED;
   1500         mPrivateHandle[i] = NULL;
   1501     }
   1502 }
   1503 
   1504 /*===========================================================================
   1505  * FUNCTION   : ~QCameraGrallocMemory
   1506  *
   1507  * DESCRIPTION: deconstructor of QCameraGrallocMemory
   1508  *
   1509  * PARAMETERS : none
   1510  *
   1511  * RETURN     : none
   1512  *==========================================================================*/
   1513 QCameraGrallocMemory::~QCameraGrallocMemory()
   1514 {
   1515 }
   1516 
   1517 /*===========================================================================
   1518  * FUNCTION   : setWindowInfo
   1519  *
   1520  * DESCRIPTION: set native window gralloc ops table
   1521  *
   1522  * PARAMETERS :
   1523  *   @window  : gralloc ops table ptr
   1524  *   @width   : width of preview frame
   1525  *   @height  : height of preview frame
   1526  *   @stride  : stride of preview frame
   1527  *   @scanline: scanline of preview frame
   1528  *   @foramt  : format of preview image
   1529  *
   1530  * RETURN     : none
   1531  *==========================================================================*/
   1532 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
   1533         int width, int height, int stride, int scanline, int format)
   1534 {
   1535     mWindow = window;
   1536     mWidth = width;
   1537     mHeight = height;
   1538     mStride = stride;
   1539     mScanline = scanline;
   1540     mFormat = format;
   1541 }
   1542 
   1543 /*===========================================================================
   1544  * FUNCTION   : displayBuffer
   1545  *
   1546  * DESCRIPTION: send received frame to display
   1547  *
   1548  * PARAMETERS :
   1549  *   @index   : index of preview frame
   1550  *
   1551  * RETURN     : int32_t type of status
   1552  *              NO_ERROR  -- success
   1553  *              none-zero failure code
   1554  *==========================================================================*/
   1555 int QCameraGrallocMemory::displayBuffer(uint32_t index)
   1556 {
   1557     int err = NO_ERROR;
   1558     int dequeuedIdx = BAD_INDEX;
   1559 
   1560     if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
   1561         ALOGE("%s: buffer to be enqueued is not owned", __func__);
   1562         return INVALID_OPERATION;
   1563     }
   1564 
   1565     err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
   1566     if(err != 0) {
   1567         ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
   1568     } else {
   1569         CDBG("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]);
   1570         mLocalFlag[index] = BUFFER_NOT_OWNED;
   1571     }
   1572 
   1573     buffer_handle_t *buffer_handle = NULL;
   1574     int stride = 0;
   1575     err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
   1576     if (err == NO_ERROR && buffer_handle != NULL) {
   1577         int i;
   1578         CDBG("%s: dequed buf hdl =%p", __func__, *buffer_handle);
   1579         for(i = 0; i < mBufferCount; i++) {
   1580             if(mBufferHandle[i] == buffer_handle) {
   1581                 CDBG("%s: Found buffer in idx:%d", __func__, i);
   1582                 mLocalFlag[i] = BUFFER_OWNED;
   1583                 dequeuedIdx = i;
   1584                 break;
   1585             }
   1586         }
   1587     } else {
   1588         CDBG_HIGH("%s: dequeue_buffer, no free buffer from display now", __func__);
   1589     }
   1590     return dequeuedIdx;
   1591 }
   1592 
   1593 /*===========================================================================
   1594  * FUNCTION   : allocate
   1595  *
   1596  * DESCRIPTION: allocate requested number of buffers of certain size
   1597  *
   1598  * PARAMETERS :
   1599  *   @count   : number of buffers to be allocated
   1600  *   @size    : lenght of the buffer to be allocated
   1601  *
   1602  * RETURN     : int32_t type of status
   1603  *              NO_ERROR  -- success
   1604  *              none-zero failure code
   1605  *==========================================================================*/
   1606 int QCameraGrallocMemory::allocate(uint8_t count, size_t /*size*/,
   1607         uint32_t /*isSecure*/)
   1608 {
   1609     traceLogAllocStart(0,count, "Grallocbufcnt");
   1610     int err = 0;
   1611     status_t ret = NO_ERROR;
   1612     int gralloc_usage = 0;
   1613     struct ion_fd_data ion_info_fd;
   1614     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
   1615 
   1616     CDBG(" %s : E ", __func__);
   1617 
   1618     if (!mWindow) {
   1619         ALOGE("Invalid native window");
   1620         return INVALID_OPERATION;
   1621     }
   1622 
   1623     // Increment buffer count by min undequeued buffer.
   1624     err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
   1625     if (err != 0) {
   1626         ALOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
   1627                 strerror(-err), -err);
   1628         ret = UNKNOWN_ERROR;
   1629         goto end;
   1630     }
   1631 
   1632     err = mWindow->set_buffer_count(mWindow, count);
   1633     if (err != 0) {
   1634          ALOGE("set_buffer_count failed: %s (%d)",
   1635                     strerror(-err), -err);
   1636          ret = UNKNOWN_ERROR;
   1637          goto end;
   1638     }
   1639 
   1640     err = mWindow->set_buffers_geometry(mWindow, mStride, mScanline, mFormat);
   1641     if (err != 0) {
   1642          ALOGE("%s: set_buffers_geometry failed: %s (%d)",
   1643                __func__, strerror(-err), -err);
   1644          ret = UNKNOWN_ERROR;
   1645          goto end;
   1646     }
   1647 
   1648     err = mWindow->set_crop(mWindow, 0, 0, mWidth, mHeight);
   1649     if (err != 0) {
   1650          ALOGE("%s: set_crop failed: %s (%d)",
   1651                __func__, strerror(-err), -err);
   1652          ret = UNKNOWN_ERROR;
   1653          goto end;
   1654     }
   1655 
   1656     gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
   1657     err = mWindow->set_usage(mWindow, gralloc_usage);
   1658     if(err != 0) {
   1659         /* set_usage error out */
   1660         ALOGE("%s: set_usage rc = %d", __func__, err);
   1661         ret = UNKNOWN_ERROR;
   1662         goto end;
   1663     }
   1664     CDBG_HIGH("%s: usage = %d, geometry: %p, %d, %d, %d, %d, %d",
   1665           __func__, gralloc_usage, mWindow, mWidth, mHeight, mStride,
   1666           mScanline, mFormat);
   1667 
   1668     //Allocate cnt number of buffers from native window
   1669     for (int cnt = 0; cnt < count; cnt++) {
   1670         int stride;
   1671         err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
   1672         if(!err) {
   1673             CDBG("dequeue buf hdl =%p", mBufferHandle[cnt]);
   1674             mLocalFlag[cnt] = BUFFER_OWNED;
   1675         } else {
   1676             mLocalFlag[cnt] = BUFFER_NOT_OWNED;
   1677             ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
   1678         }
   1679 
   1680         CDBG("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]);
   1681 
   1682         if(err != 0) {
   1683             ALOGE("%s: dequeue_buffer failed: %s (%d)",
   1684                   __func__, strerror(-err), -err);
   1685             ret = UNKNOWN_ERROR;
   1686             for(int i = 0; i < cnt; i++) {
   1687                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   1688                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1689                     CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
   1690                 }
   1691                 mLocalFlag[i] = BUFFER_NOT_OWNED;
   1692                 mBufferHandle[i] = NULL;
   1693             }
   1694             reset();
   1695             goto end;
   1696         }
   1697 
   1698         mPrivateHandle[cnt] =
   1699             (struct private_handle_t *)(*mBufferHandle[cnt]);
   1700         mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
   1701         if (mMemInfo[cnt].main_ion_fd < 0) {
   1702             ALOGE("%s: failed: could not open ion device", __func__);
   1703             for(int i = 0; i < cnt; i++) {
   1704                 struct ion_handle_data ion_handle;
   1705                 memset(&ion_handle, 0, sizeof(ion_handle));
   1706                 ion_handle.handle = mMemInfo[i].handle;
   1707                 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   1708                     ALOGE("%s: ion free failed", __func__);
   1709                 }
   1710                 close(mMemInfo[i].main_ion_fd);
   1711                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   1712                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1713                     CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
   1714                 }
   1715                 mLocalFlag[i] = BUFFER_NOT_OWNED;
   1716                 mBufferHandle[i] = NULL;
   1717             }
   1718             reset();
   1719             ret = UNKNOWN_ERROR;
   1720             goto end;
   1721         } else {
   1722             ion_info_fd.fd = mPrivateHandle[cnt]->fd;
   1723             if (ioctl(mMemInfo[cnt].main_ion_fd,
   1724                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
   1725                 ALOGE("%s: ION import failed\n", __func__);
   1726                 for(int i = 0; i < cnt; i++) {
   1727                     struct ion_handle_data ion_handle;
   1728                     memset(&ion_handle, 0, sizeof(ion_handle));
   1729                     ion_handle.handle = mMemInfo[i].handle;
   1730                     if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   1731                         ALOGE("ion free failed");
   1732                     }
   1733                     close(mMemInfo[i].main_ion_fd);
   1734 
   1735                     if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   1736                         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1737                         CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
   1738                     }
   1739                     mLocalFlag[i] = BUFFER_NOT_OWNED;
   1740                     mBufferHandle[i] = NULL;
   1741                 }
   1742                 close(mMemInfo[cnt].main_ion_fd);
   1743                 reset();
   1744                 ret = UNKNOWN_ERROR;
   1745                 goto end;
   1746             }
   1747         }
   1748         setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace);
   1749         mCameraMemory[cnt] =
   1750             mGetMemory(mPrivateHandle[cnt]->fd,
   1751                     (size_t)mPrivateHandle[cnt]->size,
   1752                     1,
   1753                     mCallbackCookie);
   1754         CDBG_HIGH("%s: idx = %d, fd = %d, size = %d, offset = %d",
   1755               __func__, cnt, mPrivateHandle[cnt]->fd,
   1756               mPrivateHandle[cnt]->size,
   1757               mPrivateHandle[cnt]->offset);
   1758         mMemInfo[cnt].fd = mPrivateHandle[cnt]->fd;
   1759         mMemInfo[cnt].size = (size_t)mPrivateHandle[cnt]->size;
   1760         mMemInfo[cnt].handle = ion_info_fd.handle;
   1761     }
   1762     mBufferCount = count;
   1763 
   1764     //Cancel min_undequeued_buffer buffers back to the window
   1765     for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
   1766         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1767         mLocalFlag[i] = BUFFER_NOT_OWNED;
   1768     }
   1769 
   1770 end:
   1771     CDBG(" %s : X ",__func__);
   1772     traceLogAllocEnd(count);
   1773     return ret;
   1774 }
   1775 
   1776 
   1777 /*===========================================================================
   1778  * FUNCTION   : allocateMore
   1779  *
   1780  * DESCRIPTION: allocate more requested number of buffers of certain size
   1781  *
   1782  * PARAMETERS :
   1783  *   @count   : number of buffers to be allocated
   1784  *   @size    : lenght of the buffer to be allocated
   1785  *
   1786  * RETURN     : int32_t type of status
   1787  *              NO_ERROR  -- success
   1788  *              none-zero failure code
   1789  *==========================================================================*/
   1790 int QCameraGrallocMemory::allocateMore(uint8_t /*count*/, size_t /*size*/)
   1791 {
   1792     ALOGE("%s: Not implenmented yet", __func__);
   1793     return UNKNOWN_ERROR;
   1794 }
   1795 
   1796 /*===========================================================================
   1797  * FUNCTION   : deallocate
   1798  *
   1799  * DESCRIPTION: deallocate buffers
   1800  *
   1801  * PARAMETERS : none
   1802  *
   1803  * RETURN     : none
   1804  *==========================================================================*/
   1805 void QCameraGrallocMemory::deallocate()
   1806 {
   1807     CDBG("%s: E ", __FUNCTION__);
   1808 
   1809     for (int cnt = 0; cnt < mBufferCount; cnt++) {
   1810         mCameraMemory[cnt]->release(mCameraMemory[cnt]);
   1811         struct ion_handle_data ion_handle;
   1812         memset(&ion_handle, 0, sizeof(ion_handle));
   1813         ion_handle.handle = mMemInfo[cnt].handle;
   1814         if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   1815             ALOGE("ion free failed");
   1816         }
   1817         close(mMemInfo[cnt].main_ion_fd);
   1818         if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
   1819             if (mWindow) {
   1820                 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
   1821                 CDBG_HIGH("cancel_buffer: hdl =%p", (*mBufferHandle[cnt]));
   1822             } else {
   1823                 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p",
   1824                       (*mBufferHandle[cnt]));
   1825             }
   1826         }
   1827         mLocalFlag[cnt] = BUFFER_NOT_OWNED;
   1828         CDBG_HIGH("put buffer %d successfully", cnt);
   1829     }
   1830     mBufferCount = 0;
   1831     CDBG(" %s : X ",__FUNCTION__);
   1832 }
   1833 
   1834 /*===========================================================================
   1835  * FUNCTION   : cacheOps
   1836  *
   1837  * DESCRIPTION: ion related memory cache operations
   1838  *
   1839  * PARAMETERS :
   1840  *   @index   : index of the buffer
   1841  *   @cmd     : cache ops command
   1842  *
   1843  * RETURN     : int32_t type of status
   1844  *              NO_ERROR  -- success
   1845  *              none-zero failure code
   1846  *==========================================================================*/
   1847 int QCameraGrallocMemory::cacheOps(uint32_t index, unsigned int cmd)
   1848 {
   1849     if (index >= mBufferCount)
   1850         return BAD_INDEX;
   1851     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
   1852 }
   1853 
   1854 /*===========================================================================
   1855  * FUNCTION   : getRegFlags
   1856  *
   1857  * DESCRIPTION: query initial reg flags
   1858  *
   1859  * PARAMETERS :
   1860  *   @regFlags: initial reg flags of the allocated buffers
   1861  *
   1862  * RETURN     : int32_t type of status
   1863  *              NO_ERROR  -- success
   1864  *              none-zero failure code
   1865  *==========================================================================*/
   1866 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
   1867 {
   1868     int i = 0;
   1869     for (i = 0; i < mMinUndequeuedBuffers; i ++)
   1870         regFlags[i] = 0;
   1871     for (; i < mBufferCount; i ++)
   1872         regFlags[i] = 1;
   1873     return NO_ERROR;
   1874 }
   1875 
   1876 /*===========================================================================
   1877  * FUNCTION   : getMemory
   1878  *
   1879  * DESCRIPTION: get camera memory
   1880  *
   1881  * PARAMETERS :
   1882  *   @index   : buffer index
   1883  *   @metadata: flag if it's metadata
   1884  *
   1885  * RETURN     : camera memory ptr
   1886  *              NULL if not supported or failed
   1887  *==========================================================================*/
   1888 camera_memory_t *QCameraGrallocMemory::getMemory(uint32_t index,
   1889         bool metadata) const
   1890 {
   1891     if (index >= mBufferCount || metadata)
   1892         return NULL;
   1893     return mCameraMemory[index];
   1894 }
   1895 
   1896 /*===========================================================================
   1897  * FUNCTION   : getMatchBufIndex
   1898  *
   1899  * DESCRIPTION: query buffer index by opaque ptr
   1900  *
   1901  * PARAMETERS :
   1902  *   @opaque  : opaque ptr
   1903  *   @metadata: flag if it's metadata
   1904  *
   1905  * RETURN     : buffer index if match found,
   1906  *              -1 if failed
   1907  *==========================================================================*/
   1908 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
   1909                                            bool metadata) const
   1910 {
   1911     int index = -1;
   1912     if (metadata) {
   1913         return -1;
   1914     }
   1915     for (int i = 0; i < mBufferCount; i++) {
   1916         if (mCameraMemory[i]->data == opaque) {
   1917             index = i;
   1918             break;
   1919         }
   1920     }
   1921     return index;
   1922 }
   1923 
   1924 /*===========================================================================
   1925  * FUNCTION   : getPtr
   1926  *
   1927  * DESCRIPTION: return buffer pointer
   1928  *
   1929  * PARAMETERS :
   1930  *   @index   : index of the buffer
   1931  *
   1932  * RETURN     : buffer ptr
   1933  *==========================================================================*/
   1934 void *QCameraGrallocMemory::getPtr(uint32_t index) const
   1935 {
   1936     if (index >= mBufferCount) {
   1937         ALOGE("index out of bound");
   1938         return (void *)BAD_INDEX;
   1939     }
   1940     return mCameraMemory[index]->data;
   1941 }
   1942 
   1943 }; //namespace qcamera
   1944