1 /*
2 Copyright (c) 2011-2012, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 int ion_fd;
401 struct msm_frame *cache_frame;
402 struct msm_frame *cache_frame1 = NULL;
403
404 CDBG("<DEBUG>: %s:ch_type:%d",__func__,ch_type);
405 switch(ch_type) {
406 case MM_CAMERA_CH_RAW:
407 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
408 &my_obj->ch[ch_type].raw.stream, evt,
409 &val->def);
410 cache_frame = val->def.frame;
411 break;
412 case MM_CAMERA_CH_PREVIEW:
413 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
414 &my_obj->ch[ch_type].preview.stream, evt,
415 &val->def);
416 cache_frame = val->def.frame;
417 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
418 val->def.frame->fd, val->def.frame->ion_alloc.len, val->def.frame->buffer);
419 break;
420 case MM_CAMERA_CH_VIDEO:
421 {
422 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
423 &my_obj->ch[ch_type].video.video, evt,
424 &val->video.video);
425 cache_frame = val->video.video.frame;
426 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
427 val->video.video.frame->fd, val->video.video.frame->ion_alloc.len, val->video.video.frame->buffer);
428
429 if(!rc && val->video.main.frame) {
430 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
431 &my_obj->ch[ch_type].video.main, evt,
432 &val->video.main);
433 cache_frame1 = val->video.main.frame;
434 }
435 }
436 break;
437 case MM_CAMERA_CH_SNAPSHOT:
438 {
439 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
440 &my_obj->ch[ch_type].snapshot.main, evt,
441 &val->snapshot.main);
442 cache_frame = val->snapshot.main.frame;
443 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
444 val->snapshot.main.frame->fd, val->snapshot.main.frame->ion_alloc.len, val->snapshot.main.frame->buffer);
445 if(!rc) {
446 if (my_obj->op_mode == MM_CAMERA_OP_MODE_ZSL)
447 stream = &my_obj->ch[MM_CAMERA_CH_PREVIEW].preview.stream;
448 else
449 stream = &my_obj->ch[ch_type].snapshot.thumbnail;
450 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
451 stream, evt,
452 &val->snapshot.thumbnail);
453 cache_frame1 = val->snapshot.thumbnail.frame;
454 CDBG("buffer fd = %d, length = %d, vaddr = %p\n",
455 val->snapshot.thumbnail.frame->fd, val->snapshot.thumbnail.frame->ion_alloc.len, val->snapshot.thumbnail.frame->buffer);
456 }
457 }
458 break;
459 default:
460 return -1;
461 break;
462 }
463 #ifdef USE_ION
464 cache_inv_data.vaddr = cache_frame->buffer;
465 cache_inv_data.fd = cache_frame->fd;
466 cache_inv_data.handle = cache_frame->fd_data.handle;
467 cache_inv_data.length = cache_frame->ion_alloc.len;
468 ion_fd = cache_frame->ion_dev_fd;
469 if(ion_fd > 0) {
470 if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0)
471 CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
472 else {
473 CDBG("%s: Successful cache invalidate\n", __func__);
474 if(cache_frame1) {
475 ion_fd = cache_frame1->ion_dev_fd;
476 cache_inv_data.vaddr = cache_frame1->buffer;
477 cache_inv_data.fd = cache_frame1->fd;
478 cache_inv_data.handle = cache_frame1->fd_data.handle;
479 cache_inv_data.length = cache_frame1->ion_alloc.len;
480 if(ioctl(ion_fd, ION_IOC_INV_CACHES, &cache_inv_data) < 0)
481 CDBG_ERROR("%s: Cache Invalidate failed\n", __func__);
482 else
483 CDBG("%s: Successful cache invalidate\n", __func__);
484 }
485 }
486 }
487 #endif
488
489 return rc;
490 }
491
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)492 static int mm_camera_ch_util_get_crop(mm_camera_obj_t *my_obj,
493 mm_camera_channel_type_t ch_type,
494 mm_camera_state_evt_type_t evt,
495 mm_camera_ch_crop_t *crop)
496 {
497 int rc = MM_CAMERA_OK;
498 switch(ch_type) {
499 case MM_CAMERA_CH_RAW:
500 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
501 &my_obj->ch[ch_type].raw.stream, evt,
502 &crop->crop);
503 break;
504 case MM_CAMERA_CH_PREVIEW:
505 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
506 &my_obj->ch[ch_type].preview.stream, evt,
507 &crop->crop);
508 break;
509 case MM_CAMERA_CH_VIDEO:
510 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
511 &my_obj->ch[ch_type].video.video, evt,
512 &crop->crop);
513 break;
514 case MM_CAMERA_CH_SNAPSHOT:
515 {
516 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
517 &my_obj->ch[ch_type].snapshot.main, evt,
518 &crop->snapshot.main_crop);
519 if(!rc && !my_obj->full_liveshot) {
520 ALOGV("%s: should not come here for Live Shot", __func__);
521 rc = mm_camera_stream_fsm_fn_vtbl(my_obj,
522 &my_obj->ch[ch_type].snapshot.thumbnail, evt,
523 &crop->snapshot.thumbnail_crop);
524 }
525 }
526 break;
527 default:
528 return -1;
529 break;
530 }
531 return rc;
532 }
533
mm_camera_ch_util_dispatch_buffered_frame(mm_camera_obj_t * my_obj,mm_camera_channel_type_t ch_type)534 static int mm_camera_ch_util_dispatch_buffered_frame(mm_camera_obj_t *my_obj,
535 mm_camera_channel_type_t ch_type)
536 {
537 return mm_camera_poll_dispatch_buffered_frames(my_obj, ch_type);
538 }
539
mm_camera_channel_get_time_diff(struct timespec * cur_ts,int usec_target,struct timespec * frame_ts)540 int mm_camera_channel_get_time_diff(struct timespec *cur_ts, int usec_target, struct timespec *frame_ts)
541 {
542 int dtusec = (cur_ts->tv_nsec - frame_ts->tv_nsec)/1000;
543 dtusec += (cur_ts->tv_sec - frame_ts->tv_sec)*1000000 - usec_target;
544 return dtusec;
545 }
546
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)547 static int mm_camera_channel_skip_frames(mm_camera_obj_t *my_obj,
548 mm_camera_frame_queue_t *mq,
549 mm_camera_frame_queue_t *sq,
550 mm_camera_stream_t *mstream,
551 mm_camera_stream_t *sstream,
552 mm_camera_channel_attr_buffering_frame_t *frame_attr)
553 {
554 int count = 0;
555 int i = 0;
556 mm_camera_frame_t *mframe = NULL, *sframe = NULL;
557 mm_camera_notify_frame_t notify_frame;
558
559 count = mm_camera_stream_frame_get_q_cnt(mq);
560 if(count < mm_camera_stream_frame_get_q_cnt(sq))
561 count = mm_camera_stream_frame_get_q_cnt(sq);
562 CDBG("%s: Q-size=%d, look_back =%d, M_match=%d, T_match=%d", __func__,
563 count, frame_attr->look_back, mq->match_cnt, sq->match_cnt);
564
565 count -= frame_attr->look_back;
566 CDBG("count=%d, frame_attr->look_back=%d,mq->match_cnt=%d, sq->match_cnt=%d",
567 count, frame_attr->look_back, mq->match_cnt,sq->match_cnt);
568 for(i=0; i < count; i++) {
569 mframe = mm_camera_stream_frame_deq(mq);
570 sframe = mm_camera_stream_frame_deq(sq);
571 if(mframe && sframe && mframe->frame.frame_id ==
572 sframe->frame.frame_id) {
573 mq->match_cnt--;
574 sq->match_cnt--;
575 }
576 if(mframe) {
577 notify_frame.frame = &mframe->frame;
578 notify_frame.idx = mframe->idx;
579 mm_camera_stream_util_buf_done(my_obj, mstream, ¬ify_frame);
580 }
581 if(sframe) {
582 notify_frame.frame = &sframe->frame;
583 notify_frame.idx = sframe->idx;
584 mm_camera_stream_util_buf_done(my_obj, sstream, ¬ify_frame);
585 }
586 }
587
588 CDBG("Post %s: Q-size=%d, look_back =%d, M_match=%d, T_match=%d", __func__,
589 count, frame_attr->look_back, mq->match_cnt, sq->match_cnt);
590 return MM_CAMERA_OK;
591 }
592
593 /*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)594 void mm_camera_dispatch_buffered_frames(mm_camera_obj_t *my_obj,
595 mm_camera_channel_type_t ch_type)
596 {
597 int mcnt, i, rc = MM_CAMERA_E_GENERAL, scnt;
598 int num_of_req_frame = 0;
599 int j;
600 mm_camera_ch_data_buf_t data;
601 mm_camera_frame_t *mframe = NULL, *sframe = NULL;
602 mm_camera_frame_t *qmframe = NULL, *qsframe = NULL;
603 mm_camera_ch_t *ch = &my_obj->ch[ch_type];
604 mm_camera_frame_queue_t *mq = NULL;
605 mm_camera_frame_queue_t *sq = NULL;
606 mm_camera_stream_t *stream1 = NULL;
607 mm_camera_stream_t *stream2 = NULL;
608 ALOGV("%s: E", __func__);
609 mm_camera_ch_util_get_stream_objs(my_obj, ch_type, &stream1, &stream2);
610 stream2 = &my_obj->ch[MM_CAMERA_CH_PREVIEW].preview.stream;
611 if(stream1) {
612 mq = &stream1->frame.readyq;
613 }
614 if(stream2) {
615 sq = &stream2->frame.readyq;
616 }
617 CDBG("mq=%p, sq=%p, stream1=%p, stream2=%p", mq, sq, stream1, stream2);
618 pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_PREVIEW].mutex);
619 pthread_mutex_lock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
620 if (mq && sq && stream1 && stream2) {
621 rc = mm_camera_channel_skip_frames(my_obj, mq, sq, stream1, stream2, &ch->buffering_frame);
622 if(rc != MM_CAMERA_OK) {
623 CDBG_ERROR("%s: Error getting right frame!", __func__);
624 goto end;
625 }
626 num_of_req_frame = my_obj->snap_burst_num_by_user;
627 ch->snapshot.pending_cnt = num_of_req_frame;
628
629 CDBG("num_of_req_frame =%d", num_of_req_frame);
630 for(i = 0; i < num_of_req_frame; i++) {
631 mframe = mm_camera_stream_frame_deq(mq);
632 sframe = mm_camera_stream_frame_deq(sq);
633 if(mframe && sframe) {
634 CDBG("%s: frame_id = 0x%x|0x%x, main idx = %d, thumbnail idx = %d", __func__,
635 mframe->frame.frame_id, sframe->frame.frame_id, mframe->idx, sframe->idx);
636 if(mframe->frame.frame_id != sframe->frame.frame_id) {
637 CDBG_ERROR("%s: ZSL algorithm error, main and thumbnail "
638 "frame_ids not same. Need bug fix", __func__);
639 }
640 memset(&data, 0, sizeof(data));
641 data.type = ch_type;
642 data.snapshot.main.frame = &mframe->frame;
643 data.snapshot.main.idx = mframe->idx;
644 data.snapshot.thumbnail.frame = &sframe->frame;
645 data.snapshot.thumbnail.idx = sframe->idx;
646 ch->snapshot.pending_cnt--;
647 mq->match_cnt--;
648 sq->match_cnt--;
649 for(j=0;j<MM_CAMERA_BUF_CB_MAX;j++) {
650 if( ch->buf_cb[j].cb!=NULL )
651 ch->buf_cb[j].cb(&data, ch->buf_cb[j].user_data);
652 }
653 } else {
654 CDBG_ERROR("%s: mframe %p, sframe = %p", __func__, mframe, sframe);
655 qmframe = mframe;
656 qsframe = sframe;
657 rc = -1;
658 break;
659 }
660 }
661 if(qmframe) {
662 mm_camera_stream_frame_enq(mq, &stream1->frame.frame[qmframe->idx]);
663 qmframe = NULL;
664 }
665 if(qsframe) {
666 mm_camera_stream_frame_enq(sq, &stream2->frame.frame[qsframe->idx]);
667 qsframe = NULL;
668 }
669 } else {
670 CDBG_ERROR(" mq =%p sq =%p stream1 =%p stream2 =%p", mq, sq , stream1 , stream2);
671
672 }
673 CDBG("%s: burst number: %d, pending_count: %d", __func__,
674 my_obj->snap_burst_num_by_user, ch->snapshot.pending_cnt);
675 end:
676 pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_SNAPSHOT].mutex);
677 pthread_mutex_unlock(&my_obj->ch[MM_CAMERA_CH_PREVIEW].mutex);
678 /* If we are done sending callbacks for all the requested number of snapshots
679 send data delivery done event*/
680 if((rc == MM_CAMERA_OK) && (!ch->snapshot.pending_cnt)) {
681 mm_camera_event_t data;
682 data.event_type = MM_CAMERA_EVT_TYPE_CH;
683 data.e.ch.evt = MM_CAMERA_CH_EVT_DATA_DELIVERY_DONE;
684 data.e.ch.ch = ch_type;
685 mm_camera_poll_send_ch_event(my_obj, &data);
686 }
687 }
688
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)689 int32_t mm_camera_ch_fn(mm_camera_obj_t * my_obj,
690 mm_camera_channel_type_t ch_type,
691 mm_camera_state_evt_type_t evt, void *val)
692 {
693 int32_t rc = MM_CAMERA_OK;
694
695 CDBG("%s:ch = %d, evt=%d\n", __func__, ch_type, evt);
696 switch(evt) {
697 case MM_CAMERA_STATE_EVT_ACQUIRE:
698 rc = mm_camera_ch_util_acquire(my_obj, ch_type);
699 break;
700 case MM_CAMERA_STATE_EVT_RELEASE:
701 /* safe code in case no stream off before release. */
702 //mm_camera_poll_thread_release(my_obj, ch_type);
703 rc = mm_camera_ch_util_release(my_obj, ch_type, evt);
704 break;
705 case MM_CAMERA_STATE_EVT_ATTR:
706 rc = mm_camera_ch_util_attr(my_obj, ch_type,
707 (mm_camera_channel_attr_t *)val);
708 break;
709 case MM_CAMERA_STATE_EVT_REG_BUF_CB:
710 rc = mm_camera_ch_util_reg_buf_cb(my_obj, ch_type,
711 (mm_camera_buf_cb_t *)val);
712 break;
713 case MM_CAMERA_STATE_EVT_SET_FMT:
714 rc = mm_camera_ch_util_set_fmt(my_obj, ch_type,
715 (mm_camera_ch_image_fmt_parm_t *)val);
716 break;
717 case MM_CAMERA_STATE_EVT_REG_BUF:
718 case MM_CAMERA_STATE_EVT_REQUEST_BUF:
719 case MM_CAMERA_STATE_EVT_ENQUEUE_BUF:
720 rc = mm_camera_ch_util_reg_buf(my_obj, ch_type, evt, val);
721 break;
722 case MM_CAMERA_STATE_EVT_UNREG_BUF:
723 rc = mm_camera_ch_util_stream_null_val(my_obj, ch_type, evt, NULL);
724 break;
725 case MM_CAMERA_STATE_EVT_STREAM_ON: {
726 if(ch_type == MM_CAMERA_CH_RAW &&
727 my_obj->ch[ch_type].raw.mode == MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE) {
728 if( MM_CAMERA_OK != (rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
729 MSM_V4L2_PID_CAM_MODE, MSM_V4L2_CAM_OP_RAW))) {
730 CDBG("%s:set MM_CAMERA_RAW_STREAMING_CAPTURE_SINGLE err=%d\n", __func__, rc);
731 break;
732 }
733 }
734 mm_camera_poll_thread_add_ch(my_obj, ch_type);
735 rc = mm_camera_ch_util_stream_null_val(my_obj, ch_type, evt, NULL);
736 if(rc < 0) {
737 CDBG_ERROR("%s: Failed in STREAM ON", __func__);
738 mm_camera_poll_thread_release(my_obj, ch_type);
739 }
740 break;
741 }
742 case MM_CAMERA_STATE_EVT_STREAM_OFF: {
743 mm_camera_poll_thread_del_ch(my_obj, ch_type);
744 rc = mm_camera_ch_util_stream_null_val(my_obj, ch_type, evt, NULL);
745 break;
746 }
747 case MM_CAMERA_STATE_EVT_QBUF:
748 rc = mm_camera_ch_util_qbuf(my_obj, ch_type, evt,
749 (mm_camera_ch_data_buf_t *)val);
750 break;
751 case MM_CAMERA_STATE_EVT_GET_CROP:
752 rc = mm_camera_ch_util_get_crop(my_obj, ch_type, evt,
753 (mm_camera_ch_crop_t *)val);
754 break;
755 case MM_CAMERA_STATE_EVT_DISPATCH_BUFFERED_FRAME:
756 rc = mm_camera_ch_util_dispatch_buffered_frame(my_obj, ch_type);
757 break;
758 default:
759 break;
760 }
761 return rc;
762 }
763