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