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 CameraHalUtilClasses.cpp
19*
20* This file maps the CameraHardwareInterface to the Camera interfaces on OMAP4 (mainly OMX).
21*
22*/
23
24#include "CameraHal.h"
25
26namespace Ti {
27namespace Camera {
28
29/*--------------------FrameProvider Class STARTS here-----------------------------*/
30
31int FrameProvider::enableFrameNotification(int32_t frameTypes)
32{
33    LOG_FUNCTION_NAME;
34    status_t ret = NO_ERROR;
35
36    ///Enable the frame notification to CameraAdapter (which implements FrameNotifier interface)
37    mFrameNotifier->enableMsgType(frameTypes<<MessageNotifier::FRAME_BIT_FIELD_POSITION
38                                    , mFrameCallback
39                                    , NULL
40                                    , mCookie
41                                    );
42
43    LOG_FUNCTION_NAME_EXIT;
44    return ret;
45}
46
47int FrameProvider::disableFrameNotification(int32_t frameTypes)
48{
49    LOG_FUNCTION_NAME;
50    status_t ret = NO_ERROR;
51
52    mFrameNotifier->disableMsgType(frameTypes<<MessageNotifier::FRAME_BIT_FIELD_POSITION
53                                    , mCookie
54                                    );
55
56    LOG_FUNCTION_NAME_EXIT;
57    return ret;
58}
59
60int FrameProvider::returnFrame(CameraBuffer *frameBuf, CameraFrame::FrameType frameType)
61{
62    status_t ret = NO_ERROR;
63
64    mFrameNotifier->returnFrame(frameBuf, frameType);
65
66    return ret;
67}
68
69void FrameProvider::addFramePointers(CameraBuffer *frameBuf, void *buf)
70{
71  mFrameNotifier->addFramePointers(frameBuf, buf);
72  return;
73}
74
75void FrameProvider::removeFramePointers()
76{
77  mFrameNotifier->removeFramePointers();
78  return;
79}
80
81/*--------------------FrameProvider Class ENDS here-----------------------------*/
82
83/*--------------------EventProvider Class STARTS here-----------------------------*/
84
85int EventProvider::enableEventNotification(int32_t frameTypes)
86{
87    LOG_FUNCTION_NAME;
88    status_t ret = NO_ERROR;
89
90    ///Enable the frame notification to CameraAdapter (which implements FrameNotifier interface)
91    mEventNotifier->enableMsgType(frameTypes<<MessageNotifier::EVENT_BIT_FIELD_POSITION
92                                    , NULL
93                                    , mEventCallback
94                                    , mCookie
95                                    );
96
97    LOG_FUNCTION_NAME_EXIT;
98    return ret;
99}
100
101int EventProvider::disableEventNotification(int32_t frameTypes)
102{
103    LOG_FUNCTION_NAME;
104    status_t ret = NO_ERROR;
105
106    mEventNotifier->disableMsgType(frameTypes<<MessageNotifier::EVENT_BIT_FIELD_POSITION
107                                    , mCookie
108                                    );
109
110    LOG_FUNCTION_NAME_EXIT;
111    return ret;
112}
113
114/*--------------------EventProvider Class ENDS here-----------------------------*/
115
116/*--------------------CameraArea Class STARTS here-----------------------------*/
117
118status_t CameraArea::transfrom(size_t width,
119                               size_t height,
120                               size_t &top,
121                               size_t &left,
122                               size_t &areaWidth,
123                               size_t &areaHeight)
124{
125    status_t ret = NO_ERROR;
126    size_t hRange, vRange;
127    double hScale, vScale;
128
129    LOG_FUNCTION_NAME
130
131    hRange = CameraArea::RIGHT - CameraArea::LEFT;
132    vRange = CameraArea::BOTTOM - CameraArea::TOP;
133    hScale = ( double ) width / ( double ) hRange;
134    vScale = ( double ) height / ( double ) vRange;
135
136    top = ( mTop + vRange / 2 ) * vScale;
137    left = ( mLeft + hRange / 2 ) * hScale;
138    areaHeight = ( mBottom + vRange / 2 ) * vScale;
139    areaHeight -= top;
140    areaWidth = ( mRight + hRange / 2) * hScale;
141    areaWidth -= left;
142
143    LOG_FUNCTION_NAME_EXIT
144
145    return ret;
146}
147
148status_t CameraArea::checkArea(ssize_t top,
149                               ssize_t left,
150                               ssize_t bottom,
151                               ssize_t right,
152                               ssize_t weight)
153{
154
155    //Handles the invalid regin corner case.
156    if ( ( 0 == top ) && ( 0 == left ) && ( 0 == bottom ) && ( 0 == right ) && ( 0 == weight ) ) {
157        return NO_ERROR;
158    }
159
160    if ( ( CameraArea::WEIGHT_MIN > weight ) ||  ( CameraArea::WEIGHT_MAX < weight ) ) {
161        CAMHAL_LOGEB("Camera area weight is invalid %d", weight);
162        return -EINVAL;
163    }
164
165    if ( ( CameraArea::TOP > top ) || ( CameraArea::BOTTOM < top ) ) {
166        CAMHAL_LOGEB("Camera area top coordinate is invalid %d", top );
167        return -EINVAL;
168    }
169
170    if ( ( CameraArea::TOP > bottom ) || ( CameraArea::BOTTOM < bottom ) ) {
171        CAMHAL_LOGEB("Camera area bottom coordinate is invalid %d", bottom );
172        return -EINVAL;
173    }
174
175    if ( ( CameraArea::LEFT > left ) || ( CameraArea::RIGHT < left ) ) {
176        CAMHAL_LOGEB("Camera area left coordinate is invalid %d", left );
177        return -EINVAL;
178    }
179
180    if ( ( CameraArea::LEFT > right ) || ( CameraArea::RIGHT < right ) ) {
181        CAMHAL_LOGEB("Camera area right coordinate is invalid %d", right );
182        return -EINVAL;
183    }
184
185    if ( left >= right ) {
186        CAMHAL_LOGEA("Camera area left larger than right");
187        return -EINVAL;
188    }
189
190    if ( top >= bottom ) {
191        CAMHAL_LOGEA("Camera area top larger than bottom");
192        return -EINVAL;
193    }
194
195    return NO_ERROR;
196}
197
198status_t CameraArea::parseAreas(const char *area,
199                                size_t areaLength,
200                                android::Vector<android::sp<CameraArea> > &areas)
201{
202    status_t ret = NO_ERROR;
203    char *ctx;
204    char *pArea = NULL;
205    char *pStart = NULL;
206    char *pEnd = NULL;
207    const char *startToken = "(";
208    const char endToken = ')';
209    const char sep = ',';
210    ssize_t top, left, bottom, right, weight;
211    char *tmpBuffer = NULL;
212    android::sp<CameraArea> currentArea;
213
214    LOG_FUNCTION_NAME
215
216    if ( ( NULL == area ) ||
217         ( 0 >= areaLength ) )
218        {
219        return -EINVAL;
220        }
221
222    tmpBuffer = ( char * ) malloc(areaLength);
223    if ( NULL == tmpBuffer )
224        {
225        return -ENOMEM;
226        }
227
228    memcpy(tmpBuffer, area, areaLength);
229
230    pArea = strtok_r(tmpBuffer, startToken, &ctx);
231
232    do
233        {
234
235        pStart = pArea;
236        if ( NULL == pStart )
237            {
238            CAMHAL_LOGEA("Parsing of the left area coordinate failed!");
239            ret = -EINVAL;
240            break;
241            }
242        else
243            {
244            left = static_cast<ssize_t>(strtol(pStart, &pEnd, 10));
245            }
246
247        if ( sep != *pEnd )
248            {
249            CAMHAL_LOGEA("Parsing of the top area coordinate failed!");
250            ret = -EINVAL;
251            break;
252            }
253        else
254            {
255            top = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10));
256            }
257
258        if ( sep != *pEnd )
259            {
260            CAMHAL_LOGEA("Parsing of the right area coordinate failed!");
261            ret = -EINVAL;
262            break;
263            }
264        else
265            {
266            right = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10));
267            }
268
269        if ( sep != *pEnd )
270            {
271            CAMHAL_LOGEA("Parsing of the bottom area coordinate failed!");
272            ret = -EINVAL;
273            break;
274            }
275        else
276            {
277            bottom = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10));
278            }
279
280        if ( sep != *pEnd )
281            {
282            CAMHAL_LOGEA("Parsing of the weight area coordinate failed!");
283            ret = -EINVAL;
284            break;
285            }
286        else
287            {
288            weight = static_cast<ssize_t>(strtol(pEnd+1, &pEnd, 10));
289            }
290
291        if ( endToken != *pEnd )
292            {
293            CAMHAL_LOGEA("Malformed area!");
294            ret = -EINVAL;
295            break;
296            }
297
298        ret = checkArea(top, left, bottom, right, weight);
299        if ( NO_ERROR != ret ) {
300            break;
301        }
302
303        currentArea = new CameraArea(top, left, bottom, right, weight);
304        CAMHAL_LOGDB("Area parsed [%dx%d, %dx%d] %d",
305                     ( int ) top,
306                     ( int ) left,
307                     ( int ) bottom,
308                     ( int ) right,
309                     ( int ) weight);
310        if ( NULL != currentArea.get() )
311            {
312            areas.add(currentArea);
313            }
314        else
315            {
316            ret = -ENOMEM;
317            break;
318            }
319
320        pArea = strtok_r(NULL, startToken, &ctx);
321
322        }
323    while ( NULL != pArea );
324
325    if ( NULL != tmpBuffer )
326        {
327        free(tmpBuffer);
328        }
329
330    LOG_FUNCTION_NAME_EXIT
331
332    return ret;
333}
334
335bool CameraArea::areAreasDifferent(android::Vector< android::sp<CameraArea> > &area1,
336                                    android::Vector< android::sp<CameraArea> > &area2) {
337    if (area1.size() != area2.size()) {
338        return true;
339    }
340
341    // not going to care about sorting order for now
342    for (int i = 0; i < area1.size(); i++) {
343        if (!area1.itemAt(i)->compare(area2.itemAt(i))) {
344            return true;
345        }
346    }
347
348    return false;
349}
350
351bool CameraArea::compare(const android::sp<CameraArea> &area) {
352    return ((mTop == area->mTop) && (mLeft == area->mLeft) &&
353            (mBottom == area->mBottom) && (mRight == area->mRight) &&
354            (mWeight == area->mWeight));
355}
356
357
358/*--------------------CameraArea Class ENDS here-----------------------------*/
359
360} // namespace Camera
361} // namespace Ti
362