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