• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 Copyright (c) 2011, 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 <sys/ioctl.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <poll.h>
38 #include "mm_camera_interface2.h"
39 #include "mm_camera.h"
40 
41 typedef enum {
42     /* ask the channel to flash out the queued frames. */
43     MM_CAMERA_PIPE_CMD_FLASH_QUEUED_FRAME,
44     /* ask ctrl fd to generate ch event to HAL */
45     MM_CAMERA_PIPE_CMD_CH_EVENT,
46     /*start*/
47     MM_CAMERA_PIPE_CMD_ADD_CH,
48 
49     /*stop*/
50     MM_CAMERA_PIPE_CMD_DEL_CH,
51 
52     /* exit */
53     MM_CAMERA_PIPE_CMD_EXIT,
54     /* max count */
55     MM_CAMERA_PIPE_CMD_MAX
56 } mm_camera_pipe_cmd_type_t;
57 
58 typedef enum {
59     MM_CAMERA_POLL_TASK_STATE_POLL,     /* polling pid in polling state. */
60     MM_CAMERA_POLL_TASK_STATE_MAX
61 } mm_camera_poll_task_state_type_t;
62 
63 typedef struct {
64     uint8_t cmd;
65     mm_camera_event_t event;
66 } mm_camera_sig_evt_t;
67 
mm_camera_poll_sig(mm_camera_poll_thread_t * poll_cb,uint32_t cmd)68 static int32_t mm_camera_poll_sig(mm_camera_poll_thread_t *poll_cb,
69                                   uint32_t cmd)
70 {
71     /* send through pipe */
72     /* get the mutex */
73     mm_camera_sig_evt_t cmd_evt;
74     memset(&cmd_evt, 0, sizeof(cmd_evt));
75     cmd_evt.cmd = cmd;
76     int len;
77     CDBG("%s: begin", __func__);
78 
79     pthread_mutex_lock(&poll_cb->mutex);
80     /* reset the statue to false */
81     poll_cb->status = FALSE;
82     /* send cmd to worker */
83     len = write(poll_cb->data.pfds[1], &cmd_evt, sizeof(cmd_evt));
84     if(len < 1) {
85       CDBG("%s: len = %d, errno = %d", __func__, len, errno);
86       //pthread_mutex_unlock(&poll_cb->mutex);
87       //return -1;
88     }
89     CDBG("%s: begin IN mutex write done, len = %d", __func__, len);
90     /* wait till worker task gives positive signal */
91     while (!poll_cb->status) {
92         int rc;
93         struct timespec ts;
94         clock_gettime(CLOCK_REALTIME, &ts);
95         ts.tv_sec += 2;
96         CDBG("%s: wait", __func__);
97         rc = pthread_cond_timedwait(&poll_cb->cond_v, &poll_cb->mutex, &ts);
98         if (rc) {
99             ALOGV("%s: error on pthread_cond_timedwait: %s", __func__, strerror(rc));
100             break;
101         }
102     }
103     /* done */
104     pthread_mutex_unlock(&poll_cb->mutex);
105     CDBG("%s: end, len = %d, size = %d", __func__, len, sizeof(cmd_evt));
106     return MM_CAMERA_OK;
107 }
108 
mm_camera_poll_sig_done(mm_camera_poll_thread_t * poll_cb)109 static void mm_camera_poll_sig_done(mm_camera_poll_thread_t *poll_cb)
110 {
111     pthread_mutex_lock(&poll_cb->mutex);
112     poll_cb->status = TRUE;
113     pthread_cond_signal(&poll_cb->cond_v);
114     CDBG("%s: done, in mutex", __func__);
115     pthread_mutex_unlock(&poll_cb->mutex);
116 }
117 
mm_camera_poll_proc_msm(mm_camera_poll_thread_t * poll_cb,struct pollfd * fds)118 static int32_t mm_camera_poll_proc_msm(mm_camera_poll_thread_t *poll_cb, struct pollfd *fds)
119 {
120    int i;
121 
122     for(i = 0; i < poll_cb->data.num_fds-1; i++) {
123         /*Checking for data events*/
124         if((poll_cb->data.poll_type == MM_CAMERA_POLL_TYPE_CH) &&
125            (fds[i].revents & POLLIN) &&
126            (fds[i].revents & POLLRDNORM)) {
127             if(poll_cb->data.used) {
128                 mm_camera_msm_data_notify(poll_cb->data.my_obj,
129                                         fds[i].fd,
130                                         poll_cb->data.poll_streams[i]->stream_type);
131             }
132 
133         }
134         /*Checking for ctrl events*/
135         if((poll_cb->data.poll_type == MM_CAMERA_POLL_TYPE_EVT) &&
136            (fds[i].revents & POLLPRI)) {
137           CDBG("%s: mm_camera_msm_evt_notify\n", __func__);
138           mm_camera_msm_evt_notify(poll_cb->data.my_obj, fds[i].fd);
139         }
140 
141     }
142     return 0;
143 }
144 
cm_camera_poll_set_state(mm_camera_poll_thread_t * poll_cb,mm_camera_poll_task_state_type_t state)145 static void cm_camera_poll_set_state(mm_camera_poll_thread_t *poll_cb,
146                                      mm_camera_poll_task_state_type_t state)
147 {
148     poll_cb->data.state = state;
149 }
150 
mm_camera_poll_proc_pipe(mm_camera_poll_thread_t * poll_cb)151 static void mm_camera_poll_proc_pipe(mm_camera_poll_thread_t *poll_cb)
152 {
153     ssize_t read_len;
154     int i;
155     mm_camera_sig_evt_t cmd_evt;
156     read_len = read(poll_cb->data.pfds[0], &cmd_evt, sizeof(cmd_evt));
157     CDBG("%s: read_fd = %d, read_len = %d, expect_len = %d",
158          __func__, poll_cb->data.pfds[0], (int)read_len, (int)sizeof(cmd_evt));
159     switch(cmd_evt.cmd) {
160     case MM_CAMERA_PIPE_CMD_FLASH_QUEUED_FRAME:
161       mm_camera_dispatch_buffered_frames(poll_cb->data.my_obj,
162                                          poll_cb->data.ch_type);
163       break;
164     case MM_CAMERA_PIPE_CMD_CH_EVENT: {
165       mm_camera_event_t *event = &cmd_evt.event;
166       CDBG("%s: ch event, type=0x%x, ch=%d, evt=%d",
167            __func__, event->event_type, event->e.ch.ch, event->e.ch.evt);
168       mm_camera_dispatch_app_event(poll_cb->data.my_obj, event);
169       break;
170     }
171     case MM_CAMERA_PIPE_CMD_ADD_CH:
172         if(poll_cb->data.poll_type == MM_CAMERA_POLL_TYPE_CH) {
173             for(i = 0; i < MM_CAMERA_CH_STREAM_MAX; i++) {
174                 if(poll_cb->data.poll_streams[i]) {
175                     poll_cb->data.poll_fd[poll_cb->data.num_fds + i] = poll_cb->data.poll_streams[i]->fd;
176                 }
177             }
178         }
179         poll_cb->data.num_fds += mm_camera_ch_util_get_num_stream(poll_cb->data.my_obj,
180                                                                       poll_cb->data.ch_type);
181         poll_cb->data.used = 1;
182         CDBG("Num fds after MM_CAMERA_PIPE_CMD_ADD_CH = %d",poll_cb->data.num_fds);
183         break;
184 
185     case MM_CAMERA_PIPE_CMD_DEL_CH:
186         poll_cb->data.num_fds -= mm_camera_ch_util_get_num_stream(poll_cb->data.my_obj,
187                                                                   poll_cb->data.ch_type);
188         poll_cb->data.used = 0;
189         CDBG("Num fds after MM_CAMERA_PIPE_CMD_DEL_CH = %d",poll_cb->data.num_fds);
190         break;
191 
192     case MM_CAMERA_PIPE_CMD_EXIT:
193     default:
194         cm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_MAX);
195         mm_camera_poll_sig_done(poll_cb);
196         break;
197     }
198 }
199 
mm_camera_poll_ch_busy(mm_camera_obj_t * my_obj,int ch_type)200 static int mm_camera_poll_ch_busy(mm_camera_obj_t * my_obj, int ch_type)
201 {
202     int i;
203     int used = 0;
204     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
205     pthread_mutex_lock(&poll_cb->mutex);
206     used = poll_cb->data.used;
207     pthread_mutex_unlock(&poll_cb->mutex);
208     if(used)
209         return 1;
210     else
211         return 0;
212 }
mm_camera_poll_dispatch_buffered_frames(mm_camera_obj_t * my_obj,int ch_type)213 int32_t mm_camera_poll_dispatch_buffered_frames(mm_camera_obj_t * my_obj, int ch_type)
214 {
215     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
216     mm_camera_sig_evt_t cmd;
217     int len;
218 
219     cmd.cmd = MM_CAMERA_PIPE_CMD_FLASH_QUEUED_FRAME;
220     memset(&cmd.event, 0, sizeof(cmd.event));
221     pthread_mutex_lock(&poll_cb->mutex);
222     len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
223     pthread_mutex_unlock(&poll_cb->mutex);
224     return MM_CAMERA_OK;
225 }
226 
mm_camera_poll_busy(mm_camera_obj_t * my_obj)227 int mm_camera_poll_busy(mm_camera_obj_t * my_obj)
228 {
229     int i;
230     mm_camera_poll_thread_t *poll_cb;
231     for(i = 0; i < (MM_CAMERA_POLL_THRAED_MAX - 1); i++) {
232         if(mm_camera_poll_ch_busy(my_obj,  i) > 0)
233           return 1;
234     }
235     return 0;
236 }
237 
mm_camera_poll_send_ch_event(mm_camera_obj_t * my_obj,mm_camera_event_t * event)238 int mm_camera_poll_send_ch_event(mm_camera_obj_t * my_obj, mm_camera_event_t *event)
239 {
240     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[MM_CAMERA_CH_MAX];
241     mm_camera_sig_evt_t cmd;
242     int len;
243 
244     cmd.cmd = MM_CAMERA_PIPE_CMD_CH_EVENT;
245     memcpy(&cmd.event, event, sizeof(cmd.event));
246     CDBG("%s: ch event, type=0x%x, ch=%d, evt=%d, poll_type = %d, read_fd=%d, write_fd=%d",
247         __func__, event->event_type, event->e.ch.ch, event->e.ch.evt, poll_cb->data.poll_type,
248         poll_cb->data.pfds[0], poll_cb->data.pfds[1]);
249     pthread_mutex_lock(&poll_cb->mutex);
250     len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
251     pthread_mutex_unlock(&poll_cb->mutex);
252     return MM_CAMERA_OK;
253 }
254 
mm_camera_poll_fn(mm_camera_poll_thread_t * poll_cb)255 static void *mm_camera_poll_fn(mm_camera_poll_thread_t *poll_cb)
256 {
257     int rc = 0, i;
258     struct pollfd fds[MM_CAMERA_CH_STREAM_MAX+1];
259     int timeoutms;
260     CDBG("%s: poll type = %d, num_fd = %d\n",
261          __func__, poll_cb->data.poll_type, poll_cb->data.num_fds);
262     do {
263         for(i = 0; i < poll_cb->data.num_fds; i++) {
264             fds[i].fd = poll_cb->data.poll_fd[i];
265             fds[i].events = POLLIN|POLLRDNORM|POLLPRI;
266         }
267         timeoutms = poll_cb->data.timeoutms;
268         rc = poll(fds, poll_cb->data.num_fds, timeoutms);
269         if(rc > 0) {
270             if((fds[0].revents & POLLIN) && (fds[0].revents & POLLRDNORM))
271                 mm_camera_poll_proc_pipe(poll_cb);
272             else
273                 mm_camera_poll_proc_msm(poll_cb, &fds[1]);
274         } else {
275             /* in error case sleep 10 us and then continue. hard coded here */
276             usleep(10);
277             continue;
278         }
279     } while (poll_cb->data.state == MM_CAMERA_POLL_TASK_STATE_POLL);
280     return NULL;
281 }
282 
mm_camera_poll_thread(void * data)283 static void *mm_camera_poll_thread(void *data)
284 {
285     int rc = 0;
286     int i;
287     void *ret = NULL;
288     mm_camera_poll_thread_t *poll_cb = data;
289 
290     poll_cb->data.poll_fd[poll_cb->data.num_fds++] = poll_cb->data.pfds[0];
291     switch(poll_cb->data.poll_type) {
292     case MM_CAMERA_POLL_TYPE_EVT:
293         poll_cb->data.poll_fd[poll_cb->data.num_fds++] =
294           ((mm_camera_obj_t *)(poll_cb->data.my_obj))->ctrl_fd;
295         break;
296     case MM_CAMERA_POLL_TYPE_CH:
297     default:
298         break;
299     }
300     mm_camera_poll_sig_done(poll_cb);
301     ret = mm_camera_poll_fn(poll_cb);
302     return ret;
303 }
304 
mm_camera_poll_start(mm_camera_obj_t * my_obj,mm_camera_poll_thread_t * poll_cb)305 int mm_camera_poll_start(mm_camera_obj_t * my_obj,  mm_camera_poll_thread_t *poll_cb)
306 {
307     pthread_mutex_lock(&poll_cb->mutex);
308     poll_cb->status = 0;
309     pthread_create(&poll_cb->data.pid, NULL, mm_camera_poll_thread, (void *)poll_cb);
310     while (!poll_cb->status) {
311         int rc;
312         struct timespec ts;
313 
314         clock_gettime(CLOCK_REALTIME, &ts);
315         ts.tv_sec += 2;
316         rc = pthread_cond_timedwait(&poll_cb->cond_v, &poll_cb->mutex, &ts);
317         if (rc) {
318             ALOGV("%s: error on pthread_cond_timedwait: %s", __func__, strerror(rc));
319             break;
320         }
321     }
322     pthread_mutex_unlock(&poll_cb->mutex);
323     return MM_CAMERA_OK;
324 }
325 
mm_camera_poll_stop(mm_camera_obj_t * my_obj,mm_camera_poll_thread_t * poll_cb)326 int mm_camera_poll_stop(mm_camera_obj_t * my_obj, mm_camera_poll_thread_t *poll_cb)
327 {
328     CDBG("%s, my_obj=0x%x\n", __func__, (uint32_t)my_obj);
329     mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_EXIT);
330     if (pthread_join(poll_cb->data.pid, NULL) != 0) {
331         CDBG("%s: pthread dead already\n", __func__);
332     }
333     return MM_CAMERA_OK;
334 }
335 
336 
mm_camera_poll_thread_add_ch(mm_camera_obj_t * my_obj,int ch_type)337 int mm_camera_poll_thread_add_ch(mm_camera_obj_t * my_obj, int ch_type)
338 {
339     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
340     mm_camera_sig_evt_t cmd;
341     int len;
342 
343     if(poll_cb->data.used == 1){
344         CDBG_ERROR("%s : Thread is Active",__func__);
345         return MM_CAMERA_OK;
346     }
347     CDBG("Run thread for ch_type = %d ",ch_type);
348     cmd.cmd = MM_CAMERA_PIPE_CMD_ADD_CH;
349     poll_cb->data.ch_type = ch_type;
350 
351     pthread_mutex_lock(&poll_cb->mutex);
352     len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
353     pthread_mutex_unlock(&poll_cb->mutex);
354     poll_cb->data.used = 1;
355     return MM_CAMERA_OK;
356 }
357 
mm_camera_poll_thread_del_ch(mm_camera_obj_t * my_obj,int ch_type)358 int mm_camera_poll_thread_del_ch(mm_camera_obj_t * my_obj, int ch_type)
359 {
360     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
361     mm_camera_sig_evt_t cmd;
362     int len;
363 
364     if(poll_cb->data.used == 0){
365         CDBG_ERROR("%s : Thread is Not Active",__func__);
366         return MM_CAMERA_OK;
367     }
368     CDBG("Stop thread for ch_type = %d ",ch_type);
369     cmd.cmd = MM_CAMERA_PIPE_CMD_DEL_CH;
370     poll_cb->data.ch_type = (mm_camera_channel_type_t)ch_type;
371 
372     pthread_mutex_lock(&poll_cb->mutex);
373     len = write(poll_cb->data.pfds[1], &cmd, sizeof(cmd));
374     pthread_mutex_unlock(&poll_cb->mutex);
375     poll_cb->data.used = 0;
376     return MM_CAMERA_OK;
377 
378 }
379 
380 
mm_camera_poll_thread_launch(mm_camera_obj_t * my_obj,int ch_type)381 int mm_camera_poll_thread_launch(mm_camera_obj_t * my_obj, int ch_type)
382 {
383     int rc = MM_CAMERA_OK;
384     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
385     if(mm_camera_poll_ch_busy(my_obj, ch_type) > 0) {
386         CDBG_ERROR("%s: err, poll thread of channel %d already running. cam_id=%d\n",
387              __func__, ch_type, my_obj->my_id);
388         return -MM_CAMERA_E_INVALID_OPERATION;
389     }
390     poll_cb->data.ch_type = ch_type;
391     rc = pipe(poll_cb->data.pfds);
392     if(rc < 0) {
393         CDBG_ERROR("%s: camera_id = %d, pipe open rc=%d\n", __func__, my_obj->my_id, rc);
394         rc = - MM_CAMERA_E_GENERAL;
395     }
396     CDBG("%s: ch = %d, poll_type = %d, read fd = %d, write fd = %d",
397         __func__, ch_type, poll_cb->data.poll_type,
398         poll_cb->data.pfds[0], poll_cb->data.pfds[1]);
399     poll_cb->data.my_obj = my_obj;
400     poll_cb->data.used = 0;
401     poll_cb->data.timeoutms = -1;  /* Infinite seconds */
402 
403     if(ch_type < MM_CAMERA_CH_MAX) {
404         poll_cb->data.poll_type = MM_CAMERA_POLL_TYPE_CH;
405         mm_camera_ch_util_get_stream_objs(my_obj, ch_type,
406                                       &poll_cb->data.poll_streams[0],
407                                       &poll_cb->data.poll_streams[1]);
408     } else{
409         poll_cb->data.poll_type = MM_CAMERA_POLL_TYPE_EVT;
410     }
411 
412     ALOGV("%s: ch_type = %d, poll_type = %d, read fd = %d, write fd = %d",
413          __func__, ch_type, poll_cb->data.poll_type,
414          poll_cb->data.pfds[0], poll_cb->data.pfds[1]);
415     /* launch the thread */
416     rc = mm_camera_poll_start(my_obj, poll_cb);
417     return rc;
418 }
419 
mm_camera_poll_thread_release(mm_camera_obj_t * my_obj,int ch_type)420 int mm_camera_poll_thread_release(mm_camera_obj_t * my_obj, int ch_type)
421 {
422     int rc = MM_CAMERA_OK;
423     mm_camera_poll_thread_t *poll_cb = &my_obj->poll_threads[ch_type];
424     if(MM_CAMERA_POLL_TASK_STATE_MAX == poll_cb->data.state) {
425         CDBG("%s: err, poll thread of channel % is not running. cam_id=%d\n",
426              __func__, ch_type, my_obj->my_id);
427         return -MM_CAMERA_E_INVALID_OPERATION;
428     }
429     rc = mm_camera_poll_stop(my_obj, poll_cb);
430 
431     if(poll_cb->data.pfds[0]) {
432         close(poll_cb->data.pfds[0]);
433     }
434     if(poll_cb->data.pfds[1]) {
435         close(poll_cb->data.pfds[1]);
436     }
437     memset(&poll_cb->data, 0, sizeof(poll_cb->data));
438     return MM_CAMERA_OK;
439 }
440 
mm_camera_poll_threads_init(mm_camera_obj_t * my_obj)441 void mm_camera_poll_threads_init(mm_camera_obj_t * my_obj)
442 {
443     int i;
444     mm_camera_poll_thread_t *poll_cb;
445 
446     for(i = 0; i < MM_CAMERA_POLL_THRAED_MAX; i++) {
447         poll_cb = &my_obj->poll_threads[i];
448         pthread_mutex_init(&poll_cb->mutex, NULL);
449         pthread_cond_init(&poll_cb->cond_v, NULL);
450     }
451 }
452 
mm_camera_poll_threads_deinit(mm_camera_obj_t * my_obj)453 void mm_camera_poll_threads_deinit(mm_camera_obj_t * my_obj)
454 {
455     int i;
456     mm_camera_poll_thread_t *poll_cb;
457 
458     for(i = 0; i < MM_CAMERA_POLL_THRAED_MAX; i++) {
459         poll_cb = &my_obj->poll_threads[i];
460         if(poll_cb->data.used)
461             mm_camera_poll_stop(my_obj, poll_cb);
462         pthread_mutex_destroy(&poll_cb->mutex);
463         pthread_cond_destroy(&poll_cb->cond_v);
464         memset(poll_cb, 0, sizeof(mm_camera_poll_thread_t));
465     }
466 }
467