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