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 
31 namespace android {
32 
33 const 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 
setParametersZoom(const CameraParameters & params,BaseCameraAdapter::AdapterState state)52 status_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 
doZoom(int index)86 status_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 
advanceZoom()138 status_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 
startSmoothZoom(int targetIdx)238 status_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 
stopSmoothZoom()267 status_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