• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &notify_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, &notify_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