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