1 /*
2 Copyright (c) 2011-2012,2015, 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 "mm_camera_dbg.h"
32 #include <errno.h>
33 #include <linux/msm_ion.h>
34 #include <sys/ioctl.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <poll.h>
39 #include "mm_camera_interface2.h"
40 #include "mm_camera.h"
41
42 #if 0
43 #undef CDBG
44 #define CDBG ALOGV
45 #endif
46 /* static functions prototype declarations */
47 static int mm_camera_channel_skip_frames(mm_camera_obj_t *my_obj,
48 mm_camera_frame_queue_t *mq,
49 mm_camera_frame_queue_t *sq,
50 mm_camera_stream_t *mstream,
51 mm_camera_stream_t *sstream,
52 mm_camera_channel_attr_buffering_frame_t *frame_attr);
53 static int mm_camera_channel_get_starting_frame(mm_camera_obj_t *my_obj,
54 mm_camera_ch_t *ch,
55 mm_camera_stream_t *mstream,
56 mm_camera_stream_t *sstream,
57 mm_camera_frame_queue_t *mq,
58 mm_camera_frame_queue_t *sq,
59 mm_camera_frame_t **mframe,
60 mm_camera_frame_t **sframe);
61 static int mm_camera_ch_search_frame_based_on_time(mm_camera_obj_t *my_obj,
62 mm_camera_ch_t *ch,
63 mm_camera_stream_t *mstream,
64 mm_camera_stream_t *sstream,
65 mm_camera_frame_queue_t *mq,
66 mm_camera_frame_queue_t *sq,
67 mm_camera_frame_t **mframe,
68 mm_camera_frame_t **sframe);
69
70
71
mm_camera_ch_util_get_num_stream(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type)72 int mm_camera_ch_util_get_num_stream(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type)
73 {
74 int num = 0;
75 switch(ch_type) {
76 case MM_CAMERA_CH_RAW:
77 num = 1;
78 break;
79 case MM_CAMERA_CH_PREVIEW:
80 num = 1;
81 break;
82 case MM_CAMERA_CH_VIDEO:
83 num = 1;
84 if(my_obj->ch[ch_type].video.has_main) {
85 num += 1;
86 }
87 break;
88 case MM_CAMERA_CH_SNAPSHOT:
89 num = 2;
90 break;
91 default:
92 break;
93 }
94 return num;
95 }
96
mm_camera_ch_util_get_stream_objs(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_stream_t ** stream1,mm_camera_stream_t ** stream2)97 void mm_camera_ch_util_get_stream_objs(mm_camera_obj_t * my_obj,
98 mm_camera_channel_type_t ch_type,
99 mm_camera_stream_t **stream1,
100 mm_camera_stream_t **stream2)
101 {
102 *stream1 = NULL;
103 *stream2 = NULL;
104
105 switch(ch_type) {
106 case MM_CAMERA_CH_RAW:
107 *stream1 = &my_obj->ch[ch_type].raw.stream;
108 break;
109 case MM_CAMERA_CH_PREVIEW:
110 *stream1 = &my_obj->ch[ch_type].preview.stream;
111 break;
112 case MM_CAMERA_CH_VIDEO:
113 *stream1 = &my_obj->ch[ch_type].video.video;
114 if(my_obj->ch[ch_type].video.has_main) {
115 *stream2 = &my_obj->ch[ch_type].video.main;
116 }
117 break;
118 case MM_CAMERA_CH_SNAPSHOT:
119 *stream1 = &my_obj->ch[ch_type].snapshot.main;
120 if (!my_obj->full_liveshot)
121 *stream2 = &my_obj->ch[ch_type].snapshot.thumbnail;
122 break;
123 default:
124 break;
125 }
126 }
127
mm_camera_ch_util_set_fmt(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_ch_image_fmt_parm_t * fmt)128 static int32_t mm_camera_ch_util_set_fmt(mm_camera_obj_t * my_obj,
129 mm_camera_channel_type_t ch_type,
130 mm_camera_ch_image_fmt_parm_t *fmt)
131 {
132 int32_t rc = MM_CAMERA_OK;
133 mm_camera_stream_t *stream1 = NULL;
134 mm_camera_stream_t *stream2 = NULL;
135 mm_camera_image_fmt_t *fmt1 = NULL;
136 mm_camera_image_fmt_t *fmt2 = NULL;
137
138 switch(ch_type) {
139 case MM_CAMERA_CH_RAW:
140 stream1 = &my_obj->ch[ch_type].raw.stream;
141 fmt1 = &fmt->def;
142 break;
143 case MM_CAMERA_CH_PREVIEW:
144 stream1 = &my_obj->ch[ch_type].preview.stream;
145 fmt1 = &fmt->def;
146 break;
147 case MM_CAMERA_CH_VIDEO:
148 stream1 = &my_obj->ch[ch_type].video.video;
149 fmt1 = &fmt->video.video;
150 if(my_obj->ch[ch_type].video.has_main) {
151 CDBG("%s:video channel has main image stream\n", __func__);
152 stream2 = &my_obj->ch[ch_type].video.main;
153 fmt2 = &fmt->video.main;
154 }
155 break;
156 case MM_CAMERA_CH_SNAPSHOT:
157 stream1 = &my_obj->ch[ch_type].snapshot.main;
158 fmt1 = &fmt->snapshot.main;
159 if (!my_obj->full_liveshot) {
160 stream2 = &my_obj->ch[ch_type].snapshot.thumbnail;
161 fmt2 = &fmt->snapshot.thumbnail;
162 }
163 break;
164 default:
165 rc = -1;
166 break;
167 }
168 CDBG("%s:ch=%d, streams[0x%x,0x%x]\n", __func__, ch_type,
169 (uint32_t)stream1, (uint32_t)stream2);
170 if(stream1)
171 rc = mm_camera_stream_fsm_fn_vtbl(my_obj, stream1,
172 MM_CAMERA_STATE_EVT_SET_FMT, fmt1);
173 if(stream2 && !rc)
174 rc = mm_camera_stream_fsm_fn_vtbl(my_obj, stream2,
175 MM_CAMERA_STATE_EVT_SET_FMT, fmt2);
176 return rc;
177 }
178
mm_camera_ch_util_acquire(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type)179 static int32_t mm_camera_ch_util_acquire(mm_camera_obj_t * my_obj,
180 mm_camera_channel_type_t ch_type)
181 {
182 int32_t rc = MM_CAMERA_OK;
183 mm_camera_stream_t *stream1 = NULL;
184 mm_camera_stream_t *stream2 = NULL;
185 mm_camera_stream_type_t type1;
186 mm_camera_stream_type_t type2;
187
188 if(my_obj->ch[ch_type].acquired) {
189 rc = MM_CAMERA_OK;
190 goto end;
191 }
192 pthread_mutex_init(&my_obj->ch[ch_type].mutex, NULL);
193 switch(ch_type) {
194 case MM_CAMERA_CH_RAW:
195 stream1 = &my_obj->ch[ch_type].raw.stream;
196 type1 = MM_CAMERA_STREAM_RAW;
197 break;
198 case MM_CAMERA_CH_PREVIEW:
199 stream1 = &my_obj->ch[ch_type].preview.stream;
200 type1 = MM_CAMERA_STREAM_PREVIEW;
201 break;
202 case MM_CAMERA_CH_VIDEO:
203 stream1 = &my_obj->ch[ch_type].video.video;
204 type1 = MM_CAMERA_STREAM_VIDEO;
205 /* no full image live shot by default */
206 my_obj->ch[ch_type].video.has_main = FALSE;
207 break;
208 case MM_CAMERA_CH_SNAPSHOT:
209 stream1 = &my_obj->ch[ch_type].snapshot.main;
210 type1 = MM_CAMERA_STREAM_SNAPSHOT;
211 if (!my_obj->full_liveshot) {
212 stream2 = &my_obj->ch[ch_type].snapshot.thumbnail;
213 type2 = MM_CAMERA_STREAM_THUMBNAIL;
214 }
215 break;
216 default:
217 return -1;
218 break;
219 }
220 if(stream1) rc = mm_camera_stream_fsm_fn_vtbl(my_obj, stream1,
221 MM_CAMERA_STATE_EVT_ACQUIRE, &type1);
222 if(stream2 && !rc) rc = mm_camera_stream_fsm_fn_vtbl(my_obj, stream2,
223 MM_CAMERA_STATE_EVT_ACQUIRE, &type2);
224 if(rc == MM_CAMERA_OK) {
225 if(!my_obj->ch[ch_type].acquired) my_obj->ch[ch_type].acquired = TRUE;
226 }
227
228 end:
229 return rc;
230 }
231
mm_camera_ch_util_release(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_state_evt_type_t evt)232 static int32_t mm_camera_ch_util_release(mm_camera_obj_t * my_obj,
233 mm_camera_channel_type_t ch_type,
234 mm_camera_state_evt_type_t evt)
235 {
236 mm_camera_stream_t *stream1, *stream2;
237
238 if(!my_obj->ch[ch_type].acquired) return MM_CAMERA_OK;
239
240 mm_camera_ch_util_get_stream_objs(my_obj,ch_type, &stream1, &stream2);
241 if(stream1)
242 mm_camera_stream_fsm_fn_vtbl(my_obj, stream1, evt, NULL);
243 if(stream2)
244 mm_camera_stream_fsm_fn_vtbl(my_obj, stream2, evt, NULL);
245 pthread_mutex_destroy(&my_obj->ch[ch_type].mutex);
246 memset(&my_obj->ch[ch_type],0,sizeof(my_obj->ch[ch_type]));
247 return 0;
248 }
249
mm_camera_ch_util_stream_null_val(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_state_evt_type_t evt,void * val)250 static int32_t mm_camera_ch_util_stream_null_val(mm_camera_obj_t * my_obj,
251 mm_camera_channel_type_t ch_type,
252 mm_camera_state_evt_type_t evt, void *val)
253 {
254 int32_t rc = 0;
255 switch(ch_type) {
256 case MM_CAMERA_CH_RAW:
257 rc = mm_camera_stream_fsm_fn_vtbl(my_obj, &my_obj->ch[ch_type].raw.stream,
258 evt, NULL);
259 break;
260 case MM_CAMERA_CH_PREVIEW:
261 rc = mm_camera_stream_fsm_fn_vtbl(my_obj, &my_obj->ch[ch_type].preview.stream,
262 evt, NULL);
263 break;
264 case MM_CAMERA_CH_VIDEO:
265 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
266 &my_obj->ch[ch_type].video.video, evt,
267 NULL);
268 if(!rc && my_obj->ch[ch_type].video.main.fd)
269 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
270 &my_obj->ch[ch_type].video.main, evt,
271 NULL);
272 break;
273 case MM_CAMERA_CH_SNAPSHOT:
274 my_obj->ch[ch_type].snapshot.expected_matching_id = 0;
275 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
276 &my_obj->ch[ch_type].snapshot.main, evt,
277 NULL);
278 if(!rc && !my_obj->full_liveshot)
279 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
280 &my_obj->ch[ch_type].snapshot.thumbnail, evt,
281 NULL);
282 break;
283 default:
284 CDBG_ERROR("%s: Invalid ch_type=%d", __func__, ch_type);
285 rc = -1;
286 break;
287 }
288 return rc;
289 }
290
mm_camera_ch_util_reg_buf(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_state_evt_type_t evt,void * val)291 static int32_t mm_camera_ch_util_reg_buf(mm_camera_obj_t * my_obj,
292 mm_camera_channel_type_t ch_type,
293 mm_camera_state_evt_type_t evt, void *val)
294 {
295 int32_t rc = 0;
296 switch(ch_type) {
297 case MM_CAMERA_CH_RAW:
298 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
299 &my_obj->ch[ch_type].raw.stream, evt,
300 (mm_camera_buf_def_t *)val);
301 break;
302 case MM_CAMERA_CH_PREVIEW:
303 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
304 &my_obj->ch[ch_type].preview.stream, evt,
305 (mm_camera_buf_def_t *)val);
306 break;
307 case MM_CAMERA_CH_VIDEO:
308 {
309 mm_camera_buf_video_t * buf = (mm_camera_buf_video_t *)val;
310 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
311 &my_obj->ch[ch_type].video.video, evt,
312 &buf->video);
313 if(!rc && my_obj->ch[ch_type].video.has_main) {
314 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
315 &my_obj->ch[ch_type].video.main, evt,
316 &buf->main);
317 }
318 }
319 break;
320 case MM_CAMERA_CH_SNAPSHOT:
321 {
322 mm_camera_buf_snapshot_t * buf = (mm_camera_buf_snapshot_t *)val;
323 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
324 &my_obj->ch[ch_type].snapshot.main, evt,
325 &buf->main);
326 if(!rc && !my_obj->full_liveshot) {
327 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
328 &my_obj->ch[ch_type].snapshot.thumbnail, evt,
329 & buf->thumbnail);
330 }
331 }
332 break;
333 default:
334 return -1;
335 break;
336 }
337 return rc;
338 }
339
mm_camera_ch_util_attr(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_channel_attr_t * val)340 static int32_t mm_camera_ch_util_attr(mm_camera_obj_t *my_obj,
341 mm_camera_channel_type_t ch_type,
342 mm_camera_channel_attr_t *val)
343 {
344 int rc = -MM_CAMERA_E_NOT_SUPPORTED;
345 /*if(ch_type != MM_CAMERA_CH_RAW) {
346 CDBG("%s: attr type %d not support for ch %d\n", __func__, val->type, ch_type);
347 return rc;
348 }*/
349 if(my_obj->ch[ch_type].acquired== 0) {
350 CDBG_ERROR("%s Channel %d not yet acquired ", __func__, ch_type);
351 return -MM_CAMERA_E_INVALID_OPERATION;
352 }
353 switch(val->type) {
354 case MM_CAMERA_CH_ATTR_RAW_STREAMING_TYPE:
355 if(val->raw_streaming_mode == MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE) {
356 my_obj->ch[ch_type].raw.mode = val->raw_streaming_mode;
357 rc = MM_CAMERA_OK;
358 }
359 break;
360 case MM_CAMERA_CH_ATTR_BUFFERING_FRAME:
361 /* it's good to check the stream state. TBD later */
362 memcpy(&my_obj->ch[ch_type].buffering_frame, &val->buffering_frame, sizeof(val->buffering_frame));
363 break;
364 default:
365 break;
366 }
367 return MM_CAMERA_OK;
368 }
369
mm_camera_ch_util_reg_buf_cb(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_buf_cb_t * val)370 static int32_t mm_camera_ch_util_reg_buf_cb(mm_camera_obj_t *my_obj,
371 mm_camera_channel_type_t ch_type,
372 mm_camera_buf_cb_t *val)
373 {
374 /* TODOhere: Need to return failure in case of MAX Cb registered
375 * but in order to return fail case need to set up rc.
376 * but the rc value needs to be thread safe
377 */
378 int i;
379 ALOGV("%s: Trying to register",__func__);
380 // pthread_mutex_lock(&my_obj->ch[ch_type].mutex);
381 for( i=0 ;i < MM_CAMERA_BUF_CB_MAX; i++ ) {
382 if(my_obj->ch[ch_type].buf_cb[i].cb==NULL) {
383 memcpy(&my_obj->ch[ch_type].buf_cb[i],val,sizeof(mm_camera_buf_cb_t));
384 break;
385 }
386 }
387 // pthread_mutex_unlock(&my_obj->ch[ch_type].mutex);
388 ALOGV("%s: Done register",__func__);
389 return MM_CAMERA_OK;
390 }
391
mm_camera_ch_util_qbuf(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_state_evt_type_t evt,mm_camera_ch_data_buf_t * val)392 static int32_t mm_camera_ch_util_qbuf(mm_camera_obj_t *my_obj,
393 mm_camera_channel_type_t ch_type,
394 mm_camera_state_evt_type_t evt,
395 mm_camera_ch_data_buf_t *val)
396 {
397 int32_t rc = -1;
398 mm_camera_stream_t *stream;
399 struct ion_flush_data cache_inv_data;
400 struct ion_custom_data custom_data;
401 int ion_fd;
402 struct msm_frame *cache_frame;
403 struct msm_frame *cache_frame1 = NULL;
404
405 CDBG("<DEBUG>: %s:ch_type:%d",__func__,ch_type);
406 switch(ch_type) {
407 case MM_CAMERA_CH_RAW:
408 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
409 &my_obj->ch[ch_type].raw.stream, evt,
410 &val->def);
411 cache_frame = val->def.frame;
412 break;
413 case MM_CAMERA_CH_PREVIEW:
414 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
415 &my_obj->ch[ch_type].preview.stream, evt,
416 &val->def);
417 cache_frame = val->def.frame;
418 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
419 val->def.frame->fd, val->def.frame->ion_alloc.len, val->def.frame->buffer);
420 break;
421 case MM_CAMERA_CH_VIDEO:
422 {
423 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
424 &my_obj->ch[ch_type].video.video, evt,
425 &val->video.video);
426 cache_frame = val->video.video.frame;
427 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
428 val->video.video.frame->fd, val->video.video.frame->ion_alloc.len, val->video.video.frame->buffer);
429
430 if(!rc && val->video.main.frame) {
431 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
432 &my_obj->ch[ch_type].video.main, evt,
433 &val->video.main);
434 cache_frame1 = val->video.main.frame;
435 }
436 }
437 break;
438 case MM_CAMERA_CH_SNAPSHOT:
439 {
440 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
441 &my_obj->ch[ch_type].snapshot.main, evt,
442 &val->snapshot.main);
443 cache_frame = val->snapshot.main.frame;
444 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
445 val->snapshot.main.frame->fd, val->snapshot.main.frame->ion_alloc.len, val->snapshot.main.frame->buffer);
446 if(!rc && (!my_obj->full_liveshot)) {
447 if (my_obj->op_mode == MM_CAMERA_OP_MODE_ZSL)
448 stream = &my_obj->ch[MM_CAMERA_CH_PREVIEW].preview.stream;
449 else
450 stream = &my_obj->ch[ch_type].snapshot.thumbnail;
451 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
452 stream, evt,
453 &val->snapshot.thumbnail);
454 cache_frame1 = val->snapshot.thumbnail.frame;
455 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
456 val->snapshot.thumbnail.frame->fd, val->snapshot.thumbnail.frame->ion_alloc.len, val->snapshot.thumbnail.frame->buffer);
457 }
458 }
459 break;
460 default:
461 return -1;
462 break;
463 }
464 #ifdef USE_ION
465 cache_inv_data.vaddr = cache_frame->buffer;
466 cache_inv_data.fd = cache_frame->fd;
467 cache_inv_data.handle = cache_frame->fd_data.handle;
468 cache_inv_data.length = cache_frame->ion_alloc.len;
469 custom_data.cmd = ION_IOC_INV_CACHES;
470 custom_data.arg = &cache_inv_data;
471 ion_fd = cache_frame->ion_dev_fd;
472 if(ion_fd > 0) {
473 if(ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0)
474 CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
475 else {
476 CDBG("%s: Successful cache invalidate\n", __func__);
477 if(cache_frame1) {
478 ion_fd = cache_frame1->ion_dev_fd;
479 cache_inv_data.vaddr = cache_frame1->buffer;
480 cache_inv_data.fd = cache_frame1->fd;
481 cache_inv_data.handle = cache_frame1->fd_data.handle;
482 cache_inv_data.length = cache_frame1->ion_alloc.len;
483 custom_data.cmd = ION_IOC_INV_CACHES;
484 custom_data.arg = &cache_inv_data;
485 if(ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0)
486 CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
487 else
488 CDBG("%s: Successful cache invalidate\n", __func__);
489 }
490 }
491 }
492 #endif
493
494 return rc;
495 }
496
mm_camera_ch_util_get_crop(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_state_evt_type_t evt,mm_camera_ch_crop_t * crop)497 static int mm_camera_ch_util_get_crop(mm_camera_obj_t *my_obj,
498 mm_camera_channel_type_t ch_type,
499 mm_camera_state_evt_type_t evt,
500 mm_camera_ch_crop_t *crop)
501 {
502 int rc = MM_CAMERA_OK;
503 switch(ch_type) {
504 case MM_CAMERA_CH_RAW:
505 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
506 &my_obj->ch[ch_type].raw.stream, evt,
507 &crop->crop);
508 break;
509 case MM_CAMERA_CH_PREVIEW:
510 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
511 &my_obj->ch[ch_type].preview.stream, evt,
512 &crop->crop);
513 break;
514 case MM_CAMERA_CH_VIDEO:
515 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
516 &my_obj->ch[ch_type].video.video, evt,
517 &crop->crop);
518 break;
519 case MM_CAMERA_CH_SNAPSHOT:
520 {
521 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
522 &my_obj->ch[ch_type].snapshot.main, evt,
523 &crop->snapshot.main_crop);
524 if(!rc && !my_obj->full_liveshot) {
525 ALOGV("%s: should not come here for Live Shot", __func__);
526 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
527 &my_obj->ch[ch_type].snapshot.thumbnail, evt,
528 &crop->snapshot.thumbnail_crop);
529 }
530 }
531 break;
532 default:
533 return -1;
534 break;
535 }
536 return rc;
537 }
538
mm_camera_ch_util_dispatch_buffered_frame(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type)539 static int mm_camera_ch_util_dispatch_buffered_frame(mm_camera_obj_t *my_obj,
540 mm_camera_channel_type_t ch_type)
541 {
542 return mm_camera_poll_dispatch_buffered_frames(my_obj, ch_type);
543 }
544
mm_camera_channel_get_time_diff(struct timespec * cur_ts,int usec_target,struct timespec * frame_ts)545 int mm_camera_channel_get_time_diff(struct timespec *cur_ts, int usec_target, struct timespec *frame_ts)
546 {
547 int dtusec = (cur_ts->tv_nsec - frame_ts->tv_nsec)/1000;
548 dtusec += (cur_ts->tv_sec - frame_ts->tv_sec)*1000000 - usec_target;
549 return dtusec;
550 }
551
mm_camera_channel_skip_frames(mm_camera_obj_t * my_obj,mm_camera_frame_queue_t * mq,mm_camera_frame_queue_t * sq,mm_camera_stream_t * mstream,mm_camera_stream_t * sstream,mm_camera_channel_attr_buffering_frame_t * frame_attr)552 static int mm_camera_channel_skip_frames(mm_camera_obj_t *my_obj,
553 mm_camera_frame_queue_t *mq,
554 mm_camera_frame_queue_t *sq,
555 mm_camera_stream_t *mstream,
556 mm_camera_stream_t *sstream,
557 mm_camera_channel_attr_buffering_frame_t *frame_attr)
558 {
559 int count = 0;
560 int i = 0;
561 mm_camera_frame_t *mframe = NULL, *sframe = NULL;
562 mm_camera_notify_frame_t notify_frame;
563
564 count = mm_camera_stream_frame_get_q_cnt(mq);
565 if(count < mm_camera_stream_frame_get_q_cnt(sq))
566 count = mm_camera_stream_frame_get_q_cnt(sq);
567 CDBG("%s: Q-size=%d, look_back =%d, M_match=%d, T_match=%d", __func__,
568 count, frame_attr->look_back, mq->match_cnt, sq->match_cnt);
569
570 count -= frame_attr->look_back;
571 CDBG("count=%d, frame_attr->look_back=%d,mq->match_cnt=%d, sq->match_cnt=%d",
572 count, frame_attr->look_back, mq->match_cnt,sq->match_cnt);
573 for(i=0; i < count; i++) {
574 mframe = mm_camera_stream_frame_deq(mq);
575 sframe = mm_camera_stream_frame_deq(sq);
576 if(mframe && sframe && mframe->frame.frame_id ==
577 sframe->frame.frame_id) {
578 mq->match_cnt--;
579 sq->match_cnt--;
580 }
581 if(mframe) {
582 notify_frame.frame = &mframe->frame;
583 notify_frame.idx = mframe->idx;
584 mm_camera_stream_util_buf_done(my_obj, mstream, ¬ify_frame);
585 }
586 if(sframe) {
587 notify_frame.frame = &sframe->frame;
588 notify_frame.idx = sframe->idx;
589 mm_camera_stream_util_buf_done(my_obj, sstream, ¬ify_frame);
590 }
591 }
592
593 CDBG("Post %s: Q-size=%d, look_back =%d, M_match=%d, T_match=%d", __func__,
594 count, frame_attr->look_back, mq->match_cnt, sq->match_cnt);
595 return MM_CAMERA_OK;
596 }
597
598 /*for ZSL mode to send the image pair to client*/
mm_camera_dispatch_buffered_frames(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type)599 void mm_camera_dispatch_buffered_frames(mm_camera_obj_t *my_obj,
600 mm_camera_channel_type_t ch_type)
601 {
602 int mcnt, i, rc = MM_CAMERA_E_GENERAL, scnt;
603 int num_of_req_frame = 0;
604 int j;
605 mm_camera_ch_data_buf_t data;
606 mm_camera_frame_t *mframe = NULL, *sframe = NULL;
607 mm_camera_frame_t *qmframe = NULL, *qsframe = NULL;
608 mm_camera_ch_t *ch = &my_obj->ch[ch_type];
609 mm_camera_frame_queue_t *mq = NULL;
610 mm_camera_frame_queue_t *sq = NULL;
611 mm_camera_stream_t *stream1 = NULL;
612 mm_camera_stream_t *stream2 = NULL;
613 ALOGV("%s: E", __func__);
614 mm_camera_ch_util_get_stream_objs(my_obj, ch_type, &stream1, &stream2);
615 stream2 = &my_obj->ch[MM_CAMERA_CH_PREVIEW].preview.stream;
616 if(stream1) {
617 mq = &stream1->frame.readyq;
618 }
619 if(stream2) {
620 sq = &stream2->frame.readyq;
621 }
622 CDBG("mq=%p, sq=%p, stream1=%p, stream2=%p", mq, sq, stream1, stream2);
623 pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_PREVIEW].mutex);
624 pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
625 if (mq && sq && stream1 && stream2) {
626 rc = mm_camera_channel_skip_frames(my_obj, mq, sq, stream1, stream2, &ch->buffering_frame);
627 if(rc != MM_CAMERA_OK) {
628 CDBG_ERROR("%s: Error getting right frame!", __func__);
629 goto end;
630 }
631 num_of_req_frame = my_obj->snap_burst_num_by_user;
632 ch->snapshot.pending_cnt = num_of_req_frame;
633
634 CDBG("num_of_req_frame =%d", num_of_req_frame);
635 for(i = 0; i < num_of_req_frame; i++) {
636 mframe = mm_camera_stream_frame_deq(mq);
637 sframe = mm_camera_stream_frame_deq(sq);
638 if(mframe && sframe) {
639 CDBG("%s: frame_id = 0x%x|0x%x, main idx = %d, thumbnail idx = %d", __func__,
640 mframe->frame.frame_id, sframe->frame.frame_id, mframe->idx, sframe->idx);
641 if(mframe->frame.frame_id != sframe->frame.frame_id) {
642 CDBG_ERROR("%s: ZSL algorithm error, main and thumbnail "
643 "frame_ids not same. Need bug fix", __func__);
644 }
645 memset(&data, 0, sizeof(data));
646 data.type = ch_type;
647 data.snapshot.main.frame = &mframe->frame;
648 data.snapshot.main.idx = mframe->idx;
649 data.snapshot.thumbnail.frame = &sframe->frame;
650 data.snapshot.thumbnail.idx = sframe->idx;
651 ch->snapshot.pending_cnt--;
652 mq->match_cnt--;
653 sq->match_cnt--;
654 for(j=0;j<MM_CAMERA_BUF_CB_MAX;j++) {
655 if( ch->buf_cb[j].cb!=NULL )
656 ch->buf_cb[j].cb(&data, ch->buf_cb[j].user_data);
657 }
658 } else {
659 CDBG_ERROR("%s: mframe %p, sframe = %p", __func__, mframe, sframe);
660 qmframe = mframe;
661 qsframe = sframe;
662 rc = -1;
663 break;
664 }
665 }
666 if(qmframe) {
667 mm_camera_stream_frame_enq(mq, &stream1->frame.frame[qmframe->idx]);
668 qmframe = NULL;
669 }
670 if(qsframe) {
671 mm_camera_stream_frame_enq(sq, &stream2->frame.frame[qsframe->idx]);
672 qsframe = NULL;
673 }
674 } else {
675 CDBG_ERROR(" mq =%p sq =%p stream1 =%p stream2 =%p", mq, sq , stream1 , stream2);
676
677 }
678 CDBG("%s: burst number: %d, pending_count: %d", __func__,
679 my_obj->snap_burst_num_by_user, ch->snapshot.pending_cnt);
680 end:
681 pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
682 pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_PREVIEW].mutex);
683 /* If we are done sending callbacks for all the requested number of snapshots
684 send data delivery done event*/
685 if((rc == MM_CAMERA_OK) && (!ch->snapshot.pending_cnt)) {
686 mm_camera_event_t data;
687 data.event_type = MM_CAMERA_EVT_TYPE_CH;
688 data.e.ch.evt = MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE;
689 data.e.ch.ch = ch_type;
690 mm_camera_poll_send_ch_event(my_obj, &data);
691 }
692 }
693
mm_camera_ch_fn(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type,mm_camera_state_evt_type_t evt,void * val)694 int32_t mm_camera_ch_fn(mm_camera_obj_t * my_obj,
695 mm_camera_channel_type_t ch_type,
696 mm_camera_state_evt_type_t evt, void *val)
697 {
698 int32_t rc = MM_CAMERA_OK;
699
700 CDBG("%s:ch = %d, evt=%d\n", __func__, ch_type, evt);
701 switch(evt) {
702 case MM_CAMERA_STATE_EVT_ACQUIRE:
703 rc = mm_camera_ch_util_acquire(my_obj, ch_type);
704 break;
705 case MM_CAMERA_STATE_EVT_RELEASE:
706 /* safe code in case no stream off before release. */
707 //mm_camera_poll_thread_release(my_obj, ch_type);
708 rc = mm_camera_ch_util_release(my_obj, ch_type, evt);
709 break;
710 case MM_CAMERA_STATE_EVT_ATTR:
711 rc = mm_camera_ch_util_attr(my_obj, ch_type,
712 (mm_camera_channel_attr_t *)val);
713 break;
714 case MM_CAMERA_STATE_EVT_REG_BUF_CB:
715 rc = mm_camera_ch_util_reg_buf_cb(my_obj, ch_type,
716 (mm_camera_buf_cb_t *)val);
717 break;
718 case MM_CAMERA_STATE_EVT_SET_FMT:
719 rc = mm_camera_ch_util_set_fmt(my_obj, ch_type,
720 (mm_camera_ch_image_fmt_parm_t *)val);
721 break;
722 case MM_CAMERA_STATE_EVT_REG_BUF:
723 case MM_CAMERA_STATE_EVT_REQUEST_BUF:
724 rc = mm_camera_ch_util_reg_buf(my_obj, ch_type, evt, val);
725 break;
726 case MM_CAMERA_STATE_EVT_UNREG_BUF:
727 rc = mm_camera_ch_util_stream_null_val(my_obj, ch_type, evt, NULL);
728 break;
729 case MM_CAMERA_STATE_EVT_STREAM_ON: {
730 if(ch_type == MM_CAMERA_CH_RAW &&
731 my_obj->ch[ch_type].raw.mode == MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE) {
732 if( MM_CAMERA_OK != (rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
733 MSM_V4L2_PID_CAM_MODE, MSM_V4L2_CAM_OP_RAW))) {
734 CDBG("%s:set MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE err=%d\n", __func__, rc);
735 break;
736 }
737 }
738 mm_camera_poll_thread_add_ch(my_obj, ch_type);
739 rc = mm_camera_ch_util_stream_null_val(my_obj, ch_type, evt, NULL);
740 if(rc < 0) {
741 CDBG_ERROR("%s: Failed in STREAM ON", __func__);
742 mm_camera_poll_thread_release(my_obj, ch_type);
743 }
744 break;
745 }
746 case MM_CAMERA_STATE_EVT_STREAM_OFF: {
747 mm_camera_poll_thread_del_ch(my_obj, ch_type);
748 rc = mm_camera_ch_util_stream_null_val(my_obj, ch_type, evt, NULL);
749 break;
750 }
751 case MM_CAMERA_STATE_EVT_QBUF:
752 rc = mm_camera_ch_util_qbuf(my_obj, ch_type, evt,
753 (mm_camera_ch_data_buf_t *)val);
754 break;
755 case MM_CAMERA_STATE_EVT_GET_CROP:
756 rc = mm_camera_ch_util_get_crop(my_obj, ch_type, evt,
757 (mm_camera_ch_crop_t *)val);
758 break;
759 case MM_CAMERA_STATE_EVT_DISPATCH_BUFFERED_FRAME:
760 rc = mm_camera_ch_util_dispatch_buffered_frame(my_obj, ch_type);
761 break;
762 default:
763 break;
764 }
765 return rc;
766 }
767