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