Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2017, The Linux Foundation. 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 LOG_TAG "QCameraHWI_Mem"
     30 
     31 // System dependencies
     32 #include <fcntl.h>
     33 #include <stdio.h>
     34 #include <utils/Errors.h>
     35 #define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h>
     36 #include MMAN_H
     37 #include "gralloc.h"
     38 #include "gralloc_priv.h"
     39 
     40 // Camera dependencies
     41 #include "QCamera2HWI.h"
     42 #include "QCameraMem.h"
     43 #include "QCameraParameters.h"
     44 #include "QCameraTrace.h"
     45 
     46 // Media dependencies
     47 #ifdef USE_MEDIA_EXTENSIONS
     48 #include <media/hardware/HardwareAPI.h>
     49 typedef struct VideoNativeHandleMetadata media_metadata_buffer;
     50 #else
     51 #include "QComOMXMetadata.h"
     52 typedef struct encoder_media_buffer_type media_metadata_buffer;
     53 #endif
     54 
     55 extern "C" {
     56 #include "mm_camera_dbg.h"
     57 #include "mm_camera_interface.h"
     58 }
     59 
     60 using namespace android;
     61 
     62 namespace qcamera {
     63 
     64 // QCaemra2Memory base class
     65 
     66 /*===========================================================================
     67  * FUNCTION   : QCameraMemory
     68  *
     69  * DESCRIPTION: default constructor of QCameraMemory
     70  *
     71  * PARAMETERS :
     72  *   @cached      : flag indicates if using cached memory
     73  *   @pool        : memory pool ptr
     74  *   @streamType  : stream type
     75  *   @bufType     : buffer type to allocate
     76  *
     77  * RETURN     : None
     78  *==========================================================================*/
     79 QCameraMemory::QCameraMemory(bool cached,
     80         QCameraMemoryPool *pool,
     81         cam_stream_type_t streamType, QCameraMemType bufType)
     82     :m_bCached(cached),
     83      mMemoryPool(pool),
     84      mStreamType(streamType),
     85      mBufType(bufType)
     86 {
     87     mBufferCount = 0;
     88     reset();
     89 }
     90 
     91 /*===========================================================================
     92  * FUNCTION   : ~QCameraMemory
     93  *
     94  * DESCRIPTION: deconstructor of QCameraMemory
     95  *
     96  * PARAMETERS : none
     97  *
     98  * RETURN     : None
     99  *==========================================================================*/
    100 QCameraMemory::~QCameraMemory()
    101 {
    102 }
    103 
    104 /*===========================================================================
    105  * FUNCTION   : cacheOpsInternal
    106  *
    107  * DESCRIPTION: ion related memory cache operations
    108  *
    109  * PARAMETERS :
    110  *   @index   : index of the buffer
    111  *   @cmd     : cache ops command
    112  *   @vaddr   : ptr to the virtual address
    113  *
    114  * RETURN     : int32_t type of status
    115  *              NO_ERROR  -- success
    116  *              none-zero failure code
    117  *==========================================================================*/
    118 int QCameraMemory::cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr)
    119 {
    120     if (!m_bCached) {
    121         // Memory is not cached, no need for cache ops
    122         LOGD("No cache ops here for uncached memory");
    123         return OK;
    124     }
    125 
    126     struct ion_flush_data cache_inv_data;
    127     struct ion_custom_data custom_data;
    128     int ret = OK;
    129 
    130     if (index >= mBufferCount) {
    131         LOGE("index %d out of bound [0, %d)", index, mBufferCount);
    132         return BAD_INDEX;
    133     }
    134 
    135     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
    136     memset(&custom_data, 0, sizeof(custom_data));
    137     cache_inv_data.vaddr = vaddr;
    138     cache_inv_data.fd = mMemInfo[index].fd;
    139     cache_inv_data.handle = mMemInfo[index].handle;
    140     cache_inv_data.length =
    141             ( /* FIXME: Should remove this after ION interface changes */ unsigned int)
    142             mMemInfo[index].size;
    143     custom_data.cmd = cmd;
    144     custom_data.arg = (unsigned long)&cache_inv_data;
    145 
    146     LOGD("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
    147           cache_inv_data.vaddr, cache_inv_data.fd,
    148          (unsigned long)cache_inv_data.handle, cache_inv_data.length,
    149          mMemInfo[index].main_ion_fd);
    150     ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
    151     if (ret < 0) {
    152         LOGE("Cache Invalidate failed: %s\n", strerror(errno));
    153     }
    154 
    155     return ret;
    156 }
    157 
    158 /*===========================================================================
    159  * FUNCTION   : getFd
    160  *
    161  * DESCRIPTION: return file descriptor of the indexed buffer
    162  *
    163  * PARAMETERS :
    164  *   @index   : index of the buffer
    165  *
    166  * RETURN     : file descriptor
    167  *==========================================================================*/
    168 int QCameraMemory::getFd(uint32_t index) const
    169 {
    170     if (index >= mBufferCount)
    171         return BAD_INDEX;
    172 
    173     return mMemInfo[index].fd;
    174 }
    175 
    176 /*===========================================================================
    177  * FUNCTION   : getSize
    178  *
    179  * DESCRIPTION: return buffer size of the indexed buffer
    180  *
    181  * PARAMETERS :
    182  *   @index   : index of the buffer
    183  *
    184  * RETURN     : buffer size
    185  *==========================================================================*/
    186 ssize_t QCameraMemory::getSize(uint32_t index) const
    187 {
    188     if (index >= mBufferCount)
    189         return BAD_INDEX;
    190 
    191     return (ssize_t)mMemInfo[index].size;
    192 }
    193 
    194 /*===========================================================================
    195  * FUNCTION   : getCnt
    196  *
    197  * DESCRIPTION: query number of buffers allocated
    198  *
    199  * PARAMETERS : none
    200  *
    201  * RETURN     : number of buffers allocated
    202  *==========================================================================*/
    203 uint8_t QCameraMemory::getCnt() const
    204 {
    205     return mBufferCount;
    206 }
    207 
    208 /*===========================================================================
    209  * FUNCTION   : reset
    210  *
    211  * DESCRIPTION: reset member variables
    212  *
    213  * PARAMETERS : none
    214  *
    215  * RETURN     : none
    216  *==========================================================================*/
    217 void QCameraMemory::reset()
    218 {
    219     size_t i, count;
    220 
    221     memset(mMemInfo, 0, sizeof(mMemInfo));
    222 
    223     count = sizeof(mMemInfo) / sizeof(mMemInfo[0]);
    224     for (i = 0; i < count; i++) {
    225         mMemInfo[i].fd = -1;
    226         mMemInfo[i].main_ion_fd = -1;
    227     }
    228 
    229     return;
    230 }
    231 
    232 /*===========================================================================
    233  * FUNCTION   : getMappable
    234  *
    235  * DESCRIPTION: query number of buffers available to map
    236  *
    237  * PARAMETERS : none
    238  *
    239  * RETURN     : number of buffers available to map
    240  *==========================================================================*/
    241 uint8_t QCameraMemory::getMappable() const
    242 {
    243     return mBufferCount;
    244 }
    245 
    246 /*===========================================================================
    247  * FUNCTION   : checkIfAllBuffersMapped
    248  *
    249  * DESCRIPTION: query if all buffers are mapped
    250  *
    251  * PARAMETERS : none
    252  *
    253  * RETURN     : 1 as buffer count is always equal to mappable count
    254  *==========================================================================*/
    255 uint8_t QCameraMemory::checkIfAllBuffersMapped() const
    256 {
    257     return 1;
    258 }
    259 
    260 
    261 /*===========================================================================
    262  * FUNCTION   : getBufDef
    263  *
    264  * DESCRIPTION: query detailed buffer information
    265  *
    266  * PARAMETERS :
    267  *   @offset  : [input] frame buffer offset
    268  *   @bufDef  : [output] reference to struct to store buffer definition
    269  *   @index   : [input] index of the buffer
    270  *
    271  * RETURN     : none
    272  *==========================================================================*/
    273 void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset,
    274         mm_camera_buf_def_t &bufDef, uint32_t index) const
    275 {
    276     if (!mBufferCount) {
    277         LOGE("Memory not allocated");
    278         return;
    279     }
    280     bufDef.fd = mMemInfo[index].fd;
    281     bufDef.frame_len = mMemInfo[index].size;
    282     bufDef.buf_type = CAM_STREAM_BUF_TYPE_MPLANE;
    283     bufDef.mem_info = (void *)this;
    284     bufDef.planes_buf.num_planes = (int8_t)offset.num_planes;
    285     bufDef.buffer = getPtr(index);
    286     bufDef.buf_idx = index;
    287 
    288     /* Plane 0 needs to be set separately. Set other planes in a loop */
    289     bufDef.planes_buf.planes[0].length = offset.mp[0].len;
    290     bufDef.planes_buf.planes[0].m.userptr = (long unsigned int)mMemInfo[index].fd;
    291     bufDef.planes_buf.planes[0].data_offset = offset.mp[0].offset;
    292     bufDef.planes_buf.planes[0].reserved[0] = 0;
    293     for (int i = 1; i < bufDef.planes_buf.num_planes; i++) {
    294          bufDef.planes_buf.planes[i].length = offset.mp[i].len;
    295          bufDef.planes_buf.planes[i].m.userptr = (long unsigned int)mMemInfo[i].fd;
    296          bufDef.planes_buf.planes[i].data_offset = offset.mp[i].offset;
    297          bufDef.planes_buf.planes[i].reserved[0] =
    298                  bufDef.planes_buf.planes[i-1].reserved[0] +
    299                  bufDef.planes_buf.planes[i-1].length;
    300     }
    301 }
    302 
    303 /*===========================================================================
    304  * FUNCTION   : getUserBufDef
    305  *
    306  * DESCRIPTION: Fill Buffer structure with user buffer information
    307                            This also fills individual stream buffers inside batch baffer strcuture
    308  *
    309  * PARAMETERS :
    310  *   @buf_info : user buffer information
    311  *   @bufDef  : Buffer strcuture to fill user buf info
    312  *   @index   : index of the buffer
    313  *   @plane_offset : plane buffer information
    314  *   @planeBufDef  : [input] frame buffer offset
    315  *   @bufs    : Stream Buffer object
    316  *
    317  * RETURN     : int32_t type of status
    318  *              NO_ERROR  -- success
    319  *              none-zero failure code
    320  *==========================================================================*/
    321 int32_t QCameraMemory::getUserBufDef(const cam_stream_user_buf_info_t &buf_info,
    322         mm_camera_buf_def_t &bufDef,
    323         uint32_t index,
    324         const cam_frame_len_offset_t &plane_offset,
    325         mm_camera_buf_def_t *planeBufDef,
    326         QCameraMemory *bufs) const
    327 {
    328     struct msm_camera_user_buf_cont_t *cont_buf = NULL;
    329     uint32_t plane_idx = (index * buf_info.frame_buf_cnt);
    330 
    331     if (!mBufferCount) {
    332         LOGE("Memory not allocated");
    333         return INVALID_OPERATION;
    334     }
    335 
    336     for (int count = 0; count < mBufferCount; count++) {
    337         bufDef.fd = mMemInfo[count].fd;
    338         bufDef.buf_type = CAM_STREAM_BUF_TYPE_USERPTR;
    339         bufDef.frame_len = buf_info.size;
    340         bufDef.mem_info = (void *)this;
    341         bufDef.buffer = (void *)((uint8_t *)getPtr(count)
    342                 + (index * buf_info.size));
    343         bufDef.buf_idx = index;
    344         bufDef.user_buf.num_buffers = (int8_t)buf_info.frame_buf_cnt;
    345         bufDef.user_buf.bufs_used = (int8_t)buf_info.frame_buf_cnt;
    346 
    347         //Individual plane buffer structure to be filled
    348         cont_buf = (struct msm_camera_user_buf_cont_t *)bufDef.buffer;
    349         cont_buf->buf_cnt = bufDef.user_buf.num_buffers;
    350 
    351         for (int i = 0; i < bufDef.user_buf.num_buffers; i++) {
    352             bufs->getBufDef(plane_offset, planeBufDef[plane_idx], plane_idx);
    353             bufDef.user_buf.buf_idx[i] = -1;
    354             cont_buf->buf_idx[i] = planeBufDef[plane_idx].buf_idx;
    355             plane_idx++;
    356         }
    357         bufDef.user_buf.plane_buf = planeBufDef;
    358 
    359         LOGD("num_buf = %d index = %d plane_idx = %d",
    360                  bufDef.user_buf.num_buffers, index, plane_idx);
    361     }
    362     return NO_ERROR;
    363 }
    364 
    365 
    366 /*===========================================================================
    367  * FUNCTION   : alloc
    368  *
    369  * DESCRIPTION: allocate requested number of buffers of certain size
    370  *
    371  * PARAMETERS :
    372  *   @count   : number of buffers to be allocated
    373  *   @size    : lenght of the buffer to be allocated
    374  *   @heap_id : heap id to indicate where the buffers will be allocated from
    375  *
    376  * RETURN     : int32_t type of status
    377  *              NO_ERROR  -- success
    378  *              none-zero failure code
    379  *==========================================================================*/
    380 int QCameraMemory::alloc(int count, size_t size, unsigned int heap_id)
    381 {
    382     int rc = OK;
    383     bool secure_mode = mBufType & QCAMERA_MEM_TYPE_SECURE ? TRUE : FALSE;
    384 
    385     int new_bufCnt = mBufferCount + count;
    386     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "Memsize", size, count);
    387 
    388     if (new_bufCnt > MM_CAMERA_MAX_NUM_FRAMES) {
    389         LOGE("Buffer count %d out of bound. Max is %d",
    390                new_bufCnt, MM_CAMERA_MAX_NUM_FRAMES);
    391         ATRACE_END();
    392         return BAD_INDEX;
    393     }
    394 
    395     for (int i = mBufferCount; i < new_bufCnt; i ++) {
    396         if ( NULL == mMemoryPool ) {
    397             LOGH("No memory pool available, allocating now");
    398             rc = allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached,
    399                      secure_mode);
    400             if (rc < 0) {
    401                 LOGE("AllocateIonMemory failed");
    402                 for (int j = i-1; j >= 0; j--)
    403                     deallocOneBuffer(mMemInfo[j]);
    404                 break;
    405             }
    406         } else {
    407             rc = mMemoryPool->allocateBuffer(mMemInfo[i],
    408                                              heap_id,
    409                                              size,
    410                                              m_bCached,
    411                                              mStreamType,
    412                                              secure_mode);
    413             if (rc < 0) {
    414                 LOGE("Memory pool allocation failed");
    415                 for (int j = i-1; j >= 0; j--)
    416                     mMemoryPool->releaseBuffer(mMemInfo[j],
    417                                                mStreamType);
    418                 break;
    419             }
    420         }
    421 
    422     }
    423     ATRACE_END();
    424     return rc;
    425 }
    426 
    427 /*===========================================================================
    428  * FUNCTION   : dealloc
    429  *
    430  * DESCRIPTION: deallocate buffers
    431  *
    432  * PARAMETERS : none
    433  *
    434  * RETURN     : none
    435  *==========================================================================*/
    436 void QCameraMemory::dealloc()
    437 {
    438     for (int i = 0; i < mBufferCount; i++) {
    439         if ( NULL == mMemoryPool ) {
    440             deallocOneBuffer(mMemInfo[i]);
    441         } else {
    442             mMemoryPool->releaseBuffer(mMemInfo[i], mStreamType);
    443         }
    444     }
    445 }
    446 
    447 /*===========================================================================
    448  * FUNCTION   : allocOneBuffer
    449  *
    450  * DESCRIPTION: impl of allocating one buffers of certain size
    451  *
    452  * PARAMETERS :
    453  *   @memInfo : [output] reference to struct to store additional memory allocation info
    454  *   @heap    : [input] heap id to indicate where the buffers will be allocated from
    455  *   @size    : [input] lenght of the buffer to be allocated
    456  *   @cached  : [input] flag whether buffer needs to be cached
    457  *   @secure_mode : secure mode
    458  *
    459  * RETURN     : int32_t type of status
    460  *              NO_ERROR  -- success
    461  *              none-zero failure code
    462  *==========================================================================*/
    463 int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo,
    464         unsigned int heap_id, size_t size, bool cached, bool secure_mode)
    465 {
    466     int rc = OK;
    467     struct ion_handle_data handle_data;
    468     struct ion_allocation_data alloc;
    469     struct ion_fd_data ion_info_fd;
    470     int main_ion_fd = -1;
    471 
    472     main_ion_fd = open("/dev/ion", O_RDONLY);
    473     if (main_ion_fd < 0) {
    474         LOGE("Ion dev open failed: %s\n", strerror(errno));
    475         goto ION_OPEN_FAILED;
    476     }
    477 
    478     memset(&alloc, 0, sizeof(alloc));
    479     alloc.len = size;
    480     /* to make it page size aligned */
    481     alloc.len = (alloc.len + 4095U) & (~4095U);
    482     alloc.align = 4096;
    483     if (cached) {
    484         alloc.flags = ION_FLAG_CACHED;
    485     }
    486     alloc.heap_id_mask = heap_id;
    487     if (secure_mode) {
    488         LOGD("Allocate secure buffer\n");
    489         alloc.flags = ION_FLAG_SECURE | ION_FLAG_CP_CAMERA;
    490         alloc.heap_id_mask = ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
    491         alloc.align = 2097152; // 2 MiB alignment to be able to protect later
    492         alloc.len = (alloc.len + 2097152U) & (~2097152U);
    493     }
    494 
    495     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
    496     if (rc < 0) {
    497         LOGE("ION allocation failed: %s\n", strerror(errno));
    498         goto ION_ALLOC_FAILED;
    499     }
    500 
    501     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    502     ion_info_fd.handle = alloc.handle;
    503     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
    504     if (rc < 0) {
    505         LOGE("ION map failed %s\n", strerror(errno));
    506         goto ION_MAP_FAILED;
    507     }
    508 
    509     memInfo.main_ion_fd = main_ion_fd;
    510     memInfo.fd = ion_info_fd.fd;
    511     memInfo.handle = ion_info_fd.handle;
    512     memInfo.size = alloc.len;
    513     memInfo.cached = cached;
    514     memInfo.heap_id = heap_id;
    515 
    516     LOGD("ION buffer %lx with size %d allocated",
    517              (unsigned long)memInfo.handle, alloc.len);
    518     return OK;
    519 
    520 ION_MAP_FAILED:
    521     memset(&handle_data, 0, sizeof(handle_data));
    522     handle_data.handle = ion_info_fd.handle;
    523     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
    524 ION_ALLOC_FAILED:
    525     close(main_ion_fd);
    526 ION_OPEN_FAILED:
    527     return NO_MEMORY;
    528 }
    529 
    530 /*===========================================================================
    531  * FUNCTION   : deallocOneBuffer
    532  *
    533  * DESCRIPTION: impl of deallocating one buffers
    534  *
    535  * PARAMETERS :
    536  *   @memInfo : reference to struct that stores additional memory allocation info
    537  *
    538  * RETURN     : none
    539  *==========================================================================*/
    540 void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo)
    541 {
    542     struct ion_handle_data handle_data;
    543 
    544     if (memInfo.fd >= 0) {
    545         close(memInfo.fd);
    546         memInfo.fd = -1;
    547     }
    548 
    549     if (memInfo.main_ion_fd >= 0) {
    550         memset(&handle_data, 0, sizeof(handle_data));
    551         handle_data.handle = memInfo.handle;
    552         ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
    553         close(memInfo.main_ion_fd);
    554         memInfo.main_ion_fd = -1;
    555     }
    556     memInfo.handle = 0;
    557     memInfo.size = 0;
    558 }
    559 
    560 /*===========================================================================
    561  * FUNCTION   : QCameraMemoryPool
    562  *
    563  * DESCRIPTION: default constructor of QCameraMemoryPool
    564  *
    565  * PARAMETERS : None
    566  *
    567  * RETURN     : None
    568  *==========================================================================*/
    569 QCameraMemoryPool::QCameraMemoryPool()
    570 {
    571     pthread_mutex_init(&mLock, NULL);
    572 }
    573 
    574 
    575 /*===========================================================================
    576  * FUNCTION   : ~QCameraMemoryPool
    577  *
    578  * DESCRIPTION: deconstructor of QCameraMemoryPool
    579  *
    580  * PARAMETERS : None
    581  *
    582  * RETURN     : None
    583  *==========================================================================*/
    584 QCameraMemoryPool::~QCameraMemoryPool()
    585 {
    586     clear();
    587     pthread_mutex_destroy(&mLock);
    588 }
    589 
    590 /*===========================================================================
    591  * FUNCTION   : releaseBuffer
    592  *
    593  * DESCRIPTION: release one cached buffers
    594  *
    595  * PARAMETERS :
    596  *   @memInfo : reference to struct that stores additional memory allocation info
    597  *   @streamType: Type of stream the buffers belongs to
    598  *
    599  * RETURN     : none
    600  *==========================================================================*/
    601 void QCameraMemoryPool::releaseBuffer(
    602         struct QCameraMemory::QCameraMemInfo &memInfo,
    603         cam_stream_type_t streamType)
    604 {
    605     pthread_mutex_lock(&mLock);
    606 
    607     mPools[streamType].push_back(memInfo);
    608 
    609     pthread_mutex_unlock(&mLock);
    610 }
    611 
    612 /*===========================================================================
    613  * FUNCTION   : clear
    614  *
    615  * DESCRIPTION: clears all cached buffers
    616  *
    617  * PARAMETERS : none
    618  *
    619  * RETURN     : none
    620  *==========================================================================*/
    621 void QCameraMemoryPool::clear()
    622 {
    623     pthread_mutex_lock(&mLock);
    624 
    625     for (int i = CAM_STREAM_TYPE_DEFAULT; i < CAM_STREAM_TYPE_MAX; i++ ) {
    626         List<struct QCameraMemory::QCameraMemInfo>::iterator it;
    627         it = mPools[i].begin();
    628         for( ; it != mPools[i].end() ; it++) {
    629             QCameraMemory::deallocOneBuffer(*it);
    630         }
    631 
    632         mPools[i].clear();
    633     }
    634 
    635     pthread_mutex_unlock(&mLock);
    636 }
    637 
    638 /*===========================================================================
    639  * FUNCTION   : findBufferLocked
    640  *
    641  * DESCRIPTION: search for a appropriate cached buffer
    642  *
    643  * PARAMETERS :
    644  *   @memInfo : reference to struct that stores additional memory allocation info
    645  *   @heap_id : type of heap
    646  *   @size    : size of the buffer
    647  *   @cached  : whether the buffer should be cached
    648  *   @streaType: type of stream this buffer belongs to
    649  *
    650  * RETURN     : int32_t type of status
    651  *              NO_ERROR  -- success
    652  *              none-zero failure code
    653  *==========================================================================*/
    654 int QCameraMemoryPool::findBufferLocked(
    655         struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id,
    656         size_t size, bool cached, cam_stream_type_t streamType)
    657 {
    658     int rc = NAME_NOT_FOUND;
    659 
    660     if (mPools[streamType].empty()) {
    661         return NAME_NOT_FOUND;
    662     }
    663 
    664     List<struct QCameraMemory::QCameraMemInfo>::iterator it = mPools[streamType].begin();
    665     if (streamType == CAM_STREAM_TYPE_OFFLINE_PROC) {
    666         for( ; it != mPools[streamType].end() ; it++) {
    667             if( ((*it).size == size) &&
    668                     ((*it).heap_id == heap_id) &&
    669                     ((*it).cached == cached) ) {
    670                 memInfo = *it;
    671                 LOGD("Found buffer %lx size %d",
    672                          (unsigned long)memInfo.handle, memInfo.size);
    673                 mPools[streamType].erase(it);
    674                 rc = NO_ERROR;
    675                 break;
    676             }
    677         }
    678     } else {
    679         for( ; it != mPools[streamType].end() ; it++) {
    680             if(((*it).size >= size) &&
    681                     ((*it).heap_id == heap_id) &&
    682                     ((*it).cached == cached) ) {
    683                 memInfo = *it;
    684                 LOGD("Found buffer %lx size %d",
    685                          (unsigned long)memInfo.handle, memInfo.size);
    686                 mPools[streamType].erase(it);
    687                 rc = NO_ERROR;
    688                 break;
    689             }
    690         }
    691     }
    692 
    693     return rc;
    694 }
    695 
    696 /*===========================================================================
    697  * FUNCTION   : allocateBuffer
    698  *
    699  * DESCRIPTION: allocates a buffer from the memory pool,
    700  *              it will re-use cached buffers if possible
    701  *
    702  * PARAMETERS :
    703  *   @memInfo : reference to struct that stores additional memory allocation info
    704  *   @heap_id : type of heap
    705  *   @size    : size of the buffer
    706  *   @cached  : whether the buffer should be cached
    707  *   @streaType: type of stream this buffer belongs to
    708  *   @secure_mode : secure mode
    709  *
    710  * RETURN     : int32_t type of status
    711  *              NO_ERROR  -- success
    712  *              none-zero failure code
    713  *==========================================================================*/
    714 int QCameraMemoryPool::allocateBuffer(
    715         struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id,
    716         size_t size, bool cached, cam_stream_type_t streamType,
    717         bool secure_mode)
    718 {
    719     int rc = NO_ERROR;
    720 
    721     pthread_mutex_lock(&mLock);
    722 
    723     rc = findBufferLocked(memInfo, heap_id, size, cached, streamType);
    724     if (NAME_NOT_FOUND == rc ) {
    725         LOGD("Buffer not found!");
    726         rc = QCameraMemory::allocOneBuffer(memInfo, heap_id, size, cached,
    727                  secure_mode);
    728     }
    729 
    730     pthread_mutex_unlock(&mLock);
    731 
    732     return rc;
    733 }
    734 
    735 /*===========================================================================
    736  * FUNCTION   : QCameraHeapMemory
    737  *
    738  * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL
    739  *
    740  * PARAMETERS :
    741  *   @cached  : flag indicates if using cached memory
    742  *
    743  * RETURN     : none
    744  *==========================================================================*/
    745 QCameraHeapMemory::QCameraHeapMemory(bool cached)
    746     : QCameraMemory(cached)
    747 {
    748     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
    749         mPtr[i] = NULL;
    750 }
    751 
    752 /*===========================================================================
    753  * FUNCTION   : ~QCameraHeapMemory
    754  *
    755  * DESCRIPTION: deconstructor of QCameraHeapMemory
    756  *
    757  * PARAMETERS : none
    758  *
    759  * RETURN     : none
    760  *==========================================================================*/
    761 QCameraHeapMemory::~QCameraHeapMemory()
    762 {
    763 }
    764 
    765 /*===========================================================================
    766  * FUNCTION   : getPtr
    767  *
    768  * DESCRIPTION: return buffer pointer
    769  *
    770  * PARAMETERS :
    771  *   @index   : index of the buffer
    772  *
    773  * RETURN     : buffer ptr
    774  *==========================================================================*/
    775 void *QCameraHeapMemory::getPtr(uint32_t index) const
    776 {
    777     if (index >= mBufferCount) {
    778         LOGE("index out of bound");
    779         return (void *)NULL;
    780     }
    781     return mPtr[index];
    782 }
    783 
    784 /*===========================================================================
    785  * FUNCTION   : allocate
    786  *
    787  * DESCRIPTION: allocate requested number of buffers of certain size
    788  *
    789  * PARAMETERS :
    790  *   @count   : number of buffers to be allocated
    791  *   @size    : lenght of the buffer to be allocated
    792  *
    793  * RETURN     : int32_t type of status
    794  *              NO_ERROR  -- success
    795  *              none-zero failure code
    796  *==========================================================================*/
    797 int QCameraHeapMemory::allocate(uint8_t count, size_t size)
    798 {
    799     int rc = -1;
    800     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "HeapMemsize", size, count);
    801     uint32_t heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
    802     if (mBufType & QCAMERA_MEM_TYPE_SECURE) {
    803         rc = alloc(count, size, heap_id_mask);
    804         if (rc < 0) {
    805             ATRACE_END();
    806             return rc;
    807         }
    808     } else {
    809         rc = alloc(count, size, heap_id_mask);
    810         if (rc < 0) {
    811             ATRACE_END();
    812             return rc;
    813         }
    814 
    815         for (int i = 0; i < count; i ++) {
    816             void *vaddr = mmap(NULL,
    817                         mMemInfo[i].size,
    818                         PROT_READ | PROT_WRITE,
    819                         MAP_SHARED,
    820                         mMemInfo[i].fd, 0);
    821             if (vaddr == MAP_FAILED) {
    822                 for (int j = i-1; j >= 0; j --) {
    823                     munmap(mPtr[j], mMemInfo[j].size);
    824                     mPtr[j] = NULL;
    825                     deallocOneBuffer(mMemInfo[j]);
    826                 }
    827                 // Deallocate remaining buffers that have already been allocated
    828                 for (int j = i; j < count; j++) {
    829                     deallocOneBuffer(mMemInfo[j]);
    830                 }
    831                 ATRACE_END();
    832                 return NO_MEMORY;
    833             } else
    834                 mPtr[i] = vaddr;
    835         }
    836     }
    837     if (rc == 0) {
    838         mBufferCount = count;
    839     }
    840     ATRACE_END();
    841     return OK;
    842 }
    843 
    844 /*===========================================================================
    845  * FUNCTION   : allocateMore
    846  *
    847  * DESCRIPTION: allocate more requested number of buffers of certain size
    848  *
    849  * PARAMETERS :
    850  *   @count   : number of buffers to be allocated
    851  *   @size    : lenght of the buffer to be allocated
    852  *
    853  * RETURN     : int32_t type of status
    854  *              NO_ERROR  -- success
    855  *              none-zero failure code
    856  *==========================================================================*/
    857 int QCameraHeapMemory::allocateMore(uint8_t count, size_t size)
    858 {
    859     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "HeapMemsize", size, count);
    860     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
    861     int rc = alloc(count, size, heap_id_mask);
    862     if (rc < 0) {
    863         ATRACE_END();
    864         return rc;
    865     }
    866 
    867     for (int i = mBufferCount; i < count + mBufferCount; i ++) {
    868         void *vaddr = mmap(NULL,
    869                     mMemInfo[i].size,
    870                     PROT_READ | PROT_WRITE,
    871                     MAP_SHARED,
    872                     mMemInfo[i].fd, 0);
    873         if (vaddr == MAP_FAILED) {
    874             for (int j = i-1; j >= mBufferCount; j --) {
    875                 munmap(mPtr[j], mMemInfo[j].size);
    876                 mPtr[j] = NULL;
    877                 deallocOneBuffer(mMemInfo[j]);
    878             }
    879             ATRACE_END();
    880             return NO_MEMORY;
    881         } else {
    882             mPtr[i] = vaddr;
    883         }
    884     }
    885     mBufferCount = (uint8_t)(mBufferCount + count);
    886     ATRACE_END();
    887     return OK;
    888 }
    889 
    890 /*===========================================================================
    891  * FUNCTION   : deallocate
    892  *
    893  * DESCRIPTION: deallocate buffers
    894  *
    895  * PARAMETERS : none
    896  *
    897  * RETURN     : none
    898  *==========================================================================*/
    899 void QCameraHeapMemory::deallocate()
    900 {
    901     for (int i = 0; i < mBufferCount; i++) {
    902         munmap(mPtr[i], mMemInfo[i].size);
    903         mPtr[i] = NULL;
    904     }
    905     dealloc();
    906     mBufferCount = 0;
    907 }
    908 
    909 /*===========================================================================
    910  * FUNCTION   : cacheOps
    911  *
    912  * DESCRIPTION: ion related memory cache operations
    913  *
    914  * PARAMETERS :
    915  *   @index   : index of the buffer
    916  *   @cmd     : cache ops command
    917  *
    918  * RETURN     : int32_t type of status
    919  *              NO_ERROR  -- success
    920  *              none-zero failure code
    921  *==========================================================================*/
    922 int QCameraHeapMemory::cacheOps(uint32_t index, unsigned int cmd)
    923 {
    924     if (index >= mBufferCount)
    925         return BAD_INDEX;
    926     return cacheOpsInternal(index, cmd, mPtr[index]);
    927 }
    928 
    929 /*===========================================================================
    930  * FUNCTION   : getRegFlags
    931  *
    932  * DESCRIPTION: query initial reg flags
    933  *
    934  * PARAMETERS :
    935  *   @regFlags: initial reg flags of the allocated buffers
    936  *
    937  * RETURN     : int32_t type of status
    938  *              NO_ERROR  -- success
    939  *              none-zero failure code
    940  *==========================================================================*/
    941 int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const
    942 {
    943     return INVALID_OPERATION;
    944 }
    945 
    946 /*===========================================================================
    947  * FUNCTION   : getMemory
    948  *
    949  * DESCRIPTION: get camera memory
    950  *
    951  * PARAMETERS :
    952  *   @index   : buffer index
    953  *   @metadata: flag if it's metadata
    954  *
    955  * RETURN     : camera memory ptr
    956  *              NULL if not supported or failed
    957  *==========================================================================*/
    958 camera_memory_t *QCameraHeapMemory::getMemory(uint32_t /*index*/, bool /*metadata*/) const
    959 {
    960     return NULL;
    961 }
    962 
    963 /*===========================================================================
    964  * FUNCTION   : getMatchBufIndex
    965  *
    966  * DESCRIPTION: query buffer index by opaque ptr
    967  *
    968  * PARAMETERS :
    969  *   @opaque  : opaque ptr
    970  *   @metadata: flag if it's metadata
    971  *
    972  * RETURN     : buffer index if match found,
    973  *              -1 if failed
    974  *==========================================================================*/
    975 int QCameraHeapMemory::getMatchBufIndex(const void *opaque,
    976                                         bool metadata) const
    977 {
    978     int index = -1;
    979     if (metadata) {
    980         return -1;
    981     }
    982     for (int i = 0; i < mBufferCount; i++) {
    983         if (mPtr[i] == opaque) {
    984             index = i;
    985             break;
    986         }
    987     }
    988     return index;
    989 }
    990 
    991 /*===========================================================================
    992  * FUNCTION   : QCameraMetadataStreamMemory
    993  *
    994  * DESCRIPTION: constructor of QCameraMetadataStreamMemory
    995  *              for ion memory used internally in HAL for metadata
    996  *
    997  * PARAMETERS :
    998  *   @cached  : flag indicates if using cached memory
    999  *
   1000  * RETURN     : none
   1001  *==========================================================================*/
   1002 QCameraMetadataStreamMemory::QCameraMetadataStreamMemory(bool cached)
   1003     : QCameraHeapMemory(cached)
   1004 {
   1005 }
   1006 
   1007 /*===========================================================================
   1008  * FUNCTION   : ~QCameraMetadataStreamMemory
   1009  *
   1010  * DESCRIPTION: destructor of QCameraMetadataStreamMemory
   1011  *
   1012  * PARAMETERS : none
   1013  *
   1014  * RETURN     : none
   1015  *==========================================================================*/
   1016 QCameraMetadataStreamMemory::~QCameraMetadataStreamMemory()
   1017 {
   1018     if (mBufferCount > 0) {
   1019         LOGH("%s, buf_cnt > 0, deallocate buffers now.\n", __func__);
   1020         deallocate();
   1021     }
   1022 }
   1023 
   1024 /*===========================================================================
   1025  * FUNCTION   : getRegFlags
   1026  *
   1027  * DESCRIPTION: query initial reg flags
   1028  *
   1029  * PARAMETERS :
   1030  *   @regFlags: initial reg flags of the allocated buffers
   1031  *
   1032  * RETURN     : int32_t type of status
   1033  *              NO_ERROR  -- success
   1034  *              none-zero failure code
   1035  *==========================================================================*/
   1036 int QCameraMetadataStreamMemory::getRegFlags(uint8_t *regFlags) const
   1037 {
   1038     for (int i = 0; i < mBufferCount; i ++) {
   1039         regFlags[i] = 1;
   1040     }
   1041     return NO_ERROR;
   1042 }
   1043 
   1044 /*===========================================================================
   1045  * FUNCTION   : QCameraStreamMemory
   1046  *
   1047  * DESCRIPTION: constructor of QCameraStreamMemory
   1048  *              ION memory allocated directly from /dev/ion and shared with framework
   1049  *
   1050  * PARAMETERS :
   1051  *   @memory        : camera memory request ops table
   1052  *   @cached        : flag indicates if using cached memory
   1053  *   @pool          : memory pool ptr
   1054  *   @streamType    : stream type
   1055  *   @bufType       : buffer type to allocate
   1056  *
   1057  * RETURN     : none
   1058  *==========================================================================*/
   1059 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory memory,
   1060         void* cbCookie,
   1061         bool cached,
   1062         QCameraMemoryPool *pool,
   1063         cam_stream_type_t streamType, QCameraMemType bufType)
   1064     :QCameraMemory(cached, pool, streamType, bufType),
   1065      mGetMemory(memory),
   1066      mCallbackCookie(cbCookie)
   1067 {
   1068     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
   1069         mCameraMemory[i] = NULL;
   1070 }
   1071 
   1072 /*===========================================================================
   1073  * FUNCTION   : ~QCameraStreamMemory
   1074  *
   1075  * DESCRIPTION: deconstructor of QCameraStreamMemory
   1076  *
   1077  * PARAMETERS : none
   1078  *
   1079  * RETURN     : none
   1080  *==========================================================================*/
   1081 QCameraStreamMemory::~QCameraStreamMemory()
   1082 {
   1083 }
   1084 
   1085 /*===========================================================================
   1086  * FUNCTION   : allocate
   1087  *
   1088  * DESCRIPTION: allocate requested number of buffers of certain size
   1089  *
   1090  * PARAMETERS :
   1091  *   @count   : number of buffers to be allocated
   1092  *   @size    : lenght of the buffer to be allocated
   1093  *
   1094  * RETURN     : int32_t type of status
   1095  *              NO_ERROR  -- success
   1096  *              none-zero failure code
   1097  *==========================================================================*/
   1098 int QCameraStreamMemory::allocate(uint8_t count, size_t size)
   1099 {
   1100     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "StreamMemsize", size, count);
   1101     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
   1102     int rc = alloc(count, size, heap_id_mask);
   1103     if (rc < 0) {
   1104         ATRACE_END();
   1105         return rc;
   1106     }
   1107 
   1108     for (int i = 0; i < count; i ++) {
   1109         if (mBufType & QCAMERA_MEM_TYPE_SECURE) {
   1110             mCameraMemory[i] = 0;
   1111         } else {
   1112             mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, mCallbackCookie);
   1113         }
   1114     }
   1115     mBufferCount = count;
   1116     ATRACE_END();
   1117     return NO_ERROR;
   1118 }
   1119 
   1120 /*===========================================================================
   1121  * FUNCTION   : allocateMore
   1122  *
   1123  * DESCRIPTION: allocate more requested number of buffers of certain size
   1124  *
   1125  * PARAMETERS :
   1126  *   @count   : number of buffers to be allocated
   1127  *   @size    : lenght of the buffer to be allocated
   1128  *
   1129  * RETURN     : int32_t type of status
   1130  *              NO_ERROR  -- success
   1131  *              none-zero failure code
   1132  *==========================================================================*/
   1133 int QCameraStreamMemory::allocateMore(uint8_t count, size_t size)
   1134 {
   1135     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "StreamMemsize", size, count);
   1136     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
   1137     int rc = alloc(count, size, heap_id_mask);
   1138     if (rc < 0) {
   1139         ATRACE_END();
   1140         return rc;
   1141     }
   1142 
   1143     for (int i = mBufferCount; i < mBufferCount + count; i++) {
   1144         mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, mCallbackCookie);
   1145     }
   1146     mBufferCount = (uint8_t)(mBufferCount + count);
   1147     ATRACE_END();
   1148     return NO_ERROR;
   1149 }
   1150 
   1151 /*===========================================================================
   1152  * FUNCTION   : deallocate
   1153  *
   1154  * DESCRIPTION: deallocate buffers
   1155  *
   1156  * PARAMETERS : none
   1157  *
   1158  * RETURN     : none
   1159  *==========================================================================*/
   1160 void QCameraStreamMemory::deallocate()
   1161 {
   1162     for (int i = 0; i < mBufferCount; i ++) {
   1163         if (mCameraMemory[i])
   1164             mCameraMemory[i]->release(mCameraMemory[i]);
   1165         mCameraMemory[i] = NULL;
   1166     }
   1167     dealloc();
   1168     mBufferCount = 0;
   1169 }
   1170 
   1171 /*===========================================================================
   1172  * FUNCTION   : cacheOps
   1173  *
   1174  * DESCRIPTION: ion related memory cache operations
   1175  *
   1176  * PARAMETERS :
   1177  *   @index   : index of the buffer
   1178  *   @cmd     : cache ops command
   1179  *
   1180  * RETURN     : int32_t type of status
   1181  *              NO_ERROR  -- success
   1182  *              none-zero failure code
   1183  *==========================================================================*/
   1184 int QCameraStreamMemory::cacheOps(uint32_t index, unsigned int cmd)
   1185 {
   1186     if (index >= mBufferCount)
   1187         return BAD_INDEX;
   1188     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
   1189 }
   1190 
   1191 /*===========================================================================
   1192  * FUNCTION   : getRegFlags
   1193  *
   1194  * DESCRIPTION: query initial reg flags
   1195  *
   1196  * PARAMETERS :
   1197  *   @regFlags: initial reg flags of the allocated buffers
   1198  *
   1199  * RETURN     : int32_t type of status
   1200  *              NO_ERROR  -- success
   1201  *              none-zero failure code
   1202  *==========================================================================*/
   1203 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
   1204 {
   1205     for (int i = 0; i < mBufferCount; i ++)
   1206         regFlags[i] = 1;
   1207     return NO_ERROR;
   1208 }
   1209 
   1210 /*===========================================================================
   1211  * FUNCTION   : getMemory
   1212  *
   1213  * DESCRIPTION: get camera memory
   1214  *
   1215  * PARAMETERS :
   1216  *   @index   : buffer index
   1217  *   @metadata: flag if it's metadata
   1218  *
   1219  * RETURN     : camera memory ptr
   1220  *              NULL if not supported or failed
   1221  *==========================================================================*/
   1222 camera_memory_t *QCameraStreamMemory::getMemory(uint32_t index,
   1223         bool metadata) const
   1224 {
   1225     if (index >= mBufferCount || metadata)
   1226         return NULL;
   1227     return mCameraMemory[index];
   1228 }
   1229 
   1230 /*===========================================================================
   1231  * FUNCTION   : getMatchBufIndex
   1232  *
   1233  * DESCRIPTION: query buffer index by opaque ptr
   1234  *
   1235  * PARAMETERS :
   1236  *   @opaque  : opaque ptr
   1237  *   @metadata: flag if it's metadata
   1238  *
   1239  * RETURN     : buffer index if match found,
   1240  *              -1 if failed
   1241  *==========================================================================*/
   1242 int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
   1243                                           bool metadata) const
   1244 {
   1245     int index = -1;
   1246     if (metadata) {
   1247         return -1;
   1248     }
   1249     for (int i = 0; i < mBufferCount; i++) {
   1250         if (mCameraMemory[i]->data == opaque) {
   1251             index = i;
   1252             break;
   1253         }
   1254     }
   1255     return index;
   1256 }
   1257 
   1258 /*===========================================================================
   1259  * FUNCTION   : getPtr
   1260  *
   1261  * DESCRIPTION: return buffer pointer
   1262  *
   1263  * PARAMETERS :
   1264  *   @index   : index of the buffer
   1265  *
   1266  * RETURN     : buffer ptr
   1267  *==========================================================================*/
   1268 void *QCameraStreamMemory::getPtr(uint32_t index) const
   1269 {
   1270     if (index >= mBufferCount) {
   1271         LOGE("index out of bound");
   1272         return NULL;
   1273     }
   1274     if (mCameraMemory[index] == 0) {
   1275         return NULL;
   1276     }
   1277     return mCameraMemory[index]->data;
   1278 }
   1279 
   1280 /*===========================================================================
   1281  * FUNCTION   : QCameraVideoMemory
   1282  *
   1283  * DESCRIPTION: constructor of QCameraVideoMemory
   1284  *              VideoStream buffers also include metadata buffers
   1285  *
   1286  * PARAMETERS :
   1287  *   @memory    : camera memory request ops table
   1288  *   @cached    : flag indicates if using cached memory
   1289  *   @bufType   : buffer type to allocate
   1290  *
   1291  * RETURN     : none
   1292  *==========================================================================*/
   1293 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory, void* cbCookie,
   1294                                        bool cached, QCameraMemType bufType)
   1295     : QCameraStreamMemory(memory, cbCookie, cached)
   1296 {
   1297     memset(mMetadata, 0, sizeof(mMetadata));
   1298     memset(mNativeHandle, 0, sizeof(mNativeHandle));
   1299     mMetaBufCount = 0;
   1300     mBufType = bufType;
   1301     //Set Default color conversion format
   1302     mUsage = private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
   1303 
   1304     //Set Default frame format
   1305     mFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   1306 }
   1307 
   1308 /*===========================================================================
   1309  * FUNCTION   : ~QCameraVideoMemory
   1310  *
   1311  * DESCRIPTION: deconstructor of QCameraVideoMemory
   1312  *
   1313  * PARAMETERS : none
   1314  *
   1315  * RETURN     : none
   1316  *==========================================================================*/
   1317 QCameraVideoMemory::~QCameraVideoMemory()
   1318 {
   1319 }
   1320 
   1321 /*===========================================================================
   1322  * FUNCTION   : allocate
   1323  *
   1324  * DESCRIPTION: allocate requested number of buffers of certain size
   1325  *
   1326  * PARAMETERS :
   1327  *   @count   : number of buffers to be allocated
   1328  *   @size    : lenght of the buffer to be allocated
   1329  *
   1330  * RETURN     : int32_t type of status
   1331  *              NO_ERROR  -- success
   1332  *              none-zero failure code
   1333  *==========================================================================*/
   1334 int QCameraVideoMemory::allocate(uint8_t count, size_t size)
   1335 {
   1336     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "VideoMemsize", size, count);
   1337     int rc = QCameraStreamMemory::allocate(count, size);
   1338     if (rc < 0) {
   1339         ATRACE_END();
   1340         return rc;
   1341     }
   1342 
   1343     if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
   1344         rc = allocateMeta(count, 1);
   1345         if (rc != NO_ERROR) {
   1346             ATRACE_END();
   1347             return rc;
   1348         }
   1349         for (int i = 0; i < count; i ++) {
   1350             native_handle_t *nh =  mNativeHandle[i];
   1351             if (!nh) {
   1352                 LOGE("Error in getting video native handle");
   1353                 ATRACE_END();
   1354                 return NO_MEMORY;
   1355             }
   1356             //Fill video metadata.
   1357             updateNativeHandle(nh, 0, mMemInfo[i].fd, (int)mMemInfo[i].size);
   1358         }
   1359     }
   1360     mBufferCount = count;
   1361     ATRACE_END();
   1362     return NO_ERROR;
   1363 }
   1364 
   1365 /*===========================================================================
   1366  * FUNCTION   : allocateMore
   1367  *
   1368  * DESCRIPTION: allocate more requested number of buffers of certain size
   1369  *
   1370  * PARAMETERS :
   1371  *   @count   : number of buffers to be allocated
   1372  *   @size    : lenght of the buffer to be allocated
   1373  *
   1374  * RETURN     : int32_t type of status
   1375  *              NO_ERROR  -- success
   1376  *              none-zero failure code
   1377  *==========================================================================*/
   1378 int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
   1379 {
   1380     ATRACE_BEGIN_SNPRINTF("%s %zu %d", "VideoMemsize", size, count);
   1381     int rc = QCameraStreamMemory::allocateMore(count, size);
   1382     if (rc < 0) {
   1383         ATRACE_END();
   1384         return rc;
   1385     }
   1386 
   1387     if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) {
   1388         for (int i = mBufferCount; i < count + mBufferCount; i ++) {
   1389             mMetadata[i] = mGetMemory(-1,
   1390                     sizeof(media_metadata_buffer), 1, mCallbackCookie);
   1391             if (!mMetadata[i]) {
   1392                 LOGE("allocation of video metadata failed.");
   1393                 for (int j = mBufferCount; j <= i-1; j ++) {
   1394                     mMetadata[j]->release(mMetadata[j]);
   1395                     mCameraMemory[j]->release(mCameraMemory[j]);
   1396                     mCameraMemory[j] = NULL;
   1397                     deallocOneBuffer(mMemInfo[j]);;
   1398                 }
   1399                 ATRACE_END();
   1400                 return NO_MEMORY;
   1401             }
   1402             media_metadata_buffer * packet =
   1403                     (media_metadata_buffer *)mMetadata[i]->data;
   1404             mNativeHandle[i] = native_handle_create(1, VIDEO_METADATA_NUM_INTS);
   1405 #ifdef USE_MEDIA_EXTENSIONS
   1406             packet->eType = kMetadataBufferTypeNativeHandleSource;
   1407             packet->pHandle = NULL;
   1408 #else
   1409             packet->buffer_type = kMetadataBufferTypeCameraSource;
   1410             packet->meta_handle = mNativeHandle[i];
   1411 #endif
   1412             native_handle_t *nh =  mNativeHandle[i];
   1413             if (!nh) {
   1414                 LOGE("Error in getting video native handle");
   1415                 ATRACE_END();
   1416                 return NO_MEMORY;
   1417             }
   1418 
   1419             MetaBufferUtil::setFdAt(nh, 0, -1);
   1420             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_OFFSET, 0);
   1421             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_SIZE, 0);
   1422             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_USAGE, mUsage);
   1423             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_TIMESTAMP, 0);
   1424             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_FORMAT, mFormat);
   1425             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_BUFIDX, i);
   1426             MetaBufferUtil::setIntAt(nh, 0, VIDEO_META_EVENT, 0);
   1427 
   1428             //Fill video metadata.
   1429             updateNativeHandle(nh, 0, mMemInfo[i].fd, (int)mMemInfo[i].size);
   1430 
   1431         }
   1432     }
   1433     mBufferCount = (uint8_t)(mBufferCount + count);
   1434     mMetaBufCount = mBufferCount;
   1435     ATRACE_END();
   1436     return NO_ERROR;
   1437 }
   1438 
   1439 /*===========================================================================
   1440  * FUNCTION   : allocateMeta
   1441  *
   1442  * DESCRIPTION: allocate video encoder metadata structure
   1443  *
   1444  * PARAMETERS :
   1445  *   @buf_cnt : Total buffer count
   1446  *   @numFDs: Number of FDs
   1447  *
   1448  * RETURN     : int32_t type of status
   1449  *              NO_ERROR  -- success
   1450  *              none-zero failure code
   1451  *==========================================================================*/
   1452 int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs)
   1453 {
   1454     int rc = NO_ERROR;
   1455     int mTotalInts = 0;
   1456 
   1457     for (int i = 0; i < buf_cnt; i++) {
   1458         mMetadata[i] = mGetMemory(-1,
   1459                 sizeof(media_metadata_buffer), 1, mCallbackCookie);
   1460         if (!mMetadata[i]) {
   1461             LOGE("allocation of video metadata failed.");
   1462             for (int j = (i - 1); j >= 0; j--) {
   1463                 if (NULL != mNativeHandle[j]) {
   1464                    native_handle_delete(mNativeHandle[j]);
   1465                 }
   1466                 mMetadata[j]->release(mMetadata[j]);
   1467             }
   1468             return NO_MEMORY;
   1469         }
   1470         media_metadata_buffer *packet =
   1471                 (media_metadata_buffer *)mMetadata[i]->data;
   1472         mTotalInts = MetaBufferUtil::getNumIntsForBatch(numFDs);
   1473         mNativeHandle[i] = native_handle_create(numFDs, mTotalInts);
   1474         if (mNativeHandle[i] == NULL) {
   1475             LOGE("Error in getting video native handle");
   1476             for (int j = (i - 1); j >= 0; j--) {
   1477                 mMetadata[i]->release(mMetadata[i]);
   1478                 if (NULL != mNativeHandle[j]) {
   1479                    native_handle_delete(mNativeHandle[j]);
   1480                 }
   1481                 mMetadata[j]->release(mMetadata[j]);
   1482             }
   1483             return NO_MEMORY;
   1484         } else {
   1485             //assign buffer index to native handle.
   1486             native_handle_t *nh =  mNativeHandle[i];
   1487             for (int j = 0; j < numFDs; j++) {
   1488                 MetaBufferUtil::setFdAt(nh, j, -1);
   1489                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_OFFSET, 0);
   1490                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_SIZE, 0);
   1491                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_USAGE, mUsage);
   1492                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_TIMESTAMP, 0);
   1493                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_FORMAT, mFormat);
   1494                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_BUFIDX, i);
   1495                 MetaBufferUtil::setIntAt(nh, j, VIDEO_META_EVENT, 0);
   1496             }
   1497         }
   1498 #ifdef USE_MEDIA_EXTENSIONS
   1499         packet->eType = kMetadataBufferTypeNativeHandleSource;
   1500         packet->pHandle = NULL;
   1501 #else
   1502         packet->buffer_type = kMetadataBufferTypeCameraSource;
   1503         packet->meta_handle = mNativeHandle[i];
   1504 #endif
   1505     }
   1506     mMetaBufCount = buf_cnt;
   1507     return rc;
   1508 }
   1509 
   1510 /*===========================================================================
   1511  * FUNCTION   : deallocateMeta
   1512  *
   1513  * DESCRIPTION: deallocate video metadata buffers
   1514  *
   1515  * PARAMETERS : none
   1516  *
   1517  * RETURN     : none
   1518  *==========================================================================*/
   1519 void QCameraVideoMemory::deallocateMeta()
   1520 {
   1521     for (int i = 0; i < mMetaBufCount; i++) {
   1522         native_handle_t *nh = mNativeHandle[i];
   1523         if (NULL != nh) {
   1524            if (native_handle_delete(nh)) {
   1525                LOGE("Unable to delete native handle");
   1526            }
   1527         } else {
   1528            LOGE("native handle not available");
   1529         }
   1530         mNativeHandle[i] = NULL;
   1531         mMetadata[i]->release(mMetadata[i]);
   1532         mMetadata[i] = NULL;
   1533     }
   1534     mMetaBufCount = 0;
   1535 }
   1536 
   1537 
   1538 /*===========================================================================
   1539  * FUNCTION   : deallocate
   1540  *
   1541  * DESCRIPTION: deallocate buffers
   1542  *
   1543  * PARAMETERS : none
   1544  *
   1545  * RETURN     : none
   1546  *==========================================================================*/
   1547 void QCameraVideoMemory::deallocate()
   1548 {
   1549     deallocateMeta();
   1550 
   1551     QCameraStreamMemory::deallocate();
   1552     mBufferCount = 0;
   1553     mMetaBufCount = 0;
   1554 }
   1555 
   1556 /*===========================================================================
   1557  * FUNCTION   : getMemory
   1558  *
   1559  * DESCRIPTION: get camera memory
   1560  *
   1561  * PARAMETERS :
   1562  *   @index   : buffer index
   1563  *   @metadata: flag if it's metadata
   1564  *
   1565  * RETURN     : camera memory ptr
   1566  *              NULL if not supported or failed
   1567  *==========================================================================*/
   1568 camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index,
   1569         bool metadata) const
   1570 {
   1571     if (index >= mMetaBufCount || (!metadata && index >= mBufferCount))
   1572         return NULL;
   1573 
   1574     if (metadata) {
   1575 #ifdef USE_MEDIA_EXTENSIONS
   1576         int i;
   1577         media_metadata_buffer *packet = NULL;
   1578 
   1579         for (i = 0; i < mMetaBufCount; i++) {
   1580             packet = (media_metadata_buffer *)mMetadata[i]->data;
   1581             if (packet != NULL && packet->pHandle == NULL) {
   1582                 packet->pHandle = mNativeHandle[index];
   1583                 break;
   1584             }
   1585         }
   1586         if (i < mMetaBufCount) {
   1587             return mMetadata[i];
   1588         } else {
   1589             LOGE("No free video meta memory");
   1590             return NULL;
   1591         }
   1592 #else
   1593         return mMetadata[index];
   1594 #endif
   1595     } else {
   1596         return mCameraMemory[index];
   1597     }
   1598 }
   1599 
   1600 /*===========================================================================
   1601  * FUNCTION   : getNativeHandle
   1602  *
   1603  * DESCRIPTION: getNativeHandle from video buffer
   1604  *
   1605  * PARAMETERS :
   1606  *   @index   : buffer index
   1607  *
   1608  * RETURN     : native_handle_t  * type of handle
   1609  *==========================================================================*/
   1610 native_handle_t *QCameraVideoMemory::getNativeHandle(uint32_t index, bool metadata)
   1611 {
   1612     if (index >= mMetaBufCount || !metadata)
   1613         return NULL;
   1614     return mNativeHandle[index];
   1615 }
   1616 
   1617 /*===========================================================================
   1618  * FUNCTION   : update native handle
   1619  *
   1620  * DESCRIPTION: update native handle with input parameter
   1621  *
   1622  * PARAMETERS :
   1623  *   @nh             : native handle to be updated
   1624  *   @batch_idx   : Batch index inside this native handle
   1625  *   @fd             : buffer fd to be updated
   1626  *   @size           : buffer size
   1627  *   @ts             : timestamp
   1628  *
   1629  * RETURN     : int32_t type of status
   1630  *              NO_ERROR  -- success
   1631  *              none-zero failure code
   1632  *==========================================================================*/
   1633 int32_t QCameraVideoMemory::updateNativeHandle(native_handle_t *nh,
   1634         int batch_idx, int fd, int size, int ts)
   1635 {
   1636     int32_t rc = NO_ERROR;
   1637     MetaBufferUtil::setFdAt(nh, batch_idx, fd);
   1638     MetaBufferUtil::setIntAt(nh, batch_idx, VIDEO_META_SIZE, size);
   1639     MetaBufferUtil::setIntAt(nh, batch_idx, VIDEO_META_TIMESTAMP, ts);
   1640     return rc;
   1641 }
   1642 
   1643 /*===========================================================================
   1644  * FUNCTION   : closeNativeHandle
   1645  *
   1646  * DESCRIPTION: close video native handle and update cached ptrs
   1647  *
   1648  * PARAMETERS :
   1649  *   @data  : ptr to video frame to be returned
   1650  *
   1651  * RETURN     : int32_t type of status
   1652  *              NO_ERROR  -- success
   1653  *              none-zero failure code
   1654  *==========================================================================*/
   1655 int QCameraVideoMemory::closeNativeHandle(const void *data)
   1656 {
   1657     int32_t rc = NO_ERROR;
   1658 
   1659 #ifdef USE_MEDIA_EXTENSIONS
   1660     const media_metadata_buffer *packet =
   1661             (const media_metadata_buffer *)data;
   1662     if ((packet != NULL) && (packet->eType ==
   1663             kMetadataBufferTypeNativeHandleSource)
   1664             && (packet->pHandle)) {
   1665         native_handle_close(packet->pHandle);
   1666         native_handle_delete(packet->pHandle);
   1667     } else {
   1668         LOGE("Invalid Data. Could not release");
   1669         return BAD_VALUE;
   1670     }
   1671 #else
   1672    (void)data;  // unused
   1673 #endif
   1674    return rc;
   1675 }
   1676 
   1677 /*===========================================================================
   1678  * FUNCTION   : closeNativeHandle
   1679  *
   1680  * DESCRIPTION: close video native handle and update cached ptrs
   1681  *
   1682  * PARAMETERS :
   1683  *   @data  : ptr to video frame to be returned
   1684  *   @metadata : Flag to update metadata mode
   1685  *
   1686  * RETURN     : int32_t type of status
   1687  *              NO_ERROR  -- success
   1688  *              none-zero failure code
   1689  *==========================================================================*/
   1690 int QCameraVideoMemory::closeNativeHandle(const void *data, bool metadata)
   1691 {
   1692     int32_t rc = NO_ERROR;
   1693 #ifdef USE_MEDIA_EXTENSIONS
   1694     if (metadata) {
   1695         const media_metadata_buffer *packet =
   1696                     (const media_metadata_buffer *)data;
   1697         if ((packet != NULL) && (packet->eType ==
   1698                 kMetadataBufferTypeNativeHandleSource)
   1699                 && (packet->pHandle)) {
   1700             native_handle_close(packet->pHandle);
   1701             native_handle_delete(packet->pHandle);
   1702             for (int i = 0; i < mMetaBufCount; i++) {
   1703                 if(mMetadata[i]->data == data) {
   1704                     media_metadata_buffer *mem =
   1705                             (media_metadata_buffer *)mMetadata[i]->data;
   1706                     mem->pHandle = NULL;
   1707                     break;
   1708                 }
   1709             }
   1710          } else {
   1711             LOGE("Invalid Data. Could not release");
   1712             return BAD_VALUE;
   1713         }
   1714     } else {
   1715         LOGW("Warning: Not of type video meta buffer");
   1716     }
   1717 #else
   1718    (void)data;  // unused
   1719    (void)metadata;  // unused
   1720 #endif
   1721     return rc;
   1722 }
   1723 
   1724 /*===========================================================================
   1725  * FUNCTION   : getMatchBufIndex
   1726  *
   1727  * DESCRIPTION: query buffer index by opaque ptr
   1728  *
   1729  * PARAMETERS :
   1730  *   @opaque  : opaque ptr
   1731  *   @metadata: flag if it's metadata
   1732  *
   1733  * RETURN     : buffer index if match found,
   1734  *              -1 if failed
   1735  *==========================================================================*/
   1736 int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
   1737                                          bool metadata) const
   1738 {
   1739     int index = -1;
   1740 
   1741     if (metadata) {
   1742 #ifdef USE_MEDIA_EXTENSIONS
   1743         const media_metadata_buffer *packet =
   1744                 (const media_metadata_buffer *)opaque;
   1745         native_handle_t *nh = NULL;
   1746         if ((packet != NULL) && (packet->eType ==
   1747                 kMetadataBufferTypeNativeHandleSource)
   1748                 && (packet->pHandle)) {
   1749             nh = (native_handle_t *)packet->pHandle;
   1750             int mBufIndex = MetaBufferUtil::getIntAt(nh, 0, VIDEO_META_BUFIDX);
   1751             for (int i = 0; i < mMetaBufCount; i++) {
   1752                 if(mBufIndex == MetaBufferUtil::getIntAt(
   1753                         mNativeHandle[i], 0, VIDEO_META_BUFIDX)) {
   1754                     index = i;
   1755                     break;
   1756                 }
   1757             }
   1758         }
   1759 #else
   1760 	    for (int i = 0; i < mMetaBufCount; i++) {
   1761             if(mMetadata[i]->data == opaque) {
   1762                 index = i;
   1763                 break;
   1764             }
   1765         }
   1766 #endif
   1767     } else {
   1768         for (int i = 0; i < mBufferCount; i++) {
   1769             if (mCameraMemory[i]->data == opaque) {
   1770                 index = i;
   1771                 break;
   1772             }
   1773         }
   1774     }
   1775     return index;
   1776 }
   1777 
   1778 /*===========================================================================
   1779  * FUNCTION   : setVideoInfo
   1780  *
   1781  * DESCRIPTION: set native window gralloc ops table
   1782  *
   1783  * PARAMETERS :
   1784  *   @usage : usage bit for video
   1785  *
   1786  * RETURN     : none
   1787  *==========================================================================*/
   1788 void QCameraVideoMemory::setVideoInfo(int usage, cam_format_t format)
   1789 {
   1790     mUsage |= usage;
   1791     mFormat = convCamtoOMXFormat(format);
   1792 }
   1793 
   1794 /*===========================================================================
   1795  * FUNCTION   : convCamtoOMXFormat
   1796  *
   1797  * DESCRIPTION: map cam_format_t to corresponding OMX format
   1798  *
   1799  * PARAMETERS :
   1800  *   @format : format in cam_format_t type
   1801  *
   1802  * RETURN     : omx format
   1803  *==========================================================================*/
   1804 int QCameraVideoMemory::convCamtoOMXFormat(cam_format_t format)
   1805 {
   1806     int omxFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   1807     switch (format) {
   1808         case CAM_FORMAT_YUV_420_NV21:
   1809         case CAM_FORMAT_YUV_420_NV21_VENUS:
   1810         case CAM_FORMAT_YUV_420_NV21_ADRENO:
   1811             omxFormat = QOMX_COLOR_FormatYVU420SemiPlanar;
   1812             break;
   1813         case CAM_FORMAT_YUV_420_NV12:
   1814         case CAM_FORMAT_YUV_420_NV12_VENUS:
   1815             omxFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   1816             break;
   1817         case CAM_FORMAT_YUV_420_NV12_UBWC:
   1818             omxFormat = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   1819             break;
   1820         default:
   1821             omxFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   1822     }
   1823     return omxFormat;
   1824 }
   1825 
   1826 /*===========================================================================
   1827  * FUNCTION   : needPerfEvent
   1828  *
   1829  * DESCRIPTION: checks if buffer turbo flush needed
   1830  *
   1831  * PARAMETERS :
   1832  *   @opaque  : opaque ptr
   1833  *   @metadata: flag if it's metadata
   1834  *
   1835  * RETURN     : buffer index if match found,
   1836  *              -1 if failed
   1837  *==========================================================================*/
   1838 bool QCameraVideoMemory::needPerfEvent(const void *opaque, bool metadata)
   1839 {
   1840     bool isPerf = FALSE;
   1841     if (metadata) {
   1842         const media_metadata_buffer *packet =
   1843                 (const media_metadata_buffer *)opaque;
   1844         native_handle_t *nh = NULL;
   1845 #ifdef USE_MEDIA_EXTENSIONS
   1846         if ((packet != NULL) && (packet->eType ==
   1847                 kMetadataBufferTypeNativeHandleSource)
   1848                 && (packet->pHandle)) {
   1849             nh = (native_handle_t *)packet->pHandle;
   1850         }
   1851         isPerf = (MetaBufferUtil::getIntAt(nh, 0, VIDEO_META_EVENT) ==
   1852                 CAM_META_BUFFER_EVENT_PERF) ? TRUE : FALSE;
   1853 #else
   1854 		if ((packet != NULL) && (packet->buffer_type ==
   1855                 kMetadataBufferTypeNativeHandleSource)
   1856                 && (packet->meta_handle)) {
   1857             nh = (native_handle_t *)packet->meta_handle;
   1858         }
   1859         for (int i = 0; i < mMetaBufCount; i++) {
   1860             if(mMetadata[i]->data == opaque) {
   1861                 isPerf = (MetaBufferUtil::getIntAt(nh, 0, VIDEO_META_EVENT) ==
   1862                         CAM_META_BUFFER_EVENT_PERF) ? TRUE : FALSE;
   1863                 break;
   1864             }
   1865         }
   1866 #endif
   1867     }
   1868     return isPerf;
   1869 }
   1870 
   1871 
   1872 /*===========================================================================
   1873  * FUNCTION   : QCameraGrallocMemory
   1874  *
   1875  * DESCRIPTION: constructor of QCameraGrallocMemory
   1876  *              preview stream buffers are allocated from gralloc native_windoe
   1877  *
   1878  * PARAMETERS :
   1879  *   @memory    : camera memory request ops table
   1880  *
   1881  * RETURN     : none
   1882  *==========================================================================*/
   1883 
   1884 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory memory, void* cbCookie, QCameraMemType bufType)
   1885         : QCameraMemory(true), mColorSpace(ITU_R_601_FR)
   1886 {
   1887     mMinUndequeuedBuffers = 0;
   1888     mMappableBuffers = 0;
   1889     mWindow = NULL;
   1890     mWidth = mHeight = mStride = mScanline = mUsage = 0;
   1891     mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
   1892     mCallbackCookie = cbCookie;
   1893     mGetMemory = memory;
   1894     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
   1895         mBufferHandle[i] = NULL;
   1896         mLocalFlag[i] = BUFFER_NOT_OWNED;
   1897         mPrivateHandle[i] = NULL;
   1898         mBufferStatus[i] = STATUS_IDLE;
   1899         mCameraMemory[i] = NULL;
   1900     }
   1901     mBufType =bufType;
   1902 }
   1903 
   1904 /*===========================================================================
   1905  * FUNCTION   : ~QCameraGrallocMemory
   1906  *
   1907  * DESCRIPTION: deconstructor of QCameraGrallocMemory
   1908  *
   1909  * PARAMETERS : none
   1910  *
   1911  * RETURN     : none
   1912  *==========================================================================*/
   1913 QCameraGrallocMemory::~QCameraGrallocMemory()
   1914 {
   1915 }
   1916 
   1917 /*===========================================================================
   1918  * FUNCTION   : setWindowInfo
   1919  *
   1920  * DESCRIPTION: set native window gralloc ops table
   1921  *
   1922  * PARAMETERS :
   1923  *   @window  : gralloc ops table ptr
   1924  *   @width   : width of preview frame
   1925  *   @height  : height of preview frame
   1926  *   @stride  : stride of preview frame
   1927  *   @scanline: scanline of preview frame
   1928  *   @foramt  : format of preview image
   1929  *   @maxFPS : max fps of preview stream
   1930  *   @usage : usage bit for gralloc
   1931  *
   1932  * RETURN     : none
   1933  *==========================================================================*/
   1934 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
   1935         int width, int height, int stride, int scanline, int format, int maxFPS, int usage)
   1936 {
   1937     mWindow = window;
   1938     mWidth = width;
   1939     mHeight = height;
   1940     mStride = stride;
   1941     mScanline = scanline;
   1942     mFormat = format;
   1943     mUsage = usage;
   1944     setMaxFPS(maxFPS);
   1945 }
   1946 
   1947 /*===========================================================================
   1948  * FUNCTION   : setMaxFPS
   1949  *
   1950  * DESCRIPTION: set max fps
   1951  *
   1952  * PARAMETERS :
   1953  *   @maxFPS : max fps of preview stream
   1954  *
   1955  * RETURN     : none
   1956  *==========================================================================*/
   1957 void QCameraGrallocMemory::setMaxFPS(int maxFPS)
   1958 {
   1959     /* input will be in multiples of 1000 */
   1960     maxFPS = (maxFPS + 500)/1000;
   1961 
   1962     /* set the lower cap to 30 always, because we are not supporting runtime update of fps info
   1963       to display. Otherwise MDP may result in underruns (for example if initial fps is 15max and later
   1964       changed to 30).*/
   1965     if (maxFPS < 30) {
   1966         maxFPS = 30;
   1967     }
   1968 
   1969     /* the new fps will be updated in metadata of the next frame enqueued to display*/
   1970     mMaxFPS = maxFPS;
   1971     LOGH("Setting max fps %d to display", maxFPS);
   1972 }
   1973 
   1974 /*===========================================================================
   1975  * FUNCTION   : displayBuffer
   1976  *
   1977  * DESCRIPTION: send received frame to display
   1978  *
   1979  * PARAMETERS :
   1980  *   @index   : index of preview frame
   1981  *
   1982  * RETURN     : int32_t type of status
   1983  *              NO_ERROR  -- success
   1984  *              none-zero failure code
   1985  *==========================================================================*/
   1986 int QCameraGrallocMemory::displayBuffer(uint32_t index)
   1987 {
   1988     int err = NO_ERROR;
   1989     int dequeuedIdx = BAD_INDEX;
   1990 
   1991     if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
   1992         LOGE("buffer to be enqueued is not owned");
   1993         return INVALID_OPERATION;
   1994     }
   1995 
   1996     err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
   1997     if(err != 0) {
   1998         LOGE("enqueue_buffer failed, err = %d", err);
   1999     } else {
   2000         LOGD("enqueue_buffer hdl=%p", *mBufferHandle[index]);
   2001         mLocalFlag[index] = BUFFER_NOT_OWNED;
   2002     }
   2003 
   2004     buffer_handle_t *buffer_handle = NULL;
   2005     int stride = 0;
   2006     err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
   2007     if (err == NO_ERROR && buffer_handle != NULL) {
   2008         int i;
   2009         LOGD("dequed buf hdl =%p", *buffer_handle);
   2010         for(i = 0; i < mMappableBuffers; i++) {
   2011             if(mBufferHandle[i] == buffer_handle) {
   2012                 LOGD("Found buffer in idx:%d", i);
   2013                 mLocalFlag[i] = BUFFER_OWNED;
   2014                 dequeuedIdx = i;
   2015                 break;
   2016             }
   2017         }
   2018 
   2019         if ((dequeuedIdx == BAD_INDEX) && (mMappableBuffers < mBufferCount)) {
   2020             dequeuedIdx = mMappableBuffers;
   2021             LOGD("Placing buffer in idx:%d", dequeuedIdx);
   2022             mBufferHandle[dequeuedIdx] = buffer_handle;
   2023             mLocalFlag[dequeuedIdx] = BUFFER_OWNED;
   2024 
   2025             mPrivateHandle[dequeuedIdx] =
   2026                     (struct private_handle_t *)(*mBufferHandle[dequeuedIdx]);
   2027             mMemInfo[dequeuedIdx].main_ion_fd = open("/dev/ion", O_RDONLY);
   2028             if (mMemInfo[dequeuedIdx].main_ion_fd < 0) {
   2029                 LOGE("failed: could not open ion device");
   2030                 return BAD_INDEX;
   2031             }
   2032 
   2033             struct ion_fd_data ion_info_fd;
   2034             memset(&ion_info_fd, 0, sizeof(ion_info_fd));
   2035             ion_info_fd.fd = mPrivateHandle[dequeuedIdx]->fd;
   2036             if (ioctl(mMemInfo[dequeuedIdx].main_ion_fd,
   2037                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
   2038                 LOGE("ION import failed\n");
   2039                 return BAD_INDEX;
   2040             }
   2041 
   2042             if (mBufType & QCAMERA_MEM_TYPE_SECURE) {
   2043                 LOGD("mBufType is QCAMERA_MEM_TYPE_SECURE. skip mGetMemory");
   2044             }else {
   2045                 mCameraMemory[dequeuedIdx] =
   2046                         mGetMemory(mPrivateHandle[dequeuedIdx]->fd,
   2047                         (size_t)mPrivateHandle[dequeuedIdx]->size,
   2048                         1,
   2049                         mCallbackCookie);
   2050             }
   2051             LOGH("idx = %d, fd = %d, size = %d, offset = %d",
   2052                      dequeuedIdx, mPrivateHandle[dequeuedIdx]->fd,
   2053                     mPrivateHandle[dequeuedIdx]->size,
   2054                     mPrivateHandle[dequeuedIdx]->offset);
   2055             mMemInfo[dequeuedIdx].fd = mPrivateHandle[dequeuedIdx]->fd;
   2056             mMemInfo[dequeuedIdx].size =
   2057                     (size_t)mPrivateHandle[dequeuedIdx]->size;
   2058             mMemInfo[dequeuedIdx].handle = ion_info_fd.handle;
   2059 
   2060             mMappableBuffers++;
   2061         }
   2062     } else {
   2063         LOGW("dequeue_buffer, no free buffer from display now");
   2064     }
   2065     return dequeuedIdx;
   2066 }
   2067 
   2068 /*===========================================================================
   2069  * FUNCTION   : enqueueBuffer
   2070  *
   2071  * DESCRIPTION: enqueue camera frame to display
   2072  *
   2073  * PARAMETERS :
   2074  *   @index   : index of frame
   2075  *   @timeStamp : frame presentation time
   2076  *
   2077  * RETURN     : int32_t type of status
   2078  *              NO_ERROR  -- success
   2079  *              none-zero failure code
   2080  *==========================================================================*/
   2081 int32_t QCameraGrallocMemory::enqueueBuffer(uint32_t index, nsecs_t timeStamp)
   2082 {
   2083     int32_t err = NO_ERROR;
   2084 
   2085     if ((mWindow == NULL) || (index >= MM_CAMERA_MAX_NUM_FRAMES))
   2086     {
   2087         LOGE("buffer index is invalid");
   2088         return INVALID_OPERATION;
   2089     }
   2090     else if(mBufferHandle[index] == NULL)
   2091     {
   2092         LOGE("buffer is NULL");
   2093         return INVALID_OPERATION;
   2094     }
   2095 
   2096     if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
   2097         LOGE("buffer to be enqueued is not owned");
   2098         return INVALID_OPERATION;
   2099     }
   2100 
   2101     if (timeStamp != 0) {
   2102         err = mWindow->set_timestamp(mWindow, timeStamp);
   2103         if (err != NO_ERROR){
   2104             LOGE("Failed to native window timestamp");
   2105         }
   2106     }
   2107 
   2108     err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
   2109     if(err != 0) {
   2110         LOGE("enqueue_buffer failed, err = %d", err);
   2111     } else {
   2112         LOGD("enqueue_buffer hdl=%p", *mBufferHandle[index]);
   2113         mLocalFlag[index] = BUFFER_NOT_OWNED;
   2114     }
   2115     return err;
   2116 }
   2117 
   2118 /*===========================================================================
   2119  * FUNCTION   : dequeueBuffer
   2120  *
   2121  * DESCRIPTION: receive a buffer from gralloc
   2122  *
   2123  * PARAMETERS : None
   2124  *
   2125  * RETURN     : int32_t
   2126  *              NO_ERROR/Buffer index : Success
   2127  *              < 0 failure code
   2128  *==========================================================================*/
   2129 int32_t QCameraGrallocMemory::dequeueBuffer()
   2130 {
   2131     int32_t err = NO_ERROR;
   2132     int32_t dequeuedIdx = BAD_INDEX;
   2133     buffer_handle_t *buffer_handle = NULL;
   2134     int32_t stride = 0;
   2135 
   2136     dequeuedIdx = BAD_INDEX;
   2137     err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
   2138     if ((err == NO_ERROR) && (buffer_handle != NULL)) {
   2139         int i;
   2140         LOGD("dequed buf hdl =%p", *buffer_handle);
   2141         for(i = 0; i < mMappableBuffers; i++) {
   2142             if(mBufferHandle[i] == buffer_handle) {
   2143                 LOGD("Found buffer in idx:%d", i);
   2144                 mLocalFlag[i] = BUFFER_OWNED;
   2145                 dequeuedIdx = i;
   2146                 break;
   2147             }
   2148         }
   2149 
   2150         if ((dequeuedIdx == BAD_INDEX) &&
   2151                 (mMappableBuffers < mBufferCount)) {
   2152             dequeuedIdx = mMappableBuffers;
   2153             LOGD("Placing buffer in idx:%d", dequeuedIdx);
   2154             mBufferHandle[dequeuedIdx] = buffer_handle;
   2155             mLocalFlag[dequeuedIdx] = BUFFER_OWNED;
   2156 
   2157             mPrivateHandle[dequeuedIdx] =
   2158                     (struct private_handle_t *)(*mBufferHandle[dequeuedIdx]);
   2159             //update max fps info
   2160             setMetaData(mPrivateHandle[dequeuedIdx], UPDATE_REFRESH_RATE, (void*)&mMaxFPS);
   2161             mMemInfo[dequeuedIdx].main_ion_fd = open("/dev/ion", O_RDONLY);
   2162             if (mMemInfo[dequeuedIdx].main_ion_fd < 0) {
   2163                 LOGE("failed: could not open ion device");
   2164                 return BAD_INDEX;
   2165             }
   2166 
   2167             struct ion_fd_data ion_info_fd;
   2168             memset(&ion_info_fd, 0, sizeof(ion_info_fd));
   2169             ion_info_fd.fd = mPrivateHandle[dequeuedIdx]->fd;
   2170             if (ioctl(mMemInfo[dequeuedIdx].main_ion_fd,
   2171                     ION_IOC_IMPORT, &ion_info_fd) < 0) {
   2172                 LOGE("ION import failed\n");
   2173                 return BAD_INDEX;
   2174             }
   2175 
   2176             setMetaData(mPrivateHandle[dequeuedIdx], UPDATE_COLOR_SPACE,
   2177                     &mColorSpace);
   2178             if (mBufType & QCAMERA_MEM_TYPE_SECURE) {
   2179                 LOGD("mBufType is QCAMERA_MEM_TYPE_SECURE. skip mGetMemory");
   2180             }else {
   2181                 mCameraMemory[dequeuedIdx] =
   2182                         mGetMemory(mPrivateHandle[dequeuedIdx]->fd,
   2183                         (size_t)mPrivateHandle[dequeuedIdx]->size,
   2184                         1,
   2185                         mCallbackCookie);
   2186             }
   2187             LOGH("idx = %d, fd = %d, size = %d, offset = %d",
   2188                      dequeuedIdx, mPrivateHandle[dequeuedIdx]->fd,
   2189                     mPrivateHandle[dequeuedIdx]->size,
   2190                     mPrivateHandle[dequeuedIdx]->offset);
   2191             mMemInfo[dequeuedIdx].fd = mPrivateHandle[dequeuedIdx]->fd;
   2192             mMemInfo[dequeuedIdx].size =
   2193                     (size_t)mPrivateHandle[dequeuedIdx]->size;
   2194             mMemInfo[dequeuedIdx].handle = ion_info_fd.handle;
   2195 
   2196             mMappableBuffers++;
   2197         }
   2198     } else {
   2199         LOGW("dequeue_buffer, no free buffer from display now");
   2200     }
   2201 
   2202     return dequeuedIdx;
   2203 }
   2204 
   2205 
   2206 /*===========================================================================
   2207  * FUNCTION   : allocate
   2208  *
   2209  * DESCRIPTION: allocate requested number of buffers of certain size
   2210  *
   2211  * PARAMETERS :
   2212  *   @count   : number of buffers to be allocated
   2213  *   @size    : lenght of the buffer to be allocated
   2214  *
   2215  * RETURN     : int32_t type of status
   2216  *              NO_ERROR  -- success
   2217  *              none-zero failure code
   2218  *==========================================================================*/
   2219 int QCameraGrallocMemory::allocate(uint8_t count, size_t /*size*/)
   2220 {
   2221     ATRACE_BEGIN_SNPRINTF("%s %d", "Grallocbufcnt", count);
   2222     int err = 0;
   2223     status_t ret = NO_ERROR;
   2224     int gralloc_usage = 0;
   2225     struct ion_fd_data ion_info_fd;
   2226     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
   2227 
   2228     LOGD("E ");
   2229 
   2230     if (!mWindow) {
   2231         LOGE("Invalid native window");
   2232         ATRACE_END();
   2233         ret = INVALID_OPERATION;
   2234         goto end;
   2235     }
   2236 
   2237     // Increment buffer count by min undequeued buffer.
   2238     err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
   2239     if (err != 0) {
   2240         LOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
   2241                 strerror(-err), -err);
   2242         ret = UNKNOWN_ERROR;
   2243         goto end;
   2244     }
   2245 
   2246     err = mWindow->set_buffer_count(mWindow, count);
   2247     if (err != 0) {
   2248          LOGE("set_buffer_count failed: %s (%d)",
   2249                     strerror(-err), -err);
   2250          ret = UNKNOWN_ERROR;
   2251          goto end;
   2252     }
   2253 
   2254     err = mWindow->set_buffers_geometry(mWindow, mWidth, mHeight, mFormat);
   2255     if (err != 0) {
   2256          LOGE("set_buffers_geometry failed: %s (%d)",
   2257                 strerror(-err), -err);
   2258          ret = UNKNOWN_ERROR;
   2259          goto end;
   2260     }
   2261 
   2262     gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
   2263     if (mBufType & QCAMERA_MEM_TYPE_SECURE) {
   2264         gralloc_usage |= ( GRALLOC_USAGE_HW_CAMERA_MASK | GRALLOC_USAGE_PROTECTED);
   2265     }
   2266 
   2267     gralloc_usage |= mUsage;
   2268     err = mWindow->set_usage(mWindow, gralloc_usage);
   2269     if(err != 0) {
   2270         /* set_usage error out */
   2271         LOGE("set_usage rc = %d", err);
   2272         ret = UNKNOWN_ERROR;
   2273         goto end;
   2274     }
   2275     LOGH("usage = %d, geometry: %p, %d, %d, %d, %d, %d",
   2276            gralloc_usage, mWindow, mWidth, mHeight, mStride,
   2277           mScanline, mFormat);
   2278 
   2279     mBufferCount = count;
   2280     if ((count < mMappableBuffers) || (mMappableBuffers == 0)) {
   2281         mMappableBuffers = count;
   2282     }
   2283 
   2284     //Allocate cnt number of buffers from native window
   2285     for (int cnt = 0; cnt < mMappableBuffers; cnt++) {
   2286         int stride;
   2287         err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
   2288         if(!err) {
   2289             LOGD("dequeue buf hdl =%p", mBufferHandle[cnt]);
   2290             mLocalFlag[cnt] = BUFFER_OWNED;
   2291         } else {
   2292             mLocalFlag[cnt] = BUFFER_NOT_OWNED;
   2293             LOGE("dequeue_buffer idx = %d err = %d", cnt, err);
   2294         }
   2295 
   2296         LOGD("dequeue buf: %p\n", mBufferHandle[cnt]);
   2297 
   2298         if(err != 0) {
   2299             LOGE("dequeue_buffer failed: %s (%d)",
   2300                    strerror(-err), -err);
   2301             ret = UNKNOWN_ERROR;
   2302             for(int i = 0; i < cnt; i++) {
   2303                 // Deallocate buffers when the native window is gone
   2304                 struct ion_handle_data ion_handle;
   2305                 memset(&ion_handle, 0, sizeof(ion_handle));
   2306                 ion_handle.handle = mMemInfo[i].handle;
   2307                 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   2308                     ALOGE("ion free failed");
   2309                 }
   2310                 close(mMemInfo[i].main_ion_fd);
   2311 
   2312                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   2313                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   2314                     LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i]));
   2315                 }
   2316                 mLocalFlag[i] = BUFFER_NOT_OWNED;
   2317                 mBufferHandle[i] = NULL;
   2318             }
   2319             reset();
   2320             goto end;
   2321         }
   2322 
   2323         mPrivateHandle[cnt] =
   2324             (struct private_handle_t *)(*mBufferHandle[cnt]);
   2325         //update max fps info
   2326         setMetaData(mPrivateHandle[cnt], UPDATE_REFRESH_RATE, (void*)&mMaxFPS);
   2327         mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
   2328         if (mMemInfo[cnt].main_ion_fd < 0) {
   2329             LOGE("failed: could not open ion device");
   2330             for(int i = 0; i < cnt; i++) {
   2331                 struct ion_handle_data ion_handle;
   2332                 memset(&ion_handle, 0, sizeof(ion_handle));
   2333                 ion_handle.handle = mMemInfo[i].handle;
   2334                 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   2335                     LOGE("ion free failed");
   2336                 }
   2337                 close(mMemInfo[i].main_ion_fd);
   2338                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   2339                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   2340                     LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i]));
   2341                 }
   2342                 mLocalFlag[i] = BUFFER_NOT_OWNED;
   2343                 mBufferHandle[i] = NULL;
   2344             }
   2345             reset();
   2346             ret = UNKNOWN_ERROR;
   2347             goto end;
   2348         } else {
   2349             ion_info_fd.fd = mPrivateHandle[cnt]->fd;
   2350             if (ioctl(mMemInfo[cnt].main_ion_fd,
   2351                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
   2352                 LOGE("ION import failed\n");
   2353                 for(int i = 0; i < cnt; i++) {
   2354                     struct ion_handle_data ion_handle;
   2355                     memset(&ion_handle, 0, sizeof(ion_handle));
   2356                     ion_handle.handle = mMemInfo[i].handle;
   2357                     if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   2358                         LOGE("ion free failed");
   2359                     }
   2360                     close(mMemInfo[i].main_ion_fd);
   2361 
   2362                     if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   2363                         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   2364                         LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i]));
   2365                     }
   2366                     mLocalFlag[i] = BUFFER_NOT_OWNED;
   2367                     mBufferHandle[i] = NULL;
   2368                 }
   2369                 close(mMemInfo[cnt].main_ion_fd);
   2370                 reset();
   2371                 ret = UNKNOWN_ERROR;
   2372                 goto end;
   2373             }
   2374         }
   2375         setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace);
   2376 
   2377         if (mBufType & QCAMERA_MEM_TYPE_SECURE) {
   2378             LOGD("mBufType is QCAMERA_MEM_TYPE_SECURE. skip mGetMemory");
   2379         } else {
   2380             mCameraMemory[cnt] =
   2381                 mGetMemory(mPrivateHandle[cnt]->fd,
   2382                         (size_t)mPrivateHandle[cnt]->size,
   2383                         1,
   2384                         mCallbackCookie);
   2385         }
   2386         LOGH("idx = %d, fd = %d, size = %d, offset = %d",
   2387                cnt, mPrivateHandle[cnt]->fd,
   2388               mPrivateHandle[cnt]->size,
   2389               mPrivateHandle[cnt]->offset);
   2390         mMemInfo[cnt].fd = mPrivateHandle[cnt]->fd;
   2391         mMemInfo[cnt].size = (size_t)mPrivateHandle[cnt]->size;
   2392         mMemInfo[cnt].handle = ion_info_fd.handle;
   2393     }
   2394 
   2395     //Cancel min_undequeued_buffer buffers back to the window
   2396     for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
   2397         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   2398         mLocalFlag[i] = BUFFER_NOT_OWNED;
   2399     }
   2400 
   2401 end:
   2402     if (ret != NO_ERROR) {
   2403         mMappableBuffers = 0;
   2404     }
   2405     LOGD("X ");
   2406     ATRACE_END();
   2407     return ret;
   2408 }
   2409 
   2410 
   2411 /*===========================================================================
   2412  * FUNCTION   : allocateMore
   2413  *
   2414  * DESCRIPTION: allocate more requested number of buffers of certain size
   2415  *
   2416  * PARAMETERS :
   2417  *   @count   : number of buffers to be allocated
   2418  *   @size    : lenght of the buffer to be allocated
   2419  *
   2420  * RETURN     : int32_t type of status
   2421  *              NO_ERROR  -- success
   2422  *              none-zero failure code
   2423  *==========================================================================*/
   2424 int QCameraGrallocMemory::allocateMore(uint8_t /*count*/, size_t /*size*/)
   2425 {
   2426     LOGE("Not implenmented yet");
   2427     return UNKNOWN_ERROR;
   2428 }
   2429 
   2430 /*===========================================================================
   2431  * FUNCTION   : deallocate
   2432  *
   2433  * DESCRIPTION: deallocate buffers
   2434  *
   2435  * PARAMETERS : none
   2436  *
   2437  * RETURN     : none
   2438  *==========================================================================*/
   2439 void QCameraGrallocMemory::deallocate()
   2440 {
   2441     LOGD("E ", __FUNCTION__);
   2442 
   2443     for (int cnt = 0; cnt < mMappableBuffers; cnt++) {
   2444         if (mCameraMemory[cnt] != NULL) {
   2445             mCameraMemory[cnt]->release(mCameraMemory[cnt]);
   2446         }
   2447         struct ion_handle_data ion_handle;
   2448         memset(&ion_handle, 0, sizeof(ion_handle));
   2449         ion_handle.handle = mMemInfo[cnt].handle;
   2450         if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   2451             LOGE("ion free failed");
   2452         }
   2453         close(mMemInfo[cnt].main_ion_fd);
   2454         if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
   2455             if (mWindow && (mBufferHandle[cnt] != NULL)
   2456                 && (*mBufferHandle[cnt] != NULL)) {
   2457                 LOGH("cancel_buffer: buffer_handle =%p",  *mBufferHandle[cnt]);
   2458                 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
   2459                 mBufferHandle[cnt]= NULL;
   2460             } else {
   2461                 LOGE("Cannot cancel buffer: hdl =%p window = %p local ptr = %p",
   2462                       (*mBufferHandle[cnt]), mWindow, mBufferHandle[cnt]);
   2463             }
   2464         }
   2465         mLocalFlag[cnt] = BUFFER_NOT_OWNED;
   2466         LOGH("put buffer %d successfully", cnt);
   2467     }
   2468     mBufferCount = 0;
   2469     mMappableBuffers = 0;
   2470     LOGD("X ",__FUNCTION__);
   2471 }
   2472 
   2473 /*===========================================================================
   2474  * FUNCTION   : cacheOps
   2475  *
   2476  * DESCRIPTION: ion related memory cache operations
   2477  *
   2478  * PARAMETERS :
   2479  *   @index   : index of the buffer
   2480  *   @cmd     : cache ops command
   2481  *
   2482  * RETURN     : int32_t type of status
   2483  *              NO_ERROR  -- success
   2484  *              none-zero failure code
   2485  *==========================================================================*/
   2486 int QCameraGrallocMemory::cacheOps(uint32_t index, unsigned int cmd)
   2487 {
   2488     if (index >= mMappableBuffers)
   2489         return BAD_INDEX;
   2490 
   2491     if (mCameraMemory[index] == NULL) {
   2492         return NULL;
   2493     }
   2494 
   2495     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
   2496 }
   2497 
   2498 /*===========================================================================
   2499  * FUNCTION   : getRegFlags
   2500  *
   2501  * DESCRIPTION: query initial reg flags
   2502  *
   2503  * PARAMETERS :
   2504  *   @regFlags: initial reg flags of the allocated buffers
   2505  *
   2506  * RETURN     : int32_t type of status
   2507  *              NO_ERROR  -- success
   2508  *              none-zero failure code
   2509  *==========================================================================*/
   2510 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
   2511 {
   2512     int i = 0;
   2513     for (i = 0; i < mMinUndequeuedBuffers; i ++)
   2514         regFlags[i] = 0;
   2515     for (; i < mMappableBuffers; i ++)
   2516         regFlags[i] = 1;
   2517     for (; i < mBufferCount; i ++)
   2518         regFlags[i] = 0;
   2519     return NO_ERROR;
   2520 }
   2521 
   2522 /*===========================================================================
   2523  * FUNCTION   : getMemory
   2524  *
   2525  * DESCRIPTION: get camera memory
   2526  *
   2527  * PARAMETERS :
   2528  *   @index   : buffer index
   2529  *   @metadata: flag if it's metadata
   2530  *
   2531  * RETURN     : camera memory ptr
   2532  *              NULL if not supported or failed
   2533  *==========================================================================*/
   2534 camera_memory_t *QCameraGrallocMemory::getMemory(uint32_t index,
   2535         bool metadata) const
   2536 {
   2537     if (index >= mMappableBuffers || metadata)
   2538         return NULL;
   2539     return mCameraMemory[index];
   2540 }
   2541 
   2542 /*===========================================================================
   2543  * FUNCTION   : getMatchBufIndex
   2544  *
   2545  * DESCRIPTION: query buffer index by opaque ptr
   2546  *
   2547  * PARAMETERS :
   2548  *   @opaque  : opaque ptr
   2549  *   @metadata: flag if it's metadata
   2550  *
   2551  * RETURN     : buffer index if match found,
   2552  *              -1 if failed
   2553  *==========================================================================*/
   2554 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
   2555                                            bool metadata) const
   2556 {
   2557     int index = -1;
   2558     if (metadata) {
   2559         return -1;
   2560     }
   2561     for (int i = 0; i < mMappableBuffers; i++) {
   2562         if ((mCameraMemory[i]) && (mCameraMemory[i]->data == opaque)) {
   2563             index = i;
   2564             break;
   2565         }
   2566     }
   2567     return index;
   2568 }
   2569 
   2570 /*===========================================================================
   2571  * FUNCTION   : getPtr
   2572  *
   2573  * DESCRIPTION: return buffer pointer
   2574  *
   2575  * PARAMETERS :
   2576  *   @index   : index of the buffer
   2577  *
   2578  * RETURN     : buffer ptr
   2579  *==========================================================================*/
   2580 void *QCameraGrallocMemory::getPtr(uint32_t index) const
   2581 {
   2582     if (index >= mMappableBuffers) {
   2583         LOGE("index out of bound");
   2584         return (void *)NULL;
   2585     }
   2586 
   2587     if (mCameraMemory[index] == NULL) {
   2588         return NULL;
   2589     }
   2590 
   2591     return mCameraMemory[index]->data;
   2592 }
   2593 
   2594 /*===========================================================================
   2595  * FUNCTION   : setMappable
   2596  *
   2597  * DESCRIPTION: configure the number of buffers ready to map
   2598  *
   2599  * PARAMETERS :
   2600  *   @mappable : the number of desired mappable buffers
   2601  *
   2602  * RETURN     : none
   2603  *==========================================================================*/
   2604 void QCameraGrallocMemory::setMappable(uint8_t mappable)
   2605 {
   2606     if (mMappableBuffers == 0) {
   2607         mMappableBuffers = mappable;
   2608     }
   2609 }
   2610 
   2611 /*===========================================================================
   2612  * FUNCTION   : getMappable
   2613  *
   2614  * DESCRIPTION: query number of buffers already allocated
   2615  *
   2616  * PARAMETERS : none
   2617  *
   2618  * RETURN     : number of buffers already allocated
   2619  *==========================================================================*/
   2620 uint8_t QCameraGrallocMemory::getMappable() const
   2621 {
   2622     return mMappableBuffers;
   2623 }
   2624 
   2625 /*===========================================================================
   2626  * FUNCTION   : checkIfAllBuffersMapped
   2627  *
   2628  * DESCRIPTION: check if all buffers for the are mapped
   2629  *
   2630  * PARAMETERS : none
   2631  *
   2632  * RETURN     : 1 if all buffers mapped
   2633  *              0 if total buffers not equal to mapped buffers
   2634  *==========================================================================*/
   2635 uint8_t QCameraGrallocMemory::checkIfAllBuffersMapped() const
   2636 {
   2637     LOGH("mBufferCount: %d, mMappableBuffers: %d",
   2638              mBufferCount, mMappableBuffers);
   2639     return (mBufferCount == mMappableBuffers);
   2640 }
   2641 
   2642 /*===========================================================================
   2643  * FUNCTION   : setBufferStatus
   2644  *
   2645  * DESCRIPTION: set buffer status
   2646  *
   2647  * PARAMETERS :
   2648  *   @index   : index of the buffer
   2649  *   @status  : status of the buffer, whether skipped,etc
   2650  *
   2651  * RETURN     : none
   2652  *==========================================================================*/
   2653 void QCameraGrallocMemory::setBufferStatus(uint32_t index, BufferStatus status)
   2654 {
   2655     if (index >= mBufferCount) {
   2656         LOGE("index out of bound");
   2657         return;
   2658     }
   2659     mBufferStatus[index] = status;
   2660 }
   2661 
   2662 }; //namespace qcamera
   2663