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