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