1/* Copyright (c) 2012-2016, The Linux Foundation. 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 LOG_TAG "QCameraHWI_Mem" 30 31// System dependencies 32#include <fcntl.h> 33#include <stdio.h> 34#include <utils/Errors.h> 35#define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h> 36#include MMAN_H 37#include "gralloc.h" 38#include "gralloc_priv.h" 39 40// OpenMAX dependencies 41#include "OMX_QCOMExtns.h" 42#include "QComOMXMetadata.h" 43 44// Camera dependencies 45#include "QCamera2HWI.h" 46#include "QCameraMem.h" 47#include "QCameraParameters.h" 48#include "QCameraTrace.h" 49 50extern "C" { 51#include "mm_camera_dbg.h" 52#include "mm_camera_interface.h" 53} 54 55using namespace android; 56 57namespace qcamera { 58 59// QCaemra2Memory base class 60 61/*=========================================================================== 62 * FUNCTION : QCameraMemory 63 * 64 * DESCRIPTION: default constructor of QCameraMemory 65 * 66 * PARAMETERS : 67 * @cached : flag indicates if using cached memory 68 * 69 * RETURN : None 70 *==========================================================================*/ 71QCameraMemory::QCameraMemory(bool cached, 72 QCameraMemoryPool *pool, 73 cam_stream_type_t streamType, QCameraMemType bufType) 74 :m_bCached(cached), 75 mMemoryPool(pool), 76 mStreamType(streamType), 77 mBufType(bufType) 78{ 79 mBufferCount = 0; 80 reset(); 81} 82 83/*=========================================================================== 84 * FUNCTION : ~QCameraMemory 85 * 86 * DESCRIPTION: deconstructor of QCameraMemory 87 * 88 * PARAMETERS : none 89 * 90 * RETURN : None 91 *==========================================================================*/ 92QCameraMemory::~QCameraMemory() 93{ 94} 95 96/*=========================================================================== 97 * FUNCTION : cacheOpsInternal 98 * 99 * DESCRIPTION: ion related memory cache operations 100 * 101 * PARAMETERS : 102 * @index : index of the buffer 103 * @cmd : cache ops command 104 * @vaddr : ptr to the virtual address 105 * 106 * RETURN : int32_t type of status 107 * NO_ERROR -- success 108 * none-zero failure code 109 *==========================================================================*/ 110int QCameraMemory::cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr) 111{ 112 if (!m_bCached) { 113 // Memory is not cached, no need for cache ops 114 LOGD("No cache ops here for uncached memory"); 115 return OK; 116 } 117 118 struct ion_flush_data cache_inv_data; 119 struct ion_custom_data custom_data; 120 int ret = OK; 121 122 if (index >= mBufferCount) { 123 LOGE("index %d out of bound [0, %d)", index, mBufferCount); 124 return BAD_INDEX; 125 } 126 127 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 128 memset(&custom_data, 0, sizeof(custom_data)); 129 cache_inv_data.vaddr = vaddr; 130 cache_inv_data.fd = mMemInfo[index].fd; 131 cache_inv_data.handle = mMemInfo[index].handle; 132 cache_inv_data.length = 133 ( /* FIXME: Should remove this after ION interface changes */ unsigned int) 134 mMemInfo[index].size; 135 custom_data.cmd = cmd; 136 custom_data.arg = (unsigned long)&cache_inv_data; 137 138 LOGH("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d", 139 cache_inv_data.vaddr, cache_inv_data.fd, 140 (unsigned long)cache_inv_data.handle, cache_inv_data.length, 141 mMemInfo[index].main_ion_fd); 142 ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data); 143 if (ret < 0) { 144 LOGE("Cache Invalidate failed: %s\n", strerror(errno)); 145 } 146 147 return ret; 148} 149 150/*=========================================================================== 151 * FUNCTION : getFd 152 * 153 * DESCRIPTION: return file descriptor of the indexed buffer 154 * 155 * PARAMETERS : 156 * @index : index of the buffer 157 * 158 * RETURN : file descriptor 159 *==========================================================================*/ 160int QCameraMemory::getFd(uint32_t index) const 161{ 162 if (index >= mBufferCount) 163 return BAD_INDEX; 164 165 return mMemInfo[index].fd; 166} 167 168/*=========================================================================== 169 * FUNCTION : getSize 170 * 171 * DESCRIPTION: return buffer size of the indexed buffer 172 * 173 * PARAMETERS : 174 * @index : index of the buffer 175 * 176 * RETURN : buffer size 177 *==========================================================================*/ 178ssize_t QCameraMemory::getSize(uint32_t index) const 179{ 180 if (index >= mBufferCount) 181 return BAD_INDEX; 182 183 return (ssize_t)mMemInfo[index].size; 184} 185 186/*=========================================================================== 187 * FUNCTION : getCnt 188 * 189 * DESCRIPTION: query number of buffers allocated 190 * 191 * PARAMETERS : none 192 * 193 * RETURN : number of buffers allocated 194 *==========================================================================*/ 195uint8_t QCameraMemory::getCnt() const 196{ 197 return mBufferCount; 198} 199 200/*=========================================================================== 201 * FUNCTION : reset 202 * 203 * DESCRIPTION: reset member variables 204 * 205 * PARAMETERS : none 206 * 207 * RETURN : none 208 *==========================================================================*/ 209void QCameraMemory::reset() 210{ 211 size_t i, count; 212 213 memset(mMemInfo, 0, sizeof(mMemInfo)); 214 215 count = sizeof(mMemInfo) / sizeof(mMemInfo[0]); 216 for (i = 0; i < count; i++) { 217 mMemInfo[i].fd = -1; 218 mMemInfo[i].main_ion_fd = -1; 219 } 220 221 return; 222} 223 224/*=========================================================================== 225 * FUNCTION : getMappable 226 * 227 * DESCRIPTION: query number of buffers available to map 228 * 229 * PARAMETERS : none 230 * 231 * RETURN : number of buffers available to map 232 *==========================================================================*/ 233uint8_t QCameraMemory::getMappable() const 234{ 235 return mBufferCount; 236} 237 238/*=========================================================================== 239 * FUNCTION : checkIfAllBuffersMapped 240 * 241 * DESCRIPTION: query if all buffers are mapped 242 * 243 * PARAMETERS : none 244 * 245 * RETURN : 1 as buffer count is always equal to mappable count 246 *==========================================================================*/ 247uint8_t QCameraMemory::checkIfAllBuffersMapped() const 248{ 249 return 1; 250} 251 252 253/*=========================================================================== 254 * FUNCTION : getBufDef 255 * 256 * DESCRIPTION: query detailed buffer information 257 * 258 * PARAMETERS : 259 * @offset : [input] frame buffer offset 260 * @bufDef : [output] reference to struct to store buffer definition 261 * @index : [input] index of the buffer 262 * 263 * RETURN : none 264 *==========================================================================*/ 265void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset, 266 mm_camera_buf_def_t &bufDef, uint32_t index) const 267{ 268 if (!mBufferCount) { 269 LOGE("Memory not allocated"); 270 return; 271 } 272 bufDef.fd = mMemInfo[index].fd; 273 bufDef.frame_len = mMemInfo[index].size; 274 bufDef.buf_type = CAM_STREAM_BUF_TYPE_MPLANE; 275 bufDef.mem_info = (void *)this; 276 bufDef.planes_buf.num_planes = (int8_t)offset.num_planes; 277 bufDef.buffer = getPtr(index); 278 bufDef.buf_idx = index; 279 280 /* Plane 0 needs to be set separately. Set other planes in a loop */ 281 bufDef.planes_buf.planes[0].length = offset.mp[0].len; 282 bufDef.planes_buf.planes[0].m.userptr = (long unsigned int)mMemInfo[index].fd; 283 bufDef.planes_buf.planes[0].data_offset = offset.mp[0].offset; 284 bufDef.planes_buf.planes[0].reserved[0] = 0; 285 for (int i = 1; i < bufDef.planes_buf.num_planes; i++) { 286 bufDef.planes_buf.planes[i].length = offset.mp[i].len; 287 bufDef.planes_buf.planes[i].m.userptr = (long unsigned int)mMemInfo[i].fd; 288 bufDef.planes_buf.planes[i].data_offset = offset.mp[i].offset; 289 bufDef.planes_buf.planes[i].reserved[0] = 290 bufDef.planes_buf.planes[i-1].reserved[0] + 291 bufDef.planes_buf.planes[i-1].length; 292 } 293} 294 295/*=========================================================================== 296 * FUNCTION : getUserBufDef 297 * 298 * DESCRIPTION: Fill Buffer structure with user buffer information 299 This also fills individual stream buffers inside batch baffer strcuture 300 * 301 * PARAMETERS : 302 * @buf_info : user buffer information 303 * @bufDef : Buffer strcuture to fill user buf info 304 * @index : index of the buffer 305 * @plane_offset : plane buffer information 306 * @planeBufDef : [input] frame buffer offset 307 * @bufs : Stream Buffer object 308 * 309 * RETURN : int32_t type of status 310 * NO_ERROR -- success 311 * none-zero failure code 312 *==========================================================================*/ 313int32_t QCameraMemory::getUserBufDef(const cam_stream_user_buf_info_t &buf_info, 314 mm_camera_buf_def_t &bufDef, 315 uint32_t index, 316 const cam_frame_len_offset_t &plane_offset, 317 mm_camera_buf_def_t *planeBufDef, 318 QCameraMemory *bufs) const 319{ 320 struct msm_camera_user_buf_cont_t *cont_buf = NULL; 321 uint32_t plane_idx = (index * buf_info.frame_buf_cnt); 322 323 if (!mBufferCount) { 324 LOGE("Memory not allocated"); 325 return INVALID_OPERATION; 326 } 327 328 for (int count = 0; count < mBufferCount; count++) { 329 bufDef.fd = mMemInfo[count].fd; 330 bufDef.buf_type = CAM_STREAM_BUF_TYPE_USERPTR; 331 bufDef.frame_len = buf_info.size; 332 bufDef.mem_info = (void *)this; 333 bufDef.buffer = (void *)((uint8_t *)getPtr(count) 334 + (index * buf_info.size)); 335 bufDef.buf_idx = index; 336 bufDef.user_buf.num_buffers = (int8_t)buf_info.frame_buf_cnt; 337 bufDef.user_buf.bufs_used = (int8_t)buf_info.frame_buf_cnt; 338 339 //Individual plane buffer structure to be filled 340 cont_buf = (struct msm_camera_user_buf_cont_t *)bufDef.buffer; 341 cont_buf->buf_cnt = bufDef.user_buf.num_buffers; 342 343 for (int i = 0; i < bufDef.user_buf.num_buffers; i++) { 344 bufs->getBufDef(plane_offset, planeBufDef[plane_idx], plane_idx); 345 bufDef.user_buf.buf_idx[i] = -1; 346 cont_buf->buf_idx[i] = planeBufDef[plane_idx].buf_idx; 347 plane_idx++; 348 } 349 bufDef.user_buf.plane_buf = planeBufDef; 350 351 LOGD("num_buf = %d index = %d plane_idx = %d", 352 bufDef.user_buf.num_buffers, index, plane_idx); 353 } 354 return NO_ERROR; 355} 356 357 358/*=========================================================================== 359 * FUNCTION : alloc 360 * 361 * DESCRIPTION: allocate requested number of buffers of certain size 362 * 363 * PARAMETERS : 364 * @count : number of buffers to be allocated 365 * @size : lenght of the buffer to be allocated 366 * @heap_id : heap id to indicate where the buffers will be allocated from 367 * 368 * RETURN : int32_t type of status 369 * NO_ERROR -- success 370 * none-zero failure code 371 *==========================================================================*/ 372int QCameraMemory::alloc(int count, size_t size, unsigned int heap_id, 373 uint32_t secure_mode) 374{ 375 int rc = OK; 376 377 int new_bufCnt = mBufferCount + count; 378 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "Memsize", size, count); 379 380 if (new_bufCnt > MM_CAMERA_MAX_NUM_FRAMES) { 381 LOGE("Buffer count %d out of bound. Max is %d", 382 new_bufCnt, MM_CAMERA_MAX_NUM_FRAMES); 383 ATRACE_END(); 384 return BAD_INDEX; 385 } 386 387 for (int i = mBufferCount; i < new_bufCnt; i ++) { 388 if ( NULL == mMemoryPool ) { 389 LOGH("No memory pool available, allocating now"); 390 rc = allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached, 391 secure_mode); 392 if (rc < 0) { 393 LOGE("AllocateIonMemory failed"); 394 for (int j = i-1; j >= 0; j--) 395 deallocOneBuffer(mMemInfo[j]); 396 break; 397 } 398 } else { 399 rc = mMemoryPool->allocateBuffer(mMemInfo[i], 400 heap_id, 401 size, 402 m_bCached, 403 mStreamType, 404 secure_mode); 405 if (rc < 0) { 406 LOGE("Memory pool allocation failed"); 407 for (int j = i-1; j >= 0; j--) 408 mMemoryPool->releaseBuffer(mMemInfo[j], 409 mStreamType); 410 break; 411 } 412 } 413 414 } 415 ATRACE_END(); 416 return rc; 417} 418 419/*=========================================================================== 420 * FUNCTION : dealloc 421 * 422 * DESCRIPTION: deallocate buffers 423 * 424 * PARAMETERS : none 425 * 426 * RETURN : none 427 *==========================================================================*/ 428void QCameraMemory::dealloc() 429{ 430 for (int i = 0; i < mBufferCount; i++) { 431 if ( NULL == mMemoryPool ) { 432 deallocOneBuffer(mMemInfo[i]); 433 } else { 434 mMemoryPool->releaseBuffer(mMemInfo[i], mStreamType); 435 } 436 } 437} 438 439/*=========================================================================== 440 * FUNCTION : allocOneBuffer 441 * 442 * DESCRIPTION: impl of allocating one buffers of certain size 443 * 444 * PARAMETERS : 445 * @memInfo : [output] reference to struct to store additional memory allocation info 446 * @heap : [input] heap id to indicate where the buffers will be allocated from 447 * @size : [input] lenght of the buffer to be allocated 448 * @cached : [input] flag whether buffer needs to be cached 449 * 450 * RETURN : int32_t type of status 451 * NO_ERROR -- success 452 * none-zero failure code 453 *==========================================================================*/ 454int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo, 455 unsigned int heap_id, size_t size, bool cached, uint32_t secure_mode) 456{ 457 int rc = OK; 458 struct ion_handle_data handle_data; 459 struct ion_allocation_data alloc; 460 struct ion_fd_data ion_info_fd; 461 int main_ion_fd = -1; 462 463 main_ion_fd = open("/dev/ion", O_RDONLY); 464 if (main_ion_fd < 0) { 465 LOGE("Ion dev open failed: %s\n", strerror(errno)); 466 goto ION_OPEN_FAILED; 467 } 468 469 memset(&alloc, 0, sizeof(alloc)); 470 alloc.len = size; 471 /* to make it page size aligned */ 472 alloc.len = (alloc.len + 4095U) & (~4095U); 473 alloc.align = 4096; 474 if (cached) { 475 alloc.flags = ION_FLAG_CACHED; 476 } 477 alloc.heap_id_mask = heap_id; 478 if (secure_mode == SECURE) { 479 LOGD("Allocate secure buffer\n"); 480 alloc.flags = ION_SECURE; 481 alloc.heap_id_mask = ION_HEAP(ION_CP_MM_HEAP_ID); 482 alloc.align = 1048576; // 1 MiB alignment to be able to protect later 483 alloc.len = (alloc.len + 1048575U) & (~1048575U); 484 } 485 486 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc); 487 if (rc < 0) { 488 LOGE("ION allocation failed: %s\n", strerror(errno)); 489 goto ION_ALLOC_FAILED; 490 } 491 492 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 493 ion_info_fd.handle = alloc.handle; 494 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 495 if (rc < 0) { 496 LOGE("ION map failed %s\n", strerror(errno)); 497 goto ION_MAP_FAILED; 498 } 499 500 memInfo.main_ion_fd = main_ion_fd; 501 memInfo.fd = ion_info_fd.fd; 502 memInfo.handle = ion_info_fd.handle; 503 memInfo.size = alloc.len; 504 memInfo.cached = cached; 505 memInfo.heap_id = heap_id; 506 507 LOGD("ION buffer %lx with size %d allocated", 508 (unsigned long)memInfo.handle, alloc.len); 509 return OK; 510 511ION_MAP_FAILED: 512 memset(&handle_data, 0, sizeof(handle_data)); 513 handle_data.handle = ion_info_fd.handle; 514 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 515ION_ALLOC_FAILED: 516 close(main_ion_fd); 517ION_OPEN_FAILED: 518 return NO_MEMORY; 519} 520 521/*=========================================================================== 522 * FUNCTION : deallocOneBuffer 523 * 524 * DESCRIPTION: impl of deallocating one buffers 525 * 526 * PARAMETERS : 527 * @memInfo : reference to struct that stores additional memory allocation info 528 * 529 * RETURN : none 530 *==========================================================================*/ 531void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo) 532{ 533 struct ion_handle_data handle_data; 534 535 if (memInfo.fd >= 0) { 536 close(memInfo.fd); 537 memInfo.fd = -1; 538 } 539 540 if (memInfo.main_ion_fd >= 0) { 541 memset(&handle_data, 0, sizeof(handle_data)); 542 handle_data.handle = memInfo.handle; 543 ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data); 544 close(memInfo.main_ion_fd); 545 memInfo.main_ion_fd = -1; 546 } 547 memInfo.handle = 0; 548 memInfo.size = 0; 549} 550 551/*=========================================================================== 552 * FUNCTION : QCameraMemoryPool 553 * 554 * DESCRIPTION: default constructor of QCameraMemoryPool 555 * 556 * PARAMETERS : None 557 * 558 * RETURN : None 559 *==========================================================================*/ 560QCameraMemoryPool::QCameraMemoryPool() 561{ 562 pthread_mutex_init(&mLock, NULL); 563} 564 565 566/*=========================================================================== 567 * FUNCTION : ~QCameraMemoryPool 568 * 569 * DESCRIPTION: deconstructor of QCameraMemoryPool 570 * 571 * PARAMETERS : None 572 * 573 * RETURN : None 574 *==========================================================================*/ 575QCameraMemoryPool::~QCameraMemoryPool() 576{ 577 clear(); 578 pthread_mutex_destroy(&mLock); 579} 580 581/*=========================================================================== 582 * FUNCTION : releaseBuffer 583 * 584 * DESCRIPTION: release one cached buffers 585 * 586 * PARAMETERS : 587 * @memInfo : reference to struct that stores additional memory allocation info 588 * @streamType: Type of stream the buffers belongs to 589 * 590 * RETURN : none 591 *==========================================================================*/ 592void QCameraMemoryPool::releaseBuffer( 593 struct QCameraMemory::QCameraMemInfo &memInfo, 594 cam_stream_type_t streamType) 595{ 596 pthread_mutex_lock(&mLock); 597 598 mPools[streamType].push_back(memInfo); 599 600 pthread_mutex_unlock(&mLock); 601} 602 603/*=========================================================================== 604 * FUNCTION : clear 605 * 606 * DESCRIPTION: clears all cached buffers 607 * 608 * PARAMETERS : none 609 * 610 * RETURN : none 611 *==========================================================================*/ 612void QCameraMemoryPool::clear() 613{ 614 pthread_mutex_lock(&mLock); 615 616 for (int i = CAM_STREAM_TYPE_DEFAULT; i < CAM_STREAM_TYPE_MAX; i++ ) { 617 List<struct QCameraMemory::QCameraMemInfo>::iterator it; 618 it = mPools[i].begin(); 619 for( ; it != mPools[i].end() ; it++) { 620 QCameraMemory::deallocOneBuffer(*it); 621 } 622 623 mPools[i].clear(); 624 } 625 626 pthread_mutex_unlock(&mLock); 627} 628 629/*=========================================================================== 630 * FUNCTION : findBufferLocked 631 * 632 * DESCRIPTION: search for a appropriate cached buffer 633 * 634 * PARAMETERS : 635 * @memInfo : reference to struct that stores additional memory allocation info 636 * @heap_id : type of heap 637 * @size : size of the buffer 638 * @cached : whether the buffer should be cached 639 * @streaType: type of stream this buffer belongs to 640 * 641 * RETURN : int32_t type of status 642 * NO_ERROR -- success 643 * none-zero failure code 644 *==========================================================================*/ 645int QCameraMemoryPool::findBufferLocked( 646 struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id, 647 size_t size, bool cached, cam_stream_type_t streamType) 648{ 649 int rc = NAME_NOT_FOUND; 650 651 if (mPools[streamType].empty()) { 652 return NAME_NOT_FOUND; 653 } 654 655 List<struct QCameraMemory::QCameraMemInfo>::iterator it = mPools[streamType].begin(); 656 if (streamType == CAM_STREAM_TYPE_OFFLINE_PROC) { 657 for( ; it != mPools[streamType].end() ; it++) { 658 if( ((*it).size == size) && 659 ((*it).heap_id == heap_id) && 660 ((*it).cached == cached) ) { 661 memInfo = *it; 662 LOGD("Found buffer %lx size %d", 663 (unsigned long)memInfo.handle, memInfo.size); 664 mPools[streamType].erase(it); 665 rc = NO_ERROR; 666 break; 667 } 668 } 669 } else { 670 for( ; it != mPools[streamType].end() ; it++) { 671 if(((*it).size >= size) && 672 ((*it).heap_id == heap_id) && 673 ((*it).cached == cached) ) { 674 memInfo = *it; 675 LOGD("Found buffer %lx size %d", 676 (unsigned long)memInfo.handle, memInfo.size); 677 mPools[streamType].erase(it); 678 rc = NO_ERROR; 679 break; 680 } 681 } 682 } 683 684 return rc; 685} 686 687/*=========================================================================== 688 * FUNCTION : allocateBuffer 689 * 690 * DESCRIPTION: allocates a buffer from the memory pool, 691 * it will re-use cached buffers if possible 692 * 693 * PARAMETERS : 694 * @memInfo : reference to struct that stores additional memory allocation info 695 * @heap_id : type of heap 696 * @size : size of the buffer 697 * @cached : whether the buffer should be cached 698 * @streaType: type of stream this buffer belongs to 699 * 700 * RETURN : int32_t type of status 701 * NO_ERROR -- success 702 * none-zero failure code 703 *==========================================================================*/ 704int QCameraMemoryPool::allocateBuffer( 705 struct QCameraMemory::QCameraMemInfo &memInfo, unsigned int heap_id, 706 size_t size, bool cached, cam_stream_type_t streamType, 707 uint32_t secure_mode) 708{ 709 int rc = NO_ERROR; 710 711 pthread_mutex_lock(&mLock); 712 713 rc = findBufferLocked(memInfo, heap_id, size, cached, streamType); 714 if (NAME_NOT_FOUND == rc ) { 715 LOGD("Buffer not found!"); 716 rc = QCameraMemory::allocOneBuffer(memInfo, heap_id, size, cached, 717 secure_mode); 718 } 719 720 pthread_mutex_unlock(&mLock); 721 722 return rc; 723} 724 725/*=========================================================================== 726 * FUNCTION : QCameraHeapMemory 727 * 728 * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL 729 * 730 * PARAMETERS : 731 * @cached : flag indicates if using cached memory 732 * 733 * RETURN : none 734 *==========================================================================*/ 735QCameraHeapMemory::QCameraHeapMemory(bool cached) 736 : QCameraMemory(cached) 737{ 738 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) 739 mPtr[i] = NULL; 740} 741 742/*=========================================================================== 743 * FUNCTION : ~QCameraHeapMemory 744 * 745 * DESCRIPTION: deconstructor of QCameraHeapMemory 746 * 747 * PARAMETERS : none 748 * 749 * RETURN : none 750 *==========================================================================*/ 751QCameraHeapMemory::~QCameraHeapMemory() 752{ 753} 754 755/*=========================================================================== 756 * FUNCTION : getPtr 757 * 758 * DESCRIPTION: return buffer pointer 759 * 760 * PARAMETERS : 761 * @index : index of the buffer 762 * 763 * RETURN : buffer ptr 764 *==========================================================================*/ 765void *QCameraHeapMemory::getPtr(uint32_t index) const 766{ 767 if (index >= mBufferCount) { 768 LOGE("index out of bound"); 769 return (void *)BAD_INDEX; 770 } 771 return mPtr[index]; 772} 773 774/*=========================================================================== 775 * FUNCTION : allocate 776 * 777 * DESCRIPTION: allocate requested number of buffers of certain size 778 * 779 * PARAMETERS : 780 * @count : number of buffers to be allocated 781 * @size : lenght of the buffer to be allocated 782 * 783 * RETURN : int32_t type of status 784 * NO_ERROR -- success 785 * none-zero failure code 786 *==========================================================================*/ 787int QCameraHeapMemory::allocate(uint8_t count, size_t size, uint32_t isSecure) 788{ 789 int rc = -1; 790 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "HeapMemsize", size, count); 791 uint32_t heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 792 if (isSecure == SECURE) { 793 rc = alloc(count, size, heap_id_mask, SECURE); 794 if (rc < 0) { 795 ATRACE_END(); 796 return rc; 797 } 798 } else { 799 rc = alloc(count, size, heap_id_mask, NON_SECURE); 800 if (rc < 0) { 801 ATRACE_END(); 802 return rc; 803 } 804 805 for (int i = 0; i < count; i ++) { 806 void *vaddr = mmap(NULL, 807 mMemInfo[i].size, 808 PROT_READ | PROT_WRITE, 809 MAP_SHARED, 810 mMemInfo[i].fd, 0); 811 if (vaddr == MAP_FAILED) { 812 for (int j = i-1; j >= 0; j --) { 813 munmap(mPtr[j], mMemInfo[j].size); 814 mPtr[j] = NULL; 815 deallocOneBuffer(mMemInfo[j]); 816 } 817 // Deallocate remaining buffers that have already been allocated 818 for (int j = i; j < count; j++) { 819 deallocOneBuffer(mMemInfo[j]); 820 } 821 ATRACE_END(); 822 return NO_MEMORY; 823 } else 824 mPtr[i] = vaddr; 825 } 826 } 827 if (rc == 0) { 828 mBufferCount = count; 829 } 830 ATRACE_END(); 831 return OK; 832} 833 834/*=========================================================================== 835 * FUNCTION : allocateMore 836 * 837 * DESCRIPTION: allocate more requested number of buffers of certain size 838 * 839 * PARAMETERS : 840 * @count : number of buffers to be allocated 841 * @size : lenght of the buffer to be allocated 842 * 843 * RETURN : int32_t type of status 844 * NO_ERROR -- success 845 * none-zero failure code 846 *==========================================================================*/ 847int QCameraHeapMemory::allocateMore(uint8_t count, size_t size) 848{ 849 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "HeapMemsize", size, count); 850 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 851 int rc = alloc(count, size, heap_id_mask, NON_SECURE); 852 if (rc < 0) { 853 ATRACE_END(); 854 return rc; 855 } 856 857 for (int i = mBufferCount; i < count + mBufferCount; i ++) { 858 void *vaddr = mmap(NULL, 859 mMemInfo[i].size, 860 PROT_READ | PROT_WRITE, 861 MAP_SHARED, 862 mMemInfo[i].fd, 0); 863 if (vaddr == MAP_FAILED) { 864 for (int j = i-1; j >= mBufferCount; j --) { 865 munmap(mPtr[j], mMemInfo[j].size); 866 mPtr[j] = NULL; 867 deallocOneBuffer(mMemInfo[j]); 868 } 869 ATRACE_END(); 870 return NO_MEMORY; 871 } else { 872 mPtr[i] = vaddr; 873 } 874 } 875 mBufferCount = (uint8_t)(mBufferCount + count); 876 ATRACE_END(); 877 return OK; 878} 879 880/*=========================================================================== 881 * FUNCTION : deallocate 882 * 883 * DESCRIPTION: deallocate buffers 884 * 885 * PARAMETERS : none 886 * 887 * RETURN : none 888 *==========================================================================*/ 889void QCameraHeapMemory::deallocate() 890{ 891 for (int i = 0; i < mBufferCount; i++) { 892 munmap(mPtr[i], mMemInfo[i].size); 893 mPtr[i] = NULL; 894 } 895 dealloc(); 896 mBufferCount = 0; 897} 898 899/*=========================================================================== 900 * FUNCTION : cacheOps 901 * 902 * DESCRIPTION: ion related memory cache operations 903 * 904 * PARAMETERS : 905 * @index : index of the buffer 906 * @cmd : cache ops command 907 * 908 * RETURN : int32_t type of status 909 * NO_ERROR -- success 910 * none-zero failure code 911 *==========================================================================*/ 912int QCameraHeapMemory::cacheOps(uint32_t index, unsigned int cmd) 913{ 914 if (index >= mBufferCount) 915 return BAD_INDEX; 916 return cacheOpsInternal(index, cmd, mPtr[index]); 917} 918 919/*=========================================================================== 920 * FUNCTION : getRegFlags 921 * 922 * DESCRIPTION: query initial reg flags 923 * 924 * PARAMETERS : 925 * @regFlags: initial reg flags of the allocated buffers 926 * 927 * RETURN : int32_t type of status 928 * NO_ERROR -- success 929 * none-zero failure code 930 *==========================================================================*/ 931int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const 932{ 933 return INVALID_OPERATION; 934} 935 936/*=========================================================================== 937 * FUNCTION : getMemory 938 * 939 * DESCRIPTION: get camera memory 940 * 941 * PARAMETERS : 942 * @index : buffer index 943 * @metadata: flag if it's metadata 944 * 945 * RETURN : camera memory ptr 946 * NULL if not supported or failed 947 *==========================================================================*/ 948camera_memory_t *QCameraHeapMemory::getMemory(uint32_t /*index*/, bool /*metadata*/) const 949{ 950 return NULL; 951} 952 953/*=========================================================================== 954 * FUNCTION : getMatchBufIndex 955 * 956 * DESCRIPTION: query buffer index by opaque ptr 957 * 958 * PARAMETERS : 959 * @opaque : opaque ptr 960 * @metadata: flag if it's metadata 961 * 962 * RETURN : buffer index if match found, 963 * -1 if failed 964 *==========================================================================*/ 965int QCameraHeapMemory::getMatchBufIndex(const void *opaque, 966 bool metadata) const 967{ 968 int index = -1; 969 if (metadata) { 970 return -1; 971 } 972 for (int i = 0; i < mBufferCount; i++) { 973 if (mPtr[i] == opaque) { 974 index = i; 975 break; 976 } 977 } 978 return index; 979} 980 981/*=========================================================================== 982 * FUNCTION : QCameraMetadataStreamMemory 983 * 984 * DESCRIPTION: constructor of QCameraMetadataStreamMemory 985 * for ion memory used internally in HAL for metadata 986 * 987 * PARAMETERS : 988 * @cached : flag indicates if using cached memory 989 * 990 * RETURN : none 991 *==========================================================================*/ 992QCameraMetadataStreamMemory::QCameraMetadataStreamMemory(bool cached) 993 : QCameraHeapMemory(cached) 994{ 995} 996 997/*=========================================================================== 998 * FUNCTION : ~QCameraMetadataStreamMemory 999 * 1000 * DESCRIPTION: destructor of QCameraMetadataStreamMemory 1001 * 1002 * PARAMETERS : none 1003 * 1004 * RETURN : none 1005 *==========================================================================*/ 1006QCameraMetadataStreamMemory::~QCameraMetadataStreamMemory() 1007{ 1008 if (mBufferCount > 0) { 1009 LOGH("%s, buf_cnt > 0, deallocate buffers now.\n", __func__); 1010 deallocate(); 1011 } 1012} 1013 1014/*=========================================================================== 1015 * FUNCTION : getRegFlags 1016 * 1017 * DESCRIPTION: query initial reg flags 1018 * 1019 * PARAMETERS : 1020 * @regFlags: initial reg flags of the allocated buffers 1021 * 1022 * RETURN : int32_t type of status 1023 * NO_ERROR -- success 1024 * none-zero failure code 1025 *==========================================================================*/ 1026int QCameraMetadataStreamMemory::getRegFlags(uint8_t *regFlags) const 1027{ 1028 for (int i = 0; i < mBufferCount; i ++) { 1029 regFlags[i] = 1; 1030 } 1031 return NO_ERROR; 1032} 1033 1034/*=========================================================================== 1035 * FUNCTION : QCameraStreamMemory 1036 * 1037 * DESCRIPTION: constructor of QCameraStreamMemory 1038 * ION memory allocated directly from /dev/ion and shared with framework 1039 * 1040 * PARAMETERS : 1041 * @memory : camera memory request ops table 1042 * @cached : flag indicates if using cached memory 1043 * 1044 * RETURN : none 1045 *==========================================================================*/ 1046QCameraStreamMemory::QCameraStreamMemory(camera_request_memory memory, 1047 bool cached, 1048 QCameraMemoryPool *pool, 1049 cam_stream_type_t streamType, __unused cam_stream_buf_type bufType) 1050 :QCameraMemory(cached, pool, streamType), 1051 mGetMemory(memory) 1052{ 1053 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) 1054 mCameraMemory[i] = NULL; 1055} 1056 1057/*=========================================================================== 1058 * FUNCTION : ~QCameraStreamMemory 1059 * 1060 * DESCRIPTION: deconstructor of QCameraStreamMemory 1061 * 1062 * PARAMETERS : none 1063 * 1064 * RETURN : none 1065 *==========================================================================*/ 1066QCameraStreamMemory::~QCameraStreamMemory() 1067{ 1068} 1069 1070/*=========================================================================== 1071 * FUNCTION : allocate 1072 * 1073 * DESCRIPTION: allocate requested number of buffers of certain size 1074 * 1075 * PARAMETERS : 1076 * @count : number of buffers to be allocated 1077 * @size : lenght of the buffer to be allocated 1078 * 1079 * RETURN : int32_t type of status 1080 * NO_ERROR -- success 1081 * none-zero failure code 1082 *==========================================================================*/ 1083int QCameraStreamMemory::allocate(uint8_t count, size_t size, uint32_t isSecure) 1084{ 1085 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "StreamMemsize", size, count); 1086 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 1087 int rc = alloc(count, size, heap_id_mask, isSecure); 1088 if (rc < 0) { 1089 ATRACE_END(); 1090 return rc; 1091 } 1092 1093 for (int i = 0; i < count; i ++) { 1094 if (isSecure == SECURE) { 1095 mCameraMemory[i] = 0; 1096 } else { 1097 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this); 1098 } 1099 } 1100 mBufferCount = count; 1101 ATRACE_END(); 1102 return NO_ERROR; 1103} 1104 1105/*=========================================================================== 1106 * FUNCTION : allocateMore 1107 * 1108 * DESCRIPTION: allocate more requested number of buffers of certain size 1109 * 1110 * PARAMETERS : 1111 * @count : number of buffers to be allocated 1112 * @size : lenght of the buffer to be allocated 1113 * 1114 * RETURN : int32_t type of status 1115 * NO_ERROR -- success 1116 * none-zero failure code 1117 *==========================================================================*/ 1118int QCameraStreamMemory::allocateMore(uint8_t count, size_t size) 1119{ 1120 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "StreamMemsize", size, count); 1121 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 1122 int rc = alloc(count, size, heap_id_mask, NON_SECURE); 1123 if (rc < 0) { 1124 ATRACE_END(); 1125 return rc; 1126 } 1127 1128 for (int i = mBufferCount; i < mBufferCount + count; i++) { 1129 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this); 1130 } 1131 mBufferCount = (uint8_t)(mBufferCount + count); 1132 ATRACE_END(); 1133 return NO_ERROR; 1134} 1135 1136/*=========================================================================== 1137 * FUNCTION : deallocate 1138 * 1139 * DESCRIPTION: deallocate buffers 1140 * 1141 * PARAMETERS : none 1142 * 1143 * RETURN : none 1144 *==========================================================================*/ 1145void QCameraStreamMemory::deallocate() 1146{ 1147 for (int i = 0; i < mBufferCount; i ++) { 1148 if (mCameraMemory[i]) 1149 mCameraMemory[i]->release(mCameraMemory[i]); 1150 mCameraMemory[i] = NULL; 1151 } 1152 dealloc(); 1153 mBufferCount = 0; 1154} 1155 1156/*=========================================================================== 1157 * FUNCTION : cacheOps 1158 * 1159 * DESCRIPTION: ion related memory cache operations 1160 * 1161 * PARAMETERS : 1162 * @index : index of the buffer 1163 * @cmd : cache ops command 1164 * 1165 * RETURN : int32_t type of status 1166 * NO_ERROR -- success 1167 * none-zero failure code 1168 *==========================================================================*/ 1169int QCameraStreamMemory::cacheOps(uint32_t index, unsigned int cmd) 1170{ 1171 if (index >= mBufferCount) 1172 return BAD_INDEX; 1173 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data); 1174} 1175 1176/*=========================================================================== 1177 * FUNCTION : getRegFlags 1178 * 1179 * DESCRIPTION: query initial reg flags 1180 * 1181 * PARAMETERS : 1182 * @regFlags: initial reg flags of the allocated buffers 1183 * 1184 * RETURN : int32_t type of status 1185 * NO_ERROR -- success 1186 * none-zero failure code 1187 *==========================================================================*/ 1188int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const 1189{ 1190 for (int i = 0; i < mBufferCount; i ++) 1191 regFlags[i] = 1; 1192 return NO_ERROR; 1193} 1194 1195/*=========================================================================== 1196 * FUNCTION : getMemory 1197 * 1198 * DESCRIPTION: get camera memory 1199 * 1200 * PARAMETERS : 1201 * @index : buffer index 1202 * @metadata: flag if it's metadata 1203 * 1204 * RETURN : camera memory ptr 1205 * NULL if not supported or failed 1206 *==========================================================================*/ 1207camera_memory_t *QCameraStreamMemory::getMemory(uint32_t index, 1208 bool metadata) const 1209{ 1210 if (index >= mBufferCount || metadata) 1211 return NULL; 1212 return mCameraMemory[index]; 1213} 1214 1215/*=========================================================================== 1216 * FUNCTION : getMatchBufIndex 1217 * 1218 * DESCRIPTION: query buffer index by opaque ptr 1219 * 1220 * PARAMETERS : 1221 * @opaque : opaque ptr 1222 * @metadata: flag if it's metadata 1223 * 1224 * RETURN : buffer index if match found, 1225 * -1 if failed 1226 *==========================================================================*/ 1227int QCameraStreamMemory::getMatchBufIndex(const void *opaque, 1228 bool metadata) const 1229{ 1230 int index = -1; 1231 if (metadata) { 1232 return -1; 1233 } 1234 for (int i = 0; i < mBufferCount; i++) { 1235 if (mCameraMemory[i]->data == opaque) { 1236 index = i; 1237 break; 1238 } 1239 } 1240 return index; 1241} 1242 1243/*=========================================================================== 1244 * FUNCTION : getPtr 1245 * 1246 * DESCRIPTION: return buffer pointer 1247 * 1248 * PARAMETERS : 1249 * @index : index of the buffer 1250 * 1251 * RETURN : buffer ptr 1252 *==========================================================================*/ 1253void *QCameraStreamMemory::getPtr(uint32_t index) const 1254{ 1255 if (index >= mBufferCount) { 1256 LOGE("index out of bound"); 1257 return (void *)BAD_INDEX; 1258 } 1259 if (mCameraMemory[index] == 0) { 1260 return NULL; 1261 } 1262 return mCameraMemory[index]->data; 1263} 1264 1265/*=========================================================================== 1266 * FUNCTION : QCameraVideoMemory 1267 * 1268 * DESCRIPTION: constructor of QCameraVideoMemory 1269 * VideoStream buffers also include metadata buffers 1270 * 1271 * PARAMETERS : 1272 * @memory : camera memory request ops table 1273 * @cached : flag indicates if using cached ION memory 1274 * 1275 * RETURN : none 1276 *==========================================================================*/ 1277QCameraVideoMemory::QCameraVideoMemory(camera_request_memory memory, 1278 bool cached, QCameraMemType bufType) 1279 : QCameraStreamMemory(memory, cached) 1280{ 1281 memset(mMetadata, 0, sizeof(mMetadata)); 1282 mMetaBufCount = 0; 1283 mBufType = bufType; 1284 //Set Default color conversion format 1285 mUsage = private_handle_t::PRIV_FLAGS_ITU_R_709; 1286 1287 //Set Default frame format 1288 mFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1289} 1290 1291/*=========================================================================== 1292 * FUNCTION : ~QCameraVideoMemory 1293 * 1294 * DESCRIPTION: deconstructor of QCameraVideoMemory 1295 * 1296 * PARAMETERS : none 1297 * 1298 * RETURN : none 1299 *==========================================================================*/ 1300QCameraVideoMemory::~QCameraVideoMemory() 1301{ 1302} 1303 1304/*=========================================================================== 1305 * FUNCTION : allocate 1306 * 1307 * DESCRIPTION: allocate requested number of buffers of certain size 1308 * 1309 * PARAMETERS : 1310 * @count : number of buffers to be allocated 1311 * @size : lenght of the buffer to be allocated 1312 * 1313 * RETURN : int32_t type of status 1314 * NO_ERROR -- success 1315 * none-zero failure code 1316 *==========================================================================*/ 1317int QCameraVideoMemory::allocate(uint8_t count, size_t size, uint32_t isSecure) 1318{ 1319 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "VideoMemsize", size, count); 1320 int rc = QCameraStreamMemory::allocate(count, size, isSecure); 1321 if (rc < 0) { 1322 ATRACE_END(); 1323 return rc; 1324 } 1325 1326 if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) { 1327 /* 1328 * FDs = 1 1329 * numInts = 5 //offset, size, usage, timestamp, format 1330 */ 1331 rc = allocateMeta(count, 1, VIDEO_METADATA_NUM_INTS); 1332 if (rc != NO_ERROR) { 1333 ATRACE_END(); 1334 return rc; 1335 } 1336 for (int i = 0; i < count; i ++) { 1337 struct encoder_media_buffer_type * packet = 1338 (struct encoder_media_buffer_type *)mMetadata[i]->data; 1339 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 1340 if (!nh) { 1341 LOGE("Error in getting video native handle"); 1342 ATRACE_END(); 1343 return NO_MEMORY; 1344 } 1345 nh->data[0] = mMemInfo[i].fd; 1346 nh->data[1] = 0; 1347 nh->data[2] = (int)mMemInfo[i].size; 1348 nh->data[3] = mUsage; 1349 nh->data[4] = 0; //dummy value for timestamp in non-batch mode 1350 nh->data[5] = mFormat; 1351 } 1352 } 1353 mBufferCount = count; 1354 ATRACE_END(); 1355 return NO_ERROR; 1356} 1357 1358/*=========================================================================== 1359 * FUNCTION : allocateMore 1360 * 1361 * DESCRIPTION: allocate more requested number of buffers of certain size 1362 * 1363 * PARAMETERS : 1364 * @count : number of buffers to be allocated 1365 * @size : lenght of the buffer to be allocated 1366 * 1367 * RETURN : int32_t type of status 1368 * NO_ERROR -- success 1369 * none-zero failure code 1370 *==========================================================================*/ 1371int QCameraVideoMemory::allocateMore(uint8_t count, size_t size) 1372{ 1373 ATRACE_BEGIN_SNPRINTF("%s %zu %d", "VideoMemsize", size, count); 1374 int rc = QCameraStreamMemory::allocateMore(count, size); 1375 if (rc < 0) { 1376 ATRACE_END(); 1377 return rc; 1378 } 1379 1380 if (!(mBufType & QCAMERA_MEM_TYPE_BATCH)) { 1381 for (int i = mBufferCount; i < count + mBufferCount; i ++) { 1382 mMetadata[i] = mGetMemory(-1, 1383 sizeof(struct encoder_media_buffer_type), 1, this); 1384 if (!mMetadata[i]) { 1385 LOGE("allocation of video metadata failed."); 1386 for (int j = mBufferCount; j <= i-1; j ++) { 1387 mMetadata[j]->release(mMetadata[j]); 1388 mCameraMemory[j]->release(mCameraMemory[j]); 1389 mCameraMemory[j] = NULL; 1390 deallocOneBuffer(mMemInfo[j]);; 1391 } 1392 ATRACE_END(); 1393 return NO_MEMORY; 1394 } 1395 struct encoder_media_buffer_type * packet = 1396 (struct encoder_media_buffer_type *)mMetadata[i]->data; 1397 1398 //FDs = 1 1399 //numInts = 5 (offset, size, usage, timestamp, format) 1400 packet->meta_handle = native_handle_create(1, VIDEO_METADATA_NUM_INTS); 1401 packet->buffer_type = kMetadataBufferTypeCameraSource; 1402 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 1403 if (!nh) { 1404 LOGE("Error in getting video native handle"); 1405 ATRACE_END(); 1406 return NO_MEMORY; 1407 } 1408 nh->data[0] = mMemInfo[i].fd; 1409 nh->data[1] = 0; 1410 nh->data[2] = (int)mMemInfo[i].size; 1411 nh->data[3] = mUsage; 1412 nh->data[4] = 0; //dummy value for timestamp in non-batch mode 1413 nh->data[5] = mFormat; 1414 } 1415 } 1416 mBufferCount = (uint8_t)(mBufferCount + count); 1417 mMetaBufCount = mBufferCount; 1418 ATRACE_END(); 1419 return NO_ERROR; 1420} 1421 1422/*=========================================================================== 1423 * FUNCTION : allocateMeta 1424 * 1425 * DESCRIPTION: allocate video encoder metadata structure 1426 * 1427 * PARAMETERS : 1428 * @fd_cnt : Total FD count 1429 * 1430 * RETURN : int32_t type of status 1431 * NO_ERROR -- success 1432 * none-zero failure code 1433 *==========================================================================*/ 1434int QCameraVideoMemory::allocateMeta(uint8_t buf_cnt, int numFDs, int numInts) 1435{ 1436 int rc = NO_ERROR; 1437 1438 for (int i = 0; i < buf_cnt; i++) { 1439 mMetadata[i] = mGetMemory(-1, 1440 sizeof(struct encoder_media_buffer_type), 1, this); 1441 if (!mMetadata[i]) { 1442 LOGE("allocation of video metadata failed."); 1443 for (int j = (i - 1); j >= 0; j--) { 1444 mMetadata[j]->release(mMetadata[j]); 1445 } 1446 return NO_MEMORY; 1447 } 1448 struct encoder_media_buffer_type * packet = 1449 (struct encoder_media_buffer_type *)mMetadata[i]->data; 1450 packet->meta_handle = native_handle_create(numFDs, (numInts * numFDs)); 1451 packet->buffer_type = kMetadataBufferTypeCameraSource; 1452 if (packet->meta_handle == NULL) { 1453 LOGE("Error in getting video native handle"); 1454 for (int j = (i - 1); j >= 0; j--) { 1455 mMetadata[j]->release(mMetadata[j]); 1456 } 1457 return NO_MEMORY; 1458 } 1459 } 1460 mMetaBufCount = buf_cnt; 1461 return rc; 1462} 1463 1464/*=========================================================================== 1465 * FUNCTION : deallocateMeta 1466 * 1467 * DESCRIPTION: deallocate video metadata buffers 1468 * 1469 * PARAMETERS : none 1470 * 1471 * RETURN : none 1472 *==========================================================================*/ 1473void QCameraVideoMemory::deallocateMeta() 1474{ 1475 for (int i = 0; i < mMetaBufCount; i++) { 1476 struct encoder_media_buffer_type * packet = 1477 (struct encoder_media_buffer_type *)mMetadata[i]->data; 1478 if (NULL != packet) { 1479 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 1480 if (NULL != nh) { 1481 if (native_handle_delete(nh)) { 1482 LOGE("Unable to delete native handle"); 1483 } 1484 } else { 1485 LOGE("native handle not available"); 1486 } 1487 } else { 1488 LOGE("packet not available"); 1489 } 1490 mMetadata[i]->release(mMetadata[i]); 1491 mMetadata[i] = NULL; 1492 } 1493 mMetaBufCount = 0; 1494} 1495 1496 1497/*=========================================================================== 1498 * FUNCTION : deallocate 1499 * 1500 * DESCRIPTION: deallocate buffers 1501 * 1502 * PARAMETERS : none 1503 * 1504 * RETURN : none 1505 *==========================================================================*/ 1506void QCameraVideoMemory::deallocate() 1507{ 1508 deallocateMeta(); 1509 1510 QCameraStreamMemory::deallocate(); 1511 mBufferCount = 0; 1512 mMetaBufCount = 0; 1513} 1514 1515/*=========================================================================== 1516 * FUNCTION : getMemory 1517 * 1518 * DESCRIPTION: get camera memory 1519 * 1520 * PARAMETERS : 1521 * @index : buffer index 1522 * @metadata: flag if it's metadata 1523 * 1524 * RETURN : camera memory ptr 1525 * NULL if not supported or failed 1526 *==========================================================================*/ 1527camera_memory_t *QCameraVideoMemory::getMemory(uint32_t index, 1528 bool metadata) const 1529{ 1530 if (index >= mMetaBufCount || (!metadata && index >= mBufferCount)) 1531 return NULL; 1532 1533 if (metadata) 1534 return mMetadata[index]; 1535 else 1536 return mCameraMemory[index]; 1537} 1538 1539/*=========================================================================== 1540 * FUNCTION : getMatchBufIndex 1541 * 1542 * DESCRIPTION: query buffer index by opaque ptr 1543 * 1544 * PARAMETERS : 1545 * @opaque : opaque ptr 1546 * @metadata: flag if it's metadata 1547 * 1548 * RETURN : buffer index if match found, 1549 * -1 if failed 1550 *==========================================================================*/ 1551int QCameraVideoMemory::getMatchBufIndex(const void *opaque, 1552 bool metadata) const 1553{ 1554 int index = -1; 1555 1556 if (metadata) { 1557 for (int i = 0; i < mMetaBufCount; i++) { 1558 if (mMetadata[i]->data == opaque) { 1559 index = i; 1560 break; 1561 } 1562 } 1563 } else { 1564 for (int i = 0; i < mBufferCount; i++) { 1565 if (mCameraMemory[i]->data == opaque) { 1566 index = i; 1567 break; 1568 } 1569 } 1570 } 1571 return index; 1572} 1573 1574/*=========================================================================== 1575 * FUNCTION : setVideoInfo 1576 * 1577 * DESCRIPTION: set native window gralloc ops table 1578 * 1579 * PARAMETERS : 1580 * @usage : usage bit for video 1581 * 1582 * RETURN : none 1583 *==========================================================================*/ 1584void QCameraVideoMemory::setVideoInfo(int usage, cam_format_t format) 1585{ 1586 mUsage |= usage; 1587 mFormat = convCamtoOMXFormat(format); 1588} 1589 1590/*=========================================================================== 1591 * FUNCTION : convCamtoOMXFormat 1592 * 1593 * DESCRIPTION: map cam_format_t to corresponding OMX format 1594 * 1595 * PARAMETERS : 1596 * @format : format in cam_format_t type 1597 * 1598 * RETURN : omx format 1599 *==========================================================================*/ 1600int QCameraVideoMemory::convCamtoOMXFormat(cam_format_t format) 1601{ 1602 int omxFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1603 switch (format) { 1604 case CAM_FORMAT_YUV_420_NV21: 1605 case CAM_FORMAT_YUV_420_NV21_VENUS: 1606 case CAM_FORMAT_YUV_420_NV21_ADRENO: 1607 omxFormat = QOMX_COLOR_FormatYVU420SemiPlanar; 1608 break; 1609 case CAM_FORMAT_YUV_420_NV12: 1610 case CAM_FORMAT_YUV_420_NV12_VENUS: 1611 omxFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1612 break; 1613#ifndef VANILLA_HAL 1614 case CAM_FORMAT_YUV_420_NV12_UBWC: 1615 omxFormat = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed; 1616 break; 1617#endif 1618 default: 1619 omxFormat = OMX_COLOR_FormatYUV420SemiPlanar; 1620 } 1621 return omxFormat; 1622} 1623 1624/*=========================================================================== 1625 * FUNCTION : QCameraGrallocMemory 1626 * 1627 * DESCRIPTION: constructor of QCameraGrallocMemory 1628 * preview stream buffers are allocated from gralloc native_windoe 1629 * 1630 * PARAMETERS : 1631 * @memory : camera memory request ops table 1632 * 1633 * RETURN : none 1634 *==========================================================================*/ 1635QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory memory) 1636 : QCameraMemory(true), mColorSpace(ITU_R_601_FR) 1637{ 1638 mMinUndequeuedBuffers = 0; 1639 mMappableBuffers = 0; 1640 mWindow = NULL; 1641 mWidth = mHeight = mStride = mScanline = mUsage = 0; 1642 mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; 1643 mGetMemory = memory; 1644 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) { 1645 mBufferHandle[i] = NULL; 1646 mLocalFlag[i] = BUFFER_NOT_OWNED; 1647 mPrivateHandle[i] = NULL; 1648 } 1649} 1650 1651/*=========================================================================== 1652 * FUNCTION : ~QCameraGrallocMemory 1653 * 1654 * DESCRIPTION: deconstructor of QCameraGrallocMemory 1655 * 1656 * PARAMETERS : none 1657 * 1658 * RETURN : none 1659 *==========================================================================*/ 1660QCameraGrallocMemory::~QCameraGrallocMemory() 1661{ 1662} 1663 1664/*=========================================================================== 1665 * FUNCTION : setWindowInfo 1666 * 1667 * DESCRIPTION: set native window gralloc ops table 1668 * 1669 * PARAMETERS : 1670 * @window : gralloc ops table ptr 1671 * @width : width of preview frame 1672 * @height : height of preview frame 1673 * @stride : stride of preview frame 1674 * @scanline: scanline of preview frame 1675 * @foramt : format of preview image 1676 * @maxFPS : max fps of preview stream 1677 * @usage : usage bit for gralloc 1678 * 1679 * RETURN : none 1680 *==========================================================================*/ 1681void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window, 1682 int width, int height, int stride, int scanline, int format, int maxFPS, int usage) 1683{ 1684 mWindow = window; 1685 mWidth = width; 1686 mHeight = height; 1687 mStride = stride; 1688 mScanline = scanline; 1689 mFormat = format; 1690 mUsage = usage; 1691 setMaxFPS(maxFPS); 1692} 1693 1694/*=========================================================================== 1695 * FUNCTION : setMaxFPS 1696 * 1697 * DESCRIPTION: set max fps 1698 * 1699 * PARAMETERS : 1700 * @maxFPS : max fps of preview stream 1701 * 1702 * RETURN : none 1703 *==========================================================================*/ 1704void QCameraGrallocMemory::setMaxFPS(int maxFPS) 1705{ 1706 /* input will be in multiples of 1000 */ 1707 maxFPS = (maxFPS + 500)/1000; 1708 1709 /* set the lower cap to 30 always, because we are not supporting runtime update of fps info 1710 to display. Otherwise MDP may result in underruns (for example if initial fps is 15max and later 1711 changed to 30).*/ 1712 if (maxFPS < 30) { 1713 maxFPS = 30; 1714 } 1715 1716 /* the new fps will be updated in metadata of the next frame enqueued to display*/ 1717 mMaxFPS = maxFPS; 1718 LOGH("Setting max fps %d to display", mMaxFPS); 1719} 1720 1721/*=========================================================================== 1722 * FUNCTION : displayBuffer 1723 * 1724 * DESCRIPTION: send received frame to display 1725 * 1726 * PARAMETERS : 1727 * @index : index of preview frame 1728 * 1729 * RETURN : int32_t type of status 1730 * NO_ERROR -- success 1731 * none-zero failure code 1732 *==========================================================================*/ 1733int QCameraGrallocMemory::displayBuffer(uint32_t index) 1734{ 1735 int err = NO_ERROR; 1736 int dequeuedIdx = BAD_INDEX; 1737 1738 if (BUFFER_NOT_OWNED == mLocalFlag[index]) { 1739 LOGE("buffer to be enqueued is not owned"); 1740 return INVALID_OPERATION; 1741 } 1742 1743 err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]); 1744 if(err != 0) { 1745 LOGE("enqueue_buffer failed, err = %d", err); 1746 } else { 1747 LOGD("enqueue_buffer hdl=%p", *mBufferHandle[index]); 1748 mLocalFlag[index] = BUFFER_NOT_OWNED; 1749 } 1750 1751 buffer_handle_t *buffer_handle = NULL; 1752 int stride = 0; 1753 err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride); 1754 if (err == NO_ERROR && buffer_handle != NULL) { 1755 int i; 1756 LOGD("dequed buf hdl =%p", *buffer_handle); 1757 for(i = 0; i < mMappableBuffers; i++) { 1758 if(mBufferHandle[i] == buffer_handle) { 1759 LOGD("Found buffer in idx:%d", i); 1760 mLocalFlag[i] = BUFFER_OWNED; 1761 dequeuedIdx = i; 1762 break; 1763 } 1764 } 1765 1766 if ((dequeuedIdx == BAD_INDEX) && (mMappableBuffers < mBufferCount)) { 1767 dequeuedIdx = mMappableBuffers; 1768 LOGD("Placing buffer in idx:%d", dequeuedIdx); 1769 mBufferHandle[dequeuedIdx] = buffer_handle; 1770 mLocalFlag[dequeuedIdx] = BUFFER_OWNED; 1771 1772 mPrivateHandle[dequeuedIdx] = 1773 (struct private_handle_t *)(*mBufferHandle[dequeuedIdx]); 1774 mMemInfo[dequeuedIdx].main_ion_fd = open("/dev/ion", O_RDONLY); 1775 if (mMemInfo[dequeuedIdx].main_ion_fd < 0) { 1776 LOGE("failed: could not open ion device"); 1777 return BAD_INDEX; 1778 } 1779 1780 struct ion_fd_data ion_info_fd; 1781 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 1782 ion_info_fd.fd = mPrivateHandle[dequeuedIdx]->fd; 1783 if (ioctl(mMemInfo[dequeuedIdx].main_ion_fd, 1784 ION_IOC_IMPORT, &ion_info_fd) < 0) { 1785 LOGE("ION import failed\n"); 1786 return BAD_INDEX; 1787 } 1788 1789 mCameraMemory[dequeuedIdx] = 1790 mGetMemory(mPrivateHandle[dequeuedIdx]->fd, 1791 (size_t)mPrivateHandle[dequeuedIdx]->size, 1792 1, 1793 (void *)this); 1794 LOGH("idx = %d, fd = %d, size = %d, offset = %d", 1795 dequeuedIdx, mPrivateHandle[dequeuedIdx]->fd, 1796 mPrivateHandle[dequeuedIdx]->size, 1797 mPrivateHandle[dequeuedIdx]->offset); 1798 mMemInfo[dequeuedIdx].fd = mPrivateHandle[dequeuedIdx]->fd; 1799 mMemInfo[dequeuedIdx].size = 1800 (size_t)mPrivateHandle[dequeuedIdx]->size; 1801 mMemInfo[dequeuedIdx].handle = ion_info_fd.handle; 1802 1803 mMappableBuffers++; 1804 } 1805 } else { 1806 LOGW("dequeue_buffer, no free buffer from display now"); 1807 } 1808 return dequeuedIdx; 1809} 1810 1811/*=========================================================================== 1812 * FUNCTION : enqueueBuffer 1813 * 1814 * DESCRIPTION: enqueue camera frame to display 1815 * 1816 * PARAMETERS : 1817 * @index : index of frame 1818 * @timeStamp : frame presentation time 1819 * 1820 * RETURN : int32_t type of status 1821 * NO_ERROR -- success 1822 * none-zero failure code 1823 *==========================================================================*/ 1824int32_t QCameraGrallocMemory::enqueueBuffer(uint32_t index, nsecs_t timeStamp) 1825{ 1826 int32_t err = NO_ERROR; 1827 1828 if (BUFFER_NOT_OWNED == mLocalFlag[index]) { 1829 LOGE("buffer to be enqueued is not owned"); 1830 return INVALID_OPERATION; 1831 } 1832 1833 if (timeStamp != 0) { 1834 err = mWindow->set_timestamp(mWindow, timeStamp); 1835 if (err != NO_ERROR){ 1836 LOGE("Failed to native window timestamp"); 1837 } 1838 } 1839 1840 err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]); 1841 if(err != 0) { 1842 LOGE("enqueue_buffer failed, err = %d", err); 1843 } else { 1844 LOGD("enqueue_buffer hdl=%p", *mBufferHandle[index]); 1845 mLocalFlag[index] = BUFFER_NOT_OWNED; 1846 } 1847 return err; 1848} 1849 1850/*=========================================================================== 1851 * FUNCTION : dequeueBuffer 1852 * 1853 * DESCRIPTION: receive a buffer from gralloc 1854 * 1855 * PARAMETERS : None 1856 * 1857 * RETURN : int32_t 1858 * NO_ERROR/Buffer index : Success 1859 * < 0 failure code 1860 *==========================================================================*/ 1861int32_t QCameraGrallocMemory::dequeueBuffer() 1862{ 1863 int32_t err = NO_ERROR; 1864 int32_t dequeuedIdx = BAD_INDEX; 1865 buffer_handle_t *buffer_handle = NULL; 1866 int32_t stride = 0; 1867 1868 dequeuedIdx = BAD_INDEX; 1869 err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride); 1870 if ((err == NO_ERROR) && (buffer_handle != NULL)) { 1871 int i; 1872 LOGD("dequed buf hdl =%p", *buffer_handle); 1873 for(i = 0; i < mMappableBuffers; i++) { 1874 if(mBufferHandle[i] == buffer_handle) { 1875 LOGD("Found buffer in idx:%d", i); 1876 mLocalFlag[i] = BUFFER_OWNED; 1877 dequeuedIdx = i; 1878 break; 1879 } 1880 } 1881 1882 if ((dequeuedIdx == BAD_INDEX) && 1883 (mMappableBuffers < mBufferCount)) { 1884 dequeuedIdx = mMappableBuffers; 1885 LOGD("Placing buffer in idx:%d", dequeuedIdx); 1886 mBufferHandle[dequeuedIdx] = buffer_handle; 1887 mLocalFlag[dequeuedIdx] = BUFFER_OWNED; 1888 1889 mPrivateHandle[dequeuedIdx] = 1890 (struct private_handle_t *)(*mBufferHandle[dequeuedIdx]); 1891 //update max fps info 1892 setMetaData(mPrivateHandle[dequeuedIdx], UPDATE_REFRESH_RATE, (void*)&mMaxFPS); 1893 mMemInfo[dequeuedIdx].main_ion_fd = open("/dev/ion", O_RDONLY); 1894 if (mMemInfo[dequeuedIdx].main_ion_fd < 0) { 1895 LOGE("failed: could not open ion device"); 1896 return BAD_INDEX; 1897 } 1898 1899 struct ion_fd_data ion_info_fd; 1900 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 1901 ion_info_fd.fd = mPrivateHandle[dequeuedIdx]->fd; 1902 if (ioctl(mMemInfo[dequeuedIdx].main_ion_fd, 1903 ION_IOC_IMPORT, &ion_info_fd) < 0) { 1904 LOGE("ION import failed\n"); 1905 return BAD_INDEX; 1906 } 1907 1908 setMetaData(mPrivateHandle[dequeuedIdx], UPDATE_COLOR_SPACE, 1909 &mColorSpace); 1910 mCameraMemory[dequeuedIdx] = 1911 mGetMemory(mPrivateHandle[dequeuedIdx]->fd, 1912 (size_t)mPrivateHandle[dequeuedIdx]->size, 1913 1, 1914 (void *)this); 1915 LOGH("idx = %d, fd = %d, size = %d, offset = %d", 1916 dequeuedIdx, mPrivateHandle[dequeuedIdx]->fd, 1917 mPrivateHandle[dequeuedIdx]->size, 1918 mPrivateHandle[dequeuedIdx]->offset); 1919 mMemInfo[dequeuedIdx].fd = mPrivateHandle[dequeuedIdx]->fd; 1920 mMemInfo[dequeuedIdx].size = 1921 (size_t)mPrivateHandle[dequeuedIdx]->size; 1922 mMemInfo[dequeuedIdx].handle = ion_info_fd.handle; 1923 1924 mMappableBuffers++; 1925 } 1926 } else { 1927 LOGW("dequeue_buffer, no free buffer from display now"); 1928 } 1929 1930 return dequeuedIdx; 1931} 1932 1933 1934/*=========================================================================== 1935 * FUNCTION : allocate 1936 * 1937 * DESCRIPTION: allocate requested number of buffers of certain size 1938 * 1939 * PARAMETERS : 1940 * @count : number of buffers to be allocated 1941 * @size : lenght of the buffer to be allocated 1942 * 1943 * RETURN : int32_t type of status 1944 * NO_ERROR -- success 1945 * none-zero failure code 1946 *==========================================================================*/ 1947int QCameraGrallocMemory::allocate(uint8_t count, size_t /*size*/, 1948 uint32_t /*isSecure*/) 1949{ 1950 ATRACE_BEGIN_SNPRINTF("%s %d", "Grallocbufcnt", count); 1951 int err = 0; 1952 status_t ret = NO_ERROR; 1953 int gralloc_usage = 0; 1954 struct ion_fd_data ion_info_fd; 1955 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 1956 1957 LOGD("E "); 1958 1959 if (!mWindow) { 1960 LOGE("Invalid native window"); 1961 ATRACE_END(); 1962 ret = INVALID_OPERATION; 1963 goto end; 1964 } 1965 1966 // Increment buffer count by min undequeued buffer. 1967 err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers); 1968 if (err != 0) { 1969 LOGE("get_min_undequeued_buffer_count failed: %s (%d)", 1970 strerror(-err), -err); 1971 ret = UNKNOWN_ERROR; 1972 goto end; 1973 } 1974 1975 err = mWindow->set_buffer_count(mWindow, count); 1976 if (err != 0) { 1977 LOGE("set_buffer_count failed: %s (%d)", 1978 strerror(-err), -err); 1979 ret = UNKNOWN_ERROR; 1980 goto end; 1981 } 1982 1983 err = mWindow->set_buffers_geometry(mWindow, mStride, mScanline, mFormat); 1984 if (err != 0) { 1985 LOGE("set_buffers_geometry failed: %s (%d)", 1986 strerror(-err), -err); 1987 ret = UNKNOWN_ERROR; 1988 goto end; 1989 } 1990 1991 err = mWindow->set_crop(mWindow, 0, 0, mWidth, mHeight); 1992 if (err != 0) { 1993 LOGE("set_crop failed: %s (%d)", 1994 strerror(-err), -err); 1995 ret = UNKNOWN_ERROR; 1996 goto end; 1997 } 1998 1999 gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE; 2000 gralloc_usage |= mUsage; 2001 err = mWindow->set_usage(mWindow, gralloc_usage); 2002 if(err != 0) { 2003 /* set_usage error out */ 2004 LOGE("set_usage rc = %d", err); 2005 ret = UNKNOWN_ERROR; 2006 goto end; 2007 } 2008 LOGH("usage = %d, geometry: %p, %d, %d, %d, %d, %d", 2009 gralloc_usage, mWindow, mWidth, mHeight, mStride, 2010 mScanline, mFormat); 2011 2012 mBufferCount = count; 2013 if ((count < mMappableBuffers) || (mMappableBuffers == 0)) { 2014 mMappableBuffers = count; 2015 } 2016 2017 //Allocate cnt number of buffers from native window 2018 for (int cnt = 0; cnt < mMappableBuffers; cnt++) { 2019 int stride; 2020 err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride); 2021 if(!err) { 2022 LOGD("dequeue buf hdl =%p", mBufferHandle[cnt]); 2023 mLocalFlag[cnt] = BUFFER_OWNED; 2024 } else { 2025 mLocalFlag[cnt] = BUFFER_NOT_OWNED; 2026 LOGE("dequeue_buffer idx = %d err = %d", cnt, err); 2027 } 2028 2029 LOGD("dequeue buf: %p\n", mBufferHandle[cnt]); 2030 2031 if(err != 0) { 2032 LOGE("dequeue_buffer failed: %s (%d)", 2033 strerror(-err), -err); 2034 ret = UNKNOWN_ERROR; 2035 for(int i = 0; i < cnt; i++) { 2036 // Deallocate buffers when the native window is gone 2037 struct ion_handle_data ion_handle; 2038 memset(&ion_handle, 0, sizeof(ion_handle)); 2039 ion_handle.handle = mMemInfo[i].handle; 2040 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 2041 ALOGE("ion free failed"); 2042 } 2043 close(mMemInfo[i].main_ion_fd); 2044 2045 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 2046 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 2047 LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i])); 2048 } 2049 mLocalFlag[i] = BUFFER_NOT_OWNED; 2050 mBufferHandle[i] = NULL; 2051 } 2052 reset(); 2053 goto end; 2054 } 2055 2056 mPrivateHandle[cnt] = 2057 (struct private_handle_t *)(*mBufferHandle[cnt]); 2058 //update max fps info 2059 setMetaData(mPrivateHandle[cnt], UPDATE_REFRESH_RATE, (void*)&mMaxFPS); 2060 mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY); 2061 if (mMemInfo[cnt].main_ion_fd < 0) { 2062 LOGE("failed: could not open ion device"); 2063 for(int i = 0; i < cnt; i++) { 2064 struct ion_handle_data ion_handle; 2065 memset(&ion_handle, 0, sizeof(ion_handle)); 2066 ion_handle.handle = mMemInfo[i].handle; 2067 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 2068 LOGE("ion free failed"); 2069 } 2070 close(mMemInfo[i].main_ion_fd); 2071 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 2072 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 2073 LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i])); 2074 } 2075 mLocalFlag[i] = BUFFER_NOT_OWNED; 2076 mBufferHandle[i] = NULL; 2077 } 2078 reset(); 2079 ret = UNKNOWN_ERROR; 2080 goto end; 2081 } else { 2082 ion_info_fd.fd = mPrivateHandle[cnt]->fd; 2083 if (ioctl(mMemInfo[cnt].main_ion_fd, 2084 ION_IOC_IMPORT, &ion_info_fd) < 0) { 2085 LOGE("ION import failed\n"); 2086 for(int i = 0; i < cnt; i++) { 2087 struct ion_handle_data ion_handle; 2088 memset(&ion_handle, 0, sizeof(ion_handle)); 2089 ion_handle.handle = mMemInfo[i].handle; 2090 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 2091 LOGE("ion free failed"); 2092 } 2093 close(mMemInfo[i].main_ion_fd); 2094 2095 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 2096 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 2097 LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[i])); 2098 } 2099 mLocalFlag[i] = BUFFER_NOT_OWNED; 2100 mBufferHandle[i] = NULL; 2101 } 2102 close(mMemInfo[cnt].main_ion_fd); 2103 reset(); 2104 ret = UNKNOWN_ERROR; 2105 goto end; 2106 } 2107 } 2108 setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace); 2109 mCameraMemory[cnt] = 2110 mGetMemory(mPrivateHandle[cnt]->fd, 2111 (size_t)mPrivateHandle[cnt]->size, 2112 1, 2113 (void *)this); 2114 LOGH("idx = %d, fd = %d, size = %d, offset = %d", 2115 cnt, mPrivateHandle[cnt]->fd, 2116 mPrivateHandle[cnt]->size, 2117 mPrivateHandle[cnt]->offset); 2118 mMemInfo[cnt].fd = mPrivateHandle[cnt]->fd; 2119 mMemInfo[cnt].size = (size_t)mPrivateHandle[cnt]->size; 2120 mMemInfo[cnt].handle = ion_info_fd.handle; 2121 } 2122 2123 //Cancel min_undequeued_buffer buffers back to the window 2124 for (int i = 0; i < mMinUndequeuedBuffers; i ++) { 2125 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 2126 mLocalFlag[i] = BUFFER_NOT_OWNED; 2127 } 2128 2129end: 2130 if (ret != NO_ERROR) { 2131 mMappableBuffers = 0; 2132 } 2133 LOGD("X "); 2134 ATRACE_END(); 2135 return ret; 2136} 2137 2138 2139/*=========================================================================== 2140 * FUNCTION : allocateMore 2141 * 2142 * DESCRIPTION: allocate more requested number of buffers of certain size 2143 * 2144 * PARAMETERS : 2145 * @count : number of buffers to be allocated 2146 * @size : lenght of the buffer to be allocated 2147 * 2148 * RETURN : int32_t type of status 2149 * NO_ERROR -- success 2150 * none-zero failure code 2151 *==========================================================================*/ 2152int QCameraGrallocMemory::allocateMore(uint8_t /*count*/, size_t /*size*/) 2153{ 2154 LOGE("Not implenmented yet"); 2155 return UNKNOWN_ERROR; 2156} 2157 2158/*=========================================================================== 2159 * FUNCTION : deallocate 2160 * 2161 * DESCRIPTION: deallocate buffers 2162 * 2163 * PARAMETERS : none 2164 * 2165 * RETURN : none 2166 *==========================================================================*/ 2167void QCameraGrallocMemory::deallocate() 2168{ 2169 LOGD("E ", __FUNCTION__); 2170 2171 for (int cnt = 0; cnt < mMappableBuffers; cnt++) { 2172 mCameraMemory[cnt]->release(mCameraMemory[cnt]); 2173 struct ion_handle_data ion_handle; 2174 memset(&ion_handle, 0, sizeof(ion_handle)); 2175 ion_handle.handle = mMemInfo[cnt].handle; 2176 if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 2177 LOGE("ion free failed"); 2178 } 2179 close(mMemInfo[cnt].main_ion_fd); 2180 if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) { 2181 if (mWindow) { 2182 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]); 2183 LOGH("cancel_buffer: hdl =%p", (*mBufferHandle[cnt])); 2184 } else { 2185 LOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p", 2186 (*mBufferHandle[cnt])); 2187 } 2188 } 2189 mLocalFlag[cnt] = BUFFER_NOT_OWNED; 2190 LOGH("put buffer %d successfully", cnt); 2191 } 2192 mBufferCount = 0; 2193 mMappableBuffers = 0; 2194 LOGD("X ",__FUNCTION__); 2195} 2196 2197/*=========================================================================== 2198 * FUNCTION : cacheOps 2199 * 2200 * DESCRIPTION: ion related memory cache operations 2201 * 2202 * PARAMETERS : 2203 * @index : index of the buffer 2204 * @cmd : cache ops command 2205 * 2206 * RETURN : int32_t type of status 2207 * NO_ERROR -- success 2208 * none-zero failure code 2209 *==========================================================================*/ 2210int QCameraGrallocMemory::cacheOps(uint32_t index, unsigned int cmd) 2211{ 2212 if (index >= mMappableBuffers) 2213 return BAD_INDEX; 2214 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data); 2215} 2216 2217/*=========================================================================== 2218 * FUNCTION : getRegFlags 2219 * 2220 * DESCRIPTION: query initial reg flags 2221 * 2222 * PARAMETERS : 2223 * @regFlags: initial reg flags of the allocated buffers 2224 * 2225 * RETURN : int32_t type of status 2226 * NO_ERROR -- success 2227 * none-zero failure code 2228 *==========================================================================*/ 2229int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const 2230{ 2231 int i = 0; 2232 for (i = 0; i < mMinUndequeuedBuffers; i ++) 2233 regFlags[i] = 0; 2234 for (; i < mMappableBuffers; i ++) 2235 regFlags[i] = 1; 2236 for (; i < mBufferCount; i ++) 2237 regFlags[i] = 0; 2238 return NO_ERROR; 2239} 2240 2241/*=========================================================================== 2242 * FUNCTION : getMemory 2243 * 2244 * DESCRIPTION: get camera memory 2245 * 2246 * PARAMETERS : 2247 * @index : buffer index 2248 * @metadata: flag if it's metadata 2249 * 2250 * RETURN : camera memory ptr 2251 * NULL if not supported or failed 2252 *==========================================================================*/ 2253camera_memory_t *QCameraGrallocMemory::getMemory(uint32_t index, 2254 bool metadata) const 2255{ 2256 if (index >= mMappableBuffers || metadata) 2257 return NULL; 2258 return mCameraMemory[index]; 2259} 2260 2261/*=========================================================================== 2262 * FUNCTION : getMatchBufIndex 2263 * 2264 * DESCRIPTION: query buffer index by opaque ptr 2265 * 2266 * PARAMETERS : 2267 * @opaque : opaque ptr 2268 * @metadata: flag if it's metadata 2269 * 2270 * RETURN : buffer index if match found, 2271 * -1 if failed 2272 *==========================================================================*/ 2273int QCameraGrallocMemory::getMatchBufIndex(const void *opaque, 2274 bool metadata) const 2275{ 2276 int index = -1; 2277 if (metadata) { 2278 return -1; 2279 } 2280 for (int i = 0; i < mMappableBuffers; i++) { 2281 if (mCameraMemory[i]->data == opaque) { 2282 index = i; 2283 break; 2284 } 2285 } 2286 return index; 2287} 2288 2289/*=========================================================================== 2290 * FUNCTION : getPtr 2291 * 2292 * DESCRIPTION: return buffer pointer 2293 * 2294 * PARAMETERS : 2295 * @index : index of the buffer 2296 * 2297 * RETURN : buffer ptr 2298 *==========================================================================*/ 2299void *QCameraGrallocMemory::getPtr(uint32_t index) const 2300{ 2301 if (index >= mMappableBuffers) { 2302 LOGE("index out of bound"); 2303 return (void *)BAD_INDEX; 2304 } 2305 return mCameraMemory[index]->data; 2306} 2307 2308/*=========================================================================== 2309 * FUNCTION : setMappable 2310 * 2311 * DESCRIPTION: configure the number of buffers ready to map 2312 * 2313 * PARAMETERS : 2314 * @mappable : the number of desired mappable buffers 2315 * 2316 * RETURN : none 2317 *==========================================================================*/ 2318void QCameraGrallocMemory::setMappable(uint8_t mappable) 2319{ 2320 if (mMappableBuffers == 0) { 2321 mMappableBuffers = mappable; 2322 } 2323} 2324 2325/*=========================================================================== 2326 * FUNCTION : getMappable 2327 * 2328 * DESCRIPTION: query number of buffers already allocated 2329 * 2330 * PARAMETERS : none 2331 * 2332 * RETURN : number of buffers already allocated 2333 *==========================================================================*/ 2334uint8_t QCameraGrallocMemory::getMappable() const 2335{ 2336 return mMappableBuffers; 2337} 2338 2339/*=========================================================================== 2340 * FUNCTION : checkIfAllBuffersMapped 2341 * 2342 * DESCRIPTION: check if all buffers for the are mapped 2343 * 2344 * PARAMETERS : none 2345 * 2346 * RETURN : 1 if all buffers mapped 2347 * 0 if total buffers not equal to mapped buffers 2348 *==========================================================================*/ 2349uint8_t QCameraGrallocMemory::checkIfAllBuffersMapped() const 2350{ 2351 LOGH("mBufferCount: %d, mMappableBuffers: %d", 2352 mBufferCount, mMappableBuffers); 2353 return (mBufferCount == mMappableBuffers); 2354} 2355 2356 2357}; //namespace qcamera 2358