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