Home | History | Annotate | Download | only in HAL
      1 /* Copyright (c) 2012-2013, 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     :m_bCached(cached)
     63 {
     64     mBufferCount = 0;
     65     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
     66         mMemInfo[i].fd = 0;
     67         mMemInfo[i].main_ion_fd = 0;
     68         mMemInfo[i].handle = NULL;
     69         mMemInfo[i].size = 0;
     70     }
     71 }
     72 
     73 /*===========================================================================
     74  * FUNCTION   : ~QCameraMemory
     75  *
     76  * DESCRIPTION: deconstructor of QCameraMemory
     77  *
     78  * PARAMETERS : none
     79  *
     80  * RETURN     : None
     81  *==========================================================================*/
     82 QCameraMemory::~QCameraMemory()
     83 {
     84 }
     85 
     86 /*===========================================================================
     87  * FUNCTION   : cacheOpsInternal
     88  *
     89  * DESCRIPTION: ion related memory cache operations
     90  *
     91  * PARAMETERS :
     92  *   @index   : index of the buffer
     93  *   @cmd     : cache ops command
     94  *   @vaddr   : ptr to the virtual address
     95  *
     96  * RETURN     : int32_t type of status
     97  *              NO_ERROR  -- success
     98  *              none-zero failure code
     99  *==========================================================================*/
    100 int QCameraMemory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr)
    101 {
    102     if (!m_bCached) {
    103         // Memory is not cached, no need for cache ops
    104         ALOGV("%s: No cache ops here for uncached memory", __func__);
    105         return OK;
    106     }
    107 
    108     struct ion_flush_data cache_inv_data;
    109     struct ion_custom_data custom_data;
    110     int ret = OK;
    111 
    112     if (index >= mBufferCount) {
    113         ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount);
    114         return BAD_INDEX;
    115     }
    116 
    117     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
    118     memset(&custom_data, 0, sizeof(custom_data));
    119     cache_inv_data.vaddr = vaddr;
    120     cache_inv_data.fd = mMemInfo[index].fd;
    121     cache_inv_data.handle = mMemInfo[index].handle;
    122     cache_inv_data.length = mMemInfo[index].size;
    123     custom_data.cmd = cmd;
    124     custom_data.arg = (unsigned long)&cache_inv_data;
    125 
    126     ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
    127          __func__, cache_inv_data.vaddr, cache_inv_data.fd,
    128          cache_inv_data.handle, cache_inv_data.length,
    129          mMemInfo[index].main_ion_fd);
    130     ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
    131     if (ret < 0)
    132         ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
    133 
    134     return ret;
    135 }
    136 
    137 /*===========================================================================
    138  * FUNCTION   : getFd
    139  *
    140  * DESCRIPTION: return file descriptor of the indexed buffer
    141  *
    142  * PARAMETERS :
    143  *   @index   : index of the buffer
    144  *
    145  * RETURN     : file descriptor
    146  *==========================================================================*/
    147 int QCameraMemory::getFd(int index) const
    148 {
    149     if (index >= mBufferCount)
    150         return BAD_INDEX;
    151 
    152     return mMemInfo[index].fd;
    153 }
    154 
    155 /*===========================================================================
    156  * FUNCTION   : getSize
    157  *
    158  * DESCRIPTION: return buffer size of the indexed buffer
    159  *
    160  * PARAMETERS :
    161  *   @index   : index of the buffer
    162  *
    163  * RETURN     : buffer size
    164  *==========================================================================*/
    165 int QCameraMemory::getSize(int index) const
    166 {
    167     if (index >= mBufferCount)
    168         return BAD_INDEX;
    169 
    170     return (int)mMemInfo[index].size;
    171 }
    172 
    173 /*===========================================================================
    174  * FUNCTION   : getCnt
    175  *
    176  * DESCRIPTION: query number of buffers allocated
    177  *
    178  * PARAMETERS : none
    179  *
    180  * RETURN     : number of buffers allocated
    181  *==========================================================================*/
    182 int QCameraMemory::getCnt() const
    183 {
    184     return mBufferCount;
    185 }
    186 
    187 /*===========================================================================
    188  * FUNCTION   : getBufDef
    189  *
    190  * DESCRIPTION: query detailed buffer information
    191  *
    192  * PARAMETERS :
    193  *   @offset  : [input] frame buffer offset
    194  *   @bufDef  : [output] reference to struct to store buffer definition
    195  *   @index   : [input] index of the buffer
    196  *
    197  * RETURN     : none
    198  *==========================================================================*/
    199 void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset,
    200         mm_camera_buf_def_t &bufDef, int index) const
    201 {
    202     if (!mBufferCount) {
    203         ALOGE("Memory not allocated");
    204         return;
    205     }
    206     bufDef.fd = mMemInfo[index].fd;
    207     bufDef.frame_len = offset.frame_len;
    208     bufDef.mem_info = (void *)this;
    209     bufDef.num_planes = offset.num_planes;
    210 	bufDef.buffer = getPtr(index);
    211     bufDef.buf_idx = index;
    212 
    213     /* Plane 0 needs to be set separately. Set other planes in a loop */
    214     bufDef.planes[0].length = offset.mp[0].len;
    215     bufDef.planes[0].m.userptr = mMemInfo[index].fd;
    216     bufDef.planes[0].data_offset = offset.mp[0].offset;
    217     bufDef.planes[0].reserved[0] = 0;
    218     for (int i = 1; i < bufDef.num_planes; i++) {
    219          bufDef.planes[i].length = offset.mp[i].len;
    220          bufDef.planes[i].m.userptr = mMemInfo[i].fd;
    221          bufDef.planes[i].data_offset = offset.mp[i].offset;
    222          bufDef.planes[i].reserved[0] =
    223                  bufDef.planes[i-1].reserved[0] +
    224                  bufDef.planes[i-1].length;
    225     }
    226 }
    227 
    228 /*===========================================================================
    229  * FUNCTION   : alloc
    230  *
    231  * DESCRIPTION: allocate requested number of buffers of certain size
    232  *
    233  * PARAMETERS :
    234  *   @count   : number of buffers to be allocated
    235  *   @size    : lenght of the buffer to be allocated
    236  *   @heap_id : heap id to indicate where the buffers will be allocated from
    237  *
    238  * RETURN     : int32_t type of status
    239  *              NO_ERROR  -- success
    240  *              none-zero failure code
    241  *==========================================================================*/
    242 int QCameraMemory::alloc(int count, int size, int heap_id)
    243 {
    244     int rc = OK;
    245     if (count > MM_CAMERA_MAX_NUM_FRAMES) {
    246         ALOGE("Buffer count %d out of bound. Max is %d", count, MM_CAMERA_MAX_NUM_FRAMES);
    247         return BAD_INDEX;
    248     }
    249     if (mBufferCount) {
    250         ALOGE("Allocating a already allocated heap memory");
    251         return INVALID_OPERATION;
    252     }
    253 
    254     for (int i = 0; i < count; i ++) {
    255         rc = allocOneBuffer(mMemInfo[i], heap_id, size);
    256         if (rc < 0) {
    257             ALOGE("AllocateIonMemory failed");
    258             for (int j = i-1; j >= 0; j--)
    259                 deallocOneBuffer(mMemInfo[j]);
    260             break;
    261         }
    262     }
    263     return rc;
    264 }
    265 
    266 /*===========================================================================
    267  * FUNCTION   : dealloc
    268  *
    269  * DESCRIPTION: deallocate buffers
    270  *
    271  * PARAMETERS : none
    272  *
    273  * RETURN     : none
    274  *==========================================================================*/
    275 void QCameraMemory::dealloc()
    276 {
    277     for (int i = 0; i < mBufferCount; i++)
    278         deallocOneBuffer(mMemInfo[i]);
    279 }
    280 
    281 /*===========================================================================
    282  * FUNCTION   : allocOneBuffer
    283  *
    284  * DESCRIPTION: impl of allocating one buffers of certain size
    285  *
    286  * PARAMETERS :
    287  *   @memInfo : [output] reference to struct to store additional memory allocation info
    288  *   @heap    : [input] heap id to indicate where the buffers will be allocated from
    289  *   @size    : [input] lenght of the buffer to be allocated
    290  *
    291  * RETURN     : int32_t type of status
    292  *              NO_ERROR  -- success
    293  *              none-zero failure code
    294  *==========================================================================*/
    295 int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo, int heap_id, int size)
    296 {
    297     int rc = OK;
    298     struct ion_handle_data handle_data;
    299     struct ion_allocation_data alloc;
    300     struct ion_fd_data ion_info_fd;
    301     int main_ion_fd = 0;
    302 
    303     main_ion_fd = open("/dev/ion", O_RDONLY);
    304     if (main_ion_fd < 0) {
    305         ALOGE("Ion dev open failed: %s\n", strerror(errno));
    306         goto ION_OPEN_FAILED;
    307     }
    308 
    309     memset(&alloc, 0, sizeof(alloc));
    310     alloc.len = size;
    311     /* to make it page size aligned */
    312     alloc.len = (alloc.len + 4095) & (~4095);
    313     alloc.align = 4096;
    314     if (m_bCached) {
    315         alloc.flags = ION_FLAG_CACHED;
    316     }
    317     alloc.heap_id_mask = heap_id;
    318     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
    319     if (rc < 0) {
    320         ALOGE("ION allocation failed: %s\n", strerror(errno));
    321         goto ION_ALLOC_FAILED;
    322     }
    323 
    324     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    325     ion_info_fd.handle = alloc.handle;
    326     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
    327     if (rc < 0) {
    328         ALOGE("ION map failed %s\n", strerror(errno));
    329         goto ION_MAP_FAILED;
    330     }
    331 
    332     memInfo.main_ion_fd = main_ion_fd;
    333     memInfo.fd = ion_info_fd.fd;
    334     memInfo.handle = ion_info_fd.handle;
    335     memInfo.size = alloc.len;
    336     return OK;
    337 
    338 ION_MAP_FAILED:
    339     memset(&handle_data, 0, sizeof(handle_data));
    340     handle_data.handle = ion_info_fd.handle;
    341     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
    342 ION_ALLOC_FAILED:
    343     close(main_ion_fd);
    344 ION_OPEN_FAILED:
    345     return NO_MEMORY;
    346 }
    347 
    348 /*===========================================================================
    349  * FUNCTION   : deallocOneBuffer
    350  *
    351  * DESCRIPTION: impl of deallocating one buffers
    352  *
    353  * PARAMETERS :
    354  *   @memInfo : reference to struct that stores additional memory allocation info
    355  *
    356  * RETURN     : none
    357  *==========================================================================*/
    358 void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo)
    359 {
    360     struct ion_handle_data handle_data;
    361 
    362     if (memInfo.fd > 0) {
    363         close(memInfo.fd);
    364         memInfo.fd = 0;
    365     }
    366 
    367     if (memInfo.main_ion_fd > 0) {
    368         memset(&handle_data, 0, sizeof(handle_data));
    369         handle_data.handle = memInfo.handle;
    370         ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
    371         close(memInfo.main_ion_fd);
    372         memInfo.main_ion_fd = 0;
    373     }
    374     memInfo.handle = NULL;
    375     memInfo.size = 0;
    376 }
    377 
    378 /*===========================================================================
    379  * FUNCTION   : QCameraHeapMemory
    380  *
    381  * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL
    382  *
    383  * PARAMETERS :
    384  *   @cached  : flag indicates if using cached memory
    385  *
    386  * RETURN     : none
    387  *==========================================================================*/
    388 QCameraHeapMemory::QCameraHeapMemory(bool cached)
    389     : QCameraMemory(cached)
    390 {
    391     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
    392         mPtr[i] = NULL;
    393 }
    394 
    395 /*===========================================================================
    396  * FUNCTION   : ~QCameraHeapMemory
    397  *
    398  * DESCRIPTION: deconstructor of QCameraHeapMemory
    399  *
    400  * PARAMETERS : none
    401  *
    402  * RETURN     : none
    403  *==========================================================================*/
    404 QCameraHeapMemory::~QCameraHeapMemory()
    405 {
    406 }
    407 
    408 /*===========================================================================
    409  * FUNCTION   : getPtr
    410  *
    411  * DESCRIPTION: return buffer pointer
    412  *
    413  * PARAMETERS :
    414  *   @index   : index of the buffer
    415  *
    416  * RETURN     : buffer ptr
    417  *==========================================================================*/
    418 void *QCameraHeapMemory::getPtr(int index) const
    419 {
    420     if (index >= mBufferCount) {
    421         ALOGE("index out of bound");
    422         return (void *)BAD_INDEX;
    423     }
    424     return mPtr[index];
    425 }
    426 
    427 /*===========================================================================
    428  * FUNCTION   : allocate
    429  *
    430  * DESCRIPTION: allocate requested number of buffers of certain size
    431  *
    432  * PARAMETERS :
    433  *   @count   : number of buffers to be allocated
    434  *   @size    : lenght of the buffer to be allocated
    435  *
    436  * RETURN     : int32_t type of status
    437  *              NO_ERROR  -- success
    438  *              none-zero failure code
    439  *==========================================================================*/
    440 int QCameraHeapMemory::allocate(int count, int size)
    441 {
    442     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
    443     int rc = alloc(count, size, heap_mask);
    444     if (rc < 0)
    445         return rc;
    446 
    447     for (int i = 0; i < count; i ++) {
    448         void *vaddr = mmap(NULL,
    449                     mMemInfo[i].size,
    450                     PROT_READ | PROT_WRITE,
    451                     MAP_SHARED,
    452                     mMemInfo[i].fd, 0);
    453         if (vaddr == MAP_FAILED) {
    454             for (int j = i-1; j >= 0; j --) {
    455                 munmap(mPtr[i], mMemInfo[i].size);
    456                 rc = NO_MEMORY;
    457                 break;
    458             }
    459         } else
    460             mPtr[i] = vaddr;
    461     }
    462     if (rc == 0)
    463         mBufferCount = count;
    464     return OK;
    465 }
    466 
    467 /*===========================================================================
    468  * FUNCTION   : deallocate
    469  *
    470  * DESCRIPTION: deallocate buffers
    471  *
    472  * PARAMETERS : none
    473  *
    474  * RETURN     : none
    475  *==========================================================================*/
    476 void QCameraHeapMemory::deallocate()
    477 {
    478     for (int i = 0; i < mBufferCount; i++) {
    479         munmap(mPtr[i], mMemInfo[i].size);
    480         mPtr[i] = NULL;
    481     }
    482     dealloc();
    483     mBufferCount = 0;
    484 }
    485 
    486 /*===========================================================================
    487  * FUNCTION   : cacheOps
    488  *
    489  * DESCRIPTION: ion related memory cache operations
    490  *
    491  * PARAMETERS :
    492  *   @index   : index of the buffer
    493  *   @cmd     : cache ops command
    494  *
    495  * RETURN     : int32_t type of status
    496  *              NO_ERROR  -- success
    497  *              none-zero failure code
    498  *==========================================================================*/
    499 int QCameraHeapMemory::cacheOps(int index, unsigned int cmd)
    500 {
    501     if (index >= mBufferCount)
    502         return BAD_INDEX;
    503     return cacheOpsInternal(index, cmd, mPtr[index]);
    504 }
    505 
    506 /*===========================================================================
    507  * FUNCTION   : getRegFlags
    508  *
    509  * DESCRIPTION: query initial reg flags
    510  *
    511  * PARAMETERS :
    512  *   @regFlags: initial reg flags of the allocated buffers
    513  *
    514  * RETURN     : int32_t type of status
    515  *              NO_ERROR  -- success
    516  *              none-zero failure code
    517  *==========================================================================*/
    518 int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const
    519 {
    520     return INVALID_OPERATION;
    521 }
    522 
    523 /*===========================================================================
    524  * FUNCTION   : getMemory
    525  *
    526  * DESCRIPTION: get camera memory
    527  *
    528  * PARAMETERS :
    529  *   @index   : buffer index
    530  *   @metadata: flag if it's metadata
    531  *
    532  * RETURN     : camera memory ptr
    533  *              NULL if not supported or failed
    534  *==========================================================================*/
    535 camera_memory_t *QCameraHeapMemory::getMemory(
    536                 int /*index*/, bool /*metadata*/) const
    537 {
    538     return NULL;
    539 }
    540 
    541 /*===========================================================================
    542  * FUNCTION   : getMatchBufIndex
    543  *
    544  * DESCRIPTION: query buffer index by opaque ptr
    545  *
    546  * PARAMETERS :
    547  *   @opaque  : opaque ptr
    548  *   @metadata: flag if it's metadata
    549  *
    550  * RETURN     : buffer index if match found,
    551  *              -1 if failed
    552  *==========================================================================*/
    553 int QCameraHeapMemory::getMatchBufIndex(const void *opaque,
    554                                         bool metadata) const
    555 {
    556     int index = -1;
    557     if (metadata) {
    558         return -1;
    559     }
    560     for (int i = 0; i < mBufferCount; i++) {
    561         if (mPtr[i] == opaque) {
    562             index = i;
    563             break;
    564         }
    565     }
    566     return index;
    567 }
    568 
    569 /*===========================================================================
    570  * FUNCTION   : QCameraStreamMemory
    571  *
    572  * DESCRIPTION: constructor of QCameraStreamMemory
    573  *              ION memory allocated directly from /dev/ion and shared with framework
    574  *
    575  * PARAMETERS :
    576  *   @getMemory : camera memory request ops table
    577  *   @cached    : flag indicates if using cached memory
    578  *
    579  * RETURN     : none
    580  *==========================================================================*/
    581 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory getMemory,
    582                                          bool cached)
    583     :QCameraMemory(cached),
    584      mGetMemory(getMemory)
    585 {
    586     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
    587         mCameraMemory[i] = NULL;
    588 }
    589 
    590 /*===========================================================================
    591  * FUNCTION   : ~QCameraStreamMemory
    592  *
    593  * DESCRIPTION: deconstructor of QCameraStreamMemory
    594  *
    595  * PARAMETERS : none
    596  *
    597  * RETURN     : none
    598  *==========================================================================*/
    599 QCameraStreamMemory::~QCameraStreamMemory()
    600 {
    601 }
    602 
    603 /*===========================================================================
    604  * FUNCTION   : allocate
    605  *
    606  * DESCRIPTION: allocate requested number of buffers of certain size
    607  *
    608  * PARAMETERS :
    609  *   @count   : number of buffers to be allocated
    610  *   @size    : lenght of the buffer to be allocated
    611  *
    612  * RETURN     : int32_t type of status
    613  *              NO_ERROR  -- success
    614  *              none-zero failure code
    615  *==========================================================================*/
    616 int QCameraStreamMemory::allocate(int count, int size)
    617 {
    618     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
    619     int rc = alloc(count, size, heap_mask);
    620     if (rc < 0)
    621         return rc;
    622 
    623     for (int i = 0; i < count; i ++) {
    624         mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
    625     }
    626     mBufferCount = count;
    627     return NO_ERROR;
    628 }
    629 
    630 /*===========================================================================
    631  * FUNCTION   : deallocate
    632  *
    633  * DESCRIPTION: deallocate buffers
    634  *
    635  * PARAMETERS : none
    636  *
    637  * RETURN     : none
    638  *==========================================================================*/
    639 void QCameraStreamMemory::deallocate()
    640 {
    641     for (int i = 0; i < mBufferCount; i ++) {
    642         mCameraMemory[i]->release(mCameraMemory[i]);
    643         mCameraMemory[i] = NULL;
    644     }
    645     dealloc();
    646     mBufferCount = 0;
    647 }
    648 
    649 /*===========================================================================
    650  * FUNCTION   : cacheOps
    651  *
    652  * DESCRIPTION: ion related memory cache operations
    653  *
    654  * PARAMETERS :
    655  *   @index   : index of the buffer
    656  *   @cmd     : cache ops command
    657  *
    658  * RETURN     : int32_t type of status
    659  *              NO_ERROR  -- success
    660  *              none-zero failure code
    661  *==========================================================================*/
    662 int QCameraStreamMemory::cacheOps(int index, unsigned int cmd)
    663 {
    664     if (index >= mBufferCount)
    665         return BAD_INDEX;
    666     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
    667 }
    668 
    669 /*===========================================================================
    670  * FUNCTION   : getRegFlags
    671  *
    672  * DESCRIPTION: query initial reg flags
    673  *
    674  * PARAMETERS :
    675  *   @regFlags: initial reg flags of the allocated buffers
    676  *
    677  * RETURN     : int32_t type of status
    678  *              NO_ERROR  -- success
    679  *              none-zero failure code
    680  *==========================================================================*/
    681 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
    682 {
    683     for (int i = 0; i < mBufferCount; i ++)
    684         regFlags[i] = 1;
    685     return NO_ERROR;
    686 }
    687 
    688 /*===========================================================================
    689  * FUNCTION   : getMemory
    690  *
    691  * DESCRIPTION: get camera memory
    692  *
    693  * PARAMETERS :
    694  *   @index   : buffer index
    695  *   @metadata: flag if it's metadata
    696  *
    697  * RETURN     : camera memory ptr
    698  *              NULL if not supported or failed
    699  *==========================================================================*/
    700 camera_memory_t *QCameraStreamMemory::getMemory(int index, bool metadata) const
    701 {
    702     if (index >= mBufferCount || metadata)
    703         return NULL;
    704     return mCameraMemory[index];
    705 }
    706 
    707 /*===========================================================================
    708  * FUNCTION   : getMatchBufIndex
    709  *
    710  * DESCRIPTION: query buffer index by opaque ptr
    711  *
    712  * PARAMETERS :
    713  *   @opaque  : opaque ptr
    714  *   @metadata: flag if it's metadata
    715  *
    716  * RETURN     : buffer index if match found,
    717  *              -1 if failed
    718  *==========================================================================*/
    719 int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
    720                                           bool metadata) const
    721 {
    722     int index = -1;
    723     if (metadata) {
    724         return -1;
    725     }
    726     for (int i = 0; i < mBufferCount; i++) {
    727         if (mCameraMemory[i]->data == opaque) {
    728             index = i;
    729             break;
    730         }
    731     }
    732     return index;
    733 }
    734 
    735 /*===========================================================================
    736  * FUNCTION   : getPtr
    737  *
    738  * DESCRIPTION: return buffer pointer
    739  *
    740  * PARAMETERS :
    741  *   @index   : index of the buffer
    742  *
    743  * RETURN     : buffer ptr
    744  *==========================================================================*/
    745 void *QCameraStreamMemory::getPtr(int index) const
    746 {
    747     if (index >= mBufferCount) {
    748         ALOGE("index out of bound");
    749         return (void *)BAD_INDEX;
    750     }
    751     return mCameraMemory[index]->data;
    752 }
    753 
    754 /*===========================================================================
    755  * FUNCTION   : QCameraVideoMemory
    756  *
    757  * DESCRIPTION: constructor of QCameraVideoMemory
    758  *              VideoStream buffers also include metadata buffers
    759  *
    760  * PARAMETERS :
    761  *   @getMemory : camera memory request ops table
    762  *   @cached    : flag indicates if using cached ION memory
    763  *
    764  * RETURN     : none
    765  *==========================================================================*/
    766 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory getMemory,
    767                                        bool cached)
    768     : QCameraStreamMemory(getMemory, cached)
    769 {
    770     memset(mMetadata, 0, sizeof(mMetadata));
    771 }
    772 
    773 /*===========================================================================
    774  * FUNCTION   : ~QCameraVideoMemory
    775  *
    776  * DESCRIPTION: deconstructor of QCameraVideoMemory
    777  *
    778  * PARAMETERS : none
    779  *
    780  * RETURN     : none
    781  *==========================================================================*/
    782 QCameraVideoMemory::~QCameraVideoMemory()
    783 {
    784 }
    785 
    786 /*===========================================================================
    787  * FUNCTION   : allocate
    788  *
    789  * DESCRIPTION: allocate requested number of buffers of certain size
    790  *
    791  * PARAMETERS :
    792  *   @count   : number of buffers to be allocated
    793  *   @size    : lenght of the buffer to be allocated
    794  *
    795  * RETURN     : int32_t type of status
    796  *              NO_ERROR  -- success
    797  *              none-zero failure code
    798  *==========================================================================*/
    799 int QCameraVideoMemory::allocate(int count, int size)
    800 {
    801     int rc = QCameraStreamMemory::allocate(count, size);
    802     if (rc < 0)
    803         return rc;
    804 
    805     for (int i = 0; i < count; i ++) {
    806         mMetadata[i] = mGetMemory(-1,
    807                 sizeof(struct encoder_media_buffer_type), 1, this);
    808         if (!mMetadata[i]) {
    809             ALOGE("allocation of video metadata failed.");
    810             for (int j = 0; j < i-1; j ++)
    811                 mMetadata[j]->release(mMetadata[j]);
    812             QCameraStreamMemory::deallocate();
    813             return NO_MEMORY;
    814         }
    815         struct encoder_media_buffer_type * packet =
    816             (struct encoder_media_buffer_type *)mMetadata[i]->data;
    817         packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
    818         packet->buffer_type = kMetadataBufferTypeCameraSource;
    819         native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
    820         nh->data[0] = mMemInfo[i].fd;
    821         nh->data[1] = 0;
    822         nh->data[2] = mMemInfo[i].size;
    823     }
    824     mBufferCount = count;
    825     return NO_ERROR;
    826 }
    827 
    828 /*===========================================================================
    829  * FUNCTION   : deallocate
    830  *
    831  * DESCRIPTION: deallocate buffers
    832  *
    833  * PARAMETERS : none
    834  *
    835  * RETURN     : none
    836  *==========================================================================*/
    837 void QCameraVideoMemory::deallocate()
    838 {
    839     for (int i = 0; i < mBufferCount; i ++) {
    840         mMetadata[i]->release(mMetadata[i]);
    841         mMetadata[i] = NULL;
    842     }
    843     QCameraStreamMemory::deallocate();
    844     mBufferCount = 0;
    845 }
    846 
    847 /*===========================================================================
    848  * FUNCTION   : getMemory
    849  *
    850  * DESCRIPTION: get camera memory
    851  *
    852  * PARAMETERS :
    853  *   @index   : buffer index
    854  *   @metadata: flag if it's metadata
    855  *
    856  * RETURN     : camera memory ptr
    857  *              NULL if not supported or failed
    858  *==========================================================================*/
    859 camera_memory_t *QCameraVideoMemory::getMemory(int index, bool metadata) const
    860 {
    861     if (index >= mBufferCount)
    862         return NULL;
    863     if (metadata)
    864         return mMetadata[index];
    865     else
    866         return mCameraMemory[index];
    867 }
    868 
    869 /*===========================================================================
    870  * FUNCTION   : getMatchBufIndex
    871  *
    872  * DESCRIPTION: query buffer index by opaque ptr
    873  *
    874  * PARAMETERS :
    875  *   @opaque  : opaque ptr
    876  *   @metadata: flag if it's metadata
    877  *
    878  * RETURN     : buffer index if match found,
    879  *              -1 if failed
    880  *==========================================================================*/
    881 int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
    882                                          bool metadata) const
    883 {
    884     int index = -1;
    885     for (int i = 0; i < mBufferCount; i++) {
    886         if (metadata) {
    887             if (mMetadata[i]->data == opaque) {
    888                 index = i;
    889                 break;
    890             }
    891         } else {
    892             if (mCameraMemory[i]->data == opaque) {
    893                 index = i;
    894                 break;
    895             }
    896         }
    897     }
    898     return index;
    899 }
    900 
    901 /*===========================================================================
    902  * FUNCTION   : QCameraGrallocMemory
    903  *
    904  * DESCRIPTION: constructor of QCameraGrallocMemory
    905  *              preview stream buffers are allocated from gralloc native_windoe
    906  *
    907  * PARAMETERS :
    908  *   @getMemory : camera memory request ops table
    909  *
    910  * RETURN     : none
    911  *==========================================================================*/
    912 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory getMemory)
    913         : QCameraMemory(true)
    914 {
    915     mMinUndequeuedBuffers = 0;
    916     mWindow = NULL;
    917     mWidth = mHeight = 0;
    918     mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
    919     mGetMemory = getMemory;
    920     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
    921         mBufferHandle[i] = NULL;
    922         mLocalFlag[i] = BUFFER_NOT_OWNED;
    923         mPrivateHandle[i] = NULL;
    924     }
    925 }
    926 
    927 /*===========================================================================
    928  * FUNCTION   : ~QCameraGrallocMemory
    929  *
    930  * DESCRIPTION: deconstructor of QCameraGrallocMemory
    931  *
    932  * PARAMETERS : none
    933  *
    934  * RETURN     : none
    935  *==========================================================================*/
    936 QCameraGrallocMemory::~QCameraGrallocMemory()
    937 {
    938 }
    939 
    940 /*===========================================================================
    941  * FUNCTION   : setWindowInfo
    942  *
    943  * DESCRIPTION: set native window gralloc ops table
    944  *
    945  * PARAMETERS :
    946  *   @window  : gralloc ops table ptr
    947  *   @width   : width of preview frame
    948  *   @height  : height of preview frame
    949  *   @foramt  : format of preview image
    950  *
    951  * RETURN     : none
    952  *==========================================================================*/
    953 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
    954         int width, int height, int format)
    955 {
    956     mWindow = window;
    957     mWidth = width;
    958     mHeight = height;
    959     mFormat = format;
    960 }
    961 
    962 /*===========================================================================
    963  * FUNCTION   : displayBuffer
    964  *
    965  * DESCRIPTION: send received frame to display
    966  *
    967  * PARAMETERS :
    968  *   @index   : index of preview frame
    969  *
    970  * RETURN     : int32_t type of status
    971  *              NO_ERROR  -- success
    972  *              none-zero failure code
    973  *==========================================================================*/
    974 int QCameraGrallocMemory::displayBuffer(int index)
    975 {
    976     int err = NO_ERROR;
    977     int dequeuedIdx = BAD_INDEX;
    978 
    979     if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
    980         ALOGE("%s: buffer to be enqueued is not owned", __func__);
    981         return INVALID_OPERATION;
    982     }
    983 
    984     err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
    985     if(err != 0) {
    986         ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
    987     } else {
    988         ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]);
    989         mLocalFlag[index] = BUFFER_NOT_OWNED;
    990     }
    991 
    992     buffer_handle_t *buffer_handle = NULL;
    993     int stride = 0;
    994     err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
    995     if (err == NO_ERROR && buffer_handle != NULL) {
    996         int i;
    997         ALOGV("%s: dequed buf hdl =%p", __func__, *buffer_handle);
    998         for(i = 0; i < mBufferCount; i++) {
    999             if(mBufferHandle[i] == buffer_handle) {
   1000                 ALOGV("%s: Found buffer in idx:%d", __func__, i);
   1001                 mLocalFlag[i] = BUFFER_OWNED;
   1002                 dequeuedIdx = i;
   1003                 break;
   1004             }
   1005         }
   1006     } else {
   1007         ALOGD("%s: dequeue_buffer, no free buffer from display now", __func__);
   1008     }
   1009     return dequeuedIdx;
   1010 }
   1011 
   1012 /*===========================================================================
   1013  * FUNCTION   : allocate
   1014  *
   1015  * DESCRIPTION: allocate requested number of buffers of certain size
   1016  *
   1017  * PARAMETERS :
   1018  *   @count   : number of buffers to be allocated
   1019  *   @size    : lenght of the buffer to be allocated
   1020  *
   1021  * RETURN     : int32_t type of status
   1022  *              NO_ERROR  -- success
   1023  *              none-zero failure code
   1024  *==========================================================================*/
   1025 int QCameraGrallocMemory::allocate(int count, int /*size*/)
   1026 {
   1027     int err = 0;
   1028     status_t ret = NO_ERROR;
   1029     int gralloc_usage = 0;
   1030     struct ion_fd_data ion_info_fd;
   1031     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
   1032 
   1033     ALOGI(" %s : E ", __FUNCTION__);
   1034 
   1035     if (!mWindow) {
   1036         ALOGE("Invalid native window");
   1037         return INVALID_OPERATION;
   1038     }
   1039 
   1040     // Increment buffer count by min undequeued buffer.
   1041     err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
   1042     if (err != 0) {
   1043         ALOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
   1044                 strerror(-err), -err);
   1045         ret = UNKNOWN_ERROR;
   1046         goto end;
   1047     }
   1048     count += mMinUndequeuedBuffers;
   1049 
   1050     err = mWindow->set_buffer_count(mWindow, count);
   1051     if (err != 0) {
   1052          ALOGE("set_buffer_count failed: %s (%d)",
   1053                     strerror(-err), -err);
   1054          ret = UNKNOWN_ERROR;
   1055          goto end;
   1056     }
   1057 
   1058     err = mWindow->set_buffers_geometry(mWindow, mWidth, mHeight, mFormat);
   1059     if (err != 0) {
   1060          ALOGE("%s: set_buffers_geometry failed: %s (%d)",
   1061                __func__, strerror(-err), -err);
   1062          ret = UNKNOWN_ERROR;
   1063          goto end;
   1064     }
   1065 
   1066     gralloc_usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
   1067     err = mWindow->set_usage(mWindow, gralloc_usage);
   1068     if(err != 0) {
   1069         /* set_usage error out */
   1070         ALOGE("%s: set_usage rc = %d", __func__, err);
   1071         ret = UNKNOWN_ERROR;
   1072         goto end;
   1073     }
   1074     ALOGD("%s: usage = %d, geometry: %p, %d, %d, %d",
   1075           __func__, gralloc_usage, mWindow, mWidth, mHeight, mFormat);
   1076 
   1077     //Allocate cnt number of buffers from native window
   1078     for (int cnt = 0; cnt < count; cnt++) {
   1079         int stride;
   1080         err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
   1081         if(!err) {
   1082             ALOGV("dequeue buf hdl =%p", mBufferHandle[cnt]);
   1083             mLocalFlag[cnt] = BUFFER_OWNED;
   1084         } else {
   1085             mLocalFlag[cnt] = BUFFER_NOT_OWNED;
   1086             ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
   1087         }
   1088 
   1089         ALOGV("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]);
   1090 
   1091         if(err != 0) {
   1092             ALOGE("%s: dequeue_buffer failed: %s (%d)",
   1093                   __func__, strerror(-err), -err);
   1094             ret = UNKNOWN_ERROR;
   1095             for(int i = 0; i < cnt; i++) {
   1096                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   1097                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1098                     ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
   1099                 }
   1100                 mLocalFlag[i] = BUFFER_NOT_OWNED;
   1101                 mBufferHandle[i] = NULL;
   1102             }
   1103             memset(&mMemInfo, 0, sizeof(mMemInfo));
   1104             goto end;
   1105         }
   1106 
   1107         mPrivateHandle[cnt] =
   1108             (struct private_handle_t *)(*mBufferHandle[cnt]);
   1109         mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
   1110         if (mMemInfo[cnt].main_ion_fd < 0) {
   1111             ALOGE("%s: failed: could not open ion device", __func__);
   1112             for(int i = 0; i < cnt; i++) {
   1113                 struct ion_handle_data ion_handle;
   1114                 memset(&ion_handle, 0, sizeof(ion_handle));
   1115                 ion_handle.handle = mMemInfo[i].handle;
   1116                 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   1117                     ALOGE("%s: ion free failed", __func__);
   1118                 }
   1119                 close(mMemInfo[i].main_ion_fd);
   1120                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   1121                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1122                     ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
   1123                 }
   1124                 mLocalFlag[i] = BUFFER_NOT_OWNED;
   1125                 mBufferHandle[i] = NULL;
   1126             }
   1127             memset(&mMemInfo, 0, sizeof(mMemInfo));
   1128             ret = UNKNOWN_ERROR;
   1129             goto end;
   1130         } else {
   1131             ion_info_fd.fd = mPrivateHandle[cnt]->fd;
   1132             if (ioctl(mMemInfo[cnt].main_ion_fd,
   1133                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
   1134                 ALOGE("%s: ION import failed\n", __func__);
   1135                 for(int i = 0; i < cnt; i++) {
   1136                     struct ion_handle_data ion_handle;
   1137                     memset(&ion_handle, 0, sizeof(ion_handle));
   1138                     ion_handle.handle = mMemInfo[i].handle;
   1139                     if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   1140                         ALOGE("ion free failed");
   1141                     }
   1142                     close(mMemInfo[i].main_ion_fd);
   1143 
   1144                     if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
   1145                         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1146                         ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
   1147                     }
   1148                     mLocalFlag[i] = BUFFER_NOT_OWNED;
   1149                     mBufferHandle[i] = NULL;
   1150                 }
   1151                 close(mMemInfo[cnt].main_ion_fd);
   1152                 memset(&mMemInfo, 0, sizeof(mMemInfo));
   1153                 ret = UNKNOWN_ERROR;
   1154                 goto end;
   1155             }
   1156         }
   1157         mCameraMemory[cnt] =
   1158             mGetMemory(mPrivateHandle[cnt]->fd,
   1159                     mPrivateHandle[cnt]->size,
   1160                     1,
   1161                     (void *)this);
   1162         ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d",
   1163               __func__, cnt, mPrivateHandle[cnt]->fd,
   1164               mPrivateHandle[cnt]->size,
   1165               mPrivateHandle[cnt]->offset);
   1166         mMemInfo[cnt].fd =
   1167             mPrivateHandle[cnt]->fd;
   1168         mMemInfo[cnt].size =
   1169             mPrivateHandle[cnt]->size;
   1170         mMemInfo[cnt].handle = ion_info_fd.handle;
   1171     }
   1172     mBufferCount = count;
   1173 
   1174     //Cancel min_undequeued_buffer buffers back to the window
   1175     for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
   1176         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
   1177         mLocalFlag[i] = BUFFER_NOT_OWNED;
   1178     }
   1179 
   1180 end:
   1181     ALOGI(" %s : X ",__func__);
   1182     return ret;
   1183 }
   1184 
   1185 /*===========================================================================
   1186  * FUNCTION   : deallocate
   1187  *
   1188  * DESCRIPTION: deallocate buffers
   1189  *
   1190  * PARAMETERS : none
   1191  *
   1192  * RETURN     : none
   1193  *==========================================================================*/
   1194 void QCameraGrallocMemory::deallocate()
   1195 {
   1196     ALOGI("%s: E ", __FUNCTION__);
   1197 
   1198     for (int cnt = 0; cnt < mBufferCount; cnt++) {
   1199         mCameraMemory[cnt]->release(mCameraMemory[cnt]);
   1200         struct ion_handle_data ion_handle;
   1201         memset(&ion_handle, 0, sizeof(ion_handle));
   1202         ion_handle.handle = mMemInfo[cnt].handle;
   1203         if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
   1204             ALOGE("ion free failed");
   1205         }
   1206         close(mMemInfo[cnt].main_ion_fd);
   1207         if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
   1208             if (mWindow) {
   1209                 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
   1210                 ALOGD("cancel_buffer: hdl =%p", (*mBufferHandle[cnt]));
   1211             } else {
   1212                 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p",
   1213                       (*mBufferHandle[cnt]));
   1214             }
   1215         }
   1216         mLocalFlag[cnt] = BUFFER_NOT_OWNED;
   1217         ALOGD("put buffer %d successfully", cnt);
   1218     }
   1219     mBufferCount = 0;
   1220     ALOGI(" %s : X ",__FUNCTION__);
   1221 }
   1222 
   1223 /*===========================================================================
   1224  * FUNCTION   : cacheOps
   1225  *
   1226  * DESCRIPTION: ion related memory cache operations
   1227  *
   1228  * PARAMETERS :
   1229  *   @index   : index of the buffer
   1230  *   @cmd     : cache ops command
   1231  *
   1232  * RETURN     : int32_t type of status
   1233  *              NO_ERROR  -- success
   1234  *              none-zero failure code
   1235  *==========================================================================*/
   1236 int QCameraGrallocMemory::cacheOps(int index, unsigned int cmd)
   1237 {
   1238     if (index >= mBufferCount)
   1239         return BAD_INDEX;
   1240     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
   1241 }
   1242 
   1243 /*===========================================================================
   1244  * FUNCTION   : getRegFlags
   1245  *
   1246  * DESCRIPTION: query initial reg flags
   1247  *
   1248  * PARAMETERS :
   1249  *   @regFlags: initial reg flags of the allocated buffers
   1250  *
   1251  * RETURN     : int32_t type of status
   1252  *              NO_ERROR  -- success
   1253  *              none-zero failure code
   1254  *==========================================================================*/
   1255 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
   1256 {
   1257     int i = 0;
   1258     for (i = 0; i < mMinUndequeuedBuffers; i ++)
   1259         regFlags[i] = 0;
   1260     for (; i < mBufferCount; i ++)
   1261         regFlags[i] = 1;
   1262     return NO_ERROR;
   1263 }
   1264 
   1265 /*===========================================================================
   1266  * FUNCTION   : getMemory
   1267  *
   1268  * DESCRIPTION: get camera memory
   1269  *
   1270  * PARAMETERS :
   1271  *   @index   : buffer index
   1272  *   @metadata: flag if it's metadata
   1273  *
   1274  * RETURN     : camera memory ptr
   1275  *              NULL if not supported or failed
   1276  *==========================================================================*/
   1277 camera_memory_t *QCameraGrallocMemory::getMemory(int index, bool metadata) const
   1278 {
   1279     if (index >= mBufferCount || metadata)
   1280         return NULL;
   1281     return mCameraMemory[index];
   1282 }
   1283 
   1284 /*===========================================================================
   1285  * FUNCTION   : getMatchBufIndex
   1286  *
   1287  * DESCRIPTION: query buffer index by opaque ptr
   1288  *
   1289  * PARAMETERS :
   1290  *   @opaque  : opaque ptr
   1291  *   @metadata: flag if it's metadata
   1292  *
   1293  * RETURN     : buffer index if match found,
   1294  *              -1 if failed
   1295  *==========================================================================*/
   1296 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
   1297                                            bool metadata) const
   1298 {
   1299     int index = -1;
   1300     if (metadata) {
   1301         return -1;
   1302     }
   1303     for (int i = 0; i < mBufferCount; i++) {
   1304         if (mCameraMemory[i]->data == opaque) {
   1305             index = i;
   1306             break;
   1307         }
   1308     }
   1309     return index;
   1310 }
   1311 
   1312 /*===========================================================================
   1313  * FUNCTION   : getPtr
   1314  *
   1315  * DESCRIPTION: return buffer pointer
   1316  *
   1317  * PARAMETERS :
   1318  *   @index   : index of the buffer
   1319  *
   1320  * RETURN     : buffer ptr
   1321  *==========================================================================*/
   1322 void *QCameraGrallocMemory::getPtr(int index) const
   1323 {
   1324     if (index >= mBufferCount) {
   1325         ALOGE("index out of bound");
   1326         return (void *)BAD_INDEX;
   1327     }
   1328     return mCameraMemory[index]->data;
   1329 }
   1330 
   1331 }; //namespace qcamera
   1332