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