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