• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AppCallbackNotifierEncoderCallback(void * main_jpeg,void * thumb_jpeg,CameraFrame::FrameType type,void * cookie1,void * cookie2,void * cookie3)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 
EncoderDoneCb(void * main_jpeg,void * thumb_jpeg,CameraFrame::FrameType type,void * cookie1,void * cookie2)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
initialize()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 
setCallbacks(CameraHal * cameraHal,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)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 
setMeasurements(bool enable)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
errorNotify(int error)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 
notificationThread()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 
notifyEvent()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 
copy2Dto1D(void * dst,void * src,int width,int height,size_t stride,uint32_t offset,unsigned int bytesPerPixel,size_t length,const char * pixelFormat)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 
copyAndSendPictureFrame(CameraFrame * frame,int32_t msgType)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 
copyAndSendPreviewFrame(CameraFrame * frame,int32_t msgType)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 
dummyRaw()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 
notifyFrame()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 
frameCallbackRelay(CameraFrame * caFrame)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 
frameCallback(CameraFrame * caFrame)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 
flushAndReturnFrames()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 
eventCallbackRelay(CameraHalEvent * chEvt)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 
eventCallback(CameraHalEvent * chEvt)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 
processMessage()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 
~AppCallbackNotifier()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
releaseSharedVideoBuffers()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 
setEventProvider(int32_t eventMask,MessageNotifier * eventNotifier)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 
setFrameProvider(FrameNotifier * frameNotifier)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 
startPreviewCallbacks(CameraParameters & params,void * buffers,uint32_t * offsets,int fd,size_t length,size_t count)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 
setBurst(bool burst)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 
useVideoBuffers(bool useVideoBuffers)1397 void AppCallbackNotifier::useVideoBuffers(bool useVideoBuffers)
1398 {
1399   LOG_FUNCTION_NAME;
1400 
1401   mUseVideoBuffers = useVideoBuffers;
1402 
1403   LOG_FUNCTION_NAME_EXIT;
1404 }
1405 
getUesVideoBuffers()1406 bool AppCallbackNotifier::getUesVideoBuffers()
1407 {
1408     return mUseVideoBuffers;
1409 }
1410 
setVideoRes(int width,int height)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 
setParameters(const CameraParameters & params)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 
stopPreviewCallbacks()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 
useMetaDataBufferMode(bool enable)1464 status_t AppCallbackNotifier::useMetaDataBufferMode(bool enable)
1465 {
1466     mUseMetaDataBufferMode = enable;
1467 
1468     return NO_ERROR;
1469 }
1470 
1471 
startRecording()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
initSharedVideoBuffers(void * buffers,uint32_t * offsets,int fd,size_t length,size_t count,void * vidBufs)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 
stopRecording()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 
releaseRecordingFrame(const void * mem)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 
enableMsgType(int32_t msgType)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 
disableMsgType(int32_t msgType)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 
start()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 
stop()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