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