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 <media/hardware/HardwareAPI.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,void * cbCookie,bool cached,QCameraMemoryPool * pool,cam_stream_type_t streamType,cam_stream_buf_type bufType)977 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory memory,
978 void* cbCookie,
979 bool cached,
980 QCameraMemoryPool *pool,
981 cam_stream_type_t streamType, cam_stream_buf_type bufType)
982 :QCameraMemory(cached, pool, streamType),
983 mGetMemory(memory),
984 mCallbackCookie(cbCookie)
985 {
986 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
987 mCameraMemory[i] = NULL;
988 }
989
990 /*===========================================================================
991 * FUNCTION : ~QCameraStreamMemory
992 *
993 * DESCRIPTION: deconstructor of QCameraStreamMemory
994 *
995 * PARAMETERS : none
996 *
997 * RETURN : none
998 *==========================================================================*/
~QCameraStreamMemory()999 QCameraStreamMemory::~QCameraStreamMemory()
1000 {
1001 }
1002
1003 /*===========================================================================
1004 * FUNCTION : allocate
1005 *
1006 * DESCRIPTION: allocate requested number of buffers of certain size
1007 *
1008 * PARAMETERS :
1009 * @count : number of buffers to be allocated
1010 * @size : lenght of the buffer to be allocated
1011 *
1012 * RETURN : int32_t type of status
1013 * NO_ERROR -- success
1014 * none-zero failure code
1015 *==========================================================================*/
allocate(uint8_t count,size_t size,uint32_t isSecure)1016 int QCameraStreamMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
1017 {
1018 traceLogAllocStart(size, count, "StreamMemsize");
1019 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
1020 int rc = alloc(count, size, heap_id_mask, isSecure);
1021 if (rc < 0)
1022 return rc;
1023
1024 for (int i = 0; i < count; i ++) {
1025 if (isSecure == SECURE) {
1026 mCameraMemory[i] = 0;
1027 } else {
1028 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, mCallbackCookie);
1029 }
1030 }
1031 mBufferCount = count;
1032 traceLogAllocEnd((size * count));
1033 return NO_ERROR;
1034 }
1035
1036 /*===========================================================================
1037 * FUNCTION : allocateMore
1038 *
1039 * DESCRIPTION: allocate more requested number of buffers of certain size
1040 *
1041 * PARAMETERS :
1042 * @count : number of buffers to be allocated
1043 * @size : lenght of the buffer to be allocated
1044 *
1045 * RETURN : int32_t type of status
1046 * NO_ERROR -- success
1047 * none-zero failure code
1048 *==========================================================================*/
allocateMore(uint8_t count,size_t size)1049 int QCameraStreamMemory::allocateMore(uint8_t count, size_t size)
1050 {
1051 traceLogAllocStart(size, count, "StreamMemsize");
1052 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
1053 int rc = alloc(count, size, heap_id_mask, NON_SECURE);
1054 if (rc < 0)
1055 return rc;
1056
1057 for (int i = mBufferCount; i < mBufferCount + count; i++) {
1058 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, mCallbackCookie);
1059 }
1060 mBufferCount = (uint8_t)(mBufferCount + count);
1061 traceLogAllocEnd((size * count));
1062 return NO_ERROR;
1063 }
1064
1065 /*===========================================================================
1066 * FUNCTION : deallocate
1067 *
1068 * DESCRIPTION: deallocate buffers
1069 *
1070 * PARAMETERS : none
1071 *
1072 * RETURN : none
1073 *==========================================================================*/
deallocate()1074 void QCameraStreamMemory::deallocate()
1075 {
1076 for (int i = 0; i < mBufferCount; i ++) {
1077 if (mCameraMemory[i])
1078 mCameraMemory[i]->release(mCameraMemory[i]);
1079 mCameraMemory[i] = NULL;
1080 }
1081 dealloc();
1082 mBufferCount = 0;
1083 }
1084
1085 /*===========================================================================
1086 * FUNCTION : cacheOps
1087 *
1088 * DESCRIPTION: ion related memory cache operations
1089 *
1090 * PARAMETERS :
1091 * @index : index of the buffer
1092 * @cmd : cache ops command
1093 *
1094 * RETURN : int32_t type of status
1095 * NO_ERROR -- success
1096 * none-zero failure code
1097 *==========================================================================*/
cacheOps(uint32_t index,unsigned int cmd)1098 int QCameraStreamMemory::cacheOps(uint32_t index, unsigned int cmd)
1099 {
1100 if (index >= mBufferCount)
1101 return BAD_INDEX;
1102 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
1103 }
1104
1105 /*===========================================================================
1106 * FUNCTION : getRegFlags
1107 *
1108 * DESCRIPTION: query initial reg flags
1109 *
1110 * PARAMETERS :
1111 * @regFlags: initial reg flags of the allocated buffers
1112 *
1113 * RETURN : int32_t type of status
1114 * NO_ERROR -- success
1115 * none-zero failure code
1116 *==========================================================================*/
getRegFlags(uint8_t * regFlags) const1117 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
1118 {
1119 for (int i = 0; i < mBufferCount; i ++)
1120 regFlags[i] = 1;
1121 return NO_ERROR;
1122 }
1123
1124 /*===========================================================================
1125 * FUNCTION : getMemory
1126 *
1127 * DESCRIPTION: get camera memory
1128 *
1129 * PARAMETERS :
1130 * @index : buffer index
1131 * @metadata: flag if it's metadata
1132 *
1133 * RETURN : camera memory ptr
1134 * NULL if not supported or failed
1135 *==========================================================================*/
getMemory(uint32_t index,bool metadata) const1136 camera_memory_t *QCameraStreamMemory::getMemory(uint32_t index,
1137 bool metadata) const
1138 {
1139 if (index >= mBufferCount || metadata)
1140 return NULL;
1141 return mCameraMemory[index];
1142 }
1143
1144 /*===========================================================================
1145 * FUNCTION : getMatchBufIndex
1146 *
1147 * DESCRIPTION: query buffer index by opaque ptr
1148 *
1149 * PARAMETERS :
1150 * @opaque : opaque ptr
1151 * @metadata: flag if it's metadata
1152 *
1153 * RETURN : buffer index if match found,
1154 * -1 if failed
1155 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1156 int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
1157 bool metadata) const
1158 {
1159 int index = -1;
1160 if (metadata) {
1161 return -1;
1162 }
1163 for (int i = 0; i < mBufferCount; i++) {
1164 if (mCameraMemory[i]->data == opaque) {
1165 index = i;
1166 break;
1167 }
1168 }
1169 return index;
1170 }
1171
1172 /*===========================================================================
1173 * FUNCTION : getPtr
1174 *
1175 * DESCRIPTION: return buffer pointer
1176 *
1177 * PARAMETERS :
1178 * @index : index of the buffer
1179 *
1180 * RETURN : buffer ptr
1181 *==========================================================================*/
getPtr(uint32_t index) const1182 void *QCameraStreamMemory::getPtr(uint32_t index) const
1183 {
1184 if (index >= mBufferCount) {
1185 ALOGE("index out of bound");
1186 return (void *)BAD_INDEX;
1187 }
1188 if (mCameraMemory[index] == 0) {
1189 return NULL;
1190 }
1191 return mCameraMemory[index]->data;
1192 }
1193
1194 /*===========================================================================
1195 * FUNCTION : QCameraVideoMemory
1196 *
1197 * DESCRIPTION: constructor of QCameraVideoMemory
1198 * VideoStream buffers also include metadata buffers
1199 *
1200 * PARAMETERS :
1201 * @memory : camera memory request ops table
1202 * @cached : flag indicates if using cached ION memory
1203 *
1204 * RETURN : none
1205 *==========================================================================*/
QCameraVideoMemory(camera_request_memory memory,void * cbCookie,bool cached,cam_stream_buf_type bufType)1206 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory,
1207 void* cbCookie,
1208 bool cached, cam_stream_buf_type bufType)
1209 : QCameraStreamMemory(memory, cbCookie, cached)
1210 {
1211 memset(mMetadata, 0, sizeof(mMetadata));
1212 mMetaBufCount = 0;
1213 mBufType = bufType;
1214 }
1215
1216 /*===========================================================================
1217 * FUNCTION : ~QCameraVideoMemory
1218 *
1219 * DESCRIPTION: deconstructor of QCameraVideoMemory
1220 *
1221 * PARAMETERS : none
1222 *
1223 * RETURN : none
1224 *==========================================================================*/
~QCameraVideoMemory()1225 QCameraVideoMemory::~QCameraVideoMemory()
1226 {
1227 }
1228
1229 /*===========================================================================
1230 * FUNCTION : allocate
1231 *
1232 * DESCRIPTION: allocate requested number of buffers of certain size
1233 *
1234 * PARAMETERS :
1235 * @count : number of buffers to be allocated
1236 * @size : lenght of the buffer to be allocated
1237 *
1238 * RETURN : int32_t type of status
1239 * NO_ERROR -- success
1240 * none-zero failure code
1241 *==========================================================================*/
allocate(uint8_t count,size_t size,uint32_t isSecure)1242 int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure)
1243 {
1244 traceLogAllocStart(size, count, "VideoMemsize");
1245 int rc = QCameraStreamMemory::allocate(count, size, isSecure);
1246 if (rc < 0)
1247 return rc;
1248
1249 if (mBufType != CAM_STREAM_BUF_TYPE_USERPTR) {
1250 rc = allocateMeta(count);
1251 if (rc != NO_ERROR) {
1252 return rc;
1253 }
1254
1255 for (int i = 0; i < count; i ++) {
1256 VideoNativeHandleMetadata *packet =
1257 static_cast<VideoNativeHandleMetadata *> (mMetadata[i]->data);
1258 //1 fd, 1 offset, 1 size, 1 color transform
1259 mNativeHandles[i] = native_handle_create(1, 3);
1260 packet->pHandle = mNativeHandles[i];
1261 packet->eType = kMetadataBufferTypeNativeHandleSource;
1262 native_handle_t * nh = packet->pHandle;
1263 if (!nh) {
1264 ALOGE("%s: Error in getting video native handle", __func__);
1265 return NO_MEMORY;
1266 }
1267 nh->data[0] = mMemInfo[i].fd;
1268 nh->data[1] = 0;
1269 nh->data[2] = (int)mMemInfo[i].size;
1270 nh->data[3] = private_handle_t::PRIV_FLAGS_ITU_R_709;
1271 }
1272 }
1273 mBufferCount = count;
1274 traceLogAllocEnd((size * count));
1275 return NO_ERROR;
1276 }
1277
1278 /*===========================================================================
1279 * FUNCTION : allocateMore
1280 *
1281 * DESCRIPTION: allocate more requested number of buffers of certain size
1282 *
1283 * PARAMETERS :
1284 * @count : number of buffers to be allocated
1285 * @size : lenght of the buffer to be allocated
1286 *
1287 * RETURN : int32_t type of status
1288 * NO_ERROR -- success
1289 * none-zero failure code
1290 *==========================================================================*/
allocateMore(uint8_t count,size_t size)1291 int QCameraVideoMemory::allocateMore(uint8_t count, size_t size)
1292 {
1293 traceLogAllocStart(size, count, "VideoMemsize");
1294 int rc = QCameraStreamMemory::allocateMore(count, size);
1295 if (rc < 0)
1296 return rc;
1297
1298 if (mBufType != CAM_STREAM_BUF_TYPE_USERPTR) {
1299 for (int i = mBufferCount; i < count + mBufferCount; i ++) {
1300 mMetadata[i] = mGetMemory(-1,
1301 sizeof(struct VideoNativeHandleMetadata), 1, mCallbackCookie);
1302 if (!mMetadata[i]) {
1303 ALOGE("allocation of video metadata failed.");
1304 for (int j = mBufferCount; j <= i-1; j ++) {
1305 mMetadata[j]->release(mMetadata[j]);
1306 mCameraMemory[j]->release(mCameraMemory[j]);
1307 mCameraMemory[j] = NULL;
1308 deallocOneBuffer(mMemInfo[j]);;
1309 }
1310 return NO_MEMORY;
1311 }
1312 VideoNativeHandleMetadata *packet =
1313 static_cast<VideoNativeHandleMetadata *>(mMetadata[i]->data);
1314 mNativeHandles[i] = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
1315 packet->pHandle = mNativeHandles[i];
1316 packet->eType = kMetadataBufferTypeNativeHandleSource;
1317 native_handle_t * nh = packet->pHandle;
1318 if (!nh) {
1319 ALOGE("%s: Error in getting video native handle", __func__);
1320 return NO_MEMORY;
1321 }
1322 nh->data[0] = mMemInfo[i].fd;
1323 nh->data[1] = 0;
1324 nh->data[2] = (int)mMemInfo[i].size;
1325 }
1326 }
1327 mBufferCount = (uint8_t)(mBufferCount + count);
1328 mMetaBufCount = mBufferCount;
1329 traceLogAllocEnd((size * count));
1330 return NO_ERROR;
1331 }
1332
1333 /*===========================================================================
1334 * FUNCTION : allocateMeta
1335 *
1336 * DESCRIPTION: allocate video encoder metadata structure
1337 *
1338 * PARAMETERS :
1339 * @fd_cnt : Total FD count
1340 *
1341 * RETURN : int32_t type of status
1342 * NO_ERROR -- success
1343 * none-zero failure code
1344 *==========================================================================*/
allocateMeta(uint8_t buf_cnt)1345 int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt)
1346 {
1347 int rc = NO_ERROR;
1348
1349 for (int i = 0; i < buf_cnt; i++) {
1350 mMetadata[i] = mGetMemory(-1,
1351 sizeof(struct VideoNativeHandleMetadata), 1, mCallbackCookie);
1352 if (!mMetadata[i]) {
1353 ALOGE("allocation of video metadata failed.");
1354 for (int j = (i - 1); j >= 0; j--) {
1355 mMetadata[j]->release(mMetadata[j]);
1356 }
1357 return NO_MEMORY;
1358 }
1359 }
1360 mMetaBufCount = buf_cnt;
1361 return rc;
1362 }
1363
1364 /*===========================================================================
1365 * FUNCTION : deallocateMeta
1366 *
1367 * DESCRIPTION: deallocate video metadata buffers
1368 *
1369 * PARAMETERS : none
1370 *
1371 * RETURN : none
1372 *==========================================================================*/
deallocateMeta()1373 void QCameraVideoMemory::deallocateMeta()
1374 {
1375 for (int i = 0; i < mMetaBufCount; i ++) {
1376 mMetadata[i]->release(mMetadata[i]);
1377 mMetadata[i] = NULL;
1378 }
1379 mMetaBufCount = 0;
1380 }
1381
1382
1383 /*===========================================================================
1384 * FUNCTION : deallocate
1385 *
1386 * DESCRIPTION: deallocate buffers
1387 *
1388 * PARAMETERS : none
1389 *
1390 * RETURN : none
1391 *==========================================================================*/
deallocate()1392 void QCameraVideoMemory::deallocate()
1393 {
1394 if (mBufType != CAM_STREAM_BUF_TYPE_USERPTR) {
1395 for (int i = 0; i < mBufferCount; i ++) {
1396 native_handle_t * nh = mNativeHandles[i];
1397 if (NULL != nh) {
1398 if (native_handle_delete(nh)) {
1399 ALOGE("Unable to delete native handle");
1400 }
1401 } else {
1402 ALOGE("native handle not available");
1403 }
1404 }
1405 }
1406
1407 deallocateMeta();
1408
1409 QCameraStreamMemory::deallocate();
1410 mBufferCount = 0;
1411 mMetaBufCount = 0;
1412 }
1413
1414 /*===========================================================================
1415 * FUNCTION : getMemory
1416 *
1417 * DESCRIPTION: get camera memory
1418 *
1419 * PARAMETERS :
1420 * @index : buffer index
1421 * @metadata: flag if it's metadata
1422 *
1423 * RETURN : camera memory ptr
1424 * NULL if not supported or failed
1425 *==========================================================================*/
getMemory(uint32_t index,bool metadata) const1426 camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index,
1427 bool metadata) const
1428 {
1429 if (index >= mMetaBufCount || (!metadata && index >= mBufferCount))
1430 return NULL;
1431
1432 if (metadata) {
1433 VideoNativeHandleMetadata *packet =
1434 static_cast<VideoNativeHandleMetadata *> (mMetadata[index]->data);
1435 packet->pHandle = mNativeHandles[index];
1436 return mMetadata[index];
1437 } else {
1438 return mCameraMemory[index];
1439 }
1440 }
1441
1442 /*===========================================================================
1443 * FUNCTION : getMatchBufIndex
1444 *
1445 * DESCRIPTION: query buffer index by opaque ptr
1446 *
1447 * PARAMETERS :
1448 * @opaque : opaque ptr
1449 * @metadata: flag if it's metadata
1450 *
1451 * RETURN : buffer index if match found,
1452 * -1 if failed
1453 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1454 int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
1455 bool metadata) const
1456 {
1457 int index = -1;
1458
1459 if (metadata) {
1460 for (int i = 0; i < mMetaBufCount; i++) {
1461 if (mMetadata[i]->data == opaque) {
1462 index = i;
1463 break;
1464 }
1465 }
1466 } else {
1467 for (int i = 0; i < mBufferCount; i++) {
1468 if (mCameraMemory[i]->data == opaque) {
1469 index = i;
1470 break;
1471 }
1472 }
1473 }
1474 return index;
1475 }
1476
1477 /*===========================================================================
1478 * FUNCTION : QCameraGrallocMemory
1479 *
1480 * DESCRIPTION: constructor of QCameraGrallocMemory
1481 * preview stream buffers are allocated from gralloc native_windoe
1482 *
1483 * PARAMETERS :
1484 * @memory : camera memory request ops table
1485 *
1486 * RETURN : none
1487 *==========================================================================*/
QCameraGrallocMemory(camera_request_memory memory,void * cbCookie)1488 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory memory, void* cbCookie)
1489 : QCameraMemory(true), mColorSpace(ITU_R_601_FR)
1490 {
1491 mMinUndequeuedBuffers = 0;
1492 mWindow = NULL;
1493 mWidth = mHeight = mStride = mScanline = 0;
1494 mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1495 mGetMemory = memory;
1496 mCallbackCookie = cbCookie;
1497 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
1498 mBufferHandle[i] = NULL;
1499 mLocalFlag[i] = BUFFER_NOT_OWNED;
1500 mPrivateHandle[i] = NULL;
1501 }
1502 }
1503
1504 /*===========================================================================
1505 * FUNCTION : ~QCameraGrallocMemory
1506 *
1507 * DESCRIPTION: deconstructor of QCameraGrallocMemory
1508 *
1509 * PARAMETERS : none
1510 *
1511 * RETURN : none
1512 *==========================================================================*/
~QCameraGrallocMemory()1513 QCameraGrallocMemory::~QCameraGrallocMemory()
1514 {
1515 }
1516
1517 /*===========================================================================
1518 * FUNCTION : setWindowInfo
1519 *
1520 * DESCRIPTION: set native window gralloc ops table
1521 *
1522 * PARAMETERS :
1523 * @window : gralloc ops table ptr
1524 * @width : width of preview frame
1525 * @height : height of preview frame
1526 * @stride : stride of preview frame
1527 * @scanline: scanline of preview frame
1528 * @foramt : format of preview image
1529 *
1530 * RETURN : none
1531 *==========================================================================*/
setWindowInfo(preview_stream_ops_t * window,int width,int height,int stride,int scanline,int format)1532 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
1533 int width, int height, int stride, int scanline, int format)
1534 {
1535 mWindow = window;
1536 mWidth = width;
1537 mHeight = height;
1538 mStride = stride;
1539 mScanline = scanline;
1540 mFormat = format;
1541 }
1542
1543 /*===========================================================================
1544 * FUNCTION : displayBuffer
1545 *
1546 * DESCRIPTION: send received frame to display
1547 *
1548 * PARAMETERS :
1549 * @index : index of preview frame
1550 *
1551 * RETURN : int32_t type of status
1552 * NO_ERROR -- success
1553 * none-zero failure code
1554 *==========================================================================*/
displayBuffer(uint32_t index)1555 int QCameraGrallocMemory::displayBuffer(uint32_t index)
1556 {
1557 int err = NO_ERROR;
1558 int dequeuedIdx = BAD_INDEX;
1559
1560 if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
1561 ALOGE("%s: buffer to be enqueued is not owned", __func__);
1562 return INVALID_OPERATION;
1563 }
1564
1565 err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
1566 if(err != 0) {
1567 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
1568 } else {
1569 CDBG("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]);
1570 mLocalFlag[index] = BUFFER_NOT_OWNED;
1571 }
1572
1573 buffer_handle_t *buffer_handle = NULL;
1574 int stride = 0;
1575 err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
1576 if (err == NO_ERROR && buffer_handle != NULL) {
1577 int i;
1578 CDBG("%s: dequed buf hdl =%p", __func__, *buffer_handle);
1579 for(i = 0; i < mBufferCount; i++) {
1580 if(mBufferHandle[i] == buffer_handle) {
1581 CDBG("%s: Found buffer in idx:%d", __func__, i);
1582 mLocalFlag[i] = BUFFER_OWNED;
1583 dequeuedIdx = i;
1584 break;
1585 }
1586 }
1587 } else {
1588 CDBG_HIGH("%s: dequeue_buffer, no free buffer from display now", __func__);
1589 }
1590 return dequeuedIdx;
1591 }
1592
1593 /*===========================================================================
1594 * FUNCTION : allocate
1595 *
1596 * DESCRIPTION: allocate requested number of buffers of certain size
1597 *
1598 * PARAMETERS :
1599 * @count : number of buffers to be allocated
1600 * @size : lenght of the buffer to be allocated
1601 *
1602 * RETURN : int32_t type of status
1603 * NO_ERROR -- success
1604 * none-zero failure code
1605 *==========================================================================*/
allocate(uint8_t count,size_t,uint32_t)1606 int QCameraGrallocMemory::allocate(uint8_t count, size_t /*size*/,
1607 uint32_t /*isSecure*/)
1608 {
1609 traceLogAllocStart(0,count, "Grallocbufcnt");
1610 int err = 0;
1611 status_t ret = NO_ERROR;
1612 int gralloc_usage = 0;
1613 struct ion_fd_data ion_info_fd;
1614 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
1615
1616 CDBG(" %s : E ", __func__);
1617
1618 if (!mWindow) {
1619 ALOGE("Invalid native window");
1620 return INVALID_OPERATION;
1621 }
1622
1623 // Increment buffer count by min undequeued buffer.
1624 err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
1625 if (err != 0) {
1626 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)",
1627 strerror(-err), -err);
1628 ret = UNKNOWN_ERROR;
1629 goto end;
1630 }
1631
1632 err = mWindow->set_buffer_count(mWindow, count);
1633 if (err != 0) {
1634 ALOGE("set_buffer_count failed: %s (%d)",
1635 strerror(-err), -err);
1636 ret = UNKNOWN_ERROR;
1637 goto end;
1638 }
1639
1640 err = mWindow->set_buffers_geometry(mWindow, mStride, mScanline, mFormat);
1641 if (err != 0) {
1642 ALOGE("%s: set_buffers_geometry failed: %s (%d)",
1643 __func__, strerror(-err), -err);
1644 ret = UNKNOWN_ERROR;
1645 goto end;
1646 }
1647
1648 err = mWindow->set_crop(mWindow, 0, 0, mWidth, mHeight);
1649 if (err != 0) {
1650 ALOGE("%s: set_crop failed: %s (%d)",
1651 __func__, strerror(-err), -err);
1652 ret = UNKNOWN_ERROR;
1653 goto end;
1654 }
1655
1656 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
1657 err = mWindow->set_usage(mWindow, gralloc_usage);
1658 if(err != 0) {
1659 /* set_usage error out */
1660 ALOGE("%s: set_usage rc = %d", __func__, err);
1661 ret = UNKNOWN_ERROR;
1662 goto end;
1663 }
1664 CDBG_HIGH("%s: usage = %d, geometry: %p, %d, %d, %d, %d, %d",
1665 __func__, gralloc_usage, mWindow, mWidth, mHeight, mStride,
1666 mScanline, mFormat);
1667
1668 //Allocate cnt number of buffers from native window
1669 for (int cnt = 0; cnt < count; cnt++) {
1670 int stride;
1671 err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
1672 if(!err) {
1673 CDBG("dequeue buf hdl =%p", mBufferHandle[cnt]);
1674 mLocalFlag[cnt] = BUFFER_OWNED;
1675 } else {
1676 mLocalFlag[cnt] = BUFFER_NOT_OWNED;
1677 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
1678 }
1679
1680 CDBG("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]);
1681
1682 if(err != 0) {
1683 ALOGE("%s: dequeue_buffer failed: %s (%d)",
1684 __func__, strerror(-err), -err);
1685 ret = UNKNOWN_ERROR;
1686 for(int i = 0; i < cnt; i++) {
1687 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1688 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1689 CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1690 }
1691 mLocalFlag[i] = BUFFER_NOT_OWNED;
1692 mBufferHandle[i] = NULL;
1693 }
1694 reset();
1695 goto end;
1696 }
1697
1698 mPrivateHandle[cnt] =
1699 (struct private_handle_t *)(*mBufferHandle[cnt]);
1700 mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
1701 if (mMemInfo[cnt].main_ion_fd < 0) {
1702 ALOGE("%s: failed: could not open ion device", __func__);
1703 for(int i = 0; i < cnt; i++) {
1704 struct ion_handle_data ion_handle;
1705 memset(&ion_handle, 0, sizeof(ion_handle));
1706 ion_handle.handle = mMemInfo[i].handle;
1707 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1708 ALOGE("%s: ion free failed", __func__);
1709 }
1710 close(mMemInfo[i].main_ion_fd);
1711 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1712 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1713 CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1714 }
1715 mLocalFlag[i] = BUFFER_NOT_OWNED;
1716 mBufferHandle[i] = NULL;
1717 }
1718 reset();
1719 ret = UNKNOWN_ERROR;
1720 goto end;
1721 } else {
1722 ion_info_fd.fd = mPrivateHandle[cnt]->fd;
1723 if (ioctl(mMemInfo[cnt].main_ion_fd,
1724 ION_IOC_IMPORT, &ion_info_fd) < 0) {
1725 ALOGE("%s: ION import failed\n", __func__);
1726 for(int i = 0; i < cnt; i++) {
1727 struct ion_handle_data ion_handle;
1728 memset(&ion_handle, 0, sizeof(ion_handle));
1729 ion_handle.handle = mMemInfo[i].handle;
1730 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1731 ALOGE("ion free failed");
1732 }
1733 close(mMemInfo[i].main_ion_fd);
1734
1735 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1736 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1737 CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1738 }
1739 mLocalFlag[i] = BUFFER_NOT_OWNED;
1740 mBufferHandle[i] = NULL;
1741 }
1742 close(mMemInfo[cnt].main_ion_fd);
1743 reset();
1744 ret = UNKNOWN_ERROR;
1745 goto end;
1746 }
1747 }
1748 setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace);
1749 mCameraMemory[cnt] =
1750 mGetMemory(mPrivateHandle[cnt]->fd,
1751 (size_t)mPrivateHandle[cnt]->size,
1752 1,
1753 mCallbackCookie);
1754 CDBG_HIGH("%s: idx = %d, fd = %d, size = %d, offset = %d",
1755 __func__, cnt, mPrivateHandle[cnt]->fd,
1756 mPrivateHandle[cnt]->size,
1757 mPrivateHandle[cnt]->offset);
1758 mMemInfo[cnt].fd = mPrivateHandle[cnt]->fd;
1759 mMemInfo[cnt].size = (size_t)mPrivateHandle[cnt]->size;
1760 mMemInfo[cnt].handle = ion_info_fd.handle;
1761 }
1762 mBufferCount = count;
1763
1764 //Cancel min_undequeued_buffer buffers back to the window
1765 for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
1766 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1767 mLocalFlag[i] = BUFFER_NOT_OWNED;
1768 }
1769
1770 end:
1771 CDBG(" %s : X ",__func__);
1772 traceLogAllocEnd(count);
1773 return ret;
1774 }
1775
1776
1777 /*===========================================================================
1778 * FUNCTION : allocateMore
1779 *
1780 * DESCRIPTION: allocate more requested number of buffers of certain size
1781 *
1782 * PARAMETERS :
1783 * @count : number of buffers to be allocated
1784 * @size : lenght of the buffer to be allocated
1785 *
1786 * RETURN : int32_t type of status
1787 * NO_ERROR -- success
1788 * none-zero failure code
1789 *==========================================================================*/
allocateMore(uint8_t,size_t)1790 int QCameraGrallocMemory::allocateMore(uint8_t /*count*/, size_t /*size*/)
1791 {
1792 ALOGE("%s: Not implenmented yet", __func__);
1793 return UNKNOWN_ERROR;
1794 }
1795
1796 /*===========================================================================
1797 * FUNCTION : deallocate
1798 *
1799 * DESCRIPTION: deallocate buffers
1800 *
1801 * PARAMETERS : none
1802 *
1803 * RETURN : none
1804 *==========================================================================*/
deallocate()1805 void QCameraGrallocMemory::deallocate()
1806 {
1807 CDBG("%s: E ", __FUNCTION__);
1808
1809 for (int cnt = 0; cnt < mBufferCount; cnt++) {
1810 mCameraMemory[cnt]->release(mCameraMemory[cnt]);
1811 struct ion_handle_data ion_handle;
1812 memset(&ion_handle, 0, sizeof(ion_handle));
1813 ion_handle.handle = mMemInfo[cnt].handle;
1814 if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1815 ALOGE("ion free failed");
1816 }
1817 close(mMemInfo[cnt].main_ion_fd);
1818 if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
1819 if (mWindow) {
1820 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
1821 CDBG_HIGH("cancel_buffer: hdl =%p", (*mBufferHandle[cnt]));
1822 } else {
1823 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p",
1824 (*mBufferHandle[cnt]));
1825 }
1826 }
1827 mLocalFlag[cnt] = BUFFER_NOT_OWNED;
1828 CDBG_HIGH("put buffer %d successfully", cnt);
1829 }
1830 mBufferCount = 0;
1831 CDBG(" %s : X ",__FUNCTION__);
1832 }
1833
1834 /*===========================================================================
1835 * FUNCTION : cacheOps
1836 *
1837 * DESCRIPTION: ion related memory cache operations
1838 *
1839 * PARAMETERS :
1840 * @index : index of the buffer
1841 * @cmd : cache ops command
1842 *
1843 * RETURN : int32_t type of status
1844 * NO_ERROR -- success
1845 * none-zero failure code
1846 *==========================================================================*/
cacheOps(uint32_t index,unsigned int cmd)1847 int QCameraGrallocMemory::cacheOps(uint32_t index, unsigned int cmd)
1848 {
1849 if (index >= mBufferCount)
1850 return BAD_INDEX;
1851 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
1852 }
1853
1854 /*===========================================================================
1855 * FUNCTION : getRegFlags
1856 *
1857 * DESCRIPTION: query initial reg flags
1858 *
1859 * PARAMETERS :
1860 * @regFlags: initial reg flags of the allocated buffers
1861 *
1862 * RETURN : int32_t type of status
1863 * NO_ERROR -- success
1864 * none-zero failure code
1865 *==========================================================================*/
getRegFlags(uint8_t * regFlags) const1866 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
1867 {
1868 int i = 0;
1869 for (i = 0; i < mMinUndequeuedBuffers; i ++)
1870 regFlags[i] = 0;
1871 for (; i < mBufferCount; i ++)
1872 regFlags[i] = 1;
1873 return NO_ERROR;
1874 }
1875
1876 /*===========================================================================
1877 * FUNCTION : getMemory
1878 *
1879 * DESCRIPTION: get camera memory
1880 *
1881 * PARAMETERS :
1882 * @index : buffer index
1883 * @metadata: flag if it's metadata
1884 *
1885 * RETURN : camera memory ptr
1886 * NULL if not supported or failed
1887 *==========================================================================*/
getMemory(uint32_t index,bool metadata) const1888 camera_memory_t *QCameraGrallocMemory::getMemory(uint32_t index,
1889 bool metadata) const
1890 {
1891 if (index >= mBufferCount || metadata)
1892 return NULL;
1893 return mCameraMemory[index];
1894 }
1895
1896 /*===========================================================================
1897 * FUNCTION : getMatchBufIndex
1898 *
1899 * DESCRIPTION: query buffer index by opaque ptr
1900 *
1901 * PARAMETERS :
1902 * @opaque : opaque ptr
1903 * @metadata: flag if it's metadata
1904 *
1905 * RETURN : buffer index if match found,
1906 * -1 if failed
1907 *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1908 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
1909 bool metadata) const
1910 {
1911 int index = -1;
1912 if (metadata) {
1913 return -1;
1914 }
1915 for (int i = 0; i < mBufferCount; i++) {
1916 if (mCameraMemory[i]->data == opaque) {
1917 index = i;
1918 break;
1919 }
1920 }
1921 return index;
1922 }
1923
1924 /*===========================================================================
1925 * FUNCTION : getPtr
1926 *
1927 * DESCRIPTION: return buffer pointer
1928 *
1929 * PARAMETERS :
1930 * @index : index of the buffer
1931 *
1932 * RETURN : buffer ptr
1933 *==========================================================================*/
getPtr(uint32_t index) const1934 void *QCameraGrallocMemory::getPtr(uint32_t index) const
1935 {
1936 if (index >= mBufferCount) {
1937 ALOGE("index out of bound");
1938 return (void *)BAD_INDEX;
1939 }
1940 return mCameraMemory[index]->data;
1941 }
1942
1943 }; //namespace qcamera
1944