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