Home | History | Annotate | Download | only in camera
      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 &params, 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