1 /* 2 * Copyright (C) Texas Instruments - http://www.ti.com/ 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifdef OMAP_ENHANCEMENT_CPCAM 18 19 #include "BufferSourceAdapter.h" 20 #include <ui/GraphicBuffer.h> 21 #include <ui/GraphicBufferMapper.h> 22 #include <hal_public.h> 23 24 namespace Ti { 25 namespace Camera { 26 27 static int getANWFormat(const char* parameters_format) 28 { 29 int format = HAL_PIXEL_FORMAT_TI_NV12; 30 31 if (parameters_format != NULL) { 32 if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { 33 CAMHAL_LOGDA("CbYCrY format selected"); 34 format = HAL_PIXEL_FORMAT_TI_UYVY; 35 } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 36 CAMHAL_LOGDA("YUV420SP format selected"); 37 format = HAL_PIXEL_FORMAT_TI_NV12; 38 } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_RGB565) == 0) { 39 CAMHAL_LOGDA("RGB565 format selected"); 40 // TODO(XXX): not defined yet 41 format = -1; 42 } else if (strcmp(parameters_format, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) { 43 format = HAL_PIXEL_FORMAT_TI_Y16; 44 } else { 45 CAMHAL_LOGDA("Invalid format, NV12 format selected as default"); 46 format = HAL_PIXEL_FORMAT_TI_NV12; 47 } 48 } 49 50 return format; 51 } 52 53 static int getUsageFromANW(int format) 54 { 55 int usage = GRALLOC_USAGE_SW_READ_RARELY | 56 GRALLOC_USAGE_SW_WRITE_NEVER; 57 58 switch (format) { 59 case HAL_PIXEL_FORMAT_TI_NV12: 60 case HAL_PIXEL_FORMAT_TI_Y16: 61 // This usage flag indicates to gralloc we want the 62 // buffers to come from system heap 63 usage |= GRALLOC_USAGE_PRIVATE_0; 64 break; 65 default: 66 // No special flags needed 67 break; 68 } 69 return usage; 70 } 71 72 static const char* getFormatFromANW(int format) 73 { 74 switch (format) { 75 case HAL_PIXEL_FORMAT_TI_NV12: 76 // Assuming NV12 1D is RAW or Image frame 77 return android::CameraParameters::PIXEL_FORMAT_YUV420SP; 78 case HAL_PIXEL_FORMAT_TI_Y16: 79 return android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB; 80 case HAL_PIXEL_FORMAT_TI_UYVY: 81 return android::CameraParameters::PIXEL_FORMAT_YUV422I; 82 default: 83 break; 84 } 85 return android::CameraParameters::PIXEL_FORMAT_YUV420SP; 86 } 87 88 static CameraFrame::FrameType formatToOutputFrameType(const char* format) { 89 switch (getANWFormat(format)) { 90 case HAL_PIXEL_FORMAT_TI_NV12: 91 case HAL_PIXEL_FORMAT_TI_Y16: 92 case HAL_PIXEL_FORMAT_TI_UYVY: 93 // Assuming NV12 1D is RAW or Image frame 94 return CameraFrame::RAW_FRAME; 95 default: 96 break; 97 } 98 return CameraFrame::RAW_FRAME; 99 } 100 101 static int getHeightFromFormat(const char* format, int stride, int size) { 102 CAMHAL_ASSERT((NULL != format) && (0 <= stride) && (0 <= size)); 103 switch (getANWFormat(format)) { 104 case HAL_PIXEL_FORMAT_TI_NV12: 105 return (size / (3 * stride)) * 2; 106 case HAL_PIXEL_FORMAT_TI_Y16: 107 case HAL_PIXEL_FORMAT_TI_UYVY: 108 return (size / stride) / 2; 109 default: 110 break; 111 } 112 return 0; 113 } 114 115 /*--------------------BufferSourceAdapter Class STARTS here-----------------------------*/ 116 117 118 ///Constant definitions 119 // TODO(XXX): Temporarily increase number of buffers we can allocate from ANW 120 // until faux-NPA mode is implemented 121 const int BufferSourceAdapter::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15; 122 123 /** 124 * Display Adapter class STARTS here.. 125 */ 126 BufferSourceAdapter::BufferSourceAdapter() : mBufferCount(0) 127 { 128 LOG_FUNCTION_NAME; 129 130 mPixelFormat = NULL; 131 mBuffers = NULL; 132 mFrameProvider = NULL; 133 mBufferSource = NULL; 134 135 mFrameWidth = 0; 136 mFrameHeight = 0; 137 mPreviewWidth = 0; 138 mPreviewHeight = 0; 139 140 LOG_FUNCTION_NAME_EXIT; 141 } 142 143 BufferSourceAdapter::~BufferSourceAdapter() 144 { 145 LOG_FUNCTION_NAME; 146 147 freeBufferList(mBuffers); 148 149 android::AutoMutex lock(mLock); 150 151 destroy(); 152 153 if (mFrameProvider) { 154 // Unregister with the frame provider 155 mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES); 156 delete mFrameProvider; 157 mFrameProvider = NULL; 158 } 159 160 if (mQueueFrame.get()) { 161 mQueueFrame->requestExit(); 162 mQueueFrame.clear(); 163 } 164 165 if (mReturnFrame.get()) { 166 mReturnFrame->requestExit(); 167 mReturnFrame.clear(); 168 } 169 170 LOG_FUNCTION_NAME_EXIT; 171 } 172 173 status_t BufferSourceAdapter::initialize() 174 { 175 status_t ret = NO_ERROR; 176 177 LOG_FUNCTION_NAME; 178 179 mReturnFrame.clear(); 180 mReturnFrame = new ReturnFrame(this); 181 mReturnFrame->run(); 182 183 mQueueFrame.clear(); 184 mQueueFrame = new QueueFrame(this); 185 mQueueFrame->run(); 186 187 LOG_FUNCTION_NAME_EXIT; 188 189 return ret; 190 } 191 192 int BufferSourceAdapter::setPreviewWindow(preview_stream_ops_t *source) 193 { 194 LOG_FUNCTION_NAME; 195 196 if (!source) { 197 CAMHAL_LOGEA("NULL window object passed to DisplayAdapter"); 198 LOG_FUNCTION_NAME_EXIT; 199 return BAD_VALUE; 200 } 201 202 if (mBufferSource) { 203 char id1[OP_STR_SIZE], id2[OP_STR_SIZE]; 204 status_t ret; 205 206 ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1)); 207 if (ret != 0) { 208 CAMHAL_LOGE("Surface::getId returned error %d", ret); 209 return ret; 210 } 211 212 ret = extendedOps()->get_id(source, id2, sizeof(id2)); 213 if (ret != 0) { 214 CAMHAL_LOGE("Surface::getId returned error %d", ret); 215 return ret; 216 } 217 if ((0 >= strlen(id1)) || (0 >= strlen(id2))) { 218 CAMHAL_LOGE("Cannot set ST without name: id1:\"%s\" id2:\"%s\"", 219 id1, id2); 220 return NOT_ENOUGH_DATA; 221 } 222 if (0 == strcmp(id1, id2)) { 223 return ALREADY_EXISTS; 224 } 225 226 // client has to unset mBufferSource before being able to set a new one 227 return BAD_VALUE; 228 } 229 230 // Move to new source obj 231 mBufferSource = source; 232 233 LOG_FUNCTION_NAME_EXIT; 234 235 return NO_ERROR; 236 } 237 238 bool BufferSourceAdapter::match(const char * str) { 239 char id1[OP_STR_SIZE]; 240 status_t ret; 241 242 ret = extendedOps()->get_id(mBufferSource, id1, sizeof(id1)); 243 244 if (ret != 0) { 245 CAMHAL_LOGE("Surface::getId returned error %d", ret); 246 } 247 248 return strcmp(id1, str) == 0; 249 } 250 251 int BufferSourceAdapter::setFrameProvider(FrameNotifier *frameProvider) 252 { 253 LOG_FUNCTION_NAME; 254 255 if ( !frameProvider ) { 256 CAMHAL_LOGEA("NULL passed for frame provider"); 257 LOG_FUNCTION_NAME_EXIT; 258 return BAD_VALUE; 259 } 260 261 if ( NULL != mFrameProvider ) { 262 delete mFrameProvider; 263 } 264 265 mFrameProvider = new FrameProvider(frameProvider, this, frameCallback); 266 267 LOG_FUNCTION_NAME_EXIT; 268 269 return NO_ERROR; 270 } 271 272 int BufferSourceAdapter::setErrorHandler(ErrorNotifier *errorNotifier) 273 { 274 status_t ret = NO_ERROR; 275 276 LOG_FUNCTION_NAME; 277 278 if ( NULL == errorNotifier ) { 279 CAMHAL_LOGEA("Invalid Error Notifier reference"); 280 return -EINVAL; 281 } 282 283 mErrorNotifier = errorNotifier; 284 285 LOG_FUNCTION_NAME_EXIT; 286 287 return ret; 288 } 289 290 int BufferSourceAdapter::enableDisplay(int width, int height, 291 struct timeval *refTime) 292 { 293 LOG_FUNCTION_NAME; 294 CameraFrame::FrameType frameType; 295 296 if (mFrameProvider == NULL) { 297 // no-op frame provider not set yet 298 return NO_ERROR; 299 } 300 301 if (mBufferSourceDirection == BUFFER_SOURCE_TAP_IN) { 302 // only supporting one type of input frame 303 frameType = CameraFrame::REPROCESS_INPUT_FRAME; 304 } else { 305 frameType = formatToOutputFrameType(mPixelFormat); 306 } 307 308 mFrameProvider->enableFrameNotification(frameType); 309 LOG_FUNCTION_NAME_EXIT; 310 311 return NO_ERROR; 312 } 313 314 int BufferSourceAdapter::disableDisplay(bool cancel_buffer) 315 { 316 LOG_FUNCTION_NAME; 317 318 if (mFrameProvider) mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES); 319 320 LOG_FUNCTION_NAME_EXIT; 321 322 return NO_ERROR; 323 } 324 325 status_t BufferSourceAdapter::pauseDisplay(bool pause) 326 { 327 status_t ret = NO_ERROR; 328 329 LOG_FUNCTION_NAME; 330 331 // no-op for BufferSourceAdapter 332 333 LOG_FUNCTION_NAME_EXIT; 334 335 return ret; 336 } 337 338 339 void BufferSourceAdapter::destroy() 340 { 341 LOG_FUNCTION_NAME; 342 343 mBufferCount = 0; 344 345 LOG_FUNCTION_NAME_EXIT; 346 } 347 348 CameraBuffer* BufferSourceAdapter::allocateBufferList(int width, int dummyHeight, const char* format, 349 int &bytes, int numBufs) 350 { 351 LOG_FUNCTION_NAME; 352 status_t err; 353 int i = -1; 354 const int lnumBufs = numBufs; 355 int undequeued = 0; 356 android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); 357 358 mBuffers = new CameraBuffer [lnumBufs]; 359 memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs); 360 361 if ( NULL == mBufferSource ) { 362 return NULL; 363 } 364 365 int pixFormat = getANWFormat(format); 366 int usage = getUsageFromANW(pixFormat); 367 mPixelFormat = CameraHal::getPixelFormatConstant(format); 368 369 // Set gralloc usage bits for window. 370 err = mBufferSource->set_usage(mBufferSource, usage); 371 if (err != 0) { 372 CAMHAL_LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err); 373 374 if ( ENODEV == err ) { 375 CAMHAL_LOGEA("Preview surface abandoned!"); 376 mBufferSource = NULL; 377 } 378 379 return NULL; 380 } 381 382 CAMHAL_LOGDB("Number of buffers set to BufferSourceAdapter %d", numBufs); 383 // Set the number of buffers needed for this buffer source 384 err = mBufferSource->set_buffer_count(mBufferSource, numBufs); 385 if (err != 0) { 386 CAMHAL_LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err); 387 388 if ( ENODEV == err ) { 389 CAMHAL_LOGEA("Preview surface abandoned!"); 390 mBufferSource = NULL; 391 } 392 393 return NULL; 394 } 395 396 CAMHAL_LOGDB("Configuring %d buffers for ANativeWindow", numBufs); 397 mBufferCount = numBufs; 398 399 // re-calculate height depending on stride and size 400 int height = getHeightFromFormat(format, width, bytes); 401 402 // Set window geometry 403 err = mBufferSource->set_buffers_geometry(mBufferSource, 404 width, height, 405 pixFormat); 406 407 if (err != 0) { 408 CAMHAL_LOGE("native_window_set_buffers_geometry failed: %s (%d)", strerror(-err), -err); 409 if ( ENODEV == err ) { 410 CAMHAL_LOGEA("Preview surface abandoned!"); 411 mBufferSource = NULL; 412 } 413 return NULL; 414 } 415 416 if ( mBuffers == NULL ) { 417 CAMHAL_LOGEA("Couldn't create array for ANativeWindow buffers"); 418 LOG_FUNCTION_NAME_EXIT; 419 return NULL; 420 } 421 422 mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued); 423 424 for (i = 0; i < mBufferCount; i++ ) { 425 buffer_handle_t *handle; 426 int stride; // dummy variable to get stride 427 // TODO(XXX): Do we need to keep stride information in camera hal? 428 429 err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride); 430 431 if (err != 0) { 432 CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 433 if ( ENODEV == err ) { 434 CAMHAL_LOGEA("Preview surface abandoned!"); 435 mBufferSource = NULL; 436 } 437 goto fail; 438 } 439 440 CAMHAL_LOGDB("got handle %p", handle); 441 mBuffers[i].opaque = (void *)handle; 442 mBuffers[i].type = CAMERA_BUFFER_ANW; 443 mBuffers[i].format = mPixelFormat; 444 mFramesWithCameraAdapterMap.add(handle, i); 445 446 bytes = CameraHal::calculateBufferSize(format, width, height); 447 } 448 449 for( i = 0; i < mBufferCount-undequeued; i++ ) { 450 void *y_uv[2]; 451 android::Rect bounds(width, height); 452 453 buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque; 454 mBufferSource->lock_buffer(mBufferSource, handle); 455 mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); 456 mBuffers[i].mapped = y_uv[0]; 457 } 458 459 // return the rest of the buffers back to ANativeWindow 460 for(i = (mBufferCount-undequeued); i >= 0 && i < mBufferCount; i++) { 461 buffer_handle_t *handle = (buffer_handle_t *) mBuffers[i].opaque; 462 void *y_uv[2]; 463 android::Rect bounds(width, height); 464 465 mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); 466 mBuffers[i].mapped = y_uv[0]; 467 mapper.unlock(*handle); 468 469 err = mBufferSource->cancel_buffer(mBufferSource, handle); 470 if (err != 0) { 471 CAMHAL_LOGEB("cancel_buffer failed: %s (%d)", strerror(-err), -err); 472 if ( ENODEV == err ) { 473 CAMHAL_LOGEA("Preview surface abandoned!"); 474 mBufferSource = NULL; 475 } 476 goto fail; 477 } 478 mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[i].opaque); 479 } 480 481 mFrameWidth = width; 482 mFrameHeight = height; 483 mBufferSourceDirection = BUFFER_SOURCE_TAP_OUT; 484 485 return mBuffers; 486 487 fail: 488 // need to cancel buffers if any were dequeued 489 for (int start = 0; start < i && i > 0; start++) { 490 int err = mBufferSource->cancel_buffer(mBufferSource, 491 (buffer_handle_t *) mBuffers[start].opaque); 492 if (err != 0) { 493 CAMHAL_LOGEB("cancelBuffer failed w/ error 0x%08x", err); 494 break; 495 } 496 mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) mBuffers[start].opaque); 497 } 498 499 freeBufferList(mBuffers); 500 501 CAMHAL_LOGEA("Error occurred, performing cleanup"); 502 503 if (NULL != mErrorNotifier.get()) { 504 mErrorNotifier->errorNotify(-ENOMEM); 505 } 506 507 LOG_FUNCTION_NAME_EXIT; 508 return NULL; 509 510 } 511 512 CameraBuffer *BufferSourceAdapter::getBuffers(bool reset) { 513 int undequeued = 0; 514 status_t err; 515 android::Mutex::Autolock lock(mLock); 516 517 if (!mBufferSource || !mBuffers) { 518 CAMHAL_LOGE("Adapter is not set up properly: " 519 "mBufferSource:%p mBuffers:%p", 520 mBufferSource, mBuffers); 521 goto fail; 522 } 523 524 // CameraHal is indicating to us that the state of the mBuffer 525 // might have changed. We might need to check the state of the 526 // buffer list and pass a new one depending on the state of our 527 // surface 528 if (reset) { 529 const int lnumBufs = mBufferCount; 530 android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); 531 android::Rect bounds(mFrameWidth, mFrameHeight); 532 void *y_uv[2]; 533 CameraBuffer * newBuffers = NULL; 534 unsigned int index = 0; 535 android::KeyedVector<void*, int> missingIndices; 536 537 newBuffers = new CameraBuffer [lnumBufs]; 538 memset (newBuffers, 0, sizeof(CameraBuffer) * lnumBufs); 539 540 // Use this vector to figure out missing indices 541 for (int i = 0; i < mBufferCount; i++) { 542 missingIndices.add(mBuffers[i].opaque, i); 543 } 544 545 // assign buffers that we have already dequeued 546 for (index = 0; index < mFramesWithCameraAdapterMap.size(); index++) { 547 int value = mFramesWithCameraAdapterMap.valueAt(index); 548 newBuffers[index].opaque = mBuffers[value].opaque; 549 newBuffers[index].type = mBuffers[value].type; 550 newBuffers[index].format = mBuffers[value].format; 551 newBuffers[index].mapped = mBuffers[value].mapped; 552 mFramesWithCameraAdapterMap.replaceValueAt(index, index); 553 missingIndices.removeItem(newBuffers[index].opaque); 554 } 555 556 mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeued); 557 558 // dequeue the rest of the buffers 559 for (index; index < (unsigned int)(mBufferCount-undequeued); index++) { 560 buffer_handle_t *handle; 561 int stride; // dummy variable to get stride 562 563 err = mBufferSource->dequeue_buffer(mBufferSource, &handle, &stride); 564 if (err != 0) { 565 CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 566 if ( ENODEV == err ) { 567 CAMHAL_LOGEA("Preview surface abandoned!"); 568 mBufferSource = NULL; 569 } 570 goto fail; 571 } 572 newBuffers[index].opaque = (void *)handle; 573 newBuffers[index].type = CAMERA_BUFFER_ANW; 574 newBuffers[index].format = mPixelFormat; 575 mFramesWithCameraAdapterMap.add(handle, index); 576 577 mBufferSource->lock_buffer(mBufferSource, handle); 578 mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); 579 newBuffers[index].mapped = y_uv[0]; 580 CAMHAL_LOGDB("got handle %p", handle); 581 582 missingIndices.removeItem(newBuffers[index].opaque); 583 } 584 585 // now we need to figure out which buffers aren't dequeued 586 // which are in mBuffers but not newBuffers yet 587 if ((mBufferCount - index) != missingIndices.size()) { 588 CAMHAL_LOGD("Hrmm somethings gone awry. We are missing a different number" 589 " of buffers than we can fill"); 590 } 591 for (unsigned int i = 0; i < missingIndices.size(); i++) { 592 int j = missingIndices.valueAt(i); 593 594 CAMHAL_LOGD("Filling at %d", j); 595 newBuffers[index].opaque = mBuffers[j].opaque; 596 newBuffers[index].type = mBuffers[j].type; 597 newBuffers[index].format = mBuffers[j].format; 598 newBuffers[index].mapped = mBuffers[j].mapped; 599 } 600 601 delete [] mBuffers; 602 mBuffers = newBuffers; 603 } 604 605 return mBuffers; 606 607 fail: 608 return NULL; 609 } 610 611 unsigned int BufferSourceAdapter::getSize() { 612 android::Mutex::Autolock lock(mLock); 613 return CameraHal::calculateBufferSize(mPixelFormat, mFrameWidth, mFrameHeight); 614 } 615 616 int BufferSourceAdapter::getBufferCount() { 617 int count = -1; 618 619 android::Mutex::Autolock lock(mLock); 620 if (mBufferSource) extendedOps()->get_buffer_count(mBufferSource, &count); 621 return count; 622 } 623 624 CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { 625 LOG_FUNCTION_NAME; 626 status_t err; 627 const int lnumBufs = 1; 628 int formatSource; 629 android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); 630 buffer_handle_t *handle; 631 632 // TODO(XXX): Only supporting one input buffer at a time right now 633 *num = 1; 634 mBuffers = new CameraBuffer [lnumBufs]; 635 memset (mBuffers, 0, sizeof(CameraBuffer) * lnumBufs); 636 637 if ( NULL == mBufferSource ) { 638 return NULL; 639 } 640 641 err = extendedOps()->update_and_get_buffer(mBufferSource, &handle, &mBuffers[0].stride); 642 if (err != 0) { 643 CAMHAL_LOGEB("update and get buffer failed: %s (%d)", strerror(-err), -err); 644 if ( ENODEV == err ) { 645 CAMHAL_LOGEA("Preview surface abandoned!"); 646 mBufferSource = NULL; 647 } 648 goto fail; 649 } 650 651 CAMHAL_LOGD("got handle %p", handle); 652 mBuffers[0].opaque = (void *)handle; 653 mBuffers[0].type = CAMERA_BUFFER_ANW; 654 mFramesWithCameraAdapterMap.add(handle, 0); 655 656 err = extendedOps()->get_buffer_dimension(mBufferSource, &mBuffers[0].width, &mBuffers[0].height); 657 err = extendedOps()->get_buffer_format(mBufferSource, &formatSource); 658 659 int t, l, r, b, w, h; 660 err = extendedOps()->get_crop(mBufferSource, &l, &t, &r, &b); 661 err = extendedOps()->get_current_size(mBufferSource, &w, &h); 662 663 // lock buffer 664 { 665 void *y_uv[2]; 666 android::Rect bounds(mBuffers[0].width, mBuffers[0].height); 667 mapper.lock(*handle, CAMHAL_GRALLOC_USAGE, bounds, y_uv); 668 mBuffers[0].mapped = y_uv[0]; 669 } 670 671 mFrameWidth = mBuffers[0].width; 672 mFrameHeight = mBuffers[0].height; 673 mPixelFormat = getFormatFromANW(formatSource); 674 675 mBuffers[0].format = mPixelFormat; 676 mBuffers[0].actual_size = CameraHal::calculateBufferSize(mPixelFormat, w, h); 677 mBuffers[0].offset = t * w + l * CameraHal::getBPP(mPixelFormat); 678 mBufferSourceDirection = BUFFER_SOURCE_TAP_IN; 679 680 return mBuffers; 681 682 fail: 683 // need to cancel buffers if any were dequeued 684 freeBufferList(mBuffers); 685 686 if (NULL != mErrorNotifier.get()) { 687 mErrorNotifier->errorNotify(-ENOMEM); 688 } 689 690 LOG_FUNCTION_NAME_EXIT; 691 return NULL; 692 } 693 694 uint32_t * BufferSourceAdapter::getOffsets() 695 { 696 LOG_FUNCTION_NAME; 697 698 LOG_FUNCTION_NAME_EXIT; 699 700 return NULL; 701 } 702 703 int BufferSourceAdapter::minUndequeueableBuffers(int& undequeueable) { 704 LOG_FUNCTION_NAME; 705 int ret = NO_ERROR; 706 707 if(!mBufferSource) 708 { 709 ret = INVALID_OPERATION; 710 goto end; 711 } 712 713 ret = mBufferSource->get_min_undequeued_buffer_count(mBufferSource, &undequeueable); 714 if ( NO_ERROR != ret ) { 715 CAMHAL_LOGEB("get_min_undequeued_buffer_count failed: %s (%d)", strerror(-ret), -ret); 716 if ( ENODEV == ret ) { 717 CAMHAL_LOGEA("Preview surface abandoned!"); 718 mBufferSource = NULL; 719 } 720 return -ret; 721 } 722 723 end: 724 return ret; 725 LOG_FUNCTION_NAME_EXIT; 726 727 } 728 729 int BufferSourceAdapter::maxQueueableBuffers(unsigned int& queueable) 730 { 731 LOG_FUNCTION_NAME; 732 int ret = NO_ERROR; 733 int undequeued = 0; 734 735 if(mBufferCount == 0) { 736 ret = INVALID_OPERATION; 737 goto end; 738 } 739 740 ret = minUndequeueableBuffers(undequeued); 741 if (ret != NO_ERROR) { 742 goto end; 743 } 744 745 queueable = mBufferCount - undequeued; 746 747 end: 748 return ret; 749 LOG_FUNCTION_NAME_EXIT; 750 } 751 752 int BufferSourceAdapter::getFd() 753 { 754 LOG_FUNCTION_NAME; 755 756 LOG_FUNCTION_NAME_EXIT; 757 758 return -1; 759 760 } 761 762 status_t BufferSourceAdapter::returnBuffersToWindow() 763 { 764 status_t ret = NO_ERROR; 765 android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); 766 767 //Give the buffers back to display here - sort of free it 768 if (mBufferSource) { 769 for(unsigned int i = 0; i < mFramesWithCameraAdapterMap.size(); i++) { 770 int value = mFramesWithCameraAdapterMap.valueAt(i); 771 buffer_handle_t *handle = (buffer_handle_t *) mBuffers[value].opaque; 772 773 // if buffer index is out of bounds skip 774 if ((value < 0) || (value >= mBufferCount)) { 775 CAMHAL_LOGEA("Potential out bounds access to handle...skipping"); 776 continue; 777 } 778 779 // unlock buffer before giving it up 780 mapper.unlock(*handle); 781 782 ret = mBufferSource->cancel_buffer(mBufferSource, handle); 783 if ( ENODEV == ret ) { 784 CAMHAL_LOGEA("Preview surface abandoned!"); 785 mBufferSource = NULL; 786 return -ret; 787 } else if ( NO_ERROR != ret ) { 788 CAMHAL_LOGEB("cancel_buffer() failed: %s (%d)", 789 strerror(-ret), 790 -ret); 791 return -ret; 792 } 793 } 794 } else { 795 CAMHAL_LOGE("mBufferSource is NULL"); 796 } 797 798 ///Clear the frames with camera adapter map 799 mFramesWithCameraAdapterMap.clear(); 800 801 return ret; 802 803 } 804 805 int BufferSourceAdapter::freeBufferList(CameraBuffer * buflist) 806 { 807 LOG_FUNCTION_NAME; 808 809 status_t ret = NO_ERROR; 810 811 if ( mBuffers != buflist ) { 812 return BAD_VALUE; 813 } 814 815 android::AutoMutex lock(mLock); 816 817 if (mBufferSourceDirection == BUFFER_SOURCE_TAP_OUT) returnBuffersToWindow(); 818 819 if( mBuffers != NULL) 820 { 821 delete [] mBuffers; 822 mBuffers = NULL; 823 } 824 825 return NO_ERROR; 826 } 827 828 829 bool BufferSourceAdapter::supportsExternalBuffering() 830 { 831 return false; 832 } 833 834 void BufferSourceAdapter::addFrame(CameraFrame* frame) 835 { 836 if (mQueueFrame.get()) { 837 mQueueFrame->addFrame(frame); 838 } 839 } 840 841 void BufferSourceAdapter::handleFrameCallback(CameraFrame* frame) 842 { 843 status_t ret = NO_ERROR; 844 buffer_handle_t *handle = NULL; 845 int i; 846 uint32_t x, y; 847 android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); 848 849 android::AutoMutex lock(mLock); 850 851 if (!mBuffers || !frame->mBuffer) { 852 CAMHAL_LOGEA("Adapter sent BufferSourceAdapter a NULL frame?"); 853 return; 854 } 855 856 for ( i = 0; i < mBufferCount; i++ ) { 857 if (frame->mBuffer == &mBuffers[i]) { 858 break; 859 } 860 } 861 862 if (i >= mBufferCount) { 863 CAMHAL_LOGD("Can't find frame in buffer list"); 864 if (frame->mFrameType != CameraFrame::REPROCESS_INPUT_FRAME) { 865 mFrameProvider->returnFrame(frame->mBuffer, 866 static_cast<CameraFrame::FrameType>(frame->mFrameType)); 867 } 868 return; 869 } 870 871 handle = (buffer_handle_t *) mBuffers[i].opaque; 872 873 // Handle input buffers 874 // TODO(XXX): Move handling of input buffers out of here if 875 // it becomes more complex 876 if (frame->mFrameType == CameraFrame::REPROCESS_INPUT_FRAME) { 877 CAMHAL_LOGD("Unlock %p (buffer #%d)", handle, i); 878 mapper.unlock(*handle); 879 return; 880 } 881 882 CameraHal::getXYFromOffset(&x, &y, frame->mOffset, frame->mAlignment, mPixelFormat); 883 CAMHAL_LOGVB("offset = %u left = %d top = %d right = %d bottom = %d", 884 frame->mOffset, x, y, x + frame->mWidth, y + frame->mHeight); 885 ret = mBufferSource->set_crop(mBufferSource, x, y, x + frame->mWidth, y + frame->mHeight); 886 if (NO_ERROR != ret) { 887 CAMHAL_LOGE("mBufferSource->set_crop returned error %d", ret); 888 goto fail; 889 } 890 891 if ( NULL != frame->mMetaData.get() ) { 892 camera_memory_t *extMeta = frame->mMetaData->getExtendedMetadata(); 893 if ( NULL != extMeta ) { 894 camera_metadata_t *metaData = static_cast<camera_metadata_t *> (extMeta->data); 895 metaData->timestamp = frame->mTimestamp; 896 ret = extendedOps()->set_metadata(mBufferSource, extMeta); 897 if (ret != 0) { 898 CAMHAL_LOGE("Surface::set_metadata returned error %d", ret); 899 goto fail; 900 } 901 } 902 } 903 904 // unlock buffer before enqueueing 905 mapper.unlock(*handle); 906 907 ret = mBufferSource->enqueue_buffer(mBufferSource, handle); 908 if (ret != 0) { 909 CAMHAL_LOGE("Surface::queueBuffer returned error %d", ret); 910 goto fail; 911 } 912 913 mFramesWithCameraAdapterMap.removeItem((buffer_handle_t *) frame->mBuffer->opaque); 914 915 return; 916 917 fail: 918 mFramesWithCameraAdapterMap.clear(); 919 mBufferSource = NULL; 920 mReturnFrame->requestExit(); 921 mQueueFrame->requestExit(); 922 } 923 924 925 bool BufferSourceAdapter::handleFrameReturn() 926 { 927 status_t err; 928 buffer_handle_t *buf; 929 int i = 0; 930 int stride; // dummy variable to get stride 931 CameraFrame::FrameType type; 932 android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get(); 933 void *y_uv[2]; 934 android::Rect bounds(mFrameWidth, mFrameHeight); 935 936 android::AutoMutex lock(mLock); 937 938 if ( (NULL == mBufferSource) || (NULL == mBuffers) ) { 939 return false; 940 } 941 942 err = mBufferSource->dequeue_buffer(mBufferSource, &buf, &stride); 943 if (err != 0) { 944 CAMHAL_LOGEB("dequeueBuffer failed: %s (%d)", strerror(-err), -err); 945 946 if ( ENODEV == err ) { 947 CAMHAL_LOGEA("Preview surface abandoned!"); 948 mBufferSource = NULL; 949 } 950 951 return false; 952 } 953 954 err = mBufferSource->lock_buffer(mBufferSource, buf); 955 if (err != 0) { 956 CAMHAL_LOGEB("lockbuffer failed: %s (%d)", strerror(-err), -err); 957 958 if ( ENODEV == err ) { 959 CAMHAL_LOGEA("Preview surface abandoned!"); 960 mBufferSource = NULL; 961 } 962 963 return false; 964 } 965 966 mapper.lock(*buf, CAMHAL_GRALLOC_USAGE, bounds, y_uv); 967 968 for(i = 0; i < mBufferCount; i++) { 969 if (mBuffers[i].opaque == buf) 970 break; 971 } 972 973 if (i >= mBufferCount) { 974 CAMHAL_LOGEB("Failed to find handle %p", buf); 975 } 976 977 mFramesWithCameraAdapterMap.add((buffer_handle_t *) mBuffers[i].opaque, i); 978 979 CAMHAL_LOGVB("handleFrameReturn: found graphic buffer %d of %d", i, mBufferCount - 1); 980 981 mFrameProvider->returnFrame(&mBuffers[i], formatToOutputFrameType(mPixelFormat)); 982 return true; 983 } 984 985 void BufferSourceAdapter::frameCallback(CameraFrame* caFrame) 986 { 987 if ((NULL != caFrame) && (NULL != caFrame->mCookie)) { 988 BufferSourceAdapter *da = (BufferSourceAdapter*) caFrame->mCookie; 989 da->addFrame(caFrame); 990 } else { 991 CAMHAL_LOGEB("Invalid Cookie in Camera Frame = %p, Cookie = %p", 992 caFrame, caFrame ? caFrame->mCookie : NULL); 993 } 994 } 995 996 /*--------------------BufferSourceAdapter Class ENDS here-----------------------------*/ 997 998 } // namespace Camera 999 } // namespace Ti 1000 1001 #endif 1002