1 /*
2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <poll.h>
37 #include <time.h>
38 #include <semaphore.h>
39
40 #include "mm_camera_dbg.h"
41 #include "mm_camera_interface.h"
42 #include "mm_camera.h"
43
44 #define MM_CAMERA_MAX_NUM_FRAMES 16
45
46 /* internal function decalre */
47 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
48 mm_camera_buf_def_t *buf);
49 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj);
50 int32_t mm_stream_set_fmt(mm_stream_t * my_obj);
51 int32_t mm_stream_get_offset(mm_stream_t *my_obj);
52 int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *in_value);
53 int32_t mm_stream_init_bufs(mm_stream_t * my_obj);
54 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj);
55 int32_t mm_stream_request_buf(mm_stream_t * my_obj);
56 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj);
57 int32_t mm_stream_release(mm_stream_t *my_obj);
58 int32_t mm_stream_get_crop(mm_stream_t *my_obj,
59 mm_camera_rect_t *crop);
60 int32_t mm_stream_get_cid(mm_stream_t *my_obj,
61 stream_cid_t *out_value);
62 int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj,
63 void *value);
64 int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj,
65 void *value);
66 int32_t mm_stream_set_parm_config(mm_stream_t *my_obj,
67 void *value);
68 int32_t mm_stream_get_parm_config(mm_stream_t *my_obj,
69 void *value);
70 int32_t mm_stream_set_parm_start(mm_stream_t *my_obj,
71 void *value);
72 int32_t mm_stream_get_parm_start(mm_stream_t *my_obj,
73 void *value);
74 int32_t mm_stream_streamon(mm_stream_t *my_obj);
75 int32_t mm_stream_streamoff(mm_stream_t *my_obj);
76 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
77 mm_camera_buf_info_t* buf_info);
78 int32_t mm_stream_config(mm_stream_t *my_obj,
79 mm_camera_stream_config_t *config);
80 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
81 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
82 mm_camera_buf_def_t *frame);
83
84
85 /* state machine function declare */
86 int32_t mm_stream_fsm_inited(mm_stream_t * my_obj,
87 mm_stream_evt_type_t evt,
88 void * in_val,
89 void * out_val);
90 int32_t mm_stream_fsm_acquired(mm_stream_t * my_obj,
91 mm_stream_evt_type_t evt,
92 void * in_val,
93 void * out_val);
94 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
95 mm_stream_evt_type_t evt,
96 void * in_val,
97 void * out_val);
98 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
99 mm_stream_evt_type_t evt,
100 void * in_val,
101 void * out_val);
102 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
103 mm_stream_evt_type_t evt,
104 void * in_val,
105 void * out_val);
106 int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,
107 mm_stream_evt_type_t evt,
108 void * in_val,
109 void * out_val);
110 int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,
111 mm_stream_evt_type_t evt,
112 void * in_val,
113 void * out_val);
114
115 extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
116 cam_ctrl_type type,
117 uint32_t length,
118 void *value);
119
get_stream_inst_handle(mm_stream_t * my_obj)120 static int get_stream_inst_handle(mm_stream_t *my_obj)
121 {
122 int rc = 0;
123 uint32_t inst_handle;
124 struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
125
126 v4l2_ioctl.id = MSM_V4L2_PID_INST_HANDLE;
127 v4l2_ioctl.ioctl_ptr = &inst_handle;
128 v4l2_ioctl.len = sizeof(inst_handle);
129 rc = ioctl(my_obj->fd, MSM_CAM_V4L2_IOCTL_PRIVATE_G_CTRL, &v4l2_ioctl);
130 if (rc) {
131 CDBG_ERROR("%s Error getting mctl pp inst handle", __func__);
132 return rc;
133 }
134
135 my_obj->inst_hdl = inst_handle;
136 CDBG("%s: X, inst_handle = 0x%x, my_handle = 0x%x, "
137 "image_mode = %d, fd = %d, state = %d, rc = %d",
138 __func__, my_obj->inst_hdl, my_obj->my_hdl,
139 my_obj->ext_image_mode, my_obj->fd, my_obj->state, rc);
140 return rc;
141 }
142
mm_stream_handle_rcvd_buf(mm_stream_t * my_obj,mm_camera_buf_info_t * buf_info)143 void mm_stream_handle_rcvd_buf(mm_stream_t *my_obj,
144 mm_camera_buf_info_t *buf_info)
145 {
146 int32_t i;
147 uint8_t has_cb = 0;
148 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
149 "image_mode = %d, fd = %d, state = %d",
150 __func__, my_obj->inst_hdl, my_obj->my_hdl,
151 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
152
153 /* enqueue to super buf thread */
154 if (my_obj->is_bundled) {
155 mm_camera_cmdcb_t* node = NULL;
156
157 /* send sem_post to wake up channel cmd thread to enqueue to super buffer */
158 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
159 if (NULL != node) {
160 memset(node, 0, sizeof(mm_camera_cmdcb_t));
161 node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
162 memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t));
163
164 /* enqueue to cmd thread */
165 mm_camera_queue_enq(&(my_obj->ch_obj->cmd_thread.cmd_queue), node);
166
167 /* wake up cmd thread */
168 sem_post(&(my_obj->ch_obj->cmd_thread.cmd_sem));
169 } else {
170 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
171 }
172 }
173
174 /* check if has CB */
175 for (i=0 ; i< MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
176 if(NULL != my_obj->buf_cb[i].cb) {
177 has_cb = 1;
178 }
179 }
180 if(has_cb) {
181 mm_camera_cmdcb_t* node = NULL;
182
183 /* send sem_post to wake up cmd thread to dispatch dataCB */
184 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
185 if (NULL != node) {
186 memset(node, 0, sizeof(mm_camera_cmdcb_t));
187 node->cmd_type = MM_CAMERA_CMD_TYPE_DATA_CB;
188 memcpy(&node->u.buf, buf_info, sizeof(mm_camera_buf_info_t));
189
190 /* enqueue to cmd thread */
191 mm_camera_queue_enq(&(my_obj->cmd_thread.cmd_queue), node);
192
193 /* wake up cmd thread */
194 sem_post(&(my_obj->cmd_thread.cmd_sem));
195 } else {
196 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
197 }
198 }
199 }
200
mm_stream_data_notify(void * user_data)201 static void mm_stream_data_notify(void* user_data)
202 {
203 mm_stream_t *my_obj = (mm_stream_t*)user_data;
204 int32_t idx = -1, i, rc;
205 uint8_t has_cb = 0;
206 mm_camera_buf_info_t buf_info;
207
208 if (NULL == my_obj) {
209 return;
210 }
211
212 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
213 "image_mode = %d, fd = %d, state = %d",
214 __func__, my_obj->inst_hdl, my_obj->my_hdl,
215 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
216 if (MM_STREAM_STATE_ACTIVE_STREAM_ON != my_obj->state) {
217 /* this Cb will only received in active_stream_on state
218 * if not so, return here */
219 CDBG_ERROR("%s: ERROR!! Wrong state (%d) to receive data notify!",
220 __func__, my_obj->state);
221 return;
222 }
223
224 memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
225
226 pthread_mutex_lock(&my_obj->buf_lock);
227 rc = mm_stream_read_msm_frame(my_obj, &buf_info);
228 if (rc != 0) {
229 pthread_mutex_unlock(&my_obj->buf_lock);
230 return;
231 }
232 idx = buf_info.buf->buf_idx;
233 /* update buffer location */
234 my_obj->buf_status[idx].in_kernel = 0;
235
236 /* update buf ref count */
237 if (my_obj->is_bundled) {
238 /* need to add into super buf since bundled, add ref count */
239 my_obj->buf_status[idx].buf_refcnt++;
240 }
241
242 for (i=0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
243 if(NULL != my_obj->buf_cb[i].cb) {
244 /* for every CB, add ref count */
245 my_obj->buf_status[idx].buf_refcnt++;
246 has_cb = 1;
247 }
248 }
249 pthread_mutex_unlock(&my_obj->buf_lock);
250
251 mm_stream_handle_rcvd_buf(my_obj, &buf_info);
252 }
253
254 /* special function for dataCB registered at other stream */
mm_stream_buf_notify(mm_camera_super_buf_t * super_buf,void * user_data)255 static void mm_stream_buf_notify(mm_camera_super_buf_t *super_buf,
256 void *user_data)
257 {
258 mm_stream_t * my_obj = (mm_stream_t*)user_data;
259 mm_camera_buf_info_t buf_info;
260 int8_t i;
261 mm_camera_buf_def_t *buf = super_buf->bufs[0];
262
263 CDBG("%s : E",__func__);
264 if (my_obj == NULL) {
265 return;
266 }
267 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
268 "image_mode = %d, fd = %d, state = %d",
269 __func__, my_obj->inst_hdl, my_obj->my_hdl,
270 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
271
272 if (MM_STREAM_STATE_ACTIVE_STREAM_OFF != my_obj->state) {
273 /* this CB will only received in active_stream_off state
274 * if not so, return here */
275 return;
276 }
277
278 /* 1) copy buf into local buf */
279 if (my_obj->buf_num <= 0) {
280 CDBG_ERROR("%s: Local buf is not allocated yet", __func__);
281 return;
282 }
283
284 my_obj->buf[my_obj->local_buf_idx].buf_idx = 0;
285 my_obj->buf[my_obj->local_buf_idx].stream_id = my_obj->my_hdl;
286 my_obj->buf[my_obj->local_buf_idx].frame_idx = buf->frame_idx;
287
288 memcpy(&my_obj->buf[my_obj->local_buf_idx].ts, &buf->ts, sizeof(buf->ts));
289
290 memcpy(my_obj->buf[my_obj->local_buf_idx].buffer, buf->buffer, buf->frame_len);
291
292 /* set flag to indicate buf be to sent out is from local */
293 my_obj->is_local_buf = 1;
294
295 /* 2) buf_done the buf from other stream */
296 mm_channel_qbuf(my_obj->ch_obj, buf);
297
298 /* 3) handle received buf */
299 memset(&buf_info, 0, sizeof(mm_camera_buf_info_t));
300 buf_info.frame_idx =my_obj->buf[my_obj->local_buf_idx].frame_idx;
301 buf_info.buf = &my_obj->buf[my_obj->local_buf_idx];
302 buf_info.stream_id = my_obj->my_hdl;
303
304 my_obj->local_buf_idx++;
305 if (my_obj->local_buf_idx >= my_obj->buf_num) {
306 my_obj->local_buf_idx = 0;
307 }
308 mm_stream_handle_rcvd_buf(my_obj, &buf_info);
309 }
310
mm_stream_dispatch_app_data(mm_camera_cmdcb_t * cmd_cb,void * user_data)311 static void mm_stream_dispatch_app_data(mm_camera_cmdcb_t *cmd_cb,
312 void* user_data)
313 {
314 int i;
315 mm_stream_t * my_obj = (mm_stream_t *)user_data;
316 mm_camera_buf_info_t* buf_info = NULL;
317 mm_camera_super_buf_t super_buf;
318
319 if (NULL == my_obj) {
320 return;
321 }
322 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
323 "image_mode = %d, fd = %d, state = %d",
324 __func__, my_obj->inst_hdl, my_obj->my_hdl,
325 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
326
327 if (MM_CAMERA_CMD_TYPE_DATA_CB != cmd_cb->cmd_type) {
328 CDBG_ERROR("%s: Wrong cmd_type (%d) for dataCB",
329 __func__, cmd_cb->cmd_type);
330 return;
331 }
332
333 buf_info = &cmd_cb->u.buf;
334 memset(&super_buf, 0, sizeof(mm_camera_super_buf_t));
335 super_buf.num_bufs = 1;
336 super_buf.bufs[0] = buf_info->buf;
337 super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
338 super_buf.ch_id = my_obj->ch_obj->my_hdl;
339
340
341 pthread_mutex_lock(&my_obj->cb_lock);
342 for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
343 if(NULL != my_obj->buf_cb[i].cb) {
344 if (my_obj->buf_cb[i].cb_count != 0) {
345 /* if <0, means infinite CB
346 * if >0, means CB for certain times
347 * both case we need to call CB */
348 my_obj->buf_cb[i].cb(&super_buf,
349 my_obj->buf_cb[i].user_data);
350 }
351
352 /* if >0, reduce count by 1 every time we called CB until reaches 0
353 * when count reach 0, reset the buf_cb to have no CB */
354 if (my_obj->buf_cb[i].cb_count > 0) {
355 my_obj->buf_cb[i].cb_count--;
356 if (0 == my_obj->buf_cb[i].cb_count) {
357 my_obj->buf_cb[i].cb = NULL;
358 my_obj->buf_cb[i].user_data = NULL;
359 }
360 }
361 }
362 }
363 pthread_mutex_unlock(&my_obj->cb_lock);
364 }
365
366 /* state machine entry */
mm_stream_fsm_fn(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)367 int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
368 mm_stream_evt_type_t evt,
369 void * in_val,
370 void * out_val)
371 {
372 int32_t rc = -1;
373
374 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
375 "image_mode = %d, fd = %d, state = %d, event = %d",
376 __func__, my_obj->inst_hdl, my_obj->my_hdl,
377 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
378 switch (my_obj->state) {
379 case MM_STREAM_STATE_NOTUSED:
380 CDBG("%s: Not handling evt in unused state", __func__);
381 break;
382 case MM_STREAM_STATE_INITED:
383 rc = mm_stream_fsm_inited(my_obj, evt, in_val, out_val);
384 break;
385 case MM_STREAM_STATE_ACQUIRED:
386 rc = mm_stream_fsm_acquired(my_obj, evt, in_val, out_val);
387 break;
388 case MM_STREAM_STATE_CFG:
389 rc = mm_stream_fsm_cfg(my_obj, evt, in_val, out_val);
390 break;
391 case MM_STREAM_STATE_BUFFED:
392 rc = mm_stream_fsm_buffed(my_obj, evt, in_val, out_val);
393 break;
394 case MM_STREAM_STATE_REG:
395 rc = mm_stream_fsm_reg(my_obj, evt, in_val, out_val);
396 break;
397 case MM_STREAM_STATE_ACTIVE_STREAM_ON:
398 rc = mm_stream_fsm_active_stream_on(my_obj, evt, in_val, out_val);
399 break;
400 case MM_STREAM_STATE_ACTIVE_STREAM_OFF:
401 rc = mm_stream_fsm_active_stream_off(my_obj, evt, in_val, out_val);
402 break;
403 default:
404 CDBG("%s: Not a valid state (%d)", __func__, my_obj->state);
405 break;
406 }
407 CDBG("%s : X rc =%d",__func__,rc);
408 return rc;
409 }
410
mm_stream_fsm_inited(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)411 int32_t mm_stream_fsm_inited(mm_stream_t *my_obj,
412 mm_stream_evt_type_t evt,
413 void * in_val,
414 void * out_val)
415 {
416 int32_t rc = 0;
417 char dev_name[MM_CAMERA_DEV_NAME_LEN];
418
419 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
420 "image_mode = %d, fd = %d, state = %d, event = %d",
421 __func__, my_obj->inst_hdl, my_obj->my_hdl,
422 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
423 switch(evt) {
424 case MM_STREAM_EVT_ACQUIRE:
425 if ((NULL == my_obj->ch_obj) || (NULL == my_obj->ch_obj->cam_obj)) {
426 CDBG_ERROR("%s: NULL channel or camera obj\n", __func__);
427 rc = -1;
428 break;
429 }
430
431 snprintf(dev_name, sizeof(dev_name), "/dev/%s",
432 mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl));
433
434 my_obj->fd = open(dev_name, O_RDWR | O_NONBLOCK);
435 if (my_obj->fd <= 0) {
436 CDBG_ERROR("%s: open dev returned %d\n", __func__, my_obj->fd);
437 rc = -1;
438 break;
439 }
440 CDBG("%s: open dev fd = %d, ext_image_mode = %d, sensor_idx = %d\n",
441 __func__, my_obj->fd, my_obj->ext_image_mode, my_obj->sensor_idx);
442 rc = mm_stream_set_ext_mode(my_obj);
443 if (0 == rc) {
444 my_obj->state = MM_STREAM_STATE_ACQUIRED;
445 } else {
446 /* failed setting ext_mode
447 * close fd */
448 if(my_obj->fd > 0) {
449 close(my_obj->fd);
450 my_obj->fd = -1;
451 }
452 break;
453 }
454 rc = get_stream_inst_handle(my_obj);
455 if(rc) {
456 if(my_obj->fd > 0) {
457 close(my_obj->fd);
458 my_obj->fd = -1;
459 }
460 }
461 break;
462 default:
463 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
464 __func__,evt,my_obj->state);
465 break;
466 }
467 return rc;
468 }
469
mm_stream_fsm_acquired(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)470 int32_t mm_stream_fsm_acquired(mm_stream_t *my_obj,
471 mm_stream_evt_type_t evt,
472 void * in_val,
473 void * out_val)
474 {
475 int32_t rc = 0;
476
477 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
478 "image_mode = %d, fd = %d, state = %d, event = %d",
479 __func__, my_obj->inst_hdl, my_obj->my_hdl,
480 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
481 switch(evt) {
482 case MM_STREAM_EVT_SET_FMT:
483 {
484 mm_camera_stream_config_t *config =
485 (mm_camera_stream_config_t *)in_val;
486
487 rc = mm_stream_config(my_obj, config);
488
489 /* change state to configed */
490 my_obj->state = MM_STREAM_STATE_CFG;
491
492 break;
493 }
494 case MM_STREAM_EVT_RELEASE:
495 rc = mm_stream_release(my_obj);
496 /* change state to not used */
497 my_obj->state = MM_STREAM_STATE_NOTUSED;
498 break;
499 case MM_STREAM_EVT_SET_PARM:
500 rc = mm_stream_set_parm_acquire(my_obj, in_val);
501 break;
502 case MM_STREAM_EVT_GET_PARM:
503 rc = mm_stream_get_parm_acquire(my_obj,out_val);
504 break;
505 default:
506 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
507 __func__, evt, my_obj->state);
508 }
509 CDBG("%s :X rc = %d",__func__,rc);
510 return rc;
511 }
512
mm_stream_fsm_cfg(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)513 int32_t mm_stream_fsm_cfg(mm_stream_t * my_obj,
514 mm_stream_evt_type_t evt,
515 void * in_val,
516 void * out_val)
517 {
518 int32_t rc = 0;
519 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
520 "image_mode = %d, fd = %d, state = %d, event = %d",
521 __func__, my_obj->inst_hdl, my_obj->my_hdl,
522 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
523 switch(evt) {
524 case MM_STREAM_EVT_SET_FMT:
525 {
526 mm_camera_stream_config_t *config =
527 (mm_camera_stream_config_t *)in_val;
528
529 rc = mm_stream_config(my_obj, config);
530
531 /* change state to configed */
532 my_obj->state = MM_STREAM_STATE_CFG;
533
534 break;
535 }
536 case MM_STREAM_EVT_RELEASE:
537 rc = mm_stream_release(my_obj);
538 my_obj->state = MM_STREAM_STATE_NOTUSED;
539 break;
540 case MM_STREAM_EVT_SET_PARM:
541 rc = mm_stream_set_parm_config(my_obj, in_val);
542 break;
543 case MM_STREAM_EVT_GET_PARM:
544 rc = mm_stream_get_parm_config(my_obj, out_val);
545 break;
546 case MM_STREAM_EVT_GET_BUF:
547 rc = mm_stream_init_bufs(my_obj);
548 /* change state to buff allocated */
549 if(0 == rc) {
550 my_obj->state = MM_STREAM_STATE_BUFFED;
551 }
552 break;
553 default:
554 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
555 __func__, evt, my_obj->state);
556 }
557 CDBG("%s :X rc = %d",__func__,rc);
558 return rc;
559 }
560
mm_stream_fsm_buffed(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)561 int32_t mm_stream_fsm_buffed(mm_stream_t * my_obj,
562 mm_stream_evt_type_t evt,
563 void * in_val,
564 void * out_val)
565 {
566 int32_t rc = 0;
567 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
568 "image_mode = %d, fd = %d, state = %d, event = %d",
569 __func__, my_obj->inst_hdl, my_obj->my_hdl,
570 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
571 switch(evt) {
572 case MM_STREAM_EVT_PUT_BUF:
573 rc = mm_stream_deinit_bufs(my_obj);
574 /* change state to configed */
575 if(0 == rc) {
576 my_obj->state = MM_STREAM_STATE_CFG;
577 }
578 break;
579 case MM_STREAM_EVT_REG_BUF:
580 rc = mm_stream_reg_buf(my_obj);
581 /* change state to regged */
582 if(0 == rc) {
583 my_obj->state = MM_STREAM_STATE_REG;
584 }
585 break;
586 case MM_STREAM_EVT_SET_PARM:
587 rc = mm_stream_set_parm_config(my_obj, in_val);
588 break;
589 case MM_STREAM_EVT_GET_PARM:
590 rc = mm_stream_get_parm_config(my_obj, out_val);
591 break;
592 default:
593 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
594 __func__, evt, my_obj->state);
595 }
596 CDBG("%s :X rc = %d",__func__,rc);
597 return rc;
598 }
599
mm_stream_fsm_reg(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)600 int32_t mm_stream_fsm_reg(mm_stream_t * my_obj,
601 mm_stream_evt_type_t evt,
602 void * in_val,
603 void * out_val)
604 {
605 int32_t rc = 0;
606 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
607 "image_mode = %d, fd = %d, state = %d, event = %d",
608 __func__, my_obj->inst_hdl, my_obj->my_hdl,
609 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
610
611 switch(evt) {
612 case MM_STREAM_EVT_UNREG_BUF:
613 rc = mm_stream_unreg_buf(my_obj);
614
615 /* change state to buffed */
616 my_obj->state = MM_STREAM_STATE_BUFFED;
617 break;
618 case MM_STREAM_EVT_START:
619 {
620 /* launch cmd thread if CB is not null */
621 if (NULL != my_obj->buf_cb) {
622 mm_camera_cmd_thread_launch(&my_obj->cmd_thread,
623 mm_stream_dispatch_app_data,
624 (void *)my_obj);
625
626 }
627
628 if(my_obj->need_stream_on) {
629 rc = mm_stream_streamon(my_obj);
630 if (0 != rc) {
631 /* failed stream on, need to release cmd thread if it's launched */
632 if (NULL != my_obj->buf_cb) {
633 mm_camera_cmd_thread_release(&my_obj->cmd_thread);
634
635 }
636 break;
637 }
638 my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_ON;
639 } else {
640 /* register CB at video fd */
641 CDBG("%s : Video Size snapshot Enabled",__func__);
642 mm_stream_data_cb_t cb;
643 memset(&cb, 0, sizeof(mm_stream_data_cb_t));
644 cb.cb_count = my_obj->num_stream_cb_times; /* reigstration cb times */
645 if (cb.cb_count == 0) {
646 cb.cb_count = 1;
647 }
648 cb.user_data = (void*)my_obj;
649 cb.cb = mm_stream_buf_notify;
650 rc = mm_channel_reg_stream_cb(my_obj->ch_obj, &cb,
651 MSM_V4L2_EXT_CAPTURE_MODE_VIDEO,
652 my_obj->sensor_idx);
653 my_obj->state = MM_STREAM_STATE_ACTIVE_STREAM_OFF;
654 }
655 }
656 break;
657 case MM_STREAM_EVT_SET_PARM:
658 rc = mm_stream_set_parm_config(my_obj, in_val);
659 break;
660 case MM_STREAM_EVT_GET_PARM:
661 rc = mm_stream_get_parm_config(my_obj, out_val);
662 break;
663 default:
664 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
665 __func__, evt, my_obj->state);
666 }
667 CDBG("%s :X rc = %d",__func__,rc);
668 return rc;
669 }
670
mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)671 int32_t mm_stream_fsm_active_stream_on(mm_stream_t * my_obj,
672 mm_stream_evt_type_t evt,
673 void * in_val,
674 void * out_val)
675 {
676 int32_t rc = 0;
677 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
678 "image_mode = %d, fd = %d, state = %d, event = %d",
679 __func__, my_obj->inst_hdl, my_obj->my_hdl,
680 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
681 switch(evt) {
682 case MM_STREAM_EVT_QBUF:
683 rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
684 break;
685 case MM_STREAM_EVT_STOP:
686 {
687 rc = mm_stream_streamoff(my_obj);
688 if (NULL != my_obj->buf_cb) {
689 mm_camera_cmd_thread_release(&my_obj->cmd_thread);
690
691 }
692 my_obj->state = MM_STREAM_STATE_REG;
693 }
694 break;
695 case MM_STREAM_EVT_SET_PARM:
696 rc = mm_stream_set_parm_start(my_obj, in_val);
697 break;
698 case MM_STREAM_EVT_GET_PARM:
699 rc = mm_stream_get_parm_start(my_obj, out_val);
700 break;
701 default:
702 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
703 __func__, evt, my_obj->state);
704 }
705 CDBG("%s :X rc = %d",__func__,rc);
706 return rc;
707 }
708
mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,mm_stream_evt_type_t evt,void * in_val,void * out_val)709 int32_t mm_stream_fsm_active_stream_off(mm_stream_t * my_obj,
710 mm_stream_evt_type_t evt,
711 void * in_val,
712 void * out_val)
713 {
714 int32_t rc = 0;
715 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
716 "image_mode = %d, fd = %d, state = %d, event = %d",
717 __func__, my_obj->inst_hdl, my_obj->my_hdl,
718 my_obj->ext_image_mode, my_obj->fd, my_obj->state, evt);
719 switch(evt) {
720 case MM_STREAM_EVT_QBUF:
721 rc = mm_stream_buf_done(my_obj, (mm_camera_buf_def_t *)in_val);
722 break;
723 case MM_STREAM_EVT_STOP:
724 {
725 if (NULL != my_obj->buf_cb) {
726 rc = mm_camera_cmd_thread_release(&my_obj->cmd_thread);
727
728 }
729 my_obj->state = MM_STREAM_STATE_REG;
730 }
731 break;
732 case MM_STREAM_EVT_SET_PARM:
733 rc = mm_stream_set_parm_config(my_obj, in_val);
734 break;
735 case MM_STREAM_EVT_GET_PARM:
736 rc = mm_stream_get_parm_config(my_obj, out_val);
737 break;
738 default:
739 CDBG_ERROR("%s: Invalid evt=%d, stream_state=%d",
740 __func__, evt, my_obj->state);
741 }
742 CDBG("%s :X rc = %d",__func__,rc);
743 return rc;
744 }
745
mm_stream_config(mm_stream_t * my_obj,mm_camera_stream_config_t * config)746 int32_t mm_stream_config(mm_stream_t *my_obj,
747 mm_camera_stream_config_t *config)
748 {
749 int32_t rc = 0;
750 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
751 "image_mode = %d, fd = %d, state = %d",
752 __func__, my_obj->inst_hdl, my_obj->my_hdl,
753 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
754 memcpy(&my_obj->fmt, &config->fmt, sizeof(mm_camera_image_fmt_t));
755 my_obj->hal_requested_num_bufs = config->num_of_bufs;
756 my_obj->need_stream_on = config->need_stream_on;
757 my_obj->num_stream_cb_times = config->num_stream_cb_times;
758
759 rc = mm_stream_get_offset(my_obj);
760 if(rc != 0) {
761 CDBG_ERROR("%s: Error in offset query",__func__);
762 return rc;
763 }
764 /* write back width and height to config in case mctl has modified the value */
765 config->fmt.width = my_obj->fmt.width;
766 config->fmt.height = my_obj->fmt.height;
767 if(my_obj->need_stream_on) {
768 /* only send fmt to backend if we need streamon */
769 rc = mm_stream_set_fmt(my_obj);
770 }
771 return rc;
772 }
773
mm_stream_release(mm_stream_t * my_obj)774 int32_t mm_stream_release(mm_stream_t *my_obj)
775 {
776 int32_t rc;
777 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
778 "image_mode = %d, fd = %d, state = %d",
779 __func__, my_obj->inst_hdl, my_obj->my_hdl,
780 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
781
782 /* close fd */
783 if(my_obj->fd > 0)
784 {
785 close(my_obj->fd);
786 }
787
788 /* destroy mutex */
789 pthread_mutex_destroy(&my_obj->buf_lock);
790 pthread_mutex_destroy(&my_obj->cb_lock);
791
792 /* reset stream obj */
793 memset(my_obj, 0, sizeof(mm_stream_t));
794 my_obj->fd = -1;
795
796 return 0;
797 }
798
mm_stream_streamon(mm_stream_t * my_obj)799 int32_t mm_stream_streamon(mm_stream_t *my_obj)
800 {
801 int32_t rc;
802 enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
803
804 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
805 "image_mode = %d, fd = %d, state = %d",
806 __func__, my_obj->inst_hdl, my_obj->my_hdl,
807 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
808 /* Add fd to data poll thread */
809 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
810 my_obj->my_hdl,
811 my_obj->fd,
812 mm_stream_data_notify,
813 (void*)my_obj);
814 if (rc < 0) {
815 return rc;
816 }
817 rc = ioctl(my_obj->fd, VIDIOC_STREAMON, &buf_type);
818 if (rc < 0) {
819 CDBG_ERROR("%s: ioctl VIDIOC_STREAMON failed: rc=%d\n",
820 __func__, rc);
821 /* remove fd from data poll thread in case of failure */
822 mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl);
823 }
824 CDBG("%s :X rc = %d",__func__,rc);
825 return rc;
826 }
827
mm_stream_streamoff(mm_stream_t * my_obj)828 int32_t mm_stream_streamoff(mm_stream_t *my_obj)
829 {
830 int32_t rc;
831 enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
832 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
833 "image_mode = %d, fd = %d, state = %d",
834 __func__, my_obj->inst_hdl, my_obj->my_hdl,
835 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
836
837 /* step1: remove fd from data poll thread */
838 mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0], my_obj->my_hdl);
839
840 /* step2: stream off */
841 rc = ioctl(my_obj->fd, VIDIOC_STREAMOFF, &buf_type);
842 if (rc < 0) {
843 CDBG_ERROR("%s: STREAMOFF failed: %s\n",
844 __func__, strerror(errno));
845 }
846 CDBG("%s :X rc = %d",__func__,rc);
847 return rc;
848 }
849
mm_stream_util_get_v4l2_fmt(cam_format_t fmt,uint8_t * num_planes)850 static uint32_t mm_stream_util_get_v4l2_fmt(cam_format_t fmt,
851 uint8_t *num_planes)
852 {
853 uint32_t val;
854 switch(fmt) {
855 case CAMERA_YUV_420_NV12:
856 val = V4L2_PIX_FMT_NV12;
857 *num_planes = 2;
858 break;
859 case CAMERA_YUV_420_NV21:
860 val = V4L2_PIX_FMT_NV21;
861 *num_planes = 2;
862 break;
863 case CAMERA_BAYER_SBGGR10:
864 case CAMERA_RDI:
865 val= V4L2_PIX_FMT_SBGGR10;
866 *num_planes = 1;
867 break;
868 case CAMERA_YUV_422_NV61:
869 val= V4L2_PIX_FMT_NV61;
870 *num_planes = 2;
871 break;
872 case CAMERA_SAEC:
873 val = V4L2_PIX_FMT_STATS_AE;
874 *num_planes = 1;
875 break;
876 case CAMERA_SAWB:
877 val = V4L2_PIX_FMT_STATS_AWB;
878 *num_planes = 1;
879 break;
880 case CAMERA_SAFC:
881 val = V4L2_PIX_FMT_STATS_AF;
882 *num_planes = 1;
883 break;
884 case CAMERA_SHST:
885 val = V4L2_PIX_FMT_STATS_IHST;
886 *num_planes = 1;
887 break;
888 case CAMERA_YUV_422_YUYV:
889 val= V4L2_PIX_FMT_YUYV;
890 *num_planes = 1;
891 break;
892 case CAMERA_YUV_420_YV12:
893 val= V4L2_PIX_FMT_NV12;
894 *num_planes = 3;
895 break;
896 default:
897 val = 0;
898 *num_planes = 0;
899 CDBG_ERROR("%s: Unknown fmt=%d", __func__, fmt);
900 break;
901 }
902 CDBG("%s: fmt=%d, val =%d, num_planes=%d", __func__, fmt, val , *num_planes);
903 return val;
904 }
905
mm_stream_read_msm_frame(mm_stream_t * my_obj,mm_camera_buf_info_t * buf_info)906 int32_t mm_stream_read_msm_frame(mm_stream_t * my_obj,
907 mm_camera_buf_info_t* buf_info)
908 {
909 int32_t idx = -1, rc = 0;
910 struct v4l2_buffer vb;
911 struct v4l2_plane planes[VIDEO_MAX_PLANES];
912 uint32_t i = 0;
913 uint8_t num_planes = 0;
914 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
915 "image_mode = %d, fd = %d, state = %d",
916 __func__, my_obj->inst_hdl, my_obj->my_hdl,
917 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
918
919 mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt,
920 &num_planes);
921
922 memset(&vb, 0, sizeof(vb));
923 vb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
924 vb.memory = V4L2_MEMORY_USERPTR;
925 vb.m.planes = &planes[0];
926 vb.length = num_planes;
927
928 rc = ioctl(my_obj->fd, VIDIOC_DQBUF, &vb);
929 if (rc < 0) {
930 CDBG_ERROR("%s: VIDIOC_DQBUF ioctl call failed (rc=%d)\n",
931 __func__, rc);
932 } else {
933 int8_t idx = vb.index;
934 buf_info->buf = &my_obj->buf[idx];
935 buf_info->frame_idx = vb.sequence;
936 buf_info->stream_id = my_obj->my_hdl;
937
938 buf_info->buf->stream_id = my_obj->my_hdl;
939 buf_info->buf->buf_idx = idx;
940 buf_info->buf->frame_idx = vb.sequence;
941 buf_info->buf->ts.tv_sec = vb.timestamp.tv_sec;
942 buf_info->buf->ts.tv_nsec = vb.timestamp.tv_usec * 1000;
943
944 for(i = 0; i < vb.length; i++) {
945 CDBG("%s plane %d addr offset: %d data offset:%d\n",
946 __func__, i, vb.m.planes[i].reserved[0],
947 vb.m.planes[i].data_offset);
948 buf_info->buf->planes[i].reserved[0] =
949 vb.m.planes[i].reserved[0];
950 buf_info->buf->planes[i].data_offset =
951 vb.m.planes[i].data_offset;
952 }
953
954
955 }
956 CDBG("%s :X rc = %d",__func__,rc);
957 return rc;
958 }
959
mm_stream_get_crop(mm_stream_t * my_obj,mm_camera_rect_t * crop)960 int32_t mm_stream_get_crop(mm_stream_t *my_obj,
961 mm_camera_rect_t *crop)
962 {
963 struct v4l2_crop crop_info;
964 int32_t rc = 0;
965 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
966 "image_mode = %d, fd = %d, state = %d",
967 __func__, my_obj->inst_hdl, my_obj->my_hdl,
968 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
969
970 memset(&crop_info, 0, sizeof(crop_info));
971 crop_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
972 rc = ioctl(my_obj->fd, VIDIOC_G_CROP, &crop_info);
973 if (0 == rc) {
974 crop->left = crop_info.c.left;
975 crop->top = crop_info.c.top;
976 crop->width = crop_info.c.width;
977 crop->height = crop_info.c.height;
978 }
979 CDBG("%s :X rc = %d",__func__,rc);
980 return rc;
981 }
982
mm_stream_set_parm_acquire(mm_stream_t * my_obj,void * in_value)983 int32_t mm_stream_set_parm_acquire(mm_stream_t *my_obj,
984 void *in_value)
985 {
986 int32_t rc = 0;
987 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
988 mm_camera_stream_parm_t parm_type = payload->parm_type;
989 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
990 "image_mode = %d, fd = %d, state = %d, parm_type = %d",
991 __func__, my_obj->inst_hdl, my_obj->my_hdl,
992 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
993
994 switch(parm_type) {
995 case MM_CAMERA_STREAM_CID:{
996 stream_cid_t *value = (stream_cid_t *)in_value;
997 mm_stream_set_cid(my_obj,value);
998 break;
999 }
1000 default:
1001 CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
1002 break;
1003 }
1004 return rc;
1005 }
mm_stream_get_parm_acquire(mm_stream_t * my_obj,void * out_value)1006 int32_t mm_stream_get_parm_acquire(mm_stream_t *my_obj,
1007 void *out_value)
1008 {
1009 int32_t rc = 0;
1010 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
1011 mm_camera_stream_parm_t parm_type = payload->parm_type;
1012 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1013 "image_mode = %d, fd = %d, state = %d, parm_type = %d",
1014 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1015 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
1016
1017 switch(parm_type) {
1018 case MM_CAMERA_STREAM_CID:{
1019 stream_cid_t *value = (stream_cid_t *)out_value;
1020 rc = mm_stream_get_cid(my_obj,value);
1021 break;
1022 }
1023 case MM_CAMERA_STREAM_CROP:{
1024 mm_camera_rect_t *crop = (mm_camera_rect_t *)out_value;
1025 rc = mm_stream_get_crop(my_obj, crop);
1026 break;
1027 }
1028 default:
1029 CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)parm_type);
1030 break;
1031 }
1032 return rc;
1033 }
1034
mm_stream_set_parm_config(mm_stream_t * my_obj,void * in_value)1035 int32_t mm_stream_set_parm_config(mm_stream_t *my_obj,
1036 void *in_value)
1037 {
1038 int32_t rc = 0;
1039 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
1040 mm_camera_stream_parm_t parm_type = payload->parm_type;
1041 void *value = payload->value;
1042
1043 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1044 "image_mode = %d, fd = %d, state = %d, parm_type = %d",
1045 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1046 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
1047 switch(parm_type) {
1048 default:
1049 CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
1050 break;
1051 }
1052 return rc;
1053 }
mm_stream_get_parm_config(mm_stream_t * my_obj,void * out_value)1054 int32_t mm_stream_get_parm_config(mm_stream_t *my_obj,
1055 void *out_value)
1056 {
1057 int32_t rc = 0;
1058 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
1059
1060 if(payload == NULL) {
1061 CDBG_ERROR("%s : Invalid Argument",__func__);
1062 return -1;
1063 }
1064 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1065 "image_mode = %d, fd = %d, state = %d, parm_type = %d",
1066 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1067 my_obj->ext_image_mode, my_obj->fd, my_obj->state, (int)payload->parm_type);
1068 switch(payload->parm_type) {
1069 case MM_CAMERA_STREAM_OFFSET:
1070 memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset));
1071 break;
1072 case MM_CAMERA_STREAM_CROP:{
1073 mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value;
1074 rc = mm_stream_get_crop(my_obj, crop);
1075 break;
1076 }
1077 default:
1078 CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type);
1079 break;
1080 }
1081 return rc;
1082 }
1083
mm_stream_set_parm_start(mm_stream_t * my_obj,void * in_value)1084 int32_t mm_stream_set_parm_start(mm_stream_t *my_obj,
1085 void *in_value)
1086 {
1087 int32_t rc = 0;
1088 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)in_value;
1089 mm_camera_stream_parm_t parm_type = payload->parm_type;
1090 void *value = payload->value;
1091
1092 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1093 "image_mode = %d, fd = %d, state = %d, parm_type = %d",
1094 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1095 my_obj->ext_image_mode, my_obj->fd, my_obj->state, parm_type);
1096 switch(parm_type) {
1097 default:
1098 CDBG_ERROR("%s : Parm -%d set is not supported here",__func__,(int)parm_type);
1099 break;
1100 }
1101 return rc;
1102 }
mm_stream_get_parm_start(mm_stream_t * my_obj,void * out_value)1103 int32_t mm_stream_get_parm_start(mm_stream_t *my_obj,
1104 void *out_value)
1105 {
1106 int32_t rc = 0;
1107 mm_evt_paylod_stream_parm_t *payload = (mm_evt_paylod_stream_parm_t *)out_value;
1108
1109 if(payload == NULL) {
1110 CDBG_ERROR("%s : Invalid Argument",__func__);
1111 return -1;
1112 }
1113 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1114 "image_mode = %d, fd = %d, state = %d, parm_type = %d",
1115 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1116 my_obj->ext_image_mode, my_obj->fd, my_obj->state, (int)payload->parm_type);
1117 switch(payload->parm_type) {
1118 case MM_CAMERA_STREAM_OFFSET:
1119 memcpy(payload->value,(void *)&my_obj->frame_offset,sizeof(mm_camera_frame_len_offset));
1120 break;
1121 case MM_CAMERA_STREAM_CROP:{
1122 mm_camera_rect_t *crop = (mm_camera_rect_t *)payload->value;
1123 rc = mm_stream_get_crop(my_obj, crop);
1124 break;
1125 }
1126 default:
1127 CDBG_ERROR("%s : Parm -%d get is not supported here",__func__,(int)payload->parm_type);
1128 break;
1129 }
1130 return rc;
1131 }
mm_stream_set_ext_mode(mm_stream_t * my_obj)1132 int32_t mm_stream_set_ext_mode(mm_stream_t * my_obj)
1133 {
1134 int32_t rc = 0;
1135 struct v4l2_streamparm s_parm;
1136 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1137 "image_mode = %d, fd = %d, state = %d",
1138 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1139 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1140
1141 s_parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1142 s_parm.parm.capture.extendedmode = my_obj->ext_image_mode;
1143
1144 rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
1145 CDBG("%s:stream fd=%d, rc=%d, extended_mode=%d\n",
1146 __func__, my_obj->fd, rc,
1147 s_parm.parm.capture.extendedmode);
1148 return rc;
1149 }
1150
mm_stream_qbuf(mm_stream_t * my_obj,mm_camera_buf_def_t * buf)1151 int32_t mm_stream_qbuf(mm_stream_t *my_obj, mm_camera_buf_def_t *buf)
1152 {
1153 int32_t i, rc = 0;
1154 int *ret;
1155 struct v4l2_buffer buffer;
1156 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1157 "image_mode = %d, fd = %d, state = %d",
1158 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1159 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1160
1161 memset(&buffer, 0, sizeof(buffer));
1162 buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1163 buffer.memory = V4L2_MEMORY_USERPTR;
1164 buffer.index = buf->buf_idx;
1165 buffer.m.planes = &buf->planes[0];
1166 buffer.length = buf->num_planes;
1167
1168 CDBG("%s:stream_hdl=%d,fd=%d,frame idx=%d,num_planes = %d\n", __func__,
1169 buf->stream_id, buf->fd, buffer.index, buffer.length);
1170
1171 rc = ioctl(my_obj->fd, VIDIOC_QBUF, &buffer);
1172 CDBG("%s: qbuf idx:%d, rc:%d", __func__, buffer.index, rc);
1173 return rc;
1174 }
1175
1176 /* This function let kernel know amount of buffers will be registered */
mm_stream_request_buf(mm_stream_t * my_obj)1177 int32_t mm_stream_request_buf(mm_stream_t * my_obj)
1178 {
1179 int32_t rc = 0;
1180 uint8_t i,reg = 0;
1181 struct v4l2_requestbuffers bufreq;
1182 uint8_t buf_num = my_obj->buf_num;
1183 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1184 "image_mode = %d, fd = %d, state = %d",
1185 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1186 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1187
1188 if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
1189 CDBG_ERROR("%s: buf num %d > max limit %d\n",
1190 __func__, buf_num, MM_CAMERA_MAX_NUM_FRAMES);
1191 return -1;
1192 }
1193 pthread_mutex_lock(&my_obj->buf_lock);
1194 for(i = 0; i < buf_num; i++){
1195 if (my_obj->buf_status[i].initial_reg_flag){
1196 reg = 1;
1197 break;
1198 }
1199 }
1200 pthread_mutex_unlock(&my_obj->buf_lock);
1201 if(!reg) {
1202 //No need to register a buffer
1203 CDBG_ERROR("No Need to register this buffer");
1204 return rc;
1205 }
1206 memset(&bufreq, 0, sizeof(bufreq));
1207 bufreq.count = buf_num;
1208 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1209 bufreq.memory = V4L2_MEMORY_USERPTR;
1210 rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
1211 if (rc < 0) {
1212 CDBG_ERROR("%s: fd=%d, ioctl VIDIOC_REQBUFS failed: rc=%d\n",
1213 __func__, my_obj->fd, rc);
1214 }
1215 CDBG("%s :X rc = %d",__func__,rc);
1216 return rc;
1217 }
1218
mm_stream_init_bufs(mm_stream_t * my_obj)1219 int32_t mm_stream_init_bufs(mm_stream_t * my_obj)
1220 {
1221 int32_t i, rc = 0, j;
1222 int image_type;
1223 mm_camear_mem_vtbl_t *mem_vtbl = NULL;
1224 mm_camera_frame_len_offset frame_offset;
1225 uint8_t *reg_flags = NULL;
1226 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1227 "image_mode = %d, fd = %d, state = %d",
1228 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1229 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1230
1231 /* deinit buf if it's not NULL*/
1232 if (NULL != my_obj->buf) {
1233 mm_stream_deinit_bufs(my_obj);
1234 }
1235
1236 my_obj->buf_num = my_obj->hal_requested_num_bufs;
1237 if (mm_camera_util_get_pp_mask(my_obj->ch_obj->cam_obj) > 0) {
1238 /* reserve extra one buf for pp */
1239 my_obj->buf_num++;
1240 }
1241
1242 my_obj->buf =
1243 (mm_camera_buf_def_t*)malloc(sizeof(mm_camera_buf_def_t) * my_obj->buf_num);
1244 my_obj->buf_status =
1245 (mm_stream_buf_status_t*)malloc(sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
1246 reg_flags = (uint8_t *)malloc(sizeof(uint8_t) * my_obj->buf_num);
1247
1248 if (NULL == my_obj->buf ||
1249 NULL == my_obj->buf_status ||
1250 NULL == reg_flags) {
1251 CDBG_ERROR("%s: No memory for buf", __func__);
1252 rc = -1;
1253 goto error_malloc;
1254 }
1255
1256 memset(my_obj->buf, 0, sizeof(mm_camera_buf_def_t) * my_obj->buf_num);
1257 memset(my_obj->buf_status, 0, sizeof(mm_stream_buf_status_t) * my_obj->buf_num);
1258 memset(reg_flags, 0, sizeof(uint8_t) * my_obj->buf_num);
1259
1260 mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl;
1261 rc = mem_vtbl->get_buf(my_obj->ch_obj->cam_obj->my_hdl,
1262 my_obj->ch_obj->my_hdl,
1263 my_obj->my_hdl,
1264 mem_vtbl->user_data,
1265 &my_obj->frame_offset,
1266 my_obj->buf_num,
1267 reg_flags,
1268 my_obj->buf);
1269
1270 if (0 != rc) {
1271 CDBG_ERROR("%s: Error get buf, rc = %d\n", __func__, rc);
1272 goto error_malloc;
1273 }
1274
1275 for (i=0; i < my_obj->buf_num; i++) {
1276 my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
1277 my_obj->buf[i].stream_id = my_obj->my_hdl;
1278 }
1279
1280 free(reg_flags);
1281 reg_flags = NULL;
1282
1283 for (i=0; i < my_obj->buf_num; i++) {
1284 if (my_obj->buf[i].fd > 0) {
1285 if(0 >= (rc = mm_camera_map_buf(my_obj->ch_obj->cam_obj,
1286 my_obj->ext_image_mode,
1287 i,
1288 my_obj->buf[i].fd,
1289 my_obj->buf[i].frame_len)))
1290 {
1291 CDBG_ERROR("%s: Error mapping buf (rc = %d)", __func__, rc);
1292 goto error_map;
1293 }
1294 } else {
1295 CDBG_ERROR("%s: Invalid fd for buf idx (%d)", __func__, i);
1296 }
1297 }
1298
1299 return 0;
1300
1301 error_map:
1302 /* error, unmapping previously mapped bufs */
1303 for (j=0; j<i; j++) {
1304 if (my_obj->buf[j].fd > 0) {
1305 mm_camera_unmap_buf(my_obj->ch_obj->cam_obj,
1306 my_obj->ext_image_mode,
1307 j);
1308 }
1309 }
1310
1311 /* put buf back */
1312 mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl,
1313 my_obj->ch_obj->my_hdl,
1314 my_obj->my_hdl,
1315 mem_vtbl->user_data,
1316 my_obj->buf_num,
1317 my_obj->buf);
1318
1319 error_malloc:
1320 if (NULL != my_obj->buf) {
1321 free(my_obj->buf);
1322 my_obj->buf = NULL;
1323 }
1324 if (NULL != my_obj->buf_status) {
1325 free(my_obj->buf_status);
1326 my_obj->buf_status = NULL;
1327 }
1328 if (NULL != reg_flags) {
1329 free(reg_flags);
1330 reg_flags = NULL;
1331 }
1332
1333 return rc;
1334 }
1335
1336 /* return buffers to surface or release buffers allocated */
mm_stream_deinit_bufs(mm_stream_t * my_obj)1337 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
1338 {
1339 int32_t rc = 0, i;
1340 mm_camear_mem_vtbl_t *mem_vtbl = NULL;
1341 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1342 "image_mode = %d, fd = %d, state = %d",
1343 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1344 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1345
1346 if (NULL == my_obj->buf) {
1347 CDBG("%s: Buf is NULL, no need to deinit", __func__);
1348 return rc;
1349 }
1350
1351 /* IOMMU unmapping */
1352 for (i=0; i<my_obj->buf_num; i++) {
1353 if (my_obj->buf[i].fd > 0) {
1354 rc = mm_camera_unmap_buf(my_obj->ch_obj->cam_obj,
1355 my_obj->ext_image_mode,
1356 i);
1357 if (rc < 0 ) {
1358 CDBG_ERROR("%s: Error unmapping bufs at idx(%d) rc=%d",
1359 __func__, i, rc);
1360 }
1361 }
1362 }
1363
1364 /* release bufs */
1365 mem_vtbl = my_obj->ch_obj->cam_obj->mem_vtbl;
1366 if (NULL != mem_vtbl) {
1367 rc = mem_vtbl->put_buf(my_obj->ch_obj->cam_obj->my_hdl,
1368 my_obj->ch_obj->my_hdl,
1369 my_obj->my_hdl,
1370 mem_vtbl->user_data,
1371 my_obj->buf_num,
1372 my_obj->buf);
1373 } else {
1374 CDBG_ERROR("%s: mem table is NULL, cannot release buf", __func__);
1375 rc = -1;
1376 }
1377 free(my_obj->buf);
1378 my_obj->buf = NULL;
1379 free(my_obj->buf_status);
1380 my_obj->buf_status = NULL;
1381
1382 return rc;
1383 }
1384
mm_stream_reg_buf(mm_stream_t * my_obj)1385 int32_t mm_stream_reg_buf(mm_stream_t * my_obj)
1386 {
1387 int32_t rc = 0;
1388 uint8_t i;
1389 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1390 "image_mode = %d, fd = %d, state = %d",
1391 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1392 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1393
1394 rc = mm_stream_request_buf(my_obj);
1395 if (rc != 0) {
1396 return rc;
1397 }
1398
1399 pthread_mutex_lock(&my_obj->buf_lock);
1400 for(i = 0; i < my_obj->buf_num; i++){
1401 my_obj->buf[i].buf_idx = i;
1402
1403 /* check if need to qbuf initially */
1404 if (my_obj->buf_status[i].initial_reg_flag) {
1405 rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
1406 if (rc != 0) {
1407 CDBG_ERROR("%s: VIDIOC_QBUF rc = %d\n", __func__, rc);
1408 break;
1409 }
1410 my_obj->buf_status[i].buf_refcnt = 0;
1411 my_obj->buf_status[i].in_kernel = 1;
1412 } else {
1413 /* the buf is held by upper layer, will not queue into kernel.
1414 * add buf reference count */
1415 my_obj->buf_status[i].buf_refcnt = 1;
1416 my_obj->buf_status[i].in_kernel = 0;
1417 }
1418 }
1419
1420 pthread_mutex_unlock(&my_obj->buf_lock);
1421 return rc;
1422 }
1423
mm_stream_unreg_buf(mm_stream_t * my_obj)1424 int32_t mm_stream_unreg_buf(mm_stream_t * my_obj)
1425 {
1426 struct v4l2_requestbuffers bufreq;
1427 int32_t i, rc = 0,reg = 0;
1428 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1429 "image_mode = %d, fd = %d, state = %d",
1430 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1431 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1432
1433 pthread_mutex_lock(&my_obj->buf_lock);
1434 if (NULL != my_obj->buf_status) {
1435 for(i = 0; i < my_obj->buf_num; i++){
1436 if (my_obj->buf_status[i].initial_reg_flag){
1437 reg = 1;
1438 break;
1439 }
1440 }
1441 }
1442 pthread_mutex_unlock(&my_obj->buf_lock);
1443 if(!reg) {
1444 //No need to unregister a buffer
1445 goto end;
1446 }
1447 bufreq.count = 0;
1448 bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1449 bufreq.memory = V4L2_MEMORY_USERPTR;
1450 rc = ioctl(my_obj->fd, VIDIOC_REQBUFS, &bufreq);
1451 if (rc < 0) {
1452 CDBG_ERROR("%s: fd=%d, VIDIOC_REQBUFS failed, rc=%d\n",
1453 __func__, my_obj->fd, rc);
1454 }
1455
1456 end:
1457 /* reset buf reference count */
1458 pthread_mutex_lock(&my_obj->buf_lock);
1459 if (NULL != my_obj->buf_status) {
1460 for(i = 0; i < my_obj->buf_num; i++){
1461 my_obj->buf_status[i].buf_refcnt = 0;
1462 my_obj->buf_status[i].in_kernel = 0;
1463 }
1464 }
1465 pthread_mutex_unlock(&my_obj->buf_lock);
1466
1467 return rc;
1468 }
1469
mm_stream_set_fmt(mm_stream_t * my_obj)1470 int32_t mm_stream_set_fmt(mm_stream_t *my_obj)
1471 {
1472 int32_t rc = 0;
1473 struct v4l2_format fmt;
1474 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1475 "image_mode = %d, fd = %d, state = %d",
1476 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1477 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1478
1479 if(my_obj->fmt.width == 0 || my_obj->fmt.height == 0) {
1480 CDBG_ERROR("%s:invalid input[w=%d,h=%d,fmt=%d]\n",
1481 __func__, my_obj->fmt.width, my_obj->fmt.height, my_obj->fmt.fmt);
1482 return -1;
1483 }
1484
1485 memset(&fmt, 0, sizeof(fmt));
1486 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1487 fmt.fmt.pix_mp.width = my_obj->fmt.width;
1488 fmt.fmt.pix_mp.height= my_obj->fmt.height;
1489 fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
1490 fmt.fmt.pix_mp.pixelformat =
1491 mm_stream_util_get_v4l2_fmt(my_obj->fmt.fmt,
1492 &(fmt.fmt.pix_mp.num_planes));
1493 rc = ioctl(my_obj->fd, VIDIOC_S_FMT, &fmt);
1494 CDBG("%s:fd=%d, ext_image_mode=%d, rc=%d, fmt.fmt.pix_mp.pixelformat : 0x%x\n",
1495 __func__, my_obj->fd, my_obj->ext_image_mode, rc,
1496 fmt.fmt.pix_mp.pixelformat);
1497 return rc;
1498 }
1499
mm_stream_get_offset(mm_stream_t * my_obj)1500 int32_t mm_stream_get_offset(mm_stream_t *my_obj)
1501 {
1502 int32_t rc = 0;
1503 cam_frame_resolution_t frame_offset;
1504 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1505 "image_mode = %d, fd = %d, state = %d",
1506 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1507 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1508
1509 memset(&my_obj->frame_offset,0,sizeof(mm_camera_frame_len_offset));
1510
1511 frame_offset.format = my_obj->fmt.fmt;
1512 frame_offset.rotation = my_obj->fmt.rotation;
1513 frame_offset.width = my_obj->fmt.width;
1514 frame_offset.height = my_obj->fmt.height;
1515 frame_offset.image_mode = my_obj->ext_image_mode;
1516 if (!my_obj->need_stream_on &&
1517 my_obj->ext_image_mode == MSM_V4L2_EXT_CAPTURE_MODE_MAIN) {
1518 /* in case of video-sized snapshot,
1519 * image_mode should be video when querying frame offset*/
1520 frame_offset.image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
1521 }
1522
1523 switch (frame_offset.image_mode) {
1524 case MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW:
1525 if (CAMERA_YUV_420_YV12 == frame_offset.format) {
1526 frame_offset.padding_format = CAMERA_PAD_TO_2K;
1527 } else {
1528 frame_offset.padding_format = CAMERA_PAD_TO_WORD;
1529 }
1530 break;
1531 case MSM_V4L2_EXT_CAPTURE_MODE_MAIN:
1532 case MSM_V4L2_EXT_CAPTURE_MODE_RAW:
1533 case MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL:
1534 case MSM_V4L2_EXT_CAPTURE_MODE_RDI:
1535 frame_offset.padding_format = CAMERA_PAD_TO_WORD;
1536 break;
1537 case MSM_V4L2_EXT_CAPTURE_MODE_AEC:
1538 case MSM_V4L2_EXT_CAPTURE_MODE_AWB:
1539 case MSM_V4L2_EXT_CAPTURE_MODE_AF:
1540 case MSM_V4L2_EXT_CAPTURE_MODE_IHIST:
1541 break;
1542 case MSM_V4L2_EXT_CAPTURE_MODE_VIDEO:
1543 default:
1544 frame_offset.padding_format = CAMERA_PAD_TO_2K;
1545 break;
1546 }
1547
1548 CDBG("%s: format = %d, image_mode = %d, padding_format = %d, rotation = %d,"
1549 "width = %d height = %d",
1550 __func__,frame_offset.format,frame_offset.image_mode,frame_offset.padding_format,
1551 frame_offset.rotation,frame_offset.width,frame_offset.height);
1552
1553 rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj,
1554 CAMERA_GET_PARM_FRAME_RESOLUTION,
1555 sizeof(cam_frame_resolution_t),
1556 &frame_offset);
1557 if(rc != 0) {
1558 CDBG_ERROR("%s: Failed to get the stream offset and frame length",__func__);
1559 return rc;
1560 }
1561 my_obj->fmt.width = frame_offset.width;
1562 my_obj->fmt.height = frame_offset.height;
1563 memcpy(&my_obj->frame_offset,&frame_offset.frame_offset,sizeof(mm_camera_frame_len_offset));
1564 CDBG("%s: Frame length = %d width = %d, height = %d, rc = %d",
1565 __func__,my_obj->frame_offset.frame_len,my_obj->fmt.width,my_obj->fmt.height,rc);
1566 return rc;
1567 }
1568
1569
mm_stream_set_cid(mm_stream_t * my_obj,stream_cid_t * value)1570 int32_t mm_stream_set_cid(mm_stream_t *my_obj,stream_cid_t *value)
1571 {
1572 int32_t rc = 0;
1573 cam_cid_info_t cam_cid_info;
1574 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1575 "image_mode = %d, fd = %d, state = %d",
1576 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1577 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1578
1579 cam_cid_info.num_cids = 1;
1580 cam_cid_info.cid_entries[0].cid = value->cid;
1581 cam_cid_info.cid_entries[0].dt = value->dt;
1582 cam_cid_info.cid_entries[0].inst_handle = my_obj->inst_hdl;
1583
1584 rc = mm_camera_send_native_ctrl_cmd(my_obj->ch_obj->cam_obj,
1585 CAMERA_SET_PARM_CID,
1586 sizeof(cam_cid_info_t),
1587 &cam_cid_info);
1588 if(rc != 0) {
1589 CDBG_ERROR("%s: Failed to set the CID",__func__);
1590 return rc;
1591 }
1592 return rc;
1593 }
1594
mm_stream_get_cid(mm_stream_t * my_obj,stream_cid_t * out_value)1595 int32_t mm_stream_get_cid(mm_stream_t *my_obj,stream_cid_t *out_value)
1596 {
1597 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1598 "image_mode = %d, fd = %d, state = %d",
1599 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1600 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1601 //TODO: Need to use sensor structure init in camera query
1602 int32_t rc = 0;
1603 return rc;
1604 }
1605
mm_stream_buf_done(mm_stream_t * my_obj,mm_camera_buf_def_t * frame)1606 int32_t mm_stream_buf_done(mm_stream_t * my_obj,
1607 mm_camera_buf_def_t *frame)
1608 {
1609 int32_t rc = 0;
1610 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1611 "image_mode = %d, fd = %d, state = %d",
1612 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1613 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1614
1615 if (my_obj->is_local_buf) {
1616 /* special case for video-sized live snapshot
1617 * buf is local, no need to qbuf to kernel */
1618 return 0;
1619 }
1620
1621 pthread_mutex_lock(&my_obj->buf_lock);
1622
1623 if(my_obj->buf_status[frame->buf_idx].buf_refcnt == 0) {
1624 CDBG("%s: Error Trying to free second time?(idx=%d) count=%d, ext_image_mode=%d\n",
1625 __func__, frame->buf_idx,
1626 my_obj->buf_status[frame->buf_idx].buf_refcnt,
1627 my_obj->ext_image_mode);
1628 rc = -1;
1629 }else{
1630 my_obj->buf_status[frame->buf_idx].buf_refcnt--;
1631 if (0 == my_obj->buf_status[frame->buf_idx].buf_refcnt) {
1632 CDBG("<DEBUG> : Buf done for buffer:%d:%d", my_obj->ext_image_mode, frame->buf_idx);
1633 rc = mm_stream_qbuf(my_obj, frame);
1634 if(rc < 0) {
1635 CDBG_ERROR("%s: mm_camera_stream_qbuf(idx=%d) err=%d\n",
1636 __func__, frame->buf_idx, rc);
1637 } else {
1638 my_obj->buf_status[frame->buf_idx].in_kernel = 1;
1639 }
1640 }else{
1641 CDBG("<DEBUG> : Still ref count pending count :%d",
1642 my_obj->buf_status[frame->buf_idx].buf_refcnt);
1643 CDBG("<DEBUG> : for buffer:%p:%d, ext_image_mode=%d",
1644 my_obj, frame->buf_idx, my_obj->ext_image_mode);
1645 }
1646 }
1647 pthread_mutex_unlock(&my_obj->buf_lock);
1648 return rc;
1649 }
1650
mm_stream_reg_buf_cb(mm_stream_t * my_obj,mm_stream_data_cb_t * val)1651 int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
1652 mm_stream_data_cb_t *val)
1653 {
1654 int32_t rc = -1;
1655 uint8_t i;
1656 CDBG("%s: E, inst_handle = 0x%x, my_handle = 0x%x, "
1657 "image_mode = %d, fd = %d, state = %d",
1658 __func__, my_obj->inst_hdl, my_obj->my_hdl,
1659 my_obj->ext_image_mode, my_obj->fd, my_obj->state);
1660
1661 pthread_mutex_lock(&my_obj->cb_lock);
1662 for (i=0 ;i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
1663 if(NULL == my_obj->buf_cb[i].cb) {
1664 memcpy(&my_obj->buf_cb[i], val, sizeof(mm_stream_data_cb_t));
1665 rc = 0;
1666 break;
1667 }
1668 }
1669 pthread_mutex_unlock(&my_obj->cb_lock);
1670
1671 return rc;
1672 }
1673