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