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