1 /*
2 ** Copyright (c) 2012 The Linux Foundation. All rights reserved.
3 **
4 ** Not a Contribution, Apache license notifications and license are retained
5 ** for attribution purposes only.
6 **
7 ** Licensed under the Apache License, Version 2.0 (the "License");
8 ** you may not use this file except in compliance with the License.
9 ** You may obtain a copy of the License at
10 **
11 **     http://www.apache.org/licenses/LICENSE-2.0
12 **
13 ** Unless required by applicable law or agreed to in writing, software
14 ** distributed under the License is distributed on an "AS IS" BASIS,
15 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ** See the License for the specific language governing permissions and
17 ** limitations under the License.
18 */
19 
20 /*#error uncomment this for compiler test!*/
21 
22 #define ALOG_NDEBUG 0
23 #define ALOG_NIDEBUG 0
24 #define LOG_TAG __FILE__
25 #include <utils/Log.h>
26 
27 #include "QCameraHWI.h"
28 #include "QCameraStream.h"
29 
30 /* QCameraStream class implementation goes here*/
31 /* following code implement the control logic of this class*/
32 
33 namespace android {
34 
35 // ---------------------------------------------------------------------------
36 // QCameraStream
37 // ---------------------------------------------------------------------------
38 
stream_cb_routine(mm_camera_super_buf_t * bufs,void * userdata)39 void stream_cb_routine(mm_camera_super_buf_t *bufs,
40                        void *userdata)
41 {
42     ALOGD("%s E ", __func__);
43     QCameraStream *p_obj=(QCameraStream*) userdata;
44     ALOGD("DEBUG4:ExtMode:%d,streamid:%d",p_obj->mExtImgMode,bufs->bufs[0]->stream_id);
45     switch(p_obj->mExtImgMode)
46     {
47         case MM_CAMERA_PREVIEW:
48             ALOGD("%s : callback for MM_CAMERA_PREVIEW", __func__);
49             ((QCameraStream_preview *)p_obj)->processPreviewFrame(bufs);
50             break;
51         case MM_CAMERA_VIDEO:
52             ((QCameraStream_record *)p_obj)->processRecordFrame(bufs);
53             break;
54         case MM_CAMERA_RDI:
55             ((QCameraStream_Rdi *)p_obj)->processRdiFrame(bufs);
56             break;
57         case MM_CAMERA_SNAPSHOT_MAIN:
58             break;
59         case MM_CAMERA_SNAPSHOT_THUMBNAIL:
60             break;
61         default:
62             break;
63 
64     }
65     ALOGD("%s X ", __func__);
66 }
67 
dataCallback(mm_camera_super_buf_t * bufs)68 void QCameraStream::dataCallback(mm_camera_super_buf_t *bufs)
69 {
70 }
71 
72 
setResolution(mm_camera_dimension_t * res)73 void QCameraStream::setResolution(mm_camera_dimension_t *res)
74 {
75     mWidth = res->width;
76     mHeight = res->height;
77 }
isResolutionSame(mm_camera_dimension_t * res)78 bool QCameraStream::isResolutionSame(mm_camera_dimension_t *res)
79 {
80     if (mWidth != res->width || mHeight != res->height)
81         return false;
82     else
83         return true;
84 }
getResolution(mm_camera_dimension_t * res)85 void QCameraStream::getResolution(mm_camera_dimension_t *res)
86 {
87     res->width = mWidth;
88     res->height = mHeight;
89 }
streamOn()90 int32_t QCameraStream::streamOn()
91 {
92    status_t rc = NO_ERROR;
93    ALOGD("%s: mActive = %d, streamid = %d, image_mode = %d",__func__, mActive, mStreamId, mExtImgMode);
94    if(mActive){
95        ALOGE("%s: Stream:%d is already active",
96             __func__,mStreamId);
97        return rc;
98    }
99 
100    if (mInit == true) {
101        /* this is the restart case, for now we need config again */
102        rc = setFormat();
103        ALOGD("%s: config_stream, rc = %d", __func__, rc);
104    }
105    rc = p_mm_ops->ops->start_streams(mCameraHandle,
106                               mChannelId,
107                               1,
108                               &mStreamId);
109    if(rc == NO_ERROR) {
110        mActive = true;
111    }
112    ALOGD("%s: X, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",
113          __func__, mActive, mInit, mStreamId, mExtImgMode);
114    return rc;
115 }
116 
streamOff(bool isAsyncCmd)117 int32_t QCameraStream::streamOff(bool isAsyncCmd)
118 {
119     status_t rc = NO_ERROR;
120     ALOGD("%s: mActive = %d, streamid = %d, image_mode = %d",__func__, mActive, mStreamId, mExtImgMode);
121     if(!mActive) {
122         ALOGE("%s: Stream:%d is not active",
123               __func__,mStreamId);
124         return rc;
125     }
126     mActive = false;
127 
128     rc = p_mm_ops->ops->stop_streams(mCameraHandle,
129                               mChannelId,
130                               1,
131                               &mStreamId);
132 
133     ALOGD("%s: X, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",
134           __func__, mActive, mInit, mStreamId, mExtImgMode);
135     return rc;
136 }
137 
138 /* initialize a streaming channel*/
initStream(uint8_t no_cb_needed,uint8_t stream_on)139 status_t QCameraStream::initStream(uint8_t no_cb_needed, uint8_t stream_on)
140 {
141 
142     int rc = MM_CAMERA_OK;
143 
144     /* save local copy */
145     m_flag_no_cb = no_cb_needed;
146     m_flag_stream_on = stream_on;
147 
148     ALOGD("%s: E, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",
149           __func__, mActive, mInit, mStreamId, mExtImgMode);
150 
151     if(mInit == true) {
152         ALOGE("%s: alraedy initted, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",
153               __func__, mActive, mInit, mStreamId, mExtImgMode);
154         return rc;
155     }
156     /***********Allocate Stream**************/
157     mStreamId = p_mm_ops->ops->add_stream(mCameraHandle,
158                         mChannelId,
159                         no_cb_needed? NULL :  stream_cb_routine,
160                         no_cb_needed? NULL : (void *)this,
161                         mExtImgMode,
162                         0/*sensor_idx*/);
163     if (mStreamId == 0) {
164         ALOGE("%s: err in add_stream, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",
165               __func__, mActive, mInit, mStreamId, mExtImgMode);
166        return BAD_VALUE;
167     }
168 
169     /***********Config Stream*****************/
170     rc = setFormat();
171     if(MM_CAMERA_OK != rc) {
172         ALOGE("%s: err in config_stream, mActive = %d, streamid = %d, image_mode = %d",
173               __func__, mActive, mStreamId, mExtImgMode);
174         p_mm_ops->ops->del_stream(mCameraHandle,
175                                   mChannelId,
176                                   mStreamId);
177         return BAD_VALUE;
178     }
179 
180     mInit=true;
181     ALOGE("%s: X, mActive = %d, streamid = %d, image_mode = %d",
182           __func__, mActive, mStreamId, mExtImgMode);
183     return NO_ERROR;
184 }
185 
deinitStream()186 status_t QCameraStream::deinitStream()
187 {
188 
189     int rc = MM_CAMERA_OK;
190 
191     ALOGD("%s: E, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",__func__, mActive, mInit, mStreamId, mExtImgMode);
192 
193     if(mInit == false) {
194         /* stream has not been initted. nop */
195         if (mStreamId > 0) {
196             ALOGE("%s: bug. mStreamId = %d, mInit = %d", __func__, mStreamId, mInit);
197             rc = -1;
198         }
199         return rc;
200     }
201     rc= p_mm_ops->ops->del_stream(mCameraHandle,mChannelId,
202                               mStreamId);
203 
204     ALOGV("%s: X, Stream = %d\n", __func__, mStreamId);
205     mInit = false;
206     mStreamId = 0;
207     ALOGD("%s: X, mActive = %d, mInit = %d, streamid = %d, image_mode = %d",
208           __func__, mActive, mInit, mStreamId, mExtImgMode);
209     return NO_ERROR;
210 }
211 
setFormat()212 status_t QCameraStream::setFormat()
213 {
214     int rc = MM_CAMERA_OK;
215     mm_camera_stream_config_t stream_config;
216 
217     ALOGV("%s: E, mActive = %d, streamid = %d, image_mode = %d",__func__, mActive, mStreamId, mExtImgMode);
218     memset(&stream_config, 0, sizeof(mm_camera_stream_config_t));
219 
220     switch(mExtImgMode)
221     {
222     case MM_CAMERA_PREVIEW:
223             /* Get mFormat */
224             rc = p_mm_ops->ops->get_parm(p_mm_ops->camera_handle,
225                                 MM_CAMERA_PARM_PREVIEW_FORMAT,
226                                 &mFormat);
227             if (MM_CAMERA_OK != rc) {
228                 ALOGE("%s: error - can't get preview format!", __func__);
229                 ALOGD("%s: X", __func__);
230                 return rc;
231             }
232             break;
233         case MM_CAMERA_VIDEO:
234             break;
235         case MM_CAMERA_SNAPSHOT_MAIN:
236             stream_config.fmt.rotation = mHalCamCtrl->getJpegRotation();
237             break;
238         case MM_CAMERA_SNAPSHOT_THUMBNAIL:
239             stream_config.fmt.rotation = mHalCamCtrl->getJpegRotation();
240             break;
241         case MM_CAMERA_RDI:
242             mWidth = 0;
243             mHeight = 0;
244             mFormat = CAMERA_BAYER_SBGGR10;
245         default:
246             break;
247     }
248 
249     stream_config.fmt.fmt = (cam_format_t)mFormat;
250     stream_config.fmt.meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
251     stream_config.fmt.width = mWidth;
252     stream_config.fmt.height = mHeight;
253     stream_config.num_of_bufs = mNumBuffers;
254     stream_config.need_stream_on = m_flag_stream_on;
255     rc = p_mm_ops->ops->config_stream(mCameraHandle,
256                               mChannelId,
257                               mStreamId,
258                               &stream_config);
259 
260     if(mHalCamCtrl->rdiMode != STREAM_IMAGE) {
261         mHalCamCtrl->mRdiWidth = stream_config.fmt.width;
262         mHalCamCtrl->mRdiHeight = stream_config.fmt.height;
263     }
264 
265     mWidth = stream_config.fmt.width;
266     mHeight = stream_config.fmt.height;
267     ALOGD("%s: X",__func__);
268     return rc;
269 }
270 
QCameraStream()271 QCameraStream::QCameraStream (){
272     mInit = false;
273     mActive = false;
274     /* memset*/
275     memset(&mCrop, 0, sizeof(mm_camera_rect_t));
276     m_flag_no_cb = FALSE;
277     m_flag_stream_on = TRUE;
278 }
279 
QCameraStream(uint32_t CameraHandle,uint32_t ChannelId,uint32_t Width,uint32_t Height,uint32_t Format,uint8_t NumBuffers,mm_camera_vtbl_t * mm_ops,mm_camera_img_mode imgmode,camera_mode_t mode,QCameraHardwareInterface * camCtrl)280 QCameraStream::QCameraStream(uint32_t CameraHandle,
281                              uint32_t ChannelId,
282                              uint32_t Width,
283                              uint32_t Height,
284                              uint32_t Format,
285                              uint8_t NumBuffers,
286                              mm_camera_vtbl_t *mm_ops,
287                              mm_camera_img_mode imgmode,
288                              camera_mode_t mode,
289                              QCameraHardwareInterface* camCtrl)
290               : mCameraHandle(CameraHandle),
291                 mChannelId(ChannelId),
292                 mWidth(Width),
293                 mHeight(Height),
294                 mFormat(Format),
295                 mNumBuffers(NumBuffers),
296                 p_mm_ops(mm_ops),
297                 mExtImgMode(imgmode),
298                 mHalCamCtrl(camCtrl)
299 {
300     mInit = false;
301     mActive = false;
302 
303     mStreamId = 0;
304     m_flag_no_cb = FALSE;
305     m_flag_stream_on = TRUE;
306 
307     /* memset*/
308     memset(&mCrop, 0, sizeof(mm_camera_rect_t));
309 }
310 
~QCameraStream()311 QCameraStream::~QCameraStream ()
312 {
313 }
314 
release()315 void QCameraStream::release() {
316     return;
317 }
318 
setCrop()319 int32_t QCameraStream::setCrop()
320 {
321     mm_camera_rect_t v4l2_crop;
322     int32_t rc = 0;
323     memset(&v4l2_crop,0,sizeof(v4l2_crop));
324 
325     if(!mActive) {
326         ALOGE("%s: Stream:%d is not active", __func__, mStreamId);
327         return -1;
328     }
329 
330     rc = p_mm_ops->ops->get_stream_parm(mCameraHandle,
331                                    mChannelId,
332                                    mStreamId,
333                                    MM_CAMERA_STREAM_CROP,
334                                    &v4l2_crop);
335     ALOGI("%s: Crop info received: %d, %d, %d, %d ",
336                                  __func__,
337                                  v4l2_crop.left,
338                                  v4l2_crop.top,
339                                  v4l2_crop.width,
340                                  v4l2_crop.height);
341     if (rc == 0) {
342         mCrop.offset_x = v4l2_crop.left;
343         mCrop.offset_y = v4l2_crop.top;
344         mCrop.width = v4l2_crop.width;
345         mCrop.height = v4l2_crop.height;
346     }
347     return rc;
348 }
349 
350 }; // namespace android
351