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