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