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 18 19 20 #define LOG_TAG "CameraHAL" 21 22 23 #include "CameraHal.h" 24 #include "VideoMetadata.h" 25 #include "Encoder_libjpeg.h" 26 #include <MetadataBufferType.h> 27 #include <ui/GraphicBuffer.h> 28 #include <ui/GraphicBufferMapper.h> 29 #include "NV12_resize.h" 30 31 namespace android { 32 33 const int AppCallbackNotifier::NOTIFIER_TIMEOUT = -1; 34 KeyedVector<void*, sp<Encoder_libjpeg> > gEncoderQueue; 35 36 void AppCallbackNotifierEncoderCallback(void* main_jpeg, 37 void* thumb_jpeg, 38 CameraFrame::FrameType type, 39 void* cookie1, 40 void* cookie2, 41 void* cookie3) 42 { 43 if (cookie1) { 44 AppCallbackNotifier* cb = (AppCallbackNotifier*) cookie1; 45 cb->EncoderDoneCb(main_jpeg, thumb_jpeg, type, cookie2, cookie3); 46 } 47 } 48 49 /*--------------------NotificationHandler Class STARTS here-----------------------------*/ 50 51 void AppCallbackNotifier::EncoderDoneCb(void* main_jpeg, void* thumb_jpeg, CameraFrame::FrameType type, void* cookie1, void* cookie2) 52 { 53 camera_memory_t* encoded_mem = NULL; 54 Encoder_libjpeg::params *main_param = NULL, *thumb_param = NULL; 55 size_t jpeg_size; 56 uint8_t* src = NULL; 57 sp<Encoder_libjpeg> encoder = NULL; 58 59 LOG_FUNCTION_NAME; 60 61 camera_memory_t* picture = NULL; 62 63 { 64 Mutex::Autolock lock(mLock); 65 66 if (!main_jpeg) { 67 goto exit; 68 } 69 70 encoded_mem = (camera_memory_t*) cookie1; 71 main_param = (Encoder_libjpeg::params *) main_jpeg; 72 jpeg_size = main_param->jpeg_size; 73 src = main_param->src; 74 75 if(encoded_mem && encoded_mem->data && (jpeg_size > 0)) { 76 if (cookie2) { 77 ExifElementsTable* exif = (ExifElementsTable*) cookie2; 78 Section_t* exif_section = NULL; 79 80 exif->insertExifToJpeg((unsigned char*) encoded_mem->data, jpeg_size); 81 82 if(thumb_jpeg) { 83 thumb_param = (Encoder_libjpeg::params *) thumb_jpeg; 84 exif->insertExifThumbnailImage((const char*)thumb_param->dst, 85 (int)thumb_param->jpeg_size); 86 } 87 88 exif_section = FindSection(M_EXIF); 89 90 if (exif_section) { 91 picture = mRequestMemory(-1, jpeg_size + exif_section->Size, 1, NULL); 92 if (picture && picture->data) { 93 exif->saveJpeg((unsigned char*) picture->data, jpeg_size + exif_section->Size); 94 } 95 } 96 delete exif; 97 cookie2 = NULL; 98 } else { 99 picture = mRequestMemory(-1, jpeg_size, 1, NULL); 100 if (picture && picture->data) { 101 memcpy(picture->data, encoded_mem->data, jpeg_size); 102 } 103 } 104 } 105 } // scope for mutex lock 106 107 if (!mRawAvailable) { 108 dummyRaw(); 109 } else { 110 mRawAvailable = false; 111 } 112 113 // Send the callback to the application only if the notifier is started and the message is enabled 114 if(picture && (mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED) && 115 (mCameraHal->msgTypeEnabled(CAMERA_MSG_COMPRESSED_IMAGE))) 116 { 117 Mutex::Autolock lock(mBurstLock); 118 #if 0 //TODO: enable burst mode later 119 if ( mBurst ) 120 { 121 `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie); 122 } 123 else 124 #endif 125 { 126 mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, picture, 0, NULL, mCallbackCookie); 127 } 128 } 129 130 exit: 131 132 if (main_jpeg) { 133 free(main_jpeg); 134 } 135 136 if (thumb_jpeg) { 137 if (((Encoder_libjpeg::params *) thumb_jpeg)->dst) { 138 free(((Encoder_libjpeg::params *) thumb_jpeg)->dst); 139 } 140 free(thumb_jpeg); 141 } 142 143 if (encoded_mem) { 144 encoded_mem->release(encoded_mem); 145 } 146 147 if (picture) { 148 picture->release(picture); 149 } 150 151 if (cookie2) { 152 delete (ExifElementsTable*) cookie2; 153 } 154 155 if (mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) { 156 encoder = gEncoderQueue.valueFor(src); 157 if (encoder.get()) { 158 gEncoderQueue.removeItem(src); 159 encoder.clear(); 160 } 161 mFrameProvider->returnFrame(src, type); 162 } 163 164 LOG_FUNCTION_NAME_EXIT; 165 } 166 167 /** 168 * NotificationHandler class 169 */ 170 171 ///Initialization function for AppCallbackNotifier 172 status_t AppCallbackNotifier::initialize() 173 { 174 LOG_FUNCTION_NAME; 175 176 mMeasurementEnabled = false; 177 178 ///Create the app notifier thread 179 mNotificationThread = new NotificationThread(this); 180 if(!mNotificationThread.get()) 181 { 182 CAMHAL_LOGEA("Couldn't create Notification thread"); 183 return NO_MEMORY; 184 } 185 186 ///Start the display thread 187 status_t ret = mNotificationThread->run("NotificationThread", PRIORITY_URGENT_DISPLAY); 188 if(ret!=NO_ERROR) 189 { 190 CAMHAL_LOGEA("Couldn't run NotificationThread"); 191 mNotificationThread.clear(); 192 return ret; 193 } 194 195 mUseMetaDataBufferMode = true; 196 mRawAvailable = false; 197 198 LOG_FUNCTION_NAME_EXIT; 199 200 return ret; 201 } 202 203 void AppCallbackNotifier::setCallbacks(CameraHal* cameraHal, 204 camera_notify_callback notify_cb, 205 camera_data_callback data_cb, 206 camera_data_timestamp_callback data_cb_timestamp, 207 camera_request_memory get_memory, 208 void *user) 209 { 210 Mutex::Autolock lock(mLock); 211 212 LOG_FUNCTION_NAME; 213 214 mCameraHal = cameraHal; 215 mNotifyCb = notify_cb; 216 mDataCb = data_cb; 217 mDataCbTimestamp = data_cb_timestamp; 218 mRequestMemory = get_memory; 219 mCallbackCookie = user; 220 221 LOG_FUNCTION_NAME_EXIT; 222 } 223 224 void AppCallbackNotifier::setMeasurements(bool enable) 225 { 226 Mutex::Autolock lock(mLock); 227 228 LOG_FUNCTION_NAME; 229 230 mMeasurementEnabled = enable; 231 232 if ( enable ) 233 { 234 mFrameProvider->enableFrameNotification(CameraFrame::FRAME_DATA_SYNC); 235 } 236 237 LOG_FUNCTION_NAME_EXIT; 238 } 239 240 241 //All sub-components of Camera HAL call this whenever any error happens 242 void AppCallbackNotifier::errorNotify(int error) 243 { 244 LOG_FUNCTION_NAME; 245 246 CAMHAL_LOGEB("AppCallbackNotifier received error %d", error); 247 248 // If it is a fatal error abort here! 249 if((error == CAMERA_ERROR_FATAL) || (error == CAMERA_ERROR_HARD)) { 250 //We kill media server if we encounter these errors as there is 251 //no point continuing and apps also don't handle errors other 252 //than media server death always. 253 abort(); 254 return; 255 } 256 257 if ( ( NULL != mCameraHal ) && 258 ( NULL != mNotifyCb ) && 259 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_ERROR) ) ) 260 { 261 CAMHAL_LOGEB("AppCallbackNotifier mNotifyCb %d", error); 262 mNotifyCb(CAMERA_MSG_ERROR, CAMERA_ERROR_UNKNOWN, 0, mCallbackCookie); 263 } 264 265 LOG_FUNCTION_NAME_EXIT; 266 } 267 268 bool AppCallbackNotifier::notificationThread() 269 { 270 bool shouldLive = true; 271 status_t ret; 272 273 LOG_FUNCTION_NAME; 274 275 //CAMHAL_LOGDA("Notification Thread waiting for message"); 276 ret = TIUTILS::MessageQueue::waitForMsg(&mNotificationThread->msgQ(), 277 &mEventQ, 278 &mFrameQ, 279 AppCallbackNotifier::NOTIFIER_TIMEOUT); 280 281 //CAMHAL_LOGDA("Notification Thread received message"); 282 283 if (mNotificationThread->msgQ().hasMsg()) { 284 ///Received a message from CameraHal, process it 285 CAMHAL_LOGDA("Notification Thread received message from Camera HAL"); 286 shouldLive = processMessage(); 287 if(!shouldLive) { 288 CAMHAL_LOGDA("Notification Thread exiting."); 289 } 290 } 291 292 if(mEventQ.hasMsg()) { 293 ///Received an event from one of the event providers 294 CAMHAL_LOGDA("Notification Thread received an event from event provider (CameraAdapter)"); 295 notifyEvent(); 296 } 297 298 if(mFrameQ.hasMsg()) { 299 ///Received a frame from one of the frame providers 300 //CAMHAL_LOGDA("Notification Thread received a frame from frame provider (CameraAdapter)"); 301 notifyFrame(); 302 } 303 304 LOG_FUNCTION_NAME_EXIT; 305 return shouldLive; 306 } 307 308 void AppCallbackNotifier::notifyEvent() 309 { 310 ///Receive and send the event notifications to app 311 TIUTILS::Message msg; 312 LOG_FUNCTION_NAME; 313 { 314 Mutex::Autolock lock(mLock); 315 mEventQ.get(&msg); 316 } 317 bool ret = true; 318 CameraHalEvent *evt = NULL; 319 CameraHalEvent::FocusEventData *focusEvtData; 320 CameraHalEvent::ZoomEventData *zoomEvtData; 321 CameraHalEvent::FaceEventData faceEvtData; 322 323 if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED) 324 { 325 return; 326 } 327 328 switch(msg.command) 329 { 330 case AppCallbackNotifier::NOTIFIER_CMD_PROCESS_EVENT: 331 332 evt = ( CameraHalEvent * ) msg.arg1; 333 334 if ( NULL == evt ) 335 { 336 CAMHAL_LOGEA("Invalid CameraHalEvent"); 337 return; 338 } 339 340 switch(evt->mEventType) 341 { 342 case CameraHalEvent::EVENT_SHUTTER: 343 344 if ( ( NULL != mCameraHal ) && 345 ( NULL != mNotifyCb ) && 346 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_SHUTTER) ) ) 347 { 348 mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); 349 } 350 mRawAvailable = false; 351 352 break; 353 354 case CameraHalEvent::EVENT_FOCUS_LOCKED: 355 case CameraHalEvent::EVENT_FOCUS_ERROR: 356 357 focusEvtData = &evt->mEventData->focusEvent; 358 if ( ( focusEvtData->focusLocked ) && 359 ( NULL != mCameraHal ) && 360 ( NULL != mNotifyCb ) && 361 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS) ) ) 362 { 363 mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); 364 mCameraHal->disableMsgType(CAMERA_MSG_FOCUS); 365 } 366 else if ( focusEvtData->focusError && 367 ( NULL != mCameraHal ) && 368 ( NULL != mNotifyCb ) && 369 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS) ) ) 370 { 371 mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie); 372 mCameraHal->disableMsgType(CAMERA_MSG_FOCUS); 373 } 374 375 break; 376 377 case CameraHalEvent::EVENT_ZOOM_INDEX_REACHED: 378 379 zoomEvtData = &evt->mEventData->zoomEvent; 380 381 if ( ( NULL != mCameraHal ) && 382 ( NULL != mNotifyCb) && 383 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_ZOOM) ) ) 384 { 385 mNotifyCb(CAMERA_MSG_ZOOM, zoomEvtData->currentZoomIndex, zoomEvtData->targetZoomIndexReached, mCallbackCookie); 386 } 387 388 break; 389 390 case CameraHalEvent::EVENT_FACE: 391 392 faceEvtData = evt->mEventData->faceEvent; 393 394 if ( ( NULL != mCameraHal ) && 395 ( NULL != mNotifyCb) && 396 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) ) ) 397 { 398 // WA for an issue inside CameraService 399 camera_memory_t *tmpBuffer = mRequestMemory(-1, 1, 1, NULL); 400 401 mDataCb(CAMERA_MSG_PREVIEW_METADATA, 402 tmpBuffer, 403 0, 404 faceEvtData->getFaceResult(), 405 mCallbackCookie); 406 407 faceEvtData.clear(); 408 409 if ( NULL != tmpBuffer ) { 410 tmpBuffer->release(tmpBuffer); 411 } 412 413 } 414 415 break; 416 417 case CameraHalEvent::ALL_EVENTS: 418 break; 419 default: 420 break; 421 } 422 423 break; 424 } 425 426 if ( NULL != evt ) 427 { 428 delete evt; 429 } 430 431 432 LOG_FUNCTION_NAME_EXIT; 433 434 } 435 436 static void copy2Dto1D(void *dst, 437 void *src, 438 int width, 439 int height, 440 size_t stride, 441 uint32_t offset, 442 unsigned int bytesPerPixel, 443 size_t length, 444 const char *pixelFormat) 445 { 446 unsigned int alignedRow, row; 447 unsigned char *bufferDst, *bufferSrc; 448 unsigned char *bufferDstEnd, *bufferSrcEnd; 449 uint16_t *bufferSrc_UV; 450 451 unsigned int *y_uv = (unsigned int *)src; 452 453 CAMHAL_LOGVB("copy2Dto1D() y= %p ; uv=%p.",y_uv[0], y_uv[1]); 454 CAMHAL_LOGVB("pixelFormat,= %d; offset=%d",*pixelFormat,offset); 455 456 if (pixelFormat!=NULL) { 457 if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { 458 bytesPerPixel = 2; 459 } else if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || 460 strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { 461 bytesPerPixel = 1; 462 bufferDst = ( unsigned char * ) dst; 463 bufferDstEnd = ( unsigned char * ) dst + width*height*bytesPerPixel; 464 bufferSrc = ( unsigned char * ) y_uv[0] + offset; 465 bufferSrcEnd = ( unsigned char * ) ( ( size_t ) y_uv[0] + length + offset); 466 row = width*bytesPerPixel; 467 alignedRow = stride-width; 468 int stride_bytes = stride / 8; 469 uint32_t xOff = offset % stride; 470 uint32_t yOff = offset / stride; 471 472 // going to convert from NV12 here and return 473 // Step 1: Y plane: iterate through each row and copy 474 for ( int i = 0 ; i < height ; i++) { 475 memcpy(bufferDst, bufferSrc, row); 476 bufferSrc += stride; 477 bufferDst += row; 478 if ( ( bufferSrc > bufferSrcEnd ) || ( bufferDst > bufferDstEnd ) ) { 479 break; 480 } 481 } 482 483 bufferSrc_UV = ( uint16_t * ) ((uint8_t*)y_uv[1] + (stride/2)*yOff + xOff); 484 485 if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 486 uint16_t *bufferDst_UV; 487 488 // Step 2: UV plane: convert NV12 to NV21 by swapping U & V 489 bufferDst_UV = (uint16_t *) (((uint8_t*)dst)+row*height); 490 491 for (int i = 0 ; i < height/2 ; i++, bufferSrc_UV += alignedRow/2) { 492 int n = width; 493 asm volatile ( 494 " pld [%[src], %[src_stride], lsl #2] \n\t" 495 " cmp %[n], #32 \n\t" 496 " blt 1f \n\t" 497 "0: @ 32 byte swap \n\t" 498 " sub %[n], %[n], #32 \n\t" 499 " vld2.8 {q0, q1} , [%[src]]! \n\t" 500 " vswp q0, q1 \n\t" 501 " cmp %[n], #32 \n\t" 502 " vst2.8 {q0,q1},[%[dst]]! \n\t" 503 " bge 0b \n\t" 504 "1: @ Is there enough data? \n\t" 505 " cmp %[n], #16 \n\t" 506 " blt 3f \n\t" 507 "2: @ 16 byte swap \n\t" 508 " sub %[n], %[n], #16 \n\t" 509 " vld2.8 {d0, d1} , [%[src]]! \n\t" 510 " vswp d0, d1 \n\t" 511 " cmp %[n], #16 \n\t" 512 " vst2.8 {d0,d1},[%[dst]]! \n\t" 513 " bge 2b \n\t" 514 "3: @ Is there enough data? \n\t" 515 " cmp %[n], #8 \n\t" 516 " blt 5f \n\t" 517 "4: @ 8 byte swap \n\t" 518 " sub %[n], %[n], #8 \n\t" 519 " vld2.8 {d0, d1} , [%[src]]! \n\t" 520 " vswp d0, d1 \n\t" 521 " cmp %[n], #8 \n\t" 522 " vst2.8 {d0[0],d1[0]},[%[dst]]! \n\t" 523 " bge 4b \n\t" 524 "5: @ end \n\t" 525 #ifdef NEEDS_ARM_ERRATA_754319_754320 526 " vmov s0,s0 @ add noop for errata item \n\t" 527 #endif 528 : [dst] "+r" (bufferDst_UV), [src] "+r" (bufferSrc_UV), [n] "+r" (n) 529 : [src_stride] "r" (stride_bytes) 530 : "cc", "memory", "q0", "q1" 531 ); 532 } 533 } else if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { 534 uint16_t *bufferDst_U; 535 uint16_t *bufferDst_V; 536 537 // Step 2: UV plane: convert NV12 to YV12 by de-interleaving U & V 538 // TODO(XXX): This version of CameraHal assumes NV12 format it set at 539 // camera adapter to support YV12. Need to address for 540 // USBCamera 541 542 bufferDst_V = (uint16_t *) (((uint8_t*)dst)+row*height); 543 bufferDst_U = (uint16_t *) (((uint8_t*)dst)+row*height+row*height/4); 544 545 for (int i = 0 ; i < height/2 ; i++, bufferSrc_UV += alignedRow/2) { 546 int n = width; 547 asm volatile ( 548 " pld [%[src], %[src_stride], lsl #2] \n\t" 549 " cmp %[n], #32 \n\t" 550 " blt 1f \n\t" 551 "0: @ 32 byte swap \n\t" 552 " sub %[n], %[n], #32 \n\t" 553 " vld2.8 {q0, q1} , [%[src]]! \n\t" 554 " cmp %[n], #32 \n\t" 555 " vst1.8 {q1},[%[dst_v]]! \n\t" 556 " vst1.8 {q0},[%[dst_u]]! \n\t" 557 " bge 0b \n\t" 558 "1: @ Is there enough data? \n\t" 559 " cmp %[n], #16 \n\t" 560 " blt 3f \n\t" 561 "2: @ 16 byte swap \n\t" 562 " sub %[n], %[n], #16 \n\t" 563 " vld2.8 {d0, d1} , [%[src]]! \n\t" 564 " cmp %[n], #16 \n\t" 565 " vst1.8 {d1},[%[dst_v]]! \n\t" 566 " vst1.8 {d0},[%[dst_u]]! \n\t" 567 " bge 2b \n\t" 568 "3: @ Is there enough data? \n\t" 569 " cmp %[n], #8 \n\t" 570 " blt 5f \n\t" 571 "4: @ 8 byte swap \n\t" 572 " sub %[n], %[n], #8 \n\t" 573 " vld2.8 {d0, d1} , [%[src]]! \n\t" 574 " cmp %[n], #8 \n\t" 575 " vst1.8 {d1[0]},[%[dst_v]]! \n\t" 576 " vst1.8 {d0[0]},[%[dst_u]]! \n\t" 577 " bge 4b \n\t" 578 "5: @ end \n\t" 579 #ifdef NEEDS_ARM_ERRATA_754319_754320 580 " vmov s0,s0 @ add noop for errata item \n\t" 581 #endif 582 : [dst_u] "+r" (bufferDst_U), [dst_v] "+r" (bufferDst_V), 583 [src] "+r" (bufferSrc_UV), [n] "+r" (n) 584 : [src_stride] "r" (stride_bytes) 585 : "cc", "memory", "q0", "q1" 586 ); 587 } 588 } 589 return ; 590 591 } else if(strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_RGB565) == 0) { 592 bytesPerPixel = 2; 593 } 594 } 595 596 bufferDst = ( unsigned char * ) dst; 597 bufferSrc = ( unsigned char * ) y_uv[0]; 598 row = width*bytesPerPixel; 599 alignedRow = ( row + ( stride -1 ) ) & ( ~ ( stride -1 ) ); 600 601 //iterate through each row 602 for ( int i = 0 ; i < height ; i++, bufferSrc += alignedRow, bufferDst += row) { 603 memcpy(bufferDst, bufferSrc, row); 604 } 605 } 606 607 void AppCallbackNotifier::copyAndSendPictureFrame(CameraFrame* frame, int32_t msgType) 608 { 609 camera_memory_t* picture = NULL; 610 void *dest = NULL, *src = NULL; 611 612 // scope for lock 613 { 614 Mutex::Autolock lock(mLock); 615 616 if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED) { 617 goto exit; 618 } 619 620 picture = mRequestMemory(-1, frame->mLength, 1, NULL); 621 622 if (NULL != picture) { 623 dest = picture->data; 624 if (NULL != dest) { 625 src = (void *) ((unsigned int) frame->mBuffer + frame->mOffset); 626 memcpy(dest, src, frame->mLength); 627 } 628 } 629 } 630 631 exit: 632 mFrameProvider->returnFrame(frame->mBuffer, (CameraFrame::FrameType) frame->mFrameType); 633 634 if(picture) { 635 if((mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) && 636 mCameraHal->msgTypeEnabled(msgType)) { 637 mDataCb(msgType, picture, 0, NULL, mCallbackCookie); 638 } 639 picture->release(picture); 640 } 641 } 642 643 void AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t msgType) 644 { 645 camera_memory_t* picture = NULL; 646 void* dest = NULL; 647 648 // scope for lock 649 { 650 Mutex::Autolock lock(mLock); 651 652 if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED) { 653 goto exit; 654 } 655 656 if (!mPreviewMemory || !frame->mBuffer) { 657 CAMHAL_LOGDA("Error! One of the buffer is NULL"); 658 goto exit; 659 } 660 661 662 dest = (void*) mPreviewBufs[mPreviewBufCount]; 663 664 CAMHAL_LOGVB("%d:copy2Dto1D(%p, %p, %d, %d, %d, %d, %d,%s)", 665 __LINE__, 666 buf, 667 frame->mBuffer, 668 frame->mWidth, 669 frame->mHeight, 670 frame->mAlignment, 671 2, 672 frame->mLength, 673 mPreviewPixelFormat); 674 675 if ( NULL != dest ) { 676 // data sync frames don't need conversion 677 if (CameraFrame::FRAME_DATA_SYNC == frame->mFrameType) { 678 if ( (mPreviewMemory->size / MAX_BUFFERS) >= frame->mLength ) { 679 memcpy(dest, (void*) frame->mBuffer, frame->mLength); 680 } else { 681 memset(dest, 0, (mPreviewMemory->size / MAX_BUFFERS)); 682 } 683 } else { 684 if ((NULL == frame->mYuv[0]) || (NULL == frame->mYuv[1])){ 685 CAMHAL_LOGEA("Error! One of the YUV Pointer is NULL"); 686 goto exit; 687 } 688 else{ 689 copy2Dto1D(dest, 690 frame->mYuv, 691 frame->mWidth, 692 frame->mHeight, 693 frame->mAlignment, 694 frame->mOffset, 695 2, 696 frame->mLength, 697 mPreviewPixelFormat); 698 } 699 } 700 } 701 } 702 703 exit: 704 mFrameProvider->returnFrame(frame->mBuffer, (CameraFrame::FrameType) frame->mFrameType); 705 706 if((mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) && 707 mCameraHal->msgTypeEnabled(msgType) && 708 (dest != NULL)) { 709 mDataCb(msgType, mPreviewMemory, mPreviewBufCount, NULL, mCallbackCookie); 710 } 711 712 // increment for next buffer 713 mPreviewBufCount = (mPreviewBufCount + 1) % AppCallbackNotifier::MAX_BUFFERS; 714 } 715 716 status_t AppCallbackNotifier::dummyRaw() 717 { 718 LOG_FUNCTION_NAME; 719 720 if ( NULL == mRequestMemory ) { 721 CAMHAL_LOGEA("Can't allocate memory for dummy raw callback!"); 722 return NO_INIT; 723 } 724 725 if ( ( NULL != mCameraHal ) && 726 ( NULL != mDataCb) && 727 ( NULL != mNotifyCb ) ){ 728 729 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE) ) { 730 camera_memory_t *dummyRaw = mRequestMemory(-1, 1, 1, NULL); 731 732 if ( NULL == dummyRaw ) { 733 CAMHAL_LOGEA("Dummy raw buffer allocation failed!"); 734 return NO_MEMORY; 735 } 736 737 mDataCb(CAMERA_MSG_RAW_IMAGE, dummyRaw, 0, NULL, mCallbackCookie); 738 739 dummyRaw->release(dummyRaw); 740 } else if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY) ) { 741 mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie); 742 } 743 } 744 745 LOG_FUNCTION_NAME_EXIT; 746 747 return NO_ERROR; 748 } 749 750 void AppCallbackNotifier::notifyFrame() 751 { 752 ///Receive and send the frame notifications to app 753 TIUTILS::Message msg; 754 CameraFrame *frame; 755 MemoryHeapBase *heap; 756 MemoryBase *buffer = NULL; 757 sp<MemoryBase> memBase; 758 void *buf = NULL; 759 760 LOG_FUNCTION_NAME; 761 762 { 763 Mutex::Autolock lock(mLock); 764 if(!mFrameQ.isEmpty()) { 765 mFrameQ.get(&msg); 766 } else { 767 return; 768 } 769 } 770 771 bool ret = true; 772 773 frame = NULL; 774 switch(msg.command) 775 { 776 case AppCallbackNotifier::NOTIFIER_CMD_PROCESS_FRAME: 777 778 frame = (CameraFrame *) msg.arg1; 779 if(!frame) 780 { 781 break; 782 } 783 784 if ( (CameraFrame::RAW_FRAME == frame->mFrameType )&& 785 ( NULL != mCameraHal ) && 786 ( NULL != mDataCb) && 787 ( NULL != mNotifyCb ) ) 788 { 789 790 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE) ) 791 { 792 #ifdef COPY_IMAGE_BUFFER 793 copyAndSendPictureFrame(frame, CAMERA_MSG_RAW_IMAGE); 794 #else 795 //TODO: Find a way to map a Tiler buffer to a MemoryHeapBase 796 #endif 797 } 798 else { 799 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY) ) { 800 mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie); 801 } 802 mFrameProvider->returnFrame(frame->mBuffer, 803 (CameraFrame::FrameType) frame->mFrameType); 804 } 805 806 mRawAvailable = true; 807 808 } 809 else if ( (CameraFrame::IMAGE_FRAME == frame->mFrameType) && 810 (NULL != mCameraHal) && 811 (NULL != mDataCb) && 812 (CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks) ) 813 { 814 815 int encode_quality = 100, tn_quality = 100; 816 int tn_width, tn_height; 817 unsigned int current_snapshot = 0; 818 Encoder_libjpeg::params *main_jpeg = NULL, *tn_jpeg = NULL; 819 void* exif_data = NULL; 820 camera_memory_t* raw_picture = mRequestMemory(-1, frame->mLength, 1, NULL); 821 822 if(raw_picture) { 823 buf = raw_picture->data; 824 } 825 826 CameraParameters parameters; 827 char *params = mCameraHal->getParameters(); 828 const String8 strParams(params); 829 parameters.unflatten(strParams); 830 831 encode_quality = parameters.getInt(CameraParameters::KEY_JPEG_QUALITY); 832 if (encode_quality < 0 || encode_quality > 100) { 833 encode_quality = 100; 834 } 835 836 tn_quality = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); 837 if (tn_quality < 0 || tn_quality > 100) { 838 tn_quality = 100; 839 } 840 841 if (CameraFrame::HAS_EXIF_DATA & frame->mQuirks) { 842 exif_data = frame->mCookie2; 843 } 844 845 main_jpeg = (Encoder_libjpeg::params*) 846 malloc(sizeof(Encoder_libjpeg::params)); 847 848 // Video snapshot with LDCNSF on adds a few bytes start offset 849 // and a few bytes on every line. They must be skipped. 850 int rightCrop = frame->mAlignment/2 - frame->mWidth; 851 852 CAMHAL_LOGDB("Video snapshot right crop = %d", rightCrop); 853 CAMHAL_LOGDB("Video snapshot offset = %d", frame->mOffset); 854 855 if (main_jpeg) { 856 main_jpeg->src = (uint8_t*) frame->mBuffer; 857 main_jpeg->src_size = frame->mLength; 858 main_jpeg->dst = (uint8_t*) buf; 859 main_jpeg->dst_size = frame->mLength; 860 main_jpeg->quality = encode_quality; 861 main_jpeg->in_width = frame->mAlignment/2; // use stride here 862 main_jpeg->in_height = frame->mHeight; 863 main_jpeg->out_width = frame->mAlignment/2; 864 main_jpeg->out_height = frame->mHeight; 865 main_jpeg->right_crop = rightCrop; 866 main_jpeg->start_offset = frame->mOffset; 867 main_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV422I; 868 } 869 870 tn_width = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); 871 tn_height = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); 872 873 if ((tn_width > 0) && (tn_height > 0)) { 874 tn_jpeg = (Encoder_libjpeg::params*) 875 malloc(sizeof(Encoder_libjpeg::params)); 876 // if malloc fails just keep going and encode main jpeg 877 if (!tn_jpeg) { 878 tn_jpeg = NULL; 879 } 880 } 881 882 if (tn_jpeg) { 883 int width, height; 884 parameters.getPreviewSize(&width,&height); 885 current_snapshot = (mPreviewBufCount + MAX_BUFFERS - 1) % MAX_BUFFERS; 886 tn_jpeg->src = (uint8_t*) mPreviewBufs[current_snapshot]; 887 tn_jpeg->src_size = mPreviewMemory->size / MAX_BUFFERS; 888 tn_jpeg->dst = (uint8_t*) malloc(tn_jpeg->src_size); 889 tn_jpeg->dst_size = tn_jpeg->src_size; 890 tn_jpeg->quality = tn_quality; 891 tn_jpeg->in_width = width; 892 tn_jpeg->in_height = height; 893 tn_jpeg->out_width = tn_width; 894 tn_jpeg->out_height = tn_height; 895 tn_jpeg->right_crop = 0; 896 tn_jpeg->start_offset = 0; 897 tn_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV420SP;; 898 } 899 900 sp<Encoder_libjpeg> encoder = new Encoder_libjpeg(main_jpeg, 901 tn_jpeg, 902 AppCallbackNotifierEncoderCallback, 903 (CameraFrame::FrameType)frame->mFrameType, 904 this, 905 raw_picture, 906 exif_data); 907 encoder->run(); 908 gEncoderQueue.add(frame->mBuffer, encoder); 909 encoder.clear(); 910 if (params != NULL) 911 { 912 mCameraHal->putParameters(params); 913 } 914 } 915 else if ( ( CameraFrame::IMAGE_FRAME == frame->mFrameType ) && 916 ( NULL != mCameraHal ) && 917 ( NULL != mDataCb) ) 918 { 919 920 // CTS, MTS requirements: Every 'takePicture()' call 921 // who registers a raw callback should receive one 922 // as well. This is not always the case with 923 // CameraAdapters though. 924 if (!mRawAvailable) { 925 dummyRaw(); 926 } else { 927 mRawAvailable = false; 928 } 929 930 #ifdef COPY_IMAGE_BUFFER 931 { 932 Mutex::Autolock lock(mBurstLock); 933 #if 0 //TODO: enable burst mode later 934 if ( mBurst ) 935 { 936 `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie); 937 } 938 else 939 #endif 940 { 941 copyAndSendPictureFrame(frame, CAMERA_MSG_COMPRESSED_IMAGE); 942 } 943 } 944 #else 945 //TODO: Find a way to map a Tiler buffer to a MemoryHeapBase 946 #endif 947 } 948 else if ( ( CameraFrame::VIDEO_FRAME_SYNC == frame->mFrameType ) && 949 ( NULL != mCameraHal ) && 950 ( NULL != mDataCb) && 951 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME) ) ) 952 { 953 mRecordingLock.lock(); 954 if(mRecording) 955 { 956 if(mUseMetaDataBufferMode) 957 { 958 camera_memory_t *videoMedatadaBufferMemory = 959 (camera_memory_t *) mVideoMetadataBufferMemoryMap.valueFor((uint32_t) frame->mBuffer); 960 video_metadata_t *videoMetadataBuffer = (video_metadata_t *) videoMedatadaBufferMemory->data; 961 962 if( (NULL == videoMedatadaBufferMemory) || (NULL == videoMetadataBuffer) || (NULL == frame->mBuffer) ) 963 { 964 CAMHAL_LOGEA("Error! One of the video buffers is NULL"); 965 break; 966 } 967 968 if ( mUseVideoBuffers ) 969 { 970 int vBuf = mVideoMap.valueFor((uint32_t) frame->mBuffer); 971 GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 972 Rect bounds; 973 bounds.left = 0; 974 bounds.top = 0; 975 bounds.right = mVideoWidth; 976 bounds.bottom = mVideoHeight; 977 978 void *y_uv[2]; 979 mapper.lock((buffer_handle_t)vBuf, CAMHAL_GRALLOC_USAGE, bounds, y_uv); 980 981 structConvImage input = {frame->mWidth, 982 frame->mHeight, 983 4096, 984 IC_FORMAT_YCbCr420_lp, 985 (mmByte *)frame->mYuv[0], 986 (mmByte *)frame->mYuv[1], 987 frame->mOffset}; 988 989 structConvImage output = {mVideoWidth, 990 mVideoHeight, 991 4096, 992 IC_FORMAT_YCbCr420_lp, 993 (mmByte *)y_uv[0], 994 (mmByte *)y_uv[1], 995 0}; 996 997 VT_resizeFrame_Video_opt2_lp(&input, &output, NULL, 0); 998 mapper.unlock((buffer_handle_t)vBuf); 999 videoMetadataBuffer->metadataBufferType = (int) kMetadataBufferTypeCameraSource; 1000 videoMetadataBuffer->handle = (void *)vBuf; 1001 videoMetadataBuffer->offset = 0; 1002 } 1003 else 1004 { 1005 videoMetadataBuffer->metadataBufferType = (int) kMetadataBufferTypeCameraSource; 1006 videoMetadataBuffer->handle = frame->mBuffer; 1007 videoMetadataBuffer->offset = frame->mOffset; 1008 } 1009 1010 CAMHAL_LOGVB("mDataCbTimestamp : frame->mBuffer=0x%x, videoMetadataBuffer=0x%x, videoMedatadaBufferMemory=0x%x", 1011 frame->mBuffer, videoMetadataBuffer, videoMedatadaBufferMemory); 1012 1013 mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME, 1014 videoMedatadaBufferMemory, 0, mCallbackCookie); 1015 } 1016 else 1017 { 1018 //TODO: Need to revisit this, should ideally be mapping the TILER buffer using mRequestMemory 1019 camera_memory_t* fakebuf = mRequestMemory(-1, 4, 1, NULL); 1020 if( (NULL == fakebuf) || ( NULL == fakebuf->data) || ( NULL == frame->mBuffer)) 1021 { 1022 CAMHAL_LOGEA("Error! One of the video buffers is NULL"); 1023 break; 1024 } 1025 1026 fakebuf->data = frame->mBuffer; 1027 mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME, fakebuf, 0, mCallbackCookie); 1028 fakebuf->release(fakebuf); 1029 } 1030 } 1031 mRecordingLock.unlock(); 1032 1033 } 1034 else if(( CameraFrame::SNAPSHOT_FRAME == frame->mFrameType ) && 1035 ( NULL != mCameraHal ) && 1036 ( NULL != mDataCb) && 1037 ( NULL != mNotifyCb)) { 1038 //When enabled, measurement data is sent instead of video data 1039 if ( !mMeasurementEnabled ) { 1040 copyAndSendPreviewFrame(frame, CAMERA_MSG_POSTVIEW_FRAME); 1041 } else { 1042 mFrameProvider->returnFrame(frame->mBuffer, 1043 (CameraFrame::FrameType) frame->mFrameType); 1044 } 1045 } 1046 else if ( ( CameraFrame::PREVIEW_FRAME_SYNC== frame->mFrameType ) && 1047 ( NULL != mCameraHal ) && 1048 ( NULL != mDataCb) && 1049 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) ) { 1050 //When enabled, measurement data is sent instead of video data 1051 if ( !mMeasurementEnabled ) { 1052 copyAndSendPreviewFrame(frame, CAMERA_MSG_PREVIEW_FRAME); 1053 } else { 1054 mFrameProvider->returnFrame(frame->mBuffer, 1055 (CameraFrame::FrameType) frame->mFrameType); 1056 } 1057 } 1058 else if ( ( CameraFrame::FRAME_DATA_SYNC == frame->mFrameType ) && 1059 ( NULL != mCameraHal ) && 1060 ( NULL != mDataCb) && 1061 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) ) { 1062 copyAndSendPreviewFrame(frame, CAMERA_MSG_PREVIEW_FRAME); 1063 } else { 1064 mFrameProvider->returnFrame(frame->mBuffer, 1065 ( CameraFrame::FrameType ) frame->mFrameType); 1066 CAMHAL_LOGDB("Frame type 0x%x is still unsupported!", frame->mFrameType); 1067 } 1068 1069 break; 1070 1071 default: 1072 1073 break; 1074 1075 }; 1076 1077 exit: 1078 1079 if ( NULL != frame ) 1080 { 1081 delete frame; 1082 } 1083 1084 LOG_FUNCTION_NAME_EXIT; 1085 } 1086 1087 void AppCallbackNotifier::frameCallbackRelay(CameraFrame* caFrame) 1088 { 1089 LOG_FUNCTION_NAME; 1090 AppCallbackNotifier *appcbn = (AppCallbackNotifier*) (caFrame->mCookie); 1091 appcbn->frameCallback(caFrame); 1092 LOG_FUNCTION_NAME_EXIT; 1093 } 1094 1095 void AppCallbackNotifier::frameCallback(CameraFrame* caFrame) 1096 { 1097 ///Post the event to the event queue of AppCallbackNotifier 1098 TIUTILS::Message msg; 1099 CameraFrame *frame; 1100 1101 LOG_FUNCTION_NAME; 1102 1103 if ( NULL != caFrame ) 1104 { 1105 1106 frame = new CameraFrame(*caFrame); 1107 if ( NULL != frame ) 1108 { 1109 msg.command = AppCallbackNotifier::NOTIFIER_CMD_PROCESS_FRAME; 1110 msg.arg1 = frame; 1111 mFrameQ.put(&msg); 1112 } 1113 else 1114 { 1115 CAMHAL_LOGEA("Not enough resources to allocate CameraFrame"); 1116 } 1117 1118 } 1119 1120 LOG_FUNCTION_NAME_EXIT; 1121 } 1122 1123 void AppCallbackNotifier::flushAndReturnFrames() 1124 { 1125 TIUTILS::Message msg; 1126 CameraFrame *frame; 1127 1128 Mutex::Autolock lock(mLock); 1129 while (!mFrameQ.isEmpty()) { 1130 mFrameQ.get(&msg); 1131 frame = (CameraFrame*) msg.arg1; 1132 if (frame) { 1133 mFrameProvider->returnFrame(frame->mBuffer, 1134 (CameraFrame::FrameType) frame->mFrameType); 1135 } 1136 } 1137 1138 LOG_FUNCTION_NAME_EXIT; 1139 } 1140 1141 void AppCallbackNotifier::eventCallbackRelay(CameraHalEvent* chEvt) 1142 { 1143 LOG_FUNCTION_NAME; 1144 AppCallbackNotifier *appcbn = (AppCallbackNotifier*) (chEvt->mCookie); 1145 appcbn->eventCallback(chEvt); 1146 LOG_FUNCTION_NAME_EXIT; 1147 } 1148 1149 void AppCallbackNotifier::eventCallback(CameraHalEvent* chEvt) 1150 { 1151 1152 ///Post the event to the event queue of AppCallbackNotifier 1153 TIUTILS::Message msg; 1154 CameraHalEvent *event; 1155 1156 1157 LOG_FUNCTION_NAME; 1158 1159 if ( NULL != chEvt ) 1160 { 1161 1162 event = new CameraHalEvent(*chEvt); 1163 if ( NULL != event ) 1164 { 1165 msg.command = AppCallbackNotifier::NOTIFIER_CMD_PROCESS_EVENT; 1166 msg.arg1 = event; 1167 { 1168 Mutex::Autolock lock(mLock); 1169 mEventQ.put(&msg); 1170 } 1171 } 1172 else 1173 { 1174 CAMHAL_LOGEA("Not enough resources to allocate CameraHalEvent"); 1175 } 1176 1177 } 1178 1179 LOG_FUNCTION_NAME_EXIT; 1180 } 1181 1182 1183 void AppCallbackNotifier::flushEventQueue() 1184 { 1185 1186 { 1187 Mutex::Autolock lock(mLock); 1188 mEventQ.clear(); 1189 } 1190 } 1191 1192 1193 bool AppCallbackNotifier::processMessage() 1194 { 1195 ///Retrieve the command from the command queue and process it 1196 TIUTILS::Message msg; 1197 1198 LOG_FUNCTION_NAME; 1199 1200 CAMHAL_LOGDA("+Msg get..."); 1201 mNotificationThread->msgQ().get(&msg); 1202 CAMHAL_LOGDA("-Msg get..."); 1203 bool ret = true; 1204 1205 switch(msg.command) 1206 { 1207 case NotificationThread::NOTIFIER_EXIT: 1208 { 1209 CAMHAL_LOGI("Received NOTIFIER_EXIT command from Camera HAL"); 1210 mNotifierState = AppCallbackNotifier::NOTIFIER_EXITED; 1211 ret = false; 1212 break; 1213 } 1214 default: 1215 { 1216 CAMHAL_LOGEA("Error: ProcessMsg() command from Camera HAL"); 1217 break; 1218 } 1219 } 1220 1221 LOG_FUNCTION_NAME_EXIT; 1222 1223 return ret; 1224 1225 1226 } 1227 1228 AppCallbackNotifier::~AppCallbackNotifier() 1229 { 1230 LOG_FUNCTION_NAME; 1231 1232 ///Stop app callback notifier if not already stopped 1233 stop(); 1234 1235 ///Unregister with the frame provider 1236 if ( NULL != mFrameProvider ) 1237 { 1238 mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES); 1239 } 1240 1241 //unregister with the event provider 1242 if ( NULL != mEventProvider ) 1243 { 1244 mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS); 1245 } 1246 1247 TIUTILS::Message msg = {0,0,0,0,0,0}; 1248 msg.command = NotificationThread::NOTIFIER_EXIT; 1249 1250 ///Post the message to display thread 1251 mNotificationThread->msgQ().put(&msg); 1252 1253 //Exit and cleanup the thread 1254 mNotificationThread->requestExit(); 1255 mNotificationThread->join(); 1256 1257 //Delete the display thread 1258 mNotificationThread.clear(); 1259 1260 1261 ///Free the event and frame providers 1262 if ( NULL != mEventProvider ) 1263 { 1264 ///Deleting the event provider 1265 CAMHAL_LOGDA("Stopping Event Provider"); 1266 delete mEventProvider; 1267 mEventProvider = NULL; 1268 } 1269 1270 if ( NULL != mFrameProvider ) 1271 { 1272 ///Deleting the frame provider 1273 CAMHAL_LOGDA("Stopping Frame Provider"); 1274 delete mFrameProvider; 1275 mFrameProvider = NULL; 1276 } 1277 1278 releaseSharedVideoBuffers(); 1279 1280 LOG_FUNCTION_NAME_EXIT; 1281 } 1282 1283 //Free all video heaps and buffers 1284 void AppCallbackNotifier::releaseSharedVideoBuffers() 1285 { 1286 LOG_FUNCTION_NAME; 1287 1288 if(mUseMetaDataBufferMode) 1289 { 1290 camera_memory_t* videoMedatadaBufferMemory; 1291 for (unsigned int i = 0; i < mVideoMetadataBufferMemoryMap.size(); i++) 1292 { 1293 videoMedatadaBufferMemory = (camera_memory_t*) mVideoMetadataBufferMemoryMap.valueAt(i); 1294 if(NULL != videoMedatadaBufferMemory) 1295 { 1296 videoMedatadaBufferMemory->release(videoMedatadaBufferMemory); 1297 CAMHAL_LOGDB("Released videoMedatadaBufferMemory=0x%x", videoMedatadaBufferMemory); 1298 } 1299 } 1300 1301 mVideoMetadataBufferMemoryMap.clear(); 1302 mVideoMetadataBufferReverseMap.clear(); 1303 if (mUseVideoBuffers) 1304 { 1305 mVideoMap.clear(); 1306 } 1307 } 1308 1309 LOG_FUNCTION_NAME_EXIT; 1310 } 1311 1312 void AppCallbackNotifier::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier) 1313 { 1314 1315 LOG_FUNCTION_NAME; 1316 ///@remarks There is no NULL check here. We will check 1317 ///for NULL when we get start command from CameraHal 1318 ///@Remarks Currently only one event provider (CameraAdapter) is supported 1319 ///@todo Have an array of event providers for each event bitmask 1320 mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay); 1321 if ( NULL == mEventProvider ) 1322 { 1323 CAMHAL_LOGEA("Error in creating EventProvider"); 1324 } 1325 else 1326 { 1327 mEventProvider->enableEventNotification(eventMask); 1328 } 1329 1330 LOG_FUNCTION_NAME_EXIT; 1331 } 1332 1333 void AppCallbackNotifier::setFrameProvider(FrameNotifier *frameNotifier) 1334 { 1335 LOG_FUNCTION_NAME; 1336 ///@remarks There is no NULL check here. We will check 1337 ///for NULL when we get the start command from CameraAdapter 1338 mFrameProvider = new FrameProvider(frameNotifier, this, frameCallbackRelay); 1339 if ( NULL == mFrameProvider ) 1340 { 1341 CAMHAL_LOGEA("Error in creating FrameProvider"); 1342 } 1343 else 1344 { 1345 //Register only for captured images and RAW for now 1346 //TODO: Register for and handle all types of frames 1347 mFrameProvider->enableFrameNotification(CameraFrame::IMAGE_FRAME); 1348 mFrameProvider->enableFrameNotification(CameraFrame::RAW_FRAME); 1349 } 1350 1351 LOG_FUNCTION_NAME_EXIT; 1352 } 1353 1354 status_t AppCallbackNotifier::startPreviewCallbacks(CameraParameters ¶ms, void *buffers, uint32_t *offsets, int fd, size_t length, size_t count) 1355 { 1356 sp<MemoryHeapBase> heap; 1357 sp<MemoryBase> buffer; 1358 unsigned int *bufArr; 1359 size_t size = 0; 1360 1361 LOG_FUNCTION_NAME; 1362 1363 Mutex::Autolock lock(mLock); 1364 1365 if ( NULL == mFrameProvider ) 1366 { 1367 CAMHAL_LOGEA("Trying to start video recording without FrameProvider"); 1368 return -EINVAL; 1369 } 1370 1371 if ( mPreviewing ) 1372 { 1373 CAMHAL_LOGDA("+Already previewing"); 1374 return NO_INIT; 1375 } 1376 1377 int w,h; 1378 ///Get preview size 1379 params.getPreviewSize(&w, &h); 1380 1381 //Get the preview pixel format 1382 mPreviewPixelFormat = params.getPreviewFormat(); 1383 1384 if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) 1385 { 1386 size = w*h*2; 1387 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV422I; 1388 } 1389 else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || 1390 strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0) 1391 { 1392 size = (w*h*3)/2; 1393 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420SP; 1394 } 1395 else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) 1396 { 1397 size = w*h*2; 1398 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_RGB565; 1399 } 1400 1401 mPreviewMemory = mRequestMemory(-1, size, AppCallbackNotifier::MAX_BUFFERS, NULL); 1402 if (!mPreviewMemory) { 1403 return NO_MEMORY; 1404 } 1405 1406 for (int i=0; i < AppCallbackNotifier::MAX_BUFFERS; i++) { 1407 mPreviewBufs[i] = (unsigned char*) mPreviewMemory->data + (i*size); 1408 } 1409 1410 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME ) ) { 1411 mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC); 1412 } 1413 1414 mPreviewBufCount = 0; 1415 1416 mPreviewing = true; 1417 1418 LOG_FUNCTION_NAME; 1419 1420 return NO_ERROR; 1421 } 1422 1423 void AppCallbackNotifier::setBurst(bool burst) 1424 { 1425 LOG_FUNCTION_NAME; 1426 1427 Mutex::Autolock lock(mBurstLock); 1428 1429 mBurst = burst; 1430 1431 LOG_FUNCTION_NAME_EXIT; 1432 } 1433 1434 void AppCallbackNotifier::useVideoBuffers(bool useVideoBuffers) 1435 { 1436 LOG_FUNCTION_NAME; 1437 1438 mUseVideoBuffers = useVideoBuffers; 1439 1440 LOG_FUNCTION_NAME_EXIT; 1441 } 1442 1443 bool AppCallbackNotifier::getUesVideoBuffers() 1444 { 1445 return mUseVideoBuffers; 1446 } 1447 1448 void AppCallbackNotifier::setVideoRes(int width, int height) 1449 { 1450 LOG_FUNCTION_NAME; 1451 1452 mVideoWidth = width; 1453 mVideoHeight = height; 1454 1455 LOG_FUNCTION_NAME_EXIT; 1456 } 1457 1458 status_t AppCallbackNotifier::stopPreviewCallbacks() 1459 { 1460 sp<MemoryHeapBase> heap; 1461 sp<MemoryBase> buffer; 1462 1463 LOG_FUNCTION_NAME; 1464 1465 if ( NULL == mFrameProvider ) 1466 { 1467 CAMHAL_LOGEA("Trying to stop preview callbacks without FrameProvider"); 1468 return -EINVAL; 1469 } 1470 1471 if ( !mPreviewing ) 1472 { 1473 return NO_INIT; 1474 } 1475 1476 mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC); 1477 1478 { 1479 Mutex::Autolock lock(mLock); 1480 mPreviewMemory->release(mPreviewMemory); 1481 } 1482 1483 mPreviewing = false; 1484 1485 LOG_FUNCTION_NAME_EXIT; 1486 1487 return NO_ERROR; 1488 1489 } 1490 1491 status_t AppCallbackNotifier::useMetaDataBufferMode(bool enable) 1492 { 1493 mUseMetaDataBufferMode = enable; 1494 1495 return NO_ERROR; 1496 } 1497 1498 1499 status_t AppCallbackNotifier::startRecording() 1500 { 1501 status_t ret = NO_ERROR; 1502 1503 LOG_FUNCTION_NAME; 1504 1505 Mutex::Autolock lock(mRecordingLock); 1506 1507 if ( NULL == mFrameProvider ) 1508 { 1509 CAMHAL_LOGEA("Trying to start video recording without FrameProvider"); 1510 ret = -1; 1511 } 1512 1513 if(mRecording) 1514 { 1515 return NO_INIT; 1516 } 1517 1518 if ( NO_ERROR == ret ) 1519 { 1520 mFrameProvider->enableFrameNotification(CameraFrame::VIDEO_FRAME_SYNC); 1521 } 1522 1523 mRecording = true; 1524 1525 LOG_FUNCTION_NAME_EXIT; 1526 1527 return ret; 1528 } 1529 1530 //Allocate metadata buffers for video recording 1531 status_t AppCallbackNotifier::initSharedVideoBuffers(void *buffers, uint32_t *offsets, int fd, size_t length, size_t count, void *vidBufs) 1532 { 1533 status_t ret = NO_ERROR; 1534 LOG_FUNCTION_NAME; 1535 1536 if(mUseMetaDataBufferMode) 1537 { 1538 uint32_t *bufArr = NULL; 1539 camera_memory_t* videoMedatadaBufferMemory = NULL; 1540 1541 if(NULL == buffers) 1542 { 1543 CAMHAL_LOGEA("Error! Video buffers are NULL"); 1544 return BAD_VALUE; 1545 } 1546 bufArr = (uint32_t *) buffers; 1547 1548 for (uint32_t i = 0; i < count; i++) 1549 { 1550 videoMedatadaBufferMemory = mRequestMemory(-1, sizeof(video_metadata_t), 1, NULL); 1551 if((NULL == videoMedatadaBufferMemory) || (NULL == videoMedatadaBufferMemory->data)) 1552 { 1553 CAMHAL_LOGEA("Error! Could not allocate memory for Video Metadata Buffers"); 1554 return NO_MEMORY; 1555 } 1556 1557 mVideoMetadataBufferMemoryMap.add(bufArr[i], (uint32_t)(videoMedatadaBufferMemory)); 1558 mVideoMetadataBufferReverseMap.add((uint32_t)(videoMedatadaBufferMemory->data), bufArr[i]); 1559 CAMHAL_LOGDB("bufArr[%d]=0x%x, videoMedatadaBufferMemory=0x%x, videoMedatadaBufferMemory->data=0x%x", 1560 i, bufArr[i], videoMedatadaBufferMemory, videoMedatadaBufferMemory->data); 1561 1562 if (vidBufs != NULL) 1563 { 1564 uint32_t *vBufArr = (uint32_t *) vidBufs; 1565 mVideoMap.add(bufArr[i], vBufArr[i]); 1566 CAMHAL_LOGVB("bufArr[%d]=0x%x, vBuffArr[%d]=0x%x", i, bufArr[i], i, vBufArr[i]); 1567 } 1568 } 1569 } 1570 1571 exit: 1572 LOG_FUNCTION_NAME_EXIT; 1573 1574 return ret; 1575 } 1576 1577 status_t AppCallbackNotifier::stopRecording() 1578 { 1579 status_t ret = NO_ERROR; 1580 1581 LOG_FUNCTION_NAME; 1582 1583 Mutex::Autolock lock(mRecordingLock); 1584 1585 if ( NULL == mFrameProvider ) 1586 { 1587 CAMHAL_LOGEA("Trying to stop video recording without FrameProvider"); 1588 ret = -1; 1589 } 1590 1591 if(!mRecording) 1592 { 1593 return NO_INIT; 1594 } 1595 1596 if ( NO_ERROR == ret ) 1597 { 1598 mFrameProvider->disableFrameNotification(CameraFrame::VIDEO_FRAME_SYNC); 1599 } 1600 1601 ///Release the shared video buffers 1602 releaseSharedVideoBuffers(); 1603 1604 mRecording = false; 1605 1606 LOG_FUNCTION_NAME_EXIT; 1607 1608 return ret; 1609 } 1610 1611 status_t AppCallbackNotifier::releaseRecordingFrame(const void* mem) 1612 { 1613 status_t ret = NO_ERROR; 1614 void *frame = NULL; 1615 1616 LOG_FUNCTION_NAME; 1617 if ( NULL == mFrameProvider ) 1618 { 1619 CAMHAL_LOGEA("Trying to stop video recording without FrameProvider"); 1620 ret = -1; 1621 } 1622 1623 if ( NULL == mem ) 1624 { 1625 CAMHAL_LOGEA("Video Frame released is invalid"); 1626 ret = -1; 1627 } 1628 1629 if( NO_ERROR != ret ) 1630 { 1631 return ret; 1632 } 1633 1634 if(mUseMetaDataBufferMode) 1635 { 1636 video_metadata_t *videoMetadataBuffer = (video_metadata_t *) mem ; 1637 frame = (void*) mVideoMetadataBufferReverseMap.valueFor((uint32_t) videoMetadataBuffer); 1638 CAMHAL_LOGVB("Releasing frame with videoMetadataBuffer=0x%x, videoMetadataBuffer->handle=0x%x & frame handle=0x%x\n", 1639 videoMetadataBuffer, videoMetadataBuffer->handle, frame); 1640 } 1641 else 1642 { 1643 frame = (void*)(*((uint32_t *)mem)); 1644 } 1645 1646 if ( NO_ERROR == ret ) 1647 { 1648 ret = mFrameProvider->returnFrame(frame, CameraFrame::VIDEO_FRAME_SYNC); 1649 } 1650 1651 LOG_FUNCTION_NAME_EXIT; 1652 1653 return ret; 1654 } 1655 1656 status_t AppCallbackNotifier::enableMsgType(int32_t msgType) 1657 { 1658 if( msgType & (CAMERA_MSG_POSTVIEW_FRAME | CAMERA_MSG_PREVIEW_FRAME) ) { 1659 mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC); 1660 } 1661 1662 return NO_ERROR; 1663 } 1664 1665 status_t AppCallbackNotifier::disableMsgType(int32_t msgType) 1666 { 1667 if(!mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_POSTVIEW_FRAME)) { 1668 mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC); 1669 } 1670 1671 return NO_ERROR; 1672 1673 } 1674 1675 status_t AppCallbackNotifier::start() 1676 { 1677 LOG_FUNCTION_NAME; 1678 if(mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED) 1679 { 1680 CAMHAL_LOGDA("AppCallbackNotifier already running"); 1681 LOG_FUNCTION_NAME_EXIT; 1682 return ALREADY_EXISTS; 1683 } 1684 1685 ///Check whether initial conditions are met for us to start 1686 ///A frame provider should be available, if not return error 1687 if(!mFrameProvider) 1688 { 1689 ///AppCallbackNotifier not properly initialized 1690 CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Frame provider is NULL"); 1691 LOG_FUNCTION_NAME_EXIT; 1692 return NO_INIT; 1693 } 1694 1695 ///At least one event notifier should be available, if not return error 1696 ///@todo Modify here when there is an array of event providers 1697 if(!mEventProvider) 1698 { 1699 CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Event provider is NULL"); 1700 LOG_FUNCTION_NAME_EXIT; 1701 ///AppCallbackNotifier not properly initialized 1702 return NO_INIT; 1703 } 1704 1705 mNotifierState = AppCallbackNotifier::NOTIFIER_STARTED; 1706 CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STARTED \n"); 1707 1708 gEncoderQueue.clear(); 1709 1710 LOG_FUNCTION_NAME_EXIT; 1711 1712 return NO_ERROR; 1713 1714 } 1715 1716 status_t AppCallbackNotifier::stop() 1717 { 1718 LOG_FUNCTION_NAME; 1719 1720 if(mNotifierState!=AppCallbackNotifier::NOTIFIER_STARTED) 1721 { 1722 CAMHAL_LOGDA("AppCallbackNotifier already in stopped state"); 1723 LOG_FUNCTION_NAME_EXIT; 1724 return ALREADY_EXISTS; 1725 } 1726 { 1727 Mutex::Autolock lock(mLock); 1728 1729 mNotifierState = AppCallbackNotifier::NOTIFIER_STOPPED; 1730 CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STOPPED \n"); 1731 } 1732 1733 while(!gEncoderQueue.isEmpty()) { 1734 sp<Encoder_libjpeg> encoder = gEncoderQueue.valueAt(0); 1735 if(encoder.get()) { 1736 encoder->cancel(); 1737 encoder->join(); 1738 encoder.clear(); 1739 } 1740 gEncoderQueue.removeItemsAt(0); 1741 } 1742 1743 LOG_FUNCTION_NAME_EXIT; 1744 return NO_ERROR; 1745 } 1746 1747 1748 /*--------------------NotificationHandler Class ENDS here-----------------------------*/ 1749 1750 1751 1752 }; 1753