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