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 OMXZoom.cpp
19*
20* This file contains functionality for handling zoom configurations.
21*
22*/
23
24#undef LOG_TAG
25
26#define LOG_TAG "CameraHAL"
27
28#include "CameraHal.h"
29#include "OMXCameraAdapter.h"
30
31namespace android {
32
33const int32_t OMXCameraAdapter::ZOOM_STEPS [ZOOM_STAGES] =  {
34                                65536, 68157, 70124, 72745,
35                                75366, 77988, 80609, 83231,
36                                86508, 89784, 92406, 95683,
37                                99615, 102892, 106168, 110100,
38                                114033, 117965, 122552, 126484,
39                                131072, 135660, 140247, 145490,
40                                150733, 155976, 161219, 167117,
41                                173015, 178913, 185467, 192020,
42                                198574, 205783, 212992, 220201,
43                                228065, 236585, 244449, 252969,
44                                262144, 271319, 281149, 290980,
45                                300810, 311951, 322437, 334234,
46                                346030, 357827, 370934, 384041,
47                                397148, 411566, 425984, 441057,
48                                456131, 472515, 488899, 506593,
49                                524288 };
50
51
52status_t OMXCameraAdapter::setParametersZoom(const CameraParameters &params,
53                                             BaseCameraAdapter::AdapterState state)
54{
55    status_t ret = NO_ERROR;
56    Mutex::Autolock lock(mZoomLock);
57
58    LOG_FUNCTION_NAME;
59
60    //Immediate zoom should not be avaialable while smooth zoom is running
61    if ( ( ZOOM_ACTIVE & state ) != ZOOM_ACTIVE )
62        {
63        int zoom = params.getInt(CameraParameters::KEY_ZOOM);
64        if( ( zoom >= 0 ) && ( zoom < ZOOM_STAGES ) )
65            {
66            mTargetZoomIdx = zoom;
67
68            //Immediate zoom should be applied instantly ( CTS requirement )
69            mCurrentZoomIdx = mTargetZoomIdx;
70            if(!mZoomUpdating) {
71                doZoom(mCurrentZoomIdx);
72                mZoomUpdating = true;
73            } else {
74                mZoomUpdate = true;
75            }
76
77            CAMHAL_LOGDB("Zoom by App %d", zoom);
78            }
79        }
80
81    LOG_FUNCTION_NAME_EXIT;
82
83    return ret;
84}
85
86status_t OMXCameraAdapter::doZoom(int index)
87{
88    status_t ret = NO_ERROR;
89    OMX_ERRORTYPE eError = OMX_ErrorNone;
90    OMX_CONFIG_SCALEFACTORTYPE zoomControl;
91
92    LOG_FUNCTION_NAME;
93
94    if ( OMX_StateInvalid == mComponentState )
95        {
96        CAMHAL_LOGEA("OMX component is in invalid state");
97        ret = -1;
98        }
99
100    if (  ( 0 > index) || ( ( ZOOM_STAGES - 1 ) < index ) )
101        {
102        CAMHAL_LOGEB("Zoom index %d out of range", index);
103        ret = -EINVAL;
104        }
105
106    if (mPreviousZoomIndx == index )
107        {
108        return NO_ERROR;
109        }
110
111    if ( NO_ERROR == ret )
112        {
113        OMX_INIT_STRUCT_PTR (&zoomControl, OMX_CONFIG_SCALEFACTORTYPE);
114        zoomControl.nPortIndex = OMX_ALL;
115        zoomControl.xHeight = ZOOM_STEPS[index];
116        zoomControl.xWidth = ZOOM_STEPS[index];
117
118        eError =  OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
119                                OMX_IndexConfigCommonDigitalZoom,
120                                &zoomControl);
121        if ( OMX_ErrorNone != eError )
122            {
123            CAMHAL_LOGEB("Error while applying digital zoom 0x%x", eError);
124            ret = -1;
125            }
126        else
127            {
128            CAMHAL_LOGDA("Digital zoom applied successfully");
129            mPreviousZoomIndx = index;
130            }
131        }
132
133    LOG_FUNCTION_NAME_EXIT;
134
135    return ret;
136}
137
138status_t OMXCameraAdapter::advanceZoom()
139{
140    status_t ret = NO_ERROR;
141    AdapterState state;
142    Mutex::Autolock lock(mZoomLock);
143
144    BaseCameraAdapter::getState(state);
145
146    if ( mReturnZoomStatus )
147        {
148        mCurrentZoomIdx +=mZoomInc;
149        mTargetZoomIdx = mCurrentZoomIdx;
150        mReturnZoomStatus = false;
151        ret = doZoom(mCurrentZoomIdx);
152        notifyZoomSubscribers(mCurrentZoomIdx, true);
153        }
154    else if ( mCurrentZoomIdx != mTargetZoomIdx )
155        {
156        if ( ZOOM_ACTIVE & state )
157            {
158            if ( mCurrentZoomIdx < mTargetZoomIdx )
159                {
160                mZoomInc = 1;
161                }
162            else
163                {
164                mZoomInc = -1;
165                }
166
167            mCurrentZoomIdx += mZoomInc;
168            }
169        else
170            {
171            mCurrentZoomIdx = mTargetZoomIdx;
172            }
173
174        ret = doZoom(mCurrentZoomIdx);
175
176        if ( ZOOM_ACTIVE & state )
177            {
178            if ( mCurrentZoomIdx == mTargetZoomIdx )
179                {
180                CAMHAL_LOGDB("[Goal Reached] Smooth Zoom notify currentIdx = %d, targetIdx = %d",
181                             mCurrentZoomIdx,
182                             mTargetZoomIdx);
183
184                if ( NO_ERROR == ret )
185                    {
186
187                    ret =  BaseCameraAdapter::setState(CAMERA_STOP_SMOOTH_ZOOM);
188
189                    if ( NO_ERROR == ret )
190                        {
191                        ret = BaseCameraAdapter::commitState();
192                        }
193                    else
194                        {
195                        ret |= BaseCameraAdapter::rollbackState();
196                        }
197
198                    }
199                mReturnZoomStatus = false;
200                notifyZoomSubscribers(mCurrentZoomIdx, true);
201                }
202            else
203                {
204                CAMHAL_LOGDB("[Advancing] Smooth Zoom notify currentIdx = %d, targetIdx = %d",
205                             mCurrentZoomIdx,
206                             mTargetZoomIdx);
207                notifyZoomSubscribers(mCurrentZoomIdx, false);
208                }
209            }
210        }
211    else if ( (mCurrentZoomIdx == mTargetZoomIdx ) &&
212              ( ZOOM_ACTIVE & state ) )
213        {
214            ret = BaseCameraAdapter::setState(CameraAdapter::CAMERA_STOP_SMOOTH_ZOOM);
215
216            if ( NO_ERROR == ret )
217                {
218                ret = BaseCameraAdapter::commitState();
219                }
220            else
221                {
222                ret |= BaseCameraAdapter::rollbackState();
223                }
224
225        }
226
227    if(mZoomUpdate) {
228        doZoom(mTargetZoomIdx);
229        mZoomUpdate = false;
230        mZoomUpdating = true;
231    } else {
232        mZoomUpdating = false;
233    }
234
235    return ret;
236}
237
238status_t OMXCameraAdapter::startSmoothZoom(int targetIdx)
239{
240    status_t ret = NO_ERROR;
241
242    LOG_FUNCTION_NAME;
243
244    Mutex::Autolock lock(mZoomLock);
245
246    CAMHAL_LOGDB("Start smooth zoom target = %d, mCurrentIdx = %d",
247                 targetIdx,
248                 mCurrentZoomIdx);
249
250    if ( ( targetIdx >= 0 ) && ( targetIdx < ZOOM_STAGES ) )
251        {
252        mTargetZoomIdx = targetIdx;
253        mZoomParameterIdx = mCurrentZoomIdx;
254        mReturnZoomStatus = false;
255        }
256    else
257        {
258        CAMHAL_LOGEB("Smooth value out of range %d!", targetIdx);
259        ret = -EINVAL;
260        }
261
262    LOG_FUNCTION_NAME_EXIT;
263
264    return ret;
265}
266
267status_t OMXCameraAdapter::stopSmoothZoom()
268{
269    status_t ret = NO_ERROR;
270    Mutex::Autolock lock(mZoomLock);
271
272    LOG_FUNCTION_NAME;
273
274    if ( mTargetZoomIdx != mCurrentZoomIdx )
275        {
276        if ( mCurrentZoomIdx < mTargetZoomIdx )
277            {
278            mZoomInc = 1;
279            }
280        else
281            {
282            mZoomInc = -1;
283            }
284        mReturnZoomStatus = true;
285        mReturnZoomStatus = true;
286        CAMHAL_LOGDB("Stop smooth zoom mCurrentZoomIdx = %d, mTargetZoomIdx = %d",
287                     mCurrentZoomIdx,
288                     mTargetZoomIdx);
289        }
290
291    LOG_FUNCTION_NAME_EXIT;
292
293    return ret;
294}
295
296};
297