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