1 /* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 // To remove
31 #include <cutils/properties.h>
32
33 // System dependencies
34 #include <pthread.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
39 #include IOCTL_H
40
41 // Camera dependencies
42 #include "cam_semaphore.h"
43 #include "mm_camera_dbg.h"
44 #include "mm_camera_sock.h"
45 #include "mm_camera_interface.h"
46 #include "mm_camera.h"
47
48 #define SET_PARM_BIT32(parm, parm_arr) \
49 (parm_arr[parm/32] |= (1<<(parm%32)))
50
51 #define GET_PARM_BIT32(parm, parm_arr) \
52 ((parm_arr[parm/32]>>(parm%32))& 0x1)
53
54 /* internal function declare */
55 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
56 uint8_t reg_flag);
57 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
58 mm_camera_event_t *event);
59
60 /*===========================================================================
61 * FUNCTION : mm_camera_util_get_channel_by_handler
62 *
63 * DESCRIPTION: utility function to get a channel object from its handle
64 *
65 * PARAMETERS :
66 * @cam_obj: ptr to a camera object
67 * @handler: channel handle
68 *
69 * RETURN : ptr to a channel object.
70 * NULL if failed.
71 *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)72 mm_channel_t * mm_camera_util_get_channel_by_handler(
73 mm_camera_obj_t * cam_obj,
74 uint32_t handler)
75 {
76 int i;
77 mm_channel_t *ch_obj = NULL;
78 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
79 if (handler == cam_obj->ch[i].my_hdl) {
80 ch_obj = &cam_obj->ch[i];
81 break;
82 }
83 }
84 return ch_obj;
85 }
86
87 /*===========================================================================
88 * FUNCTION : mm_camera_util_chip_is_a_family
89 *
90 * DESCRIPTION: utility function to check if the host is A family chip
91 *
92 * PARAMETERS :
93 *
94 * RETURN : TRUE if A family.
95 * FALSE otherwise.
96 *==========================================================================*/
mm_camera_util_chip_is_a_family(void)97 uint8_t mm_camera_util_chip_is_a_family(void)
98 {
99 #ifdef USE_A_FAMILY
100 return TRUE;
101 #else
102 return FALSE;
103 #endif
104 }
105
106 /*===========================================================================
107 * FUNCTION : mm_camera_dispatch_app_event
108 *
109 * DESCRIPTION: dispatch event to apps who regitster for event notify
110 *
111 * PARAMETERS :
112 * @cmd_cb: ptr to a struct storing event info
113 * @user_data: user data ptr (camera object)
114 *
115 * RETURN : none
116 *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)117 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
118 void* user_data)
119 {
120 int i;
121 mm_camera_event_t *event = &cmd_cb->u.evt;
122 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
123 if (NULL != my_obj) {
124 mm_camera_cmd_thread_name(my_obj->evt_thread.threadName);
125 pthread_mutex_lock(&my_obj->cb_lock);
126 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
127 if(my_obj->evt.evt[i].evt_cb) {
128 my_obj->evt.evt[i].evt_cb(
129 my_obj->my_hdl,
130 event,
131 my_obj->evt.evt[i].user_data);
132 }
133 }
134 pthread_mutex_unlock(&my_obj->cb_lock);
135 }
136 }
137
138 /*===========================================================================
139 * FUNCTION : mm_camera_event_notify
140 *
141 * DESCRIPTION: callback to handle event notify from kernel. This call will
142 * dequeue event from kernel.
143 *
144 * PARAMETERS :
145 * @user_data: user data ptr (camera object)
146 *
147 * RETURN : none
148 *==========================================================================*/
mm_camera_event_notify(void * user_data)149 static void mm_camera_event_notify(void* user_data)
150 {
151 struct v4l2_event ev;
152 struct msm_v4l2_event_data *msm_evt = NULL;
153 int rc;
154 mm_camera_event_t evt;
155 memset(&evt, 0, sizeof(mm_camera_event_t));
156
157 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
158 if (NULL != my_obj) {
159 /* read evt */
160 memset(&ev, 0, sizeof(ev));
161 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
162
163 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
164 msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
165 switch (msm_evt->command) {
166 case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
167 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
168 mm_camera_enqueue_evt(my_obj, &evt);
169 break;
170 case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
171 pthread_mutex_lock(&my_obj->evt_lock);
172 my_obj->evt_rcvd.server_event_type = msm_evt->command;
173 my_obj->evt_rcvd.status = msm_evt->status;
174 pthread_cond_signal(&my_obj->evt_cond);
175 pthread_mutex_unlock(&my_obj->evt_lock);
176 break;
177 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
178 case CAM_EVENT_TYPE_INT_TAKE_RAW:
179 {
180 evt.server_event_type = msm_evt->command;
181 mm_camera_enqueue_evt(my_obj, &evt);
182 }
183 break;
184 case MSM_CAMERA_PRIV_SHUTDOWN:
185 {
186 LOGE("Camera Event DAEMON DIED received");
187 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
188 mm_camera_enqueue_evt(my_obj, &evt);
189 }
190 break;
191 case CAM_EVENT_TYPE_CAC_DONE:
192 {
193 evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE;
194 mm_camera_enqueue_evt(my_obj, &evt);
195 }
196 break;
197 default:
198 break;
199 }
200 }
201 }
202 }
203
204 /*===========================================================================
205 * FUNCTION : mm_camera_enqueue_evt
206 *
207 * DESCRIPTION: enqueue received event into event queue to be processed by
208 * event thread.
209 *
210 * PARAMETERS :
211 * @my_obj : ptr to a camera object
212 * @event : event to be queued
213 *
214 * RETURN : int32_t type of status
215 * 0 -- success
216 * -1 -- failure
217 *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)218 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
219 mm_camera_event_t *event)
220 {
221 int32_t rc = 0;
222 mm_camera_cmdcb_t *node = NULL;
223
224 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
225 if (NULL != node) {
226 memset(node, 0, sizeof(mm_camera_cmdcb_t));
227 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
228 node->u.evt = *event;
229
230 /* enqueue to evt cmd thread */
231 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
232 /* wake up evt cmd thread */
233 cam_sem_post(&(my_obj->evt_thread.cmd_sem));
234 } else {
235 LOGE("No memory for mm_camera_node_t");
236 rc = -1;
237 }
238
239 return rc;
240 }
241
242 /*===========================================================================
243 * FUNCTION : mm_camera_open
244 *
245 * DESCRIPTION: open a camera
246 *
247 * PARAMETERS :
248 * @my_obj : ptr to a camera object
249 *
250 * RETURN : int32_t type of status
251 * 0 -- success
252 * -1 -- failure
253 *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)254 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
255 {
256 char dev_name[MM_CAMERA_DEV_NAME_LEN];
257 int32_t rc = 0;
258 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
259 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
260 int cam_idx = 0;
261 const char *dev_name_value = NULL;
262 int l_errno = 0;
263
264 LOGD("begin\n");
265
266 if (NULL == my_obj) {
267 goto on_error;
268 }
269 dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl);
270 if (NULL == dev_name_value) {
271 goto on_error;
272 }
273 snprintf(dev_name, sizeof(dev_name), "/dev/%s",
274 dev_name_value);
275 sscanf(dev_name, "/dev/video%d", &cam_idx);
276 LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx);
277
278 do{
279 n_try--;
280 errno = 0;
281 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
282 l_errno = errno;
283 LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno);
284 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
285 LOGH("opened, break out while loop");
286 break;
287 }
288 LOGE("Failed with %s error, retrying after %d milli-seconds",
289 strerror(errno), sleep_msec);
290 usleep(sleep_msec * 1000U);
291 }while (n_try > 0);
292
293 if (my_obj->ctrl_fd < 0) {
294 LOGE("cannot open control fd of '%s' (%s)\n",
295 dev_name, strerror(l_errno));
296 if (l_errno == EBUSY)
297 rc = -EUSERS;
298 else
299 rc = -1;
300 goto on_error;
301 }
302
303 /* open domain socket*/
304 n_try = MM_CAMERA_DEV_OPEN_TRIES;
305 do {
306 n_try--;
307 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
308 l_errno = errno;
309 LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno);
310 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
311 LOGD("opened, break out while loop");
312 break;
313 }
314 LOGD("failed with I/O error retrying after %d milli-seconds",
315 sleep_msec);
316 usleep(sleep_msec * 1000U);
317 } while (n_try > 0);
318
319 if (my_obj->ds_fd < 0) {
320 LOGE("cannot open domain socket fd of '%s'(%s)\n",
321 dev_name, strerror(l_errno));
322 rc = -1;
323 goto on_error;
324 }
325 pthread_mutex_init(&my_obj->msg_lock, NULL);
326
327 pthread_mutex_init(&my_obj->cb_lock, NULL);
328 pthread_mutex_init(&my_obj->evt_lock, NULL);
329 pthread_cond_init(&my_obj->evt_cond, NULL);
330
331 LOGD("Launch evt Thread in Cam Open");
332 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
333 mm_camera_cmd_thread_launch(&my_obj->evt_thread,
334 mm_camera_dispatch_app_event,
335 (void *)my_obj);
336
337 /* launch event poll thread
338 * we will add evt fd into event poll thread upon user first register for evt */
339 LOGD("Launch evt Poll Thread in Cam Open");
340 snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");
341 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
342 MM_CAMERA_POLL_TYPE_EVT);
343 mm_camera_evt_sub(my_obj, TRUE);
344
345 /* unlock cam_lock, we need release global intf_lock in camera_open(),
346 * in order not block operation of other Camera in dual camera use case.*/
347 pthread_mutex_unlock(&my_obj->cam_lock);
348 LOGD("end (rc = %d)\n", rc);
349 return rc;
350
351 on_error:
352
353 if (NULL == dev_name_value) {
354 LOGE("Invalid device name\n");
355 rc = -1;
356 }
357
358 if (NULL == my_obj) {
359 LOGE("Invalid camera object\n");
360 rc = -1;
361 } else {
362 if (my_obj->ctrl_fd >= 0) {
363 close(my_obj->ctrl_fd);
364 my_obj->ctrl_fd = -1;
365 }
366 if (my_obj->ds_fd >= 0) {
367 mm_camera_socket_close(my_obj->ds_fd);
368 my_obj->ds_fd = -1;
369 }
370 }
371
372 /* unlock cam_lock, we need release global intf_lock in camera_open(),
373 * in order not block operation of other Camera in dual camera use case.*/
374 pthread_mutex_unlock(&my_obj->cam_lock);
375 return rc;
376 }
377
378 /*===========================================================================
379 * FUNCTION : mm_camera_close
380 *
381 * DESCRIPTION: enqueue received event into event queue to be processed by
382 * event thread.
383 *
384 * PARAMETERS :
385 * @my_obj : ptr to a camera object
386 * @event : event to be queued
387 *
388 * RETURN : int32_t type of status
389 * 0 -- success
390 * -1 -- failure
391 *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)392 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
393 {
394 LOGD("unsubscribe evt");
395 mm_camera_evt_sub(my_obj, FALSE);
396
397 LOGD("Close evt Poll Thread in Cam Close");
398 mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
399
400 LOGD("Close evt cmd Thread in Cam Close");
401 mm_camera_cmd_thread_release(&my_obj->evt_thread);
402
403 if(my_obj->ctrl_fd >= 0) {
404 close(my_obj->ctrl_fd);
405 my_obj->ctrl_fd = -1;
406 }
407 if(my_obj->ds_fd >= 0) {
408 mm_camera_socket_close(my_obj->ds_fd);
409 my_obj->ds_fd = -1;
410 }
411 pthread_mutex_destroy(&my_obj->msg_lock);
412
413 pthread_mutex_destroy(&my_obj->cb_lock);
414 pthread_mutex_destroy(&my_obj->evt_lock);
415 pthread_cond_destroy(&my_obj->evt_cond);
416
417 pthread_mutex_unlock(&my_obj->cam_lock);
418 return 0;
419 }
420
421 /*===========================================================================
422 * FUNCTION : mm_camera_register_event_notify_internal
423 *
424 * DESCRIPTION: internal implementation for registering callback for event notify.
425 *
426 * PARAMETERS :
427 * @my_obj : ptr to a camera object
428 * @evt_cb : callback to be registered to handle event notify
429 * @user_data: user data ptr
430 *
431 * RETURN : int32_t type of status
432 * 0 -- success
433 * -1 -- failure
434 *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)435 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
436 mm_camera_event_notify_t evt_cb,
437 void * user_data)
438 {
439 int i;
440 int rc = -1;
441 mm_camera_evt_obj_t *evt_array = NULL;
442
443 pthread_mutex_lock(&my_obj->cb_lock);
444 evt_array = &my_obj->evt;
445 if(evt_cb) {
446 /* this is reg case */
447 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
448 if(evt_array->evt[i].user_data == NULL) {
449 evt_array->evt[i].evt_cb = evt_cb;
450 evt_array->evt[i].user_data = user_data;
451 evt_array->reg_count++;
452 rc = 0;
453 break;
454 }
455 }
456 } else {
457 /* this is unreg case */
458 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
459 if(evt_array->evt[i].user_data == user_data) {
460 evt_array->evt[i].evt_cb = NULL;
461 evt_array->evt[i].user_data = NULL;
462 evt_array->reg_count--;
463 rc = 0;
464 break;
465 }
466 }
467 }
468
469 pthread_mutex_unlock(&my_obj->cb_lock);
470 return rc;
471 }
472
473 /*===========================================================================
474 * FUNCTION : mm_camera_register_event_notify
475 *
476 * DESCRIPTION: registering a callback for event notify.
477 *
478 * PARAMETERS :
479 * @my_obj : ptr to a camera object
480 * @evt_cb : callback to be registered to handle event notify
481 * @user_data: user data ptr
482 *
483 * RETURN : int32_t type of status
484 * 0 -- success
485 * -1 -- failure
486 *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)487 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
488 mm_camera_event_notify_t evt_cb,
489 void * user_data)
490 {
491 int rc = -1;
492 rc = mm_camera_register_event_notify_internal(my_obj,
493 evt_cb,
494 user_data);
495 pthread_mutex_unlock(&my_obj->cam_lock);
496 return rc;
497 }
498
499 /*===========================================================================
500 * FUNCTION : mm_camera_qbuf
501 *
502 * DESCRIPTION: enqueue buffer back to kernel
503 *
504 * PARAMETERS :
505 * @my_obj : camera object
506 * @ch_id : channel handle
507 * @buf : buf ptr to be enqueued
508 *
509 * RETURN : int32_t type of status
510 * 0 -- success
511 * -1 -- failure
512 *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)513 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
514 uint32_t ch_id,
515 mm_camera_buf_def_t *buf)
516 {
517 int rc = -1;
518 mm_channel_t * ch_obj = NULL;
519 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
520
521 pthread_mutex_unlock(&my_obj->cam_lock);
522
523 /* we always assume qbuf will be done before channel/stream is fully stopped
524 * because qbuf is done within dataCB context
525 * in order to avoid deadlock, we are not locking ch_lock for qbuf */
526 if (NULL != ch_obj) {
527 rc = mm_channel_qbuf(ch_obj, buf);
528 }
529
530 return rc;
531 }
532
533 /*===========================================================================
534 * FUNCTION : mm_camera_get_queued_buf_count
535 *
536 * DESCRIPTION: return queued buffer count
537 *
538 * PARAMETERS :
539 * @my_obj : camera object
540 * @ch_id : channel handle
541 * @stream_id : stream id
542 *
543 * RETURN : queued buffer count
544 *==========================================================================*/
mm_camera_get_queued_buf_count(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)545 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
546 uint32_t ch_id, uint32_t stream_id)
547 {
548 int rc = -1;
549 mm_channel_t * ch_obj = NULL;
550 uint32_t payload;
551 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
552 payload = stream_id;
553
554 if (NULL != ch_obj) {
555 pthread_mutex_lock(&ch_obj->ch_lock);
556 pthread_mutex_unlock(&my_obj->cam_lock);
557 rc = mm_channel_fsm_fn(ch_obj,
558 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
559 (void *)&payload,
560 NULL);
561 } else {
562 pthread_mutex_unlock(&my_obj->cam_lock);
563 }
564
565 return rc;
566 }
567
568 /*===========================================================================
569 * FUNCTION : mm_camera_query_capability
570 *
571 * DESCRIPTION: query camera capability
572 *
573 * PARAMETERS :
574 * @my_obj: camera object
575 *
576 * RETURN : int32_t type of status
577 * 0 -- success
578 * -1 -- failure
579 *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)580 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
581 {
582 int32_t rc = 0;
583 struct v4l2_capability cap;
584
585 /* get camera capabilities */
586 memset(&cap, 0, sizeof(cap));
587 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
588 if (rc != 0) {
589 LOGE("cannot get camera capabilities, rc = %d, errno %d",
590 rc, errno);
591 }
592
593 pthread_mutex_unlock(&my_obj->cam_lock);
594 return rc;
595
596 }
597
598 /*===========================================================================
599 * FUNCTION : mm_camera_set_parms
600 *
601 * DESCRIPTION: set parameters per camera
602 *
603 * PARAMETERS :
604 * @my_obj : camera object
605 * @parms : ptr to a param struct to be set to server
606 *
607 * RETURN : int32_t type of status
608 * 0 -- success
609 * -1 -- failure
610 * NOTE : Assume the parms struct buf is already mapped to server via
611 * domain socket. Corresponding fields of parameters to be set
612 * are already filled in by upper layer caller.
613 *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)614 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
615 parm_buffer_t *parms)
616 {
617 int32_t rc = -1;
618 int32_t value = 0;
619 if (parms != NULL) {
620 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
621 }
622 pthread_mutex_unlock(&my_obj->cam_lock);
623 return rc;
624 }
625
626 /*===========================================================================
627 * FUNCTION : mm_camera_get_parms
628 *
629 * DESCRIPTION: get parameters per camera
630 *
631 * PARAMETERS :
632 * @my_obj : camera object
633 * @parms : ptr to a param struct to be get from server
634 *
635 * RETURN : int32_t type of status
636 * 0 -- success
637 * -1 -- failure
638 * NOTE : Assume the parms struct buf is already mapped to server via
639 * domain socket. Parameters to be get from server are already
640 * filled in by upper layer caller. After this call, corresponding
641 * fields of requested parameters will be filled in by server with
642 * detailed information.
643 *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)644 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
645 parm_buffer_t *parms)
646 {
647 int32_t rc = -1;
648 int32_t value = 0;
649 if (parms != NULL) {
650 rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
651 }
652 pthread_mutex_unlock(&my_obj->cam_lock);
653 return rc;
654 }
655
656 /*===========================================================================
657 * FUNCTION : mm_camera_do_auto_focus
658 *
659 * DESCRIPTION: performing auto focus
660 *
661 * PARAMETERS :
662 * @camera_handle: camera handle
663 *
664 * RETURN : int32_t type of status
665 * 0 -- success
666 * -1 -- failure
667 * NOTE : if this call success, we will always assume there will
668 * be an auto_focus event following up.
669 *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)670 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
671 {
672 int32_t rc = -1;
673 int32_t value = 0;
674 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
675 pthread_mutex_unlock(&my_obj->cam_lock);
676 return rc;
677 }
678
679 /*===========================================================================
680 * FUNCTION : mm_camera_cancel_auto_focus
681 *
682 * DESCRIPTION: cancel auto focus
683 *
684 * PARAMETERS :
685 * @camera_handle: camera handle
686 *
687 * RETURN : int32_t type of status
688 * 0 -- success
689 * -1 -- failure
690 *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)691 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
692 {
693 int32_t rc = -1;
694 int32_t value = 0;
695 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
696 pthread_mutex_unlock(&my_obj->cam_lock);
697 return rc;
698 }
699
700 /*===========================================================================
701 * FUNCTION : mm_camera_prepare_snapshot
702 *
703 * DESCRIPTION: prepare hardware for snapshot
704 *
705 * PARAMETERS :
706 * @my_obj : camera object
707 * @do_af_flag : flag indicating if AF is needed
708 *
709 * RETURN : int32_t type of status
710 * 0 -- success
711 * -1 -- failure
712 *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)713 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
714 int32_t do_af_flag)
715 {
716 int32_t rc = -1;
717 int32_t value = do_af_flag;
718 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
719 pthread_mutex_unlock(&my_obj->cam_lock);
720 return rc;
721 }
722
723 /*===========================================================================
724 * FUNCTION : mm_camera_start_zsl_snapshot
725 *
726 * DESCRIPTION: start zsl snapshot
727 *
728 * PARAMETERS :
729 * @my_obj : camera object
730 *
731 * RETURN : int32_t type of status
732 * 0 -- success
733 * -1 -- failure
734 *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)735 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
736 {
737 int32_t rc = -1;
738 int32_t value = 0;
739
740 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
741 CAM_PRIV_START_ZSL_SNAPSHOT, &value);
742 return rc;
743 }
744
745 /*===========================================================================
746 * FUNCTION : mm_camera_stop_zsl_snapshot
747 *
748 * DESCRIPTION: stop zsl capture
749 *
750 * PARAMETERS :
751 * @my_obj : camera object
752 *
753 * RETURN : int32_t type of status
754 * 0 -- success
755 * -1 -- failure
756 *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)757 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
758 {
759 int32_t rc = -1;
760 int32_t value;
761 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
762 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
763 return rc;
764 }
765
766 /*===========================================================================
767 * FUNCTION : mm_camera_flush
768 *
769 * DESCRIPTION: flush the current camera state and buffers
770 *
771 * PARAMETERS :
772 * @my_obj : camera object
773 *
774 * RETURN : int32_t type of status
775 * 0 -- success
776 * -1 -- failure
777 *==========================================================================*/
mm_camera_flush(mm_camera_obj_t * my_obj)778 int32_t mm_camera_flush(mm_camera_obj_t *my_obj)
779 {
780 int32_t rc = -1;
781 int32_t value;
782 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
783 CAM_PRIV_FLUSH, &value);
784 pthread_mutex_unlock(&my_obj->cam_lock);
785 return rc;
786 }
787
788 /*===========================================================================
789 * FUNCTION : mm_camera_add_channel
790 *
791 * DESCRIPTION: add a channel
792 *
793 * PARAMETERS :
794 * @my_obj : camera object
795 * @attr : bundle attribute of the channel if needed
796 * @channel_cb : callback function for bundle data notify
797 * @userdata : user data ptr
798 *
799 * RETURN : uint32_t type of channel handle
800 * 0 -- invalid channel handle, meaning the op failed
801 * >0 -- successfully added a channel with a valid handle
802 * NOTE : if no bundle data notify is needed, meaning each stream in the
803 * channel will have its own stream data notify callback, then
804 * attr, channel_cb, and userdata can be NULL. In this case,
805 * no matching logic will be performed in channel for the bundling.
806 *==========================================================================*/
mm_camera_add_channel(mm_camera_obj_t * my_obj,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)807 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
808 mm_camera_channel_attr_t *attr,
809 mm_camera_buf_notify_t channel_cb,
810 void *userdata)
811 {
812 mm_channel_t *ch_obj = NULL;
813 uint8_t ch_idx = 0;
814 uint32_t ch_hdl = 0;
815
816 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
817 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
818 ch_obj = &my_obj->ch[ch_idx];
819 break;
820 }
821 }
822
823 if (NULL != ch_obj) {
824 /* initialize channel obj */
825 memset(ch_obj, 0, sizeof(mm_channel_t));
826 ch_hdl = mm_camera_util_generate_handler(ch_idx);
827 ch_obj->my_hdl = ch_hdl;
828 ch_obj->state = MM_CHANNEL_STATE_STOPPED;
829 ch_obj->cam_obj = my_obj;
830 pthread_mutex_init(&ch_obj->ch_lock, NULL);
831 ch_obj->sessionid = my_obj->sessionid;
832 mm_channel_init(ch_obj, attr, channel_cb, userdata);
833 }
834
835 pthread_mutex_unlock(&my_obj->cam_lock);
836
837 return ch_hdl;
838 }
839
840 /*===========================================================================
841 * FUNCTION : mm_camera_del_channel
842 *
843 * DESCRIPTION: delete a channel by its handle
844 *
845 * PARAMETERS :
846 * @my_obj : camera object
847 * @ch_id : channel handle
848 *
849 * RETURN : int32_t type of status
850 * 0 -- success
851 * -1 -- failure
852 * NOTE : all streams in the channel should be stopped already before
853 * this channel can be deleted.
854 *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)855 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
856 uint32_t ch_id)
857 {
858 int32_t rc = -1;
859 mm_channel_t * ch_obj =
860 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
861
862 if (NULL != ch_obj) {
863 pthread_mutex_lock(&ch_obj->ch_lock);
864 pthread_mutex_unlock(&my_obj->cam_lock);
865
866 rc = mm_channel_fsm_fn(ch_obj,
867 MM_CHANNEL_EVT_DELETE,
868 NULL,
869 NULL);
870
871 pthread_mutex_destroy(&ch_obj->ch_lock);
872 memset(ch_obj, 0, sizeof(mm_channel_t));
873 } else {
874 pthread_mutex_unlock(&my_obj->cam_lock);
875 }
876 return rc;
877 }
878
879 /*===========================================================================
880 * FUNCTION : mm_camera_get_bundle_info
881 *
882 * DESCRIPTION: query bundle info of the channel
883 *
884 * PARAMETERS :
885 * @my_obj : camera object
886 * @ch_id : channel handle
887 * @bundle_info : bundle info to be filled in
888 *
889 * RETURN : int32_t type of status
890 * 0 -- success
891 * -1 -- failure
892 * NOTE : all streams in the channel should be stopped already before
893 * this channel can be deleted.
894 *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)895 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
896 uint32_t ch_id,
897 cam_bundle_config_t *bundle_info)
898 {
899 int32_t rc = -1;
900 mm_channel_t * ch_obj =
901 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
902
903 if (NULL != ch_obj) {
904 pthread_mutex_lock(&ch_obj->ch_lock);
905 pthread_mutex_unlock(&my_obj->cam_lock);
906
907 rc = mm_channel_fsm_fn(ch_obj,
908 MM_CHANNEL_EVT_GET_BUNDLE_INFO,
909 (void *)bundle_info,
910 NULL);
911 } else {
912 pthread_mutex_unlock(&my_obj->cam_lock);
913 }
914 return rc;
915 }
916
917 /*===========================================================================
918 * FUNCTION : mm_camera_link_stream
919 *
920 * DESCRIPTION: link a stream into a channel
921 *
922 * PARAMETERS :
923 * @my_obj : camera object
924 * @ch_id : channel handle
925 * @stream_id : stream that will be linked
926 * @linked_ch_id : channel in which the stream will be linked
927 *
928 * RETURN : uint32_t type of stream handle
929 * 0 -- invalid stream handle, meaning the op failed
930 * >0 -- successfully linked a stream with a valid handle
931 *==========================================================================*/
mm_camera_link_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t linked_ch_id)932 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
933 uint32_t ch_id,
934 uint32_t stream_id,
935 uint32_t linked_ch_id)
936 {
937 uint32_t s_hdl = 0;
938 mm_channel_t * ch_obj =
939 mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id);
940 mm_channel_t * owner_obj =
941 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
942
943 if ((NULL != ch_obj) && (NULL != owner_obj)) {
944 pthread_mutex_lock(&ch_obj->ch_lock);
945 pthread_mutex_unlock(&my_obj->cam_lock);
946
947 mm_camera_stream_link_t stream_link;
948 memset(&stream_link, 0, sizeof(mm_camera_stream_link_t));
949 stream_link.ch = owner_obj;
950 stream_link.stream_id = stream_id;
951 mm_channel_fsm_fn(ch_obj,
952 MM_CHANNEL_EVT_LINK_STREAM,
953 (void*)&stream_link,
954 (void*)&s_hdl);
955 } else {
956 pthread_mutex_unlock(&my_obj->cam_lock);
957 }
958
959 return s_hdl;
960 }
961
962 /*===========================================================================
963 * FUNCTION : mm_camera_add_stream
964 *
965 * DESCRIPTION: add a stream into a channel
966 *
967 * PARAMETERS :
968 * @my_obj : camera object
969 * @ch_id : channel handle
970 *
971 * RETURN : uint32_t type of stream handle
972 * 0 -- invalid stream handle, meaning the op failed
973 * >0 -- successfully added a stream with a valid handle
974 *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)975 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
976 uint32_t ch_id)
977 {
978 uint32_t s_hdl = 0;
979 mm_channel_t * ch_obj =
980 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
981
982 if (NULL != ch_obj) {
983 pthread_mutex_lock(&ch_obj->ch_lock);
984 pthread_mutex_unlock(&my_obj->cam_lock);
985
986 mm_channel_fsm_fn(ch_obj,
987 MM_CHANNEL_EVT_ADD_STREAM,
988 NULL,
989 (void *)&s_hdl);
990 } else {
991 pthread_mutex_unlock(&my_obj->cam_lock);
992 }
993
994 return s_hdl;
995 }
996
997 /*===========================================================================
998 * FUNCTION : mm_camera_del_stream
999 *
1000 * DESCRIPTION: delete a stream by its handle
1001 *
1002 * PARAMETERS :
1003 * @my_obj : camera object
1004 * @ch_id : channel handle
1005 * @stream_id : stream handle
1006 *
1007 * RETURN : int32_t type of status
1008 * 0 -- success
1009 * -1 -- failure
1010 * NOTE : stream should be stopped already before it can be deleted.
1011 *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)1012 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
1013 uint32_t ch_id,
1014 uint32_t stream_id)
1015 {
1016 int32_t rc = -1;
1017 mm_channel_t * ch_obj =
1018 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1019
1020 if (NULL != ch_obj) {
1021 pthread_mutex_lock(&ch_obj->ch_lock);
1022 pthread_mutex_unlock(&my_obj->cam_lock);
1023
1024 rc = mm_channel_fsm_fn(ch_obj,
1025 MM_CHANNEL_EVT_DEL_STREAM,
1026 (void *)&stream_id,
1027 NULL);
1028 } else {
1029 pthread_mutex_unlock(&my_obj->cam_lock);
1030 }
1031
1032 return rc;
1033 }
1034
1035 /*===========================================================================
1036 * FUNCTION : mm_camera_start_zsl_snapshot_ch
1037 *
1038 * DESCRIPTION: starts zsl snapshot for specific channel
1039 *
1040 * PARAMETERS :
1041 * @my_obj : camera object
1042 * @ch_id : channel handle
1043 *
1044 * RETURN : int32_t type of status
1045 * 0 -- success
1046 * -1 -- failure
1047 *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1048 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1049 uint32_t ch_id)
1050 {
1051 int32_t rc = -1;
1052 mm_channel_t * ch_obj =
1053 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1054
1055 if (NULL != ch_obj) {
1056 pthread_mutex_lock(&ch_obj->ch_lock);
1057 pthread_mutex_unlock(&my_obj->cam_lock);
1058
1059 rc = mm_channel_fsm_fn(ch_obj,
1060 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
1061 NULL,
1062 NULL);
1063 } else {
1064 pthread_mutex_unlock(&my_obj->cam_lock);
1065 }
1066
1067 return rc;
1068 }
1069
1070 /*===========================================================================
1071 * FUNCTION : mm_camera_stop_zsl_snapshot_ch
1072 *
1073 * DESCRIPTION: stops zsl snapshot for specific channel
1074 *
1075 * PARAMETERS :
1076 * @my_obj : camera object
1077 * @ch_id : channel handle
1078 *
1079 * RETURN : int32_t type of status
1080 * 0 -- success
1081 * -1 -- failure
1082 *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1083 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1084 uint32_t ch_id)
1085 {
1086 int32_t rc = -1;
1087 mm_channel_t * ch_obj =
1088 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1089
1090 if (NULL != ch_obj) {
1091 pthread_mutex_lock(&ch_obj->ch_lock);
1092 pthread_mutex_unlock(&my_obj->cam_lock);
1093
1094 rc = mm_channel_fsm_fn(ch_obj,
1095 MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
1096 NULL,
1097 NULL);
1098 } else {
1099 pthread_mutex_unlock(&my_obj->cam_lock);
1100 }
1101
1102 return rc;
1103 }
1104
1105 /*===========================================================================
1106 * FUNCTION : mm_camera_config_stream
1107 *
1108 * DESCRIPTION: configure a stream
1109 *
1110 * PARAMETERS :
1111 * @my_obj : camera object
1112 * @ch_id : channel handle
1113 * @stream_id : stream handle
1114 * @config : stream configuration
1115 *
1116 * RETURN : int32_t type of status
1117 * 0 -- success
1118 * -1 -- failure
1119 *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)1120 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
1121 uint32_t ch_id,
1122 uint32_t stream_id,
1123 mm_camera_stream_config_t *config)
1124 {
1125 int32_t rc = -1;
1126 mm_channel_t * ch_obj =
1127 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1128 mm_evt_paylod_config_stream_t payload;
1129
1130 if (NULL != ch_obj) {
1131 pthread_mutex_lock(&ch_obj->ch_lock);
1132 pthread_mutex_unlock(&my_obj->cam_lock);
1133
1134 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
1135 payload.stream_id = stream_id;
1136 payload.config = config;
1137 rc = mm_channel_fsm_fn(ch_obj,
1138 MM_CHANNEL_EVT_CONFIG_STREAM,
1139 (void *)&payload,
1140 NULL);
1141 } else {
1142 pthread_mutex_unlock(&my_obj->cam_lock);
1143 }
1144
1145 return rc;
1146 }
1147
1148 /*===========================================================================
1149 * FUNCTION : mm_camera_start_channel
1150 *
1151 * DESCRIPTION: start a channel, which will start all streams in the channel
1152 *
1153 * PARAMETERS :
1154 * @my_obj : camera object
1155 * @ch_id : channel handle
1156 *
1157 * RETURN : int32_t type of status
1158 * 0 -- success
1159 * -1 -- failure
1160 *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1161 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id)
1162 {
1163 int32_t rc = -1;
1164 mm_channel_t * ch_obj =
1165 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1166
1167 if (NULL != ch_obj) {
1168 pthread_mutex_lock(&ch_obj->ch_lock);
1169 pthread_mutex_unlock(&my_obj->cam_lock);
1170
1171 rc = mm_channel_fsm_fn(ch_obj,
1172 MM_CHANNEL_EVT_START,
1173 NULL,
1174 NULL);
1175 } else {
1176 pthread_mutex_unlock(&my_obj->cam_lock);
1177 }
1178
1179 return rc;
1180 }
1181
1182 /*===========================================================================
1183 * FUNCTION : mm_camera_stop_channel
1184 *
1185 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1186 *
1187 * PARAMETERS :
1188 * @my_obj : camera object
1189 * @ch_id : channel handle
1190 *
1191 * RETURN : int32_t type of status
1192 * 0 -- success
1193 * -1 -- failure
1194 *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1195 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1196 uint32_t ch_id)
1197 {
1198 int32_t rc = 0;
1199 mm_channel_t * ch_obj =
1200 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1201
1202 if (NULL != ch_obj) {
1203 pthread_mutex_lock(&ch_obj->ch_lock);
1204 pthread_mutex_unlock(&my_obj->cam_lock);
1205
1206 rc = mm_channel_fsm_fn(ch_obj,
1207 MM_CHANNEL_EVT_STOP,
1208 NULL,
1209 NULL);
1210 } else {
1211 pthread_mutex_unlock(&my_obj->cam_lock);
1212 }
1213 return rc;
1214 }
1215
1216 /*===========================================================================
1217 * FUNCTION : mm_camera_request_super_buf
1218 *
1219 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1220 * frames from superbuf queue
1221 *
1222 * PARAMETERS :
1223 * @my_obj : camera object
1224 * @ch_id : channel handle
1225 * @num_buf_requested : number of matched frames needed
1226 *
1227 * RETURN : int32_t type of status
1228 * 0 -- success
1229 * -1 -- failure
1230 *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_req_buf_t * buf)1231 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1232 uint32_t ch_id, mm_camera_req_buf_t *buf)
1233 {
1234 int32_t rc = -1;
1235 mm_channel_t * ch_obj =
1236 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1237
1238 if ((NULL != ch_obj) && (buf != NULL)) {
1239 pthread_mutex_lock(&ch_obj->ch_lock);
1240 pthread_mutex_unlock(&my_obj->cam_lock);
1241
1242 rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1243 (void *)buf, NULL);
1244 } else {
1245 pthread_mutex_unlock(&my_obj->cam_lock);
1246 }
1247
1248 return rc;
1249 }
1250
1251 /*===========================================================================
1252 * FUNCTION : mm_camera_cancel_super_buf_request
1253 *
1254 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1255 * of matched frames from superbuf queue
1256 *
1257 * PARAMETERS :
1258 * @my_obj : camera object
1259 * @ch_id : channel handle
1260 *
1261 * RETURN : int32_t type of status
1262 * 0 -- success
1263 * -1 -- failure
1264 *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1265 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1266 {
1267 int32_t rc = -1;
1268 mm_channel_t * ch_obj =
1269 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1270
1271 if (NULL != ch_obj) {
1272 pthread_mutex_lock(&ch_obj->ch_lock);
1273 pthread_mutex_unlock(&my_obj->cam_lock);
1274
1275 rc = mm_channel_fsm_fn(ch_obj,
1276 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1277 NULL,
1278 NULL);
1279 } else {
1280 pthread_mutex_unlock(&my_obj->cam_lock);
1281 }
1282
1283 return rc;
1284 }
1285
1286 /*===========================================================================
1287 * FUNCTION : mm_camera_flush_super_buf_queue
1288 *
1289 * DESCRIPTION: flush out all frames in the superbuf queue
1290 *
1291 * PARAMETERS :
1292 * @my_obj : camera object
1293 * @ch_id : channel handle
1294 *
1295 * RETURN : int32_t type of status
1296 * 0 -- success
1297 * -1 -- failure
1298 *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1299 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1300 uint32_t frame_idx)
1301 {
1302 int32_t rc = -1;
1303 mm_channel_t * ch_obj =
1304 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1305
1306 if (NULL != ch_obj) {
1307 pthread_mutex_lock(&ch_obj->ch_lock);
1308 pthread_mutex_unlock(&my_obj->cam_lock);
1309
1310 rc = mm_channel_fsm_fn(ch_obj,
1311 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1312 (void *)&frame_idx,
1313 NULL);
1314 } else {
1315 pthread_mutex_unlock(&my_obj->cam_lock);
1316 }
1317
1318 return rc;
1319 }
1320
1321 /*===========================================================================
1322 * FUNCTION : mm_camera_config_channel_notify
1323 *
1324 * DESCRIPTION: configures the channel notification mode
1325 *
1326 * PARAMETERS :
1327 * @my_obj : camera object
1328 * @ch_id : channel handle
1329 * @notify_mode : notification mode
1330 *
1331 * RETURN : int32_t type of status
1332 * 0 -- success
1333 * -1 -- failure
1334 *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1335 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1336 uint32_t ch_id,
1337 mm_camera_super_buf_notify_mode_t notify_mode)
1338 {
1339 int32_t rc = -1;
1340 mm_channel_t * ch_obj =
1341 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1342
1343 if (NULL != ch_obj) {
1344 pthread_mutex_lock(&ch_obj->ch_lock);
1345 pthread_mutex_unlock(&my_obj->cam_lock);
1346
1347 rc = mm_channel_fsm_fn(ch_obj,
1348 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1349 (void *)¬ify_mode,
1350 NULL);
1351 } else {
1352 pthread_mutex_unlock(&my_obj->cam_lock);
1353 }
1354
1355 return rc;
1356 }
1357
1358 /*===========================================================================
1359 * FUNCTION : mm_camera_set_stream_parms
1360 *
1361 * DESCRIPTION: set parameters per stream
1362 *
1363 * PARAMETERS :
1364 * @my_obj : camera object
1365 * @ch_id : channel handle
1366 * @s_id : stream handle
1367 * @parms : ptr to a param struct to be set to server
1368 *
1369 * RETURN : int32_t type of status
1370 * 0 -- success
1371 * -1 -- failure
1372 * NOTE : Assume the parms struct buf is already mapped to server via
1373 * domain socket. Corresponding fields of parameters to be set
1374 * are already filled in by upper layer caller.
1375 *==========================================================================*/
mm_camera_set_stream_parms(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1376 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1377 uint32_t ch_id,
1378 uint32_t s_id,
1379 cam_stream_parm_buffer_t *parms)
1380 {
1381 int32_t rc = -1;
1382 mm_evt_paylod_set_get_stream_parms_t payload;
1383 mm_channel_t * ch_obj =
1384 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1385
1386 if (NULL != ch_obj) {
1387 pthread_mutex_lock(&ch_obj->ch_lock);
1388 pthread_mutex_unlock(&my_obj->cam_lock);
1389
1390 memset(&payload, 0, sizeof(payload));
1391 payload.stream_id = s_id;
1392 payload.parms = parms;
1393
1394 rc = mm_channel_fsm_fn(ch_obj,
1395 MM_CHANNEL_EVT_SET_STREAM_PARM,
1396 (void *)&payload,
1397 NULL);
1398 } else {
1399 pthread_mutex_unlock(&my_obj->cam_lock);
1400 }
1401
1402 return rc;
1403 }
1404
1405 /*===========================================================================
1406 * FUNCTION : mm_camera_get_stream_parms
1407 *
1408 * DESCRIPTION: get parameters per stream
1409 *
1410 * PARAMETERS :
1411 * @my_obj : camera object
1412 * @ch_id : channel handle
1413 * @s_id : stream handle
1414 * @parms : ptr to a param struct to be get from server
1415 *
1416 * RETURN : int32_t type of status
1417 * 0 -- success
1418 * -1 -- failure
1419 * NOTE : Assume the parms struct buf is already mapped to server via
1420 * domain socket. Parameters to be get from server are already
1421 * filled in by upper layer caller. After this call, corresponding
1422 * fields of requested parameters will be filled in by server with
1423 * detailed information.
1424 *==========================================================================*/
mm_camera_get_stream_parms(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1425 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1426 uint32_t ch_id,
1427 uint32_t s_id,
1428 cam_stream_parm_buffer_t *parms)
1429 {
1430 int32_t rc = -1;
1431 mm_evt_paylod_set_get_stream_parms_t payload;
1432 mm_channel_t * ch_obj =
1433 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1434
1435 if (NULL != ch_obj) {
1436 pthread_mutex_lock(&ch_obj->ch_lock);
1437 pthread_mutex_unlock(&my_obj->cam_lock);
1438
1439 memset(&payload, 0, sizeof(payload));
1440 payload.stream_id = s_id;
1441 payload.parms = parms;
1442
1443 rc = mm_channel_fsm_fn(ch_obj,
1444 MM_CHANNEL_EVT_GET_STREAM_PARM,
1445 (void *)&payload,
1446 NULL);
1447 } else {
1448 pthread_mutex_unlock(&my_obj->cam_lock);
1449 }
1450
1451 return rc;
1452 }
1453
1454 /*===========================================================================
1455 * FUNCTION : mm_camera_do_stream_action
1456 *
1457 * DESCRIPTION: request server to perform stream based action. Maybe removed later
1458 * if the functionality is included in mm_camera_set_parms
1459 *
1460 * PARAMETERS :
1461 * @my_obj : camera object
1462 * @ch_id : channel handle
1463 * @s_id : stream handle
1464 * @actions : ptr to an action struct buf to be performed by server
1465 *
1466 * RETURN : int32_t type of status
1467 * 0 -- success
1468 * -1 -- failure
1469 * NOTE : Assume the action struct buf is already mapped to server via
1470 * domain socket. Actions to be performed by server are already
1471 * filled in by upper layer caller.
1472 *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1473 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1474 uint32_t ch_id,
1475 uint32_t stream_id,
1476 void *actions)
1477 {
1478 int32_t rc = -1;
1479 mm_evt_paylod_do_stream_action_t payload;
1480 mm_channel_t * ch_obj =
1481 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1482
1483 if (NULL != ch_obj) {
1484 pthread_mutex_lock(&ch_obj->ch_lock);
1485 pthread_mutex_unlock(&my_obj->cam_lock);
1486
1487 memset(&payload, 0, sizeof(payload));
1488 payload.stream_id = stream_id;
1489 payload.actions = actions;
1490
1491 rc = mm_channel_fsm_fn(ch_obj,
1492 MM_CHANNEL_EVT_DO_STREAM_ACTION,
1493 (void*)&payload,
1494 NULL);
1495 } else {
1496 pthread_mutex_unlock(&my_obj->cam_lock);
1497 }
1498
1499 return rc;
1500 }
1501
1502 /*===========================================================================
1503 * FUNCTION : mm_camera_map_stream_buf
1504 *
1505 * DESCRIPTION: mapping stream buffer via domain socket to server
1506 *
1507 * PARAMETERS :
1508 * @my_obj : camera object
1509 * @ch_id : channel handle
1510 * @s_id : stream handle
1511 * @buf_type : type of buffer to be mapped. could be following values:
1512 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1513 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1514 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1515 * @buf_idx : index of buffer within the stream buffers, only valid if
1516 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1517 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1518 * @plane_idx : plane index. If all planes share the same fd,
1519 * plane_idx = -1; otherwise, plean_idx is the
1520 * index to plane (0..num_of_planes)
1521 * @fd : file descriptor of the buffer
1522 * @size : size of the buffer
1523 *
1524 * RETURN : int32_t type of status
1525 * 0 -- success
1526 * -1 -- failure
1527 *==========================================================================*/
mm_camera_map_stream_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,size_t size)1528 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1529 uint32_t ch_id,
1530 uint32_t stream_id,
1531 uint8_t buf_type,
1532 uint32_t buf_idx,
1533 int32_t plane_idx,
1534 int fd,
1535 size_t size)
1536 {
1537 int32_t rc = -1;
1538 cam_buf_map_type payload;
1539 mm_channel_t * ch_obj =
1540 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1541
1542 if (NULL != ch_obj) {
1543 pthread_mutex_lock(&ch_obj->ch_lock);
1544 pthread_mutex_unlock(&my_obj->cam_lock);
1545
1546 memset(&payload, 0, sizeof(payload));
1547 payload.stream_id = stream_id;
1548 payload.type = buf_type;
1549 payload.frame_idx = buf_idx;
1550 payload.plane_idx = plane_idx;
1551 payload.fd = fd;
1552 payload.size = size;
1553 rc = mm_channel_fsm_fn(ch_obj,
1554 MM_CHANNEL_EVT_MAP_STREAM_BUF,
1555 (void*)&payload,
1556 NULL);
1557 } else {
1558 pthread_mutex_unlock(&my_obj->cam_lock);
1559 }
1560
1561 return rc;
1562 }
1563
1564 /*===========================================================================
1565 * FUNCTION : mm_camera_map_stream_bufs
1566 *
1567 * DESCRIPTION: mapping stream buffers via domain socket to server
1568 *
1569 * PARAMETERS :
1570 * @my_obj : camera object
1571 * @ch_id : channel handle
1572 * @buf_map_list : list of buffers to be mapped
1573 *
1574 * RETURN : int32_t type of status
1575 * 0 -- success
1576 * -1 -- failure
1577 *==========================================================================*/
mm_camera_map_stream_bufs(mm_camera_obj_t * my_obj,uint32_t ch_id,const cam_buf_map_type_list * buf_map_list)1578 int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj,
1579 uint32_t ch_id,
1580 const cam_buf_map_type_list *buf_map_list)
1581 {
1582 int32_t rc = -1;
1583 cam_buf_map_type_list payload;
1584 mm_channel_t * ch_obj =
1585 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1586
1587 if (NULL != ch_obj) {
1588 pthread_mutex_lock(&ch_obj->ch_lock);
1589 pthread_mutex_unlock(&my_obj->cam_lock);
1590
1591 memcpy(&payload, buf_map_list, sizeof(payload));
1592 rc = mm_channel_fsm_fn(ch_obj,
1593 MM_CHANNEL_EVT_MAP_STREAM_BUFS,
1594 (void*)&payload,
1595 NULL);
1596 } else {
1597 pthread_mutex_unlock(&my_obj->cam_lock);
1598 }
1599
1600 return rc;
1601 }
1602
1603 /*===========================================================================
1604 * FUNCTION : mm_camera_unmap_stream_buf
1605 *
1606 * DESCRIPTION: unmapping stream buffer via domain socket to server
1607 *
1608 * PARAMETERS :
1609 * @my_obj : camera object
1610 * @ch_id : channel handle
1611 * @s_id : stream handle
1612 * @buf_type : type of buffer to be mapped. could be following values:
1613 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1614 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1615 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1616 * @buf_idx : index of buffer within the stream buffers, only valid if
1617 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1618 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1619 * @plane_idx : plane index. If all planes share the same fd,
1620 * plane_idx = -1; otherwise, plean_idx is the
1621 * index to plane (0..num_of_planes)
1622 *
1623 * RETURN : int32_t type of status
1624 * 0 -- success
1625 * -1 -- failure
1626 *==========================================================================*/
mm_camera_unmap_stream_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)1627 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1628 uint32_t ch_id,
1629 uint32_t stream_id,
1630 uint8_t buf_type,
1631 uint32_t buf_idx,
1632 int32_t plane_idx)
1633 {
1634 int32_t rc = -1;
1635 cam_buf_unmap_type payload;
1636 mm_channel_t * ch_obj =
1637 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1638
1639 if (NULL != ch_obj) {
1640 pthread_mutex_lock(&ch_obj->ch_lock);
1641 pthread_mutex_unlock(&my_obj->cam_lock);
1642
1643 memset(&payload, 0, sizeof(payload));
1644 payload.stream_id = stream_id;
1645 payload.type = buf_type;
1646 payload.frame_idx = buf_idx;
1647 payload.plane_idx = plane_idx;
1648 rc = mm_channel_fsm_fn(ch_obj,
1649 MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1650 (void*)&payload,
1651 NULL);
1652 } else {
1653 pthread_mutex_unlock(&my_obj->cam_lock);
1654 }
1655
1656 return rc;
1657 }
1658
1659 /*===========================================================================
1660 * FUNCTION : mm_camera_evt_sub
1661 *
1662 * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1663 *
1664 * PARAMETERS :
1665 * @my_obj : camera object
1666 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe
1667 *
1668 * RETURN : int32_t type of status
1669 * 0 -- success
1670 * -1 -- failure
1671 *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1672 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1673 uint8_t reg_flag)
1674 {
1675 int32_t rc = 0;
1676 struct v4l2_event_subscription sub;
1677
1678 memset(&sub, 0, sizeof(sub));
1679 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1680 sub.id = MSM_CAMERA_MSM_NOTIFY;
1681 if(FALSE == reg_flag) {
1682 /* unsubscribe */
1683 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1684 if (rc < 0) {
1685 LOGE("unsubscribe event rc = %d, errno %d",
1686 rc, errno);
1687 return rc;
1688 }
1689 /* remove evt fd from the polling thraed when unreg the last event */
1690 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1691 my_obj->my_hdl,
1692 mm_camera_sync_call);
1693 } else {
1694 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1695 if (rc < 0) {
1696 LOGE("subscribe event rc = %d, errno %d",
1697 rc, errno);
1698 return rc;
1699 }
1700 /* add evt fd to polling thread when subscribe the first event */
1701 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1702 my_obj->my_hdl,
1703 my_obj->ctrl_fd,
1704 mm_camera_event_notify,
1705 (void*)my_obj,
1706 mm_camera_sync_call);
1707 }
1708 return rc;
1709 }
1710
1711 /*===========================================================================
1712 * FUNCTION : mm_camera_util_wait_for_event
1713 *
1714 * DESCRIPTION: utility function to wait for certain events
1715 *
1716 * PARAMETERS :
1717 * @my_obj : camera object
1718 * @evt_mask : mask for events to be waited. Any of event in the mask would
1719 * trigger the wait to end
1720 * @status : status of the event
1721 *
1722 * RETURN : none
1723 *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,uint32_t * status)1724 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1725 uint32_t evt_mask,
1726 uint32_t *status)
1727 {
1728 int32_t rc = 0;
1729 struct timespec ts;
1730
1731 pthread_mutex_lock(&my_obj->evt_lock);
1732 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1733 clock_gettime(CLOCK_REALTIME, &ts);
1734 ts.tv_sec += WAIT_TIMEOUT;
1735 rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts);
1736 if (rc) {
1737 LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d",
1738 evt_mask, rc);
1739 break;
1740 }
1741 }
1742 if (!rc) {
1743 *status = my_obj->evt_rcvd.status;
1744 } else {
1745 *status = MSM_CAMERA_STATUS_FAIL;
1746 }
1747 /* reset local storage for recieved event for next event */
1748 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1749 pthread_mutex_unlock(&my_obj->evt_lock);
1750 }
1751
1752 /*===========================================================================
1753 * FUNCTION : mm_camera_util_bundled_sendmsg
1754 *
1755 * DESCRIPTION: utility function to send bundled msg via domain socket
1756 *
1757 * PARAMETERS :
1758 * @my_obj : camera object
1759 * @msg : message to be sent
1760 * @buf_size : size of the message to be sent
1761 * @sendfds : array of file descriptors to be sent
1762 * @numfds : number of file descriptors to be sent
1763 *
1764 * RETURN : int32_t type of status
1765 * 0 -- success
1766 * -1 -- failure
1767 *==========================================================================*/
mm_camera_util_bundled_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],int numfds)1768 int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj,
1769 void *msg,
1770 size_t buf_size,
1771 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
1772 int numfds)
1773 {
1774 int32_t rc = -1;
1775 uint32_t status;
1776
1777 /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/
1778 pthread_mutex_lock(&my_obj->msg_lock);
1779 if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) {
1780 /* wait for event that mapping/unmapping is done */
1781 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1782 if (MSM_CAMERA_STATUS_SUCCESS == status) {
1783 rc = 0;
1784 }
1785 }
1786 pthread_mutex_unlock(&my_obj->msg_lock);
1787 return rc;
1788 }
1789
1790 /*===========================================================================
1791 * FUNCTION : mm_camera_util_sendmsg
1792 *
1793 * DESCRIPTION: utility function to send msg via domain socket
1794 *
1795 * PARAMETERS :
1796 * @my_obj : camera object
1797 * @msg : message to be sent
1798 * @buf_size : size of the message to be sent
1799 * @sendfd : >0 if any file descriptor need to be passed across process
1800 *
1801 * RETURN : int32_t type of status
1802 * 0 -- success
1803 * -1 -- failure
1804 *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfd)1805 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1806 void *msg,
1807 size_t buf_size,
1808 int sendfd)
1809 {
1810 int32_t rc = -1;
1811 uint32_t status;
1812
1813 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1814 pthread_mutex_lock(&my_obj->msg_lock);
1815 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1816 /* wait for event that mapping/unmapping is done */
1817 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1818 if (MSM_CAMERA_STATUS_SUCCESS == status) {
1819 rc = 0;
1820 }
1821 }
1822 pthread_mutex_unlock(&my_obj->msg_lock);
1823 return rc;
1824 }
1825
1826 /*===========================================================================
1827 * FUNCTION : mm_camera_map_buf
1828 *
1829 * DESCRIPTION: mapping camera buffer via domain socket to server
1830 *
1831 * PARAMETERS :
1832 * @my_obj : camera object
1833 * @buf_type : type of buffer to be mapped. could be following values:
1834 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1835 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1836 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1837 * @fd : file descriptor of the buffer
1838 * @size : size of the buffer
1839 *
1840 * RETURN : int32_t type of status
1841 * 0 -- success
1842 * -1 -- failure
1843 *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,size_t size)1844 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1845 uint8_t buf_type,
1846 int fd,
1847 size_t size)
1848 {
1849 int32_t rc = 0;
1850 cam_sock_packet_t packet;
1851 memset(&packet, 0, sizeof(cam_sock_packet_t));
1852 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1853 packet.payload.buf_map.type = buf_type;
1854 packet.payload.buf_map.fd = fd;
1855 packet.payload.buf_map.size = size;
1856 rc = mm_camera_util_sendmsg(my_obj,
1857 &packet,
1858 sizeof(cam_sock_packet_t),
1859 fd);
1860 pthread_mutex_unlock(&my_obj->cam_lock);
1861 return rc;
1862 }
1863
1864 /*===========================================================================
1865 * FUNCTION : mm_camera_map_bufs
1866 *
1867 * DESCRIPTION: mapping camera buffers via domain socket to server
1868 *
1869 * PARAMETERS :
1870 * @my_obj : camera object
1871 * @buf_map_list : list of buffers to be mapped
1872 *
1873 * RETURN : int32_t type of status
1874 * 0 -- success
1875 * -1 -- failure
1876 *==========================================================================*/
mm_camera_map_bufs(mm_camera_obj_t * my_obj,const cam_buf_map_type_list * buf_map_list)1877 int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj,
1878 const cam_buf_map_type_list* buf_map_list)
1879 {
1880 int32_t rc = 0;
1881 cam_sock_packet_t packet;
1882 memset(&packet, 0, sizeof(cam_sock_packet_t));
1883 packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING;
1884
1885 memcpy(&packet.payload.buf_map_list, buf_map_list,
1886 sizeof(packet.payload.buf_map_list));
1887
1888 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM];
1889 uint32_t numbufs = packet.payload.buf_map_list.length;
1890 uint32_t i;
1891 for (i = 0; i < numbufs; i++) {
1892 sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd;
1893 }
1894
1895 for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) {
1896 packet.payload.buf_map_list.buf_maps[i].fd = -1;
1897 sendfds[i] = -1;
1898 }
1899
1900 rc = mm_camera_util_bundled_sendmsg(my_obj,
1901 &packet,
1902 sizeof(cam_sock_packet_t),
1903 sendfds,
1904 numbufs);
1905
1906 pthread_mutex_unlock(&my_obj->cam_lock);
1907 return rc;
1908 }
1909
1910 /*===========================================================================
1911 * FUNCTION : mm_camera_unmap_buf
1912 *
1913 * DESCRIPTION: unmapping camera buffer via domain socket to server
1914 *
1915 * PARAMETERS :
1916 * @my_obj : camera object
1917 * @buf_type : type of buffer to be mapped. could be following values:
1918 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1919 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1920 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1921 *
1922 * RETURN : int32_t type of status
1923 * 0 -- success
1924 * -1 -- failure
1925 *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)1926 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1927 uint8_t buf_type)
1928 {
1929 int32_t rc = 0;
1930 cam_sock_packet_t packet;
1931 memset(&packet, 0, sizeof(cam_sock_packet_t));
1932 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
1933 packet.payload.buf_unmap.type = buf_type;
1934 rc = mm_camera_util_sendmsg(my_obj,
1935 &packet,
1936 sizeof(cam_sock_packet_t),
1937 -1);
1938 pthread_mutex_unlock(&my_obj->cam_lock);
1939 return rc;
1940 }
1941
1942 /*===========================================================================
1943 * FUNCTION : mm_camera_util_s_ctrl
1944 *
1945 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
1946 *
1947 * PARAMETERS :
1948 * @fd : file descritpor for sending ioctl
1949 * @id : control id
1950 * @value : value of the ioctl to be sent
1951 *
1952 * RETURN : int32_t type of status
1953 * 0 -- success
1954 * -1 -- failure
1955 *==========================================================================*/
mm_camera_util_s_ctrl(int32_t fd,uint32_t id,int32_t * value)1956 int32_t mm_camera_util_s_ctrl(int32_t fd, uint32_t id, int32_t *value)
1957 {
1958 int rc = 0;
1959 struct v4l2_control control;
1960
1961 memset(&control, 0, sizeof(control));
1962 control.id = id;
1963 if (value != NULL) {
1964 control.value = *value;
1965 }
1966 rc = ioctl(fd, VIDIOC_S_CTRL, &control);
1967
1968 LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n",
1969 fd, id, value, rc);
1970 if (rc < 0) {
1971 LOGE("ioctl failed %d, errno %d", rc, errno);
1972 } else if (value != NULL) {
1973 *value = control.value;
1974 }
1975 return (rc >= 0)? 0 : -1;
1976 }
1977
1978 /*===========================================================================
1979 * FUNCTION : mm_camera_util_g_ctrl
1980 *
1981 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
1982 *
1983 * PARAMETERS :
1984 * @fd : file descritpor for sending ioctl
1985 * @id : control id
1986 * @value : value of the ioctl to be sent
1987 *
1988 * RETURN : int32_t type of status
1989 * 0 -- success
1990 * -1 -- failure
1991 *==========================================================================*/
mm_camera_util_g_ctrl(int32_t fd,uint32_t id,int32_t * value)1992 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1993 {
1994 int rc = 0;
1995 struct v4l2_control control;
1996
1997 memset(&control, 0, sizeof(control));
1998 control.id = id;
1999 if (value != NULL) {
2000 control.value = *value;
2001 }
2002 rc = ioctl(fd, VIDIOC_G_CTRL, &control);
2003 LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc);
2004 if (value != NULL) {
2005 *value = control.value;
2006 }
2007 return (rc >= 0)? 0 : -1;
2008 }
2009
2010 /*===========================================================================
2011 * FUNCTION : mm_camera_channel_advanced_capture
2012 *
2013 * DESCRIPTION: sets the channel advanced capture
2014 *
2015 * PARAMETERS :
2016 * @my_obj : camera object
2017 * @ch_id : channel handle
2018 * @type : advanced capture type.
2019 * @start_flag : flag to indicate start/stop
2020 * @in_value : input configaration
2021 *
2022 * RETURN : int32_t type of status
2023 * 0 -- success
2024 * -1 -- failure
2025 *==========================================================================*/
mm_camera_channel_advanced_capture(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_advanced_capture_t type,uint32_t trigger,void * in_value)2026 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
2027 uint32_t ch_id, mm_camera_advanced_capture_t type,
2028 uint32_t trigger, void *in_value)
2029 {
2030 LOGD("E type = %d", type);
2031 int32_t rc = -1;
2032 mm_channel_t * ch_obj =
2033 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2034
2035 if (NULL != ch_obj) {
2036 pthread_mutex_lock(&ch_obj->ch_lock);
2037 pthread_mutex_unlock(&my_obj->cam_lock);
2038 switch (type) {
2039 case MM_CAMERA_AF_BRACKETING:
2040 rc = mm_channel_fsm_fn(ch_obj,
2041 MM_CHANNEL_EVT_AF_BRACKETING,
2042 (void *)&trigger,
2043 NULL);
2044 break;
2045 case MM_CAMERA_AE_BRACKETING:
2046 rc = mm_channel_fsm_fn(ch_obj,
2047 MM_CHANNEL_EVT_AE_BRACKETING,
2048 (void *)&trigger,
2049 NULL);
2050 break;
2051 case MM_CAMERA_FLASH_BRACKETING:
2052 rc = mm_channel_fsm_fn(ch_obj,
2053 MM_CHANNEL_EVT_FLASH_BRACKETING,
2054 (void *)&trigger,
2055 NULL);
2056 break;
2057 case MM_CAMERA_ZOOM_1X:
2058 rc = mm_channel_fsm_fn(ch_obj,
2059 MM_CHANNEL_EVT_ZOOM_1X,
2060 (void *)&trigger,
2061 NULL);
2062 break;
2063 case MM_CAMERA_FRAME_CAPTURE:
2064 rc = mm_channel_fsm_fn(ch_obj,
2065 MM_CAMERA_EVT_CAPTURE_SETTING,
2066 (void *)in_value,
2067 NULL);
2068 break;
2069 default:
2070 break;
2071 }
2072
2073 } else {
2074 pthread_mutex_unlock(&my_obj->cam_lock);
2075 }
2076
2077 LOGD("X");
2078 return rc;
2079 }
2080
2081 /*===========================================================================
2082 * FUNCTION : mm_camera_get_session_id
2083 *
2084 * DESCRIPTION: get the session identity
2085 *
2086 * PARAMETERS :
2087 * @my_obj : camera object
2088 * @sessionid: pointer to the output session id
2089 *
2090 * RETURN : int32_t type of status
2091 * 0 -- success
2092 * -1 -- failure
2093 * NOTE : if this call succeeds, we will get a valid session id
2094 *==========================================================================*/
mm_camera_get_session_id(mm_camera_obj_t * my_obj,uint32_t * sessionid)2095 int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj,
2096 uint32_t* sessionid)
2097 {
2098 int32_t rc = -1;
2099 int32_t value = 0;
2100 if(sessionid != NULL) {
2101 rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd,
2102 MSM_CAMERA_PRIV_G_SESSION_ID, &value);
2103 LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n",
2104 my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID,
2105 value, rc);
2106 *sessionid = value;
2107 my_obj->sessionid = value;
2108 }
2109
2110 pthread_mutex_unlock(&my_obj->cam_lock);
2111 return rc;
2112 }
2113
2114 /*===========================================================================
2115 * FUNCTION : mm_camera_sync_related_sensors
2116 *
2117 * DESCRIPTION: send sync cmd
2118 *
2119 * PARAMETERS :
2120 * @my_obj : camera object
2121 * @parms : ptr to the related cam info to be sent to server
2122 *
2123 * RETURN : int32_t type of status
2124 * 0 -- success
2125 * -1 -- failure
2126 * NOTE : Assume the sync struct buf is already mapped to server via
2127 * domain socket. Corresponding fields of parameters to be set
2128 * are already filled in by upper layer caller.
2129 *==========================================================================*/
mm_camera_sync_related_sensors(mm_camera_obj_t * my_obj,cam_sync_related_sensors_event_info_t * parms)2130 int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj,
2131 cam_sync_related_sensors_event_info_t* parms)
2132 {
2133 int32_t rc = -1;
2134 int32_t value = 0;
2135 if (parms != NULL) {
2136 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
2137 CAM_PRIV_SYNC_RELATED_SENSORS, &value);
2138 }
2139 pthread_mutex_unlock(&my_obj->cam_lock);
2140 return rc;
2141 }
2142
2143 /*===========================================================================
2144 * FUNCTION : mm_camera_reg_stream_buf_cb
2145 *
2146 * DESCRIPTION: Register callback for stream buffer
2147 *
2148 * PARAMETERS :
2149 * @my_obj : camera object
2150 * @ch_id : channel handle
2151 * @stream_id : stream that will be linked
2152 * @buf_cb : special callback needs to be registered for stream buffer
2153 * @cb_type : Callback type SYNC/ASYNC
2154 * @userdata : user data pointer
2155 *
2156 * RETURN : int32_t type of status
2157 * 0 -- success
2158 * 1 -- failure
2159 *==========================================================================*/
mm_camera_reg_stream_buf_cb(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_buf_notify_t stream_cb,mm_camera_stream_cb_type cb_type,void * userdata)2160 int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
2161 uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb,
2162 mm_camera_stream_cb_type cb_type, void *userdata)
2163 {
2164 int rc = 0;
2165 mm_stream_data_cb_t buf_cb;
2166 mm_channel_t * ch_obj =
2167 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2168
2169 if (NULL != ch_obj) {
2170 pthread_mutex_lock(&ch_obj->ch_lock);
2171 pthread_mutex_unlock(&my_obj->cam_lock);
2172
2173 memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t));
2174 buf_cb.cb = stream_cb;
2175 buf_cb.cb_count = -1;
2176 buf_cb.cb_type = cb_type;
2177 buf_cb.user_data = userdata;
2178
2179 mm_evt_paylod_reg_stream_buf_cb payload;
2180 memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb));
2181 payload.buf_cb = buf_cb;
2182 payload.stream_id = stream_id;
2183 mm_channel_fsm_fn(ch_obj,
2184 MM_CHANNEL_EVT_REG_STREAM_BUF_CB,
2185 (void*)&payload, NULL);
2186 } else {
2187 pthread_mutex_unlock(&my_obj->cam_lock);
2188 }
2189 return rc;
2190 }
2191
2192 #ifdef QCAMERA_REDEFINE_LOG
2193
2194 /*===========================================================================
2195 * DESCRIPTION: mm camera debug interface
2196 *
2197 *==========================================================================*/
2198 pthread_mutex_t dbg_log_mutex;
2199
2200 #undef LOG_TAG
2201 #define LOG_TAG "QCamera"
2202 #define CDBG_MAX_STR_LEN 1024
2203 #define CDBG_MAX_LINE_LENGTH 256
2204
2205 /* current trace loggin permissions
2206 * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */
2207 int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = {
2208 {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE */
2209 {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE */
2210 {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE */
2211 {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE */
2212 };
2213
2214 /* string representation for logging level */
2215 static const char *cam_dbg_level_to_str[] = {
2216 "", /* CAM_GLBL_DBG_NONE */
2217 "<ERROR>", /* CAM_GLBL_DBG_ERR */
2218 "<WARN>", /* CAM_GLBL_DBG_WARN */
2219 "<HIGH>", /* CAM_GLBL_DBG_HIGH */
2220 "<DBG>", /* CAM_GLBL_DBG_DEBUG */
2221 "<LOW>", /* CAM_GLBL_DBG_LOW */
2222 "<INFO>" /* CAM_GLBL_DBG_INFO */
2223 };
2224
2225 /* current trace logging configuration */
2226 typedef struct {
2227 cam_global_debug_level_t level;
2228 int initialized;
2229 const char *name;
2230 const char *prop;
2231 } module_debug_t;
2232
2233 static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = {
2234 {CAM_GLBL_DBG_ERR, 1,
2235 "", "persist.camera.global.debug" }, /* CAM_NO_MODULE */
2236 {CAM_GLBL_DBG_ERR, 1,
2237 "<HAL>", "persist.camera.hal.debug" }, /* CAM_HAL_MODULE */
2238 {CAM_GLBL_DBG_ERR, 1,
2239 "<MCI>", "persist.camera.mci.debug" }, /* CAM_MCI_MODULE */
2240 {CAM_GLBL_DBG_ERR, 1,
2241 "<JPEG>", "persist.camera.mmstill.logs" }, /* CAM_JPEG_MODULE */
2242 };
2243
2244 /** cam_get_dbg_level
2245 *
2246 * @module: module name
2247 * @level: module debug logging level
2248 *
2249 * Maps debug log string to value.
2250 *
2251 * Return: logging level
2252 **/
2253 __unused
cam_get_dbg_level(const char * module,char * pValue)2254 static cam_global_debug_level_t cam_get_dbg_level(const char *module,
2255 char *pValue) {
2256
2257 cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE;
2258
2259 if (!strcmp(pValue, "none")) {
2260 rc = CAM_GLBL_DBG_NONE;
2261 } else if (!strcmp(pValue, "warn")) {
2262 rc = CAM_GLBL_DBG_WARN;
2263 } else if (!strcmp(pValue, "debug")) {
2264 rc = CAM_GLBL_DBG_DEBUG;
2265 } else if (!strcmp(pValue, "error")) {
2266 rc = CAM_GLBL_DBG_ERR;
2267 } else if (!strcmp(pValue, "low")) {
2268 rc = CAM_GLBL_DBG_LOW;
2269 } else if (!strcmp(pValue, "high")) {
2270 rc = CAM_GLBL_DBG_HIGH;
2271 } else if (!strcmp(pValue, "info")) {
2272 rc = CAM_GLBL_DBG_INFO;
2273 } else {
2274 ALOGE("Invalid %s debug log level %s\n", module, pValue);
2275 }
2276
2277 ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]);
2278
2279 return rc;
2280 }
2281
2282 /** cam_vsnprintf
2283 * @pdst: destination buffer pointer
2284 * @size: size of destination b uffer
2285 * @pfmt: string format
2286 * @argptr: variabkle length argument list
2287 *
2288 * Processes variable length argument list to a formatted string.
2289 *
2290 * Return: n/a
2291 **/
cam_vsnprintf(char * pdst,unsigned int size,const char * pfmt,va_list argptr)2292 static void cam_vsnprintf(char* pdst, unsigned int size,
2293 const char* pfmt, va_list argptr) {
2294 int num_chars_written = 0;
2295
2296 pdst[0] = '\0';
2297 num_chars_written = vsnprintf(pdst, size, pfmt, argptr);
2298
2299 if ((num_chars_written >= (int)size) && (size > 0)) {
2300 /* Message length exceeds the buffer limit size */
2301 num_chars_written = size - 1;
2302 pdst[size - 1] = '\0';
2303 }
2304 }
2305
2306 /** mm_camera_debug_log
2307 * @module: origin or log message
2308 * @level: logging level
2309 * @func: caller function name
2310 * @line: caller line number
2311 * @fmt: log message formatting string
2312 * @...: variable argument list
2313 *
2314 * Generig logger method.
2315 *
2316 * Return: N/A
2317 **/
mm_camera_debug_log(const cam_modules_t module,const cam_global_debug_level_t level,const char * func,const int line,const char * fmt,...)2318 void mm_camera_debug_log(const cam_modules_t module,
2319 const cam_global_debug_level_t level,
2320 const char *func, const int line, const char *fmt, ...) {
2321 char str_buffer[CDBG_MAX_STR_LEN];
2322 va_list args;
2323
2324 va_start(args, fmt);
2325 cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args);
2326 va_end(args);
2327
2328 switch (level) {
2329 case CAM_GLBL_DBG_WARN:
2330 ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name,
2331 cam_dbg_level_to_str[level], func, line, str_buffer);
2332 break;
2333 case CAM_GLBL_DBG_ERR:
2334 ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name,
2335 cam_dbg_level_to_str[level], func, line, str_buffer);
2336 break;
2337 case CAM_GLBL_DBG_INFO:
2338 ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name,
2339 cam_dbg_level_to_str[level], func, line, str_buffer);
2340 break;
2341 case CAM_GLBL_DBG_HIGH:
2342 case CAM_GLBL_DBG_DEBUG:
2343 case CAM_GLBL_DBG_LOW:
2344 default:
2345 ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name,
2346 cam_dbg_level_to_str[level], func, line, str_buffer);
2347 }
2348 }
2349
2350 /** mm_camera_set_dbg_log_properties
2351 *
2352 * Set global and module log level properties.
2353 *
2354 * Return: N/A
2355 **/
mm_camera_set_dbg_log_properties(void)2356 void mm_camera_set_dbg_log_properties(void) {
2357 int i;
2358 unsigned int j;
2359 static int boot_init = 1;
2360 char property_value[PROPERTY_VALUE_MAX] = {0};
2361 char default_value[PROPERTY_VALUE_MAX] = {0};
2362
2363 if (boot_init) {
2364 boot_init = 0;
2365 pthread_mutex_init(&dbg_log_mutex, 0);
2366 }
2367
2368 /* set global and individual module logging levels */
2369 pthread_mutex_lock(&dbg_log_mutex);
2370 for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) {
2371 cam_global_debug_level_t log_level;
2372 snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level);
2373 property_get(cam_loginfo[i].prop, property_value, default_value);
2374 log_level = (cam_global_debug_level_t)atoi(property_value);
2375
2376 /* fix KW warnings */
2377 if (log_level > CAM_GLBL_DBG_INFO) {
2378 log_level = CAM_GLBL_DBG_INFO;
2379 }
2380
2381 cam_loginfo[i].level = log_level;
2382
2383 /* The logging macros will produce a log message when logging level for
2384 * a module is less or equal to the level specified in the property for
2385 * the module, or less or equal the level specified by the global logging
2386 * property. Currently we don't allow INFO logging to be turned off */
2387 for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) {
2388 g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE) &&
2389 (cam_loginfo[i].level != CAM_GLBL_DBG_NONE) &&
2390 ((j <= cam_loginfo[i].level) ||
2391 (j <= cam_loginfo[CAM_NO_MODULE].level));
2392 }
2393 }
2394 pthread_mutex_unlock(&dbg_log_mutex);
2395 }
2396
2397 #endif
2398