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