QCameraMem.cpp revision 3de90b6340b8c7dedb86a220f86bc43d372d668e
1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30#define LOG_TAG "QCameraHWI_Mem" 31 32#include <string.h> 33#include <fcntl.h> 34#include <sys/mman.h> 35#include <utils/Log.h> 36#include <utils/Errors.h> 37#include <genlock.h> 38#include <gralloc_priv.h> 39#include <QComOMXMetadata.h> 40#include "QCameraMem.h" 41 42extern "C" { 43#include <mm_camera_interface.h> 44} 45 46using namespace android; 47 48namespace qcamera { 49 50// QCaemra2Memory base class 51 52QCameraMemory::QCameraMemory() 53{ 54 mBufferCount = 0; 55 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 56 mMemInfo[i].fd = 0; 57 mMemInfo[i].main_ion_fd = 0; 58 mMemInfo[i].handle = NULL; 59 mMemInfo[i].size = 0; 60 } 61} 62 63QCameraMemory::~QCameraMemory() 64{ 65} 66 67int QCameraMemory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr) 68{ 69 struct ion_flush_data cache_inv_data; 70 struct ion_custom_data custom_data; 71 int ret = OK; 72 73 if (index >= mBufferCount) { 74 ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount); 75 return BAD_INDEX; 76 } 77 78 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 79 memset(&custom_data, 0, sizeof(custom_data)); 80 cache_inv_data.vaddr = vaddr; 81 cache_inv_data.fd = mMemInfo[index].fd; 82 cache_inv_data.handle = mMemInfo[index].handle; 83 cache_inv_data.length = mMemInfo[index].size; 84 custom_data.cmd = cmd; 85 custom_data.arg = (unsigned long)&cache_inv_data; 86 87 ALOGD("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d", 88 __func__, cache_inv_data.vaddr, cache_inv_data.fd, 89 cache_inv_data.handle, cache_inv_data.length, 90 mMemInfo[index].main_ion_fd); 91 ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data); 92 if (ret < 0) 93 ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno)); 94 95 return ret; 96} 97 98int QCameraMemory::getFd(int index) const 99{ 100 if (index >= mBufferCount) 101 return BAD_INDEX; 102 103 return mMemInfo[index].fd; 104} 105 106int QCameraMemory::getSize(int index) const 107{ 108 if (index >= mBufferCount) 109 return BAD_INDEX; 110 111 return (int)mMemInfo[index].size; 112} 113 114int QCameraMemory::getCnt() const 115{ 116 return mBufferCount; 117} 118 119void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset, 120 mm_camera_buf_def_t &bufDef, int index) const 121{ 122 if (!mBufferCount) { 123 ALOGE("Memory not allocated"); 124 return; 125 } 126 bufDef.fd = mMemInfo[index].fd; 127 bufDef.frame_len = mMemInfo[index].size; 128 bufDef.mem_info = (void *)this; 129 bufDef.num_planes = offset.num_planes; 130 bufDef.buffer = getPtr(index); 131 bufDef.buf_idx = index; 132 133 /* Plane 0 needs to be set separately. Set other planes in a loop */ 134 bufDef.planes[0].length = offset.mp[0].len; 135 bufDef.planes[0].m.userptr = mMemInfo[index].fd; 136 bufDef.planes[0].data_offset = offset.mp[0].offset; 137 bufDef.planes[0].reserved[0] = 0; 138 for (int i = 1; i < bufDef.num_planes; i++) { 139 bufDef.planes[i].length = offset.mp[i].len; 140 bufDef.planes[i].m.userptr = mMemInfo[i].fd; 141 bufDef.planes[i].data_offset = offset.mp[i].offset; 142 bufDef.planes[i].reserved[0] = 143 bufDef.planes[i-1].reserved[0] + 144 bufDef.planes[i-1].length; 145 } 146} 147 148int QCameraMemory::alloc(int count, int size, int heap_id) 149{ 150 int rc = OK; 151 if (count > MM_CAMERA_MAX_NUM_FRAMES) { 152 ALOGE("Buffer count %d out of bound. Max is %d", count, MM_CAMERA_MAX_NUM_FRAMES); 153 return BAD_INDEX; 154 } 155 if (mBufferCount) { 156 ALOGE("Allocating a already allocated heap memory"); 157 return INVALID_OPERATION; 158 } 159 160 for (int i = 0; i < count; i ++) { 161 rc = allocOneBuffer(mMemInfo[i], heap_id, size); 162 if (rc < 0) { 163 ALOGE("AllocateIonMemory failed"); 164 for (int j = i-1; j >= 0; j--) 165 deallocOneBuffer(mMemInfo[j]); 166 break; 167 } 168 } 169 return rc; 170} 171 172void QCameraMemory::dealloc() 173{ 174 for (int i = 0; i < mBufferCount; i++) 175 deallocOneBuffer(mMemInfo[i]); 176} 177 178int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo, int heap_id, int size) 179{ 180 int rc = OK; 181 struct ion_handle_data handle_data; 182 struct ion_allocation_data alloc; 183 struct ion_fd_data ion_info_fd; 184 int main_ion_fd = 0; 185 186 main_ion_fd = open("/dev/ion", O_RDONLY); 187 if (main_ion_fd <= 0) { 188 ALOGE("Ion dev open failed: %s\n", strerror(errno)); 189 goto ION_OPEN_FAILED; 190 } 191 192 memset(&alloc, 0, sizeof(alloc)); 193 alloc.len = size; 194 /* to make it page size aligned */ 195 alloc.len = (alloc.len + 4095) & (~4095); 196 alloc.align = 4096; 197 alloc.flags = ION_FLAG_CACHED; 198 alloc.heap_mask = heap_id; 199 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc); 200 if (rc < 0) { 201 ALOGE("ION allocation failed: %s\n", strerror(errno)); 202 goto ION_ALLOC_FAILED; 203 } 204 205 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 206 ion_info_fd.handle = alloc.handle; 207 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 208 if (rc < 0) { 209 ALOGE("ION map failed %s\n", strerror(errno)); 210 goto ION_MAP_FAILED; 211 } 212 213 memInfo.main_ion_fd = main_ion_fd; 214 memInfo.fd = ion_info_fd.fd; 215 memInfo.handle = ion_info_fd.handle; 216 memInfo.size = alloc.len; 217 return OK; 218 219ION_MAP_FAILED: 220 memset(&handle_data, 0, sizeof(handle_data)); 221 handle_data.handle = ion_info_fd.handle; 222 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 223ION_ALLOC_FAILED: 224 close(main_ion_fd); 225ION_OPEN_FAILED: 226 return NO_MEMORY; 227} 228 229void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo) 230{ 231 struct ion_handle_data handle_data; 232 233 if (memInfo.fd > 0) { 234 close(memInfo.fd); 235 memInfo.fd = 0; 236 } 237 238 if (memInfo.main_ion_fd > 0) { 239 memset(&handle_data, 0, sizeof(handle_data)); 240 handle_data.handle = memInfo.handle; 241 ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data); 242 close(memInfo.main_ion_fd); 243 memInfo.main_ion_fd = 0; 244 } 245 memInfo.handle = NULL; 246 memInfo.size = 0; 247} 248 249// QCameraHeapMemory for ion memory used internally in HAL. 250QCameraHeapMemory::QCameraHeapMemory() 251 : QCameraMemory() 252{ 253 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) 254 mPtr[i] = NULL; 255} 256 257QCameraHeapMemory::~QCameraHeapMemory() 258{ 259} 260 261void *QCameraHeapMemory::getPtr(int index) const 262{ 263 if (index >= mBufferCount) { 264 ALOGE("index out of bound"); 265 return (void *)BAD_INDEX; 266 } 267 return mPtr[index]; 268} 269 270int QCameraHeapMemory::allocate(int count, int size) 271{ 272 int heap_mask = (0x1 << ION_CP_MM_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID); 273 int rc = alloc(count, size, heap_mask); 274 if (rc < 0) 275 return rc; 276 277 for (int i = 0; i < count; i ++) { 278 void *vaddr = mmap(NULL, 279 mMemInfo[i].size, 280 PROT_READ | PROT_WRITE, 281 MAP_SHARED, 282 mMemInfo[i].fd, 0); 283 if (vaddr == MAP_FAILED) { 284 for (int j = i-1; j >= 0; j --) { 285 munmap(mPtr[i], mMemInfo[i].size); 286 rc = NO_MEMORY; 287 break; 288 } 289 } else 290 mPtr[i] = vaddr; 291 } 292 if (rc == 0) 293 mBufferCount = count; 294 return OK; 295} 296 297void QCameraHeapMemory::deallocate() 298{ 299 for (int i = 0; i < mBufferCount; i++) { 300 munmap(mPtr[i], mMemInfo[i].size); 301 mPtr[i] = NULL; 302 } 303 dealloc(); 304 mBufferCount = 0; 305} 306 307int QCameraHeapMemory::cacheOps(int index, unsigned int cmd) 308{ 309 if (index >= mBufferCount) 310 return BAD_INDEX; 311 return cacheOpsInternal(index, cmd, mPtr[index]); 312} 313 314int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const 315{ 316 return INVALID_OPERATION; 317} 318 319camera_memory_t *QCameraHeapMemory::getMemory( 320 int /*index*/, bool /*metadata*/) const 321{ 322 return NULL; 323} 324 325int QCameraHeapMemory::getMatchBufIndex(const void *opaque, 326 bool metadata) const 327{ 328 int index = -1; 329 if (metadata) { 330 return -1; 331 } 332 for (int i = 0; i < mBufferCount; i++) { 333 if (mPtr[i] == opaque) { 334 index = i; 335 break; 336 } 337 } 338 return index; 339} 340 341 342// QCameraStreamMemory for ION memory allocated directly from /dev/ion 343// and shared with framework 344QCameraStreamMemory::QCameraStreamMemory(camera_request_memory getMemory) : 345 mGetMemory(getMemory) 346{ 347 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) 348 mCameraMemory[i] = NULL; 349} 350 351QCameraStreamMemory::~QCameraStreamMemory() 352{ 353} 354 355int QCameraStreamMemory::allocate(int count, int size) 356{ 357 int heap_mask = (0x1 << ION_CP_MM_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID); 358 int rc = alloc(count, size, heap_mask); 359 if (rc < 0) 360 return rc; 361 362 for (int i = 0; i < count; i ++) { 363 mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this); 364 } 365 mBufferCount = count; 366 return NO_ERROR; 367} 368 369void QCameraStreamMemory::deallocate() 370{ 371 for (int i = 0; i < mBufferCount; i ++) { 372 mCameraMemory[i]->release(mCameraMemory[i]); 373 mCameraMemory[i] = NULL; 374 } 375 dealloc(); 376 mBufferCount = 0; 377} 378 379int QCameraStreamMemory::cacheOps(int index, unsigned int cmd) 380{ 381 if (index >= mBufferCount) 382 return BAD_INDEX; 383 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data); 384} 385 386int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const 387{ 388 for (int i = 0; i < mBufferCount; i ++) 389 regFlags[i] = 1; 390 return NO_ERROR; 391} 392 393camera_memory_t *QCameraStreamMemory::getMemory(int index, bool metadata) const 394{ 395 if (index >= mBufferCount || metadata) 396 return NULL; 397 return mCameraMemory[index]; 398} 399 400int QCameraStreamMemory::getMatchBufIndex(const void *opaque, 401 bool metadata) const 402{ 403 int index = -1; 404 if (metadata) { 405 return -1; 406 } 407 for (int i = 0; i < mBufferCount; i++) { 408 if (mCameraMemory[i]->data == opaque) { 409 index = i; 410 break; 411 } 412 } 413 return index; 414} 415 416void *QCameraStreamMemory::getPtr(int index) const 417{ 418 if (index >= mBufferCount) { 419 ALOGE("index out of bound"); 420 return (void *)BAD_INDEX; 421 } 422 return mCameraMemory[index]->data; 423} 424 425QCameraVideoMemory::QCameraVideoMemory(camera_request_memory getMemory) 426 : QCameraStreamMemory(getMemory) 427{ 428 memset(mMetadata, 0, sizeof(mMetadata)); 429} 430 431QCameraVideoMemory::~QCameraVideoMemory() 432{ 433} 434 435int QCameraVideoMemory::allocate(int count, int size) 436{ 437 int rc = QCameraStreamMemory::allocate(count, size); 438 if (rc < 0) 439 return rc; 440 441 for (int i = 0; i < count; i ++) { 442 mMetadata[i] = mGetMemory(-1, 443 sizeof(struct encoder_media_buffer_type), 1, this); 444 if (!mMetadata[i]) { 445 ALOGE("allocation of video metadata failed."); 446 for (int j = 0; j < i-1; j ++) 447 mMetadata[j]->release(mMetadata[j]); 448 QCameraStreamMemory::deallocate(); 449 return NO_MEMORY; 450 } 451 struct encoder_media_buffer_type * packet = 452 (struct encoder_media_buffer_type *)mMetadata[i]->data; 453 packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size 454 packet->buffer_type = kMetadataBufferTypeCameraSource; 455 native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle); 456 nh->data[0] = mMemInfo[i].fd; 457 nh->data[1] = 0; 458 nh->data[2] = mMemInfo[i].size; 459 } 460 mBufferCount = count; 461 return NO_ERROR; 462} 463 464void QCameraVideoMemory::deallocate() 465{ 466 for (int i = 0; i < mBufferCount; i ++) { 467 mMetadata[i]->release(mMetadata[i]); 468 mMetadata[i] = NULL; 469 } 470 QCameraStreamMemory::dealloc(); 471 mBufferCount = 0; 472} 473 474camera_memory_t *QCameraVideoMemory::getMemory(int index, bool metadata) const 475{ 476 if (index >= mBufferCount) 477 return NULL; 478 if (metadata) 479 return mMetadata[index]; 480 else 481 return mCameraMemory[index]; 482} 483 484int QCameraVideoMemory::getMatchBufIndex(const void *opaque, 485 bool metadata) const 486{ 487 int index = -1; 488 for (int i = 0; i < mBufferCount; i++) { 489 if (metadata) { 490 if (mMetadata[i]->data == opaque) { 491 index = i; 492 break; 493 } 494 } else { 495 if (mCameraMemory[i]->data == opaque) { 496 index = i; 497 break; 498 } 499 } 500 } 501 return index; 502} 503 504// QCameraGrallocMemory for memory allocated from native_window 505QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory getMemory) 506 : QCameraMemory() 507{ 508 mMinUndequeuedBuffers = 0; 509 mWindow = NULL; 510 mWidth = mHeight = 0; 511 mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; 512 mGetMemory = getMemory; 513 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) { 514 mBufferHandle[i] = NULL; 515 mLocalFlag[i] = BUFFER_NOT_OWNED; 516 mPrivateHandle[i] = NULL; 517 } 518} 519 520QCameraGrallocMemory::~QCameraGrallocMemory() 521{ 522} 523 524void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window, 525 int width, int height, int format) 526{ 527 mWindow = window; 528 mWidth = width; 529 mHeight = height; 530 mFormat = format; 531} 532 533int QCameraGrallocMemory::displayBuffer(int index) 534{ 535 int err = NO_ERROR; 536 int dequeuedIdx = BAD_INDEX; 537 538 if (BUFFER_LOCKED == mLocalFlag[index]) { 539 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t*) 540 (*mBufferHandle[index]))) { 541 ALOGE("genlock_unlock_buffer failed"); 542 } else { 543 mLocalFlag[index] = BUFFER_UNLOCKED; 544 } 545 } else { 546 ALOGE("buffer to be enqueued is not locked"); 547 } 548 549 cleanInvalidateCache(index); 550 err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]); 551 if(err != 0) { 552 ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err); 553 } else { 554 ALOGV("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]); 555 mLocalFlag[index] = BUFFER_NOT_OWNED; 556 } 557 558 buffer_handle_t *buffer_handle = NULL; 559 int stride = 0; 560 err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride); 561 if (err == NO_ERROR && buffer_handle != NULL) { 562 int i; 563 ALOGV("%s: dequed buf hdl =%p", __func__, *buffer_handle); 564 for(i = 0; i < mBufferCount; i++) { 565 if(mBufferHandle[i] == buffer_handle) { 566 ALOGV("%s: Found buffer in idx:%d", __func__, i); 567 mLocalFlag[i] = BUFFER_UNLOCKED; 568 break; 569 } 570 } 571 if (i < mBufferCount ) { 572 err = mWindow->lock_buffer(mWindow, buffer_handle); 573 ALOGD("camera call genlock_lock: hdl =%p", *buffer_handle); 574 if (GENLOCK_FAILURE == genlock_lock_buffer((native_handle_t*) 575 (*buffer_handle), GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 576 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__); 577 } else { 578 mLocalFlag[i] = BUFFER_LOCKED; 579 dequeuedIdx = i; 580 } 581 } 582 } else { 583 ALOGD("%s: dequeue_buffer, no free buffer from display now", __func__); 584 } 585 return dequeuedIdx; 586} 587 588int QCameraGrallocMemory::allocate(int count, int /*size*/) 589{ 590 int err = 0; 591 status_t ret = NO_ERROR; 592 int gralloc_usage; 593 struct ion_fd_data ion_info_fd; 594 595 ALOGI(" %s : E ", __FUNCTION__); 596 597 if (!mWindow) { 598 ALOGE("Invalid native window"); 599 return INVALID_OPERATION; 600 } 601 602 // Increment buffer count by min undequeued buffer. 603 err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers); 604 if (err != 0) { 605 ALOGE("get_min_undequeued_buffer_count failed: %s (%d)", 606 strerror(-err), -err); 607 ret = UNKNOWN_ERROR; 608 goto end; 609 } 610 count += mMinUndequeuedBuffers; 611 612 err = mWindow->set_buffer_count(mWindow, count); 613 if (err != 0) { 614 ALOGE("set_buffer_count failed: %s (%d)", 615 strerror(-err), -err); 616 ret = UNKNOWN_ERROR; 617 goto end; 618 } 619 620 err = mWindow->set_buffers_geometry(mWindow, mWidth, mHeight, mFormat); 621 if (err != 0) { 622 ALOGE("%s: set_buffers_geometry failed: %s (%d)", 623 __func__, strerror(-err), -err); 624 ret = UNKNOWN_ERROR; 625 goto end; 626 } 627 628 gralloc_usage = GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; 629 err = mWindow->set_usage(mWindow, gralloc_usage); 630 if(err != 0) { 631 /* set_usage error out */ 632 ALOGE("%s: set_usage rc = %d", __func__, err); 633 ret = UNKNOWN_ERROR; 634 goto end; 635 } 636 ALOGD("%s: usage = %d, geometry: %p, %d, %d, %d", 637 __func__, gralloc_usage, mWindow, mWidth, mHeight, mFormat); 638 639 //Allocate cnt number of buffers from native window 640 for (int cnt = 0; cnt < count; cnt++) { 641 int stride; 642 err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride); 643 if(!err) { 644 ALOGV("dequeue buf hdl =%p", mBufferHandle[cnt]); 645 err = mWindow->lock_buffer(mWindow, mBufferHandle[cnt]); 646 // lock the buffer using genlock 647 ALOGV("camera call genlock_lock, hdl=%p", *mBufferHandle[cnt]); 648 if (GENLOCK_NO_ERROR != genlock_lock_buffer( 649 (native_handle_t *)(*mBufferHandle[cnt]), 650 GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { 651 ALOGE("%s: genlock_lock_buffer(WRITE) failed", __func__); 652 mLocalFlag[cnt] = BUFFER_UNLOCKED; 653 } else { 654 ALOGV("genlock_lock_buffer hdl =%p", *mBufferHandle[cnt]); 655 mLocalFlag[cnt] = BUFFER_LOCKED; 656 } 657 } else { 658 mLocalFlag[cnt] = BUFFER_NOT_OWNED; 659 ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err); 660 } 661 662 ALOGV("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]); 663 664 if(err != 0) { 665 ALOGE("%s: dequeue_buffer failed: %s (%d)", 666 __func__, strerror(-err), -err); 667 ret = UNKNOWN_ERROR; 668 for(int i = 0; i < cnt; i++) { 669 if (BUFFER_LOCKED == mLocalFlag[i]) { 670 ALOGD("%s: camera call genlock_unlock", __func__); 671 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 672 (*(mBufferHandle[i])))) { 673 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", 674 __func__, (*(mBufferHandle[i])) ); 675 } else { 676 mLocalFlag[i] = BUFFER_UNLOCKED; 677 } 678 } 679 if(mLocalFlag[i] != BUFFER_NOT_OWNED) { 680 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 681 ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i])); 682 } 683 mLocalFlag[i] = BUFFER_NOT_OWNED; 684 mBufferHandle[i] = NULL; 685 } 686 memset(&mMemInfo, 0, sizeof(mMemInfo)); 687 goto end; 688 } 689 690 mPrivateHandle[cnt] = 691 (struct private_handle_t *)(*mBufferHandle[cnt]); 692 mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY); 693 if (mMemInfo[cnt].main_ion_fd < 0) { 694 ALOGE("%s: failed: could not open ion device", __func__); 695 } else { 696 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 697 ion_info_fd.fd = mPrivateHandle[cnt]->fd; 698 if (ioctl(mMemInfo[cnt].main_ion_fd, 699 ION_IOC_IMPORT, &ion_info_fd) < 0) { 700 ALOGE("%s: ION import failed\n", __func__); 701 } 702 } 703 mCameraMemory[cnt] = 704 mGetMemory(mPrivateHandle[cnt]->fd, 705 mPrivateHandle[cnt]->size, 706 1, 707 (void *)this); 708 ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d", 709 __func__, cnt, mPrivateHandle[cnt]->fd, 710 mPrivateHandle[cnt]->size, 711 mPrivateHandle[cnt]->offset); 712 mMemInfo[cnt].fd = 713 mPrivateHandle[cnt]->fd; 714 mMemInfo[cnt].size = 715 mPrivateHandle[cnt]->size; 716 mMemInfo[cnt].handle = ion_info_fd.handle; 717 } 718 mBufferCount = count; 719 720 //Cancel min_undequeued_buffer buffers back to the window 721 for (int i = 0; i < mMinUndequeuedBuffers; i ++) { 722 if (BUFFER_LOCKED == mLocalFlag[i]) { 723 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 724 (*(mBufferHandle[i])))) { 725 ALOGE("%s: genlock_unlock_buffer failed: hdl =%p", 726 __func__, (*(mBufferHandle[i]))); 727 } else { 728 mLocalFlag[i] = BUFFER_UNLOCKED; 729 } 730 } 731 err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]); 732 mLocalFlag[i] = BUFFER_NOT_OWNED; 733 } 734 735end: 736 ALOGI(" %s : X ",__func__); 737 return ret; 738} 739 740void QCameraGrallocMemory::deallocate() 741{ 742 ALOGI("%s: E ", __FUNCTION__); 743 744 for (int cnt = 0; cnt < mBufferCount; cnt++) { 745 mCameraMemory[cnt]->release(mCameraMemory[cnt]); 746 struct ion_handle_data ion_handle; 747 memset(&ion_handle, 0, sizeof(ion_handle)); 748 ion_handle.handle = mMemInfo[cnt].handle; 749 if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 750 ALOGE("ion free failed"); 751 } 752 close(mMemInfo[cnt].main_ion_fd); 753 if (BUFFER_LOCKED == mLocalFlag[cnt]) { 754 ALOGD("camera call genlock_unlock"); 755 if (GENLOCK_FAILURE == genlock_unlock_buffer((native_handle_t *) 756 (*(mBufferHandle[cnt])))) { 757 ALOGE("genlock_unlock_buffer failed, handle =%p", 758 (*(mBufferHandle[cnt]))); 759 continue; 760 } else { 761 ALOGD("genlock_unlock_buffer, handle =%p", 762 (*(mBufferHandle[cnt]))); 763 mLocalFlag[cnt] = BUFFER_UNLOCKED; 764 } 765 } 766 if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) { 767 if (mWindow) { 768 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]); 769 ALOGD("cancel_buffer: hdl =%p", (*mBufferHandle[cnt])); 770 } else { 771 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p", 772 (*mBufferHandle[cnt])); 773 } 774 } 775 mLocalFlag[cnt] = BUFFER_NOT_OWNED; 776 ALOGD("put buffer %d successfully", cnt); 777 } 778 mBufferCount = 0; 779 ALOGI(" %s : X ",__FUNCTION__); 780} 781 782int QCameraGrallocMemory::cacheOps(int index, unsigned int cmd) 783{ 784 if (index >= mBufferCount) 785 return BAD_INDEX; 786 return cacheOpsInternal(index, cmd, mCameraMemory[index]->data); 787} 788 789int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const 790{ 791 int i = 0; 792 for (i = 0; i < mMinUndequeuedBuffers; i ++) 793 regFlags[i] = 0; 794 for (; i < mBufferCount; i ++) 795 regFlags[i] = 1; 796 return NO_ERROR; 797} 798 799camera_memory_t *QCameraGrallocMemory::getMemory(int index, bool metadata) const 800{ 801 if (index >= mBufferCount || metadata) 802 return NULL; 803 return mCameraMemory[index]; 804} 805 806int QCameraGrallocMemory::getMatchBufIndex(const void *opaque, 807 bool metadata) const 808{ 809 int index = -1; 810 if (metadata) { 811 return -1; 812 } 813 for (int i = 0; i < mBufferCount; i++) { 814 if (mCameraMemory[i]->data == opaque) { 815 index = i; 816 break; 817 } 818 } 819 return index; 820} 821 822void *QCameraGrallocMemory::getPtr(int index) const 823{ 824 if (index >= mBufferCount) { 825 ALOGE("index out of bound"); 826 return (void *)BAD_INDEX; 827 } 828 return mCameraMemory[index]->data; 829} 830 831}; //namespace qcamera 832