summaryrefslogtreecommitdiff
path: root/AppCallbackNotifier.cpp (plain)
blob: 4b304941ad0fb009f540ee2d18c10c1e39cec2ff
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#ifdef METADATA_MODE_FOR_PREVIEW_CALLBACK
731 if (mUseMetaDataBufferMode) {
732 unsigned int *format_ptr;
733 video_metadata_t *videoMetadataBuffer = (video_metadata_t *)dest;
734 videoMetadataBuffer->metadataBufferType = frame->metadataBufferType;
735 videoMetadataBuffer->handle = (void*)frame->mBuffer;
736 videoMetadataBuffer->canvas = frame->mCanvas;
737 format_ptr = (unsigned int *)(dest + sizeof(video_metadata_t));
738 *format_ptr = frame->mColorFormat;
739 CAMHAL_LOGDB("copyAndSendPreviewFrame Metadata mode, canvas:0x%x", videoMetadataBuffer->canvas);
740 }else
741#endif
742 if (CameraFrame::FRAME_DATA_SYNC == frame->mFrameType) {
743 if ( (mPreviewMemory->size / MAX_BUFFERS) >= frame->mLength ) {
744 memcpy(dest, (void*) src, frame->mLength);
745 } else {
746 memset(dest, 0, (mPreviewMemory->size / MAX_BUFFERS));
747 }
748 } else {
749 if ((NULL == (void*)frame->mYuv[0]) || (NULL == (void*)frame->mYuv[1])){
750 CAMHAL_LOGEA("Error! One of the YUV Pointer is NULL");
751 goto exit;
752 }
753 else{
754 copy2Dto1D(dest,
755 frame->mYuv,
756 frame->mWidth,
757 frame->mHeight,
758 frame->mPixelFmt,
759 frame->mAlignment,
760 frame->mOffset,
761 2,
762 frame->mLength,
763 mPreviewPixelFormat);
764 }
765 }
766 }
767 }
768
769 exit:
770 mFrameProvider->returnFrame(frame->mBuffer, (CameraFrame::FrameType) frame->mFrameType);
771
772 if((mNotifierState == AppCallbackNotifier::NOTIFIER_STARTED) &&
773 mCameraHal->msgTypeEnabled(msgType) &&
774 (dest != NULL)) {
775 mDataCb(msgType, mPreviewMemory, mPreviewBufCount, NULL, mCallbackCookie);
776 }
777
778 // increment for next buffer
779 mPreviewBufCount = (mPreviewBufCount + 1) % AppCallbackNotifier::MAX_BUFFERS;
780}
781
782status_t AppCallbackNotifier::dummyRaw()
783{
784 LOG_FUNCTION_NAME;
785
786 if ( NULL == mRequestMemory ) {
787 CAMHAL_LOGEA("Can't allocate memory for dummy raw callback!");
788 return NO_INIT;
789 }
790
791 if ( ( NULL != mCameraHal ) &&
792 ( NULL != mDataCb) &&
793 ( NULL != mNotifyCb ) ){
794
795 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE) ) {
796 camera_memory_t *dummyRaw = mRequestMemory(-1, 1, 1, NULL);
797
798 if ( NULL == dummyRaw ) {
799 CAMHAL_LOGEA("Dummy raw buffer allocation failed!");
800 return NO_MEMORY;
801 }
802
803 mDataCb(CAMERA_MSG_RAW_IMAGE, dummyRaw, 0, NULL, mCallbackCookie);
804
805 dummyRaw->release(dummyRaw);
806 } else if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY) ) {
807 mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie);
808 }
809 }
810
811 LOG_FUNCTION_NAME_EXIT;
812
813 return NO_ERROR;
814}
815
816void AppCallbackNotifier::notifyFrame()
817{
818 ///Receive and send the frame notifications to app
819 MSGUTILS::Message msg;
820 CameraFrame *frame;
821 MemoryHeapBase *heap;
822 MemoryBase *buffer = NULL;
823 sp<MemoryBase> memBase;
824 void *buf = NULL;
825
826 LOG_FUNCTION_NAME;
827
828 {
829 Mutex::Autolock lock(mLock);
830 if(!mFrameQ.isEmpty()) {
831 mFrameQ.get(&msg);
832 } else {
833 return;
834 }
835 }
836
837 bool ret = true;
838
839 frame = NULL;
840 switch(msg.command)
841 {
842 case AppCallbackNotifier::NOTIFIER_CMD_PROCESS_FRAME:
843
844 frame = (CameraFrame *) msg.arg1;
845 if(!frame)
846 {
847 break;
848 }
849
850 if ( (CameraFrame::RAW_FRAME == frame->mFrameType )&&
851 ( NULL != mCameraHal ) &&
852 ( NULL != mDataCb) &&
853 ( NULL != mNotifyCb ) )
854 {
855
856 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE) )
857 {
858#ifdef COPY_IMAGE_BUFFER
859 copyAndSendPictureFrame(frame, CAMERA_MSG_RAW_IMAGE);
860#else
861 //TODO: Find a way to map a Tiler buffer to a MemoryHeapBase
862#endif
863 }
864 else
865 {
866 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY) ) {
867 mNotifyCb(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCallbackCookie);
868 }
869 mFrameProvider->returnFrame(frame->mBuffer,
870 (CameraFrame::FrameType) frame->mFrameType);
871 }
872 mRawAvailable = true;
873 }
874 else if ( (CameraFrame::IMAGE_FRAME == frame->mFrameType) &&
875 (NULL != mCameraHal) &&
876 (NULL != mDataCb) &&
877 ((CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks) ||
878 (CameraFrame::ENCODE_RAW_RGB24_TO_JPEG & frame->mQuirks)||
879 (CameraFrame::ENCODE_RAW_YUV420SP_TO_JPEG & frame->mQuirks)))
880 {
881
882 CAMHAL_LOGDA("IMAGE_FRAME ENCODE_RAW.. ");
883 int encode_quality = 100, tn_quality = 100;
884 int tn_width, tn_height;
885 unsigned int current_snapshot = 0;
886 Encoder_libjpeg::params *main_jpeg = NULL, *tn_jpeg = NULL;
887 void* exif_data = NULL;
888 camera_memory_t* raw_picture = mRequestMemory(-1, frame->mLength, 1, NULL);
889
890 if(raw_picture) {
891 buf = raw_picture->data;
892 }else{
893 CAMHAL_LOGEA("Error! Main Jpeg encoder request memory fail!");
894 break;
895 }
896
897 CameraParameters parameters;
898 char *params = mCameraHal->getParameters();
899 const String8 strParams(params);
900 parameters.unflatten(strParams);
901
902 encode_quality = parameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
903 if (encode_quality < 0 || encode_quality > 100) {
904 encode_quality = 100;
905 }
906
907 tn_quality = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
908 if (tn_quality < 0 || tn_quality > 100) {
909 tn_quality = 100;
910 }
911
912 if (CameraFrame::HAS_EXIF_DATA & frame->mQuirks) {
913 exif_data = frame->mCookie2;
914 }
915
916 main_jpeg = (Encoder_libjpeg::params*)
917 malloc(sizeof(Encoder_libjpeg::params));
918 if (main_jpeg) {
919 main_jpeg->src = (uint8_t*) frame->mBuffer;
920 main_jpeg->src_size = frame->mLength;
921 main_jpeg->dst = (uint8_t*) buf;
922 main_jpeg->dst_size = frame->mLength;
923 main_jpeg->quality = encode_quality;
924 main_jpeg->in_width = frame->mWidth;
925 main_jpeg->in_height = frame->mHeight;
926 main_jpeg->out_width = frame->mWidth;
927 main_jpeg->out_height = frame->mHeight;
928 if ((CameraFrame::ENCODE_RAW_RGB24_TO_JPEG & frame->mQuirks))
929 main_jpeg->format = CameraProperties::PIXEL_FORMAT_RGB24;
930 else if ((CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks))
931 main_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV422I;
932 else if ((CameraFrame::ENCODE_RAW_YUV420SP_TO_JPEG & frame->mQuirks))
933 main_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV420SP;
934 }
935
936 tn_width = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
937 tn_height = parameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
938
939 if(frame->mHeight>frame->mWidth){
940 int temp = tn_width;
941 tn_width = tn_height;
942 tn_height = temp;
943 }
944
945 if ((tn_width > 0) && (tn_height > 0)) {
946 tn_jpeg = (Encoder_libjpeg::params*)
947 malloc(sizeof(Encoder_libjpeg::params));
948 // if malloc fails just keep going and encode main jpeg
949 if (!tn_jpeg) {
950 tn_jpeg = NULL;
951 }
952 }
953
954 if (tn_jpeg) {
955 tn_jpeg->dst = (uint8_t*) malloc(tn_width*tn_height*3);
956 if(tn_jpeg->dst){
957 tn_jpeg->src = (uint8_t*) frame->mBuffer;
958 tn_jpeg->src_size = frame->mLength;
959 tn_jpeg->dst_size = tn_width*tn_height*3;
960 tn_jpeg->quality = tn_quality;
961 tn_jpeg->in_width = frame->mWidth;
962 tn_jpeg->in_height = frame->mHeight;
963 tn_jpeg->out_width = tn_width;
964 tn_jpeg->out_height = tn_height;
965 if ((CameraFrame::ENCODE_RAW_RGB24_TO_JPEG & frame->mQuirks))
966 tn_jpeg->format = CameraProperties::PIXEL_FORMAT_RGB24;
967 else if ((CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks))
968 tn_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV422I;
969 else if ((CameraFrame::ENCODE_RAW_YUV420SP_TO_JPEG & frame->mQuirks))
970 tn_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV420SP;
971 }else{
972 free(tn_jpeg);
973 tn_jpeg = NULL;
974 CAMHAL_LOGEA("Error! Thumbnail Jpeg encoder malloc memory fail!");
975 }
976 }
977
978 CAMHAL_LOGDA("IMAGE_FRAME ENCODE_RAW..");
979 sp<Encoder_libjpeg> encoder = new Encoder_libjpeg(main_jpeg,
980 tn_jpeg,
981 AppCallbackNotifierEncoderCallback,
982 (CameraFrame::FrameType)frame->mFrameType,
983 this,
984 raw_picture,
985 exif_data);
986 encoder->run();
987 gEncoderQueue.add(frame->mBuffer, encoder);
988 encoder.clear();
989 if (params != NULL)
990 {
991 mCameraHal->putParameters(params);
992 }
993 }
994 else if ( ( CameraFrame::IMAGE_FRAME == frame->mFrameType ) &&
995 ( NULL != mCameraHal ) &&
996 ( NULL != mDataCb) )
997 {
998
999 // CTS, MTS requirements: Every 'takePicture()' call
1000 // who registers a raw callback should receive one
1001 // as well. This is not always the case with
1002 // CameraAdapters though.
1003 if (!mRawAvailable) {
1004 dummyRaw();
1005 } else {
1006 mRawAvailable = false;
1007 }
1008
1009#ifdef COPY_IMAGE_BUFFER
1010 {
1011 Mutex::Autolock lock(mBurstLock);
1012#if 0 //TODO: enable burst mode later
1013 if ( mBurst )
1014 {
1015 `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie);
1016 }
1017 else
1018#endif
1019 {
1020 copyAndSendPictureFrame(frame, CAMERA_MSG_COMPRESSED_IMAGE);
1021 }
1022 }
1023#else
1024 //TODO: Find a way to map a Tiler buffer to a MemoryHeapBase
1025#endif
1026 }
1027 else if ( ( CameraFrame::VIDEO_FRAME_SYNC == frame->mFrameType ) &&
1028 ( NULL != mCameraHal ) &&
1029 ( NULL != mDataCb) &&
1030 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_VIDEO_FRAME) ) )
1031 {
1032 mRecordingLock.lock();
1033 if(mRecording)
1034 {
1035 if(mUseMetaDataBufferMode)
1036 {
1037 camera_memory_t *videoMedatadaBufferMemory =
1038 (camera_memory_t *) mVideoMetadataBufferMemoryMap.valueFor((uint32_t) frame->mBuffer);
1039 video_metadata_t *videoMetadataBuffer = (video_metadata_t *) videoMedatadaBufferMemory->data;
1040
1041 if( (NULL == videoMedatadaBufferMemory) || (NULL == videoMetadataBuffer) || (NULL == frame->mBuffer) )
1042 {
1043 CAMHAL_LOGEA("Error! One of the video buffers is NULL");
1044 break;
1045 }
1046
1047 if ( mUseVideoBuffers )
1048 {
1049 int vBuf = mVideoMap.valueFor((uint32_t) frame->mBuffer);
1050 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1051 Rect bounds;
1052 bounds.left = 0;
1053 bounds.top = 0;
1054 bounds.right = mVideoWidth;
1055 bounds.bottom = mVideoHeight;
1056
1057 void *y_uv[2];
1058 mapper.lock((buffer_handle_t)vBuf, CAMHAL_GRALLOC_USAGE, bounds, y_uv);
1059
1060 structConvImage input = {(int)frame->mWidth,
1061 (int)frame->mHeight,
1062 4096,
1063 IC_FORMAT_YCbCr420_lp,
1064 (mmByte *)frame->mYuv[0],
1065 (mmByte *)(frame->mYuv[0]+frame->mWidth*frame->mHeight),
1066 (int)frame->mOffset};
1067
1068 structConvImage output = {mVideoWidth,
1069 mVideoHeight,
1070 4096,
1071 IC_FORMAT_YCbCr420_lp,
1072 (mmByte *)y_uv[0],
1073 (mmByte *)((unsigned)y_uv[0]+mVideoWidth*mVideoHeight),
1074 0};
1075
1076 VT_resizeFrame_Video_opt2_lp(&input, &output, NULL, 0);
1077 mapper.unlock((buffer_handle_t)vBuf);
1078 videoMetadataBuffer->metadataBufferType = kMetadataBufferTypeGrallocSource;
1079 videoMetadataBuffer->handle= (void *)vBuf;
1080 videoMetadataBuffer->canvas = 0;
1081 }
1082 else
1083 {
1084 videoMetadataBuffer->metadataBufferType = frame->metadataBufferType;
1085 videoMetadataBuffer->handle = (void*)frame->mBuffer;
1086 videoMetadataBuffer->canvas = frame->mCanvas;
1087 }
1088 CAMHAL_LOGVB("mDataCbTimestamp : frame->mBuffer=0x%x, videoMetadataBuffer=0x%x, videoMedatadaBufferMemory=0x%x, videoMetadataBuffer->ptr=0x%x, videoMetadataBuffer->canvas_index = 0x%x",
1089 frame->mBuffer, videoMetadataBuffer, videoMedatadaBufferMemory,(unsigned)videoMetadataBuffer->handle,videoMetadataBuffer->canvas);
1090
1091 mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME,
1092 videoMedatadaBufferMemory, 0, mCallbackCookie);
1093 }
1094 else
1095 {
1096 //TODO: Need to revisit this, should ideally be mapping the TILER buffer using mRequestMemory
1097 if( NULL == frame->mBuffer)
1098 {
1099 CAMHAL_LOGEA("Error! frame->mBuffer is NULL");
1100 break;
1101 }
1102#ifdef AMLOGIC_CAMERA_OVERLAY_SUPPORT
1103 camera_memory_t* VideoCameraBufferMemoryBase = (camera_memory_t*)frame->mBuffer;
1104 if((NULL == VideoCameraBufferMemoryBase)||(NULL == VideoCameraBufferMemoryBase->data))
1105 {
1106 CAMHAL_LOGEA("Error! one of video buffer is NULL");
1107 break;
1108 }
1109 mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME, VideoCameraBufferMemoryBase, 0, mCallbackCookie);
1110#else
1111 camera_memory_t* VideoCameraBufferMemoryBase = (camera_memory_t*)mVideoHeaps.valueFor((uint32_t)frame->mBuffer);
1112 private_handle_t* gralloc_hnd = (private_handle_t*)frame->mBuffer;
1113 if((!VideoCameraBufferMemoryBase) ||(!gralloc_hnd->base))
1114 {
1115 CAMHAL_LOGEA("Error! one of video buffer is NULL");
1116 break;
1117 }
1118 uint8_t* src = (uint8_t*)gralloc_hnd->base;
1119 uint8_t* dest = (uint8_t*)VideoCameraBufferMemoryBase->data;
1120 memcpy(dest,src,frame->mLength);
1121 mDataCbTimestamp(frame->mTimestamp, CAMERA_MSG_VIDEO_FRAME, VideoCameraBufferMemoryBase, 0, mCallbackCookie);
1122#endif
1123 }
1124 }
1125 mRecordingLock.unlock();
1126 }
1127 else if(( CameraFrame::SNAPSHOT_FRAME == frame->mFrameType ) &&
1128 ( NULL != mCameraHal ) &&
1129 ( NULL != mDataCb) &&
1130 ( NULL != mNotifyCb)) {
1131 //When enabled, measurement data is sent instead of video data
1132 if ( !mMeasurementEnabled ) {
1133 copyAndSendPreviewFrame(frame, CAMERA_MSG_POSTVIEW_FRAME);
1134 } else {
1135 mFrameProvider->returnFrame(frame->mBuffer,
1136 (CameraFrame::FrameType) frame->mFrameType);
1137 }
1138 }
1139 else if ( ( CameraFrame::PREVIEW_FRAME_SYNC== frame->mFrameType ) &&
1140 ( NULL != mCameraHal ) &&
1141 ( NULL != mDataCb) &&
1142 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) ) {
1143 //When enabled, measurement data is sent instead of video data
1144 if ( !mMeasurementEnabled ) {
1145 copyAndSendPreviewFrame(frame, CAMERA_MSG_PREVIEW_FRAME);
1146 } else {
1147 mFrameProvider->returnFrame(frame->mBuffer,
1148 (CameraFrame::FrameType) frame->mFrameType);
1149 }
1150 }
1151 else if ( ( CameraFrame::FRAME_DATA_SYNC == frame->mFrameType ) &&
1152 ( NULL != mCameraHal ) &&
1153 ( NULL != mDataCb) &&
1154 ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME)) ) {
1155 copyAndSendPreviewFrame(frame, CAMERA_MSG_PREVIEW_FRAME);
1156 } else {
1157 mFrameProvider->returnFrame(frame->mBuffer,
1158 ( CameraFrame::FrameType ) frame->mFrameType);
1159 CAMHAL_LOGVB("Frame type 0x%x is still unsupported!", frame->mFrameType);
1160 }
1161
1162 break;
1163
1164 default:
1165
1166 break;
1167
1168 };
1169
1170exit:
1171
1172 if ( NULL != frame )
1173 {
1174 delete frame;
1175 }
1176
1177 LOG_FUNCTION_NAME_EXIT;
1178}
1179
1180void AppCallbackNotifier::frameCallbackRelay(CameraFrame* caFrame)
1181{
1182 LOG_FUNCTION_NAME;
1183 AppCallbackNotifier *appcbn = (AppCallbackNotifier*) (caFrame->mCookie);
1184 appcbn->frameCallback(caFrame);
1185 LOG_FUNCTION_NAME_EXIT;
1186}
1187
1188void AppCallbackNotifier::frameCallback(CameraFrame* caFrame)
1189{
1190 ///Post the event to the event queue of AppCallbackNotifier
1191 MSGUTILS::Message msg;
1192 CameraFrame *frame;
1193
1194 LOG_FUNCTION_NAME;
1195
1196 if ( NULL != caFrame )
1197 {
1198 frame = new CameraFrame(*caFrame);
1199 if ( NULL != frame )
1200 {
1201 msg.command = AppCallbackNotifier::NOTIFIER_CMD_PROCESS_FRAME;
1202 msg.arg1 = frame;
1203 mFrameQ.put(&msg);
1204 }
1205 else
1206 {
1207 CAMHAL_LOGEA("Not enough resources to allocate CameraFrame");
1208 }
1209 }
1210
1211 LOG_FUNCTION_NAME_EXIT;
1212}
1213
1214void AppCallbackNotifier::flushAndReturnFrames()
1215{
1216 MSGUTILS::Message msg;
1217 CameraFrame *frame;
1218
1219 Mutex::Autolock lock(mLock);
1220 while (!mFrameQ.isEmpty()) {
1221 mFrameQ.get(&msg);
1222 frame = (CameraFrame*) msg.arg1;
1223 if (frame) {
1224 mFrameProvider->returnFrame(frame->mBuffer,
1225 (CameraFrame::FrameType) frame->mFrameType);
1226 }
1227 }
1228
1229 LOG_FUNCTION_NAME_EXIT;
1230}
1231
1232void AppCallbackNotifier::eventCallbackRelay(CameraHalEvent* chEvt)
1233{
1234 LOG_FUNCTION_NAME;
1235 AppCallbackNotifier *appcbn = (AppCallbackNotifier*) (chEvt->mCookie);
1236 appcbn->eventCallback(chEvt);
1237 LOG_FUNCTION_NAME_EXIT;
1238}
1239
1240void AppCallbackNotifier::eventCallback(CameraHalEvent* chEvt)
1241{
1242
1243 ///Post the event to the event queue of AppCallbackNotifier
1244 MSGUTILS::Message msg;
1245 CameraHalEvent *event;
1246
1247
1248 LOG_FUNCTION_NAME;
1249
1250 if ( NULL != chEvt )
1251 {
1252
1253 event = new CameraHalEvent(*chEvt);
1254 if ( NULL != event )
1255 {
1256 msg.command = AppCallbackNotifier::NOTIFIER_CMD_PROCESS_EVENT;
1257 msg.arg1 = event;
1258 {
1259 Mutex::Autolock lock(mLock);
1260 mEventQ.put(&msg);
1261 }
1262 }
1263 else
1264 {
1265 CAMHAL_LOGEA("Not enough resources to allocate CameraHalEvent");
1266 }
1267
1268 }
1269
1270 LOG_FUNCTION_NAME_EXIT;
1271}
1272
1273
1274void AppCallbackNotifier::flushEventQueue()
1275{
1276
1277 MSGUTILS::Message msg;
1278 CameraHalEvent *evt = NULL;
1279 {
1280 Mutex::Autolock lock(mLock);
1281 while (!mEventQ.isEmpty()){
1282 mEventQ.get(&msg);
1283 evt = (CameraHalEvent *)msg.arg1;
1284 if (NULL != evt){
1285 delete evt;
1286 evt = NULL;
1287 }
1288 }
1289
1290 //mEventQ.clear();
1291 }
1292}
1293
1294
1295bool AppCallbackNotifier::processMessage()
1296{
1297 ///Retrieve the command from the command queue and process it
1298 MSGUTILS::Message msg;
1299
1300 LOG_FUNCTION_NAME;
1301
1302 CAMHAL_LOGDA("+Msg get...");
1303 mNotificationThread->msgQ().get(&msg);
1304 CAMHAL_LOGDA("-Msg get...");
1305 bool ret = true;
1306
1307 switch(msg.command)
1308 {
1309 case NotificationThread::NOTIFIER_EXIT:
1310 {
1311 CAMHAL_LOGEA("Received NOTIFIER_EXIT command from Camera HAL");
1312 mNotifierState = AppCallbackNotifier::NOTIFIER_EXITED;
1313 ret = false;
1314 break;
1315 }
1316 default:
1317 {
1318 CAMHAL_LOGEA("Error: ProcessMsg() command from Camera HAL");
1319 break;
1320 }
1321 }
1322
1323 LOG_FUNCTION_NAME_EXIT;
1324
1325 return ret;
1326
1327
1328}
1329
1330AppCallbackNotifier::~AppCallbackNotifier()
1331{
1332 LOG_FUNCTION_NAME;
1333
1334 ///Stop app callback notifier if not already stopped
1335 stop();
1336
1337 ///Unregister with the frame provider
1338 if ( NULL != mFrameProvider )
1339 {
1340 mFrameProvider->disableFrameNotification(CameraFrame::ALL_FRAMES);
1341 }
1342
1343 //unregister with the event provider
1344 if ( NULL != mEventProvider )
1345 {
1346 mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
1347 }
1348
1349 MSGUTILS::Message msg = {0,0,0,0,0,0};
1350 msg.command = NotificationThread::NOTIFIER_EXIT;
1351
1352 ///Post the message to display thread
1353 mNotificationThread->msgQ().put(&msg);
1354
1355 //Exit and cleanup the thread
1356 mNotificationThread->requestExit();
1357 mNotificationThread->join();
1358
1359 //Delete the display thread
1360 mNotificationThread.clear();
1361
1362
1363 ///Free the event and frame providers
1364 if ( NULL != mEventProvider )
1365 {
1366 ///Deleting the event provider
1367 CAMHAL_LOGDA("Stopping Event Provider");
1368 delete mEventProvider;
1369 mEventProvider = NULL;
1370 }
1371
1372 if ( NULL != mFrameProvider )
1373 {
1374 ///Deleting the frame provider
1375 CAMHAL_LOGDA("Stopping Frame Provider");
1376 delete mFrameProvider;
1377 mFrameProvider = NULL;
1378 }
1379
1380 releaseSharedVideoBuffers();
1381
1382 LOG_FUNCTION_NAME_EXIT;
1383}
1384
1385//Free all video heaps and buffers
1386void AppCallbackNotifier::releaseSharedVideoBuffers()
1387{
1388 LOG_FUNCTION_NAME;
1389
1390 if(mUseMetaDataBufferMode)
1391 {
1392 camera_memory_t* videoMedatadaBufferMemory;
1393 for (unsigned int i = 0; i < mVideoMetadataBufferMemoryMap.size(); i++)
1394 {
1395 videoMedatadaBufferMemory = (camera_memory_t*) mVideoMetadataBufferMemoryMap.valueAt(i);
1396 if(NULL != videoMedatadaBufferMemory)
1397 {
1398 videoMedatadaBufferMemory->release(videoMedatadaBufferMemory);
1399 CAMHAL_LOGDB("Released videoMedatadaBufferMemory=0x%x", (uint32_t)videoMedatadaBufferMemory);
1400 }
1401 }
1402
1403 mVideoMetadataBufferMemoryMap.clear();
1404 mVideoMetadataBufferReverseMap.clear();
1405 if (mUseVideoBuffers)
1406 {
1407 mVideoMap.clear();
1408 }
1409 }
1410 else
1411 {
1412#ifndef AMLOGIC_CAMERA_OVERLAY_SUPPORT
1413 camera_memory_t* VideoCameraBufferMemoryBase = NULL;
1414 for (unsigned int i = 0; i < mVideoHeaps.size(); i++)
1415 {
1416 VideoCameraBufferMemoryBase = (camera_memory_t*) mVideoHeaps.valueAt(i);
1417 if(NULL != VideoCameraBufferMemoryBase)
1418 {
1419 VideoCameraBufferMemoryBase->release(VideoCameraBufferMemoryBase);
1420 CAMHAL_LOGDB("Released VideoCameraBufferMemoryBase=0x%x", (uint32_t)VideoCameraBufferMemoryBase);
1421 }
1422 }
1423#endif
1424 mVideoMap.clear();
1425 mVideoHeaps.clear();
1426 }
1427
1428 LOG_FUNCTION_NAME_EXIT;
1429}
1430
1431void AppCallbackNotifier::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
1432{
1433
1434 LOG_FUNCTION_NAME;
1435 ///@remarks There is no NULL check here. We will check
1436 ///for NULL when we get start command from CameraHal
1437 ///@Remarks Currently only one event provider (CameraAdapter) is supported
1438 ///@todo Have an array of event providers for each event bitmask
1439 mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
1440 if ( NULL == mEventProvider )
1441 {
1442 CAMHAL_LOGEA("Error in creating EventProvider");
1443 }
1444 else
1445 {
1446 mEventProvider->enableEventNotification(eventMask);
1447 }
1448
1449 LOG_FUNCTION_NAME_EXIT;
1450}
1451
1452void AppCallbackNotifier::setFrameProvider(FrameNotifier *frameNotifier)
1453{
1454 LOG_FUNCTION_NAME;
1455 ///@remarks There is no NULL check here. We will check
1456 ///for NULL when we get the start command from CameraAdapter
1457 mFrameProvider = new FrameProvider(frameNotifier, this, frameCallbackRelay);
1458 if ( NULL == mFrameProvider )
1459 {
1460 CAMHAL_LOGEA("Error in creating FrameProvider");
1461 }
1462 else
1463 {
1464 //Register only for captured images and RAW for now
1465 //TODO: Register for and handle all types of frames
1466 mFrameProvider->enableFrameNotification(CameraFrame::IMAGE_FRAME);
1467 mFrameProvider->enableFrameNotification(CameraFrame::RAW_FRAME);
1468 }
1469
1470 LOG_FUNCTION_NAME_EXIT;
1471}
1472
1473status_t AppCallbackNotifier::startPreviewCallbacks(CameraParameters &params, void *buffers, uint32_t *offsets, int fd, size_t length, size_t count)
1474{
1475 sp<MemoryHeapBase> heap;
1476 sp<MemoryBase> buffer;
1477 unsigned int *bufArr;
1478 size_t size = 0;
1479
1480 LOG_FUNCTION_NAME;
1481
1482 Mutex::Autolock lock(mLock);
1483
1484 if ( NULL == mFrameProvider )
1485 {
1486 CAMHAL_LOGEA("Trying to start video recording without FrameProvider");
1487 return -EINVAL;
1488 }
1489
1490 if ( mPreviewing )
1491 {
1492 CAMHAL_LOGDA("+Already previewing");
1493 return NO_INIT;
1494 }
1495
1496 int w,h;
1497 ///Get preview size
1498 params.getPreviewSize(&w, &h);
1499
1500 //Get the preview pixel format
1501 mPreviewPixelFormat = params.getPreviewFormat();
1502
1503 if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0)
1504 {
1505 size = w*h*2;
1506 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV422I;
1507 }
1508 else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 )
1509 {
1510 size = (w*h*3)/2;
1511 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420SP;
1512 }
1513 else if( strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0)
1514 {
1515 int y_size,c_size,c_stride;
1516 w = ALIGN(w,2);
1517 y_size = w*h;
1518 c_stride = ALIGN(w/2, 16);
1519 c_size = c_stride * h/2;
1520 size = y_size + c_size*2;
1521
1522 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420P;
1523 }
1524 else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0)
1525 {
1526 size = w*h*2;
1527 mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_RGB565;
1528 }
1529
1530#ifdef METADATA_MODE_FOR_PREVIEW_CALLBACK
1531 if (mUseMetaDataBufferMode)
1532 size = sizeof(video_metadata_t) + 4;
1533#endif
1534
1535 mPreviewMemory = mRequestMemory(-1, size, AppCallbackNotifier::MAX_BUFFERS, NULL);
1536 if (!mPreviewMemory) {
1537 return NO_MEMORY;
1538 }
1539
1540 for (int i=0; i < AppCallbackNotifier::MAX_BUFFERS; i++) {
1541 mPreviewBufs[i] = (unsigned char*) mPreviewMemory->data + (i*size);
1542 }
1543
1544 if ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME ) ) {
1545 mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
1546 }
1547
1548 mPreviewBufCount = 0;
1549
1550 mPreviewing = true;
1551
1552 LOG_FUNCTION_NAME;
1553
1554 return NO_ERROR;
1555}
1556
1557void AppCallbackNotifier::setBurst(bool burst)
1558{
1559 LOG_FUNCTION_NAME;
1560
1561 Mutex::Autolock lock(mBurstLock);
1562
1563 mBurst = burst;
1564
1565 LOG_FUNCTION_NAME_EXIT;
1566}
1567
1568void AppCallbackNotifier::useVideoBuffers(bool useVideoBuffers)
1569{
1570 LOG_FUNCTION_NAME;
1571#ifndef AMLOGIC_CAMERA_OVERLAY_SUPPORT
1572 mUseVideoBuffers = useVideoBuffers;
1573 CAMHAL_LOGDB("Set mUseVideoBuffers as %d",(uint32_t)useVideoBuffers);
1574#endif
1575 LOG_FUNCTION_NAME_EXIT;
1576}
1577
1578bool AppCallbackNotifier::getUseVideoBuffers()
1579{
1580 return mUseVideoBuffers;
1581}
1582
1583void AppCallbackNotifier::setVideoRes(int width, int height)
1584{
1585 LOG_FUNCTION_NAME;
1586
1587 mVideoWidth = width;
1588 mVideoHeight = height;
1589
1590 LOG_FUNCTION_NAME_EXIT;
1591}
1592
1593status_t AppCallbackNotifier::stopPreviewCallbacks()
1594{
1595 sp<MemoryHeapBase> heap;
1596 sp<MemoryBase> buffer;
1597
1598 LOG_FUNCTION_NAME;
1599
1600 if ( NULL == mFrameProvider )
1601 {
1602 CAMHAL_LOGEA("Trying to stop preview callbacks without FrameProvider");
1603 return -EINVAL;
1604 }
1605
1606 if ( !mPreviewing )
1607 {
1608 return NO_INIT;
1609 }
1610
1611 mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
1612
1613 {
1614 Mutex::Autolock lock(mLock);
1615 mPreviewMemory->release(mPreviewMemory);
1616 }
1617
1618 mPreviewing = false;
1619
1620 LOG_FUNCTION_NAME_EXIT;
1621
1622 return NO_ERROR;
1623
1624}
1625
1626status_t AppCallbackNotifier::useMetaDataBufferMode(bool enable)
1627{
1628 mUseMetaDataBufferMode = enable;
1629 CAMHAL_LOGDB("Set mUseMetaDataBufferMode as %d",(uint32_t)enable);
1630 return NO_ERROR;
1631}
1632
1633
1634status_t AppCallbackNotifier::startRecording()
1635{
1636 status_t ret = NO_ERROR;
1637
1638 LOG_FUNCTION_NAME;
1639
1640 Mutex::Autolock lock(mRecordingLock);
1641
1642 if ( NULL == mFrameProvider )
1643 {
1644 CAMHAL_LOGEA("Trying to start video recording without FrameProvider");
1645 ret = -1;
1646 }
1647
1648 if(mRecording)
1649 {
1650 return NO_INIT;
1651 }
1652
1653 if ( NO_ERROR == ret )
1654 {
1655 mFrameProvider->enableFrameNotification(CameraFrame::VIDEO_FRAME_SYNC);
1656 }
1657
1658 mRecording = true;
1659
1660 LOG_FUNCTION_NAME_EXIT;
1661
1662 return ret;
1663}
1664
1665//Allocate metadata buffers for video recording
1666status_t AppCallbackNotifier::initSharedVideoBuffers(void *buffers, uint32_t *offsets, int fd, size_t length, size_t count, void *vidBufs)
1667{
1668 status_t ret = NO_ERROR;
1669 LOG_FUNCTION_NAME;
1670
1671 if(mUseMetaDataBufferMode)
1672 {
1673 uint32_t *bufArr = NULL;
1674 camera_memory_t* videoMedatadaBufferMemory = NULL;
1675
1676 if(NULL == buffers)
1677 {
1678 CAMHAL_LOGEA("Error! Video buffers are NULL");
1679 return BAD_VALUE;
1680 }
1681 bufArr = (uint32_t *) buffers;
1682
1683 for (uint32_t i = 0; i < count; i++)
1684 {
1685 videoMedatadaBufferMemory = mRequestMemory(-1, sizeof(video_metadata_t), 1, NULL);
1686 if((NULL == videoMedatadaBufferMemory) || (NULL == videoMedatadaBufferMemory->data))
1687 {
1688 CAMHAL_LOGEA("Error! Could not allocate memory for Video Metadata Buffers");
1689 return NO_MEMORY;
1690 }
1691
1692 mVideoMetadataBufferMemoryMap.add(bufArr[i], (uint32_t)(videoMedatadaBufferMemory));
1693 mVideoMetadataBufferReverseMap.add((uint32_t)(videoMedatadaBufferMemory->data), bufArr[i]);
1694 CAMHAL_LOGDB("bufArr[%d]=0x%x, videoMedatadaBufferMemory=0x%x, videoMedatadaBufferMemory->data=0x%x",
1695 i, bufArr[i], (uint32_t)videoMedatadaBufferMemory, (uint32_t)videoMedatadaBufferMemory->data);
1696
1697 if (vidBufs != NULL)
1698 {
1699 uint32_t *vBufArr = (uint32_t *) vidBufs;
1700 mVideoMap.add(bufArr[i], vBufArr[i]);
1701 CAMHAL_LOGVB("bufArr[%d]=0x%x, vBuffArr[%d]=0x%x", i, bufArr[i], i, vBufArr[i]);
1702 }
1703 }
1704 }
1705 else
1706 {
1707 uint32_t *bufArr = NULL;
1708 camera_memory_t* VideoCameraBufferMemoryBase = NULL;
1709
1710 if(NULL == buffers)
1711 {
1712 CAMHAL_LOGEA("Error! Video buffers are NULL");
1713 return BAD_VALUE;
1714 }
1715 bufArr = (uint32_t *) buffers;
1716
1717 for (uint32_t i = 0; i < count; i++)
1718 {
1719 #ifdef AMLOGIC_CAMERA_OVERLAY_SUPPORT
1720 VideoCameraBufferMemoryBase = (camera_memory_t*)bufArr[i];
1721 #else
1722 VideoCameraBufferMemoryBase = mRequestMemory(-1, mVideoWidth*mVideoHeight*3/2, 1, NULL); // only supported nv21 or nv12;
1723 #endif
1724 if((NULL == VideoCameraBufferMemoryBase) || (NULL == VideoCameraBufferMemoryBase->data))
1725 {
1726 CAMHAL_LOGEA("Error! Could not allocate memory for Video Metadata Buffers");
1727 return NO_MEMORY;
1728 }
1729 mVideoHeaps.add(bufArr[i], (uint32_t)(VideoCameraBufferMemoryBase));
1730 mVideoMap.add((uint32_t)(VideoCameraBufferMemoryBase->data),bufArr[i]);
1731 CAMHAL_LOGDB("bufArr[%d]=0x%x, VideoCameraBufferMemoryBase=0x%x, VideoCameraBufferMemoryBase->data=0x%x",
1732 i, bufArr[i], (uint32_t)VideoCameraBufferMemoryBase, (uint32_t)VideoCameraBufferMemoryBase->data);
1733 }
1734 }
1735exit:
1736 LOG_FUNCTION_NAME_EXIT;
1737
1738 return ret;
1739}
1740
1741status_t AppCallbackNotifier::stopRecording()
1742{
1743 status_t ret = NO_ERROR;
1744
1745 LOG_FUNCTION_NAME;
1746
1747 Mutex::Autolock lock(mRecordingLock);
1748
1749 if ( NULL == mFrameProvider )
1750 {
1751 CAMHAL_LOGEA("Trying to stop video recording without FrameProvider");
1752 ret = -1;
1753 }
1754
1755 if(!mRecording)
1756 {
1757 return NO_INIT;
1758 }
1759
1760 if ( NO_ERROR == ret )
1761 {
1762 mFrameProvider->disableFrameNotification(CameraFrame::VIDEO_FRAME_SYNC);
1763 }
1764
1765 ///Release the shared video buffers
1766 releaseSharedVideoBuffers();
1767
1768 mRecording = false;
1769
1770 LOG_FUNCTION_NAME_EXIT;
1771
1772 return ret;
1773}
1774
1775status_t AppCallbackNotifier::releaseRecordingFrame(const void* mem)
1776{
1777 status_t ret = NO_ERROR;
1778 void *frame = NULL;
1779
1780 LOG_FUNCTION_NAME;
1781 if ( NULL == mFrameProvider )
1782 {
1783 CAMHAL_LOGEA("Trying to stop video recording without FrameProvider");
1784 ret = -1;
1785 }
1786
1787 if ( NULL == mem )
1788 {
1789 CAMHAL_LOGEA("Video Frame released is invalid");
1790 ret = -1;
1791 }
1792
1793 if( NO_ERROR != ret )
1794 {
1795 return ret;
1796 }
1797
1798 if(mUseMetaDataBufferMode)
1799 {
1800 video_metadata_t *videoMetadataBuffer = (video_metadata_t *) mem ;
1801 frame = (void*) mVideoMetadataBufferReverseMap.valueFor((uint32_t) videoMetadataBuffer);
1802 CAMHAL_LOGVB("Releasing frame with videoMetadataBuffer=0x%x, videoMetadataBuffer->handle=0x%x & frame handle=0x%x\n",
1803 videoMetadataBuffer, videoMetadataBuffer->handle, frame);
1804 }
1805 else
1806 {
1807 frame = (void *)mVideoMap.valueFor((uint32_t)mem);
1808 //CAMHAL_LOGDB("release recording mem.0x%x, frame:0x%x",(uint32_t)mem,(uint32_t)frame);
1809 }
1810
1811 if ( NO_ERROR == ret )
1812 {
1813 ret = mFrameProvider->returnFrame(frame, CameraFrame::VIDEO_FRAME_SYNC);
1814 }
1815
1816 LOG_FUNCTION_NAME_EXIT;
1817
1818 return ret;
1819}
1820
1821status_t AppCallbackNotifier::enableMsgType(int32_t msgType)
1822{
1823 if( msgType & (CAMERA_MSG_POSTVIEW_FRAME | CAMERA_MSG_PREVIEW_FRAME) ) {
1824 //if( msgType & (CAMERA_MSG_PREVIEW_FRAME) ) {
1825 mFrameProvider->enableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
1826 }
1827 return NO_ERROR;
1828}
1829
1830status_t AppCallbackNotifier::disableMsgType(int32_t msgType)
1831{
1832 //if(!mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_POSTVIEW_FRAME)) {
1833 if(!(msgType & (CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_POSTVIEW_FRAME))){
1834 mFrameProvider->disableFrameNotification(CameraFrame::PREVIEW_FRAME_SYNC);
1835 }
1836 return NO_ERROR;
1837}
1838
1839status_t AppCallbackNotifier::start()
1840{
1841 LOG_FUNCTION_NAME;
1842 if(mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED)
1843 {
1844 CAMHAL_LOGDA("AppCallbackNotifier already running");
1845 LOG_FUNCTION_NAME_EXIT;
1846 return ALREADY_EXISTS;
1847 }
1848
1849 ///Check whether initial conditions are met for us to start
1850 ///A frame provider should be available, if not return error
1851 if(!mFrameProvider)
1852 {
1853 ///AppCallbackNotifier not properly initialized
1854 CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Frame provider is NULL");
1855 LOG_FUNCTION_NAME_EXIT;
1856 return NO_INIT;
1857 }
1858
1859 ///At least one event notifier should be available, if not return error
1860 ///@todo Modify here when there is an array of event providers
1861 if(!mEventProvider)
1862 {
1863 CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Event provider is NULL");
1864 LOG_FUNCTION_NAME_EXIT;
1865 ///AppCallbackNotifier not properly initialized
1866 return NO_INIT;
1867 }
1868
1869 mNotifierState = AppCallbackNotifier::NOTIFIER_STARTED;
1870 CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STARTED \n");
1871
1872 gEncoderQueue.clear();
1873
1874 LOG_FUNCTION_NAME_EXIT;
1875
1876 return NO_ERROR;
1877
1878}
1879
1880status_t AppCallbackNotifier::stop()
1881{
1882 LOG_FUNCTION_NAME;
1883
1884 if(mNotifierState!=AppCallbackNotifier::NOTIFIER_STARTED)
1885 {
1886 CAMHAL_LOGDA("AppCallbackNotifier already in stopped state");
1887 LOG_FUNCTION_NAME_EXIT;
1888 return ALREADY_EXISTS;
1889 }
1890
1891 {
1892 Mutex::Autolock lock(mLock);
1893
1894 mNotifierState = AppCallbackNotifier::NOTIFIER_STOPPED;
1895 CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STOPPED \n");
1896 }
1897
1898 while(!gEncoderQueue.isEmpty()) {
1899 sp<Encoder_libjpeg> encoder = gEncoderQueue.valueAt(0);
1900 if(encoder.get()) {
1901 encoder->cancel();
1902 encoder->join();
1903 encoder.clear();
1904 }
1905 gEncoderQueue.removeItemsAt(0);
1906 }
1907
1908 LOG_FUNCTION_NAME_EXIT;
1909 return NO_ERROR;
1910}
1911
1912
1913/*--------------------NotificationHandler Class ENDS here-----------------------------*/
1914
1915
1916
1917};
1918