1/*
2** Copyright (c) 2011-2012 Code Aurora Forum. All rights reserved.
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/*#error uncomment this for compiler test!*/
18
19#define LOG_NDEBUG 0
20#define LOG_NIDEBUG 0
21#define LOG_TAG __FILE__
22#include <utils/Log.h>
23#include <utils/threads.h>
24
25
26#include "QCameraStream.h"
27
28/* QCameraStream class implementation goes here*/
29/* following code implement the control logic of this class*/
30
31namespace android {
32
33StreamQueue::StreamQueue(){
34    mInitialized = false;
35}
36
37StreamQueue::~StreamQueue(){
38    flush();
39}
40
41void StreamQueue::init(){
42    Mutex::Autolock l(&mQueueLock);
43    mInitialized = true;
44    mQueueWait.signal();
45}
46
47void StreamQueue::deinit(){
48    Mutex::Autolock l(&mQueueLock);
49    mInitialized = false;
50    mQueueWait.signal();
51}
52
53bool StreamQueue::isInitialized(){
54   Mutex::Autolock l(&mQueueLock);
55   return mInitialized;
56}
57
58bool StreamQueue::enqueue(
59                 void * element){
60    Mutex::Autolock l(&mQueueLock);
61    if(mInitialized == false)
62        return false;
63
64    mContainer.add(element);
65    mQueueWait.signal();
66    return true;
67}
68
69bool StreamQueue::isEmpty(){
70    return (mInitialized && mContainer.isEmpty());
71}
72void* StreamQueue::dequeue(){
73
74    void *frame;
75    mQueueLock.lock();
76    while(mInitialized && mContainer.isEmpty()){
77        mQueueWait.wait(mQueueLock);
78    }
79
80    if(!mInitialized){
81        mQueueLock.unlock();
82        return NULL;
83    }
84
85    frame = mContainer.itemAt(0);
86    mContainer.removeAt(0);
87    mQueueLock.unlock();
88    return frame;
89}
90
91void StreamQueue::flush(){
92    Mutex::Autolock l(&mQueueLock);
93    mContainer.clear();
94}
95
96
97// ---------------------------------------------------------------------------
98// QCameraStream
99// ---------------------------------------------------------------------------
100
101/* initialize a streaming channel*/
102status_t QCameraStream::initChannel(int cameraId,
103                                    uint32_t ch_type_mask)
104{
105#if 0
106    int rc = MM_CAMERA_OK;
107    int i;
108    status_t ret = NO_ERROR;
109    int width = 0;  /* width of channel      */
110    int height = 0; /* height of channel */
111    cam_ctrl_dimension_t dim;
112    mm_camera_ch_image_fmt_parm_t fmt;
113
114    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
115    rc = cam_config_get_parm(cameraId, MM_CAMERA_PARM_DIMENSION, &dim);
116    if (MM_CAMERA_OK != rc) {
117      LOGE("%s: error - can't get camera dimension!", __func__);
118      LOGE("%s: X", __func__);
119      return BAD_VALUE;
120    }
121
122    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask) {
123        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
124        LOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
125
126        if(MM_CAMERA_OK != rc) {
127                LOGE("%s: preview channel acquir error =%d\n", __func__, rc);
128                LOGE("%s: X", __func__);
129                return BAD_VALUE;
130        }
131        else{
132            memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
133            fmt.ch_type = MM_CAMERA_CH_PREVIEW;
134            fmt.def.fmt = CAMERA_YUV_420_NV12; //dim.prev_format;
135            fmt.def.dim.width = dim.display_width;
136            fmt.def.dim.height =  dim.display_height;
137            LOGV("%s: preview channel fmt = %d", __func__,
138                     dim.prev_format);
139            LOGV("%s: preview channel resolution = %d X %d", __func__,
140                     dim.display_width, dim.display_height);
141
142            rc = cam_config_set_parm(cameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
143            LOGV("%s: preview MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
144            if(MM_CAMERA_OK != rc) {
145                    LOGE("%s:set preview channel format err=%d\n", __func__, ret);
146                    LOGE("%s: X", __func__);
147                    ret = BAD_VALUE;
148            }
149        }
150    }
151
152
153    if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask)
154    {
155        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
156        LOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
157
158        if(MM_CAMERA_OK != rc) {
159                LOGE("%s: video channel acquir error =%d\n", __func__, rc);
160                LOGE("%s: X", __func__);
161                ret = BAD_VALUE;
162        }
163        else {
164            memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
165            fmt.ch_type = MM_CAMERA_CH_VIDEO;
166            fmt.video.video.fmt = CAMERA_YUV_420_NV12; //dim.enc_format;
167            fmt.video.video.dim.width = dim.video_width;
168            fmt.video.video.dim.height = dim.video_height;
169            LOGV("%s: video channel fmt = %d", __func__,
170                     dim.enc_format);
171            LOGV("%s: video channel resolution = %d X %d", __func__,
172                 dim.video_width, dim.video_height);
173
174            rc = cam_config_set_parm(cameraId,  MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
175
176            LOGV("%s: video MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
177            if(MM_CAMERA_OK != rc) {
178                LOGE("%s:set video channel format err=%d\n", __func__, rc);
179                LOGE("%s: X", __func__);
180                ret= BAD_VALUE;
181            }
182        }
183
184  } /*MM_CAMERA_CH_VIDEO*/
185#endif
186
187    int rc = MM_CAMERA_OK;
188    status_t ret = NO_ERROR;
189    mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
190    int i;
191
192    LOGV("QCameraStream::initChannel : E");
193    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
194        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
195        LOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
196        if(MM_CAMERA_OK != rc) {
197                LOGE("%s: preview channel acquir error =%d\n", __func__, rc);
198                LOGE("%s: X", __func__);
199                return BAD_VALUE;
200        }
201        /*Callback register*/
202        /* register a notify into the mmmm_camera_t object*/
203       /* ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
204                                                preview_notify_cb,
205                                                this);
206        LOGV("Buf notify MM_CAMERA_CH_PREVIEW, rc=%d\n",rc);*/
207    }else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
208        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
209        LOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
210        if(MM_CAMERA_OK != rc) {
211                LOGE("%s: preview channel acquir error =%d\n", __func__, rc);
212                LOGE("%s: X", __func__);
213                return BAD_VALUE;
214        }
215        /*Callback register*/
216        /* register a notify into the mmmm_camera_t object*/
217        /*ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
218                                                record_notify_cb,
219                                                this);
220        LOGV("Buf notify MM_CAMERA_CH_VIDEO, rc=%d\n",rc);*/
221    }
222
223    ret = (MM_CAMERA_OK==rc)? NO_ERROR : BAD_VALUE;
224    LOGV("%s: X, ret = %d", __func__, ret);
225    return ret;
226}
227
228status_t QCameraStream::deinitChannel(int cameraId,
229                                    mm_camera_channel_type_t ch_type)
230{
231
232    int rc = MM_CAMERA_OK;
233
234    LOGV("%s: E, channel = %d\n", __func__, ch_type);
235
236    if (MM_CAMERA_CH_MAX <= ch_type) {
237        LOGE("%s: X: BAD_VALUE", __func__);
238        return BAD_VALUE;
239    }
240
241    cam_ops_ch_release(cameraId, ch_type);
242
243    LOGV("%s: X, channel = %d\n", __func__, ch_type);
244    return NO_ERROR;
245}
246
247status_t QCameraStream::setMode(int enable) {
248  LOGE("%s :myMode %x ", __func__, myMode);
249  if (enable) {
250      myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
251  } else {
252      myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
253  }
254  return NO_ERROR;
255}
256
257status_t QCameraStream::setFormat(uint8_t ch_type_mask)
258{
259    int rc = MM_CAMERA_OK;
260    status_t ret = NO_ERROR;
261    int width = 0;  /* width of channel      */
262    int height = 0; /* height of channel */
263    cam_ctrl_dimension_t dim;
264    mm_camera_ch_image_fmt_parm_t fmt;
265    int preview_format;
266    LOGE("%s: E",__func__);
267
268    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
269    rc = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
270    if (MM_CAMERA_OK != rc) {
271      LOGE("%s: error - can't get camera dimension!", __func__);
272      LOGE("%s: X", __func__);
273      return BAD_VALUE;
274    }
275    char mDeviceName[PROPERTY_VALUE_MAX];
276    property_get("ro.product.device",mDeviceName," ");
277    memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
278    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
279        fmt.ch_type = MM_CAMERA_CH_PREVIEW;
280        ret = cam_config_get_parm(mCameraId,
281                  MM_CAMERA_PARM_PREVIEW_FORMAT, &preview_format);
282        fmt.def.fmt = (cam_format_t)preview_format;
283        fmt.def.dim.width = dim.display_width;
284        fmt.def.dim.height =  dim.display_height;
285    }else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
286        fmt.ch_type = MM_CAMERA_CH_VIDEO;
287        fmt.video.video.fmt = CAMERA_YUV_420_NV21; //dim.enc_format;
288        fmt.video.video.dim.width = dim.video_width;
289        fmt.video.video.dim.height = dim.video_height;
290    }/*else if(MM_CAMERA_CH_SNAPSHOT_MASK & ch_type_mask){
291        if(mHalCamCtrl->isRawSnapshot()) {
292            fmt.ch_type = MM_CAMERA_CH_RAW;
293            fmt.def.fmt = CAMERA_BAYER_SBGGR10;
294            fmt.def.dim.width = dim.raw_picture_width;
295            fmt.def.dim.height = dim.raw_picture_height;
296        }else{
297            //Jpeg???
298            fmt.ch_type = MM_CAMERA_CH_SNAPSHOT;
299            fmt.snapshot.main.fmt = dim.main_img_format;
300            fmt.snapshot.main.dim.width = dim.picture_width;
301            fmt.snapshot.main.dim.height = dim.picture_height;
302
303            fmt.snapshot.thumbnail.fmt = dim.thumb_format;
304            fmt.snapshot.thumbnail.dim.width = dim.ui_thumbnail_width;
305            fmt.snapshot.thumbnail.dim.height = dim.ui_thumbnail_height;
306        }
307    }*/
308
309    rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
310    LOGV("%s: Stream MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
311    if(MM_CAMERA_OK != rc) {
312        LOGE("%s:set stream channel format err=%d\n", __func__, ret);
313        LOGE("%s: X", __func__);
314        ret = BAD_VALUE;
315    }
316    LOGE("%s: X",__func__);
317    return ret;
318}
319
320QCameraStream::QCameraStream (){
321    mInit = false;
322    mActive = false;
323    /* memset*/
324    memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
325}
326
327QCameraStream::QCameraStream (int cameraId, camera_mode_t mode)
328              :mCameraId(cameraId),
329               myMode(mode)
330{
331    mInit = false;
332    mActive = false;
333
334    /* memset*/
335    memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
336}
337
338QCameraStream::~QCameraStream () {;}
339
340
341status_t QCameraStream::init() {
342    return NO_ERROR;
343}
344
345status_t QCameraStream::start() {
346    return NO_ERROR;
347}
348
349void QCameraStream::stop() {
350    return;
351}
352
353void QCameraStream::release() {
354    return;
355}
356
357void QCameraStream::setHALCameraControl(QCameraHardwareInterface* ctrl) {
358
359    /* provide a frame data user,
360    for the  queue monitor thread to call the busy queue is not empty*/
361    mHalCamCtrl = ctrl;
362}
363
364}; // namespace android
365