1 /* Copyright (c) 2012-2013, 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 :m_bCached(cached) 63 { 64 mBufferCount = 0; 65 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 66 mMemInfo[i].fd = 0; 67 mMemInfo[i].main_ion_fd = 0; 68 mMemInfo[i].handle = NULL; 69 mMemInfo[i].size = 0; 70 } 71 } 72 73 /*=========================================================================== 74 * FUNCTION : ~QCameraMemory 75 * 76 * DESCRIPTION: deconstructor of QCameraMemory 77 * 78 * PARAMETERS : none 79 * 80 * RETURN : None 81 *==========================================================================*/ 82 QCameraMemory::~QCameraMemory() 83 { 84 } 85 86 /*=========================================================================== 87 * FUNCTION : cacheOpsInternal 88 * 89 * DESCRIPTION: ion related memory cache operations 90 * 91 * PARAMETERS : 92 * @index : index of the buffer 93 * @cmd : cache ops command 94 * @vaddr : ptr to the virtual address 95 * 96 * RETURN : int32_t type of status 97 * NO_ERROR -- success 98 * none-zero failure code 99 *==========================================================================*/ 100 int QCameraMemory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr) 101 { 102 if (!m_bCached) { 103 // Memory is not cached, no need for cache ops 104 ALOGV("%s: No cache ops here for uncached memory", __func__); 105 return OK; 106 } 107 108 struct ion_flush_data cache_inv_data; 109 struct ion_custom_data custom_data; 110 int ret = OK; 111 112 if (index >= mBufferCount) { 113 ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount); 114 return BAD_INDEX; 115 } 116 117 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 118 memset(&custom_data, 0, sizeof(custom_data)); 119 cache_inv_data.vaddr = vaddr; 120 cache_inv_data.fd = mMemInfo[index].fd; 121 cache_inv_data.handle = mMemInfo[index].handle; 122 cache_inv_data.length = mMemInfo[index].size; 123 custom_data.cmd = cmd; 124 custom_data.arg = (unsigned long)&cache_inv_data; 125 126 ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d", 127 __func__, cache_inv_data.vaddr, cache_inv_data.fd, 128 cache_inv_data.handle, cache_inv_data.length, 129 mMemInfo[index].main_ion_fd); 130 ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data); 131 if (ret < 0) 132 ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno)); 133 134 return ret; 135 } 136 137 /*=========================================================================== 138 * FUNCTION : getFd 139 * 140 * DESCRIPTION: return file descriptor of the indexed buffer 141 * 142 * PARAMETERS : 143 * @index : index of the buffer 144 * 145 * RETURN : file descriptor 146 *==========================================================================*/ 147 int QCameraMemory::getFd(int index) const 148 { 149 if (index >= mBufferCount) 150 return BAD_INDEX; 151 152 return mMemInfo[index].fd; 153 } 154 155 /*=========================================================================== 156 * FUNCTION : getSize 157 * 158 * DESCRIPTION: return buffer size of the indexed buffer 159 * 160 * PARAMETERS : 161 * @index : index of the buffer 162 * 163 * RETURN : buffer size 164 *==========================================================================*/ 165 int QCameraMemory::getSize(int index) const 166 { 167 if (index >= mBufferCount) 168 return BAD_INDEX; 169 170 return (int)mMemInfo[index].size; 171 } 172 173 /*=========================================================================== 174 * FUNCTION : getCnt 175 * 176 * DESCRIPTION: query number of buffers allocated 177 * 178 * PARAMETERS : none 179 * 180 * RETURN : number of buffers allocated 181 *==========================================================================*/ 182 int QCameraMemory::getCnt() const 183 { 184 return mBufferCount; 185 } 186 187 /*=========================================================================== 188 * FUNCTION : getBufDef 189 * 190 * DESCRIPTION: query detailed buffer information 191 * 192 * PARAMETERS : 193 * @offset : [input] frame buffer offset 194 * @bufDef : [output] reference to struct to store buffer definition 195 * @index : [input] index of the buffer 196 * 197 * RETURN : none 198 *==========================================================================*/ 199 void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset, 200 mm_camera_buf_def_t &bufDef, int index) const 201 { 202 if (!mBufferCount) { 203 ALOGE("Memory not allocated"); 204 return; 205 } 206 bufDef.fd = mMemInfo[index].fd; 207 bufDef.frame_len = offset.frame_len; 208 bufDef.mem_info = (void *)this; 209 bufDef.num_planes = offset.num_planes; 210 bufDef.buffer = getPtr(index); 211 bufDef.buf_idx = index; 212 213 /* Plane 0 needs to be set separately. Set other planes in a loop */ 214 bufDef.planes[0].length = offset.mp[0].len; 215 bufDef.planes[0].m.userptr = mMemInfo[index].fd; 216 bufDef.planes[0].data_offset = offset.mp[0].offset; 217 bufDef.planes[0].reserved[0] = 0; 218 for (int i = 1; i < bufDef.num_planes; i++) { 219 bufDef.planes[i].length = offset.mp[i].len; 220 bufDef.planes[i].m.userptr = mMemInfo[i].fd; 221 bufDef.planes[i].data_offset = offset.mp[i].offset; 222 bufDef.planes[i].reserved[0] = 223 bufDef.planes[i-1].reserved[0] + 224 bufDef.planes[i-1].length; 225 } 226 } 227 228 /*=========================================================================== 229 * FUNCTION : alloc 230 * 231 * DESCRIPTION: allocate requested number of buffers of certain size 232 * 233 * PARAMETERS : 234 * @count : number of buffers to be allocated 235 * @size : lenght of the buffer to be allocated 236 * @heap_id : heap id to indicate where the buffers will be allocated from 237 * 238 * RETURN : int32_t type of status 239 * NO_ERROR -- success 240 * none-zero failure code 241 *==========================================================================*/ 242 int QCameraMemory::alloc(int count, int size, int heap_id) 243 { 244 int rc = OK; 245 if (count > MM_CAMERA_MAX_NUM_FRAMES) { 246 ALOGE("Buffer count %d out of bound. Max is %d", count, MM_CAMERA_MAX_NUM_FRAMES); 247 return BAD_INDEX; 248 } 249 if (mBufferCount) { 250 ALOGE("Allocating a already allocated heap memory"); 251 return INVALID_OPERATION; 252 } 253 254 for (int i = 0; i < count; i ++) { 255 rc = allocOneBuffer(mMemInfo[i], heap_id, size); 256 if (rc < 0) { 257 ALOGE("AllocateIonMemory failed"); 258 for (int j = i-1; j >= 0; j--) 259 deallocOneBuffer(mMemInfo[j]); 260 break; 261 } 262 } 263 return rc; 264 } 265 266 /*=========================================================================== 267 * FUNCTION : dealloc 268 * 269 * DESCRIPTION: deallocate buffers 270 * 271 * PARAMETERS : none 272 * 273 * RETURN : none 274 *==========================================================================*/ 275 void QCameraMemory::dealloc() 276 { 277 for (int i = 0; i < mBufferCount; i++) 278 deallocOneBuffer(mMemInfo[i]); 279 } 280 281 /*=========================================================================== 282 * FUNCTION : allocOneBuffer 283 * 284 * DESCRIPTION: impl of allocating one buffers of certain size 285 * 286 * PARAMETERS : 287 * @memInfo : [output] reference to struct to store additional memory allocation info 288 * @heap : [input] heap id to indicate where the buffers will be allocated from 289 * @size : [input] lenght of the buffer to be allocated 290 * 291 * RETURN : int32_t type of status 292 * NO_ERROR -- success 293 * none-zero failure code 294 *==========================================================================*/ 295 int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo, int heap_id, int size) 296 { 297 int rc = OK; 298 struct ion_handle_data handle_data; 299 struct ion_allocation_data alloc; 300 struct ion_fd_data ion_info_fd; 301 int main_ion_fd = 0; 302 303 main_ion_fd = open("/dev/ion", O_RDONLY); 304 if (main_ion_fd < 0) { 305 ALOGE("Ion dev open failed: %s\n", strerror(errno)); 306 goto ION_OPEN_FAILED; 307 } 308 309 memset(&alloc, 0, sizeof(alloc)); 310 alloc.len = size; 311 /* to make it page size aligned */ 312 alloc.len = (alloc.len + 4095) & (~4095); 313 alloc.align = 4096; 314 if (m_bCached) { 315 alloc.flags = ION_FLAG_CACHED; 316 } 317 alloc.heap_mask = heap_id; 318 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc); 319 if (rc < 0) { 320 ALOGE("ION allocation failed: %s\n", strerror(errno)); 321 goto ION_ALLOC_FAILED; 322 } 323 324 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 325 ion_info_fd.handle = alloc.handle; 326 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 327 if (rc < 0) { 328 ALOGE("ION map failed %s\n", strerror(errno)); 329 goto ION_MAP_FAILED; 330 } 331 332 memInfo.main_ion_fd = main_ion_fd; 333 memInfo.fd = ion_info_fd.fd; 334 memInfo.handle = ion_info_fd.handle; 335 memInfo.size = alloc.len; 336 return OK; 337 338 ION_MAP_FAILED: 339 memset(&handle_data, 0, sizeof(handle_data)); 340 handle_data.handle = ion_info_fd.handle; 341 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 342 ION_ALLOC_FAILED: 343 close(main_ion_fd); 344 ION_OPEN_FAILED: 345 return NO_MEMORY; 346 } 347 348 /*=========================================================================== 349 * FUNCTION : deallocOneBuffer 350 * 351 * DESCRIPTION: impl of deallocating one buffers 352 * 353 * PARAMETERS : 354 * @memInfo : reference to struct that stores additional memory allocation info 355 * 356 * RETURN : none 357 *==========================================================================*/ 358 void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo) 359 { 360 struct ion_handle_data handle_data; 361 362 if (memInfo.fd > 0) { 363 close(memInfo.fd); 364 memInfo.fd = 0; 365 } 366 367 if (memInfo.main_ion_fd > 0) { 368 memset(&handle_data, 0, sizeof(handle_data)); 369 handle_data.handle = memInfo.handle; 370 ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data); 371 close(memInfo.main_ion_fd); 372 memInfo.main_ion_fd = 0; 373 } 374 memInfo.handle = NULL; 375 memInfo.size = 0; 376 } 377 378 /*=========================================================================== 379 * FUNCTION : QCameraHeapMemory 380 * 381 * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL 382 * 383 * PARAMETERS : 384 * @cached : flag indicates if using cached memory 385 * 386 * RETURN : none 387 *==========================================================================*/ 388 QCameraHeapMemory::QCameraHeapMemory(bool cached) 389 : QCameraMemory(cached) 390 { 391 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) 392 mPtr[i] = NULL; 393 } 394 395 /*=========================================================================== 396 * FUNCTION : ~QCameraHeapMemory 397 * 398 * DESCRIPTION: deconstructor of QCameraHeapMemory 399 * 400 * PARAMETERS : none 401 * 402 * RETURN : none 403 *==========================================================================*/ 404 QCameraHeapMemory::~QCameraHeapMemory() 405 { 406 } 407 408 /*=========================================================================== 409 * FUNCTION : getPtr 410 * 411 * DESCRIPTION: return buffer pointer 412 * 413 * PARAMETERS : 414 * @index : index of the buffer 415 * 416 * RETURN : buffer ptr 417 *==========================================================================*/ 418 void *QCameraHeapMemory::getPtr(int index) const 419 { 420 if (index >= mBufferCount) { 421 ALOGE("index out of bound"); 422 return (void *)BAD_INDEX; 423 } 424 return mPtr[index]; 425 } 426 427 /*=========================================================================== 428 * FUNCTION : allocate 429 * 430 * DESCRIPTION: allocate requested number of buffers of certain size 431 * 432 * PARAMETERS : 433 * @count : number of buffers to be allocated 434 * @size : lenght of the buffer to be allocated 435 * 436 * RETURN : int32_t type of status 437 * NO_ERROR -- success 438 * none-zero failure code 439 *==========================================================================*/ 440 int QCameraHeapMemory::allocate(int count, int size) 441 { 442 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID; 443 int rc = alloc(count, size, heap_mask); 444 if (rc < 0) 445 return rc; 446 447 for (int i = 0; i < count; i ++) { 448 void *vaddr = mmap(NULL, 449 mMemInfo[i].size, 450 PROT_READ | PROT_WRITE, 451 MAP_SHARED, 452 mMemInfo[i].fd, 0); 453 if (vaddr == MAP_FAILED) { 454 for (int j = i-1; j >= 0; j --) { 455 munmap(mPtr[i], mMemInfo[i].size); 456 rc = NO_MEMORY; 457 break; 458 } 459 } else 460 mPtr[i] = vaddr; 461 } 462 if (rc == 0) 463 mBufferCount = count; 464 return OK; 465 } 466 467 /*=========================================================================== 468 * FUNCTION : deallocate 469 * 470 * DESCRIPTION: deallocate buffers 471 * 472 * PARAMETERS : none 473 * 474 * RETURN : none 475 *==========================================================================*/ 476 void QCameraHeapMemory::deallocate() 477 { 478 for (int i = 0; i < mBufferCount; i++) { 479 munmap(mPtr[i], mMemInfo[i].size); 480 mPtr[i] = NULL; 481 } 482 dealloc(); 483 mBufferCount = 0; 484 } 485 486 /*=========================================================================== 487 * FUNCTION : cacheOps 488 * 489 * DESCRIPTION: ion related memory cache operations 490 * 491 * PARAMETERS : 492 * @index : index of the buffer 493 * @cmd : cache ops command 494 * 495 * RETURN : int32_t type of status 496 * NO_ERROR -- success 497 * none-zero failure code 498 *==========================================================================*/ 499 int QCameraHeapMemory::cacheOps(int index, unsigned int cmd) 500 { 501 if (index >= mBufferCount) 502 return BAD_INDEX; 503 return cacheOpsInternal(index, cmd, mPtr[index]); 504 } 505 506 /*=========================================================================== 507 * FUNCTION : getRegFlags 508 * 509 * DESCRIPTION: query initial reg flags 510 * 511 * PARAMETERS : 512 * @regFlags: initial reg flags of the allocated buffers 513 * 514 * RETURN : int32_t type of status 515 * NO_ERROR -- success 516 * none-zero failure code 517 *==========================================================================*/ 518 int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const 519 { 520 return INVALID_OPERATION; 521 } 522 523 /*=========================================================================== 524 * FUNCTION : getMemory 525 * 526 * DESCRIPTION: get camera memory 527 * 528 * PARAMETERS : 529 * @index : buffer index 530 * @metadata: flag if it's metadata 531 * 532 * RETURN : camera memory ptr 533 * NULL if not supported or failed 534 *==========================================================================*/ 535 camera_memory_t *QCameraHeapMemory::getMemory( 536 int /*index*/, bool /*metadata*/) const 537 { 538 return NULL; 539 } 540 541 /*=========================================================================== 542 * FUNCTION : getMatchBufIndex 543 * 544 * DESCRIPTION: query buffer index by opaque ptr 545 * 546 * PARAMETERS : 547 * @opaque : opaque ptr 548 * @metadata: flag if it's metadata 549 * 550 * RETURN : buffer index if match found, 551 * -1 if failed 552 *==========================================================================*/ 553 int QCameraHeapMemory::getMatchBufIndex(const void *opaque, 554 bool metadata) const 555 { 556 int index = -1; 557 if (metadata) { 558 return -1; 559 } 560 for (int i = 0; i < mBufferCount; i++) { 561 if (mPtr[i] == opaque) { 562 index = i; 563 break; 564 } 565 } 566 return index; 567 } 568 569 /*=========================================================================== 570 * FUNCTION : QCameraStreamMemory 571 * 572 * DESCRIPTION: constructor of QCameraStreamMemory 573 * ION memory allocated directly from /dev/ion and shared with framework 574 * 575 * PARAMETERS : 576 * @getMemory : camera memory request ops table 577 * @cached : flag indicates if using cached memory 578 * 579 * RETURN : none 580 *==========================================================================*/ 581 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory getMemory, 582 bool cached) 583 :QCameraMemory(cached), 584 mGetMemory(getMemory) 585 { 586 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) 587 mCameraMemory[i] = NULL; 588 } 589 590 /*=========================================================================== 591 * FUNCTION : ~QCameraStreamMemory 592 * 593 * DESCRIPTION: deconstructor of QCameraStreamMemory 594 * 595 * PARAMETERS : none 596 * 597 * RETURN : none 598 *==========================================================================*/ 599 QCameraStreamMemory::~QCameraStreamMemory() 600 { 601 } 602 603 /*=========================================================================== 604 * FUNCTION : allocate 605 * 606 * DESCRIPTION: allocate requested number of buffers of certain size 607 * 608 * PARAMETERS : 609 * @count : number of buffers to be allocated 610 * @size : lenght of the buffer to be allocated 611 * 612 * RETURN : int32_t type of status 613 * NO_ERROR -- success 614 * none-zero failure code 615 *==========================================================================*/ 616 int QCameraStreamMemory::allocate(int count, int size) 617 { 618 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID; 619 int rc = alloc(count, size, heap_mask); 620 if (rc < 0) 621 return rc; 622 623 for (int i = 0; i < count; i ++) { 624 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this); 625 } 626 mBufferCount = count; 627 return NO_ERROR; 628 } 629 630 /*=========================================================================== 631 * FUNCTION : deallocate 632 * 633 * DESCRIPTION: deallocate buffers 634 * 635 * PARAMETERS : none 636 * 637 * RETURN : none 638 *==========================================================================*/ 639 void QCameraStreamMemory::deallocate() 640 { 641 for (int i = 0; i < mBufferCount; i ++) { 642 mCameraMemory[i]->release(mCameraMemory[i]); 643 mCameraMemory[i] = NULL; 644 } 645 dealloc(); 646 mBufferCount = 0; 647 } 648 649 /*=========================================================================== 650 * FUNCTION : cacheOps 651 * 652 * DESCRIPTION: ion related memory cache operations 653 * 654 * PARAMETERS : 655 * @index : index of the buffer 656 * @cmd : cache ops command 657 * 658 * RETURN : int32_t type of status 659 * NO_ERROR -- success 660 * none-zero failure code 661 *==========================================================================*/ 662 int QCameraStreamMemory::cacheOps(int index, unsigned int cmd) 663 { 664 if (index >= mBufferCount) 665 return BAD_INDEX; 666 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data); 667 } 668 669 /*=========================================================================== 670 * FUNCTION : getRegFlags 671 * 672 * DESCRIPTION: query initial reg flags 673 * 674 * PARAMETERS : 675 * @regFlags: initial reg flags of the allocated buffers 676 * 677 * RETURN : int32_t type of status 678 * NO_ERROR -- success 679 * none-zero failure code 680 *==========================================================================*/ 681 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const 682 { 683 for (int i = 0; i < mBufferCount; i ++) 684 regFlags[i] = 1; 685 return NO_ERROR; 686 } 687 688 /*=========================================================================== 689 * FUNCTION : getMemory 690 * 691 * DESCRIPTION: get camera memory 692 * 693 * PARAMETERS : 694 * @index : buffer index 695 * @metadata: flag if it's metadata 696 * 697 * RETURN : camera memory ptr 698 * NULL if not supported or failed 699 *==========================================================================*/ 700 camera_memory_t *QCameraStreamMemory::getMemory(int index, bool metadata) const 701 { 702 if (index >= mBufferCount || metadata) 703 return NULL; 704 return mCameraMemory[index]; 705 } 706 707 /*=========================================================================== 708 * FUNCTION : getMatchBufIndex 709 * 710 * DESCRIPTION: query buffer index by opaque ptr 711 * 712 * PARAMETERS : 713 * @opaque : opaque ptr 714 * @metadata: flag if it's metadata 715 * 716 * RETURN : buffer index if match found, 717 * -1 if failed 718 *==========================================================================*/ 719 int QCameraStreamMemory::getMatchBufIndex(const void *opaque, 720 bool metadata) const 721 { 722 int index = -1; 723 if (metadata) { 724 return -1; 725 } 726 for (int i = 0; i < mBufferCount; i++) { 727 if (mCameraMemory[i]->data == opaque) { 728 index = i; 729 break; 730 } 731 } 732 return index; 733 } 734 735 /*=========================================================================== 736 * FUNCTION : getPtr 737 * 738 * DESCRIPTION: return buffer pointer 739 * 740 * PARAMETERS : 741 * @index : index of the buffer 742 * 743 * RETURN : buffer ptr 744 *==========================================================================*/ 745 void *QCameraStreamMemory::getPtr(int index) const 746 { 747 if (index >= mBufferCount) { 748 ALOGE("index out of bound"); 749 return (void *)BAD_INDEX; 750 } 751 return mCameraMemory[index]->data; 752 } 753 754 /*=========================================================================== 755 * FUNCTION : QCameraVideoMemory 756 * 757 * DESCRIPTION: constructor of QCameraVideoMemory 758 * VideoStream buffers also include metadata buffers 759 * 760 * PARAMETERS : 761 * @getMemory : camera memory request ops table 762 * @cached : flag indicates if using cached ION memory 763 * 764 * RETURN : none 765 *==========================================================================*/ 766 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory getMemory, 767 bool cached) 768 : QCameraStreamMemory(getMemory, cached) 769 { 770 memset(mMetadata, 0, sizeof(mMetadata)); 771 } 772 773 /*=========================================================================== 774 * FUNCTION : ~QCameraVideoMemory 775 * 776 * DESCRIPTION: deconstructor of QCameraVideoMemory 777 * 778 * PARAMETERS : none 779 * 780 * RETURN : none 781 *==========================================================================*/ 782 QCameraVideoMemory::~QCameraVideoMemory() 783 { 784 } 785 786 /*=========================================================================== 787 * FUNCTION : allocate 788 * 789 * DESCRIPTION: allocate requested number of buffers of certain size 790 * 791 * PARAMETERS : 792 * @count : number of buffers to be allocated 793 * @size : lenght of the buffer to be allocated 794 * 795 * RETURN : int32_t type of status 796 * NO_ERROR -- success 797 * none-zero failure code 798 *==========================================================================*/ 799 int QCameraVideoMemory::allocate(int count, int size) 800 { 801 int rc = QCameraStreamMemory::allocate(count, size); 802 if (rc < 0) 803 return rc; 804 805 for (int i = 0; i < count; i ++) { 806 mMetadata[i] = mGetMemory(-1, 807 sizeof(struct encoder_media_buffer_type), 1, this); 808 if (!mMetadata[i]) { 809 ALOGE("allocation of video metadata failed."); 810 for (int j = 0; j < i-1; j ++) 811 mMetadata[j]->release(mMetadata[j]); 812 QCameraStreamMemory::deallocate(); 813 return NO_MEMORY; 814 } 815 struct encoder_media_buffer_type * packet = 816 (struct encoder_media_buffer_type *)mMetadata[i]->data; 817 packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size 818 packet->buffer_type = kMetadataBufferTypeCameraSource; 819 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 820 nh->data[0] = mMemInfo[i].fd; 821 nh->data[1] = 0; 822 nh->data[2] = mMemInfo[i].size; 823 } 824 mBufferCount = count; 825 return NO_ERROR; 826 } 827 828 /*=========================================================================== 829 * FUNCTION : deallocate 830 * 831 * DESCRIPTION: deallocate buffers 832 * 833 * PARAMETERS : none 834 * 835 * RETURN : none 836 *==========================================================================*/ 837 void QCameraVideoMemory::deallocate() 838 { 839 for (int i = 0; i < mBufferCount; i ++) { 840 mMetadata[i]->release(mMetadata[i]); 841 mMetadata[i] = NULL; 842 } 843 QCameraStreamMemory::deallocate(); 844 mBufferCount = 0; 845 } 846 847 /*=========================================================================== 848 * FUNCTION : getMemory 849 * 850 * DESCRIPTION: get camera memory 851 * 852 * PARAMETERS : 853 * @index : buffer index 854 * @metadata: flag if it's metadata 855 * 856 * RETURN : camera memory ptr 857 * NULL if not supported or failed 858 *==========================================================================*/ 859 camera_memory_t *QCameraVideoMemory::getMemory(int index, bool metadata) const 860 { 861 if (index >= mBufferCount) 862 return NULL; 863 if (metadata) 864 return mMetadata[index]; 865 else 866 return mCameraMemory[index]; 867 } 868 869 /*=========================================================================== 870 * FUNCTION : getMatchBufIndex 871 * 872 * DESCRIPTION: query buffer index by opaque ptr 873 * 874 * PARAMETERS : 875 * @opaque : opaque ptr 876 * @metadata: flag if it's metadata 877 * 878 * RETURN : buffer index if match found, 879 * -1 if failed 880 *==========================================================================*/ 881 int QCameraVideoMemory::getMatchBufIndex(const void *opaque, 882 bool metadata) const 883 { 884 int index = -1; 885 for (int i = 0; i < mBufferCount; i++) { 886 if (metadata) { 887 if (mMetadata[i]->data == opaque) { 888 index = i; 889 break; 890 } 891 } else { 892 if (mCameraMemory[i]->data == opaque) { 893 index = i; 894 break; 895 } 896 } 897 } 898 return index; 899 } 900 901 /*=========================================================================== 902 * FUNCTION : QCameraGrallocMemory 903 * 904 * DESCRIPTION: constructor of QCameraGrallocMemory 905 * preview stream buffers are allocated from gralloc native_windoe 906 * 907 * PARAMETERS : 908 * @getMemory : camera memory request ops table 909 * 910 * RETURN : none 911 *==========================================================================*/ 912 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory getMemory) 913 : QCameraMemory(true) 914 { 915 mMinUndequeuedBuffers = 0; 916 mWindow = NULL; 917 mWidth = mHeight = 0; 918 mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; 919 mGetMemory = getMemory; 920 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) { 921 mBufferHandle[i] = NULL; 922 mLocalFlag[i] = BUFFER_NOT_OWNED; 923 mPrivateHandle[i] = NULL; 924 } 925 } 926 927 /*=========================================================================== 928 * FUNCTION : ~QCameraGrallocMemory 929 * 930 * DESCRIPTION: deconstructor of QCameraGrallocMemory 931 * 932 * PARAMETERS : none 933 * 934 * RETURN : none 935 *==========================================================================*/ 936 QCameraGrallocMemory::~QCameraGrallocMemory() 937 { 938 } 939 940 /*=========================================================================== 941 * FUNCTION : setWindowInfo 942 * 943 * DESCRIPTION: set native window gralloc ops table 944 * 945 * PARAMETERS : 946 * @window : gralloc ops table ptr 947 * @width : width of preview frame 948 * @height : height of preview frame 949 * @foramt : format of preview image 950 * 951 * RETURN : none 952 *==========================================================================*/ 953 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window, 954 int width, int height, int format) 955 { 956 mWindow = window; 957 mWidth = width; 958 mHeight = height; 959 mFormat = format; 960 } 961 962 /*=========================================================================== 963 * FUNCTION : displayBuffer 964 * 965 * DESCRIPTION: send received frame to display 966 * 967 * PARAMETERS : 968 * @index : index of preview frame 969 * 970 * RETURN : int32_t type of status 971 * NO_ERROR -- success 972 * none-zero failure code 973 *==========================================================================*/ 974 int QCameraGrallocMemory::displayBuffer(int index) 975 { 976 int err = NO_ERROR; 977 int dequeuedIdx = BAD_INDEX; 978 979 if (BUFFER_NOT_OWNED == mLocalFlag[index]) { 980 ALOGE("%s: buffer to be enqueued is not owned", __func__); 981 return INVALID_OPERATION; 982 } 983 984 err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]); 985 if(err != 0) { 986 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err); 987 } else { 988 ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]); 989 mLocalFlag[index] = BUFFER_NOT_OWNED; 990 } 991 992 buffer_handle_t *buffer_handle = NULL; 993 int stride = 0; 994 err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride); 995 if (err == NO_ERROR && buffer_handle != NULL) { 996 int i; 997 ALOGV("%s: dequed buf hdl =%p", __func__, *buffer_handle); 998 for(i = 0; i < mBufferCount; i++) { 999 if(mBufferHandle[i] == buffer_handle) { 1000 ALOGV("%s: Found buffer in idx:%d", __func__, i); 1001 mLocalFlag[i] = BUFFER_OWNED; 1002 dequeuedIdx = i; 1003 break; 1004 } 1005 } 1006 } else { 1007 ALOGD("%s: dequeue_buffer, no free buffer from display now", __func__); 1008 } 1009 return dequeuedIdx; 1010 } 1011 1012 /*=========================================================================== 1013 * FUNCTION : allocate 1014 * 1015 * DESCRIPTION: allocate requested number of buffers of certain size 1016 * 1017 * PARAMETERS : 1018 * @count : number of buffers to be allocated 1019 * @size : lenght of the buffer to be allocated 1020 * 1021 * RETURN : int32_t type of status 1022 * NO_ERROR -- success 1023 * none-zero failure code 1024 *==========================================================================*/ 1025 int QCameraGrallocMemory::allocate(int count, int /*size*/) 1026 { 1027 int err = 0; 1028 status_t ret = NO_ERROR; 1029 int gralloc_usage = 0; 1030 struct ion_fd_data ion_info_fd; 1031 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 1032 1033 ALOGI(" %s : E ", __FUNCTION__); 1034 1035 if (!mWindow) { 1036 ALOGE("Invalid native window"); 1037 return INVALID_OPERATION; 1038 } 1039 1040 // Increment buffer count by min undequeued buffer. 1041 err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers); 1042 if (err != 0) { 1043 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)", 1044 strerror(-err), -err); 1045 ret = UNKNOWN_ERROR; 1046 goto end; 1047 } 1048 count += mMinUndequeuedBuffers; 1049 1050 err = mWindow->set_buffer_count(mWindow, count); 1051 if (err != 0) { 1052 ALOGE("set_buffer_count failed: %s (%d)", 1053 strerror(-err), -err); 1054 ret = UNKNOWN_ERROR; 1055 goto end; 1056 } 1057 1058 err = mWindow->set_buffers_geometry(mWindow, mWidth, mHeight, mFormat); 1059 if (err != 0) { 1060 ALOGE("%s: set_buffers_geometry failed: %s (%d)", 1061 __func__, strerror(-err), -err); 1062 ret = UNKNOWN_ERROR; 1063 goto end; 1064 } 1065 1066 gralloc_usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; 1067 err = mWindow->set_usage(mWindow, gralloc_usage); 1068 if(err != 0) { 1069 /* set_usage error out */ 1070 ALOGE("%s: set_usage rc = %d", __func__, err); 1071 ret = UNKNOWN_ERROR; 1072 goto end; 1073 } 1074 ALOGD("%s: usage = %d, geometry: %p, %d, %d, %d", 1075 __func__, gralloc_usage, mWindow, mWidth, mHeight, mFormat); 1076 1077 //Allocate cnt number of buffers from native window 1078 for (int cnt = 0; cnt < count; cnt++) { 1079 int stride; 1080 err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride); 1081 if(!err) { 1082 ALOGV("dequeue buf hdl =%p", mBufferHandle[cnt]); 1083 mLocalFlag[cnt] = BUFFER_OWNED; 1084 } else { 1085 mLocalFlag[cnt] = BUFFER_NOT_OWNED; 1086 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err); 1087 } 1088 1089 ALOGV("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]); 1090 1091 if(err != 0) { 1092 ALOGE("%s: dequeue_buffer failed: %s (%d)", 1093 __func__, strerror(-err), -err); 1094 ret = UNKNOWN_ERROR; 1095 for(int i = 0; i < cnt; i++) { 1096 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 1097 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 1098 ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); 1099 } 1100 mLocalFlag[i] = BUFFER_NOT_OWNED; 1101 mBufferHandle[i] = NULL; 1102 } 1103 memset(&mMemInfo, 0, sizeof(mMemInfo)); 1104 goto end; 1105 } 1106 1107 mPrivateHandle[cnt] = 1108 (struct private_handle_t *)(*mBufferHandle[cnt]); 1109 mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY); 1110 if (mMemInfo[cnt].main_ion_fd < 0) { 1111 ALOGE("%s: failed: could not open ion device", __func__); 1112 for(int i = 0; i < cnt; i++) { 1113 struct ion_handle_data ion_handle; 1114 memset(&ion_handle, 0, sizeof(ion_handle)); 1115 ion_handle.handle = mMemInfo[i].handle; 1116 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 1117 ALOGE("%s: ion free failed", __func__); 1118 } 1119 close(mMemInfo[i].main_ion_fd); 1120 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 1121 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 1122 ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); 1123 } 1124 mLocalFlag[i] = BUFFER_NOT_OWNED; 1125 mBufferHandle[i] = NULL; 1126 } 1127 memset(&mMemInfo, 0, sizeof(mMemInfo)); 1128 ret = UNKNOWN_ERROR; 1129 goto end; 1130 } else { 1131 ion_info_fd.fd = mPrivateHandle[cnt]->fd; 1132 if (ioctl(mMemInfo[cnt].main_ion_fd, 1133 ION_IOC_IMPORT, &ion_info_fd) < 0) { 1134 ALOGE("%s: ION import failed\n", __func__); 1135 for(int i = 0; i < cnt; i++) { 1136 struct ion_handle_data ion_handle; 1137 memset(&ion_handle, 0, sizeof(ion_handle)); 1138 ion_handle.handle = mMemInfo[i].handle; 1139 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 1140 ALOGE("ion free failed"); 1141 } 1142 close(mMemInfo[i].main_ion_fd); 1143 1144 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 1145 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 1146 ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); 1147 } 1148 mLocalFlag[i] = BUFFER_NOT_OWNED; 1149 mBufferHandle[i] = NULL; 1150 } 1151 close(mMemInfo[cnt].main_ion_fd); 1152 memset(&mMemInfo, 0, sizeof(mMemInfo)); 1153 ret = UNKNOWN_ERROR; 1154 goto end; 1155 } 1156 } 1157 mCameraMemory[cnt] = 1158 mGetMemory(mPrivateHandle[cnt]->fd, 1159 mPrivateHandle[cnt]->size, 1160 1, 1161 (void *)this); 1162 ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", 1163 __func__, cnt, mPrivateHandle[cnt]->fd, 1164 mPrivateHandle[cnt]->size, 1165 mPrivateHandle[cnt]->offset); 1166 mMemInfo[cnt].fd = 1167 mPrivateHandle[cnt]->fd; 1168 mMemInfo[cnt].size = 1169 mPrivateHandle[cnt]->size; 1170 mMemInfo[cnt].handle = ion_info_fd.handle; 1171 } 1172 mBufferCount = count; 1173 1174 //Cancel min_undequeued_buffer buffers back to the window 1175 for (int i = 0; i < mMinUndequeuedBuffers; i ++) { 1176 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 1177 mLocalFlag[i] = BUFFER_NOT_OWNED; 1178 } 1179 1180 end: 1181 ALOGI(" %s : X ",__func__); 1182 return ret; 1183 } 1184 1185 /*=========================================================================== 1186 * FUNCTION : deallocate 1187 * 1188 * DESCRIPTION: deallocate buffers 1189 * 1190 * PARAMETERS : none 1191 * 1192 * RETURN : none 1193 *==========================================================================*/ 1194 void QCameraGrallocMemory::deallocate() 1195 { 1196 ALOGI("%s: E ", __FUNCTION__); 1197 1198 for (int cnt = 0; cnt < mBufferCount; cnt++) { 1199 mCameraMemory[cnt]->release(mCameraMemory[cnt]); 1200 struct ion_handle_data ion_handle; 1201 memset(&ion_handle, 0, sizeof(ion_handle)); 1202 ion_handle.handle = mMemInfo[cnt].handle; 1203 if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 1204 ALOGE("ion free failed"); 1205 } 1206 close(mMemInfo[cnt].main_ion_fd); 1207 if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) { 1208 if (mWindow) { 1209 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]); 1210 ALOGD("cancel_buffer: hdl =%p", (*mBufferHandle[cnt])); 1211 } else { 1212 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p", 1213 (*mBufferHandle[cnt])); 1214 } 1215 } 1216 mLocalFlag[cnt] = BUFFER_NOT_OWNED; 1217 ALOGD("put buffer %d successfully", cnt); 1218 } 1219 mBufferCount = 0; 1220 ALOGI(" %s : X ",__FUNCTION__); 1221 } 1222 1223 /*=========================================================================== 1224 * FUNCTION : cacheOps 1225 * 1226 * DESCRIPTION: ion related memory cache operations 1227 * 1228 * PARAMETERS : 1229 * @index : index of the buffer 1230 * @cmd : cache ops command 1231 * 1232 * RETURN : int32_t type of status 1233 * NO_ERROR -- success 1234 * none-zero failure code 1235 *==========================================================================*/ 1236 int QCameraGrallocMemory::cacheOps(int index, unsigned int cmd) 1237 { 1238 if (index >= mBufferCount) 1239 return BAD_INDEX; 1240 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data); 1241 } 1242 1243 /*=========================================================================== 1244 * FUNCTION : getRegFlags 1245 * 1246 * DESCRIPTION: query initial reg flags 1247 * 1248 * PARAMETERS : 1249 * @regFlags: initial reg flags of the allocated buffers 1250 * 1251 * RETURN : int32_t type of status 1252 * NO_ERROR -- success 1253 * none-zero failure code 1254 *==========================================================================*/ 1255 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const 1256 { 1257 int i = 0; 1258 for (i = 0; i < mMinUndequeuedBuffers; i ++) 1259 regFlags[i] = 0; 1260 for (; i < mBufferCount; i ++) 1261 regFlags[i] = 1; 1262 return NO_ERROR; 1263 } 1264 1265 /*=========================================================================== 1266 * FUNCTION : getMemory 1267 * 1268 * DESCRIPTION: get camera memory 1269 * 1270 * PARAMETERS : 1271 * @index : buffer index 1272 * @metadata: flag if it's metadata 1273 * 1274 * RETURN : camera memory ptr 1275 * NULL if not supported or failed 1276 *==========================================================================*/ 1277 camera_memory_t *QCameraGrallocMemory::getMemory(int index, bool metadata) const 1278 { 1279 if (index >= mBufferCount || metadata) 1280 return NULL; 1281 return mCameraMemory[index]; 1282 } 1283 1284 /*=========================================================================== 1285 * FUNCTION : getMatchBufIndex 1286 * 1287 * DESCRIPTION: query buffer index by opaque ptr 1288 * 1289 * PARAMETERS : 1290 * @opaque : opaque ptr 1291 * @metadata: flag if it's metadata 1292 * 1293 * RETURN : buffer index if match found, 1294 * -1 if failed 1295 *==========================================================================*/ 1296 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque, 1297 bool metadata) const 1298 { 1299 int index = -1; 1300 if (metadata) { 1301 return -1; 1302 } 1303 for (int i = 0; i < mBufferCount; i++) { 1304 if (mCameraMemory[i]->data == opaque) { 1305 index = i; 1306 break; 1307 } 1308 } 1309 return index; 1310 } 1311 1312 /*=========================================================================== 1313 * FUNCTION : getPtr 1314 * 1315 * DESCRIPTION: return buffer pointer 1316 * 1317 * PARAMETERS : 1318 * @index : index of the buffer 1319 * 1320 * RETURN : buffer ptr 1321 *==========================================================================*/ 1322 void *QCameraGrallocMemory::getPtr(int index) const 1323 { 1324 if (index >= mBufferCount) { 1325 ALOGE("index out of bound"); 1326 return (void *)BAD_INDEX; 1327 } 1328 return mCameraMemory[index]->data; 1329 } 1330 1331 }; //namespace qcamera 1332