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