1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18* @file CameraHal.cpp
19*
20* This file maps the Camera Hardware Interface to V4L2.
21*
22*/
23
24#include "CameraHal.h"
25#include "ANativeWindowDisplayAdapter.h"
26#include "BufferSourceAdapter.h"
27#include "TICameraParameters.h"
28#include "CameraProperties.h"
29#include <cutils/properties.h>
30
31#include <poll.h>
32#include <math.h>
33
34namespace Ti {
35namespace Camera {
36
37extern "C" CameraAdapter* OMXCameraAdapter_Factory(size_t);
38extern "C" CameraAdapter* V4LCameraAdapter_Factory(size_t);
39
40/*****************************************************************************/
41
42////Constant definitions and declarations
43////@todo Have a CameraProperties class to store these parameters as constants for every camera
44////       Currently, they are hard-coded
45
46const int CameraHal::NO_BUFFERS_PREVIEW = MAX_CAMERA_BUFFERS;
47const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 5;
48const int CameraHal::SW_SCALING_FPS_LIMIT = 15;
49
50const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 16;
51
52const uint32_t MessageNotifier::FRAME_BIT_FIELD_POSITION = 0;
53
54// TODO(XXX): Temporarily increase number of buffers we can allocate from ANW
55// until faux-NPA mode is implemented
56const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP = 15;
57
58#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
59// HACK: Default path to directory where RAW images coming from video port will be saved to.
60//       If directory not exists the saving is skipped and video port frame is ignored.
61//       The directory name is choosed in so weird way to enable RAW images saving only when
62//       directory has been created explicitly by user.
63extern const char * const kRawImagesOutputDirPath = "/data/misc/camera/RaW_PiCtUrEs";
64extern const char * const kYuvImagesOutputDirPath = "/data/misc/camera/YuV_PiCtUrEs";
65#endif
66
67/******************************************************************************/
68
69
70#ifdef OMAP_ENHANCEMENT_CPCAM
71static int dummy_update_and_get_buffer(preview_stream_ops_t*, buffer_handle_t**, int*) {
72    return INVALID_OPERATION;
73}
74
75static int dummy_get_buffer_dimension(preview_stream_ops_t*, int*, int*) {
76    return INVALID_OPERATION;
77}
78
79static int dummy_get_buffer_format(preview_stream_ops_t*, int*) {
80    return INVALID_OPERATION;
81}
82
83static int dummy_set_metadata(preview_stream_ops_t*, const camera_memory_t*) {
84    return INVALID_OPERATION;
85}
86
87static int dummy_get_id(preview_stream_ops_t*, char *data, unsigned int dataSize) {
88    return INVALID_OPERATION;
89}
90
91static int dummy_get_buffer_count(preview_stream_ops_t*, int *count) {
92    return INVALID_OPERATION;
93}
94
95static int dummy_get_crop(preview_stream_ops_t*,
96                          int *, int *, int *, int *) {
97    return INVALID_OPERATION;
98}
99
100static int dummy_get_current_size(preview_stream_ops_t*,
101                                  int *, int *) {
102    return INVALID_OPERATION;
103}
104#endif
105
106#ifdef OMAP_ENHANCEMENT
107static preview_stream_extended_ops_t dummyPreviewStreamExtendedOps = {
108#ifdef OMAP_ENHANCEMENT_CPCAM
109    dummy_update_and_get_buffer,
110    dummy_get_buffer_dimension,
111    dummy_get_buffer_format,
112    dummy_set_metadata,
113    dummy_get_id,
114    dummy_get_buffer_count,
115    dummy_get_crop,
116    dummy_get_current_size,
117#endif
118};
119#endif
120
121
122DisplayAdapter::DisplayAdapter()
123{
124#ifdef OMAP_ENHANCEMENT
125    mExtendedOps = &dummyPreviewStreamExtendedOps;
126#endif
127}
128
129#ifdef OMAP_ENHANCEMENT
130void DisplayAdapter::setExtendedOps(preview_stream_extended_ops_t * extendedOps) {
131    mExtendedOps = extendedOps ? extendedOps : &dummyPreviewStreamExtendedOps;
132}
133#endif
134
135
136
137#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
138
139struct timeval CameraHal::mStartPreview;
140struct timeval CameraHal::mStartFocus;
141struct timeval CameraHal::mStartCapture;
142
143#endif
144
145static void orientation_cb(uint32_t orientation, uint32_t tilt, void* cookie) {
146    CameraHal *camera = NULL;
147
148    if (cookie) {
149        camera = (CameraHal*) cookie;
150        camera->onOrientationEvent(orientation, tilt);
151    }
152
153}
154
155/*-------------Camera Hal Interface Method definitions STARTS here--------------------*/
156
157/**
158  Callback function to receive orientation events from SensorListener
159 */
160void CameraHal::onOrientationEvent(uint32_t orientation, uint32_t tilt) {
161    LOG_FUNCTION_NAME;
162
163    if ( NULL != mCameraAdapter ) {
164        mCameraAdapter->onOrientationEvent(orientation, tilt);
165    }
166
167    LOG_FUNCTION_NAME_EXIT;
168}
169
170/**
171   @brief Set the notification and data callbacks
172
173   @param[in] notify_cb Notify callback for notifying the app about events and errors
174   @param[in] data_cb   Buffer callback for sending the preview/raw frames to the app
175   @param[in] data_cb_timestamp Buffer callback for sending the video frames w/ timestamp
176   @param[in] user  Callback cookie
177   @return none
178
179 */
180void CameraHal::setCallbacks(camera_notify_callback notify_cb,
181                            camera_data_callback data_cb,
182                            camera_data_timestamp_callback data_cb_timestamp,
183                            camera_request_memory get_memory,
184                            void *user)
185{
186    LOG_FUNCTION_NAME;
187
188    if ( NULL != mAppCallbackNotifier.get() )
189    {
190            mAppCallbackNotifier->setCallbacks(this,
191                                                notify_cb,
192                                                data_cb,
193                                                data_cb_timestamp,
194                                                get_memory,
195                                                user);
196    }
197
198    if ( NULL != mCameraAdapter ) {
199        mCameraAdapter->setSharedAllocator(get_memory);
200    }
201
202    LOG_FUNCTION_NAME_EXIT;
203}
204
205/**
206   @brief Enable a message, or set of messages.
207
208   @param[in] msgtype Bitmask of the messages to enable (defined in include/ui/Camera.h)
209   @return none
210
211 */
212void CameraHal::enableMsgType(int32_t msgType)
213{
214    LOG_FUNCTION_NAME;
215
216    if ( ( msgType & CAMERA_MSG_SHUTTER ) && ( !mShutterEnabled ) )
217        {
218        msgType &= ~CAMERA_MSG_SHUTTER;
219        }
220
221    // ignoring enable focus message from camera service
222    // we will enable internally in autoFocus call
223    msgType &= ~CAMERA_MSG_FOCUS;
224#ifdef ANDROID_API_JB_OR_LATER
225    msgType &= ~CAMERA_MSG_FOCUS_MOVE;
226#endif
227
228    {
229    android::AutoMutex lock(mLock);
230    mMsgEnabled |= msgType;
231    }
232
233    if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
234    {
235        if(mDisplayPaused)
236        {
237            CAMHAL_LOGDA("Preview currently paused...will enable preview callback when restarted");
238            msgType &= ~CAMERA_MSG_PREVIEW_FRAME;
239        }else
240        {
241            CAMHAL_LOGDA("Enabling Preview Callback");
242        }
243    }
244    else
245    {
246        CAMHAL_LOGDB("Preview callback not enabled %x", msgType);
247    }
248
249
250    ///Configure app callback notifier with the message callback required
251    mAppCallbackNotifier->enableMsgType (msgType);
252
253    LOG_FUNCTION_NAME_EXIT;
254}
255
256/**
257   @brief Disable a message, or set of messages.
258
259   @param[in] msgtype Bitmask of the messages to disable (defined in include/ui/Camera.h)
260   @return none
261
262 */
263void CameraHal::disableMsgType(int32_t msgType)
264{
265    LOG_FUNCTION_NAME;
266
267        {
268        android::AutoMutex lock(mLock);
269        mMsgEnabled &= ~msgType;
270        }
271
272    if( msgType & CAMERA_MSG_PREVIEW_FRAME)
273        {
274        CAMHAL_LOGDA("Disabling Preview Callback");
275        }
276
277    ///Configure app callback notifier
278    mAppCallbackNotifier->disableMsgType (msgType);
279
280    LOG_FUNCTION_NAME_EXIT;
281}
282
283/**
284   @brief Query whether a message, or a set of messages, is enabled.
285
286   Note that this is operates as an AND, if any of the messages queried are off, this will
287   return false.
288
289   @param[in] msgtype Bitmask of the messages to query (defined in include/ui/Camera.h)
290   @return true If all message types are enabled
291          false If any message type
292
293 */
294int CameraHal::msgTypeEnabled(int32_t msgType)
295{
296    int32_t msgEnabled = 0;
297
298    LOG_FUNCTION_NAME;
299    android::AutoMutex lock(mLock);
300
301    msgEnabled = mMsgEnabled;
302    if (!previewEnabled() && !mPreviewInitializationDone) {
303        msgEnabled &= ~(CAMERA_MSG_PREVIEW_FRAME | CAMERA_MSG_PREVIEW_METADATA);
304    }
305
306    LOG_FUNCTION_NAME_EXIT;
307    return (msgEnabled & msgType);
308}
309
310/**
311   @brief Set the camera parameters.
312
313   @param[in] params Camera parameters to configure the camera
314   @return NO_ERROR
315   @todo Define error codes
316
317 */
318int CameraHal::setParameters(const char* parameters)
319{
320
321    LOG_FUNCTION_NAME;
322
323    android::CameraParameters params;
324
325    android::String8 str_params(parameters);
326    params.unflatten(str_params);
327
328    LOG_FUNCTION_NAME_EXIT;
329
330    return setParameters(params);
331}
332
333/**
334   @brief Set the camera parameters.
335
336   @param[in] params Camera parameters to configure the camera
337   @return NO_ERROR
338   @todo Define error codes
339
340 */
341int CameraHal::setParameters(const android::CameraParameters& params)
342{
343
344    LOG_FUNCTION_NAME;
345
346    int w, h;
347    int framerate;
348    int maxFPS, minFPS;
349    const char *valstr = NULL;
350    int varint = 0;
351    status_t ret = NO_ERROR;
352    // Needed for KEY_RECORDING_HINT
353    bool restartPreviewRequired = false;
354    bool updateRequired = false;
355    android::CameraParameters oldParams = mParameters;
356
357#ifdef V4L_CAMERA_ADAPTER
358    if (strcmp (V4L_CAMERA_NAME_USB, mCameraProperties->get(CameraProperties::CAMERA_NAME)) == 0 ) {
359        updateRequired = true;
360    }
361#endif
362
363    {
364        android::AutoMutex lock(mLock);
365
366        ///Ensure that preview is not enabled when the below parameters are changed.
367        if(!previewEnabled())
368            {
369            if ((valstr = params.getPreviewFormat()) != NULL) {
370                if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS))) {
371                    mParameters.setPreviewFormat(valstr);
372                    CAMHAL_LOGDB("PreviewFormat set %s", valstr);
373                } else {
374                    CAMHAL_LOGEB("Invalid preview format: %s. Supported: %s", valstr,
375                        mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
376                    return BAD_VALUE;
377                }
378            }
379
380            if ((valstr = params.get(TICameraParameters::KEY_VNF)) != NULL) {
381                if (strcmp(mCameraProperties->get(CameraProperties::VNF_SUPPORTED),
382                           android::CameraParameters::TRUE) == 0) {
383                    CAMHAL_LOGDB("VNF %s", valstr);
384                    mParameters.set(TICameraParameters::KEY_VNF, valstr);
385                } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
386                    CAMHAL_LOGEB("ERROR: Invalid VNF: %s", valstr);
387                    return BAD_VALUE;
388                } else {
389                    mParameters.set(TICameraParameters::KEY_VNF,
390                                    android::CameraParameters::FALSE);
391                }
392            }
393
394            if ((valstr = params.get(android::CameraParameters::KEY_VIDEO_STABILIZATION)) != NULL) {
395                // make sure we support vstab...if we don't and application is trying to set
396                // vstab then return an error
397                if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
398                           android::CameraParameters::TRUE) == 0) {
399                    CAMHAL_LOGDB("VSTAB %s", valstr);
400                    mParameters.set(android::CameraParameters::KEY_VIDEO_STABILIZATION, valstr);
401                } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
402                    CAMHAL_LOGEB("ERROR: Invalid VSTAB: %s", valstr);
403                    return BAD_VALUE;
404                } else {
405                    mParameters.set(android::CameraParameters::KEY_VIDEO_STABILIZATION,
406                                    android::CameraParameters::FALSE);
407                }
408            }
409
410            if( (valstr = params.get(TICameraParameters::KEY_CAP_MODE)) != NULL) {
411
412                    if (strcmp(TICameraParameters::VIDEO_MODE, valstr)) {
413                        mCapModeBackup = valstr;
414                    }
415
416                    CAMHAL_LOGDB("Capture mode set %s", valstr);
417
418                    const char *currentMode = mParameters.get(TICameraParameters::KEY_CAP_MODE);
419                    if ( NULL != currentMode ) {
420                        if ( strcmp(currentMode, valstr) != 0 ) {
421                            updateRequired = true;
422                        }
423                    } else {
424                        updateRequired = true;
425                    }
426
427                    mParameters.set(TICameraParameters::KEY_CAP_MODE, valstr);
428            } else if (!mCapModeBackup.isEmpty()) {
429                // Restore previous capture mode after stopPreview()
430                mParameters.set(TICameraParameters::KEY_CAP_MODE,
431                                mCapModeBackup.string());
432                updateRequired = true;
433            }
434
435#ifdef OMAP_ENHANCEMENT_VTC
436            if ((valstr = params.get(TICameraParameters::KEY_VTC_HINT)) != NULL ) {
437                mParameters.set(TICameraParameters::KEY_VTC_HINT, valstr);
438                if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
439                    mVTCUseCase = true;
440                } else {
441                    mVTCUseCase = false;
442                }
443                CAMHAL_LOGDB("VTC Hint = %d", mVTCUseCase);
444            }
445
446            if (mVTCUseCase) {
447                if ((valstr = params.get(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE)) != NULL ) {
448                    mParameters.set(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE, valstr);
449                }
450
451                if ((valstr = params.get(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT)) != NULL ) {
452                    mParameters.set(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT, valstr);
453                }
454            }
455#endif
456        }
457
458        if ((valstr = params.get(TICameraParameters::KEY_IPP)) != NULL) {
459            if (isParameterValid(valstr,mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES))) {
460                if ((mParameters.get(TICameraParameters::KEY_IPP) == NULL) ||
461                        (strcmp(valstr, mParameters.get(TICameraParameters::KEY_IPP)))) {
462                    CAMHAL_LOGDB("IPP mode set %s", params.get(TICameraParameters::KEY_IPP));
463                    mParameters.set(TICameraParameters::KEY_IPP, valstr);
464                    restartPreviewRequired = true;
465                }
466            } else {
467                CAMHAL_LOGEB("ERROR: Invalid IPP mode: %s", valstr);
468                return BAD_VALUE;
469            }
470        }
471
472        if ( (valstr = params.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)) != NULL )
473            {
474            if (strcmp(valstr, mParameters.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)))
475                {
476                CAMHAL_LOGDB("Stereo 3D preview image layout is %s", valstr);
477                mParameters.set(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT, valstr);
478                restartPreviewRequired = true;
479                }
480            }
481
482#ifdef OMAP_ENHANCEMENT
483        int orientation =0;
484        if((valstr = params.get(TICameraParameters::KEY_SENSOR_ORIENTATION)) != NULL)
485            {
486            doesSetParameterNeedUpdate(valstr,
487                                       mParameters.get(TICameraParameters::KEY_SENSOR_ORIENTATION),
488                                       updateRequired);
489
490            orientation = params.getInt(TICameraParameters::KEY_SENSOR_ORIENTATION);
491            if ( orientation < 0 || orientation >= 360 || (orientation%90) != 0 ) {
492                CAMHAL_LOGE("Invalid sensor orientation: %s. Value must be one of: [0, 90, 180, 270]", valstr);
493                return BAD_VALUE;
494            }
495
496            CAMHAL_LOGD("Sensor Orientation is set to %d", orientation);
497            mParameters.set(TICameraParameters::KEY_SENSOR_ORIENTATION, valstr);
498            }
499#endif
500
501        params.getPreviewSize(&w, &h);
502        if (w == -1 && h == -1) {
503            CAMHAL_LOGEA("Unable to get preview size");
504            return BAD_VALUE;
505        }
506
507        mVideoWidth = w;
508        mVideoHeight = h;
509
510        // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
511        valstr = params.get(android::CameraParameters::KEY_RECORDING_HINT);
512        if(valstr != NULL)
513            {
514            CAMHAL_LOGDB("Recording Hint is set to %s", valstr);
515            if(strcmp(valstr, android::CameraParameters::TRUE) == 0)
516                {
517                CAMHAL_LOGVB("Video Resolution: %d x %d", mVideoWidth, mVideoHeight);
518#ifdef OMAP_ENHANCEMENT_VTC
519                if (!mVTCUseCase)
520#endif
521                {
522                    int maxFPS, minFPS;
523
524                    params.getPreviewFpsRange(&minFPS, &maxFPS);
525                    maxFPS /= CameraHal::VFR_SCALE;
526                    if ( ( maxFPS <= SW_SCALING_FPS_LIMIT ) ) {
527                        getPreferredPreviewRes(&w, &h);
528                    }
529                }
530                mParameters.set(android::CameraParameters::KEY_RECORDING_HINT, valstr);
531                restartPreviewRequired |= setVideoModeParameters(params);
532                }
533            else if(strcmp(valstr, android::CameraParameters::FALSE) == 0)
534                {
535                mParameters.set(android::CameraParameters::KEY_RECORDING_HINT, valstr);
536                restartPreviewRequired |= resetVideoModeParameters();
537                }
538            else
539                {
540                CAMHAL_LOGEA("Invalid RECORDING_HINT");
541                return BAD_VALUE;
542                }
543            }
544        else
545            {
546            // This check is required in following case.
547            // If VideoRecording activity sets KEY_RECORDING_HINT to TRUE and
548            // ImageCapture activity doesnot set KEY_RECORDING_HINT to FALSE (i.e. simply NULL),
549            // then Video Mode parameters may remain present in ImageCapture activity as well.
550            CAMHAL_LOGDA("Recording Hint is set to NULL");
551            mParameters.set(android::CameraParameters::KEY_RECORDING_HINT, "");
552            restartPreviewRequired |= resetVideoModeParameters();
553            }
554
555        if ( (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES)))
556                && (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SUBSAMPLED_SIZES)))
557                && (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES)))
558                && (!isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_TOPBOTTOM_SIZES))) ) {
559            CAMHAL_LOGEB("Invalid preview resolution %d x %d", w, h);
560            return BAD_VALUE;
561        }
562
563        int oldWidth, oldHeight;
564        mParameters.getPreviewSize(&oldWidth, &oldHeight);
565        if ( ( oldWidth != w ) || ( oldHeight != h ) )
566            {
567            mParameters.setPreviewSize(w, h);
568            restartPreviewRequired = true;
569            }
570
571        CAMHAL_LOGDB("Preview Resolution: %d x %d", w, h);
572
573        if ((valstr = params.get(android::CameraParameters::KEY_FOCUS_MODE)) != NULL) {
574            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES))) {
575                CAMHAL_LOGDB("Focus mode set %s", valstr);
576
577                // we need to take a decision on the capture mode based on whether CAF picture or
578                // video is chosen so the behavior of each is consistent to the application
579                if(strcmp(valstr, android::CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0){
580                    restartPreviewRequired |= resetVideoModeParameters();
581                } else if (strcmp(valstr, android::CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) == 0){
582                    restartPreviewRequired |= setVideoModeParameters(params);
583                }
584
585                mParameters.set(android::CameraParameters::KEY_FOCUS_MODE, valstr);
586             } else {
587                CAMHAL_LOGEB("ERROR: Invalid FOCUS mode = %s", valstr);
588                return BAD_VALUE;
589             }
590        }
591
592        mRawCapture = false;
593
594#ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
595        valstr = params.get(TICameraParameters::KEY_CAP_MODE);
596        if ( (!valstr || strcmp(valstr, TICameraParameters::HIGH_QUALITY_MODE) == 0) &&
597                access(kRawImagesOutputDirPath, F_OK) != -1 ) {
598            mRawCapture = true;
599        }
600#endif
601
602        if ( (valstr = params.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT)) != NULL )
603            {
604            CAMHAL_LOGDB("Stereo 3D capture image layout is %s", valstr);
605            mParameters.set(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT, valstr);
606            }
607
608        params.getPictureSize(&w, &h);
609        if ( (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES)))
610                || (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SUBSAMPLED_SIZES)))
611                || (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_TOPBOTTOM_SIZES)))
612                || (isResolutionValid(w, h, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIDEBYSIDE_SIZES))) ) {
613            mParameters.setPictureSize(w, h);
614        } else {
615            CAMHAL_LOGEB("ERROR: Invalid picture resolution %d x %d", w, h);
616            return BAD_VALUE;
617        }
618
619        CAMHAL_LOGDB("Picture Size by App %d x %d", w, h);
620
621        if ( (valstr = params.getPictureFormat()) != NULL ) {
622            if (isParameterValid(valstr,mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS))) {
623                if ((strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) &&
624                    mCameraProperties->get(CameraProperties::MAX_PICTURE_WIDTH) &&
625                    mCameraProperties->get(CameraProperties::MAX_PICTURE_HEIGHT)) {
626                    unsigned int width = 0, height = 0;
627                    // Set picture size to full frame for raw bayer capture
628                    width = atoi(mCameraProperties->get(CameraProperties::MAX_PICTURE_WIDTH));
629                    height = atoi(mCameraProperties->get(CameraProperties::MAX_PICTURE_HEIGHT));
630                    mParameters.setPictureSize(width,height);
631                }
632                mParameters.setPictureFormat(valstr);
633            } else {
634                CAMHAL_LOGEB("ERROR: Invalid picture format: %s",valstr);
635                ret = BAD_VALUE;
636            }
637        }
638
639#ifdef OMAP_ENHANCEMENT_BURST_CAPTURE
640        if ((valstr = params.get(TICameraParameters::KEY_BURST)) != NULL) {
641            if (params.getInt(TICameraParameters::KEY_BURST) >=0) {
642                CAMHAL_LOGDB("Burst set %s", valstr);
643                mParameters.set(TICameraParameters::KEY_BURST, valstr);
644            } else {
645                CAMHAL_LOGEB("ERROR: Invalid Burst value: %s",valstr);
646                return BAD_VALUE;
647            }
648        }
649#endif
650
651        // Variable framerate ranges have higher priority over
652        // deprecated constant FPS. "KEY_PREVIEW_FPS_RANGE" should
653        // be cleared by the client in order for constant FPS to get
654        // applied.
655        // If Port FPS needs to be used for configuring, then FPS RANGE should not be set by the APP.
656        valstr = params.get(android::CameraParameters::KEY_PREVIEW_FPS_RANGE);
657        if (valstr != NULL && strlen(valstr)) {
658            int curMaxFPS = 0;
659            int curMinFPS = 0;
660
661            // APP wants to set FPS range
662            // Set framerate = MAXFPS
663            CAMHAL_LOGDA("APP IS CHANGING FRAME RATE RANGE");
664
665            mParameters.getPreviewFpsRange(&curMinFPS, &curMaxFPS);
666            CAMHAL_LOGDB("## current minFPS = %d; maxFPS=%d",curMinFPS, curMaxFPS);
667
668            params.getPreviewFpsRange(&minFPS, &maxFPS);
669            CAMHAL_LOGDB("## requested minFPS = %d; maxFPS=%d",minFPS, maxFPS);
670            // Validate VFR
671            if (!isFpsRangeValid(minFPS, maxFPS, params.get(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE)) &&
672                !isFpsRangeValid(minFPS, maxFPS, params.get(TICameraParameters::KEY_FRAMERATE_RANGES_EXT_SUPPORTED))) {
673                CAMHAL_LOGEA("Invalid FPS Range");
674                return BAD_VALUE;
675            } else {
676                framerate = maxFPS / CameraHal::VFR_SCALE;
677                mParameters.setPreviewFrameRate(framerate);
678                CAMHAL_LOGDB("SET FRAMERATE %d", framerate);
679                mParameters.set(android::CameraParameters::KEY_PREVIEW_FPS_RANGE, valstr);
680                CAMHAL_LOGDB("FPS Range = %s", valstr);
681                if ( curMaxFPS == (FRAME_RATE_HIGH_HD * CameraHal::VFR_SCALE) &&
682                     maxFPS < (FRAME_RATE_HIGH_HD * CameraHal::VFR_SCALE) ) {
683                    restartPreviewRequired = true;
684                }
685            }
686        } else {
687            framerate = params.getPreviewFrameRate();
688            if (!isParameterValid(framerate, params.get(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES)) &&
689                !isParameterValid(framerate, params.get(TICameraParameters::KEY_FRAMERATES_EXT_SUPPORTED))) {
690                CAMHAL_LOGEA("Invalid frame rate");
691                return BAD_VALUE;
692            }
693            char tmpBuffer[MAX_PROP_VALUE_LENGTH];
694
695            sprintf(tmpBuffer, "%d,%d", framerate * CameraHal::VFR_SCALE, framerate * CameraHal::VFR_SCALE);
696            mParameters.setPreviewFrameRate(framerate);
697            CAMHAL_LOGDB("SET FRAMERATE %d", framerate);
698            mParameters.set(android::CameraParameters::KEY_PREVIEW_FPS_RANGE, tmpBuffer);
699            CAMHAL_LOGDB("FPS Range = %s", tmpBuffer);
700        }
701
702        if ((valstr = params.get(TICameraParameters::KEY_GBCE)) != NULL) {
703            if (strcmp(mCameraProperties->get(CameraProperties::SUPPORTED_GBCE),
704                    android::CameraParameters::TRUE) == 0) {
705                CAMHAL_LOGDB("GBCE %s", valstr);
706                mParameters.set(TICameraParameters::KEY_GBCE, valstr);
707            } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
708                CAMHAL_LOGEB("ERROR: Invalid GBCE: %s", valstr);
709                return BAD_VALUE;
710            } else {
711                mParameters.set(TICameraParameters::KEY_GBCE, android::CameraParameters::FALSE);
712            }
713        } else {
714            mParameters.set(TICameraParameters::KEY_GBCE, android::CameraParameters::FALSE);
715        }
716
717        if ((valstr = params.get(TICameraParameters::KEY_GLBCE)) != NULL) {
718            if (strcmp(mCameraProperties->get(CameraProperties::SUPPORTED_GLBCE),
719                    android::CameraParameters::TRUE) == 0) {
720                CAMHAL_LOGDB("GLBCE %s", valstr);
721                mParameters.set(TICameraParameters::KEY_GLBCE, valstr);
722            } else if (strcmp(valstr, android::CameraParameters::TRUE) == 0) {
723                CAMHAL_LOGEB("ERROR: Invalid GLBCE: %s", valstr);
724                return BAD_VALUE;
725            } else {
726                mParameters.set(TICameraParameters::KEY_GLBCE, android::CameraParameters::FALSE);
727            }
728        } else {
729            mParameters.set(TICameraParameters::KEY_GLBCE, android::CameraParameters::FALSE);
730        }
731
732#ifdef OMAP_ENHANCEMENT_S3D
733        ///Update the current parameter set
734        if ( (valstr = params.get(TICameraParameters::KEY_AUTOCONVERGENCE_MODE)) != NULL ) {
735            CAMHAL_LOGDB("AutoConvergence mode set = %s", valstr);
736            mParameters.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, valstr);
737        }
738
739        if ( (valstr = params.get(TICameraParameters::KEY_MANUAL_CONVERGENCE)) != NULL ) {
740            int manualConvergence = (int)strtol(valstr, 0, 0);
741
742            if ( ( manualConvergence < strtol(mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MIN), 0, 0) ) ||
743                    ( manualConvergence > strtol(mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MAX), 0, 0) ) ) {
744                CAMHAL_LOGEB("ERROR: Invalid Manual Convergence = %d", manualConvergence);
745                return BAD_VALUE;
746            } else {
747                CAMHAL_LOGDB("ManualConvergence Value = %d", manualConvergence);
748                mParameters.set(TICameraParameters::KEY_MANUAL_CONVERGENCE, valstr);
749            }
750        }
751
752        if((valstr = params.get(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION)) != NULL) {
753            if ( strcmp(mCameraProperties->get(CameraProperties::MECHANICAL_MISALIGNMENT_CORRECTION_SUPPORTED),
754                    android::CameraParameters::TRUE) == 0 ) {
755                CAMHAL_LOGDB("Mechanical Mialignment Correction is %s", valstr);
756                mParameters.set(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION, valstr);
757            } else {
758                mParameters.remove(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION);
759            }
760        }
761
762        if ((valstr = params.get(TICameraParameters::KEY_EXPOSURE_MODE)) != NULL) {
763            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES))) {
764                CAMHAL_LOGDB("Exposure mode set = %s", valstr);
765                mParameters.set(TICameraParameters::KEY_EXPOSURE_MODE, valstr);
766                if (!strcmp(valstr, TICameraParameters::EXPOSURE_MODE_MANUAL)) {
767                    int manualVal;
768                    if ((valstr = params.get(TICameraParameters::KEY_MANUAL_EXPOSURE)) != NULL) {
769                        manualVal = params.getInt(TICameraParameters::KEY_MANUAL_EXPOSURE);
770                        if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN) ||
771                                manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MAX)) {
772                            CAMHAL_LOGEB("ERROR: Manual Exposure = %s is out of range - "
773                                            "setting minimum supported value", valstr);
774                            valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN);
775                        }
776                        CAMHAL_LOGDB("Manual Exposure = %s", valstr);
777                        mParameters.set(TICameraParameters::KEY_MANUAL_EXPOSURE, valstr);
778                    }
779                    if ((valstr = params.get(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT)) != NULL) {
780                        manualVal = params.getInt(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT);
781                        if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN) ||
782                                manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MAX)) {
783                            CAMHAL_LOGEB("ERROR: Manual Exposure right = %s is out of range - "
784                                            "setting minimum supported value", valstr);
785                            valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN);
786                        }
787                        CAMHAL_LOGDB("Manual Exposure right = %s", valstr);
788                        mParameters.set(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT, valstr);
789                    }
790                    if ((valstr = params.get(TICameraParameters::KEY_MANUAL_GAIN_ISO)) != NULL) {
791                        manualVal = params.getInt(TICameraParameters::KEY_MANUAL_GAIN_ISO);
792                        if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN) ||
793                                manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX)) {
794                            CAMHAL_LOGEB("ERROR: Manual Gain = %s is out of range - "
795                                            "setting minimum supported value", valstr);
796                            valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN);
797                        }
798                        CAMHAL_LOGDB("Manual Gain = %s", valstr);
799                        mParameters.set(TICameraParameters::KEY_MANUAL_GAIN_ISO, valstr);
800                    }
801                    if ((valstr = params.get(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT)) != NULL) {
802                        manualVal = params.getInt(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT);
803                        if (manualVal < mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN) ||
804                                manualVal > mParameters.getInt(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX)) {
805                            CAMHAL_LOGEB("ERROR: Manual Gain right = %s is out of range - "
806                                            "setting minimum supported value", valstr);
807                            valstr = mParameters.get(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN);
808                        }
809                        CAMHAL_LOGDB("Manual Gain right = %s", valstr);
810                        mParameters.set(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT, valstr);
811                    }
812                }
813            } else {
814                CAMHAL_LOGEB("ERROR: Invalid Exposure mode = %s", valstr);
815                return BAD_VALUE;
816            }
817        }
818#endif
819
820        if ((valstr = params.get(android::CameraParameters::KEY_WHITE_BALANCE)) != NULL) {
821           if ( isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE))) {
822               CAMHAL_LOGDB("White balance set %s", valstr);
823               mParameters.set(android::CameraParameters::KEY_WHITE_BALANCE, valstr);
824            } else {
825               CAMHAL_LOGEB("ERROR: Invalid white balance  = %s", valstr);
826               return BAD_VALUE;
827            }
828        }
829
830#ifdef OMAP_ENHANCEMENT
831        if ((valstr = params.get(TICameraParameters::KEY_CONTRAST)) != NULL) {
832            if (params.getInt(TICameraParameters::KEY_CONTRAST) >= 0 ) {
833                CAMHAL_LOGDB("Contrast set %s", valstr);
834                mParameters.set(TICameraParameters::KEY_CONTRAST, valstr);
835            } else {
836                CAMHAL_LOGEB("ERROR: Invalid Contrast  = %s", valstr);
837                return BAD_VALUE;
838            }
839        }
840
841        if ((valstr =params.get(TICameraParameters::KEY_SHARPNESS)) != NULL) {
842            if (params.getInt(TICameraParameters::KEY_SHARPNESS) >= 0 ) {
843                CAMHAL_LOGDB("Sharpness set %s", valstr);
844                mParameters.set(TICameraParameters::KEY_SHARPNESS, valstr);
845            } else {
846                CAMHAL_LOGEB("ERROR: Invalid Sharpness = %s", valstr);
847                return BAD_VALUE;
848            }
849        }
850
851        if ((valstr = params.get(TICameraParameters::KEY_SATURATION)) != NULL) {
852            if (params.getInt(TICameraParameters::KEY_SATURATION) >= 0 ) {
853                CAMHAL_LOGDB("Saturation set %s", valstr);
854                mParameters.set(TICameraParameters::KEY_SATURATION, valstr);
855             } else {
856                CAMHAL_LOGEB("ERROR: Invalid Saturation = %s", valstr);
857                return BAD_VALUE;
858            }
859        }
860
861        if ((valstr = params.get(TICameraParameters::KEY_BRIGHTNESS)) != NULL) {
862            if (params.getInt(TICameraParameters::KEY_BRIGHTNESS) >= 0 ) {
863                CAMHAL_LOGDB("Brightness set %s", valstr);
864                mParameters.set(TICameraParameters::KEY_BRIGHTNESS, valstr);
865            } else {
866                CAMHAL_LOGEB("ERROR: Invalid Brightness = %s", valstr);
867                return BAD_VALUE;
868            }
869         }
870#endif
871
872        if ((valstr = params.get(android::CameraParameters::KEY_ANTIBANDING)) != NULL) {
873            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING))) {
874                CAMHAL_LOGDB("Antibanding set %s", valstr);
875                mParameters.set(android::CameraParameters::KEY_ANTIBANDING, valstr);
876             } else {
877                CAMHAL_LOGEB("ERROR: Invalid Antibanding = %s", valstr);
878                return BAD_VALUE;
879             }
880         }
881
882#ifdef OMAP_ENHANCEMENT
883        if ((valstr = params.get(TICameraParameters::KEY_ISO)) != NULL) {
884            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES))) {
885                CAMHAL_LOGDB("ISO set %s", valstr);
886                mParameters.set(TICameraParameters::KEY_ISO, valstr);
887            } else {
888                CAMHAL_LOGEB("ERROR: Invalid ISO = %s", valstr);
889                return BAD_VALUE;
890            }
891        }
892#endif
893
894        if( (valstr = params.get(android::CameraParameters::KEY_FOCUS_AREAS)) != NULL )
895            {
896            CAMHAL_LOGDB("Focus areas position set %s", params.get(android::CameraParameters::KEY_FOCUS_AREAS));
897            mParameters.set(android::CameraParameters::KEY_FOCUS_AREAS, valstr);
898            }
899
900#ifdef OMAP_ENHANCEMENT
901        if( (valstr = params.get(TICameraParameters::KEY_MEASUREMENT_ENABLE)) != NULL )
902            {
903            CAMHAL_LOGDB("Measurements set to %s", valstr);
904            mParameters.set(TICameraParameters::KEY_MEASUREMENT_ENABLE, valstr);
905
906            if (strcmp(valstr, android::CameraParameters::TRUE) == 0)
907                {
908                mMeasurementEnabled = true;
909                }
910            else if (strcmp(valstr, android::CameraParameters::FALSE) == 0)
911                {
912                mMeasurementEnabled = false;
913                }
914            else
915                {
916                mMeasurementEnabled = false;
917                }
918
919            }
920#endif
921
922        if( (valstr = params.get(android::CameraParameters::KEY_EXPOSURE_COMPENSATION)) != NULL)
923            {
924            CAMHAL_LOGDB("Exposure compensation set %s", params.get(android::CameraParameters::KEY_EXPOSURE_COMPENSATION));
925            mParameters.set(android::CameraParameters::KEY_EXPOSURE_COMPENSATION, valstr);
926            }
927
928        if ((valstr = params.get(android::CameraParameters::KEY_SCENE_MODE)) != NULL) {
929            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES))) {
930                CAMHAL_LOGDB("Scene mode set %s", valstr);
931                doesSetParameterNeedUpdate(valstr,
932                                           mParameters.get(android::CameraParameters::KEY_SCENE_MODE),
933                                           updateRequired);
934                mParameters.set(android::CameraParameters::KEY_SCENE_MODE, valstr);
935            } else {
936                CAMHAL_LOGEB("ERROR: Invalid Scene mode = %s", valstr);
937                return BAD_VALUE;
938            }
939        }
940
941        if ((valstr = params.get(android::CameraParameters::KEY_FLASH_MODE)) != NULL) {
942            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES))) {
943                CAMHAL_LOGDB("Flash mode set %s", valstr);
944                mParameters.set(android::CameraParameters::KEY_FLASH_MODE, valstr);
945            } else {
946                CAMHAL_LOGEB("ERROR: Invalid Flash mode = %s", valstr);
947                return BAD_VALUE;
948            }
949        }
950
951        if ((valstr = params.get(android::CameraParameters::KEY_EFFECT)) != NULL) {
952            if (isParameterValid(valstr, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS))) {
953                CAMHAL_LOGDB("Effect set %s", valstr);
954                mParameters.set(android::CameraParameters::KEY_EFFECT, valstr);
955             } else {
956                CAMHAL_LOGEB("ERROR: Invalid Effect = %s", valstr);
957                return BAD_VALUE;
958             }
959        }
960
961        varint = params.getInt(android::CameraParameters::KEY_ROTATION);
962        if ( varint >= 0 ) {
963            CAMHAL_LOGDB("Rotation set %d", varint);
964            mParameters.set(android::CameraParameters::KEY_ROTATION, varint);
965        }
966
967        varint = params.getInt(android::CameraParameters::KEY_JPEG_QUALITY);
968        if ( varint >= 0 ) {
969            CAMHAL_LOGDB("Jpeg quality set %d", varint);
970            mParameters.set(android::CameraParameters::KEY_JPEG_QUALITY, varint);
971        }
972
973        varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
974        if ( varint >= 0 ) {
975            CAMHAL_LOGDB("Thumbnail width set %d", varint);
976            mParameters.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, varint);
977        }
978
979        varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
980        if ( varint >= 0 ) {
981            CAMHAL_LOGDB("Thumbnail width set %d", varint);
982            mParameters.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, varint);
983        }
984
985        varint = params.getInt(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
986        if ( varint >= 0 ) {
987            CAMHAL_LOGDB("Thumbnail quality set %d", varint);
988            mParameters.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, varint);
989        }
990
991        if( (valstr = params.get(android::CameraParameters::KEY_GPS_LATITUDE)) != NULL )
992            {
993            CAMHAL_LOGDB("GPS latitude set %s", params.get(android::CameraParameters::KEY_GPS_LATITUDE));
994            mParameters.set(android::CameraParameters::KEY_GPS_LATITUDE, valstr);
995            }else{
996                mParameters.remove(android::CameraParameters::KEY_GPS_LATITUDE);
997            }
998
999        if( (valstr = params.get(android::CameraParameters::KEY_GPS_LONGITUDE)) != NULL )
1000            {
1001            CAMHAL_LOGDB("GPS longitude set %s", params.get(android::CameraParameters::KEY_GPS_LONGITUDE));
1002            mParameters.set(android::CameraParameters::KEY_GPS_LONGITUDE, valstr);
1003            }else{
1004                mParameters.remove(android::CameraParameters::KEY_GPS_LONGITUDE);
1005            }
1006
1007        if( (valstr = params.get(android::CameraParameters::KEY_GPS_ALTITUDE)) != NULL )
1008            {
1009            CAMHAL_LOGDB("GPS altitude set %s", params.get(android::CameraParameters::KEY_GPS_ALTITUDE));
1010            mParameters.set(android::CameraParameters::KEY_GPS_ALTITUDE, valstr);
1011            }else{
1012                mParameters.remove(android::CameraParameters::KEY_GPS_ALTITUDE);
1013            }
1014
1015        if( (valstr = params.get(android::CameraParameters::KEY_GPS_TIMESTAMP)) != NULL )
1016            {
1017            CAMHAL_LOGDB("GPS timestamp set %s", params.get(android::CameraParameters::KEY_GPS_TIMESTAMP));
1018            mParameters.set(android::CameraParameters::KEY_GPS_TIMESTAMP, valstr);
1019            }else{
1020                mParameters.remove(android::CameraParameters::KEY_GPS_TIMESTAMP);
1021            }
1022
1023        if( (valstr = params.get(TICameraParameters::KEY_GPS_DATESTAMP)) != NULL )
1024            {
1025            CAMHAL_LOGDB("GPS datestamp set %s", valstr);
1026            mParameters.set(TICameraParameters::KEY_GPS_DATESTAMP, valstr);
1027            }else{
1028                mParameters.remove(TICameraParameters::KEY_GPS_DATESTAMP);
1029            }
1030
1031        if( (valstr = params.get(android::CameraParameters::KEY_GPS_PROCESSING_METHOD)) != NULL )
1032            {
1033            CAMHAL_LOGDB("GPS processing method set %s", params.get(android::CameraParameters::KEY_GPS_PROCESSING_METHOD));
1034            mParameters.set(android::CameraParameters::KEY_GPS_PROCESSING_METHOD, valstr);
1035            }else{
1036                mParameters.remove(android::CameraParameters::KEY_GPS_PROCESSING_METHOD);
1037            }
1038
1039        if( (valstr = params.get(TICameraParameters::KEY_GPS_MAPDATUM )) != NULL )
1040            {
1041            CAMHAL_LOGDB("GPS MAPDATUM set %s", valstr);
1042            mParameters.set(TICameraParameters::KEY_GPS_MAPDATUM, valstr);
1043            }else{
1044                mParameters.remove(TICameraParameters::KEY_GPS_MAPDATUM);
1045            }
1046
1047        if( (valstr = params.get(TICameraParameters::KEY_GPS_VERSION)) != NULL )
1048            {
1049            CAMHAL_LOGDB("GPS MAPDATUM set %s", valstr);
1050            mParameters.set(TICameraParameters::KEY_GPS_VERSION, valstr);
1051            }else{
1052                mParameters.remove(TICameraParameters::KEY_GPS_VERSION);
1053            }
1054
1055        if( (valstr = params.get(TICameraParameters::KEY_EXIF_MODEL)) != NULL )
1056            {
1057            CAMHAL_LOGDB("EXIF Model set %s", valstr);
1058            mParameters.set(TICameraParameters::KEY_EXIF_MODEL, valstr);
1059            }
1060
1061        if( (valstr = params.get(TICameraParameters::KEY_EXIF_MAKE)) != NULL )
1062            {
1063            CAMHAL_LOGDB("EXIF Make set %s", valstr);
1064            mParameters.set(TICameraParameters::KEY_EXIF_MAKE, valstr);
1065            }
1066
1067#ifdef OMAP_ENHANCEMENT
1068        if( (valstr = params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE)) != NULL )
1069            {
1070            CAMHAL_LOGDB("Exposure Bracketing set %s", params.get(TICameraParameters::KEY_EXP_BRACKETING_RANGE));
1071            mParameters.set(TICameraParameters::KEY_EXP_BRACKETING_RANGE, valstr);
1072            mParameters.remove(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE);
1073            }
1074        else if ((valstr = params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE)) != NULL) {
1075            CAMHAL_LOGDB("ABS Exposure+Gain Bracketing set %s", params.get(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE));
1076            mParameters.set(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE, valstr);
1077            mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
1078        } else
1079            {
1080            mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
1081            }
1082
1083        if( (valstr = params.get(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE)) != NULL ) {
1084            CAMHAL_LOGDB("Zoom Bracketing range %s", valstr);
1085            mParameters.set(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE, valstr);
1086        } else {
1087            mParameters.remove(TICameraParameters::KEY_ZOOM_BRACKETING_RANGE);
1088        }
1089#endif
1090
1091        if ((valstr = params.get(android::CameraParameters::KEY_ZOOM)) != NULL ) {
1092            varint = atoi(valstr);
1093            if ( varint >= 0 && varint <= mMaxZoomSupported ) {
1094                CAMHAL_LOGDB("Zoom set %d", varint);
1095                doesSetParameterNeedUpdate(valstr,
1096                                           mParameters.get(android::CameraParameters::KEY_ZOOM),
1097                                           updateRequired);
1098                mParameters.set(android::CameraParameters::KEY_ZOOM, valstr);
1099             } else {
1100                CAMHAL_LOGEB("ERROR: Invalid Zoom: %s", valstr);
1101                return BAD_VALUE;
1102            }
1103        }
1104
1105        if( (valstr = params.get(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK)) != NULL )
1106          {
1107            CAMHAL_LOGDB("Auto Exposure Lock set %s", valstr);
1108            doesSetParameterNeedUpdate(valstr,
1109                                       mParameters.get(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK),
1110                                       updateRequired);
1111            mParameters.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK, valstr);
1112          }
1113
1114        if( (valstr = params.get(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK)) != NULL )
1115          {
1116            CAMHAL_LOGDB("Auto WhiteBalance Lock set %s", valstr);
1117            doesSetParameterNeedUpdate(valstr,
1118                                       mParameters.get(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK),
1119                                       updateRequired);
1120            mParameters.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, valstr);
1121          }
1122        if( (valstr = params.get(android::CameraParameters::KEY_METERING_AREAS)) != NULL )
1123            {
1124            CAMHAL_LOGDB("Metering areas position set %s", params.get(android::CameraParameters::KEY_METERING_AREAS));
1125            mParameters.set(android::CameraParameters::KEY_METERING_AREAS, valstr);
1126            }
1127
1128        if( (valstr = params.get(TICameraParameters::RAW_WIDTH)) != NULL ) {
1129            CAMHAL_LOGDB("Raw image width set %s", params.get(TICameraParameters::RAW_WIDTH));
1130            mParameters.set(TICameraParameters::RAW_WIDTH, valstr);
1131        }
1132
1133        if( (valstr = params.get(TICameraParameters::RAW_HEIGHT)) != NULL ) {
1134            CAMHAL_LOGDB("Raw image height set %s", params.get(TICameraParameters::RAW_HEIGHT));
1135            mParameters.set(TICameraParameters::RAW_HEIGHT, valstr);
1136        }
1137
1138        //TI extensions for enable/disable algos
1139        if( (valstr = params.get(TICameraParameters::KEY_ALGO_EXTERNAL_GAMMA)) != NULL )
1140            {
1141            CAMHAL_LOGDB("External Gamma set %s", valstr);
1142            mParameters.set(TICameraParameters::KEY_ALGO_EXTERNAL_GAMMA, valstr);
1143            }
1144
1145        if( (valstr = params.get(TICameraParameters::KEY_ALGO_NSF1)) != NULL )
1146            {
1147            CAMHAL_LOGDB("NSF1 set %s", valstr);
1148            mParameters.set(TICameraParameters::KEY_ALGO_NSF1, valstr);
1149            }
1150
1151        if( (valstr = params.get(TICameraParameters::KEY_ALGO_NSF2)) != NULL )
1152            {
1153            CAMHAL_LOGDB("NSF2 set %s", valstr);
1154            mParameters.set(TICameraParameters::KEY_ALGO_NSF2, valstr);
1155            }
1156
1157        if( (valstr = params.get(TICameraParameters::KEY_ALGO_SHARPENING)) != NULL )
1158            {
1159            CAMHAL_LOGDB("Sharpening set %s", valstr);
1160            mParameters.set(TICameraParameters::KEY_ALGO_SHARPENING, valstr);
1161            }
1162
1163        if( (valstr = params.get(TICameraParameters::KEY_ALGO_THREELINCOLORMAP)) != NULL )
1164            {
1165            CAMHAL_LOGDB("Color Conversion set %s", valstr);
1166            mParameters.set(TICameraParameters::KEY_ALGO_THREELINCOLORMAP, valstr);
1167            }
1168
1169        if( (valstr = params.get(TICameraParameters::KEY_ALGO_GIC)) != NULL )
1170            {
1171            CAMHAL_LOGDB("Green Inballance Correction set %s", valstr);
1172            mParameters.set(TICameraParameters::KEY_ALGO_GIC, valstr);
1173            }
1174
1175        if( (valstr = params.get(TICameraParameters::KEY_GAMMA_TABLE)) != NULL )
1176            {
1177            CAMHAL_LOGDB("Manual gamma table set %s", valstr);
1178            mParameters.set(TICameraParameters::KEY_GAMMA_TABLE, valstr);
1179            }
1180
1181        android::CameraParameters adapterParams = mParameters;
1182
1183#ifdef OMAP_ENHANCEMENT
1184        if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS) )
1185            {
1186            int posBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_POS);
1187            if ( 0 < posBracketRange )
1188                {
1189                mBracketRangePositive = posBracketRange;
1190                }
1191            }
1192        CAMHAL_LOGDB("Positive bracketing range %d", mBracketRangePositive);
1193
1194
1195        if( NULL != params.get(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG) )
1196            {
1197            int negBracketRange = params.getInt(TICameraParameters::KEY_TEMP_BRACKETING_RANGE_NEG);
1198            if ( 0 < negBracketRange )
1199                {
1200                mBracketRangeNegative = negBracketRange;
1201                }
1202            }
1203        CAMHAL_LOGDB("Negative bracketing range %d", mBracketRangeNegative);
1204
1205        if( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL) &&
1206            ( strcmp(valstr, android::CameraParameters::TRUE) == 0 )) {
1207            if ( !mBracketingEnabled ) {
1208                CAMHAL_LOGDA("Enabling bracketing");
1209                mBracketingEnabled = true;
1210            } else {
1211                CAMHAL_LOGDA("Bracketing already enabled");
1212            }
1213            adapterParams.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
1214            mParameters.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
1215        } else if ( ( (valstr = params.get(TICameraParameters::KEY_TEMP_BRACKETING)) != NULL ) &&
1216            ( strcmp(valstr, android::CameraParameters::FALSE) == 0 )) {
1217            CAMHAL_LOGDA("Disabling bracketing");
1218
1219            adapterParams.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
1220            mParameters.set(TICameraParameters::KEY_TEMP_BRACKETING, valstr);
1221            mBracketingEnabled = false;
1222            if ( mBracketingRunning ) {
1223                stopImageBracketing();
1224            }
1225
1226        } else {
1227            adapterParams.remove(TICameraParameters::KEY_TEMP_BRACKETING);
1228            mParameters.remove(TICameraParameters::KEY_TEMP_BRACKETING);
1229        }
1230#endif
1231
1232#ifdef OMAP_ENHANCEMENT_VTC
1233        if (mVTCUseCase && !mTunnelSetup && (mCameraAdapter != NULL) &&
1234                ((mParameters.get(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE)) != NULL )&&
1235                ((mParameters.get(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT)) != NULL )) {
1236
1237            uint32_t sliceHeight = mParameters.getInt(TICameraParameters::KEY_VIDEO_ENCODER_SLICE_HEIGHT);
1238            uint32_t encoderHandle = mParameters.getInt(TICameraParameters::KEY_VIDEO_ENCODER_HANDLE);
1239            int w, h;
1240            mParameters.getPreviewSize(&w, &h);
1241            status_t done = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SETUP_TUNNEL, sliceHeight, encoderHandle, w, h);
1242            if (done == NO_ERROR) mTunnelSetup = true;
1243            ret |= done;
1244        }
1245#endif
1246
1247        // Only send parameters to adapter if preview is already
1248        // enabled or doesSetParameterNeedUpdate says so. Initial setParameters to camera adapter,
1249        // will be called in startPreview()
1250        // TODO(XXX): Need to identify other parameters that need update from camera adapter
1251        if ( (NULL != mCameraAdapter) &&
1252             (mPreviewEnabled || updateRequired) &&
1253             (!(mPreviewEnabled && restartPreviewRequired)) ) {
1254            ret |= mCameraAdapter->setParameters(adapterParams);
1255        }
1256
1257#ifdef OMAP_ENHANCEMENT
1258        if( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
1259            ( strcmp(valstr, android::CameraParameters::TRUE) == 0 ))
1260            {
1261            CAMHAL_LOGDA("Enabling shutter sound");
1262
1263            mShutterEnabled = true;
1264            mMsgEnabled |= CAMERA_MSG_SHUTTER;
1265            mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
1266            }
1267        else if ( ( (valstr = params.get(TICameraParameters::KEY_SHUTTER_ENABLE)) != NULL ) &&
1268            ( strcmp(valstr, android::CameraParameters::FALSE) == 0 ))
1269            {
1270            CAMHAL_LOGDA("Disabling shutter sound");
1271
1272            mShutterEnabled = false;
1273            mMsgEnabled &= ~CAMERA_MSG_SHUTTER;
1274            mParameters.set(TICameraParameters::KEY_SHUTTER_ENABLE, valstr);
1275            }
1276#endif
1277    }
1278
1279    //On fail restore old parameters
1280    if ( NO_ERROR != ret ) {
1281        mParameters = oldParams;
1282    }
1283
1284    // Restart Preview if needed by KEY_RECODING_HINT only if preview is already running.
1285    // If preview is not started yet, Video Mode parameters will take effect on next startPreview()
1286    if (restartPreviewRequired && previewEnabled() && !mRecordingEnabled) {
1287        CAMHAL_LOGDA("Restarting Preview");
1288        ret = restartPreview();
1289    } else if (restartPreviewRequired && !previewEnabled() &&
1290                mDisplayPaused && !mRecordingEnabled) {
1291        CAMHAL_LOGDA("Restarting preview in paused mode");
1292        ret = restartPreview();
1293
1294        // TODO(XXX): If there is some delay between the restartPreview call and the code
1295        // below, then the user could see some preview frames and callbacks. Let's find
1296        // a better place to put this later...
1297        if (ret == NO_ERROR) {
1298            mDisplayPaused = true;
1299            mPreviewEnabled = false;
1300            ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
1301        }
1302    }
1303
1304    if ( !mBracketingRunning && mBracketingEnabled ) {
1305        startImageBracketing();
1306    }
1307
1308    if (ret != NO_ERROR)
1309        {
1310        CAMHAL_LOGEA("Failed to restart Preview");
1311        return ret;
1312        }
1313
1314    LOG_FUNCTION_NAME_EXIT;
1315
1316    return ret;
1317}
1318
1319status_t CameraHal::allocPreviewBufs(int width, int height, const char* previewFormat,
1320                                        unsigned int buffercount, unsigned int &max_queueable)
1321{
1322    status_t ret = NO_ERROR;
1323
1324    LOG_FUNCTION_NAME;
1325
1326    if(mDisplayAdapter.get() == NULL)
1327    {
1328        // Memory allocation of preview buffers is now placed in gralloc
1329        // CameraHal should not allocate preview buffers without DisplayAdapter
1330        return NO_MEMORY;
1331    }
1332
1333    if(!mPreviewBuffers)
1334    {
1335        mPreviewLength = 0;
1336        mPreviewBuffers = mDisplayAdapter->allocateBufferList(width, height,
1337                                                                    previewFormat,
1338                                                                    mPreviewLength,
1339                                                                    buffercount);
1340        if (NULL == mPreviewBuffers ) {
1341            CAMHAL_LOGEA("Couldn't allocate preview buffers");
1342            return NO_MEMORY;
1343        }
1344
1345        mPreviewOffsets = (uint32_t *) mDisplayAdapter->getOffsets();
1346        if ( NULL == mPreviewOffsets ) {
1347            CAMHAL_LOGEA("Buffer mapping failed");
1348            return BAD_VALUE;
1349        }
1350
1351        mBufProvider = (BufferProvider*) mDisplayAdapter.get();
1352
1353        ret = mDisplayAdapter->maxQueueableBuffers(max_queueable);
1354        if (ret != NO_ERROR) {
1355            return ret;
1356        }
1357    }
1358
1359    LOG_FUNCTION_NAME_EXIT;
1360
1361    return ret;
1362}
1363
1364status_t CameraHal::freePreviewBufs()
1365{
1366    status_t ret = NO_ERROR;
1367    LOG_FUNCTION_NAME;
1368
1369    CAMHAL_LOGDB("mPreviewBuffers = %p", mPreviewBuffers);
1370    if(mPreviewBuffers)
1371        {
1372        ret = mBufProvider->freeBufferList(mPreviewBuffers);
1373        mPreviewBuffers = NULL;
1374        LOG_FUNCTION_NAME_EXIT;
1375        return ret;
1376        }
1377    LOG_FUNCTION_NAME_EXIT;
1378    return ret;
1379}
1380
1381
1382status_t CameraHal::allocPreviewDataBufs(size_t size, size_t bufferCount)
1383{
1384    status_t ret = NO_ERROR;
1385    int bytes;
1386
1387    LOG_FUNCTION_NAME;
1388
1389    bytes = size;
1390
1391    if ( NO_ERROR == ret )
1392        {
1393        if( NULL != mPreviewDataBuffers )
1394            {
1395            ret = freePreviewDataBufs();
1396            }
1397        }
1398
1399    if ( NO_ERROR == ret )
1400        {
1401        bytes = ((bytes+4095)/4096)*4096;
1402        mPreviewDataBuffers = mMemoryManager->allocateBufferList(0, 0, NULL, bytes, bufferCount);
1403
1404        CAMHAL_LOGDB("Size of Preview data buffer = %d", bytes);
1405        if( NULL == mPreviewDataBuffers )
1406            {
1407            CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
1408            ret = -NO_MEMORY;
1409            }
1410        else
1411            {
1412            bytes = size;
1413            }
1414        }
1415
1416    if ( NO_ERROR == ret )
1417        {
1418        mPreviewDataFd = mMemoryManager->getFd();
1419        mPreviewDataLength = bytes;
1420        mPreviewDataOffsets = mMemoryManager->getOffsets();
1421        }
1422    else
1423        {
1424        mPreviewDataFd = -1;
1425        mPreviewDataLength = 0;
1426        mPreviewDataOffsets = NULL;
1427        }
1428
1429    LOG_FUNCTION_NAME_EXIT;
1430
1431    return ret;
1432}
1433
1434status_t CameraHal::freePreviewDataBufs()
1435{
1436    status_t ret = NO_ERROR;
1437
1438    LOG_FUNCTION_NAME;
1439
1440    if ( NO_ERROR == ret )
1441        {
1442
1443        if( NULL != mPreviewDataBuffers )
1444            {
1445
1446            ret = mMemoryManager->freeBufferList(mPreviewDataBuffers);
1447            mPreviewDataBuffers = NULL;
1448
1449            }
1450        }
1451
1452    LOG_FUNCTION_NAME_EXIT;
1453
1454    return ret;
1455}
1456
1457status_t CameraHal::allocImageBufs(unsigned int width, unsigned int height, size_t size,
1458                                   const char* previewFormat, unsigned int bufferCount)
1459{
1460    status_t ret = NO_ERROR;
1461    int bytes = size;
1462
1463    LOG_FUNCTION_NAME;
1464
1465    // allocate image buffers only if not already allocated
1466    if(NULL != mImageBuffers) {
1467        return NO_ERROR;
1468    }
1469
1470    if ( NO_ERROR == ret ) {
1471        bytes = ((bytes+4095)/4096)*4096;
1472        mImageBuffers = mMemoryManager->allocateBufferList(0, 0, previewFormat, bytes, bufferCount);
1473        CAMHAL_LOGDB("Size of Image cap buffer = %d", bytes);
1474        if( NULL == mImageBuffers ) {
1475            CAMHAL_LOGEA("Couldn't allocate image buffers using memory manager");
1476            ret = -NO_MEMORY;
1477        } else {
1478            bytes = size;
1479        }
1480    }
1481
1482    if ( NO_ERROR == ret ) {
1483        mImageFd = mMemoryManager->getFd();
1484        mImageLength = bytes;
1485        mImageOffsets = mMemoryManager->getOffsets();
1486        mImageCount = bufferCount;
1487    } else {
1488        mImageFd = -1;
1489        mImageLength = 0;
1490        mImageOffsets = NULL;
1491        mImageCount = 0;
1492    }
1493
1494    LOG_FUNCTION_NAME_EXIT;
1495
1496    return ret;
1497}
1498
1499status_t CameraHal::allocVideoBufs(uint32_t width, uint32_t height, uint32_t bufferCount)
1500{
1501  status_t ret = NO_ERROR;
1502  LOG_FUNCTION_NAME;
1503
1504  if( NULL != mVideoBuffers ){
1505    ret = freeVideoBufs(mVideoBuffers);
1506    mVideoBuffers = NULL;
1507  }
1508
1509  if ( NO_ERROR == ret ){
1510    int32_t stride;
1511    CameraBuffer *buffers = new CameraBuffer [bufferCount];
1512
1513    memset (buffers, 0, sizeof(CameraBuffer) * bufferCount);
1514
1515    if (buffers != NULL){
1516      for (unsigned int i = 0; i< bufferCount; i++){
1517        android::GraphicBufferAllocator &GrallocAlloc = android::GraphicBufferAllocator::get();
1518        buffer_handle_t handle;
1519        ret = GrallocAlloc.alloc(width, height, HAL_PIXEL_FORMAT_NV12, CAMHAL_GRALLOC_USAGE, &handle, &stride);
1520        if (ret != NO_ERROR){
1521          CAMHAL_LOGEA("Couldn't allocate video buffers using Gralloc");
1522          ret = -NO_MEMORY;
1523          for (unsigned int j=0; j< i; j++){
1524            CAMHAL_LOGEB("Freeing Gralloc Buffer %p", buffers[i].opaque);
1525            GrallocAlloc.free((buffer_handle_t)buffers[i].opaque);
1526          }
1527          delete [] buffers;
1528          goto exit;
1529        }
1530        buffers[i].type = CAMERA_BUFFER_GRALLOC;
1531        buffers[i].opaque = (void *)handle;
1532        CAMHAL_LOGVB("*** Gralloc Handle =0x%x ***", handle);
1533      }
1534
1535      mVideoBuffers = buffers;
1536    }
1537    else{
1538      CAMHAL_LOGEA("Couldn't allocate video buffers ");
1539      ret = -NO_MEMORY;
1540    }
1541  }
1542
1543 exit:
1544  LOG_FUNCTION_NAME_EXIT;
1545
1546  return ret;
1547}
1548
1549status_t CameraHal::allocRawBufs(int width, int height, const char* previewFormat, int bufferCount)
1550{
1551   status_t ret = NO_ERROR;
1552
1553    LOG_FUNCTION_NAME
1554
1555
1556    ///@todo Enhance this method allocImageBufs() to take in a flag for burst capture
1557    ///Always allocate the buffers for image capture using MemoryManager
1558    if (NO_ERROR == ret) {
1559        if(( NULL != mVideoBuffers )) {
1560            // Re-use the buffer for raw capture.
1561            return ret;
1562        }
1563    }
1564
1565    if ( NO_ERROR == ret ) {
1566        mVideoLength = 0;
1567        mVideoLength = (((width * height * 2) + 4095)/4096)*4096;
1568        mVideoBuffers = mMemoryManager->allocateBufferList(width, height, previewFormat,
1569                                                           mVideoLength, bufferCount);
1570
1571        CAMHAL_LOGDB("Size of Video cap buffer (used for RAW capture) %d", mVideoLength);
1572        if( NULL == mVideoBuffers ) {
1573            CAMHAL_LOGEA("Couldn't allocate Video buffers using memory manager");
1574            ret = -NO_MEMORY;
1575        }
1576    }
1577
1578    if ( NO_ERROR == ret ) {
1579        mVideoFd = mMemoryManager->getFd();
1580        mVideoOffsets = mMemoryManager->getOffsets();
1581    } else {
1582        mVideoFd = -1;
1583        mVideoOffsets = NULL;
1584    }
1585
1586    LOG_FUNCTION_NAME_EXIT;
1587
1588    return ret;
1589}
1590
1591void endImageCapture( void *userData)
1592{
1593    LOG_FUNCTION_NAME;
1594
1595    if ( NULL != userData )
1596        {
1597        CameraHal *c = reinterpret_cast<CameraHal *>(userData);
1598        c->signalEndImageCapture();
1599        }
1600
1601    LOG_FUNCTION_NAME_EXIT;
1602}
1603
1604void releaseImageBuffers(void *userData)
1605{
1606    LOG_FUNCTION_NAME;
1607
1608    if (NULL != userData) {
1609        CameraHal *c = reinterpret_cast<CameraHal *>(userData);
1610        c->freeImageBufs();
1611    }
1612
1613    LOG_FUNCTION_NAME_EXIT;
1614}
1615
1616status_t CameraHal::signalEndImageCapture()
1617{
1618    status_t ret = NO_ERROR;
1619    int w,h;
1620    android::AutoMutex lock(mLock);
1621
1622    LOG_FUNCTION_NAME;
1623
1624    if (mBufferSourceAdapter_Out.get()) {
1625        mBufferSourceAdapter_Out->disableDisplay();
1626    }
1627
1628    if (mBufferSourceAdapter_In.get()) {
1629        mBufferSourceAdapter_In->disableDisplay();
1630    }
1631
1632    if ( mBracketingRunning ) {
1633        stopImageBracketing();
1634    } else {
1635        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
1636    }
1637
1638    LOG_FUNCTION_NAME_EXIT;
1639
1640    return ret;
1641}
1642
1643status_t CameraHal::freeImageBufs()
1644{
1645    status_t ret = NO_ERROR;
1646
1647    LOG_FUNCTION_NAME;
1648
1649    if (NULL == mImageBuffers) {
1650        return -EINVAL;
1651    }
1652
1653    if (mBufferSourceAdapter_Out.get()) {
1654        mBufferSourceAdapter_Out = 0;
1655    } else {
1656        ret = mMemoryManager->freeBufferList(mImageBuffers);
1657    }
1658
1659    mImageBuffers = NULL;
1660
1661    LOG_FUNCTION_NAME_EXIT;
1662
1663    return ret;
1664}
1665
1666status_t CameraHal::freeVideoBufs(CameraBuffer *bufs)
1667{
1668  status_t ret = NO_ERROR;
1669
1670  LOG_FUNCTION_NAME;
1671
1672  int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
1673  if(bufs == NULL)
1674    {
1675      CAMHAL_LOGEA("NULL pointer passed to freeVideoBuffer");
1676      LOG_FUNCTION_NAME_EXIT;
1677      return BAD_VALUE;
1678    }
1679
1680  android::GraphicBufferAllocator &GrallocAlloc = android::GraphicBufferAllocator::get();
1681
1682  for(int i = 0; i < count; i++){
1683    CAMHAL_LOGVB("Free Video Gralloc Handle 0x%x", bufs[i].opaque);
1684    GrallocAlloc.free((buffer_handle_t)bufs[i].opaque);
1685  }
1686
1687  LOG_FUNCTION_NAME_EXIT;
1688
1689  return ret;
1690}
1691
1692status_t CameraHal::freeRawBufs()
1693{
1694    status_t ret = NO_ERROR;
1695
1696    LOG_FUNCTION_NAME
1697
1698    if ( NO_ERROR == ret ) {
1699        if( NULL != mVideoBuffers ) {
1700            ///@todo Pluralise the name of this method to freeBuffers
1701            ret = mMemoryManager->freeBufferList(mVideoBuffers);
1702            mVideoBuffers = NULL;
1703        } else {
1704            ret = -EINVAL;
1705        }
1706    }
1707
1708    LOG_FUNCTION_NAME_EXIT
1709
1710    return ret;
1711}
1712
1713/**
1714   @brief Start preview mode.
1715
1716   @param none
1717   @return NO_ERROR Camera switched to VF mode
1718   @todo Update function header with the different errors that are possible
1719
1720 */
1721status_t CameraHal::startPreview() {
1722    LOG_FUNCTION_NAME;
1723
1724    // When tunneling is enabled during VTC, startPreview happens in 2 steps:
1725    // When the application sends the command CAMERA_CMD_PREVIEW_INITIALIZATION,
1726    // cameraPreviewInitialization() is called, which in turn causes the CameraAdapter
1727    // to move from loaded to idle state. And when the application calls startPreview,
1728    // the CameraAdapter moves from idle to executing state.
1729    //
1730    // If the application calls startPreview() without sending the command
1731    // CAMERA_CMD_PREVIEW_INITIALIZATION, then the function cameraPreviewInitialization()
1732    // AND startPreview() are executed. In other words, if the application calls
1733    // startPreview() without sending the command CAMERA_CMD_PREVIEW_INITIALIZATION,
1734    // then the CameraAdapter moves from loaded to idle to executing state in one shot.
1735    status_t ret = cameraPreviewInitialization();
1736
1737    // The flag mPreviewInitializationDone is set to true at the end of the function
1738    // cameraPreviewInitialization(). Therefore, if everything goes alright, then the
1739    // flag will be set. Sometimes, the function cameraPreviewInitialization() may
1740    // return prematurely if all the resources are not available for starting preview.
1741    // For example, if the preview window is not set, then it would return NO_ERROR.
1742    // Under such circumstances, one should return from startPreview as well and should
1743    // not continue execution. That is why, we check the flag and not the return value.
1744    if (!mPreviewInitializationDone) return ret;
1745
1746    // Once startPreview is called, there is no need to continue to remember whether
1747    // the function cameraPreviewInitialization() was called earlier or not. And so
1748    // the flag mPreviewInitializationDone is reset here. Plus, this preserves the
1749    // current behavior of startPreview under the circumstances where the application
1750    // calls startPreview twice or more.
1751    mPreviewInitializationDone = false;
1752
1753    ///Enable the display adapter if present, actual overlay enable happens when we post the buffer
1754    if(mDisplayAdapter.get() != NULL) {
1755        CAMHAL_LOGDA("Enabling display");
1756        int width, height;
1757        mParameters.getPreviewSize(&width, &height);
1758
1759#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1760        ret = mDisplayAdapter->enableDisplay(width, height, &mStartPreview);
1761#else
1762        ret = mDisplayAdapter->enableDisplay(width, height, NULL);
1763#endif
1764
1765        if ( ret != NO_ERROR ) {
1766            CAMHAL_LOGEA("Couldn't enable display");
1767
1768            // FIXME: At this stage mStateSwitchLock is locked and unlock is supposed to be called
1769            //        only from mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW)
1770            //        below. But this will never happen because of goto error. Thus at next
1771            //        startPreview() call CameraHAL will be deadlocked.
1772            //        Need to revisit mStateSwitch lock, for now just abort the process.
1773            CAMHAL_ASSERT_X(false,
1774                "At this stage mCameraAdapter->mStateSwitchLock is still locked, "
1775                "deadlock is guaranteed");
1776
1777            goto error;
1778        }
1779
1780    }
1781
1782    ///Send START_PREVIEW command to adapter
1783    CAMHAL_LOGDA("Starting CameraAdapter preview mode");
1784
1785    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW);
1786
1787    if(ret!=NO_ERROR) {
1788        CAMHAL_LOGEA("Couldn't start preview w/ CameraAdapter");
1789        goto error;
1790    }
1791    CAMHAL_LOGDA("Started preview");
1792
1793    mPreviewEnabled = true;
1794    mPreviewStartInProgress = false;
1795    return ret;
1796
1797    error:
1798
1799        CAMHAL_LOGEA("Performing cleanup after error");
1800
1801        //Do all the cleanup
1802        freePreviewBufs();
1803        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
1804        if(mDisplayAdapter.get() != NULL) {
1805            mDisplayAdapter->disableDisplay(false);
1806        }
1807        mAppCallbackNotifier->stop();
1808        mPreviewStartInProgress = false;
1809        mPreviewEnabled = false;
1810        LOG_FUNCTION_NAME_EXIT;
1811
1812        return ret;
1813}
1814
1815////////////
1816/**
1817   @brief Set preview mode related initialization
1818          -> Camera Adapter set params
1819          -> Allocate buffers
1820          -> Set use buffers for preview
1821   @param none
1822   @return NO_ERROR
1823   @todo Update function header with the different errors that are possible
1824
1825 */
1826status_t CameraHal::cameraPreviewInitialization()
1827{
1828
1829    status_t ret = NO_ERROR;
1830    CameraAdapter::BuffersDescriptor desc;
1831    CameraFrame frame;
1832    unsigned int required_buffer_count;
1833    unsigned int max_queueble_buffers;
1834
1835#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
1836        gettimeofday(&mStartPreview, NULL);
1837#endif
1838
1839    LOG_FUNCTION_NAME;
1840
1841    if (mPreviewInitializationDone) {
1842        return NO_ERROR;
1843    }
1844
1845    if ( mPreviewEnabled ){
1846      CAMHAL_LOGDA("Preview already running");
1847      LOG_FUNCTION_NAME_EXIT;
1848      return ALREADY_EXISTS;
1849    }
1850
1851    if ( NULL != mCameraAdapter ) {
1852      ret = mCameraAdapter->setParameters(mParameters);
1853    }
1854
1855    if ((mPreviewStartInProgress == false) && (mDisplayPaused == false)){
1856      ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_RESOLUTION_PREVIEW,( int ) &frame);
1857      if ( NO_ERROR != ret ){
1858        CAMHAL_LOGEB("Error: CAMERA_QUERY_RESOLUTION_PREVIEW %d", ret);
1859        return ret;
1860      }
1861
1862      ///Update the current preview width and height
1863      mPreviewWidth = frame.mWidth;
1864      mPreviewHeight = frame.mHeight;
1865    }
1866
1867    ///If we don't have the preview callback enabled and display adapter,
1868    if(!mSetPreviewWindowCalled || (mDisplayAdapter.get() == NULL)){
1869      CAMHAL_LOGD("Preview not started. Preview in progress flag set");
1870      mPreviewStartInProgress = true;
1871      ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_SWITCH_TO_EXECUTING);
1872      if ( NO_ERROR != ret ){
1873        CAMHAL_LOGEB("Error: CAMERA_SWITCH_TO_EXECUTING %d", ret);
1874        return ret;
1875      }
1876      return NO_ERROR;
1877    }
1878
1879    if( (mDisplayAdapter.get() != NULL) && ( !mPreviewEnabled ) && ( mDisplayPaused ) )
1880        {
1881        CAMHAL_LOGDA("Preview is in paused state");
1882
1883        mDisplayPaused = false;
1884        mPreviewEnabled = true;
1885        if ( NO_ERROR == ret )
1886            {
1887            ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
1888
1889            if ( NO_ERROR != ret )
1890                {
1891                CAMHAL_LOGEB("Display adapter resume failed %x", ret);
1892                }
1893            }
1894        //restart preview callbacks
1895        if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
1896        {
1897            mAppCallbackNotifier->enableMsgType (CAMERA_MSG_PREVIEW_FRAME);
1898        }
1899
1900        signalEndImageCapture();
1901        return ret;
1902        }
1903
1904    required_buffer_count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
1905
1906    ///Allocate the preview buffers
1907    ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count, max_queueble_buffers);
1908
1909    if ( NO_ERROR != ret )
1910        {
1911        CAMHAL_LOGEA("Couldn't allocate buffers for Preview");
1912        goto error;
1913        }
1914
1915    if ( mMeasurementEnabled )
1916        {
1917
1918        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA,
1919                                          ( int ) &frame,
1920                                          required_buffer_count);
1921        if ( NO_ERROR != ret )
1922            {
1923            return ret;
1924            }
1925
1926         ///Allocate the preview data buffers
1927        ret = allocPreviewDataBufs(frame.mLength, required_buffer_count);
1928        if ( NO_ERROR != ret ) {
1929            CAMHAL_LOGEA("Couldn't allocate preview data buffers");
1930            goto error;
1931           }
1932
1933        if ( NO_ERROR == ret )
1934            {
1935            desc.mBuffers = mPreviewDataBuffers;
1936            desc.mOffsets = mPreviewDataOffsets;
1937            desc.mFd = mPreviewDataFd;
1938            desc.mLength = mPreviewDataLength;
1939            desc.mCount = ( size_t ) required_buffer_count;
1940            desc.mMaxQueueable = (size_t) required_buffer_count;
1941
1942            mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW_DATA,
1943                                        ( int ) &desc);
1944            }
1945
1946        }
1947
1948    ///Pass the buffers to Camera Adapter
1949    desc.mBuffers = mPreviewBuffers;
1950    desc.mOffsets = mPreviewOffsets;
1951    desc.mFd = mPreviewFd;
1952    desc.mLength = mPreviewLength;
1953    desc.mCount = ( size_t ) required_buffer_count;
1954    desc.mMaxQueueable = (size_t) max_queueble_buffers;
1955
1956    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_PREVIEW,
1957                                      ( int ) &desc);
1958
1959    if ( NO_ERROR != ret )
1960        {
1961        CAMHAL_LOGEB("Failed to register preview buffers: 0x%x", ret);
1962        freePreviewBufs();
1963        return ret;
1964        }
1965
1966    ///Start the callback notifier
1967    ret = mAppCallbackNotifier->start();
1968
1969    if( ALREADY_EXISTS == ret )
1970        {
1971        //Already running, do nothing
1972        CAMHAL_LOGDA("AppCallbackNotifier already running");
1973        ret = NO_ERROR;
1974        }
1975    else if ( NO_ERROR == ret ) {
1976        CAMHAL_LOGDA("Started AppCallbackNotifier..");
1977        mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
1978        }
1979    else
1980        {
1981        CAMHAL_LOGDA("Couldn't start AppCallbackNotifier");
1982        goto error;
1983        }
1984
1985    if (ret == NO_ERROR) mPreviewInitializationDone = true;
1986
1987    mAppCallbackNotifier->startPreviewCallbacks(mParameters, mPreviewBuffers, mPreviewOffsets, mPreviewFd, mPreviewLength, required_buffer_count);
1988
1989    return ret;
1990
1991    error:
1992
1993        CAMHAL_LOGEA("Performing cleanup after error");
1994
1995        //Do all the cleanup
1996        freePreviewBufs();
1997        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
1998        if(mDisplayAdapter.get() != NULL)
1999            {
2000            mDisplayAdapter->disableDisplay(false);
2001            }
2002        mAppCallbackNotifier->stop();
2003        mPreviewStartInProgress = false;
2004        mPreviewEnabled = false;
2005        LOG_FUNCTION_NAME_EXIT;
2006
2007        return ret;
2008}
2009
2010/**
2011   @brief Sets ANativeWindow object.
2012
2013   Preview buffers provided to CameraHal via this object. DisplayAdapter will be interfacing with it
2014   to render buffers to display.
2015
2016   @param[in] window The ANativeWindow object created by Surface flinger
2017   @return NO_ERROR If the ANativeWindow object passes validation criteria
2018   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2019
2020 */
2021status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window)
2022{
2023    status_t ret = NO_ERROR;
2024    CameraAdapter::BuffersDescriptor desc;
2025
2026    LOG_FUNCTION_NAME;
2027    mSetPreviewWindowCalled = true;
2028
2029   ///If the Camera service passes a null window, we destroy existing window and free the DisplayAdapter
2030    if(!window)
2031    {
2032        if(mDisplayAdapter.get() != NULL)
2033        {
2034            ///NULL window passed, destroy the display adapter if present
2035            CAMHAL_LOGD("NULL window passed, destroying display adapter");
2036            mDisplayAdapter.clear();
2037            ///@remarks If there was a window previously existing, we usually expect another valid window to be passed by the client
2038            ///@remarks so, we will wait until it passes a valid window to begin the preview again
2039            mSetPreviewWindowCalled = false;
2040        }
2041        CAMHAL_LOGD("NULL ANativeWindow passed to setPreviewWindow");
2042        return NO_ERROR;
2043    }else if(mDisplayAdapter.get() == NULL)
2044    {
2045        // Need to create the display adapter since it has not been created
2046        // Create display adapter
2047        mDisplayAdapter = new ANativeWindowDisplayAdapter();
2048#ifdef OMAP_ENHANCEMENT
2049        mDisplayAdapter->setExtendedOps(mExtendedPreviewStreamOps);
2050#endif
2051        ret = NO_ERROR;
2052        if(!mDisplayAdapter.get() || ((ret=mDisplayAdapter->initialize())!=NO_ERROR))
2053        {
2054            if(ret!=NO_ERROR)
2055            {
2056                mDisplayAdapter.clear();
2057                CAMHAL_LOGEA("DisplayAdapter initialize failed");
2058                LOG_FUNCTION_NAME_EXIT;
2059                return ret;
2060            }
2061            else
2062            {
2063                CAMHAL_LOGEA("Couldn't create DisplayAdapter");
2064                LOG_FUNCTION_NAME_EXIT;
2065                return NO_MEMORY;
2066            }
2067        }
2068
2069        // DisplayAdapter needs to know where to get the CameraFrames from inorder to display
2070        // Since CameraAdapter is the one that provides the frames, set it as the frame provider for DisplayAdapter
2071        mDisplayAdapter->setFrameProvider(mCameraAdapter);
2072
2073        // Any dynamic errors that happen during the camera use case has to be propagated back to the application
2074        // via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that  notifies such errors to the application
2075        // Set it as the error handler for the DisplayAdapter
2076        mDisplayAdapter->setErrorHandler(mAppCallbackNotifier.get());
2077
2078        // Update the display adapter with the new window that is passed from CameraService
2079        ret  = mDisplayAdapter->setPreviewWindow(window);
2080        if(ret!=NO_ERROR)
2081            {
2082            CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
2083            }
2084
2085        if(mPreviewStartInProgress)
2086        {
2087            CAMHAL_LOGDA("setPreviewWindow called when preview running");
2088            // Start the preview since the window is now available
2089            ret = startPreview();
2090        }
2091    } else {
2092        // Update the display adapter with the new window that is passed from CameraService
2093        ret = mDisplayAdapter->setPreviewWindow(window);
2094        if ( (NO_ERROR == ret) && previewEnabled() ) {
2095            restartPreview();
2096        } else if (ret == ALREADY_EXISTS) {
2097            // ALREADY_EXISTS should be treated as a noop in this case
2098            ret = NO_ERROR;
2099        }
2100    }
2101    LOG_FUNCTION_NAME_EXIT;
2102
2103    return ret;
2104
2105}
2106
2107
2108#ifdef OMAP_ENHANCEMENT_CPCAM
2109void CameraHal::setExtendedPreviewStreamOps(preview_stream_extended_ops_t *ops)
2110{
2111    mExtendedPreviewStreamOps = ops;
2112}
2113
2114/**
2115   @brief Sets Tapout Surfaces.
2116
2117   Buffers provided to CameraHal via this object for tap-out
2118   functionality.
2119
2120   @param[in] window The ANativeWindow object created by Surface flinger
2121   @return NO_ERROR If the ANativeWindow object passes validation criteria
2122   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2123
2124 */
2125status_t CameraHal::setTapoutLocked(struct preview_stream_ops *tapout)
2126{
2127    status_t ret = NO_ERROR;
2128    int index = -1;
2129
2130    LOG_FUNCTION_NAME;
2131
2132    if (!tapout) {
2133        CAMHAL_LOGD("Missing argument");
2134        LOG_FUNCTION_NAME_EXIT;
2135        return NO_ERROR;
2136    }
2137
2138    // Set tapout point
2139    // 1. Check name of tap-out
2140    // 2. If not already set, then create a new one
2141    // 3. Allocate buffers. If user is re-setting the surface, free buffers first and re-allocate
2142    //    in case dimensions have changed
2143
2144    for (unsigned int i = 0; i < mOutAdapters.size(); i++) {
2145        android::sp<DisplayAdapter> out;
2146        out = mOutAdapters.itemAt(i);
2147        ret = out->setPreviewWindow(tapout);
2148        if (ret == ALREADY_EXISTS) {
2149            CAMHAL_LOGD("Tap Out already set at index = %d", i);
2150            index = i;
2151            ret = NO_ERROR;
2152        }
2153    }
2154
2155    if (index < 0) {
2156        android::sp<DisplayAdapter> out  = new BufferSourceAdapter();
2157
2158        ret = out->initialize();
2159        if (ret != NO_ERROR) {
2160            out.clear();
2161            CAMHAL_LOGEA("DisplayAdapter initialize failed");
2162            goto exit;
2163        }
2164
2165        // BufferSourceAdapter will be handler of the extended OPS
2166        out->setExtendedOps(mExtendedPreviewStreamOps);
2167
2168        // CameraAdapter will be the frame provider for BufferSourceAdapter
2169        out->setFrameProvider(mCameraAdapter);
2170
2171        // BufferSourceAdapter will use ErrorHandler to send errors back to
2172        // the application
2173        out->setErrorHandler(mAppCallbackNotifier.get());
2174
2175        // Update the display adapter with the new window that is passed from CameraService
2176        ret  = out->setPreviewWindow(tapout);
2177        if(ret != NO_ERROR) {
2178            CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
2179            goto exit;
2180        }
2181
2182        if (NULL != mCameraAdapter) {
2183            unsigned int bufferCount, max_queueable;
2184            CameraFrame frame;
2185
2186            bufferCount = out->getBufferCount();
2187            if (bufferCount < 1) bufferCount = NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;
2188
2189            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
2190                                                  ( int ) &frame,
2191                                                  bufferCount);
2192            if (NO_ERROR != ret) {
2193                CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
2194            }
2195            if (NO_ERROR == ret) {
2196                CameraBuffer *bufs = NULL;
2197                unsigned int stride;
2198                unsigned int height = frame.mHeight;
2199                int size = frame.mLength;
2200
2201                stride = frame.mAlignment / getBPP(mParameters.getPictureFormat());
2202                bufs = out->allocateBufferList(stride,
2203                                               height,
2204                                               mParameters.getPictureFormat(),
2205                                               size,
2206                                               bufferCount);
2207                if (bufs == NULL){
2208                    CAMHAL_LOGEB("error allocating buffer list");
2209                    goto exit;
2210                }
2211            }
2212        }
2213        mOutAdapters.add(out);
2214    }
2215
2216exit:
2217
2218    LOG_FUNCTION_NAME_EXIT;
2219
2220    return ret;
2221}
2222
2223/**
2224   @brief Releases Tapout Surfaces.
2225
2226   @param[in] window The ANativeWindow object created by Surface flinger
2227   @return NO_ERROR If the ANativeWindow object passes validation criteria
2228   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2229
2230 */
2231status_t CameraHal::releaseTapoutLocked(struct preview_stream_ops *tapout)
2232{
2233    status_t ret = NO_ERROR;
2234    char id[OP_STR_SIZE];
2235
2236    LOG_FUNCTION_NAME;
2237
2238    if (!tapout) {
2239        CAMHAL_LOGD("Missing argument");
2240        LOG_FUNCTION_NAME_EXIT;
2241        return NO_ERROR;
2242    }
2243
2244    // Get the name of tapout
2245    ret = mExtendedPreviewStreamOps->get_id(tapout, id, sizeof(id));
2246    if (NO_ERROR != ret) {
2247        CAMHAL_LOGEB("get_id OPS returned error %d", ret);
2248        return ret;
2249    }
2250
2251    // 1. Check name of tap-out
2252    // 2. If exist, then free buffers and then remove it
2253    if (mBufferSourceAdapter_Out.get() && mBufferSourceAdapter_Out->match(id)) {
2254        CAMHAL_LOGD("REMOVE tap out %p previously set as current", tapout);
2255        mBufferSourceAdapter_Out.clear();
2256    }
2257    for (unsigned int i = 0; i < mOutAdapters.size(); i++) {
2258        android::sp<DisplayAdapter> out;
2259        out = mOutAdapters.itemAt(i);
2260        if (out->match(id)) {
2261            CAMHAL_LOGD("REMOVE tap out %p \"%s\" at position %d", tapout, id, i);
2262            mOutAdapters.removeAt(i);
2263            break;
2264        }
2265    }
2266
2267    LOG_FUNCTION_NAME_EXIT;
2268
2269    return ret;
2270}
2271
2272/**
2273   @brief Sets Tapin Surfaces.
2274
2275   Buffers provided to CameraHal via this object for tap-in
2276   functionality.
2277
2278   @param[in] window The ANativeWindow object created by Surface flinger
2279   @return NO_ERROR If the ANativeWindow object passes validation criteria
2280   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2281
2282 */
2283status_t CameraHal::setTapinLocked(struct preview_stream_ops *tapin)
2284{
2285    status_t ret = NO_ERROR;
2286    int index = -1;
2287
2288    LOG_FUNCTION_NAME;
2289
2290    if (!tapin) {
2291        CAMHAL_LOGD("Missing argument");
2292        LOG_FUNCTION_NAME_EXIT;
2293        return NO_ERROR;
2294    }
2295
2296    // 1. Set tapin point
2297    // 1. Check name of tap-in
2298    // 2. If not already set, then create a new one
2299    // 3. Allocate buffers. If user is re-setting the surface, free buffers first and re-allocate
2300    //    in case dimensions have changed
2301    for (unsigned int i = 0; i < mInAdapters.size(); i++) {
2302        android::sp<DisplayAdapter> in;
2303        in = mInAdapters.itemAt(i);
2304        ret = in->setPreviewWindow(tapin);
2305        if (ret == ALREADY_EXISTS) {
2306            CAMHAL_LOGD("Tap In already set at index = %d", i);
2307            index = i;
2308            ret = NO_ERROR;
2309        }
2310    }
2311
2312    if (index < 0) {
2313        android::sp<DisplayAdapter> in  = new BufferSourceAdapter();
2314
2315        ret = in->initialize();
2316        if (ret != NO_ERROR) {
2317            in.clear();
2318            CAMHAL_LOGEA("DisplayAdapter initialize failed");
2319            goto exit;
2320        }
2321
2322        // BufferSourceAdapter will be handler of the extended OPS
2323        in->setExtendedOps(mExtendedPreviewStreamOps);
2324
2325        // CameraAdapter will be the frame provider for BufferSourceAdapter
2326        in->setFrameProvider(mCameraAdapter);
2327
2328        // BufferSourceAdapter will use ErrorHandler to send errors back to
2329        // the application
2330        in->setErrorHandler(mAppCallbackNotifier.get());
2331
2332        // Update the display adapter with the new window that is passed from CameraService
2333        ret  = in->setPreviewWindow(tapin);
2334        if(ret != NO_ERROR) {
2335            CAMHAL_LOGEB("DisplayAdapter setPreviewWindow returned error %d", ret);
2336            goto exit;
2337        }
2338
2339        mInAdapters.add(in);
2340    }
2341
2342exit:
2343
2344    LOG_FUNCTION_NAME_EXIT;
2345
2346    return ret;
2347}
2348
2349
2350/**
2351   @brief Releases Tapin Surfaces.
2352
2353   @param[in] window The ANativeWindow object created by Surface flinger
2354   @return NO_ERROR If the ANativeWindow object passes validation criteria
2355   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2356
2357 */
2358status_t CameraHal::releaseTapinLocked(struct preview_stream_ops *tapin)
2359{
2360    status_t ret = NO_ERROR;
2361    char id[OP_STR_SIZE];
2362
2363    LOG_FUNCTION_NAME;
2364
2365    if (!tapin) {
2366        CAMHAL_LOGD("Missing argument");
2367        LOG_FUNCTION_NAME_EXIT;
2368        return NO_ERROR;
2369    }
2370
2371    // Get the name of tapin
2372    ret = mExtendedPreviewStreamOps->get_id(tapin, id, sizeof(id));
2373    if (NO_ERROR != ret) {
2374        CAMHAL_LOGEB("get_id OPS returned error %d", ret);
2375        return ret;
2376    }
2377
2378    // 1. Check name of tap-in
2379    // 2. If exist, then free buffers and then remove it
2380    if (mBufferSourceAdapter_In.get() && mBufferSourceAdapter_In->match(id)) {
2381        CAMHAL_LOGD("REMOVE tap in %p previously set as current", tapin);
2382        mBufferSourceAdapter_In.clear();
2383    }
2384    for (unsigned int i = 0; i < mInAdapters.size(); i++) {
2385        android::sp<DisplayAdapter> in;
2386        in = mInAdapters.itemAt(i);
2387        if (in->match(id)) {
2388            CAMHAL_LOGD("REMOVE tap in %p \"%s\" at position %d", tapin, id, i);
2389            mInAdapters.removeAt(i);
2390            break;
2391        }
2392    }
2393
2394    LOG_FUNCTION_NAME_EXIT;
2395
2396    return ret;
2397}
2398
2399
2400/**
2401   @brief Sets ANativeWindow object.
2402
2403   Buffers provided to CameraHal via this object for tap-in/tap-out
2404   functionality.
2405
2406   TODO(XXX): this is just going to use preview_stream_ops for now, but we
2407   most likely need to extend it when we want more functionality
2408
2409   @param[in] window The ANativeWindow object created by Surface flinger
2410   @return NO_ERROR If the ANativeWindow object passes validation criteria
2411   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2412
2413 */
2414status_t CameraHal::setBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout)
2415{
2416    status_t ret = NO_ERROR;
2417    int index = -1;
2418
2419    LOG_FUNCTION_NAME;
2420
2421    android::AutoMutex lock(mLock);
2422
2423    CAMHAL_LOGD ("setBufferSource(%p, %p)", tapin, tapout);
2424
2425    ret = setTapoutLocked(tapout);
2426    if (ret != NO_ERROR) {
2427        CAMHAL_LOGE("setTapoutLocked returned error 0x%x", ret);
2428        goto exit;
2429    }
2430
2431    ret = setTapinLocked(tapin);
2432    if (ret != NO_ERROR) {
2433        CAMHAL_LOGE("setTapinLocked returned error 0x%x", ret);
2434        goto exit;
2435    }
2436
2437exit:
2438    LOG_FUNCTION_NAME_EXIT;
2439
2440    return ret;
2441}
2442
2443
2444/**
2445   @brief Releases ANativeWindow object.
2446
2447   Release Buffers previously released with setBufferSource()
2448
2449   TODO(XXX): this is just going to use preview_stream_ops for now, but we
2450   most likely need to extend it when we want more functionality
2451
2452   @param[in] window The ANativeWindow object created by Surface flinger
2453   @return NO_ERROR If the ANativeWindow object passes validation criteria
2454   @todo Define validation criteria for ANativeWindow object. Define error codes for scenarios
2455
2456 */
2457status_t CameraHal::releaseBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout)
2458{
2459    status_t ret = NO_ERROR;
2460    int index = -1;
2461
2462    LOG_FUNCTION_NAME;
2463
2464    android::AutoMutex lock(mLock);
2465    CAMHAL_LOGD ("releaseBufferSource(%p, %p)", tapin, tapout);
2466    if (tapout) {
2467        ret |= releaseTapoutLocked(tapout);
2468        if (ret != NO_ERROR) {
2469            CAMHAL_LOGE("Error %d to release tap out", ret);
2470        }
2471    }
2472
2473    if (tapin) {
2474        ret |= releaseTapinLocked(tapin);
2475        if (ret != NO_ERROR) {
2476            CAMHAL_LOGE("Error %d to release tap in", ret);
2477        }
2478    }
2479
2480exit:
2481
2482    LOG_FUNCTION_NAME_EXIT;
2483
2484    return ret;
2485}
2486#endif
2487
2488
2489/**
2490   @brief Stop a previously started preview.
2491
2492   @param none
2493   @return none
2494
2495 */
2496void CameraHal::stopPreview()
2497{
2498    LOG_FUNCTION_NAME;
2499
2500    if( (!previewEnabled() && !mDisplayPaused) || mRecordingEnabled)
2501        {
2502        LOG_FUNCTION_NAME_EXIT;
2503        return;
2504        }
2505
2506    bool imageCaptureRunning = (mCameraAdapter->getState() & CameraAdapter::CAPTURE_STATE) &&
2507                                    (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE);
2508    if(mDisplayPaused && !imageCaptureRunning)
2509        {
2510        // Display is paused, which essentially means there is no preview active.
2511        // Note: this is done so that when stopPreview is called by client after
2512        // an image capture, we do not de-initialize the camera adapter and
2513        // restart over again.
2514
2515        return;
2516        }
2517
2518    forceStopPreview();
2519
2520    // Reset Capture-Mode to default, so that when we switch from VideoRecording
2521    // to ImageCapture, CAPTURE_MODE is not left to VIDEO_MODE.
2522    CAMHAL_LOGDA("Resetting Capture-Mode to default");
2523    mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
2524
2525    LOG_FUNCTION_NAME_EXIT;
2526}
2527
2528/**
2529   @brief Returns true if preview is enabled
2530
2531   @param none
2532   @return true If preview is running currently
2533         false If preview has been stopped
2534
2535 */
2536bool CameraHal::previewEnabled()
2537{
2538    LOG_FUNCTION_NAME;
2539
2540    return (mPreviewEnabled || mPreviewStartInProgress);
2541}
2542
2543/**
2544   @brief Start record mode.
2545
2546  When a record image is available a CAMERA_MSG_VIDEO_FRAME message is sent with
2547  the corresponding frame. Every record frame must be released by calling
2548  releaseRecordingFrame().
2549
2550   @param none
2551   @return NO_ERROR If recording could be started without any issues
2552   @todo Update the header with possible error values in failure scenarios
2553
2554 */
2555status_t CameraHal::startRecording( )
2556{
2557    int w, h;
2558    const char *valstr = NULL;
2559    bool restartPreviewRequired = false;
2560    status_t ret = NO_ERROR;
2561
2562    LOG_FUNCTION_NAME;
2563
2564
2565#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2566
2567            gettimeofday(&mStartPreview, NULL);
2568
2569#endif
2570
2571    if(!previewEnabled())
2572        {
2573        return NO_INIT;
2574        }
2575
2576    // set internal recording hint in case camera adapter needs to make some
2577    // decisions....(will only be sent to camera adapter if camera restart is required)
2578    mParameters.set(TICameraParameters::KEY_RECORDING_HINT, android::CameraParameters::TRUE);
2579
2580    // if application starts recording in continuous focus picture mode...
2581    // then we need to force default capture mode (as opposed to video mode)
2582    if ( ((valstr = mParameters.get(android::CameraParameters::KEY_FOCUS_MODE)) != NULL) &&
2583         (strcmp(valstr, android::CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) == 0) ){
2584        restartPreviewRequired = resetVideoModeParameters();
2585    }
2586
2587    // only need to check recording hint if preview restart is not already needed
2588    valstr = mParameters.get(android::CameraParameters::KEY_RECORDING_HINT);
2589    if ( !restartPreviewRequired &&
2590         (!valstr || (valstr && (strcmp(valstr, android::CameraParameters::TRUE) != 0))) ) {
2591        restartPreviewRequired = setVideoModeParameters(mParameters);
2592    }
2593
2594    if (restartPreviewRequired) {
2595        {
2596            android::AutoMutex lock(mLock);
2597            mCapModeBackup = mParameters.get(TICameraParameters::KEY_CAP_MODE);
2598        }
2599        ret = restartPreview();
2600    }
2601
2602    if ( NO_ERROR == ret )
2603      {
2604        int count = atoi(mCameraProperties->get(CameraProperties::REQUIRED_PREVIEW_BUFS));
2605        mParameters.getPreviewSize(&w, &h);
2606        CAMHAL_LOGDB("%s Video Width=%d Height=%d", __FUNCTION__, mVideoWidth, mVideoHeight);
2607
2608        if ((w != mVideoWidth) && (h != mVideoHeight))
2609          {
2610            ret = allocVideoBufs(mVideoWidth, mVideoHeight, count);
2611            if ( NO_ERROR != ret )
2612              {
2613                CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
2614                mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
2615                return ret;
2616              }
2617
2618            mAppCallbackNotifier->useVideoBuffers(true);
2619            mAppCallbackNotifier->setVideoRes(mVideoWidth, mVideoHeight);
2620            ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBuffers, mPreviewOffsets, mPreviewFd, mPreviewLength, count, mVideoBuffers);
2621          }
2622        else
2623          {
2624            mAppCallbackNotifier->useVideoBuffers(false);
2625            mAppCallbackNotifier->setVideoRes(mPreviewWidth, mPreviewHeight);
2626            ret = mAppCallbackNotifier->initSharedVideoBuffers(mPreviewBuffers, mPreviewOffsets, mPreviewFd, mPreviewLength, count, NULL);
2627          }
2628      }
2629
2630    if ( NO_ERROR == ret )
2631        {
2632         ret = mAppCallbackNotifier->startRecording();
2633        }
2634
2635    if ( NO_ERROR == ret )
2636        {
2637        ///Buffers for video capture (if different from preview) are expected to be allocated within CameraAdapter
2638         ret =  mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_VIDEO);
2639        }
2640
2641    if ( NO_ERROR == ret )
2642        {
2643        mRecordingEnabled = true;
2644        }
2645
2646    LOG_FUNCTION_NAME_EXIT;
2647
2648    return ret;
2649}
2650
2651/**
2652   @brief Set the camera parameters specific to Video Recording.
2653
2654   This function checks for the camera parameters which have to be set for recording.
2655   Video Recording needs CAPTURE_MODE to be VIDEO_MODE. This function sets it.
2656   This function also enables Video Recording specific functions like VSTAB & VNF.
2657
2658   @param none
2659   @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
2660   @todo Modify the policies for enabling VSTAB & VNF usecase based later.
2661
2662 */
2663bool CameraHal::setVideoModeParameters(const android::CameraParameters& params)
2664{
2665    const char *valstr = NULL;
2666    const char *valstrRemote = NULL;
2667    bool restartPreviewRequired = false;
2668
2669    LOG_FUNCTION_NAME;
2670
2671    // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
2672    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
2673    if ( (valstr == NULL) ||
2674        ( (valstr != NULL) && ( (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE) != 0) &&
2675                                (strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE_HQ ) != 0) ) ) ) {
2676        CAMHAL_LOGDA("Set CAPTURE_MODE to VIDEO_MODE");
2677        mParameters.set(TICameraParameters::KEY_CAP_MODE, (const char *) TICameraParameters::VIDEO_MODE);
2678        restartPreviewRequired = true;
2679    }
2680
2681    // set VSTAB. restart is required if vstab value has changed
2682    if ( (valstrRemote = params.get(android::CameraParameters::KEY_VIDEO_STABILIZATION)) != NULL ) {
2683        // make sure we support vstab
2684        if (strcmp(mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED),
2685                   android::CameraParameters::TRUE) == 0) {
2686            valstr = mParameters.get(android::CameraParameters::KEY_VIDEO_STABILIZATION);
2687            // vstab value has changed
2688            if ((valstr != NULL) &&
2689                 strcmp(valstr, valstrRemote) != 0) {
2690                restartPreviewRequired = true;
2691            }
2692            mParameters.set(android::CameraParameters::KEY_VIDEO_STABILIZATION,
2693                            valstrRemote);
2694        }
2695    } else if (mParameters.get(android::CameraParameters::KEY_VIDEO_STABILIZATION)) {
2696        // vstab was configured but now unset
2697        restartPreviewRequired = true;
2698        mParameters.remove(android::CameraParameters::KEY_VIDEO_STABILIZATION);
2699    }
2700
2701    // Set VNF
2702    if ((valstrRemote = params.get(TICameraParameters::KEY_VNF)) == NULL) {
2703        CAMHAL_LOGDA("Enable VNF");
2704        mParameters.set(TICameraParameters::KEY_VNF, android::CameraParameters::TRUE);
2705        restartPreviewRequired = true;
2706    } else {
2707        valstr = mParameters.get(TICameraParameters::KEY_VNF);
2708        if (valstr && strcmp(valstr, valstrRemote) != 0) {
2709            restartPreviewRequired = true;
2710        }
2711        mParameters.set(TICameraParameters::KEY_VNF, valstrRemote);
2712    }
2713
2714#if !defined(OMAP_ENHANCEMENT) && !defined(ENHANCED_DOMX)
2715        // For VSTAB alone for 1080p resolution, padded width goes > 2048, which cannot be rendered by GPU.
2716        // In such case, there is support in Ducati for combination of VSTAB & VNF requiring padded width < 2048.
2717        // So we are forcefully enabling VNF, if VSTAB is enabled for 1080p resolution.
2718        int w, h;
2719        params.getPreviewSize(&w, &h);
2720        valstr = mParameters.get(android::CameraParameters::KEY_VIDEO_STABILIZATION);
2721        if (valstr && (strcmp(valstr, android::CameraParameters::TRUE) == 0) && (w == 1920)) {
2722            CAMHAL_LOGDA("Force Enable VNF for 1080p");
2723            const char *valKeyVnf = mParameters.get(TICameraParameters::KEY_VNF);
2724            if(!valKeyVnf || (strcmp(valKeyVnf, android::CameraParameters::TRUE) != 0)) {
2725                mParameters.set(TICameraParameters::KEY_VNF, android::CameraParameters::TRUE);
2726                restartPreviewRequired = true;
2727            }
2728        }
2729#endif
2730
2731    LOG_FUNCTION_NAME_EXIT;
2732
2733    return restartPreviewRequired;
2734}
2735
2736/**
2737   @brief Reset the camera parameters specific to Video Recording.
2738
2739   This function resets CAPTURE_MODE and disables Recording specific functions like VSTAB & VNF.
2740
2741   @param none
2742   @return true if preview needs to be restarted for VIDEO_MODE parameters to take effect.
2743
2744 */
2745bool CameraHal::resetVideoModeParameters()
2746{
2747    const char *valstr = NULL;
2748    bool restartPreviewRequired = false;
2749    status_t ret = NO_ERROR;
2750
2751    LOG_FUNCTION_NAME;
2752
2753    // ignore this if we are already recording
2754    if (mRecordingEnabled) {
2755        return false;
2756    }
2757
2758    // Set CAPTURE_MODE to VIDEO_MODE, if not set already and Restart Preview
2759    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
2760    if ((valstr != NULL) && (strcmp(valstr, TICameraParameters::VIDEO_MODE) == 0)) {
2761        CAMHAL_LOGDA("Reset Capture-Mode to default");
2762        mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
2763        restartPreviewRequired = true;
2764    }
2765
2766    LOG_FUNCTION_NAME_EXIT;
2767
2768    return restartPreviewRequired;
2769}
2770
2771/**
2772   @brief Restart the preview with setParameter.
2773
2774   This function restarts preview, for some VIDEO_MODE parameters to take effect.
2775
2776   @param none
2777   @return NO_ERROR If recording parameters could be set without any issues
2778
2779 */
2780status_t CameraHal::restartPreview()
2781{
2782    status_t ret = NO_ERROR;
2783
2784    LOG_FUNCTION_NAME;
2785
2786    // Retain CAPTURE_MODE before calling stopPreview(), since it is reset in stopPreview().
2787
2788    forceStopPreview();
2789
2790    {
2791        android::AutoMutex lock(mLock);
2792        if (!mCapModeBackup.isEmpty()) {
2793            mParameters.set(TICameraParameters::KEY_CAP_MODE, mCapModeBackup.string());
2794            mCapModeBackup = "";
2795        } else {
2796            mParameters.set(TICameraParameters::KEY_CAP_MODE, "");
2797        }
2798        mCameraAdapter->setParameters(mParameters);
2799    }
2800
2801    ret = startPreview();
2802
2803    LOG_FUNCTION_NAME_EXIT;
2804
2805    return ret;
2806}
2807
2808/**
2809   @brief Stop a previously started recording.
2810
2811   @param none
2812   @return none
2813
2814 */
2815void CameraHal::stopRecording()
2816{
2817    CameraAdapter::AdapterState currentState;
2818
2819    LOG_FUNCTION_NAME;
2820
2821    android::AutoMutex lock(mLock);
2822
2823    if (!mRecordingEnabled )
2824        {
2825        return;
2826        }
2827
2828    currentState = mCameraAdapter->getState();
2829    if (currentState == CameraAdapter::VIDEO_CAPTURE_STATE) {
2830        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_IMAGE_CAPTURE);
2831    }
2832
2833    mAppCallbackNotifier->stopRecording();
2834
2835    mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_VIDEO);
2836
2837    mRecordingEnabled = false;
2838
2839    if ( mAppCallbackNotifier->getUesVideoBuffers() ){
2840      freeVideoBufs(mVideoBuffers);
2841      if (mVideoBuffers){
2842        CAMHAL_LOGVB(" FREEING mVideoBuffers %p", mVideoBuffers);
2843        delete [] mVideoBuffers;
2844      }
2845      mVideoBuffers = NULL;
2846    }
2847
2848    // reset internal recording hint in case camera adapter needs to make some
2849    // decisions....(will only be sent to camera adapter if camera restart is required)
2850    mParameters.remove(TICameraParameters::KEY_RECORDING_HINT);
2851
2852    LOG_FUNCTION_NAME_EXIT;
2853}
2854
2855/**
2856   @brief Returns true if recording is enabled.
2857
2858   @param none
2859   @return true If recording is currently running
2860         false If recording has been stopped
2861
2862 */
2863int CameraHal::recordingEnabled()
2864{
2865    LOG_FUNCTION_NAME;
2866
2867    LOG_FUNCTION_NAME_EXIT;
2868
2869    return mRecordingEnabled;
2870}
2871
2872/**
2873   @brief Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
2874
2875   @param[in] mem MemoryBase pointer to the frame being released. Must be one of the buffers
2876               previously given by CameraHal
2877   @return none
2878
2879 */
2880void CameraHal::releaseRecordingFrame(const void* mem)
2881{
2882    LOG_FUNCTION_NAME;
2883
2884    //CAMHAL_LOGDB(" 0x%x", mem->pointer());
2885
2886    if ( ( mRecordingEnabled ) && mem != NULL)
2887    {
2888        mAppCallbackNotifier->releaseRecordingFrame(mem);
2889    }
2890
2891    LOG_FUNCTION_NAME_EXIT;
2892
2893    return;
2894}
2895
2896/**
2897   @brief Start auto focus
2898
2899   This call asynchronous.
2900   The notification callback routine is called with CAMERA_MSG_FOCUS once when
2901   focusing is complete. autoFocus() will be called again if another auto focus is
2902   needed.
2903
2904   @param none
2905   @return NO_ERROR
2906   @todo Define the error codes if the focus is not locked
2907
2908 */
2909status_t CameraHal::autoFocus()
2910{
2911    status_t ret = NO_ERROR;
2912
2913#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2914
2915    gettimeofday(&mStartFocus, NULL);
2916
2917#endif
2918
2919    LOG_FUNCTION_NAME;
2920
2921    android::AutoMutex lock(mLock);
2922
2923    mMsgEnabled |= CAMERA_MSG_FOCUS;
2924
2925    if ( NULL == mCameraAdapter )
2926        {
2927            ret = -1;
2928            goto EXIT;
2929        }
2930
2931    CameraAdapter::AdapterState state;
2932    ret = mCameraAdapter->getState(state);
2933    if (ret != NO_ERROR)
2934        {
2935            goto EXIT;
2936        }
2937
2938    if (state == CameraAdapter::AF_STATE)
2939        {
2940            CAMHAL_LOGI("Ignoring start-AF (already in progress)");
2941            goto EXIT;
2942        }
2943
2944#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
2945
2946    //pass the autoFocus timestamp along with the command to camera adapter
2947    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS, ( int ) &mStartFocus);
2948
2949#else
2950
2951    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_PERFORM_AUTOFOCUS);
2952
2953#endif
2954
2955EXIT:
2956    LOG_FUNCTION_NAME_EXIT;
2957
2958    return ret;
2959}
2960
2961/**
2962   @brief Cancels auto-focus function.
2963
2964   If the auto-focus is still in progress, this function will cancel it.
2965   Whether the auto-focus is in progress or not, this function will return the
2966   focus position to the default. If the camera does not support auto-focus, this is a no-op.
2967
2968
2969   @param none
2970   @return NO_ERROR If the cancel succeeded
2971   @todo Define error codes if cancel didnt succeed
2972
2973 */
2974status_t CameraHal::cancelAutoFocus()
2975{
2976    LOG_FUNCTION_NAME;
2977
2978    android::AutoMutex lock(mLock);
2979    android::CameraParameters adapterParams = mParameters;
2980    mMsgEnabled &= ~CAMERA_MSG_FOCUS;
2981
2982    if( NULL != mCameraAdapter )
2983    {
2984        adapterParams.set(TICameraParameters::KEY_AUTO_FOCUS_LOCK, android::CameraParameters::FALSE);
2985        mCameraAdapter->setParameters(adapterParams);
2986        mCameraAdapter->sendCommand(CameraAdapter::CAMERA_CANCEL_AUTOFOCUS);
2987        mAppCallbackNotifier->flushEventQueue();
2988    }
2989
2990    LOG_FUNCTION_NAME_EXIT;
2991    return NO_ERROR;
2992}
2993
2994void CameraHal::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
2995{
2996
2997    LOG_FUNCTION_NAME;
2998
2999    if ( NULL != mEventProvider )
3000        {
3001        mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
3002        delete mEventProvider;
3003        mEventProvider = NULL;
3004        }
3005
3006    mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
3007    if ( NULL == mEventProvider )
3008        {
3009        CAMHAL_LOGEA("Error in creating EventProvider");
3010        }
3011    else
3012        {
3013        mEventProvider->enableEventNotification(eventMask);
3014        }
3015
3016    LOG_FUNCTION_NAME_EXIT;
3017}
3018
3019void CameraHal::eventCallbackRelay(CameraHalEvent* event)
3020{
3021    LOG_FUNCTION_NAME;
3022
3023    CameraHal *appcbn = ( CameraHal * ) (event->mCookie);
3024    appcbn->eventCallback(event );
3025
3026    LOG_FUNCTION_NAME_EXIT;
3027}
3028
3029void CameraHal::eventCallback(CameraHalEvent* event)
3030{
3031    LOG_FUNCTION_NAME;
3032
3033    LOG_FUNCTION_NAME_EXIT;
3034}
3035
3036status_t CameraHal::startImageBracketing()
3037{
3038    status_t ret = NO_ERROR;
3039    CameraFrame frame;
3040    CameraAdapter::BuffersDescriptor desc;
3041    unsigned int max_queueable = 0;
3042
3043
3044
3045#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3046
3047        gettimeofday(&mStartCapture, NULL);
3048
3049#endif
3050
3051        LOG_FUNCTION_NAME;
3052
3053        if(!previewEnabled() && !mDisplayPaused)
3054            {
3055            LOG_FUNCTION_NAME_EXIT;
3056            return NO_INIT;
3057            }
3058
3059        if ( !mBracketingEnabled )
3060            {
3061            return ret;
3062            }
3063
3064        if ( NO_ERROR == ret )
3065            {
3066            mBracketingRunning = true;
3067            }
3068
3069        if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
3070            {
3071            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
3072                                              ( int ) &frame,
3073                                              ( mBracketRangeNegative + 1 ));
3074
3075            if ( NO_ERROR != ret )
3076                {
3077                CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
3078                }
3079            }
3080
3081        if ( NO_ERROR == ret )
3082            {
3083            if ( NULL != mAppCallbackNotifier.get() )
3084                 {
3085                 mAppCallbackNotifier->setBurst(true);
3086                 }
3087            }
3088
3089        if ( NO_ERROR == ret )
3090            {
3091            mParameters.getPictureSize(( int * ) &frame.mWidth,
3092                                       ( int * ) &frame.mHeight);
3093
3094            ret = allocImageBufs(frame.mWidth,
3095                                 frame.mHeight,
3096                                 frame.mLength,
3097                                 mParameters.getPictureFormat(),
3098                                 ( mBracketRangeNegative + 1 ));
3099            if ( NO_ERROR != ret )
3100              {
3101                CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
3102              }
3103            }
3104
3105        if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
3106            {
3107
3108            desc.mBuffers = mImageBuffers;
3109            desc.mOffsets = mImageOffsets;
3110            desc.mFd = mImageFd;
3111            desc.mLength = mImageLength;
3112            desc.mCount = ( size_t ) ( mBracketRangeNegative + 1 );
3113            desc.mMaxQueueable = ( size_t ) ( mBracketRangeNegative + 1 );
3114
3115            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
3116                                              ( int ) &desc);
3117
3118            if ( NO_ERROR == ret )
3119                {
3120
3121#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3122
3123                 //pass capture timestamp along with the camera adapter command
3124                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE,  ( mBracketRangePositive + 1 ),  (int) &mStartCapture);
3125
3126#else
3127
3128                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_BRACKET_CAPTURE, ( mBracketRangePositive + 1 ));
3129
3130#endif
3131
3132                }
3133            }
3134
3135        return ret;
3136}
3137
3138status_t CameraHal::stopImageBracketing()
3139{
3140        status_t ret = NO_ERROR;
3141
3142        LOG_FUNCTION_NAME;
3143
3144        if( !previewEnabled() )
3145            {
3146            return NO_INIT;
3147            }
3148
3149        mBracketingRunning = false;
3150
3151        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_BRACKET_CAPTURE);
3152
3153        LOG_FUNCTION_NAME_EXIT;
3154
3155        return ret;
3156}
3157
3158/**
3159   @brief Take a picture.
3160
3161   @param none
3162   @return NO_ERROR If able to switch to image capture
3163   @todo Define error codes if unable to switch to image capture
3164
3165 */
3166status_t CameraHal::takePicture(const char *params)
3167{
3168    android::AutoMutex lock(mLock);
3169    return __takePicture(params);
3170}
3171
3172/**
3173   @brief Internal function for getting a captured image.
3174          shared by takePicture and reprocess.
3175   @param none
3176   @return NO_ERROR If able to switch to image capture
3177   @todo Define error codes if unable to switch to image capture
3178
3179 */
3180status_t CameraHal::__takePicture(const char *params, struct timeval *captureStart)
3181{
3182    // cancel AF state if needed (before any operation and mutex lock)
3183    if (mCameraAdapter->getState() == CameraAdapter::AF_STATE) {
3184        cancelAutoFocus();
3185    }
3186
3187    status_t ret = NO_ERROR;
3188    CameraFrame frame;
3189    CameraAdapter::BuffersDescriptor desc;
3190    int burst = -1;
3191    const char *valstr = NULL;
3192    unsigned int bufferCount = 1;
3193    unsigned int max_queueable = 0;
3194    unsigned int rawBufferCount = 1;
3195    bool isCPCamMode = false;
3196    android::sp<DisplayAdapter> outAdapter = 0;
3197    bool reuseTapout = false;
3198
3199#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3200
3201    if ( NULL == captureStart ) {
3202        gettimeofday(&mStartCapture, NULL);
3203    } else {
3204        memcpy(&mStartCapture, captureStart, sizeof(struct timeval));
3205    }
3206
3207#endif
3208
3209    LOG_FUNCTION_NAME;
3210
3211    if(!previewEnabled() && !mDisplayPaused)
3212        {
3213        LOG_FUNCTION_NAME_EXIT;
3214        CAMHAL_LOGEA("Preview not started...");
3215        return NO_INIT;
3216        }
3217
3218    valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
3219
3220    isCPCamMode = valstr && !strcmp(valstr, TICameraParameters::CP_CAM_MODE);
3221
3222    // return error if we are already capturing
3223    // however, we can queue a capture when in cpcam mode
3224    if ( ((mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
3225          mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) ||
3226         (mCameraAdapter->getState() == CameraAdapter::VIDEO_CAPTURE_STATE &&
3227          mCameraAdapter->getNextState() != CameraAdapter::VIDEO_STATE)) &&
3228         !isCPCamMode) {
3229        CAMHAL_LOGEA("Already capturing an image...");
3230        return NO_INIT;
3231    }
3232
3233    // we only support video snapshot if we are in video mode (recording hint is set)
3234    if ( (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) &&
3235         (valstr && ( strcmp(valstr, TICameraParameters::VIDEO_MODE) &&
3236                      strcmp(valstr, TICameraParameters::VIDEO_MODE_HQ ) ) ) ) {
3237        CAMHAL_LOGEA("Trying to capture while recording without recording hint set...");
3238        return INVALID_OPERATION;
3239    }
3240
3241#ifdef OMAP_ENHANCEMENT_CPCAM
3242    // check if camera application is using shots parameters
3243    // api. parameters set here override anything set using setParameters
3244    // TODO(XXX): Just going to use legacy TI parameters for now. Need
3245    // add new APIs in CameraHal to utilize android::ShotParameters later, so
3246    // we don't have to parse through the whole set of parameters
3247    // in camera adapter
3248    if (strlen(params) > 0) {
3249        android::ShotParameters shotParams;
3250        const char *valStr;
3251        const char *valExpComp, *valExpGain;
3252        int valNum;
3253
3254        android::String8 shotParams8(params);
3255
3256        shotParams.unflatten(shotParams8);
3257        mParameters.remove(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE);
3258        mParameters.remove(TICameraParameters::KEY_EXP_BRACKETING_RANGE);
3259
3260        valExpGain = shotParams.get(android::ShotParameters::KEY_EXP_GAIN_PAIRS);
3261        valExpComp = shotParams.get(android::ShotParameters::KEY_EXP_COMPENSATION);
3262        if (NULL != valExpComp) {
3263            mParameters.set(TICameraParameters::KEY_EXP_BRACKETING_RANGE, valExpComp);
3264        } else if (NULL != valExpGain) {
3265            mParameters.set(TICameraParameters::KEY_EXP_GAIN_BRACKETING_RANGE, valExpGain);
3266        }
3267
3268        valNum = shotParams.getInt(android::ShotParameters::KEY_BURST);
3269        if (valNum >= 0) {
3270            mParameters.set(TICameraParameters::KEY_BURST, valNum);
3271            burst = valNum;
3272        }
3273
3274        valStr = shotParams.get(android::ShotParameters::KEY_FLUSH_CONFIG);
3275        if (valStr!= NULL) {
3276            if ( 0 == strcmp(valStr, android::ShotParameters::TRUE) ) {
3277                mParameters.set(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE,
3278                                android::CameraParameters::TRUE);
3279            } else if ( 0 == strcmp(valStr, android::ShotParameters::FALSE) ) {
3280                mParameters.set(TICameraParameters::KEY_FLUSH_SHOT_CONFIG_QUEUE,
3281                                android::CameraParameters::FALSE);
3282            }
3283        }
3284
3285        valStr = shotParams.get(android::ShotParameters::KEY_CURRENT_TAP_OUT);
3286        if (valStr != NULL) {
3287            int index = -1;
3288            for (unsigned int i = 0; i < mOutAdapters.size(); i++) {
3289                if(mOutAdapters.itemAt(i)->match(valStr)) {
3290                    index = i;
3291                    break;
3292                }
3293            }
3294            if (index < 0) {
3295                CAMHAL_LOGE("Invalid tap out surface passed to camerahal");
3296                return BAD_VALUE;
3297            }
3298            CAMHAL_LOGD("Found matching out adapter at %d", index);
3299            outAdapter = mOutAdapters.itemAt(index);
3300            if ( outAdapter == mBufferSourceAdapter_Out ) {
3301                reuseTapout = true;
3302            }
3303        }
3304
3305        mCameraAdapter->setParameters(mParameters);
3306    } else
3307#endif
3308    {
3309        // TODO(XXX): Should probably reset burst and bracketing params
3310        // when we remove legacy TI parameters implementation
3311    }
3312
3313#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3314
3315    CameraHal::PPM("Takepicture parameters set: ", &mStartCapture);
3316
3317#endif
3318
3319    // if we are already in the middle of a capture and using the same
3320    // tapout ST...then we just need setParameters and start image
3321    // capture to queue more shots
3322    if (((mCameraAdapter->getState() & CameraAdapter::CAPTURE_STATE) ==
3323              CameraAdapter::CAPTURE_STATE) &&
3324         (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) &&
3325         (reuseTapout) ) {
3326#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3327        //pass capture timestamp along with the camera adapter command
3328        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE,
3329                                          (int) &mStartCapture);
3330#else
3331        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE);
3332#endif
3333        return ret;
3334    }
3335
3336    if ( !mBracketingRunning )
3337    {
3338         // if application didn't set burst through android::ShotParameters
3339         // then query from TICameraParameters
3340         if ((burst == -1) && (NO_ERROR == ret)) {
3341            burst = mParameters.getInt(TICameraParameters::KEY_BURST);
3342         }
3343
3344         //Allocate all buffers only in burst capture case
3345         if ( burst > 0 ) {
3346             // For CPCam mode...allocate for worst case burst
3347             bufferCount = isCPCamMode || (burst > CameraHal::NO_BUFFERS_IMAGE_CAPTURE) ?
3348                               CameraHal::NO_BUFFERS_IMAGE_CAPTURE : burst;
3349
3350             if (outAdapter.get()) {
3351                if ( reuseTapout ) {
3352                    bufferCount = mImageCount;
3353                } else {
3354                    bufferCount = outAdapter->getBufferCount();
3355                    if (bufferCount < 1) {
3356                        bufferCount = NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP;
3357                    }
3358                }
3359             }
3360
3361             if ( NULL != mAppCallbackNotifier.get() ) {
3362                 mAppCallbackNotifier->setBurst(true);
3363             }
3364         } else if ( mBracketingEnabled ) {
3365             bufferCount = mBracketRangeNegative + 1;
3366             if ( NULL != mAppCallbackNotifier.get() ) {
3367                 mAppCallbackNotifier->setBurst(false);
3368             }
3369         } else {
3370             if ( NULL != mAppCallbackNotifier.get() ) {
3371                 mAppCallbackNotifier->setBurst(false);
3372             }
3373         }
3374
3375        // pause preview during normal image capture
3376        // do not pause preview if recording (video state)
3377        if ( (NO_ERROR == ret) && (NULL != mDisplayAdapter.get()) ) {
3378            if (mCameraAdapter->getState() != CameraAdapter::VIDEO_STATE) {
3379                mDisplayPaused = true;
3380                mPreviewEnabled = false;
3381                ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
3382                // since preview is paused we should stop sending preview frames too
3383                if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
3384                    mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
3385                }
3386            }
3387
3388#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3389            mDisplayAdapter->setSnapshotTimeRef(&mStartCapture);
3390#endif
3391        }
3392
3393        // if we taking video snapshot...
3394        if ((NO_ERROR == ret) && (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE)) {
3395            // enable post view frames if not already enabled so we can internally
3396            // save snapshot frames for generating thumbnail
3397            if((mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) == 0) {
3398                mAppCallbackNotifier->enableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
3399            }
3400        }
3401
3402        if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) )
3403            {
3404            if ( NO_ERROR == ret )
3405                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
3406                                                  ( int ) &frame,
3407                                                  bufferCount);
3408
3409            if ( NO_ERROR != ret )
3410                {
3411                CAMHAL_LOGEB("CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE returned error 0x%x", ret);
3412                }
3413            }
3414
3415#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3416
3417    CameraHal::PPM("Takepicture buffer size queried: ", &mStartCapture);
3418
3419#endif
3420
3421        if (outAdapter.get()) {
3422            // Avoid locking the tapout again when reusing it
3423            if (!reuseTapout) {
3424                // Need to reset buffers if we are switching adapters since we don't know
3425                // the state of the new buffer list
3426                ret = outAdapter->maxQueueableBuffers(max_queueable);
3427                if (NO_ERROR != ret) {
3428                    CAMHAL_LOGE("Couldn't get max queuable");
3429                    return ret;
3430                }
3431                mImageBuffers = outAdapter->getBuffers(true);
3432                mImageOffsets = outAdapter->getOffsets();
3433                mImageFd = outAdapter->getFd();
3434                mImageLength = outAdapter->getSize();
3435                mImageCount = bufferCount;
3436                mBufferSourceAdapter_Out = outAdapter;
3437            }
3438        } else {
3439            mBufferSourceAdapter_Out.clear();
3440            // allocImageBufs will only allocate new buffers if mImageBuffers is NULL
3441            if ( NO_ERROR == ret ) {
3442                max_queueable = bufferCount;
3443                ret = allocImageBufs(frame.mAlignment / getBPP(mParameters.getPictureFormat()),
3444                                     frame.mHeight,
3445                                     frame.mLength,
3446                                     mParameters.getPictureFormat(),
3447                                     bufferCount);
3448                if ( NO_ERROR != ret ) {
3449                    CAMHAL_LOGEB("allocImageBufs returned error 0x%x", ret);
3450                }
3451            }
3452        }
3453
3454#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3455
3456    CameraHal::PPM("Takepicture buffers allocated: ", &mStartCapture);
3457    memcpy(&mImageBuffers->ppmStamp, &mStartCapture, sizeof(struct timeval));
3458
3459#endif
3460
3461    if (  (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
3462            {
3463            desc.mBuffers = mImageBuffers;
3464            desc.mOffsets = mImageOffsets;
3465            desc.mFd = mImageFd;
3466            desc.mLength = mImageLength;
3467            desc.mCount = ( size_t ) bufferCount;
3468            desc.mMaxQueueable = ( size_t ) max_queueable;
3469
3470            ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_IMAGE_CAPTURE,
3471                                              ( int ) &desc);
3472            }
3473        if (mRawCapture) {
3474            if ( NO_ERROR == ret ) {
3475                CAMHAL_LOGDB("Raw capture buffers setup - %s", mParameters.getPictureFormat());
3476                ret = allocRawBufs(mParameters.getInt(TICameraParameters::RAW_WIDTH),
3477                                   mParameters.getInt(TICameraParameters::RAW_HEIGHT),
3478                                   android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB,
3479                                   rawBufferCount);
3480
3481                if ( NO_ERROR != ret ) {
3482                    CAMHAL_LOGEB("allocRawBufs (for RAW capture) returned error 0x%x", ret);
3483                }
3484            }
3485
3486            if ((NO_ERROR == ret) && ( NULL != mCameraAdapter )) {
3487                desc.mBuffers = mVideoBuffers;
3488                desc.mOffsets = mVideoOffsets;
3489                desc.mFd = mVideoFd;
3490                desc.mLength = mVideoLength;
3491                desc.mCount = ( size_t ) rawBufferCount;
3492                desc.mMaxQueueable = ( size_t ) rawBufferCount;
3493
3494                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_VIDEO_CAPTURE,
3495                        ( int ) &desc);
3496            }
3497        }
3498    }
3499
3500#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3501
3502        CameraHal::PPM("Takepicture buffers registered: ", &mStartCapture);
3503
3504#endif
3505
3506    if ((ret == NO_ERROR) && mBufferSourceAdapter_Out.get()) {
3507        mBufferSourceAdapter_Out->enableDisplay(0, 0, NULL);
3508    }
3509
3510    if ((NO_ERROR == ret) && (NULL != mCameraAdapter)) {
3511
3512#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3513
3514         //pass capture timestamp along with the camera adapter command
3515        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE,  (int) &mStartCapture);
3516
3517        CameraHal::PPM("Takepicture capture started: ", &mStartCapture);
3518
3519#else
3520
3521        ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE);
3522
3523#endif
3524
3525    }
3526
3527    return ret;
3528}
3529
3530/**
3531   @brief Cancel a picture that was started with takePicture.
3532
3533   Calling this method when no picture is being taken is a no-op.
3534
3535   @param none
3536   @return NO_ERROR If cancel succeeded. Cancel can succeed if image callback is not sent
3537   @todo Define error codes
3538
3539 */
3540status_t CameraHal::cancelPicture( )
3541{
3542    LOG_FUNCTION_NAME;
3543    status_t ret = NO_ERROR;
3544
3545    ret = signalEndImageCapture();
3546    return NO_ERROR;
3547}
3548
3549/**
3550   @brief Return the camera parameters.
3551
3552   @param none
3553   @return Currently configured camera parameters
3554
3555 */
3556char* CameraHal::getParameters()
3557{
3558    android::String8 params_str8;
3559    char* params_string;
3560    const char * valstr = NULL;
3561
3562    LOG_FUNCTION_NAME;
3563
3564    if( NULL != mCameraAdapter )
3565    {
3566        mCameraAdapter->getParameters(mParameters);
3567    }
3568
3569    if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT)) != NULL ) {
3570        if (!strcmp(TICameraParameters::S3D_TB_FULL, valstr)) {
3571            mParameters.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PICTURE_TOPBOTTOM_SIZES));
3572        } else if (!strcmp(TICameraParameters::S3D_SS_FULL, valstr)) {
3573            mParameters.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PICTURE_SIDEBYSIDE_SIZES));
3574        } else if ((!strcmp(TICameraParameters::S3D_TB_SUBSAMPLED, valstr))
3575            || (!strcmp(TICameraParameters::S3D_SS_SUBSAMPLED, valstr))) {
3576            mParameters.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PICTURE_SUBSAMPLED_SIZES));
3577        }
3578    }
3579
3580    if ( (valstr = mParameters.get(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT)) != NULL ) {
3581        if (!strcmp(TICameraParameters::S3D_TB_FULL, valstr)) {
3582            mParameters.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PREVIEW_TOPBOTTOM_SIZES));
3583        } else if (!strcmp(TICameraParameters::S3D_SS_FULL, valstr)) {
3584            mParameters.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES));
3585        } else if ((!strcmp(TICameraParameters::S3D_TB_SUBSAMPLED, valstr))
3586                || (!strcmp(TICameraParameters::S3D_SS_SUBSAMPLED, valstr))) {
3587            mParameters.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mParameters.get(TICameraParameters::KEY_SUPPORTED_PREVIEW_SUBSAMPLED_SIZES));
3588        }
3589    }
3590
3591    android::CameraParameters mParams = mParameters;
3592
3593    // Handle RECORDING_HINT to Set/Reset Video Mode Parameters
3594    valstr = mParameters.get(android::CameraParameters::KEY_RECORDING_HINT);
3595    if(valstr != NULL)
3596      {
3597        if(strcmp(valstr, android::CameraParameters::TRUE) == 0)
3598          {
3599            //HACK FOR MMS MODE
3600            resetPreviewRes(&mParams);
3601          }
3602      }
3603
3604    // do not send internal parameters to upper layers
3605    mParams.remove(TICameraParameters::KEY_RECORDING_HINT);
3606    mParams.remove(TICameraParameters::KEY_AUTO_FOCUS_LOCK);
3607
3608    params_str8 = mParams.flatten();
3609
3610    // camera service frees this string...
3611    params_string = (char*) malloc(sizeof(char) * (params_str8.length()+1));
3612    strcpy(params_string, params_str8.string());
3613
3614    LOG_FUNCTION_NAME_EXIT;
3615
3616    ///Return the current set of parameters
3617
3618    return params_string;
3619}
3620
3621
3622#ifdef OMAP_ENHANCEMENT_CPCAM
3623/**
3624   @brief Starts reprocessing operation.
3625 */
3626status_t CameraHal::reprocess(const char *params)
3627{
3628    status_t ret = NO_ERROR;
3629    int bufferCount = 0;
3630    CameraAdapter::BuffersDescriptor desc;
3631    CameraBuffer *reprocBuffers = NULL;
3632    android::ShotParameters shotParams;
3633    const char *valStr = NULL;
3634    struct timeval startReprocess;
3635
3636    android::AutoMutex lock(mLock);
3637
3638    LOG_FUNCTION_NAME;
3639
3640#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3641
3642    gettimeofday(&startReprocess, NULL);
3643
3644#endif
3645
3646    // 0. Get tap in surface
3647    if (strlen(params) > 0) {
3648        android::String8 shotParams8(params);
3649        shotParams.unflatten(shotParams8);
3650    }
3651
3652    valStr = shotParams.get(android::ShotParameters::KEY_CURRENT_TAP_IN);
3653    if (valStr != NULL) {
3654        int index = -1;
3655        for (unsigned int i = 0; i < mInAdapters.size(); i++) {
3656            if(mInAdapters.itemAt(i)->match(valStr)) {
3657                index = i;
3658                break;
3659            }
3660        }
3661        if (index < 0) {
3662            CAMHAL_LOGE("Invalid tap in surface passed to camerahal");
3663            return BAD_VALUE;
3664        }
3665        CAMHAL_LOGD("Found matching in adapter at %d", index);
3666        mBufferSourceAdapter_In = mInAdapters.itemAt(index);
3667    } else {
3668        CAMHAL_LOGE("No tap in surface sent with shot config!");
3669        return BAD_VALUE;
3670    }
3671
3672    // 1. Get buffers
3673    if (mBufferSourceAdapter_In.get()) {
3674        reprocBuffers = mBufferSourceAdapter_In->getBufferList(&bufferCount);
3675    }
3676
3677    if (!reprocBuffers) {
3678        CAMHAL_LOGE("Error: couldn't get input buffers for reprocess()");
3679        goto exit;
3680    }
3681
3682
3683#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3684
3685    CameraHal::PPM("Got reprocess buffers: ", &startReprocess);
3686
3687#endif
3688
3689    // 2. Get buffer information and parse parameters
3690    {
3691        shotParams.setBurst(bufferCount);
3692    }
3693
3694#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3695
3696    memcpy(&reprocBuffers->ppmStamp, &startReprocess, sizeof(struct timeval));
3697
3698#endif
3699
3700    // 3. Give buffer to camera adapter
3701    desc.mBuffers = reprocBuffers;
3702    desc.mOffsets = 0;
3703    desc.mFd = 0;
3704    desc.mLength = 0;
3705    desc.mCount = (size_t) bufferCount;
3706    desc.mMaxQueueable = (size_t) bufferCount;
3707
3708    ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_REPROCESS, (int) &desc);
3709    if (ret != NO_ERROR) {
3710        CAMHAL_LOGE("Error calling camera use buffers");
3711        goto exit;
3712    }
3713
3714#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3715
3716    CameraHal::PPM("Reprocess buffers registered: ", &startReprocess);
3717
3718#endif
3719
3720    // 4. Start reprocessing
3721    ret = mBufferSourceAdapter_In->enableDisplay(0, 0, NULL);
3722    if (ret != NO_ERROR) {
3723        CAMHAL_LOGE("Error enabling tap in point");
3724        goto exit;
3725    }
3726
3727    // 5. Start capturing
3728    ret = __takePicture(shotParams.flatten().string(), &startReprocess);
3729
3730exit:
3731    return ret;
3732}
3733
3734/**
3735   @brief Cancels current reprocessing operation
3736
3737 */
3738status_t CameraHal::cancel_reprocess( )
3739{
3740    LOG_FUNCTION_NAME;
3741    status_t ret = NO_ERROR;
3742
3743    ret = signalEndImageCapture();
3744    return NO_ERROR;
3745}
3746#endif
3747
3748
3749void CameraHal::putParameters(char *parms)
3750{
3751    free(parms);
3752}
3753
3754/**
3755   @brief Send command to camera driver.
3756
3757   @param none
3758   @return NO_ERROR If the command succeeds
3759   @todo Define the error codes that this function can return
3760
3761 */
3762status_t CameraHal::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
3763{
3764    status_t ret = NO_ERROR;
3765
3766    LOG_FUNCTION_NAME;
3767
3768    if ( ( NO_ERROR == ret ) && ( NULL == mCameraAdapter ) )
3769        {
3770        CAMHAL_LOGEA("No CameraAdapter instance");
3771        return -EINVAL;
3772        }
3773
3774    ///////////////////////////////////////////////////////
3775    // Following commands do NOT need preview to be started
3776    ///////////////////////////////////////////////////////
3777
3778    switch ( cmd ) {
3779#ifdef ANDROID_API_JB_OR_LATER
3780    case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
3781    {
3782        const bool enable = static_cast<bool>(arg1);
3783        android::AutoMutex lock(mLock);
3784        if ( enable ) {
3785            mMsgEnabled |= CAMERA_MSG_FOCUS_MOVE;
3786        } else {
3787            mMsgEnabled &= ~CAMERA_MSG_FOCUS_MOVE;
3788        }
3789    }
3790        return OK;
3791#endif
3792    }
3793
3794    if ( ret == OK && !previewEnabled()
3795#ifdef OMAP_ENHANCEMENT_VTC
3796            && (cmd != CAMERA_CMD_PREVIEW_INITIALIZATION)
3797#endif
3798         ) {
3799        CAMHAL_LOGEA("Preview is not running");
3800        ret = -EINVAL;
3801    }
3802
3803    ///////////////////////////////////////////////////////
3804    // Following commands NEED preview to be started
3805    ///////////////////////////////////////////////////////
3806
3807    if ( NO_ERROR == ret )
3808        {
3809        switch(cmd)
3810            {
3811            case CAMERA_CMD_START_SMOOTH_ZOOM:
3812
3813                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_SMOOTH_ZOOM, arg1);
3814
3815                break;
3816            case CAMERA_CMD_STOP_SMOOTH_ZOOM:
3817
3818                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM);
3819                break;
3820
3821            case CAMERA_CMD_START_FACE_DETECTION:
3822
3823                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_FD);
3824
3825                break;
3826
3827            case CAMERA_CMD_STOP_FACE_DETECTION:
3828
3829                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
3830
3831                break;
3832
3833#ifdef OMAP_ENHANCEMENT_VTC
3834            case CAMERA_CMD_PREVIEW_DEINITIALIZATION:
3835                if(mDisplayAdapter.get() != NULL) {
3836                    ///Stop the buffer display first
3837                    mDisplayAdapter->disableDisplay();
3838                }
3839
3840                if(mAppCallbackNotifier.get() != NULL) {
3841                    //Stop the callback sending
3842                    mAppCallbackNotifier->stop();
3843                    mAppCallbackNotifier->flushAndReturnFrames();
3844                    mAppCallbackNotifier->stopPreviewCallbacks();
3845                }
3846
3847                ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_DESTROY_TUNNEL);
3848                mTunnelSetup = false;
3849
3850                break;
3851
3852            case CAMERA_CMD_PREVIEW_INITIALIZATION:
3853                ret = cameraPreviewInitialization();
3854
3855                break;
3856#endif
3857
3858            default:
3859                break;
3860            };
3861        }
3862
3863    LOG_FUNCTION_NAME_EXIT;
3864
3865    return ret;
3866}
3867
3868/**
3869   @brief Release the hardware resources owned by this object.
3870
3871   Note that this is *not* done in the destructor.
3872
3873   @param none
3874   @return none
3875
3876 */
3877void CameraHal::release()
3878{
3879    LOG_FUNCTION_NAME;
3880    ///@todo Investigate on how release is used by CameraService. Vaguely remember that this is called
3881    ///just before CameraHal object destruction
3882    deinitialize();
3883    LOG_FUNCTION_NAME_EXIT;
3884}
3885
3886
3887/**
3888   @brief Dump state of the camera hardware
3889
3890   @param[in] fd    File descriptor
3891   @param[in] args  Arguments
3892   @return NO_ERROR Dump succeeded
3893   @todo  Error codes for dump fail
3894
3895 */
3896status_t  CameraHal::dump(int fd) const
3897{
3898    LOG_FUNCTION_NAME;
3899    ///Implement this method when the h/w dump function is supported on Ducati side
3900    return NO_ERROR;
3901}
3902
3903/*-------------Camera Hal Interface Method definitions ENDS here--------------------*/
3904
3905
3906
3907
3908/*-------------Camera Hal Internal Method definitions STARTS here--------------------*/
3909
3910/**
3911   @brief Constructor of CameraHal
3912
3913   Member variables are initialized here.  No allocations should be done here as we
3914   don't use c++ exceptions in the code.
3915
3916 */
3917CameraHal::CameraHal(int cameraId)
3918{
3919    LOG_FUNCTION_NAME;
3920
3921    ///Initialize all the member variables to their defaults
3922    mPreviewEnabled = false;
3923    mPreviewBuffers = NULL;
3924    mImageBuffers = NULL;
3925    mBufProvider = NULL;
3926    mPreviewStartInProgress = false;
3927    mVideoBuffers = NULL;
3928    mVideoBufProvider = NULL;
3929    mRecordingEnabled = false;
3930    mDisplayPaused = false;
3931    mSetPreviewWindowCalled = false;
3932    mMsgEnabled = 0;
3933    mAppCallbackNotifier = NULL;
3934    mMemoryManager = NULL;
3935    mCameraAdapter = NULL;
3936    mBracketingEnabled = false;
3937    mBracketingRunning = false;
3938    mEventProvider = NULL;
3939    mBracketRangePositive = 1;
3940    mBracketRangeNegative = 1;
3941    mMaxZoomSupported = 0;
3942    mShutterEnabled = true;
3943    mMeasurementEnabled = false;
3944    mPreviewDataBuffers = NULL;
3945    mCameraProperties = NULL;
3946    mCurrentTime = 0;
3947    mFalsePreview = 0;
3948    mImageOffsets = NULL;
3949    mImageLength = 0;
3950    mImageFd = 0;
3951    mImageCount = 0;
3952    mVideoOffsets = NULL;
3953    mVideoFd = 0;
3954    mVideoLength = 0;
3955    mPreviewDataOffsets = NULL;
3956    mPreviewDataFd = 0;
3957    mPreviewDataLength = 0;
3958    mPreviewFd = 0;
3959    mPreviewWidth = 0;
3960    mPreviewHeight = 0;
3961    mPreviewLength = 0;
3962    mPreviewOffsets = NULL;
3963    mPreviewRunning = 0;
3964    mPreviewStateOld = 0;
3965    mRecordingEnabled = 0;
3966    mRecordEnabled = 0;
3967    mSensorListener = NULL;
3968    mVideoWidth = 0;
3969    mVideoHeight = 0;
3970#ifdef OMAP_ENHANCEMENT_VTC
3971    mVTCUseCase = false;
3972    mTunnelSetup = false;
3973#endif
3974    mPreviewInitializationDone = false;
3975
3976#ifdef OMAP_ENHANCEMENT_CPCAM
3977    mExtendedPreviewStreamOps = 0;
3978#endif
3979
3980    //These values depends on the sensor characteristics
3981
3982    mRawCapture = false;
3983
3984#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
3985
3986    //Initialize the CameraHAL constructor timestamp, which is used in the
3987    // PPM() method as time reference if the user does not supply one.
3988    gettimeofday(&ppm_start, NULL);
3989
3990#endif
3991
3992    mCameraIndex = cameraId;
3993
3994    LOG_FUNCTION_NAME_EXIT;
3995}
3996
3997/**
3998   @brief Destructor of CameraHal
3999
4000   This function simply calls deinitialize() to free up memory allocate during construct
4001   phase
4002 */
4003CameraHal::~CameraHal()
4004{
4005    LOG_FUNCTION_NAME;
4006
4007    ///Call de-initialize here once more - it is the last chance for us to relinquish all the h/w and s/w resources
4008    deinitialize();
4009
4010    if ( NULL != mEventProvider )
4011        {
4012        mEventProvider->disableEventNotification(CameraHalEvent::ALL_EVENTS);
4013        delete mEventProvider;
4014        mEventProvider = NULL;
4015        }
4016
4017    /// Free the callback notifier
4018    mAppCallbackNotifier.clear();
4019
4020    /// Free the display adapter
4021    mDisplayAdapter.clear();
4022
4023    if ( NULL != mCameraAdapter ) {
4024        int strongCount = mCameraAdapter->getStrongCount();
4025
4026        mCameraAdapter->decStrong(mCameraAdapter);
4027
4028        mCameraAdapter = NULL;
4029    }
4030
4031    freeImageBufs();
4032    freeRawBufs();
4033
4034    /// Free the memory manager
4035    mMemoryManager.clear();
4036
4037    LOG_FUNCTION_NAME_EXIT;
4038}
4039
4040/**
4041   @brief Initialize the Camera HAL
4042
4043   Creates CameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager
4044
4045   @param None
4046   @return NO_ERROR - On success
4047         NO_MEMORY - On failure to allocate memory for any of the objects
4048   @remarks Camera Hal internal function
4049
4050 */
4051
4052status_t CameraHal::initialize(CameraProperties::Properties* properties)
4053{
4054    LOG_FUNCTION_NAME;
4055
4056    int sensor_index = 0;
4057    const char* sensor_name = NULL;
4058
4059    ///Initialize the event mask used for registering an event provider for AppCallbackNotifier
4060    ///Currently, registering all events as to be coming from CameraAdapter
4061    int32_t eventMask = CameraHalEvent::ALL_EVENTS;
4062
4063    // Get my camera properties
4064    mCameraProperties = properties;
4065
4066    if(!mCameraProperties)
4067    {
4068        goto fail_loop;
4069    }
4070
4071    // Dump the properties of this Camera
4072    // will only print if DEBUG macro is defined
4073    mCameraProperties->dump();
4074
4075    if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)) != 0 )
4076        {
4077        sensor_index = atoi(mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX));
4078        }
4079
4080    if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_NAME)) != 0 ) {
4081        sensor_name = mCameraProperties->get(CameraProperties::CAMERA_NAME);
4082    }
4083    CAMHAL_LOGDB("Sensor index= %d; Sensor name= %s", sensor_index, sensor_name);
4084
4085    if (strcmp(sensor_name, V4L_CAMERA_NAME_USB) == 0) {
4086#ifdef V4L_CAMERA_ADAPTER
4087        mCameraAdapter = V4LCameraAdapter_Factory(sensor_index);
4088#endif
4089    }
4090    else {
4091#ifdef OMX_CAMERA_ADAPTER
4092        mCameraAdapter = OMXCameraAdapter_Factory(sensor_index);
4093#endif
4094    }
4095
4096    if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties)!=NO_ERROR))
4097        {
4098        CAMHAL_LOGEA("Unable to create or initialize CameraAdapter");
4099        mCameraAdapter = NULL;
4100        goto fail_loop;
4101        }
4102
4103    mCameraAdapter->incStrong(mCameraAdapter);
4104    mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);
4105    mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this);
4106
4107    if(!mAppCallbackNotifier.get())
4108        {
4109        /// Create the callback notifier
4110        mAppCallbackNotifier = new AppCallbackNotifier();
4111        if( ( NULL == mAppCallbackNotifier.get() ) || ( mAppCallbackNotifier->initialize() != NO_ERROR))
4112            {
4113            CAMHAL_LOGEA("Unable to create or initialize AppCallbackNotifier");
4114            goto fail_loop;
4115            }
4116        }
4117
4118    if(!mMemoryManager.get())
4119        {
4120        /// Create Memory Manager
4121        mMemoryManager = new MemoryManager();
4122        if( ( NULL == mMemoryManager.get() ) || ( mMemoryManager->initialize() != NO_ERROR))
4123            {
4124            CAMHAL_LOGEA("Unable to create or initialize MemoryManager");
4125            goto fail_loop;
4126            }
4127        }
4128
4129    ///Setup the class dependencies...
4130
4131    ///AppCallbackNotifier has to know where to get the Camera frames and the events like auto focus lock etc from.
4132    ///CameraAdapter is the one which provides those events
4133    ///Set it as the frame and event providers for AppCallbackNotifier
4134    ///@remarks  setEventProvider API takes in a bit mask of events for registering a provider for the different events
4135    ///         That way, if events can come from DisplayAdapter in future, we will be able to add it as provider
4136    ///         for any event
4137    mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);
4138    mAppCallbackNotifier->setFrameProvider(mCameraAdapter);
4139
4140    ///Any dynamic errors that happen during the camera use case has to be propagated back to the application
4141    ///via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that  notifies such errors to the application
4142    ///Set it as the error handler for CameraAdapter
4143    mCameraAdapter->setErrorHandler(mAppCallbackNotifier.get());
4144
4145    ///Start the callback notifier
4146    if(mAppCallbackNotifier->start() != NO_ERROR)
4147      {
4148        CAMHAL_LOGEA("Couldn't start AppCallbackNotifier");
4149        goto fail_loop;
4150      }
4151
4152    CAMHAL_LOGDA("Started AppCallbackNotifier..");
4153    mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
4154
4155    ///Initialize default parameters
4156    initDefaultParameters();
4157
4158
4159    if ( setParameters(mParameters) != NO_ERROR )
4160        {
4161        CAMHAL_LOGEA("Failed to set default parameters?!");
4162        }
4163
4164    // register for sensor events
4165    mSensorListener = new SensorListener();
4166    if (mSensorListener.get()) {
4167        if (mSensorListener->initialize() == NO_ERROR) {
4168            mSensorListener->setCallbacks(orientation_cb, this);
4169            mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);
4170        } else {
4171            CAMHAL_LOGEA("Error initializing SensorListener. not fatal, continuing");
4172            mSensorListener.clear();
4173            mSensorListener = NULL;
4174        }
4175    }
4176
4177    LOG_FUNCTION_NAME_EXIT;
4178
4179    return NO_ERROR;
4180
4181    fail_loop:
4182
4183        ///Free up the resources because we failed somewhere up
4184        deinitialize();
4185        LOG_FUNCTION_NAME_EXIT;
4186
4187        return NO_MEMORY;
4188
4189}
4190
4191bool CameraHal::isResolutionValid(unsigned int width, unsigned int height, const char *supportedResolutions)
4192{
4193    bool ret = false;
4194    status_t status = NO_ERROR;
4195    char tmpBuffer[MAX_PROP_VALUE_LENGTH];
4196    char *pos = NULL;
4197
4198    LOG_FUNCTION_NAME;
4199
4200    if (NULL == supportedResolutions) {
4201        CAMHAL_LOGEA("Invalid supported resolutions string");
4202        goto exit;
4203    }
4204
4205    status = snprintf(tmpBuffer, MAX_PROP_VALUE_LENGTH - 1, "%dx%d", width, height);
4206    if (0 > status) {
4207        CAMHAL_LOGEA("Error encountered while generating validation string");
4208        goto exit;
4209    }
4210
4211    ret = isParameterValid(tmpBuffer, supportedResolutions);
4212
4213exit:
4214    LOG_FUNCTION_NAME_EXIT;
4215
4216    return ret;
4217}
4218
4219bool CameraHal::isFpsRangeValid(int fpsMin, int fpsMax, const char *supportedFpsRanges)
4220{
4221    bool ret = false;
4222    char supported[MAX_PROP_VALUE_LENGTH];
4223    char *pos;
4224    int suppFpsRangeArray[2];
4225    int i = 0;
4226
4227    LOG_FUNCTION_NAME;
4228
4229    if ( NULL == supportedFpsRanges ) {
4230        CAMHAL_LOGEA("Invalid supported FPS ranges string");
4231        return false;
4232    }
4233
4234    if (fpsMin <= 0 || fpsMax <= 0 || fpsMin > fpsMax) {
4235        return false;
4236    }
4237
4238    strncpy(supported, supportedFpsRanges, MAX_PROP_VALUE_LENGTH);
4239    pos = strtok(supported, " (,)");
4240    while (pos != NULL) {
4241        suppFpsRangeArray[i] = atoi(pos);
4242        if (i++) {
4243            if (fpsMin >= suppFpsRangeArray[0] && fpsMax <= suppFpsRangeArray[1]) {
4244                ret = true;
4245                break;
4246            }
4247            i = 0;
4248        }
4249        pos = strtok(NULL, " (,)");
4250    }
4251
4252    LOG_FUNCTION_NAME_EXIT;
4253
4254    return ret;
4255}
4256
4257bool CameraHal::isParameterValid(const char *param, const char *supportedParams)
4258{
4259    bool ret = false;
4260    char *pos;
4261    char supported[MAX_PROP_VALUE_LENGTH];
4262
4263    LOG_FUNCTION_NAME;
4264
4265    if (NULL == supportedParams) {
4266        CAMHAL_LOGEA("Invalid supported parameters string");
4267        goto exit;
4268    }
4269
4270    if (NULL == param) {
4271        CAMHAL_LOGEA("Invalid parameter string");
4272        goto exit;
4273    }
4274
4275    strncpy(supported, supportedParams, MAX_PROP_VALUE_LENGTH - 1);
4276
4277    pos = strtok(supported, ",");
4278    while (pos != NULL) {
4279        if (!strcmp(pos, param)) {
4280            ret = true;
4281            break;
4282        }
4283        pos = strtok(NULL, ",");
4284    }
4285
4286exit:
4287    LOG_FUNCTION_NAME_EXIT;
4288
4289    return ret;
4290}
4291
4292bool CameraHal::isParameterValid(int param, const char *supportedParams)
4293{
4294    bool ret = false;
4295    status_t status;
4296    char tmpBuffer[MAX_PROP_VALUE_LENGTH];
4297
4298    LOG_FUNCTION_NAME;
4299
4300    if (NULL == supportedParams) {
4301        CAMHAL_LOGEA("Invalid supported parameters string");
4302        goto exit;
4303    }
4304
4305    status = snprintf(tmpBuffer, MAX_PROP_VALUE_LENGTH - 1, "%d", param);
4306    if (0 > status) {
4307        CAMHAL_LOGEA("Error encountered while generating validation string");
4308        goto exit;
4309    }
4310
4311    ret = isParameterValid(tmpBuffer, supportedParams);
4312
4313exit:
4314    LOG_FUNCTION_NAME_EXIT;
4315
4316    return ret;
4317}
4318
4319status_t CameraHal::doesSetParameterNeedUpdate(const char* new_param, const char* old_param, bool& update) {
4320    if (!new_param || !old_param) {
4321        return -EINVAL;
4322    }
4323
4324    // if params mismatch we should update parameters for camera adapter
4325    if ((strcmp(new_param, old_param) != 0)) {
4326       update = true;
4327    }
4328
4329   return NO_ERROR;
4330}
4331
4332status_t CameraHal::parseResolution(const char *resStr, int &width, int &height)
4333{
4334    status_t ret = NO_ERROR;
4335    char *ctx, *pWidth, *pHeight;
4336    const char *sep = "x";
4337
4338    LOG_FUNCTION_NAME;
4339
4340    if ( NULL == resStr )
4341        {
4342        return -EINVAL;
4343        }
4344
4345    //This fixes "Invalid input resolution"
4346    char *resStr_copy = (char *)malloc(strlen(resStr) + 1);
4347    if ( NULL != resStr_copy )
4348        {
4349        strcpy(resStr_copy, resStr);
4350        pWidth = strtok_r(resStr_copy, sep, &ctx);
4351
4352        if ( NULL != pWidth )
4353            {
4354            width = atoi(pWidth);
4355            }
4356        else
4357            {
4358            CAMHAL_LOGEB("Invalid input resolution %s", resStr);
4359            ret = -EINVAL;
4360            }
4361        }
4362
4363    if ( NO_ERROR == ret )
4364        {
4365        pHeight = strtok_r(NULL, sep, &ctx);
4366
4367        if ( NULL != pHeight )
4368            {
4369            height = atoi(pHeight);
4370            }
4371        else
4372            {
4373            CAMHAL_LOGEB("Invalid input resolution %s", resStr);
4374            ret = -EINVAL;
4375            }
4376        }
4377
4378    free(resStr_copy);
4379    resStr_copy = NULL;
4380
4381    LOG_FUNCTION_NAME_EXIT;
4382
4383    return ret;
4384}
4385
4386void CameraHal::insertSupportedParams()
4387{
4388    LOG_FUNCTION_NAME;
4389
4390    android::CameraParameters &p = mParameters;
4391
4392    ///Set the name of the camera
4393    p.set(TICameraParameters::KEY_CAMERA_NAME, mCameraProperties->get(CameraProperties::CAMERA_NAME));
4394
4395    mMaxZoomSupported = atoi(mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
4396
4397    p.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIZES));
4398    p.set(android::CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_FORMATS));
4399    p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIZES));
4400    p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FORMATS));
4401    p.set(TICameraParameters::KEY_SUPPORTED_PICTURE_SUBSAMPLED_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SUBSAMPLED_SIZES));
4402    p.set(TICameraParameters::KEY_SUPPORTED_PICTURE_SIDEBYSIDE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_SIDEBYSIDE_SIZES));
4403    p.set(TICameraParameters::KEY_SUPPORTED_PICTURE_TOPBOTTOM_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PICTURE_TOPBOTTOM_SIZES));
4404    p.set(TICameraParameters::KEY_SUPPORTED_PREVIEW_SUBSAMPLED_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SUBSAMPLED_SIZES));
4405    p.set(TICameraParameters::KEY_SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES));
4406    p.set(TICameraParameters::KEY_SUPPORTED_PREVIEW_TOPBOTTOM_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_TOPBOTTOM_SIZES));
4407    p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES));
4408    p.set(TICameraParameters::KEY_FRAMERATES_EXT_SUPPORTED, mCameraProperties->get(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES_EXT));
4409    p.set(android::CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_SUPPORTED));
4410    p.set(TICameraParameters::KEY_FRAMERATE_RANGES_EXT_SUPPORTED, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE_EXT_SUPPORTED));
4411    p.set(android::CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, mCameraProperties->get(CameraProperties::SUPPORTED_THUMBNAIL_SIZES));
4412    p.set(android::CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mCameraProperties->get(CameraProperties::SUPPORTED_WHITE_BALANCE));
4413    p.set(android::CameraParameters::KEY_SUPPORTED_EFFECTS, mCameraProperties->get(CameraProperties::SUPPORTED_EFFECTS));
4414    p.set(android::CameraParameters::KEY_SUPPORTED_SCENE_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_SCENE_MODES));
4415    p.set(android::CameraParameters::KEY_SUPPORTED_FLASH_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FLASH_MODES));
4416    p.set(android::CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mCameraProperties->get(CameraProperties::SUPPORTED_FOCUS_MODES));
4417    p.set(android::CameraParameters::KEY_SUPPORTED_ANTIBANDING, mCameraProperties->get(CameraProperties::SUPPORTED_ANTIBANDING));
4418    p.set(android::CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MAX));
4419    p.set(android::CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::SUPPORTED_EV_MIN));
4420    p.set(android::CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_EV_STEP));
4421    p.set(TICameraParameters::KEY_SUPPORTED_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_EXPOSURE_MODES));
4422    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MIN, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MIN));
4423    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_MAX, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MAX));
4424    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_EXPOSURE_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_STEP));
4425    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MIN));
4426    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MAX));
4427    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_GAIN_ISO_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_STEP));
4428    p.set(TICameraParameters::KEY_SUPPORTED_ISO_VALUES, mCameraProperties->get(CameraProperties::SUPPORTED_ISO_VALUES));
4429    p.set(android::CameraParameters::KEY_ZOOM_RATIOS, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_RATIOS));
4430    p.set(android::CameraParameters::KEY_MAX_ZOOM, mCameraProperties->get(CameraProperties::SUPPORTED_ZOOM_STAGES));
4431    p.set(android::CameraParameters::KEY_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::ZOOM_SUPPORTED));
4432    p.set(android::CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, mCameraProperties->get(CameraProperties::SMOOTH_ZOOM_SUPPORTED));
4433    p.set(TICameraParameters::KEY_SUPPORTED_IPP, mCameraProperties->get(CameraProperties::SUPPORTED_IPP_MODES));
4434    p.set(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT_VALUES, mCameraProperties->get(CameraProperties::S3D_PRV_FRAME_LAYOUT_VALUES));
4435    p.set(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT_VALUES, mCameraProperties->get(CameraProperties::S3D_CAP_FRAME_LAYOUT_VALUES));
4436    p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE_VALUES, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE_VALUES));
4437    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_CONVERGENCE_MIN, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MIN));
4438    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_CONVERGENCE_MAX, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_MAX));
4439    p.set(TICameraParameters::KEY_SUPPORTED_MANUAL_CONVERGENCE_STEP, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_CONVERGENCE_STEP));
4440    p.set(android::CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED, mCameraProperties->get(CameraProperties::VSTAB_SUPPORTED));
4441    p.set(TICameraParameters::KEY_VNF_SUPPORTED, mCameraProperties->get(CameraProperties::VNF_SUPPORTED));
4442    p.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK_SUPPORTED));
4443    p.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK_SUPPORTED));
4444    p.set(android::CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED, mCameraProperties->get(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED));
4445    p.set(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION_SUPPORTED, mCameraProperties->get(CameraProperties::MECHANICAL_MISALIGNMENT_CORRECTION_SUPPORTED));
4446    p.set(TICameraParameters::KEY_CAP_MODE_VALUES, mCameraProperties->get(CameraProperties::CAP_MODE_VALUES));
4447
4448    LOG_FUNCTION_NAME_EXIT;
4449
4450}
4451
4452void CameraHal::initDefaultParameters()
4453{
4454    //Purpose of this function is to initialize the default current and supported parameters for the currently
4455    //selected camera.
4456
4457    android::CameraParameters &p = mParameters;
4458    int currentRevision, adapterRevision;
4459    status_t ret = NO_ERROR;
4460    int width, height;
4461    const char *valstr;
4462
4463    LOG_FUNCTION_NAME;
4464
4465    insertSupportedParams();
4466
4467    ret = parseResolution(mCameraProperties->get(CameraProperties::PREVIEW_SIZE), width, height);
4468
4469    if ( NO_ERROR == ret )
4470        {
4471        p.setPreviewSize(width, height);
4472        }
4473    else
4474        {
4475        p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
4476        }
4477
4478    ret = parseResolution(mCameraProperties->get(CameraProperties::PICTURE_SIZE), width, height);
4479
4480    if ( NO_ERROR == ret )
4481        {
4482        p.setPictureSize(width, height);
4483        }
4484    else
4485        {
4486        p.setPictureSize(PICTURE_WIDTH, PICTURE_HEIGHT);
4487        }
4488
4489    ret = parseResolution(mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_SIZE), width, height);
4490
4491    if ( NO_ERROR == ret )
4492        {
4493        p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, width);
4494        p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, height);
4495        }
4496    else
4497        {
4498        p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, MIN_WIDTH);
4499        p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, MIN_HEIGHT);
4500        }
4501
4502    //Insert default values
4503    p.setPreviewFrameRate(atoi(mCameraProperties->get(CameraProperties::PREVIEW_FRAME_RATE)));
4504    p.set(android::CameraParameters::KEY_PREVIEW_FPS_RANGE, mCameraProperties->get(CameraProperties::FRAMERATE_RANGE));
4505    p.setPreviewFormat(mCameraProperties->get(CameraProperties::PREVIEW_FORMAT));
4506    p.setPictureFormat(mCameraProperties->get(CameraProperties::PICTURE_FORMAT));
4507    p.set(android::CameraParameters::KEY_JPEG_QUALITY, mCameraProperties->get(CameraProperties::JPEG_QUALITY));
4508    p.set(android::CameraParameters::KEY_WHITE_BALANCE, mCameraProperties->get(CameraProperties::WHITEBALANCE));
4509    p.set(android::CameraParameters::KEY_EFFECT,  mCameraProperties->get(CameraProperties::EFFECT));
4510    p.set(android::CameraParameters::KEY_ANTIBANDING, mCameraProperties->get(CameraProperties::ANTIBANDING));
4511    p.set(android::CameraParameters::KEY_FLASH_MODE, mCameraProperties->get(CameraProperties::FLASH_MODE));
4512    p.set(android::CameraParameters::KEY_FOCUS_MODE, mCameraProperties->get(CameraProperties::FOCUS_MODE));
4513    p.set(android::CameraParameters::KEY_EXPOSURE_COMPENSATION, mCameraProperties->get(CameraProperties::EV_COMPENSATION));
4514    p.set(android::CameraParameters::KEY_SCENE_MODE, mCameraProperties->get(CameraProperties::SCENE_MODE));
4515    p.set(android::CameraParameters::KEY_ZOOM, mCameraProperties->get(CameraProperties::ZOOM));
4516    p.set(TICameraParameters::KEY_CONTRAST, mCameraProperties->get(CameraProperties::CONTRAST));
4517    p.set(TICameraParameters::KEY_SATURATION, mCameraProperties->get(CameraProperties::SATURATION));
4518    p.set(TICameraParameters::KEY_BRIGHTNESS, mCameraProperties->get(CameraProperties::BRIGHTNESS));
4519    p.set(TICameraParameters::KEY_SHARPNESS, mCameraProperties->get(CameraProperties::SHARPNESS));
4520    p.set(TICameraParameters::KEY_EXPOSURE_MODE, mCameraProperties->get(CameraProperties::EXPOSURE_MODE));
4521    p.set(TICameraParameters::KEY_MANUAL_EXPOSURE, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MIN));
4522    p.set(TICameraParameters::KEY_MANUAL_EXPOSURE_RIGHT, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_EXPOSURE_MIN));
4523    p.set(TICameraParameters::KEY_MANUAL_GAIN_ISO, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MIN));
4524    p.set(TICameraParameters::KEY_MANUAL_GAIN_ISO_RIGHT, mCameraProperties->get(CameraProperties::SUPPORTED_MANUAL_GAIN_ISO_MIN));
4525    p.set(TICameraParameters::KEY_ISO, mCameraProperties->get(CameraProperties::ISO_MODE));
4526    p.set(TICameraParameters::KEY_IPP, mCameraProperties->get(CameraProperties::IPP));
4527    p.set(TICameraParameters::KEY_GBCE, mCameraProperties->get(CameraProperties::GBCE));
4528    p.set(TICameraParameters::KEY_GBCE_SUPPORTED, mCameraProperties->get(CameraProperties::SUPPORTED_GBCE));
4529    p.set(TICameraParameters::KEY_GLBCE, mCameraProperties->get(CameraProperties::GLBCE));
4530    p.set(TICameraParameters::KEY_GLBCE_SUPPORTED, mCameraProperties->get(CameraProperties::SUPPORTED_GLBCE));
4531    p.set(TICameraParameters::KEY_S3D_PRV_FRAME_LAYOUT, mCameraProperties->get(CameraProperties::S3D_PRV_FRAME_LAYOUT));
4532    p.set(TICameraParameters::KEY_S3D_CAP_FRAME_LAYOUT, mCameraProperties->get(CameraProperties::S3D_CAP_FRAME_LAYOUT));
4533    p.set(TICameraParameters::KEY_AUTOCONVERGENCE_MODE, mCameraProperties->get(CameraProperties::AUTOCONVERGENCE_MODE));
4534    p.set(TICameraParameters::KEY_MANUAL_CONVERGENCE, mCameraProperties->get(CameraProperties::MANUAL_CONVERGENCE));
4535    p.set(android::CameraParameters::KEY_VIDEO_STABILIZATION, mCameraProperties->get(CameraProperties::VSTAB));
4536    p.set(TICameraParameters::KEY_VNF, mCameraProperties->get(CameraProperties::VNF));
4537    p.set(android::CameraParameters::KEY_FOCAL_LENGTH, mCameraProperties->get(CameraProperties::FOCAL_LENGTH));
4538    p.set(android::CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::HOR_ANGLE));
4539    p.set(android::CameraParameters::KEY_VERTICAL_VIEW_ANGLE, mCameraProperties->get(CameraProperties::VER_ANGLE));
4540    p.set(TICameraParameters::KEY_SENSOR_ORIENTATION, mCameraProperties->get(CameraProperties::SENSOR_ORIENTATION));
4541    p.set(TICameraParameters::KEY_EXIF_MAKE, mCameraProperties->get(CameraProperties::EXIF_MAKE));
4542    p.set(TICameraParameters::KEY_EXIF_MODEL, mCameraProperties->get(CameraProperties::EXIF_MODEL));
4543    p.set(android::CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, mCameraProperties->get(CameraProperties::JPEG_THUMBNAIL_QUALITY));
4544    p.set(android::CameraParameters::KEY_VIDEO_FRAME_FORMAT, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar");
4545    p.set(android::CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, mCameraProperties->get(CameraProperties::MAX_FD_HW_FACES));
4546    p.set(android::CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, mCameraProperties->get(CameraProperties::MAX_FD_SW_FACES));
4547    p.set(TICameraParameters::KEY_MECHANICAL_MISALIGNMENT_CORRECTION, mCameraProperties->get(CameraProperties::MECHANICAL_MISALIGNMENT_CORRECTION));
4548    // Only one area a.k.a Touch AF for now.
4549    // TODO: Add support for multiple focus areas.
4550    p.set(android::CameraParameters::KEY_MAX_NUM_FOCUS_AREAS, mCameraProperties->get(CameraProperties::MAX_FOCUS_AREAS));
4551    p.set(android::CameraParameters::KEY_AUTO_EXPOSURE_LOCK, mCameraProperties->get(CameraProperties::AUTO_EXPOSURE_LOCK));
4552    p.set(android::CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK, mCameraProperties->get(CameraProperties::AUTO_WHITEBALANCE_LOCK));
4553    p.set(android::CameraParameters::KEY_MAX_NUM_METERING_AREAS, mCameraProperties->get(CameraProperties::MAX_NUM_METERING_AREAS));
4554    p.set(TICameraParameters::RAW_WIDTH, mCameraProperties->get(CameraProperties::RAW_WIDTH));
4555    p.set(TICameraParameters::RAW_HEIGHT,mCameraProperties->get(CameraProperties::RAW_HEIGHT));
4556
4557    // TI extensions for enable/disable algos
4558    // Hadcoded for now
4559    p.set(TICameraParameters::KEY_ALGO_EXTERNAL_GAMMA, android::CameraParameters::FALSE);
4560    p.set(TICameraParameters::KEY_ALGO_NSF1, android::CameraParameters::TRUE);
4561    p.set(TICameraParameters::KEY_ALGO_NSF2, android::CameraParameters::TRUE);
4562    p.set(TICameraParameters::KEY_ALGO_SHARPENING, android::CameraParameters::TRUE);
4563    p.set(TICameraParameters::KEY_ALGO_THREELINCOLORMAP, android::CameraParameters::TRUE);
4564    p.set(TICameraParameters::KEY_ALGO_GIC, android::CameraParameters::TRUE);
4565
4566    LOG_FUNCTION_NAME_EXIT;
4567}
4568
4569/**
4570   @brief Stop a previously started preview.
4571   @param none
4572   @return none
4573
4574 */
4575void CameraHal::forceStopPreview()
4576{
4577    LOG_FUNCTION_NAME;
4578
4579    // stop bracketing if it is running
4580    if ( mBracketingRunning ) {
4581        stopImageBracketing();
4582    }
4583
4584    if(mDisplayAdapter.get() != NULL) {
4585        ///Stop the buffer display first
4586        mDisplayAdapter->disableDisplay();
4587    }
4588
4589    if(mAppCallbackNotifier.get() != NULL) {
4590        //Stop the callback sending
4591        mAppCallbackNotifier->stop();
4592        mAppCallbackNotifier->flushAndReturnFrames();
4593        mAppCallbackNotifier->stopPreviewCallbacks();
4594    }
4595
4596    if ( NULL != mCameraAdapter ) {
4597        // only need to send these control commands to state machine if we are
4598        // passed the LOADED_PREVIEW_STATE
4599        if (mCameraAdapter->getState() > CameraAdapter::LOADED_PREVIEW_STATE) {
4600           // according to javadoc...FD should be stopped in stopPreview
4601           // and application needs to call startFaceDection again
4602           // to restart FD
4603           mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_FD);
4604        }
4605
4606        mCameraAdapter->rollbackToInitializedState();
4607
4608    }
4609
4610    freePreviewBufs();
4611    freePreviewDataBufs();
4612
4613    mPreviewEnabled = false;
4614    mDisplayPaused = false;
4615    mPreviewStartInProgress = false;
4616
4617    LOG_FUNCTION_NAME_EXIT;
4618}
4619
4620/**
4621   @brief Deallocates memory for all the resources held by Camera HAL.
4622
4623   Frees the following objects- CameraAdapter, AppCallbackNotifier, DisplayAdapter,
4624   and Memory Manager
4625
4626   @param none
4627   @return none
4628
4629 */
4630void CameraHal::deinitialize()
4631{
4632    LOG_FUNCTION_NAME;
4633
4634    if ( mPreviewEnabled || mDisplayPaused ) {
4635        forceStopPreview();
4636    }
4637
4638    mSetPreviewWindowCalled = false;
4639
4640    if (mSensorListener.get()) {
4641        mSensorListener->disableSensor(SensorListener::SENSOR_ORIENTATION);
4642        mSensorListener.clear();
4643        mSensorListener = NULL;
4644    }
4645
4646    mBufferSourceAdapter_Out.clear();
4647    mBufferSourceAdapter_In.clear();
4648    mOutAdapters.clear();
4649    mInAdapters.clear();
4650
4651    LOG_FUNCTION_NAME_EXIT;
4652
4653}
4654
4655status_t CameraHal::storeMetaDataInBuffers(bool enable)
4656{
4657    LOG_FUNCTION_NAME;
4658
4659    return mAppCallbackNotifier->useMetaDataBufferMode(enable);
4660
4661    LOG_FUNCTION_NAME_EXIT;
4662}
4663
4664void CameraHal::getPreferredPreviewRes(int *width, int *height)
4665{
4666    LOG_FUNCTION_NAME;
4667
4668    // We request Ducati for a higher resolution so preview looks better and then downscale the frame before the callback.
4669    // TODO: This should be moved to configuration constants and boolean flag whether to provide such optimization
4670    // Also consider providing this configurability of the desired display resolution from the application
4671    if ( ( *width == 320 ) && ( *height == 240 ) ) {
4672        *width = 640;
4673        *height = 480;
4674    } else if ( ( *width == 176 ) && ( *height == 144 ) ) {
4675        *width = 704;
4676        *height = 576;
4677    }
4678
4679    LOG_FUNCTION_NAME_EXIT;
4680}
4681
4682void CameraHal::resetPreviewRes(android::CameraParameters *params)
4683{
4684  LOG_FUNCTION_NAME;
4685
4686  if ( (mVideoWidth <= 320) && (mVideoHeight <= 240)){
4687    params->setPreviewSize(mVideoWidth, mVideoHeight);
4688  }
4689
4690  LOG_FUNCTION_NAME_EXIT;
4691}
4692
4693void *
4694camera_buffer_get_omx_ptr (CameraBuffer *buffer)
4695{
4696    CAMHAL_LOGV("buffer_type %d opaque %p", buffer->type, buffer->opaque);
4697
4698    if (buffer->type == CAMERA_BUFFER_ANW) {
4699        buffer_handle_t *handle = (buffer_handle_t *)buffer->opaque;
4700        CAMHAL_LOGV("anw %08x", *handle);
4701        return (void *)*handle;
4702    } else if (buffer->type == CAMERA_BUFFER_ION) {
4703        return (void *)buffer->fd;
4704    } else {
4705        CAMHAL_LOGV("other %08x", buffer->opaque);
4706        return (void *)buffer->opaque;
4707    }
4708}
4709
4710} // namespace Camera
4711} // namespace Ti
4712