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