1 /* Copyright (c) 2012-2015, The Linux Foundataion. 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
30 #define LOG_TAG "QCameraHWI_Mem"
31
32 #include <string.h>
33 #include <fcntl.h>
34 #include <sys/mman.h>
35 #include <utils/Errors.h>
36 #include <gralloc_priv.h>
37 #include <QComOMXMetadata.h>
38 #include "QCamera2HWI.h"
39 #include "QCameraMem.h"
40
41 extern "C" {
42 #include <mm_camera_interface.h>
43 }
44
45 using namespace android;
46
47 namespace qcamera {
48
49 // QCaemra2Memory base class
50
51 /*===========================================================================
52 * FUNCTION : QCameraMemory
53 *
54 * DESCRIPTION: default constructor of QCameraMemory
55 *
56 * PARAMETERS :
57 * @cached : flag indicates if using cached memory
58 *
59 * RETURN : None
60 *==========================================================================*/
QCameraMemory(bool cached,QCameraMemoryPool * pool,cam_stream_type_t streamType)61 QCameraMemory::QCameraMemory(bool cached,
62 QCameraMemoryPool *pool,
63 cam_stream_type_t streamType)
64 :m_bCached(cached),
65 mMemoryPool(pool),
66 mStreamType(streamType)
67 {
68 mBufferCount = 0;
69 memset(mMemInfo, 0, sizeof(mMemInfo));
70 }
71
72 /*===========================================================================
73 * FUNCTION : ~QCameraMemory
74 *
75 * DESCRIPTION: deconstructor of QCameraMemory
76 *
77 * PARAMETERS : none
78 *
79 * RETURN : None
80 *==========================================================================*/
~QCameraMemory()81 QCameraMemory::~QCameraMemory()
82 {
83 }
84
85 /*===========================================================================
86 * FUNCTION : cacheOpsInternal
87 *
88 * DESCRIPTION: ion related memory cache operations
89 *
90 * PARAMETERS :
91 * @index : index of the buffer
92 * @cmd : cache ops command
93 * @vaddr : ptr to the virtual address
94 *
95 * RETURN : int32_t type of status
96 * NO_ERROR -- success
97 * none-zero failure code
98 *==========================================================================*/
cacheOpsInternal(int index,unsigned int cmd,void * vaddr)99 int QCameraMemory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr)
100 {
101 if (!m_bCached) {
102 // Memory is not cached, no need for cache ops
103 CDBG("%s: No cache ops here for uncached memory", __func__);
104 return OK;
105 }
106
107 struct ion_flush_data cache_inv_data;
108 struct ion_custom_data custom_data;
109 int ret = OK;
110
111 if (index >= mBufferCount) {
112 ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount);
113 return BAD_INDEX;
114 }
115
116 memset(&cache_inv_data, 0, sizeof(cache_inv_data));
117 memset(&custom_data, 0, sizeof(custom_data));
118 cache_inv_data.vaddr = vaddr;
119 cache_inv_data.fd = mMemInfo[index].fd;
120 cache_inv_data.handle = mMemInfo[index].handle;
121 cache_inv_data.length = mMemInfo[index].size;
122 custom_data.cmd = cmd;
123 custom_data.arg = (unsigned long)&cache_inv_data;
124
125 CDBG_HIGH("%s: addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
126 __func__, cache_inv_data.vaddr, cache_inv_data.fd,
127 (unsigned long)cache_inv_data.handle, cache_inv_data.length,
128 mMemInfo[index].main_ion_fd);
129 ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
130 if (ret < 0)
131 ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
132
133 return ret;
134 }
135
136 /*===========================================================================
137 * FUNCTION : getFd
138 *
139 * DESCRIPTION: return file descriptor of the indexed buffer
140 *
141 * PARAMETERS :
142 * @index : index of the buffer
143 *
144 * RETURN : file descriptor
145 *==========================================================================*/
getFd(int index) const146 int QCameraMemory::getFd(int index) const
147 {
148 if (index >= mBufferCount)
149 return BAD_INDEX;
150
151 return mMemInfo[index].fd;
152 }
153
154 /*===========================================================================
155 * FUNCTION : getSize
156 *
157 * DESCRIPTION: return buffer size of the indexed buffer
158 *
159 * PARAMETERS :
160 * @index : index of the buffer
161 *
162 * RETURN : buffer size
163 *==========================================================================*/
getSize(int index) const164 int QCameraMemory::getSize(int index) const
165 {
166 if (index >= mBufferCount)
167 return BAD_INDEX;
168
169 return (int)mMemInfo[index].size;
170 }
171
172 /*===========================================================================
173 * FUNCTION : getCnt
174 *
175 * DESCRIPTION: query number of buffers allocated
176 *
177 * PARAMETERS : none
178 *
179 * RETURN : number of buffers allocated
180 *==========================================================================*/
getCnt() const181 int QCameraMemory::getCnt() const
182 {
183 return mBufferCount;
184 }
185
186 /*===========================================================================
187 * FUNCTION : getBufDef
188 *
189 * DESCRIPTION: query detailed buffer information
190 *
191 * PARAMETERS :
192 * @offset : [input] frame buffer offset
193 * @bufDef : [output] reference to struct to store buffer definition
194 * @index : [input] index of the buffer
195 *
196 * RETURN : none
197 *==========================================================================*/
getBufDef(const cam_frame_len_offset_t & offset,mm_camera_buf_def_t & bufDef,int index) const198 void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset,
199 mm_camera_buf_def_t &bufDef, int index) const
200 {
201 if (!mBufferCount) {
202 ALOGE("Memory not allocated");
203 return;
204 }
205 bufDef.fd = mMemInfo[index].fd;
206 bufDef.frame_len = offset.frame_len;
207 bufDef.mem_info = (void *)this;
208 bufDef.num_planes = offset.num_planes;
209 bufDef.buffer = getPtr(index);
210 bufDef.buf_idx = index;
211
212 /* Plane 0 needs to be set separately. Set other planes in a loop */
213 bufDef.planes[0].length = offset.mp[0].len;
214 bufDef.planes[0].m.userptr = mMemInfo[index].fd;
215 bufDef.planes[0].data_offset = offset.mp[0].offset;
216 bufDef.planes[0].reserved[0] = 0;
217 for (int i = 1; i < bufDef.num_planes; i++) {
218 bufDef.planes[i].length = offset.mp[i].len;
219 bufDef.planes[i].m.userptr = mMemInfo[i].fd;
220 bufDef.planes[i].data_offset = offset.mp[i].offset;
221 bufDef.planes[i].reserved[0] =
222 bufDef.planes[i-1].reserved[0] +
223 bufDef.planes[i-1].length;
224 }
225 }
226
227 /*===========================================================================
228 * FUNCTION : alloc
229 *
230 * DESCRIPTION: allocate requested number of buffers of certain size
231 *
232 * PARAMETERS :
233 * @count : number of buffers to be allocated
234 * @size : lenght of the buffer to be allocated
235 * @heap_id : heap id to indicate where the buffers will be allocated from
236 *
237 * RETURN : int32_t type of status
238 * NO_ERROR -- success
239 * none-zero failure code
240 *==========================================================================*/
alloc(int count,int size,int heap_id,uint32_t secure_mode)241 int QCameraMemory::alloc(int count, int size, int heap_id, uint32_t secure_mode)
242 {
243 int rc = OK;
244
245 if (mBufferCount < 0) {
246 mBufferCount = 0;
247 }
248
249 int new_bufCnt = mBufferCount + count;
250
251 if (new_bufCnt > MM_CAMERA_MAX_NUM_FRAMES) {
252 ALOGE("%s: Buffer count %d out of bound. Max is %d",
253 __func__, new_bufCnt, MM_CAMERA_MAX_NUM_FRAMES);
254 return BAD_INDEX;
255 }
256
257 for (int i = mBufferCount; i < new_bufCnt; i ++) {
258 if ( NULL == mMemoryPool ) {
259 ALOGE("%s : No memory pool available", __func__);
260 rc = allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached,
261 secure_mode);
262 if (rc < 0) {
263 ALOGE("%s: AllocateIonMemory failed", __func__);
264 for (int j = i-1; j >= 0; j--)
265 deallocOneBuffer(mMemInfo[j]);
266 break;
267 }
268 } else {
269 rc = mMemoryPool->allocateBuffer(mMemInfo[i],
270 heap_id,
271 size,
272 m_bCached,
273 mStreamType,
274 secure_mode);
275 if (rc < 0) {
276 ALOGE("%s: Memory pool allocation failed", __func__);
277 for (int j = i-1; j >= 0; j--)
278 mMemoryPool->releaseBuffer(mMemInfo[j],
279 mStreamType);
280 break;
281 }
282 }
283
284 }
285 return rc;
286 }
287
288 /*===========================================================================
289 * FUNCTION : dealloc
290 *
291 * DESCRIPTION: deallocate buffers
292 *
293 * PARAMETERS : none
294 *
295 * RETURN : none
296 *==========================================================================*/
dealloc()297 void QCameraMemory::dealloc()
298 {
299 for (int i = 0; i < mBufferCount; i++) {
300 if ( NULL == mMemoryPool ) {
301 deallocOneBuffer(mMemInfo[i]);
302 } else {
303 mMemoryPool->releaseBuffer(mMemInfo[i], mStreamType);
304 }
305 }
306 }
307
308 /*===========================================================================
309 * FUNCTION : allocOneBuffer
310 *
311 * DESCRIPTION: impl of allocating one buffers of certain size
312 *
313 * PARAMETERS :
314 * @memInfo : [output] reference to struct to store additional memory allocation info
315 * @heap : [input] heap id to indicate where the buffers will be allocated from
316 * @size : [input] lenght of the buffer to be allocated
317 * @cached : [input] flag whether buffer needs to be cached
318 *
319 * RETURN : int32_t type of status
320 * NO_ERROR -- success
321 * none-zero failure code
322 *==========================================================================*/
allocOneBuffer(QCameraMemInfo & memInfo,int heap_id,int size,bool cached,uint32_t secure_mode)323 int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo,
324 int heap_id,
325 int size,
326 bool cached,
327 uint32_t secure_mode)
328 {
329 int rc = OK;
330 struct ion_handle_data handle_data;
331 struct ion_allocation_data alloc;
332 struct ion_fd_data ion_info_fd;
333 int main_ion_fd = 0;
334
335 main_ion_fd = open("/dev/ion", O_RDONLY);
336 if (main_ion_fd < 0) {
337 ALOGE("Ion dev open failed: %s\n", strerror(errno));
338 goto ION_OPEN_FAILED;
339 }
340
341 memset(&alloc, 0, sizeof(alloc));
342 alloc.len = size;
343 /* to make it page size aligned */
344 alloc.len = (alloc.len + 4095) & (~4095);
345 alloc.align = 4096;
346 if (cached) {
347 alloc.flags = ION_FLAG_CACHED;
348 }
349 alloc.heap_mask = heap_id;
350 if (secure_mode == SECURE) {
351 ALOGD("%s: Allocate secure buffer\n", __func__);
352 alloc.flags = ION_SECURE;
353 alloc.heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
354 alloc.align = 1024*1024; //1 MB alignment to be able to protect later
355 alloc.len = (alloc.len + (1024 * 1024 - 1)) & (~(1024 * 1024 -1));
356 }
357
358 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
359 if (rc < 0) {
360 ALOGE("ION allocation failed: %s\n", strerror(errno));
361 goto ION_ALLOC_FAILED;
362 }
363
364 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
365 ion_info_fd.handle = alloc.handle;
366 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
367 if (rc < 0) {
368 ALOGE("ION map failed %s\n", strerror(errno));
369 goto ION_MAP_FAILED;
370 }
371
372 memInfo.main_ion_fd = main_ion_fd;
373 memInfo.fd = ion_info_fd.fd;
374 memInfo.handle = ion_info_fd.handle;
375 memInfo.size = alloc.len;
376 memInfo.cached = cached;
377 memInfo.heap_id = heap_id;
378
379 ALOGD("%s : ION buffer %lx with size %d allocated",
380 __func__, (unsigned long)memInfo.handle, alloc.len);
381 return OK;
382
383 ION_MAP_FAILED:
384 memset(&handle_data, 0, sizeof(handle_data));
385 handle_data.handle = ion_info_fd.handle;
386 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
387 ION_ALLOC_FAILED:
388 close(main_ion_fd);
389 ION_OPEN_FAILED:
390 return NO_MEMORY;
391 }
392
393 /*===========================================================================
394 * FUNCTION : deallocOneBuffer
395 *
396 * DESCRIPTION: impl of deallocating one buffers
397 *
398 * PARAMETERS :
399 * @memInfo : reference to struct that stores additional memory allocation info
400 *
401 * RETURN : none
402 *==========================================================================*/
deallocOneBuffer(QCameraMemInfo & memInfo)403 void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo)
404 {
405 struct ion_handle_data handle_data;
406
407 if (memInfo.fd > 0) {
408 close(memInfo.fd);
409 memInfo.fd = 0;
410 }
411
412 if (memInfo.main_ion_fd > 0) {
413 memset(&handle_data, 0, sizeof(handle_data));
414 handle_data.handle = memInfo.handle;
415 ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
416 close(memInfo.main_ion_fd);
417 memInfo.main_ion_fd = 0;
418 }
419 memInfo.handle = 0;
420 memInfo.size = 0;
421 }
422
423 /*===========================================================================
424 * FUNCTION : QCameraMemoryPool
425 *
426 * DESCRIPTION: default constructor of QCameraMemoryPool
427 *
428 * PARAMETERS : None
429 *
430 * RETURN : None
431 *==========================================================================*/
QCameraMemoryPool()432 QCameraMemoryPool::QCameraMemoryPool()
433 {
434 pthread_mutex_init(&mLock, NULL);
435 }
436
437
438 /*===========================================================================
439 * FUNCTION : ~QCameraMemoryPool
440 *
441 * DESCRIPTION: deconstructor of QCameraMemoryPool
442 *
443 * PARAMETERS : None
444 *
445 * RETURN : None
446 *==========================================================================*/
~QCameraMemoryPool()447 QCameraMemoryPool::~QCameraMemoryPool()
448 {
449 clear();
450 pthread_mutex_destroy(&mLock);
451 }
452
453 /*===========================================================================
454 * FUNCTION : releaseBuffer
455 *
456 * DESCRIPTION: release one cached buffers
457 *
458 * PARAMETERS :
459 * @memInfo : reference to struct that stores additional memory allocation info
460 * @streamType: Type of stream the buffers belongs to
461 *
462 * RETURN : none
463 *==========================================================================*/
releaseBuffer(struct QCameraMemory::QCameraMemInfo & memInfo,cam_stream_type_t streamType)464 void QCameraMemoryPool::releaseBuffer(
465 struct QCameraMemory::QCameraMemInfo &memInfo,
466 cam_stream_type_t streamType)
467 {
468 pthread_mutex_lock(&mLock);
469
470 mPools[streamType].push_back(memInfo);
471
472 pthread_mutex_unlock(&mLock);
473 }
474
475 /*===========================================================================
476 * FUNCTION : clear
477 *
478 * DESCRIPTION: clears all cached buffers
479 *
480 * PARAMETERS : none
481 *
482 * RETURN : none
483 *==========================================================================*/
clear()484 void QCameraMemoryPool::clear()
485 {
486 pthread_mutex_lock(&mLock);
487
488 for (int i = CAM_STREAM_TYPE_DEFAULT; i < CAM_STREAM_TYPE_MAX; i++ ) {
489 List<struct QCameraMemory::QCameraMemInfo>::iterator it;
490 it = mPools[i].begin();
491 for( ; it != mPools[i].end() ; it++) {
492 QCameraMemory::deallocOneBuffer(*it);
493 }
494
495 mPools[i].clear();
496 }
497
498 pthread_mutex_unlock(&mLock);
499 }
500
501 /*===========================================================================
502 * FUNCTION : findBufferLocked
503 *
504 * DESCRIPTION: search for a appropriate cached buffer
505 *
506 * PARAMETERS :
507 * @memInfo : reference to struct that stores additional memory allocation info
508 * @heap_id : type of heap
509 * @size : size of the buffer
510 * @cached : whether the buffer should be cached
511 * @streaType: type of stream this buffer belongs to
512 *
513 * RETURN : int32_t type of status
514 * NO_ERROR -- success
515 * none-zero failure code
516 *==========================================================================*/
findBufferLocked(struct QCameraMemory::QCameraMemInfo & memInfo,int heap_id,uint32_t size,bool cached,cam_stream_type_t streamType)517 int QCameraMemoryPool::findBufferLocked(
518 struct QCameraMemory::QCameraMemInfo &memInfo,
519 int heap_id,
520 uint32_t size,
521 bool cached,
522 cam_stream_type_t streamType)
523 {
524 int rc = NAME_NOT_FOUND;
525
526 if (mPools[streamType].empty()) {
527 return NAME_NOT_FOUND;
528 }
529
530 List<struct QCameraMemory::QCameraMemInfo>::iterator it;
531 it = mPools[streamType].begin();
532 for ( ; it != mPools[streamType].end() ; it++) {
533 if ( ((*it).size >= size) &&
534 ((*it).heap_id == heap_id) &&
535 ((*it).cached == cached) ) {
536 memInfo = *it;
537 mPools[streamType].erase(it);
538 rc = NO_ERROR;
539 break;
540 }
541 }
542
543 return rc;
544 }
545
546 /*===========================================================================
547 * FUNCTION : allocateBuffer
548 *
549 * DESCRIPTION: allocates a buffer from the memory pool,
550 * it will re-use cached buffers if possible
551 *
552 * PARAMETERS :
553 * @memInfo : reference to struct that stores additional memory allocation info
554 * @heap_id : type of heap
555 * @size : size of the buffer
556 * @cached : whether the buffer should be cached
557 * @streaType: type of stream this buffer belongs to
558 *
559 * RETURN : int32_t type of status
560 * NO_ERROR -- success
561 * none-zero failure code
562 *==========================================================================*/
allocateBuffer(struct QCameraMemory::QCameraMemInfo & memInfo,int heap_id,int size,bool cached,cam_stream_type_t streamType,int secure_mode)563 int QCameraMemoryPool::allocateBuffer(
564 struct QCameraMemory::QCameraMemInfo &memInfo,
565 int heap_id,
566 int size,
567 bool cached,
568 cam_stream_type_t streamType,
569 int secure_mode)
570 {
571 int rc = NO_ERROR;
572
573 pthread_mutex_lock(&mLock);
574
575 rc = findBufferLocked(memInfo, heap_id, size, cached, streamType);
576 if (NAME_NOT_FOUND == rc ) {
577 ALOGE("%s : Buffer not found!", __func__);
578 rc = QCameraMemory::allocOneBuffer(memInfo, heap_id, size, cached,
579 secure_mode);
580 }
581
582 pthread_mutex_unlock(&mLock);
583
584 return rc;
585 }
586
587 /*===========================================================================
588 * FUNCTION : QCameraHeapMemory
589 *
590 * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL
591 *
592 * PARAMETERS :
593 * @cached : flag indicates if using cached memory
594 *
595 * RETURN : none
596 *==========================================================================*/
QCameraHeapMemory(bool cached)597 QCameraHeapMemory::QCameraHeapMemory(bool cached)
598 : QCameraMemory(cached)
599 {
600 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
601 mPtr[i] = NULL;
602 }
603
604 /*===========================================================================
605 * FUNCTION : ~QCameraHeapMemory
606 *
607 * DESCRIPTION: deconstructor of QCameraHeapMemory
608 *
609 * PARAMETERS : none
610 *
611 * RETURN : none
612 *==========================================================================*/
~QCameraHeapMemory()613 QCameraHeapMemory::~QCameraHeapMemory()
614 {
615 }
616
617 /*===========================================================================
618 * FUNCTION : getPtr
619 *
620 * DESCRIPTION: return buffer pointer
621 *
622 * PARAMETERS :
623 * @index : index of the buffer
624 *
625 * RETURN : buffer ptr
626 *==========================================================================*/
getPtr(int index) const627 void *QCameraHeapMemory::getPtr(int index) const
628 {
629 if (index >= mBufferCount) {
630 ALOGE("index out of bound");
631 return (void *)BAD_INDEX;
632 }
633 return mPtr[index];
634 }
635
636 /*===========================================================================
637 * FUNCTION : allocate
638 *
639 * DESCRIPTION: allocate requested number of buffers of certain size
640 *
641 * PARAMETERS :
642 * @count : number of buffers to be allocated
643 * @size : lenght of the buffer to be allocated
644 *
645 * RETURN : int32_t type of status
646 * NO_ERROR -- success
647 * none-zero failure code
648 *==========================================================================*/
allocate(int count,int size,uint32_t isSecure)649 int QCameraHeapMemory::allocate(int count, int size, uint32_t isSecure)
650 {
651 int rc = -1;
652 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
653 if (isSecure == SECURE) {
654 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
655 rc = alloc(count, size, heap_mask, SECURE);
656 if (rc < 0)
657 return rc;
658
659 } else {
660 rc = alloc(count, size, heap_mask, NON_SECURE);
661 if (rc < 0)
662 return rc;
663
664 for (int i = 0; i < count; i ++) {
665 void *vaddr = mmap(NULL,
666 mMemInfo[i].size,
667 PROT_READ | PROT_WRITE,
668 MAP_SHARED,
669 mMemInfo[i].fd, 0);
670 if (vaddr == MAP_FAILED) {
671 for (int j = i-1; j >= 0; j --) {
672 munmap(mPtr[j], mMemInfo[j].size);
673 mPtr[j] = NULL;
674 deallocOneBuffer(mMemInfo[j]);
675 }
676 return NO_MEMORY;
677 } else
678 mPtr[i] = vaddr;
679 }
680 }
681 if (rc == 0) {
682 mBufferCount = count;
683 }
684 return OK;
685 }
686
687 /*===========================================================================
688 * FUNCTION : allocateMore
689 *
690 * DESCRIPTION: allocate more requested number of buffers of certain size
691 *
692 * PARAMETERS :
693 * @count : number of buffers to be allocated
694 * @size : lenght of the buffer to be allocated
695 *
696 * RETURN : int32_t type of status
697 * NO_ERROR -- success
698 * none-zero failure code
699 *==========================================================================*/
allocateMore(int count,int size)700 int QCameraHeapMemory::allocateMore(int count, int size)
701 {
702 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
703 int rc = alloc(count, size, heap_mask, NON_SECURE);
704 if (rc < 0)
705 return rc;
706
707 for (int i = mBufferCount; i < count + mBufferCount; i ++) {
708 void *vaddr = mmap(NULL,
709 mMemInfo[i].size,
710 PROT_READ | PROT_WRITE,
711 MAP_SHARED,
712 mMemInfo[i].fd, 0);
713 if (vaddr == MAP_FAILED) {
714 for (int j = i-1; j >= mBufferCount; j --) {
715 munmap(mPtr[j], mMemInfo[j].size);
716 mPtr[j] = NULL;
717 deallocOneBuffer(mMemInfo[j]);
718 }
719 return NO_MEMORY;
720 } else {
721 mPtr[i] = vaddr;
722 }
723 }
724 mBufferCount += count;
725 return OK;
726 }
727
728 /*===========================================================================
729 * FUNCTION : deallocate
730 *
731 * DESCRIPTION: deallocate buffers
732 *
733 * PARAMETERS : none
734 *
735 * RETURN : none
736 *==========================================================================*/
deallocate()737 void QCameraHeapMemory::deallocate()
738 {
739 for (int i = 0; i < mBufferCount; i++) {
740 munmap(mPtr[i], mMemInfo[i].size);
741 mPtr[i] = NULL;
742 }
743 dealloc();
744 mBufferCount = 0;
745 }
746
747 /*===========================================================================
748 * FUNCTION : cacheOps
749 *
750 * DESCRIPTION: ion related memory cache operations
751 *
752 * PARAMETERS :
753 * @index : index of the buffer
754 * @cmd : cache ops command
755 *
756 * RETURN : int32_t type of status
757 * NO_ERROR -- success
758 * none-zero failure code
759 *==========================================================================*/
cacheOps(int index,unsigned int cmd)760 int QCameraHeapMemory::cacheOps(int index, unsigned int cmd)
761 {
762 if (index >= mBufferCount)
763 return BAD_INDEX;
764 return cacheOpsInternal(index, cmd, mPtr[index]);
765 }
766
767 /*===========================================================================
768 * FUNCTION : getRegFlags
769 *
770 * DESCRIPTION: query initial reg flags
771 *
772 * PARAMETERS :
773 * @regFlags: initial reg flags of the allocated buffers
774 *
775 * RETURN : int32_t type of status
776 * NO_ERROR -- success
777 * none-zero failure code
778 *==========================================================================*/
getRegFlags(uint8_t *) const779 int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const
780 {
781 return INVALID_OPERATION;
782 }
783
784 /*===========================================================================
785 * FUNCTION : getMemory
786 *
787 * DESCRIPTION: get camera memory
788 *
789 * PARAMETERS :
790 * @index : buffer index
791 * @metadata: flag if it's metadata
792 *
793 * RETURN : camera memory ptr
794 * NULL if not supported or failed
795 *==========================================================================*/
getMemory(int,bool) const796 camera_memory_t *QCameraHeapMemory::getMemory(
797 int /*index*/, bool /*metadata*/) const
798 {
799 return NULL;
800 }
801
802 /*===========================================================================
803 * FUNCTION : getMatchBufIndex
804 *
805 * DESCRIPTION: query buffer index by opaque ptr
806 *
807 * PARAMETERS :
808 * @opaque : opaque ptr
809 * @metadata: flag if it's metadata
810 *
811 * RETURN : buffer index if match found,
812 * -1 if failed
813 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const814 int QCameraHeapMemory::getMatchBufIndex(const void *opaque,
815 bool metadata) const
816 {
817 int index = -1;
818 if (metadata) {
819 return -1;
820 }
821 for (int i = 0; i < mBufferCount; i++) {
822 if (mPtr[i] == opaque) {
823 index = i;
824 break;
825 }
826 }
827 return index;
828 }
829
830 /*===========================================================================
831 * FUNCTION : QCameraStreamMemory
832 *
833 * DESCRIPTION: constructor of QCameraStreamMemory
834 * ION memory allocated directly from /dev/ion and shared with framework
835 *
836 * PARAMETERS :
837 * @getMemory : camera memory request ops table
838 * @cached : flag indicates if using cached memory
839 *
840 * RETURN : none
841 *==========================================================================*/
QCameraStreamMemory(camera_request_memory getMemory,bool cached,QCameraMemoryPool * pool,cam_stream_type_t streamType)842 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory getMemory,
843 bool cached,
844 QCameraMemoryPool *pool,
845 cam_stream_type_t streamType)
846 :QCameraMemory(cached, pool, streamType),
847 mGetMemory(getMemory)
848 {
849 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
850 mCameraMemory[i] = NULL;
851 }
852
853 /*===========================================================================
854 * FUNCTION : ~QCameraStreamMemory
855 *
856 * DESCRIPTION: deconstructor of QCameraStreamMemory
857 *
858 * PARAMETERS : none
859 *
860 * RETURN : none
861 *==========================================================================*/
~QCameraStreamMemory()862 QCameraStreamMemory::~QCameraStreamMemory()
863 {
864 }
865
866 /*===========================================================================
867 * FUNCTION : allocate
868 *
869 * DESCRIPTION: allocate requested number of buffers of certain size
870 *
871 * PARAMETERS :
872 * @count : number of buffers to be allocated
873 * @size : lenght of the buffer to be allocated
874 *
875 * RETURN : int32_t type of status
876 * NO_ERROR -- success
877 * none-zero failure code
878 *==========================================================================*/
allocate(int count,int size,uint32_t isSecure)879 int QCameraStreamMemory::allocate(int count, int size, uint32_t isSecure)
880 {
881 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
882 int rc = alloc(count, size, heap_mask, isSecure);
883 if (rc < 0)
884 return rc;
885
886 for (int i = 0; i < count; i ++) {
887 if (isSecure == SECURE) {
888 mCameraMemory[i] = 0;
889 } else {
890 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
891 }
892 }
893 mBufferCount = count;
894 return NO_ERROR;
895 }
896
897 /*===========================================================================
898 * FUNCTION : allocateMore
899 *
900 * DESCRIPTION: allocate more requested number of buffers of certain size
901 *
902 * PARAMETERS :
903 * @count : number of buffers to be allocated
904 * @size : lenght of the buffer to be allocated
905 *
906 * RETURN : int32_t type of status
907 * NO_ERROR -- success
908 * none-zero failure code
909 *==========================================================================*/
allocateMore(int count,int size)910 int QCameraStreamMemory::allocateMore(int count, int size)
911 {
912 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
913 int rc = alloc(count, size, heap_mask, NON_SECURE);
914 if (rc < 0)
915 return rc;
916
917 for (int i = mBufferCount; i < mBufferCount + count; i++) {
918 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
919 }
920 mBufferCount += count;
921 return NO_ERROR;
922 }
923
924 /*===========================================================================
925 * FUNCTION : deallocate
926 *
927 * DESCRIPTION: deallocate buffers
928 *
929 * PARAMETERS : none
930 *
931 * RETURN : none
932 *==========================================================================*/
deallocate()933 void QCameraStreamMemory::deallocate()
934 {
935 for (int i = 0; i < mBufferCount; i ++) {
936 if (mCameraMemory[i])
937 mCameraMemory[i]->release(mCameraMemory[i]);
938 mCameraMemory[i] = NULL;
939 }
940 dealloc();
941 mBufferCount = 0;
942 }
943
944 /*===========================================================================
945 * FUNCTION : cacheOps
946 *
947 * DESCRIPTION: ion related memory cache operations
948 *
949 * PARAMETERS :
950 * @index : index of the buffer
951 * @cmd : cache ops command
952 *
953 * RETURN : int32_t type of status
954 * NO_ERROR -- success
955 * none-zero failure code
956 *==========================================================================*/
cacheOps(int index,unsigned int cmd)957 int QCameraStreamMemory::cacheOps(int index, unsigned int cmd)
958 {
959 if (index >= mBufferCount)
960 return BAD_INDEX;
961 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
962 }
963
964 /*===========================================================================
965 * FUNCTION : getRegFlags
966 *
967 * DESCRIPTION: query initial reg flags
968 *
969 * PARAMETERS :
970 * @regFlags: initial reg flags of the allocated buffers
971 *
972 * RETURN : int32_t type of status
973 * NO_ERROR -- success
974 * none-zero failure code
975 *==========================================================================*/
getRegFlags(uint8_t * regFlags) const976 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
977 {
978 for (int i = 0; i < mBufferCount; i ++)
979 regFlags[i] = 1;
980 return NO_ERROR;
981 }
982
983 /*===========================================================================
984 * FUNCTION : getMemory
985 *
986 * DESCRIPTION: get camera memory
987 *
988 * PARAMETERS :
989 * @index : buffer index
990 * @metadata: flag if it's metadata
991 *
992 * RETURN : camera memory ptr
993 * NULL if not supported or failed
994 *==========================================================================*/
getMemory(int index,bool metadata) const995 camera_memory_t *QCameraStreamMemory::getMemory(int index, bool metadata) const
996 {
997 if (index >= mBufferCount || metadata)
998 return NULL;
999 return mCameraMemory[index];
1000 }
1001
1002 /*===========================================================================
1003 * FUNCTION : getMatchBufIndex
1004 *
1005 * DESCRIPTION: query buffer index by opaque ptr
1006 *
1007 * PARAMETERS :
1008 * @opaque : opaque ptr
1009 * @metadata: flag if it's metadata
1010 *
1011 * RETURN : buffer index if match found,
1012 * -1 if failed
1013 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1014 int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
1015 bool metadata) const
1016 {
1017 int index = -1;
1018 if (metadata) {
1019 return -1;
1020 }
1021 for (int i = 0; i < mBufferCount; i++) {
1022 if (mCameraMemory[i]->data == opaque) {
1023 index = i;
1024 break;
1025 }
1026 }
1027 return index;
1028 }
1029
1030 /*===========================================================================
1031 * FUNCTION : getPtr
1032 *
1033 * DESCRIPTION: return buffer pointer
1034 *
1035 * PARAMETERS :
1036 * @index : index of the buffer
1037 *
1038 * RETURN : buffer ptr
1039 *==========================================================================*/
getPtr(int index) const1040 void *QCameraStreamMemory::getPtr(int index) const
1041 {
1042 if (index >= mBufferCount) {
1043 ALOGE("index out of bound");
1044 return (void *)BAD_INDEX;
1045 }
1046 if (mCameraMemory[index] == 0) {
1047 return NULL;
1048 }
1049 return mCameraMemory[index]->data;
1050 }
1051
1052 /*===========================================================================
1053 * FUNCTION : QCameraVideoMemory
1054 *
1055 * DESCRIPTION: constructor of QCameraVideoMemory
1056 * VideoStream buffers also include metadata buffers
1057 *
1058 * PARAMETERS :
1059 * @getMemory : camera memory request ops table
1060 * @cached : flag indicates if using cached ION memory
1061 *
1062 * RETURN : none
1063 *==========================================================================*/
QCameraVideoMemory(camera_request_memory getMemory,bool cached)1064 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory getMemory,
1065 bool cached)
1066 : QCameraStreamMemory(getMemory, cached)
1067 {
1068 memset(mMetadata, 0, sizeof(mMetadata));
1069 }
1070
1071 /*===========================================================================
1072 * FUNCTION : ~QCameraVideoMemory
1073 *
1074 * DESCRIPTION: deconstructor of QCameraVideoMemory
1075 *
1076 * PARAMETERS : none
1077 *
1078 * RETURN : none
1079 *==========================================================================*/
~QCameraVideoMemory()1080 QCameraVideoMemory::~QCameraVideoMemory()
1081 {
1082 }
1083
1084 /*===========================================================================
1085 * FUNCTION : allocate
1086 *
1087 * DESCRIPTION: allocate requested number of buffers of certain size
1088 *
1089 * PARAMETERS :
1090 * @count : number of buffers to be allocated
1091 * @size : lenght of the buffer to be allocated
1092 *
1093 * RETURN : int32_t type of status
1094 * NO_ERROR -- success
1095 * none-zero failure code
1096 *==========================================================================*/
allocate(int count,int size,uint32_t isSecure)1097 int QCameraVideoMemory::allocate(int count, int size, uint32_t isSecure)
1098 {
1099 int rc = QCameraStreamMemory::allocate(count, size, isSecure);
1100 if (rc < 0)
1101 return rc;
1102
1103 for (int i = 0; i < count; i ++) {
1104 mMetadata[i] = mGetMemory(-1,
1105 sizeof(struct encoder_media_buffer_type), 1, this);
1106 if (!mMetadata[i]) {
1107 ALOGE("allocation of video metadata failed.");
1108 for (int j = 0; j <= i-1; j ++)
1109 mMetadata[j]->release(mMetadata[j]);
1110 QCameraStreamMemory::deallocate();
1111 return NO_MEMORY;
1112 }
1113 struct encoder_media_buffer_type * packet =
1114 (struct encoder_media_buffer_type *)mMetadata[i]->data;
1115 packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
1116 packet->buffer_type = kMetadataBufferTypeCameraSource;
1117 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1118 nh->data[0] = mMemInfo[i].fd;
1119 nh->data[1] = 0;
1120 nh->data[2] = mMemInfo[i].size;
1121 nh->data[3] = private_handle_t::PRIV_FLAGS_ITU_R_709;
1122 }
1123 mBufferCount = count;
1124 return NO_ERROR;
1125 }
1126
1127 /*===========================================================================
1128 * FUNCTION : allocateMore
1129 *
1130 * DESCRIPTION: allocate more requested number of buffers of certain size
1131 *
1132 * PARAMETERS :
1133 * @count : number of buffers to be allocated
1134 * @size : lenght of the buffer to be allocated
1135 *
1136 * RETURN : int32_t type of status
1137 * NO_ERROR -- success
1138 * none-zero failure code
1139 *==========================================================================*/
allocateMore(int count,int size)1140 int QCameraVideoMemory::allocateMore(int count, int size)
1141 {
1142 int rc = QCameraStreamMemory::allocateMore(count, size);
1143 if (rc < 0)
1144 return rc;
1145
1146 for (int i = mBufferCount; i < count + mBufferCount; i ++) {
1147 mMetadata[i] = mGetMemory(-1,
1148 sizeof(struct encoder_media_buffer_type), 1, this);
1149 if (!mMetadata[i]) {
1150 ALOGE("allocation of video metadata failed.");
1151 for (int j = mBufferCount; j <= i-1; j ++) {
1152 mMetadata[j]->release(mMetadata[j]);
1153 mCameraMemory[j]->release(mCameraMemory[j]);
1154 mCameraMemory[j] = NULL;
1155 deallocOneBuffer(mMemInfo[j]);;
1156 }
1157 return NO_MEMORY;
1158 }
1159 struct encoder_media_buffer_type * packet =
1160 (struct encoder_media_buffer_type *)mMetadata[i]->data;
1161 packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
1162 packet->buffer_type = kMetadataBufferTypeCameraSource;
1163 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1164 nh->data[0] = mMemInfo[i].fd;
1165 nh->data[1] = 0;
1166 nh->data[2] = mMemInfo[i].size;
1167 }
1168 mBufferCount += count;
1169 return NO_ERROR;
1170 }
1171
1172 /*===========================================================================
1173 * FUNCTION : deallocate
1174 *
1175 * DESCRIPTION: deallocate buffers
1176 *
1177 * PARAMETERS : none
1178 *
1179 * RETURN : none
1180 *==========================================================================*/
deallocate()1181 void QCameraVideoMemory::deallocate()
1182 {
1183 for (int i = 0; i < mBufferCount; i ++) {
1184 struct encoder_media_buffer_type * packet =
1185 (struct encoder_media_buffer_type *)mMetadata[i]->data;
1186 if (NULL != packet) {
1187 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1188 if (NULL != nh) {
1189 if (native_handle_delete(nh)) {
1190 ALOGE("Unable to delete native handle");
1191 }
1192 }
1193 else {
1194 ALOGE("native handle not available");
1195 }
1196 }
1197 else {
1198 ALOGE("packet not available");
1199 }
1200 mMetadata[i]->release(mMetadata[i]);
1201 mMetadata[i] = NULL;
1202 }
1203 QCameraStreamMemory::deallocate();
1204 mBufferCount = 0;
1205 }
1206
1207 /*===========================================================================
1208 * FUNCTION : getMemory
1209 *
1210 * DESCRIPTION: get camera memory
1211 *
1212 * PARAMETERS :
1213 * @index : buffer index
1214 * @metadata: flag if it's metadata
1215 *
1216 * RETURN : camera memory ptr
1217 * NULL if not supported or failed
1218 *==========================================================================*/
getMemory(int index,bool metadata) const1219 camera_memory_t *QCameraVideoMemory::getMemory(int index, bool metadata) const
1220 {
1221 if (index >= mBufferCount)
1222 return NULL;
1223 if (metadata)
1224 return mMetadata[index];
1225 else
1226 return mCameraMemory[index];
1227 }
1228
1229 /*===========================================================================
1230 * FUNCTION : getMatchBufIndex
1231 *
1232 * DESCRIPTION: query buffer index by opaque ptr
1233 *
1234 * PARAMETERS :
1235 * @opaque : opaque ptr
1236 * @metadata: flag if it's metadata
1237 *
1238 * RETURN : buffer index if match found,
1239 * -1 if failed
1240 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1241 int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
1242 bool metadata) const
1243 {
1244 int index = -1;
1245 for (int i = 0; i < mBufferCount; i++) {
1246 if (metadata) {
1247 if (mMetadata[i]->data == opaque) {
1248 index = i;
1249 break;
1250 }
1251 } else {
1252 if (mCameraMemory[i]->data == opaque) {
1253 index = i;
1254 break;
1255 }
1256 }
1257 }
1258 return index;
1259 }
1260
1261 /*===========================================================================
1262 * FUNCTION : QCameraGrallocMemory
1263 *
1264 * DESCRIPTION: constructor of QCameraGrallocMemory
1265 * preview stream buffers are allocated from gralloc native_windoe
1266 *
1267 * PARAMETERS :
1268 * @getMemory : camera memory request ops table
1269 *
1270 * RETURN : none
1271 *==========================================================================*/
QCameraGrallocMemory(camera_request_memory getMemory)1272 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory getMemory)
1273 : QCameraMemory(true), mColorSpace(ITU_R_601_FR)
1274 {
1275 mMinUndequeuedBuffers = 0;
1276 mWindow = NULL;
1277 mWidth = mHeight = mStride = mScanline = 0;
1278 mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1279 mGetMemory = getMemory;
1280 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
1281 mBufferHandle[i] = NULL;
1282 mLocalFlag[i] = BUFFER_NOT_OWNED;
1283 mPrivateHandle[i] = NULL;
1284 }
1285 }
1286
1287 /*===========================================================================
1288 * FUNCTION : ~QCameraGrallocMemory
1289 *
1290 * DESCRIPTION: deconstructor of QCameraGrallocMemory
1291 *
1292 * PARAMETERS : none
1293 *
1294 * RETURN : none
1295 *==========================================================================*/
~QCameraGrallocMemory()1296 QCameraGrallocMemory::~QCameraGrallocMemory()
1297 {
1298 }
1299
1300 /*===========================================================================
1301 * FUNCTION : setWindowInfo
1302 *
1303 * DESCRIPTION: set native window gralloc ops table
1304 *
1305 * PARAMETERS :
1306 * @window : gralloc ops table ptr
1307 * @width : width of preview frame
1308 * @height : height of preview frame
1309 * @stride : stride of preview frame
1310 * @scanline: scanline of preview frame
1311 * @foramt : format of preview image
1312 *
1313 * RETURN : none
1314 *==========================================================================*/
setWindowInfo(preview_stream_ops_t * window,int width,int height,int stride,int scanline,int format)1315 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
1316 int width, int height, int stride, int scanline, int format)
1317 {
1318 mWindow = window;
1319 mWidth = width;
1320 mHeight = height;
1321 mStride = stride;
1322 mScanline = scanline;
1323 mFormat = format;
1324 }
1325
1326 /*===========================================================================
1327 * FUNCTION : displayBuffer
1328 *
1329 * DESCRIPTION: send received frame to display
1330 *
1331 * PARAMETERS :
1332 * @index : index of preview frame
1333 *
1334 * RETURN : int32_t type of status
1335 * NO_ERROR -- success
1336 * none-zero failure code
1337 *==========================================================================*/
displayBuffer(int index)1338 int QCameraGrallocMemory::displayBuffer(int index)
1339 {
1340 int err = NO_ERROR;
1341 int dequeuedIdx = BAD_INDEX;
1342
1343 if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
1344 ALOGE("%s: buffer to be enqueued is not owned", __func__);
1345 return INVALID_OPERATION;
1346 }
1347
1348 err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
1349 if(err != 0) {
1350 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
1351 } else {
1352 CDBG("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]);
1353 mLocalFlag[index] = BUFFER_NOT_OWNED;
1354 }
1355
1356 buffer_handle_t *buffer_handle = NULL;
1357 int stride = 0;
1358 err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
1359 if (err == NO_ERROR && buffer_handle != NULL) {
1360 int i;
1361 CDBG("%s: dequed buf hdl =%p", __func__, *buffer_handle);
1362 for(i = 0; i < mBufferCount; i++) {
1363 if(mBufferHandle[i] == buffer_handle) {
1364 CDBG("%s: Found buffer in idx:%d", __func__, i);
1365 mLocalFlag[i] = BUFFER_OWNED;
1366 dequeuedIdx = i;
1367 break;
1368 }
1369 }
1370 } else {
1371 CDBG_HIGH("%s: dequeue_buffer, no free buffer from display now", __func__);
1372 }
1373 return dequeuedIdx;
1374 }
1375
1376 /*===========================================================================
1377 * FUNCTION : allocate
1378 *
1379 * DESCRIPTION: allocate requested number of buffers of certain size
1380 *
1381 * PARAMETERS :
1382 * @count : number of buffers to be allocated
1383 * @size : lenght of the buffer to be allocated
1384 *
1385 * RETURN : int32_t type of status
1386 * NO_ERROR -- success
1387 * none-zero failure code
1388 *==========================================================================*/
allocate(int count,int,uint32_t)1389 int QCameraGrallocMemory::allocate(int count, int /*size*/, uint32_t /*isSecure*/)
1390 {
1391 int err = 0;
1392 status_t ret = NO_ERROR;
1393 int gralloc_usage = 0;
1394 struct ion_fd_data ion_info_fd;
1395 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
1396
1397 CDBG(" %s : E ", __func__);
1398
1399 if (!mWindow) {
1400 ALOGE("Invalid native window");
1401 return INVALID_OPERATION;
1402 }
1403
1404 // Increment buffer count by min undequeued buffer.
1405 err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
1406 if (err != 0) {
1407 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)",
1408 strerror(-err), -err);
1409 ret = UNKNOWN_ERROR;
1410 goto end;
1411 }
1412
1413 err = mWindow->set_buffer_count(mWindow, count);
1414 if (err != 0) {
1415 ALOGE("set_buffer_count failed: %s (%d)",
1416 strerror(-err), -err);
1417 ret = UNKNOWN_ERROR;
1418 goto end;
1419 }
1420
1421 err = mWindow->set_buffers_geometry(mWindow, mStride, mScanline, mFormat);
1422 if (err != 0) {
1423 ALOGE("%s: set_buffers_geometry failed: %s (%d)",
1424 __func__, strerror(-err), -err);
1425 ret = UNKNOWN_ERROR;
1426 goto end;
1427 }
1428
1429 err = mWindow->set_crop(mWindow, 0, 0, mWidth, mHeight);
1430 if (err != 0) {
1431 ALOGE("%s: set_crop failed: %s (%d)",
1432 __func__, strerror(-err), -err);
1433 ret = UNKNOWN_ERROR;
1434 goto end;
1435 }
1436
1437 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
1438 err = mWindow->set_usage(mWindow, gralloc_usage);
1439 if(err != 0) {
1440 /* set_usage error out */
1441 ALOGE("%s: set_usage rc = %d", __func__, err);
1442 ret = UNKNOWN_ERROR;
1443 goto end;
1444 }
1445 CDBG_HIGH("%s: usage = %d, geometry: %p, %d, %d, %d, %d, %d",
1446 __func__, gralloc_usage, mWindow, mWidth, mHeight, mStride,
1447 mScanline, mFormat);
1448
1449 //Allocate cnt number of buffers from native window
1450 for (int cnt = 0; cnt < count; cnt++) {
1451 int stride;
1452 err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
1453 if(!err) {
1454 CDBG("dequeue buf hdl =%p", mBufferHandle[cnt]);
1455 mLocalFlag[cnt] = BUFFER_OWNED;
1456 } else {
1457 mLocalFlag[cnt] = BUFFER_NOT_OWNED;
1458 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
1459 }
1460
1461 CDBG("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]);
1462
1463 if(err != 0) {
1464 ALOGE("%s: dequeue_buffer failed: %s (%d)",
1465 __func__, strerror(-err), -err);
1466 ret = UNKNOWN_ERROR;
1467 for(int i = 0; i < cnt; i++) {
1468 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1469 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1470 CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1471 }
1472 mLocalFlag[i] = BUFFER_NOT_OWNED;
1473 mBufferHandle[i] = NULL;
1474 }
1475 memset(&mMemInfo, 0, sizeof(mMemInfo));
1476 goto end;
1477 }
1478
1479 mPrivateHandle[cnt] =
1480 (struct private_handle_t *)(*mBufferHandle[cnt]);
1481 mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
1482 if (mMemInfo[cnt].main_ion_fd < 0) {
1483 ALOGE("%s: failed: could not open ion device", __func__);
1484 for(int i = 0; i < cnt; i++) {
1485 struct ion_handle_data ion_handle;
1486 memset(&ion_handle, 0, sizeof(ion_handle));
1487 ion_handle.handle = mMemInfo[i].handle;
1488 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1489 ALOGE("%s: ion free failed", __func__);
1490 }
1491 close(mMemInfo[i].main_ion_fd);
1492 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1493 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1494 CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1495 }
1496 mLocalFlag[i] = BUFFER_NOT_OWNED;
1497 mBufferHandle[i] = NULL;
1498 }
1499 memset(&mMemInfo, 0, sizeof(mMemInfo));
1500 ret = UNKNOWN_ERROR;
1501 goto end;
1502 } else {
1503 ion_info_fd.fd = mPrivateHandle[cnt]->fd;
1504 if (ioctl(mMemInfo[cnt].main_ion_fd,
1505 ION_IOC_IMPORT, &ion_info_fd) < 0) {
1506 ALOGE("%s: ION import failed\n", __func__);
1507 for(int i = 0; i < cnt; i++) {
1508 struct ion_handle_data ion_handle;
1509 memset(&ion_handle, 0, sizeof(ion_handle));
1510 ion_handle.handle = mMemInfo[i].handle;
1511 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1512 ALOGE("ion free failed");
1513 }
1514 close(mMemInfo[i].main_ion_fd);
1515
1516 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1517 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1518 CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1519 }
1520 mLocalFlag[i] = BUFFER_NOT_OWNED;
1521 mBufferHandle[i] = NULL;
1522 }
1523 close(mMemInfo[cnt].main_ion_fd);
1524 memset(&mMemInfo, 0, sizeof(mMemInfo));
1525 ret = UNKNOWN_ERROR;
1526 goto end;
1527 }
1528 }
1529 setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace);
1530 mCameraMemory[cnt] =
1531 mGetMemory(mPrivateHandle[cnt]->fd,
1532 mPrivateHandle[cnt]->size,
1533 1,
1534 (void *)this);
1535 CDBG_HIGH("%s: idx = %d, fd = %d, size = %d, offset = %d",
1536 __func__, cnt, mPrivateHandle[cnt]->fd,
1537 mPrivateHandle[cnt]->size,
1538 mPrivateHandle[cnt]->offset);
1539 mMemInfo[cnt].fd =
1540 mPrivateHandle[cnt]->fd;
1541 mMemInfo[cnt].size =
1542 mPrivateHandle[cnt]->size;
1543 mMemInfo[cnt].handle = ion_info_fd.handle;
1544 }
1545 mBufferCount = count;
1546
1547 //Cancel min_undequeued_buffer buffers back to the window
1548 for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
1549 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1550 mLocalFlag[i] = BUFFER_NOT_OWNED;
1551 }
1552
1553 end:
1554 CDBG(" %s : X ",__func__);
1555 return ret;
1556 }
1557
1558
1559 /*===========================================================================
1560 * FUNCTION : allocateMore
1561 *
1562 * DESCRIPTION: allocate more requested number of buffers of certain size
1563 *
1564 * PARAMETERS :
1565 * @count : number of buffers to be allocated
1566 * @size : lenght of the buffer to be allocated
1567 *
1568 * RETURN : int32_t type of status
1569 * NO_ERROR -- success
1570 * none-zero failure code
1571 *==========================================================================*/
allocateMore(int,int)1572 int QCameraGrallocMemory::allocateMore(int /*count*/, int /*size*/)
1573 {
1574 ALOGE("%s: Not implenmented yet", __func__);
1575 return UNKNOWN_ERROR;
1576 }
1577
1578 /*===========================================================================
1579 * FUNCTION : deallocate
1580 *
1581 * DESCRIPTION: deallocate buffers
1582 *
1583 * PARAMETERS : none
1584 *
1585 * RETURN : none
1586 *==========================================================================*/
deallocate()1587 void QCameraGrallocMemory::deallocate()
1588 {
1589 CDBG("%s: E ", __FUNCTION__);
1590
1591 for (int cnt = 0; cnt < mBufferCount; cnt++) {
1592 mCameraMemory[cnt]->release(mCameraMemory[cnt]);
1593 struct ion_handle_data ion_handle;
1594 memset(&ion_handle, 0, sizeof(ion_handle));
1595 ion_handle.handle = mMemInfo[cnt].handle;
1596 if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1597 ALOGE("ion free failed");
1598 }
1599 close(mMemInfo[cnt].main_ion_fd);
1600 if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
1601 if (mWindow) {
1602 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
1603 CDBG_HIGH("cancel_buffer: hdl =%p", (*mBufferHandle[cnt]));
1604 } else {
1605 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p",
1606 (*mBufferHandle[cnt]));
1607 }
1608 }
1609 mLocalFlag[cnt] = BUFFER_NOT_OWNED;
1610 CDBG_HIGH("put buffer %d successfully", cnt);
1611 }
1612 mBufferCount = 0;
1613 CDBG(" %s : X ",__FUNCTION__);
1614 }
1615
1616 /*===========================================================================
1617 * FUNCTION : cacheOps
1618 *
1619 * DESCRIPTION: ion related memory cache operations
1620 *
1621 * PARAMETERS :
1622 * @index : index of the buffer
1623 * @cmd : cache ops command
1624 *
1625 * RETURN : int32_t type of status
1626 * NO_ERROR -- success
1627 * none-zero failure code
1628 *==========================================================================*/
cacheOps(int index,unsigned int cmd)1629 int QCameraGrallocMemory::cacheOps(int index, unsigned int cmd)
1630 {
1631 if (index >= mBufferCount)
1632 return BAD_INDEX;
1633 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
1634 }
1635
1636 /*===========================================================================
1637 * FUNCTION : getRegFlags
1638 *
1639 * DESCRIPTION: query initial reg flags
1640 *
1641 * PARAMETERS :
1642 * @regFlags: initial reg flags of the allocated buffers
1643 *
1644 * RETURN : int32_t type of status
1645 * NO_ERROR -- success
1646 * none-zero failure code
1647 *==========================================================================*/
getRegFlags(uint8_t * regFlags) const1648 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
1649 {
1650 int i = 0;
1651 for (i = 0; i < mMinUndequeuedBuffers; i ++)
1652 regFlags[i] = 0;
1653 for (; i < mBufferCount; i ++)
1654 regFlags[i] = 1;
1655 return NO_ERROR;
1656 }
1657
1658 /*===========================================================================
1659 * FUNCTION : getMemory
1660 *
1661 * DESCRIPTION: get camera memory
1662 *
1663 * PARAMETERS :
1664 * @index : buffer index
1665 * @metadata: flag if it's metadata
1666 *
1667 * RETURN : camera memory ptr
1668 * NULL if not supported or failed
1669 *==========================================================================*/
getMemory(int index,bool metadata) const1670 camera_memory_t *QCameraGrallocMemory::getMemory(int index, bool metadata) const
1671 {
1672 if (index >= mBufferCount || metadata)
1673 return NULL;
1674 return mCameraMemory[index];
1675 }
1676
1677 /*===========================================================================
1678 * FUNCTION : getMatchBufIndex
1679 *
1680 * DESCRIPTION: query buffer index by opaque ptr
1681 *
1682 * PARAMETERS :
1683 * @opaque : opaque ptr
1684 * @metadata: flag if it's metadata
1685 *
1686 * RETURN : buffer index if match found,
1687 * -1 if failed
1688 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1689 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
1690 bool metadata) const
1691 {
1692 int index = -1;
1693 if (metadata) {
1694 return -1;
1695 }
1696 for (int i = 0; i < mBufferCount; i++) {
1697 if (mCameraMemory[i]->data == opaque) {
1698 index = i;
1699 break;
1700 }
1701 }
1702 return index;
1703 }
1704
1705 /*===========================================================================
1706 * FUNCTION : getPtr
1707 *
1708 * DESCRIPTION: return buffer pointer
1709 *
1710 * PARAMETERS :
1711 * @index : index of the buffer
1712 *
1713 * RETURN : buffer ptr
1714 *==========================================================================*/
getPtr(int index) const1715 void *QCameraGrallocMemory::getPtr(int index) const
1716 {
1717 if (index >= mBufferCount) {
1718 ALOGE("index out of bound");
1719 return (void *)BAD_INDEX;
1720 }
1721 return mCameraMemory[index]->data;
1722 }
1723
1724 }; //namespace qcamera
1725