1/* Copyright (c) 2012-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#include <linux/media.h>
39#include <media/msm_cam_sensor.h>
40#include <dlfcn.h>
41
42#define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
43#include IOCTL_H
44
45// Camera dependencies
46#include "mm_camera_dbg.h"
47#include "mm_camera_interface.h"
48#include "mm_camera.h"
49#include "mm_camera_muxer.h"
50
51static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
52static mm_camera_ctrl_t g_cam_ctrl;
53
54static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
55static uint8_t g_handler_history_count = 0; /* history count for handler */
56
57// 16th (starting from 0) bit tells its a BACK or FRONT camera
58#define CAM_SENSOR_FACING_MASK       (1U<<16)
59#define CAM_SENSOR_TYPE_MASK         (1U<<24)
60#define CAM_SENSOR_FORMAT_MASK       (1U<<25)
61
62/*===========================================================================
63 * FUNCTION   : mm_camera_util_generate_handler
64 *
65 * DESCRIPTION: utility function to generate handler for camera/channel/stream
66 *
67 * PARAMETERS :
68 *   @index: index of the object to have handler
69 *
70 * RETURN     : uint32_t type of handle that uniquely identify the object
71 *==========================================================================*/
72uint32_t mm_camera_util_generate_handler(uint8_t index)
73{
74    uint32_t handler = 0;
75    pthread_mutex_lock(&g_handler_lock);
76    g_handler_history_count++;
77    if (0 == g_handler_history_count) {
78        g_handler_history_count++;
79    }
80    handler = g_handler_history_count;
81    handler = (handler<<8) | index;
82    pthread_mutex_unlock(&g_handler_lock);
83    return handler;
84}
85
86/*===========================================================================
87 * FUNCTION   : mm_camera_util_get_index_by_handler
88 *
89 * DESCRIPTION: utility function to get index from handle
90 *
91 * PARAMETERS :
92 *   @handler: object handle
93 *
94 * RETURN     : uint8_t type of index derived from handle
95 *==========================================================================*/
96uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
97{
98    return (handler & 0x000000ff);
99}
100
101/*===========================================================================
102 * FUNCTION   : mm_camera_util_get_dev_name
103 *
104 * DESCRIPTION: utility function to get device name from camera handle
105 *
106 * PARAMETERS :
107 *   @cam_handle: camera handle
108 *
109 * RETURN     : char ptr to the device name stored in global variable
110 * NOTE       : caller should not free the char ptr
111 *==========================================================================*/
112const char *mm_camera_util_get_dev_name(uint32_t cam_handle)
113{
114    char *dev_name = NULL;
115    uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
116    if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
117        dev_name = g_cam_ctrl.video_dev_name[cam_idx];
118    }
119    return dev_name;
120}
121
122/*===========================================================================
123 * FUNCTION   : mm_camera_util_get_camera_by_handler
124 *
125 * DESCRIPTION: utility function to get camera object from camera handle
126 *
127 * PARAMETERS :
128 *   @cam_handle: camera handle
129 *
130 * RETURN     : ptr to the camera object stored in global variable
131 * NOTE       : caller should not free the camera object ptr
132 *==========================================================================*/
133mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
134{
135    mm_camera_obj_t *cam_obj = NULL;
136    uint8_t cam_idx = 0;
137
138    for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) {
139         if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
140                (cam_handle == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
141            cam_obj = g_cam_ctrl.cam_obj[cam_idx];
142            break;
143        }
144    }
145    return cam_obj;
146}
147
148
149/*===========================================================================
150 * FUNCTION   : mm_camera_util_set_camera_object
151 *
152 * DESCRIPTION: utility function to set camera object to global structure
153 *
154 * PARAMETERS :
155 *   @cam_idx : index to store cambera object
156 *   @obj     : Camera object to store
157 *
158 * RETURN     : int32_t type of status
159 *              0  -- success
160 *              -1 -- failure
161 *==========================================================================*/
162int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj)
163{
164    int32_t rc = 0;
165    pthread_mutex_lock(&g_intf_lock);
166    if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
167        g_cam_ctrl.cam_obj[cam_idx] = obj;
168    } else {
169        rc = -1;
170    }
171    pthread_mutex_unlock(&g_intf_lock);
172    return rc;
173}
174
175/*===========================================================================
176 * FUNCTION   : mm_camera_util_get_camera_head_obj
177 *
178 * DESCRIPTION: utility function to get camera object from camera handle
179 *
180 * PARAMETERS :
181 *   @cam_handle: camera handle
182 *
183 * RETURN     : ptr to the master/primary camera object
184 *==========================================================================*/
185mm_camera_obj_t* mm_camera_util_get_camera_head(uint32_t cam_handle)
186{
187    mm_camera_obj_t *cam_obj = NULL;
188
189    cam_obj = mm_camera_util_get_camera_by_handler(cam_handle);
190    if (cam_obj != NULL && cam_obj->master_cam_obj != NULL) {
191        cam_obj = cam_obj->master_cam_obj;
192    }
193    return cam_obj;
194}
195
196/*===========================================================================
197 * FUNCTION   : mm_camera_util_get_camera_by_session_id
198 *
199 * DESCRIPTION: utility function to get camera object from camera sessionID
200 *
201 * PARAMETERS :
202 *   @session_id: sessionid for which cam obj mapped
203 *
204 * RETURN     : ptr to the camera object stored in global variable
205 * NOTE       : caller should not free the camera object ptr
206 *==========================================================================*/
207mm_camera_obj_t* mm_camera_util_get_camera_by_session_id(uint32_t session_id)
208{
209   int cam_idx = 0;
210   mm_camera_obj_t *cam_obj = NULL;
211   for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) {
212        if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
213                (session_id == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->sessionid)) {
214            LOGD("session id:%d match idx:%d\n", session_id, cam_idx);
215            cam_obj = g_cam_ctrl.cam_obj[cam_idx];
216        }
217    }
218    return cam_obj;
219}
220
221/*===========================================================================
222 * FUNCTION   : mm_camera_intf_query_capability
223 *
224 * DESCRIPTION: query camera capability
225 *
226 * PARAMETERS :
227 *   @camera_handle: camera handle
228 *
229 * RETURN     : int32_t type of status
230 *              0  -- success
231 *              -1 -- failure
232 *==========================================================================*/
233static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
234{
235    int32_t rc = -1;
236    mm_camera_obj_t *my_obj = NULL;
237    uint32_t handle = 0;
238    uint32_t aux_handle = 0;
239
240    LOGD("E: camera_handler = %d ", camera_handle);
241
242    pthread_mutex_lock(&g_intf_lock);
243    handle = get_main_camera_handle(camera_handle);
244    aux_handle = get_aux_camera_handle(camera_handle);
245
246    if (handle) {
247        my_obj = mm_camera_util_get_camera_by_handler(handle);
248
249        if(my_obj) {
250            pthread_mutex_lock(&my_obj->cam_lock);
251            pthread_mutex_unlock(&g_intf_lock);
252            rc = mm_camera_query_capability(my_obj);
253        } else {
254            pthread_mutex_unlock(&g_intf_lock);
255        }
256    } else {
257        pthread_mutex_unlock(&g_intf_lock);
258    }
259
260    if (aux_handle) {
261        pthread_mutex_lock(&g_intf_lock);
262        my_obj = mm_camera_util_get_camera_head(aux_handle);
263        if (my_obj) {
264            pthread_mutex_lock(&my_obj->muxer_lock);
265            pthread_mutex_unlock(&g_intf_lock);
266            rc = mm_camera_muxer_query_capability(aux_handle, my_obj);
267        } else {
268            pthread_mutex_unlock(&g_intf_lock);
269        }
270    }
271
272    LOGH("camera_handle = %u rc = %u X", camera_handle, rc);
273    return rc;
274}
275
276/*===========================================================================
277 * FUNCTION   : mm_camera_intf_set_parms
278 *
279 * DESCRIPTION: set parameters per camera
280 *
281 * PARAMETERS :
282 *   @camera_handle: camera handle
283 *   @parms        : ptr to a param struct to be set to server
284 *
285 * RETURN     : int32_t type of status
286 *              0  -- success
287 *              -1 -- failure
288 * NOTE       : Assume the parms struct buf is already mapped to server via
289 *              domain socket. Corresponding fields of parameters to be set
290 *              are already filled in by upper layer caller.
291 *==========================================================================*/
292static int32_t mm_camera_intf_set_parms(uint32_t camera_handle,
293                                        parm_buffer_t *parms)
294{
295    int32_t rc = -1;
296    mm_camera_obj_t * my_obj = NULL;
297
298    uint32_t handle = get_main_camera_handle(camera_handle);
299    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
300
301    if (aux_handle) {
302        pthread_mutex_lock(&g_intf_lock);
303        my_obj = mm_camera_util_get_camera_head(aux_handle);
304        if (my_obj) {
305            pthread_mutex_lock(&my_obj->muxer_lock);
306            pthread_mutex_unlock(&g_intf_lock);
307            rc = mm_camera_muxer_set_parms(aux_handle,
308                    parms, my_obj);
309        } else {
310            pthread_mutex_unlock(&g_intf_lock);
311        }
312    }
313
314    if (handle) {
315        pthread_mutex_lock(&g_intf_lock);
316        my_obj = mm_camera_util_get_camera_by_handler(handle);
317
318        if(my_obj) {
319            pthread_mutex_lock(&my_obj->cam_lock);
320            pthread_mutex_unlock(&g_intf_lock);
321            rc = mm_camera_set_parms(my_obj, parms);
322        } else {
323            pthread_mutex_unlock(&g_intf_lock);
324        }
325    }
326    return rc;
327}
328
329/*===========================================================================
330 * FUNCTION   : mm_camera_intf_get_parms
331 *
332 * DESCRIPTION: get parameters per camera
333 *
334 * PARAMETERS :
335 *   @camera_handle: camera handle
336 *   @parms        : ptr to a param struct to be get from server
337 *
338 * RETURN     : int32_t type of status
339 *              0  -- success
340 *              -1 -- failure
341 * NOTE       : Assume the parms struct buf is already mapped to server via
342 *              domain socket. Parameters to be get from server are already
343 *              filled in by upper layer caller. After this call, corresponding
344 *              fields of requested parameters will be filled in by server with
345 *              detailed information.
346 *==========================================================================*/
347static int32_t mm_camera_intf_get_parms(uint32_t camera_handle,
348                                        parm_buffer_t *parms)
349{
350    int32_t rc = -1;
351    mm_camera_obj_t * my_obj = NULL;
352    uint32_t handle = get_main_camera_handle(camera_handle);
353    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
354
355    if (aux_handle) {
356        pthread_mutex_lock(&g_intf_lock);
357        my_obj = mm_camera_util_get_camera_head(aux_handle);
358        if (my_obj) {
359            pthread_mutex_lock(&my_obj->muxer_lock);
360            pthread_mutex_unlock(&g_intf_lock);
361            rc = mm_camera_muxer_get_parms(aux_handle,
362                    parms, my_obj);
363        } else {
364            pthread_mutex_unlock(&g_intf_lock);
365        }
366    }
367
368    if (handle) {
369        pthread_mutex_lock(&g_intf_lock);
370        my_obj = mm_camera_util_get_camera_by_handler(handle);
371
372        if(my_obj) {
373            pthread_mutex_lock(&my_obj->cam_lock);
374            pthread_mutex_unlock(&g_intf_lock);
375            rc = mm_camera_get_parms(my_obj, parms);
376        } else {
377            pthread_mutex_unlock(&g_intf_lock);
378        }
379    }
380    return rc;
381
382}
383
384/*===========================================================================
385 * FUNCTION   : mm_camera_intf_do_auto_focus
386 *
387 * DESCRIPTION: performing auto focus
388 *
389 * PARAMETERS :
390 *   @camera_handle: camera handle
391 *
392 * RETURN     : int32_t type of status
393 *              0  -- success
394 *              -1 -- failure
395 * NOTE       : if this call success, we will always assume there will
396 *              be an auto_focus event following up.
397 *==========================================================================*/
398static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle)
399{
400    int32_t rc = -1;
401    mm_camera_obj_t * my_obj = NULL;
402    uint32_t handle = get_main_camera_handle(camera_handle);
403    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
404
405    if (aux_handle) {
406        pthread_mutex_lock(&g_intf_lock);
407        my_obj = mm_camera_util_get_camera_head(aux_handle);
408        if (my_obj) {
409            pthread_mutex_lock(&my_obj->muxer_lock);
410            pthread_mutex_unlock(&g_intf_lock);
411            rc = mm_camera_muxer_do_auto_focus(aux_handle, my_obj);
412        } else {
413            pthread_mutex_unlock(&g_intf_lock);
414        }
415    }
416
417    if (handle) {
418        pthread_mutex_lock(&g_intf_lock);
419        my_obj = mm_camera_util_get_camera_by_handler(handle);
420
421        if(my_obj) {
422            pthread_mutex_lock(&my_obj->cam_lock);
423            pthread_mutex_unlock(&g_intf_lock);
424            rc = mm_camera_do_auto_focus(my_obj);
425        } else {
426            pthread_mutex_unlock(&g_intf_lock);
427        }
428    }
429    LOGH("rc = %d camera_handle = %u X", rc, camera_handle);
430    return rc;
431}
432
433/*===========================================================================
434 * FUNCTION   : mm_camera_intf_cancel_auto_focus
435 *
436 * DESCRIPTION: cancel auto focus
437 *
438 * PARAMETERS :
439 *   @camera_handle: camera handle
440 *
441 * RETURN     : int32_t type of status
442 *              0  -- success
443 *              -1 -- failure
444 *==========================================================================*/
445static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)
446{
447    int32_t rc = -1;
448    mm_camera_obj_t * my_obj = NULL;
449    uint32_t handle = get_main_camera_handle(camera_handle);
450    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
451
452    if (aux_handle) {
453        pthread_mutex_lock(&g_intf_lock);
454        my_obj = mm_camera_util_get_camera_head(aux_handle);
455        if (my_obj) {
456            pthread_mutex_lock(&my_obj->muxer_lock);
457            pthread_mutex_unlock(&g_intf_lock);
458            rc = mm_camera_muxer_cancel_auto_focus(aux_handle, my_obj);
459        } else {
460            pthread_mutex_unlock(&g_intf_lock);
461        }
462    }
463
464    if (handle) {
465        pthread_mutex_lock(&g_intf_lock);
466        my_obj = mm_camera_util_get_camera_by_handler(handle);
467        if(my_obj) {
468            pthread_mutex_lock(&my_obj->cam_lock);
469            pthread_mutex_unlock(&g_intf_lock);
470            rc = mm_camera_cancel_auto_focus(my_obj);
471        } else {
472            pthread_mutex_unlock(&g_intf_lock);
473        }
474    }
475    LOGH("rc = %d camera_handle = %u X", rc, camera_handle);
476    return rc;
477}
478
479/*===========================================================================
480 * FUNCTION   : mm_camera_intf_prepare_snapshot
481 *
482 * DESCRIPTION: prepare hardware for snapshot
483 *
484 * PARAMETERS :
485 *   @camera_handle: camera handle
486 *   @do_af_flag   : flag indicating if AF is needed
487 *
488 * RETURN     : int32_t type of status
489 *              0  -- success
490 *              -1 -- failure
491 *==========================================================================*/
492static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle,
493                                               int32_t do_af_flag)
494{
495    int32_t rc = -1;
496    mm_camera_obj_t * my_obj = NULL;
497    uint32_t handle = get_main_camera_handle(camera_handle);
498    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
499
500    if (aux_handle) {
501        pthread_mutex_lock(&g_intf_lock);
502        my_obj = mm_camera_util_get_camera_head(aux_handle);
503        if (my_obj) {
504            pthread_mutex_lock(&my_obj->muxer_lock);
505            pthread_mutex_unlock(&g_intf_lock);
506            rc = mm_camera_muxer_prepare_snapshot(aux_handle,
507                    do_af_flag, my_obj);
508        } else {
509            pthread_mutex_unlock(&g_intf_lock);
510        }
511    }
512
513    if (handle) {
514        pthread_mutex_lock(&g_intf_lock);
515        my_obj = mm_camera_util_get_camera_by_handler(handle);
516
517        if(my_obj) {
518            pthread_mutex_lock(&my_obj->cam_lock);
519            pthread_mutex_unlock(&g_intf_lock);
520
521            rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
522        } else {
523            pthread_mutex_unlock(&g_intf_lock);
524        }
525        return rc;
526    }
527    LOGH("rc = %d camera_handle = %u X", rc, camera_handle);
528    return rc;
529}
530
531/*===========================================================================
532 * FUNCTION   : mm_camera_intf_flush
533 *
534 * DESCRIPTION: flush the current camera state and buffers
535 *
536 * PARAMETERS :
537 *   @camera_handle: camera handle
538 *
539 * RETURN     : int32_t type of status
540 *              0  -- success
541 *              -1 -- failure
542 *==========================================================================*/
543static int32_t mm_camera_intf_flush(uint32_t camera_handle)
544{
545    int32_t rc = -1;
546    mm_camera_obj_t * my_obj = NULL;
547    uint32_t handle = get_main_camera_handle(camera_handle);
548    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
549
550    if (aux_handle) {
551        pthread_mutex_lock(&g_intf_lock);
552        my_obj = mm_camera_util_get_camera_head(aux_handle);
553
554        if (my_obj) {
555            pthread_mutex_lock(&my_obj->muxer_lock);
556            pthread_mutex_unlock(&g_intf_lock);
557            rc = mm_camera_muxer_flush(aux_handle, my_obj);
558        } else {
559            pthread_mutex_unlock(&g_intf_lock);
560        }
561    }
562
563    if (handle) {
564        pthread_mutex_lock(&g_intf_lock);
565        my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
566
567        if(my_obj) {
568            pthread_mutex_lock(&my_obj->cam_lock);
569            pthread_mutex_unlock(&g_intf_lock);
570            rc = mm_camera_flush(my_obj);
571        } else {
572            pthread_mutex_unlock(&g_intf_lock);
573        }
574    }
575    return rc;
576}
577
578/*===========================================================================
579 * FUNCTION   : mm_camera_intf_close
580 *
581 * DESCRIPTION: close a camera by its handle
582 *
583 * PARAMETERS :
584 *   @camera_handle: camera handle
585 *
586 * RETURN     : int32_t type of status
587 *              0  -- success
588 *              -1 -- failure
589 *==========================================================================*/
590static int32_t mm_camera_intf_close(uint32_t camera_handle)
591{
592    int32_t rc = -1;
593    uint8_t cam_idx = -1;
594    mm_camera_obj_t *my_obj = NULL;
595
596    LOGD("E: camera_handler = %d ", camera_handle);
597
598    uint32_t handle = get_main_camera_handle(camera_handle);
599    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
600    if (aux_handle) {
601        pthread_mutex_lock(&g_intf_lock);
602        my_obj = mm_camera_util_get_camera_head(aux_handle);
603        if (my_obj) {
604            pthread_mutex_lock(&my_obj->muxer_lock);
605            pthread_mutex_unlock(&g_intf_lock);
606            rc = mm_camera_muxer_close_camera(aux_handle, my_obj);
607        }
608    }
609
610    if (handle) {
611        pthread_mutex_lock(&g_intf_lock);
612        my_obj = mm_camera_util_get_camera_by_handler(handle);
613
614        if (my_obj){
615            if (my_obj->aux_cam_obj[0] != NULL) {
616                /*Close aux cameras*/
617                pthread_mutex_lock(&my_obj->muxer_lock);
618                pthread_mutex_unlock(&g_intf_lock);
619                rc = mm_camera_muxer_close_camera(
620                        my_obj->aux_cam_obj[0]->my_hdl, my_obj);
621                pthread_mutex_lock(&g_intf_lock);
622            }
623
624            cam_idx = mm_camera_util_get_index_by_num(
625                    my_obj->my_num, my_obj->my_hdl);
626            my_obj->ref_count--;
627            if(my_obj->ref_count > 0) {
628                /* still have reference to obj, return here */
629                LOGD("ref_count=%d\n", my_obj->ref_count);
630                pthread_mutex_unlock(&g_intf_lock);
631                rc = 0;
632            } else {
633                /* need close camera here as no other reference
634                 * first empty g_cam_ctrl's referent to cam_obj */
635                g_cam_ctrl.cam_obj[cam_idx] = NULL;
636                pthread_mutex_lock(&my_obj->cam_lock);
637                pthread_mutex_unlock(&g_intf_lock);
638                rc = mm_camera_close(my_obj);
639                pthread_mutex_destroy(&my_obj->cam_lock);
640                pthread_mutex_destroy(&my_obj->muxer_lock);
641                free(my_obj);
642                my_obj = NULL;
643            }
644        } else {
645             pthread_mutex_unlock(&g_intf_lock);
646        }
647    } else {
648        pthread_mutex_unlock(&g_intf_lock);
649    }
650
651    LOGH("camera_handler = %u rc = %d", camera_handle, rc);
652#ifdef QCAMERA_REDEFINE_LOG
653    mm_camera_debug_close();
654#endif
655
656    return rc;
657}
658
659/*===========================================================================
660 * FUNCTION   : mm_camera_intf_add_channel
661 *
662 * DESCRIPTION: add a channel
663 *
664 * PARAMETERS :
665 *   @camera_handle: camera handle
666 *   @attr         : bundle attribute of the channel if needed
667 *   @channel_cb   : callback function for bundle data notify
668 *   @userdata     : user data ptr
669 *
670 * RETURN     : uint32_t type of channel handle
671 *              0  -- invalid channel handle, meaning the op failed
672 *              >0 -- successfully added a channel with a valid handle
673 * NOTE       : if no bundle data notify is needed, meaning each stream in the
674 *              channel will have its own stream data notify callback, then
675 *              attr, channel_cb, and userdata can be NULL. In this case,
676 *              no matching logic will be performed in channel for the bundling.
677 *==========================================================================*/
678static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
679                                           mm_camera_channel_attr_t *attr,
680                                           mm_camera_buf_notify_t channel_cb,
681                                           void *userdata)
682{
683    uint32_t ch_id = 0, aux_ch_id = 0;
684    mm_camera_obj_t * my_obj = NULL;
685    uint32_t handle = get_main_camera_handle(camera_handle);
686    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
687
688    LOGD("E camera_handler = %d", camera_handle);
689    if (handle) {
690        pthread_mutex_lock(&g_intf_lock);
691        my_obj = mm_camera_util_get_camera_by_handler(handle);
692        if(my_obj) {
693            pthread_mutex_lock(&my_obj->cam_lock);
694            pthread_mutex_unlock(&g_intf_lock);
695            ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
696        } else {
697            pthread_mutex_unlock(&g_intf_lock);
698        }
699    }
700
701    if (aux_handle) {
702        pthread_mutex_lock(&g_intf_lock);
703        my_obj = mm_camera_util_get_camera_head(aux_handle);
704        if (my_obj) {
705            pthread_mutex_lock(&my_obj->muxer_lock);
706            pthread_mutex_unlock(&g_intf_lock);
707            aux_ch_id = mm_camera_muxer_add_channel(aux_handle, attr,
708                    channel_cb, userdata, ch_id, my_obj);
709            if (aux_ch_id <= 0) {
710                pthread_mutex_lock(&my_obj->cam_lock);
711                mm_camera_del_channel(my_obj, ch_id);
712            } else {
713                ch_id |= aux_ch_id;
714           }
715        } else {
716            pthread_mutex_unlock(&g_intf_lock);
717        }
718    }
719    LOGH("camera_handle = %u ch_id = %u X", ch_id);
720    return ch_id;
721}
722
723/*===========================================================================
724 * FUNCTION   : mm_camera_intf_del_channel
725 *
726 * DESCRIPTION: delete a channel by its handle
727 *
728 * PARAMETERS :
729 *   @camera_handle: camera handle
730 *   @ch_id        : channel handle
731 *
732 * RETURN     : int32_t type of status
733 *              0  -- success
734 *              -1 -- failure
735 * NOTE       : all streams in the channel should be stopped already before
736 *              this channel can be deleted.
737 *==========================================================================*/
738static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
739                                          uint32_t ch_id)
740{
741    int32_t rc = -1;
742    mm_camera_obj_t * my_obj = NULL;
743    uint32_t m_chid = get_main_camera_handle(ch_id);
744    uint32_t aux_chid = get_aux_camera_handle(ch_id);
745
746    LOGD("E ch_id = %d", ch_id);
747
748    if (aux_chid) {
749        pthread_mutex_lock(&g_intf_lock);
750        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
751        my_obj = mm_camera_util_get_camera_head(aux_handle);
752        if (my_obj) {
753            pthread_mutex_lock(&my_obj->muxer_lock);
754            pthread_mutex_unlock(&g_intf_lock);
755            mm_camera_muxer_delete_channel(aux_handle, aux_chid, my_obj);
756        } else {
757            pthread_mutex_unlock(&g_intf_lock);
758        }
759    }
760
761    if (m_chid) {
762        pthread_mutex_lock(&g_intf_lock);
763        uint32_t handle = get_main_camera_handle(camera_handle);
764        my_obj = mm_camera_util_get_camera_by_handler(handle);
765
766        if(my_obj) {
767            pthread_mutex_lock(&my_obj->cam_lock);
768            pthread_mutex_unlock(&g_intf_lock);
769            rc = mm_camera_del_channel(my_obj, m_chid);
770        } else {
771            pthread_mutex_unlock(&g_intf_lock);
772        }
773    }
774    LOGH("rc = %d ch_id = %u X", rc, ch_id);
775    return rc;
776}
777
778/*===========================================================================
779 * FUNCTION   : mm_camera_intf_get_bundle_info
780 *
781 * DESCRIPTION: query bundle info of the channel
782 *
783 * PARAMETERS :
784 *   @camera_handle: camera handle
785 *   @ch_id        : channel handle
786 *   @bundle_info  : bundle info to be filled in
787 *
788 * RETURN     : int32_t type of status
789 *              0  -- success
790 *              -1 -- failure
791 * NOTE       : all streams in the channel should be stopped already before
792 *              this channel can be deleted.
793 *==========================================================================*/
794static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
795                                              uint32_t ch_id,
796                                              cam_bundle_config_t *bundle_info)
797{
798    int32_t rc = -1;
799    mm_camera_obj_t * my_obj = NULL;
800    uint32_t m_chid = get_main_camera_handle(ch_id);
801    uint32_t aux_chid = get_aux_camera_handle(ch_id);
802
803    LOGD("E ch_id = %d", ch_id);
804
805    if (aux_chid && m_chid) {
806        LOGE("Does not support 2 channels for bundle info");
807        return rc;
808    }
809
810    if (aux_chid) {
811        pthread_mutex_lock(&g_intf_lock);
812        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
813        my_obj = mm_camera_util_get_camera_head(aux_handle);
814        if (my_obj) {
815            pthread_mutex_lock(&my_obj->muxer_lock);
816            pthread_mutex_unlock(&g_intf_lock);
817            rc = mm_camera_muxer_get_bundle_info(aux_handle, aux_chid,
818                    bundle_info, my_obj);
819        } else {
820            pthread_mutex_unlock(&g_intf_lock);
821        }
822    } else if (m_chid) {
823        pthread_mutex_lock(&g_intf_lock);
824        uint32_t handle = get_main_camera_handle(camera_handle);
825        my_obj = mm_camera_util_get_camera_by_handler(handle);
826        if(my_obj) {
827            pthread_mutex_lock(&my_obj->cam_lock);
828            pthread_mutex_unlock(&g_intf_lock);
829            rc = mm_camera_get_bundle_info(my_obj, m_chid, bundle_info);
830        } else {
831            pthread_mutex_unlock(&g_intf_lock);
832        }
833    }
834    LOGD("rc = %d ch_id = %d X", rc, ch_id);
835    return rc;
836}
837
838/*===========================================================================
839 * FUNCTION   : mm_camera_intf_register_event_notify
840 *
841 * DESCRIPTION: register for event notify
842 *
843 * PARAMETERS :
844 *   @camera_handle: camera handle
845 *   @evt_cb       : callback for event notify
846 *   @user_data    : user data ptr
847 *
848 * RETURN     : int32_t type of status
849 *              0  -- success
850 *              -1 -- failure
851 *==========================================================================*/
852static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
853                                                    mm_camera_event_notify_t evt_cb,
854                                                    void * user_data)
855{
856    int32_t rc = -1;
857    mm_camera_obj_t *my_obj = NULL;
858    LOGD("E ");
859
860    uint32_t handle = get_main_camera_handle(camera_handle);
861    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
862
863    if (handle) {
864        pthread_mutex_lock(&g_intf_lock);
865        my_obj = mm_camera_util_get_camera_by_handler(handle);
866
867        if(my_obj) {
868            pthread_mutex_lock(&my_obj->cam_lock);
869            pthread_mutex_unlock(&g_intf_lock);
870            rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
871        } else {
872            pthread_mutex_unlock(&g_intf_lock);
873        }
874    }
875
876    if (aux_handle) {
877        pthread_mutex_lock(&g_intf_lock);
878        my_obj = mm_camera_util_get_camera_head(aux_handle);
879        if (my_obj) {
880            pthread_mutex_lock(&my_obj->muxer_lock);
881            pthread_mutex_unlock(&g_intf_lock);
882            rc = mm_camera_muxer_register_event_notify(aux_handle,
883                    evt_cb, user_data, my_obj);
884        }
885    }
886    LOGD("E rc = %d", rc);
887    return rc;
888}
889
890/*===========================================================================
891 * FUNCTION   : mm_camera_intf_qbuf
892 *
893 * DESCRIPTION: enqueue buffer back to kernel
894 *
895 * PARAMETERS :
896 *   @camera_handle: camera handle
897 *   @ch_id        : channel handle
898 *   @buf          : buf ptr to be enqueued
899 *
900 * RETURN     : int32_t type of status
901 *              0  -- success
902 *              -1 -- failure
903 *==========================================================================*/
904static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
905                                    uint32_t ch_id,
906                                    mm_camera_buf_def_t *buf)
907{
908    int32_t rc = -1;
909    mm_camera_obj_t *my_obj = NULL;
910    uint32_t strid = 0;
911    uint32_t aux_strid = 0;
912
913    if (buf != NULL) {
914        strid = get_main_camera_handle(buf->stream_id);
915        aux_strid = get_aux_camera_handle(buf->stream_id);
916    }
917
918    if (strid) {
919        pthread_mutex_lock(&g_intf_lock);
920        uint32_t handle = get_main_camera_handle(camera_handle);
921        uint32_t chid = get_main_camera_handle(ch_id);
922        my_obj = mm_camera_util_get_camera_by_handler(handle);
923        if(my_obj) {
924            pthread_mutex_lock(&my_obj->cam_lock);
925            pthread_mutex_unlock(&g_intf_lock);
926            rc = mm_camera_qbuf(my_obj, chid, buf);
927        } else {
928            pthread_mutex_unlock(&g_intf_lock);
929        }
930    }
931
932    if (aux_strid) {
933        pthread_mutex_lock(&g_intf_lock);
934        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
935        uint32_t aux_chid = get_aux_camera_handle(ch_id);
936        my_obj = mm_camera_util_get_camera_head(aux_handle);
937        if (my_obj) {
938            pthread_mutex_lock(&my_obj->muxer_lock);
939            pthread_mutex_unlock(&g_intf_lock);
940            rc = mm_camera_muxer_qbuf(aux_handle, aux_chid, buf, my_obj);
941        } else {
942            pthread_mutex_unlock(&g_intf_lock);
943        }
944    }
945    LOGD("X evt_type = %d",rc);
946    return rc;
947}
948
949/*===========================================================================
950 * FUNCTION   : mm_camera_intf_qbuf
951 *
952 * DESCRIPTION: enqueue buffer back to kernel
953 *
954 * PARAMETERS :
955 *   @camera_handle: camera handle
956 *   @ch_id        : channel handle
957 *   @buf          : buf ptr to be enqueued
958 *
959 * RETURN     : int32_t type of status
960 *              0  -- success
961 *              -1 -- failure
962 *==========================================================================*/
963static int32_t mm_camera_intf_cancel_buf(uint32_t camera_handle, uint32_t ch_id, uint32_t stream_id,
964                     uint32_t buf_idx)
965{
966    int32_t rc = -1;
967    mm_camera_obj_t * my_obj = NULL;
968
969    pthread_mutex_lock(&g_intf_lock);
970    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
971
972    if(my_obj) {
973        pthread_mutex_lock(&my_obj->cam_lock);
974        pthread_mutex_unlock(&g_intf_lock);
975        rc = mm_camera_cancel_buf(my_obj, ch_id, stream_id, buf_idx);
976    } else {
977        pthread_mutex_unlock(&g_intf_lock);
978    }
979    LOGD("X evt_type = %d",rc);
980    return rc;
981}
982
983
984/*===========================================================================
985 * FUNCTION   : mm_camera_intf_get_queued_buf_count
986 *
987 * DESCRIPTION: returns the queued buffer count
988 *
989 * PARAMETERS :
990 *   @camera_handle: camera handle
991 *   @ch_id        : channel handle
992 *   @stream_id : stream id
993 *
994 * RETURN     : int32_t - queued buffer count
995 *
996 *==========================================================================*/
997static int32_t mm_camera_intf_get_queued_buf_count(uint32_t camera_handle,
998        uint32_t ch_id, uint32_t stream_id)
999{
1000    int32_t rc = -1;
1001    mm_camera_obj_t * my_obj = NULL;
1002    uint32_t strid = get_main_camera_handle(stream_id);
1003    uint32_t aux_strid = get_main_camera_handle(stream_id);
1004
1005    if (strid) {
1006        pthread_mutex_lock(&g_intf_lock);
1007        uint32_t handle = get_main_camera_handle(camera_handle);
1008        uint32_t chid = get_main_camera_handle(ch_id);
1009        my_obj = mm_camera_util_get_camera_by_handler(handle);
1010        if(my_obj) {
1011            pthread_mutex_lock(&my_obj->cam_lock);
1012            pthread_mutex_unlock(&g_intf_lock);
1013            rc = mm_camera_get_queued_buf_count(my_obj, chid, stream_id);
1014        } else {
1015            pthread_mutex_unlock(&g_intf_lock);
1016        }
1017    } else if (aux_strid) {
1018        pthread_mutex_lock(&g_intf_lock);
1019        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1020        uint32_t aux_chid = get_aux_camera_handle(ch_id);
1021        my_obj = mm_camera_util_get_camera_head(aux_handle);
1022        if (my_obj) {
1023            pthread_mutex_lock(&my_obj->muxer_lock);
1024            pthread_mutex_unlock(&g_intf_lock);
1025            rc = mm_camera_muxer_get_queued_buf_count(aux_handle,
1026                    aux_chid, aux_strid, my_obj);
1027        } else {
1028            pthread_mutex_unlock(&g_intf_lock);
1029        }
1030    }
1031    LOGD("X queued buffer count = %d",rc);
1032    return rc;
1033}
1034
1035/*===========================================================================
1036 * FUNCTION   : mm_camera_intf_link_stream
1037 *
1038 * DESCRIPTION: link a stream into a new channel
1039 *
1040 * PARAMETERS :
1041 *   @camera_handle: camera handle
1042 *   @ch_id        : channel handle
1043 *   @stream_id    : stream id
1044 *   @linked_ch_id : channel in which the stream will be linked
1045 *
1046 * RETURN     : int32_t type of stream handle
1047 *              0  -- invalid stream handle, meaning the op failed
1048 *              >0 -- successfully linked a stream with a valid handle
1049 *==========================================================================*/
1050static int32_t mm_camera_intf_link_stream(uint32_t camera_handle,
1051        uint32_t ch_id,
1052        uint32_t stream_id,
1053        uint32_t linked_ch_id)
1054{
1055    uint32_t id = 0;
1056    mm_camera_obj_t * my_obj = NULL;
1057    uint32_t strid = get_main_camera_handle(stream_id);
1058    uint32_t aux_strid = get_aux_camera_handle(stream_id);
1059    uint32_t linked_chid = get_main_camera_handle(linked_ch_id);
1060    uint32_t aux_linked_chid = get_aux_camera_handle(linked_ch_id);
1061
1062    LOGD("E handle = %u ch_id = %u",
1063          camera_handle, ch_id);
1064
1065    if (strid && linked_chid) {
1066        pthread_mutex_lock(&g_intf_lock);
1067        uint32_t handle = get_main_camera_handle(camera_handle);
1068        uint32_t m_chid = get_main_camera_handle(ch_id);
1069        my_obj = mm_camera_util_get_camera_by_handler(handle);
1070
1071        if(my_obj) {
1072            pthread_mutex_lock(&my_obj->cam_lock);
1073            pthread_mutex_unlock(&g_intf_lock);
1074            id = mm_camera_link_stream(my_obj, m_chid, strid, linked_chid);
1075        } else {
1076            pthread_mutex_unlock(&g_intf_lock);
1077        }
1078    }
1079
1080    if (aux_strid && aux_linked_chid) {
1081        pthread_mutex_lock(&g_intf_lock);
1082        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1083        uint32_t aux_chid = get_aux_camera_handle(ch_id);
1084        my_obj = mm_camera_util_get_camera_head(aux_handle);
1085        if (my_obj) {
1086            pthread_mutex_lock(&my_obj->muxer_lock);
1087            pthread_mutex_unlock(&g_intf_lock);
1088            id = mm_camera_muxer_link_stream(aux_handle, aux_chid,
1089                    aux_strid, aux_linked_chid, my_obj);
1090        } else {
1091            pthread_mutex_unlock(&g_intf_lock);
1092        }
1093    }
1094
1095    LOGH("X ch_id = %u stream_id = %u linked_ch_id = %u id = %u",
1096            ch_id, stream_id, linked_ch_id, id);
1097    return (int32_t)id;
1098}
1099
1100/*===========================================================================
1101 * FUNCTION   : mm_camera_intf_add_stream
1102 *
1103 * DESCRIPTION: add a stream into a channel
1104 *
1105 * PARAMETERS :
1106 *   @camera_handle: camera handle
1107 *   @ch_id        : channel handle
1108 *
1109 * RETURN     : uint32_t type of stream handle
1110 *              0  -- invalid stream handle, meaning the op failed
1111 *              >0 -- successfully added a stream with a valid handle
1112 *==========================================================================*/
1113static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
1114                                          uint32_t ch_id)
1115{
1116    uint32_t stream_id = 0, aux_stream_id;
1117    mm_camera_obj_t *my_obj = NULL;
1118    uint32_t m_ch_id = get_main_camera_handle(ch_id);
1119    uint32_t aux_chid = get_aux_camera_handle(ch_id);
1120
1121    LOGD("E handle = %d ch_id = %d",
1122          camera_handle, ch_id);
1123    if (m_ch_id) {
1124        pthread_mutex_lock(&g_intf_lock);
1125        uint32_t handle = get_main_camera_handle(camera_handle);
1126        my_obj = mm_camera_util_get_camera_by_handler(handle);
1127        if(my_obj) {
1128            pthread_mutex_lock(&my_obj->cam_lock);
1129            pthread_mutex_unlock(&g_intf_lock);
1130            stream_id = mm_camera_add_stream(my_obj, m_ch_id);
1131       } else {
1132            pthread_mutex_unlock(&g_intf_lock);
1133       }
1134    }
1135
1136    if (aux_chid) {
1137        pthread_mutex_lock(&g_intf_lock);
1138        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1139        my_obj = mm_camera_util_get_camera_head(aux_handle);
1140        if (my_obj) {
1141            pthread_mutex_lock(&my_obj->muxer_lock);
1142            pthread_mutex_unlock(&g_intf_lock);
1143            aux_stream_id = mm_camera_muxer_add_stream(aux_handle, aux_chid,
1144                    m_ch_id, stream_id, my_obj);
1145            if (aux_stream_id <= 0) {
1146                LOGE("Failed to add stream");
1147                pthread_mutex_lock(&my_obj->cam_lock);
1148                mm_camera_del_stream(my_obj, m_ch_id, stream_id);
1149            } else {
1150                stream_id = stream_id | aux_stream_id;
1151            }
1152        } else {
1153            pthread_mutex_unlock(&g_intf_lock);
1154        }
1155    }
1156    LOGH("X ch_id = %u stream_id = %u", ch_id, stream_id);
1157    return stream_id;
1158}
1159
1160/*===========================================================================
1161 * FUNCTION   : mm_camera_intf_del_stream
1162 *
1163 * DESCRIPTION: delete a stream by its handle
1164 *
1165 * PARAMETERS :
1166 *   @camera_handle: camera handle
1167 *   @ch_id        : channel handle
1168 *   @stream_id    : stream handle
1169 *
1170 * RETURN     : int32_t type of status
1171 *              0  -- success
1172 *              -1 -- failure
1173 * NOTE       : stream should be stopped already before it can be deleted.
1174 *==========================================================================*/
1175static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
1176                                         uint32_t ch_id,
1177                                         uint32_t stream_id)
1178{
1179    int32_t rc = -1;
1180    mm_camera_obj_t * my_obj = NULL;
1181    uint32_t m_strid = get_main_camera_handle(stream_id);
1182    uint32_t aux_strid = get_aux_camera_handle(stream_id);
1183
1184    LOGD("E handle = %d ch_id = %d stream_id = %d",
1185          camera_handle, ch_id, stream_id);
1186
1187    if (aux_strid) {
1188        pthread_mutex_lock(&g_intf_lock);
1189        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1190        uint32_t aux_chid = get_aux_camera_handle(ch_id);
1191        my_obj = mm_camera_util_get_camera_head(aux_handle);
1192        if (my_obj) {
1193            pthread_mutex_lock(&my_obj->muxer_lock);
1194            pthread_mutex_unlock(&g_intf_lock);
1195            mm_camera_muxer_delete_stream(aux_handle, aux_chid,
1196                    aux_strid, my_obj);
1197        } else {
1198            pthread_mutex_unlock(&g_intf_lock);
1199        }
1200    }
1201
1202    if (m_strid) {
1203        pthread_mutex_lock(&g_intf_lock);
1204        uint32_t handle = get_main_camera_handle(camera_handle);
1205        uint32_t m_chid = get_main_camera_handle(ch_id);
1206
1207        my_obj = mm_camera_util_get_camera_by_handler(handle);
1208        if(my_obj) {
1209            pthread_mutex_lock(&my_obj->cam_lock);
1210            pthread_mutex_unlock(&g_intf_lock);
1211            rc = mm_camera_del_stream(my_obj, m_chid, m_strid);
1212        } else {
1213            pthread_mutex_unlock(&g_intf_lock);
1214        }
1215    }
1216    LOGH("X stream_id = %u rc = %d", stream_id, rc);
1217    return rc;
1218}
1219
1220/*===========================================================================
1221 * FUNCTION   : mm_camera_intf_config_stream
1222 *
1223 * DESCRIPTION: configure a stream
1224 *
1225 * PARAMETERS :
1226 *   @camera_handle: camera handle
1227 *   @ch_id        : channel handle
1228 *   @stream_id    : stream handle
1229 *   @config       : stream configuration
1230 *
1231 * RETURN     : int32_t type of status
1232 *              0  -- success
1233 *              -1 -- failure
1234 *==========================================================================*/
1235static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
1236                                            uint32_t ch_id,
1237                                            uint32_t stream_id,
1238                                            mm_camera_stream_config_t *config)
1239{
1240    int32_t rc = -1;
1241    mm_camera_obj_t * my_obj = NULL;
1242    uint32_t strid = get_main_camera_handle(stream_id);
1243    uint32_t aux_strid = get_aux_camera_handle(stream_id);
1244
1245    LOGD("E handle = %d, ch_id = %d,stream_id = %d",
1246          camera_handle, ch_id, stream_id);
1247
1248    if (strid) {
1249        pthread_mutex_lock(&g_intf_lock);
1250        uint32_t handle = get_main_camera_handle(camera_handle);
1251        uint32_t chid = get_main_camera_handle(ch_id);
1252
1253        my_obj = mm_camera_util_get_camera_by_handler(handle);
1254        if(my_obj) {
1255            pthread_mutex_lock(&my_obj->cam_lock);
1256            pthread_mutex_unlock(&g_intf_lock);
1257            rc = mm_camera_config_stream(my_obj, chid, strid, config);
1258        } else {
1259            pthread_mutex_unlock(&g_intf_lock);
1260        }
1261    }
1262
1263    if (aux_strid && rc == 0) {
1264        pthread_mutex_lock(&g_intf_lock);
1265        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1266        uint32_t aux_chid = get_aux_camera_handle(ch_id);
1267
1268        my_obj = mm_camera_util_get_camera_head(aux_handle);
1269        if (my_obj) {
1270            pthread_mutex_lock(&my_obj->muxer_lock);
1271            pthread_mutex_unlock(&g_intf_lock);
1272            rc = mm_camera_muxer_config_stream(aux_handle,
1273                    aux_chid, aux_strid, config, my_obj);
1274        } else {
1275            pthread_mutex_unlock(&g_intf_lock);
1276        }
1277    }
1278    LOGH("X stream_id = %u rc = %d", stream_id, rc);
1279    return rc;
1280}
1281
1282/*===========================================================================
1283 * FUNCTION   : mm_camera_intf_start_channel
1284 *
1285 * DESCRIPTION: start a channel, which will start all streams in the channel
1286 *
1287 * PARAMETERS :
1288 *   @camera_handle: camera handle
1289 *   @ch_id        : channel handle
1290 *
1291 * RETURN     : int32_t type of status
1292 *              0  -- success
1293 *              -1 -- failure
1294 *==========================================================================*/
1295static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
1296                                            uint32_t ch_id)
1297{
1298    int32_t rc = -1;
1299    mm_camera_obj_t * my_obj = NULL;
1300    uint32_t chid = get_main_camera_handle(ch_id);
1301    uint32_t aux_chid = get_aux_camera_handle(ch_id);
1302
1303    if (chid) {
1304        uint32_t handle = get_main_camera_handle(camera_handle);
1305        pthread_mutex_lock(&g_intf_lock);
1306
1307        my_obj = mm_camera_util_get_camera_by_handler(handle);
1308        if(my_obj) {
1309            pthread_mutex_lock(&my_obj->cam_lock);
1310            pthread_mutex_unlock(&g_intf_lock);
1311            rc = mm_camera_start_channel(my_obj, chid);
1312        } else {
1313            pthread_mutex_unlock(&g_intf_lock);
1314        }
1315    }
1316
1317    if (aux_chid && rc == 0) {
1318        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1319        pthread_mutex_lock(&g_intf_lock);
1320
1321        my_obj = mm_camera_util_get_camera_head(aux_handle);
1322        if(my_obj) {
1323            pthread_mutex_lock(&my_obj->muxer_lock);
1324            pthread_mutex_unlock(&g_intf_lock);
1325            rc = mm_camera_muxer_start_channel(aux_handle, aux_chid, my_obj);
1326        } else {
1327            pthread_mutex_unlock(&g_intf_lock);
1328        }
1329    }
1330    LOGH("X ch_id = %u rc = %d", ch_id, rc);
1331    return rc;
1332}
1333
1334/*===========================================================================
1335 * FUNCTION   : mm_camera_intf_stop_channel
1336 *
1337 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1338 *
1339 * PARAMETERS :
1340 *   @camera_handle: camera handle
1341 *   @ch_id        : channel handle
1342 *
1343 * RETURN     : int32_t type of status
1344 *              0  -- success
1345 *              -1 -- failure
1346 *==========================================================================*/
1347static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
1348                                           uint32_t ch_id)
1349{
1350    int32_t rc = -1;
1351    mm_camera_obj_t * my_obj = NULL;
1352    uint32_t chid = get_main_camera_handle(ch_id);
1353    uint32_t aux_chid = get_aux_camera_handle(ch_id);
1354
1355    if (aux_chid) {
1356        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1357        pthread_mutex_lock(&g_intf_lock);
1358
1359        my_obj = mm_camera_util_get_camera_head(aux_handle);
1360        if(my_obj) {
1361            pthread_mutex_lock(&my_obj->muxer_lock);
1362            pthread_mutex_unlock(&g_intf_lock);
1363            rc = mm_camera_muxer_stop_channel(aux_handle, aux_chid, my_obj);
1364        } else {
1365            pthread_mutex_unlock(&g_intf_lock);
1366        }
1367    }
1368    if (chid) {
1369        uint32_t handle = get_main_camera_handle(camera_handle);
1370        pthread_mutex_lock(&g_intf_lock);
1371
1372        my_obj = mm_camera_util_get_camera_by_handler(handle);
1373        if(my_obj) {
1374            pthread_mutex_lock(&my_obj->cam_lock);
1375            pthread_mutex_unlock(&g_intf_lock);
1376            rc = mm_camera_stop_channel(my_obj, chid);
1377        } else {
1378            pthread_mutex_unlock(&g_intf_lock);
1379        }
1380    }
1381    LOGH("X ch_id = %u rc = %d", ch_id, rc);
1382    return rc;
1383
1384}
1385
1386/*===========================================================================
1387 * FUNCTION   : mm_camera_intf_request_super_buf
1388 *
1389 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1390 *              frames from superbuf queue
1391 *
1392 * PARAMETERS :
1393 *   @camera_handle: camera handle
1394 *   @ch_id             : channel handle
1395 *   @buf                : request buffer info
1396 *
1397 * RETURN     : int32_t type of status
1398 *              0  -- success
1399 *              -1 -- failure
1400 *==========================================================================*/
1401static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
1402        uint32_t ch_id, mm_camera_req_buf_t *buf)
1403{
1404    int32_t rc = -1;
1405    LOGD("E camera_handler = %d,ch_id = %d",
1406          camera_handle, ch_id);
1407    mm_camera_obj_t * my_obj = NULL;
1408    uint32_t chid = get_main_camera_handle(ch_id);
1409    uint32_t aux_chid = get_aux_camera_handle(ch_id);
1410
1411    pthread_mutex_lock(&g_intf_lock);
1412    if (aux_chid && chid) {
1413        uint32_t handle = get_main_camera_handle(camera_handle);
1414        my_obj = mm_camera_util_get_camera_by_handler(handle);
1415        if (my_obj && buf) {
1416            pthread_mutex_lock(&my_obj->muxer_lock);
1417            pthread_mutex_unlock(&g_intf_lock);
1418            rc = mm_camera_muxer_request_super_buf(
1419                    ch_id, buf, my_obj);
1420        } else {
1421            pthread_mutex_unlock(&g_intf_lock);
1422        }
1423    } else if (chid) {
1424        uint32_t handle = get_main_camera_handle(camera_handle);
1425        my_obj = mm_camera_util_get_camera_by_handler(handle);
1426
1427        if(my_obj && buf) {
1428            pthread_mutex_lock(&my_obj->cam_lock);
1429            pthread_mutex_unlock(&g_intf_lock);
1430            rc = mm_camera_request_super_buf (my_obj, chid, buf);
1431        } else {
1432            pthread_mutex_unlock(&g_intf_lock);
1433        }
1434    } else if (aux_chid) {
1435        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1436        my_obj = mm_camera_util_get_camera_by_handler(aux_handle);
1437
1438        if(my_obj && buf) {
1439            pthread_mutex_lock(&my_obj->cam_lock);
1440            pthread_mutex_unlock(&g_intf_lock);
1441            rc = mm_camera_request_super_buf (my_obj, aux_chid, buf);
1442        } else {
1443            pthread_mutex_unlock(&g_intf_lock);
1444        }
1445    }
1446
1447    LOGH("X ch_id = %u rc = %d", ch_id, rc);
1448    return rc;
1449}
1450
1451/*===========================================================================
1452 * FUNCTION   : mm_camera_intf_cancel_super_buf_request
1453 *
1454 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1455 *              of matched frames from superbuf queue
1456 *
1457 * PARAMETERS :
1458 *   @camera_handle: camera handle
1459 *   @ch_id        : channel handle
1460 *
1461 * RETURN     : int32_t type of status
1462 *              0  -- success
1463 *              -1 -- failure
1464 *==========================================================================*/
1465static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
1466                                                       uint32_t ch_id)
1467{
1468    int32_t rc = -1;
1469    LOGD("E camera_handler = %d,ch_id = %d",
1470          camera_handle, ch_id);
1471    mm_camera_obj_t * my_obj = NULL;
1472    uint32_t chid = get_main_camera_handle(ch_id);
1473    uint32_t aux_chid = get_aux_camera_handle(ch_id);
1474
1475    pthread_mutex_lock(&g_intf_lock);
1476    if (aux_chid && chid) {
1477        my_obj = mm_camera_util_get_camera_head(camera_handle);
1478        if (my_obj) {
1479            pthread_mutex_lock(&my_obj->muxer_lock);
1480            pthread_mutex_unlock(&g_intf_lock);
1481            rc = mm_camera_muxer_cancel_super_buf_request(
1482                    camera_handle, ch_id, my_obj);
1483        } else {
1484            pthread_mutex_unlock(&g_intf_lock);
1485        }
1486    } else if (aux_chid) {
1487        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1488        my_obj = mm_camera_util_get_camera_by_handler(aux_handle);
1489
1490        if(my_obj) {
1491            pthread_mutex_lock(&my_obj->cam_lock);
1492            pthread_mutex_unlock(&g_intf_lock);
1493            rc = mm_camera_cancel_super_buf_request(my_obj, chid);
1494        } else {
1495            pthread_mutex_unlock(&g_intf_lock);
1496        }
1497    } else if (chid) {
1498        uint32_t handle = get_main_camera_handle(camera_handle);
1499        my_obj = mm_camera_util_get_camera_by_handler(handle);
1500
1501        if(my_obj) {
1502            pthread_mutex_lock(&my_obj->cam_lock);
1503            pthread_mutex_unlock(&g_intf_lock);
1504            rc = mm_camera_cancel_super_buf_request(my_obj, chid);
1505        } else {
1506            pthread_mutex_unlock(&g_intf_lock);
1507        }
1508    }
1509
1510    LOGH("X ch_id = %u rc = %d", ch_id, rc);
1511    return rc;
1512}
1513
1514/*===========================================================================
1515 * FUNCTION   : mm_camera_intf_flush_super_buf_queue
1516 *
1517 * DESCRIPTION: flush out all frames in the superbuf queue
1518 *
1519 * PARAMETERS :
1520 *   @camera_handle: camera handle
1521 *   @ch_id        : channel handle
1522 *   @frame_idx    : frame index
1523 *
1524 * RETURN     : int32_t type of status
1525 *              0  -- success
1526 *              -1 -- failure
1527 *==========================================================================*/
1528static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
1529                                                    uint32_t ch_id, uint32_t frame_idx)
1530{
1531    int32_t rc = -1;
1532    mm_camera_obj_t * my_obj = NULL;
1533    uint32_t chid = get_main_camera_handle(ch_id);
1534    uint32_t aux_chid = get_aux_camera_handle(ch_id);
1535
1536    LOGD("E camera_handler = %d,ch_id = %d",
1537          camera_handle, ch_id);
1538    if (chid) {
1539        pthread_mutex_lock(&g_intf_lock);
1540        uint32_t handle = get_main_camera_handle(camera_handle);
1541        my_obj = mm_camera_util_get_camera_by_handler(handle);
1542        if(my_obj) {
1543            pthread_mutex_lock(&my_obj->cam_lock);
1544            pthread_mutex_unlock(&g_intf_lock);
1545            rc = mm_camera_flush_super_buf_queue(my_obj, chid, frame_idx);
1546        } else {
1547            pthread_mutex_unlock(&g_intf_lock);
1548        }
1549    }
1550
1551    if (aux_chid) {
1552        pthread_mutex_lock(&g_intf_lock);
1553        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1554        my_obj = mm_camera_util_get_camera_head(aux_handle);
1555        if (my_obj) {
1556            pthread_mutex_lock(&my_obj->muxer_lock);
1557            pthread_mutex_unlock(&g_intf_lock);
1558            rc = mm_camera_muxer_flush_super_buf_queue(aux_handle,
1559                    aux_chid, frame_idx, my_obj);
1560        } else {
1561            pthread_mutex_unlock(&g_intf_lock);
1562        }
1563    }
1564
1565    LOGH("X ch_id = %u rc = %d", ch_id, rc);
1566    return rc;
1567}
1568
1569/*===========================================================================
1570 * FUNCTION   : mm_camera_intf_start_zsl_snapshot
1571 *
1572 * DESCRIPTION: Starts zsl snapshot
1573 *
1574 * PARAMETERS :
1575 *   @camera_handle: camera handle
1576 *   @ch_id        : channel handle
1577 *
1578 * RETURN     : int32_t type of status
1579 *              0  -- success
1580 *              -1 -- failure
1581 *==========================================================================*/
1582static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
1583        uint32_t ch_id)
1584{
1585    int32_t rc = -1;
1586    mm_camera_obj_t *my_obj = NULL;
1587    uint32_t m_chid = get_main_camera_handle(ch_id);
1588    uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
1589
1590    LOGD("E camera_handler = %d,ch_id = %d",
1591          camera_handle, ch_id);
1592
1593    if (aux_ch_id) {
1594        pthread_mutex_lock(&g_intf_lock);
1595        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1596        my_obj = mm_camera_util_get_camera_head(aux_handle);
1597        if(my_obj) {
1598            pthread_mutex_lock(&my_obj->muxer_lock);
1599            pthread_mutex_unlock(&g_intf_lock);
1600            rc = mm_camera_muxer_start_zsl_snapshot(aux_handle,
1601                    aux_ch_id, my_obj);
1602        } else {
1603            pthread_mutex_unlock(&g_intf_lock);
1604        }
1605    }
1606
1607    if (m_chid) {
1608        uint32_t m_handle = get_main_camera_handle(camera_handle);
1609        pthread_mutex_lock(&g_intf_lock);
1610        my_obj = mm_camera_util_get_camera_by_handler(m_handle);
1611        if(my_obj) {
1612            pthread_mutex_lock(&my_obj->cam_lock);
1613            pthread_mutex_unlock(&g_intf_lock);
1614            rc = mm_camera_start_zsl_snapshot_ch(my_obj, m_chid);
1615        } else {
1616            pthread_mutex_unlock(&g_intf_lock);
1617        }
1618    }
1619    LOGD("X rc = %d", rc);
1620    return rc;
1621}
1622
1623/*===========================================================================
1624 * FUNCTION   : mm_camera_intf_stop_zsl_snapshot
1625 *
1626 * DESCRIPTION: Stops zsl snapshot
1627 *
1628 * PARAMETERS :
1629 *   @camera_handle: camera handle
1630 *   @ch_id        : channel handle
1631 *
1632 * RETURN     : int32_t type of status
1633 *              0  -- success
1634 *              -1 -- failure
1635 *==========================================================================*/
1636static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
1637        uint32_t ch_id)
1638{
1639    int32_t rc = -1;
1640    mm_camera_obj_t * my_obj = NULL;
1641    uint32_t m_chid = get_main_camera_handle(ch_id);
1642    uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
1643
1644    LOGD("E camera_handler = %d,ch_id = %d",
1645          camera_handle, ch_id);
1646
1647    if (aux_ch_id) {
1648        pthread_mutex_lock(&g_intf_lock);
1649        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1650        my_obj = mm_camera_util_get_camera_head(aux_handle);
1651        if(my_obj) {
1652            pthread_mutex_lock(&my_obj->muxer_lock);
1653            pthread_mutex_unlock(&g_intf_lock);
1654            rc = mm_camera_muxer_stop_zsl_snapshot(aux_handle, aux_ch_id, my_obj);
1655        } else {
1656            pthread_mutex_unlock(&g_intf_lock);
1657        }
1658    }
1659
1660    if (ch_id) {
1661        pthread_mutex_lock(&g_intf_lock);
1662        uint32_t handle = get_main_camera_handle(camera_handle);
1663        my_obj = mm_camera_util_get_camera_by_handler(handle);
1664        if(my_obj) {
1665            pthread_mutex_lock(&my_obj->cam_lock);
1666            pthread_mutex_unlock(&g_intf_lock);
1667            rc = mm_camera_stop_zsl_snapshot_ch(my_obj, m_chid);
1668        } else {
1669            pthread_mutex_unlock(&g_intf_lock);
1670        }
1671    }
1672
1673    LOGD("X rc = %d", rc);
1674    return rc;
1675}
1676
1677/*===========================================================================
1678 * FUNCTION   : mm_camera_intf_configure_notify_mode
1679 *
1680 * DESCRIPTION: Configures channel notification mode
1681 *
1682 * PARAMETERS :
1683 *   @camera_handle: camera handle
1684 *   @ch_id        : channel handle
1685 *   @notify_mode  : notification mode
1686 *
1687 * RETURN     : int32_t type of status
1688 *              0  -- success
1689 *              -1 -- failure
1690 *==========================================================================*/
1691static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
1692                                                    uint32_t ch_id,
1693                                                    mm_camera_super_buf_notify_mode_t notify_mode)
1694{
1695    int32_t rc = -1;
1696    mm_camera_obj_t * my_obj = NULL;
1697    uint32_t chid = get_main_camera_handle(ch_id);
1698    uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
1699
1700    LOGD("E camera_handler = %d,ch_id = %d",
1701          camera_handle, ch_id);
1702
1703    if (aux_ch_id) {
1704        pthread_mutex_lock(&g_intf_lock);
1705        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1706        my_obj = mm_camera_util_get_camera_head(aux_handle);
1707        if(my_obj) {
1708            pthread_mutex_lock(&my_obj->muxer_lock);
1709            pthread_mutex_unlock(&g_intf_lock);
1710            rc = mm_camera_muxer_configure_notify_mode(aux_handle, aux_ch_id,
1711                    notify_mode, my_obj);
1712        } else {
1713            pthread_mutex_unlock(&g_intf_lock);
1714        }
1715    }
1716
1717    if (chid) {
1718        pthread_mutex_lock(&g_intf_lock);
1719        uint32_t handle = get_main_camera_handle(camera_handle);
1720        my_obj = mm_camera_util_get_camera_by_handler(handle);
1721        if(my_obj) {
1722            pthread_mutex_lock(&my_obj->cam_lock);
1723            pthread_mutex_unlock(&g_intf_lock);
1724            rc = mm_camera_config_channel_notify(my_obj, chid,
1725                    notify_mode);
1726        } else {
1727            pthread_mutex_unlock(&g_intf_lock);
1728        }
1729    }
1730    LOGD("X rc = %d", rc);
1731    return rc;
1732}
1733
1734/*===========================================================================
1735 * FUNCTION   : mm_camera_intf_map_buf
1736 *
1737 * DESCRIPTION: mapping camera buffer via domain socket to server
1738 *
1739 * PARAMETERS :
1740 *   @camera_handle: camera handle
1741 *   @buf_type     : type of buffer to be mapped. could be following values:
1742 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1743 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1744 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1745 *   @fd           : file descriptor of the buffer
1746 *   @size         : size of the buffer
1747 *
1748 * RETURN     : int32_t type of status
1749 *              0  -- success
1750 *              -1 -- failure
1751 *==========================================================================*/
1752static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
1753    uint8_t buf_type, int fd, size_t size, void *buffer)
1754{
1755    int32_t rc = -1;
1756    mm_camera_obj_t *my_obj = NULL;
1757    uint32_t handle = get_main_camera_handle(camera_handle);
1758    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1759
1760    if (handle) {
1761        pthread_mutex_lock(&g_intf_lock);
1762        my_obj = mm_camera_util_get_camera_by_handler(handle);
1763
1764        if(my_obj) {
1765            pthread_mutex_lock(&my_obj->cam_lock);
1766            pthread_mutex_unlock(&g_intf_lock);
1767            rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
1768        } else {
1769            pthread_mutex_unlock(&g_intf_lock);
1770        }
1771    } else if (aux_handle) {
1772        pthread_mutex_lock(&g_intf_lock);
1773        my_obj = mm_camera_util_get_camera_head(aux_handle);
1774        if(my_obj) {
1775            pthread_mutex_lock(&my_obj->muxer_lock);
1776            pthread_mutex_unlock(&g_intf_lock);
1777            rc = mm_camera_muxer_map_buf(aux_handle, buf_type,
1778                    fd, size, buffer, my_obj);
1779        } else {
1780            pthread_mutex_unlock(&g_intf_lock);
1781        }
1782    }
1783    return rc;
1784}
1785
1786/*===========================================================================
1787 * FUNCTION   : mm_camera_intf_map_bufs
1788 *
1789 * DESCRIPTION: mapping camera buffer via domain socket to server
1790 *
1791 * PARAMETERS :
1792 *   @camera_handle: camera handle
1793 *   @buf_type     : type of buffer to be mapped. could be following values:
1794 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1795 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1796 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1797 *
1798 * RETURN     : int32_t type of status
1799 *              0  -- success
1800 *              -1 -- failure
1801 *==========================================================================*/
1802static int32_t mm_camera_intf_map_bufs(uint32_t camera_handle,
1803        const cam_buf_map_type_list *buf_map_list)
1804{
1805    int32_t rc = -1;
1806    mm_camera_obj_t * my_obj = NULL;
1807    uint32_t handle = get_main_camera_handle(camera_handle);
1808    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1809
1810    if (handle) {
1811        pthread_mutex_lock(&g_intf_lock);
1812        my_obj = mm_camera_util_get_camera_by_handler(handle);
1813        if(my_obj) {
1814            pthread_mutex_lock(&my_obj->cam_lock);
1815            pthread_mutex_unlock(&g_intf_lock);
1816            rc = mm_camera_map_bufs(my_obj, buf_map_list);
1817        } else {
1818            pthread_mutex_unlock(&g_intf_lock);
1819        }
1820    } else if (aux_handle) {
1821        pthread_mutex_lock(&g_intf_lock);
1822        my_obj = mm_camera_util_get_camera_head(aux_handle);
1823        if(my_obj) {
1824            pthread_mutex_lock(&my_obj->muxer_lock);
1825            pthread_mutex_unlock(&g_intf_lock);
1826            rc = mm_camera_muxer_map_bufs(aux_handle, buf_map_list, my_obj);
1827        } else {
1828            pthread_mutex_unlock(&g_intf_lock);
1829        }
1830    }
1831    return rc;
1832}
1833
1834/*===========================================================================
1835 * FUNCTION   : mm_camera_intf_unmap_buf
1836 *
1837 * DESCRIPTION: unmapping camera buffer via domain socket to server
1838 *
1839 * PARAMETERS :
1840 *   @camera_handle: camera handle
1841 *   @buf_type     : type of buffer to be unmapped. could be following values:
1842 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1843 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1844 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1845 *
1846 * RETURN     : int32_t type of status
1847 *              0  -- success
1848 *              -1 -- failure
1849 *==========================================================================*/
1850static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
1851                                        uint8_t buf_type)
1852{
1853    int32_t rc = -1;
1854    mm_camera_obj_t * my_obj = NULL;
1855    uint32_t handle = get_main_camera_handle(camera_handle);
1856    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1857
1858    if (handle) {
1859        pthread_mutex_lock(&g_intf_lock);
1860        my_obj = mm_camera_util_get_camera_by_handler(handle);
1861
1862        if(my_obj) {
1863            pthread_mutex_lock(&my_obj->cam_lock);
1864            pthread_mutex_unlock(&g_intf_lock);
1865            rc = mm_camera_unmap_buf(my_obj, buf_type);
1866        } else {
1867            pthread_mutex_unlock(&g_intf_lock);
1868        }
1869    }
1870
1871    if (aux_handle) {
1872        pthread_mutex_lock(&g_intf_lock);
1873        my_obj = mm_camera_util_get_camera_head(aux_handle);
1874        if(my_obj) {
1875            pthread_mutex_lock(&my_obj->muxer_lock);
1876            pthread_mutex_unlock(&g_intf_lock);
1877            rc = mm_camera_muxer_unmap_buf(aux_handle, buf_type, my_obj);
1878        } else {
1879            pthread_mutex_unlock(&g_intf_lock);
1880        }
1881    }
1882    return rc;
1883}
1884
1885/*===========================================================================
1886 * FUNCTION   : mm_camera_intf_set_stream_parms
1887 *
1888 * DESCRIPTION: set parameters per stream
1889 *
1890 * PARAMETERS :
1891 *   @camera_handle: camera handle
1892 *   @ch_id        : channel handle
1893 *   @s_id         : stream handle
1894 *   @parms        : ptr to a param struct to be set to server
1895 *
1896 * RETURN     : int32_t type of status
1897 *              0  -- success
1898 *              -1 -- failure
1899 * NOTE       : Assume the parms struct buf is already mapped to server via
1900 *              domain socket. Corresponding fields of parameters to be set
1901 *              are already filled in by upper layer caller.
1902 *==========================================================================*/
1903static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
1904                                               uint32_t ch_id,
1905                                               uint32_t s_id,
1906                                               cam_stream_parm_buffer_t *parms)
1907{
1908    int32_t rc = -1;
1909    mm_camera_obj_t * my_obj = NULL;
1910    uint32_t strid = get_main_camera_handle(s_id);
1911    uint32_t aux_strid = get_aux_camera_handle(s_id);
1912
1913    LOGD("E camera_handle = %d,ch_id = %d,s_id = %d",
1914          camera_handle, ch_id, s_id);
1915    if (strid) {
1916        pthread_mutex_lock(&g_intf_lock);
1917        uint32_t handle = get_main_camera_handle(camera_handle);
1918        uint32_t chid = get_main_camera_handle(ch_id);
1919
1920        my_obj = mm_camera_util_get_camera_by_handler(handle);
1921        if(my_obj) {
1922            pthread_mutex_lock(&my_obj->cam_lock);
1923            pthread_mutex_unlock(&g_intf_lock);
1924            rc = mm_camera_set_stream_parms(my_obj, chid, strid, parms);
1925        } else {
1926            pthread_mutex_unlock(&g_intf_lock);
1927        }
1928    }
1929
1930    if (aux_strid) {
1931        pthread_mutex_lock(&g_intf_lock);
1932        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1933        uint32_t aux_chid = get_aux_camera_handle(ch_id);
1934        my_obj = mm_camera_util_get_camera_head(aux_handle);
1935
1936        if (my_obj) {
1937            pthread_mutex_lock(&my_obj->muxer_lock);
1938            pthread_mutex_unlock(&g_intf_lock);
1939            rc = mm_camera_muxer_set_stream_parms(aux_handle, aux_chid,
1940                    aux_strid, parms, my_obj);
1941        } else {
1942            pthread_mutex_unlock(&g_intf_lock);
1943        }
1944    }
1945    LOGD("X rc = %d", rc);
1946    return rc;
1947}
1948
1949/*===========================================================================
1950 * FUNCTION   : mm_camera_intf_get_stream_parms
1951 *
1952 * DESCRIPTION: get parameters per stream
1953 *
1954 * PARAMETERS :
1955 *   @camera_handle: camera handle
1956 *   @ch_id        : channel handle
1957 *   @s_id         : stream handle
1958 *   @parms        : ptr to a param struct to be get from server
1959 *
1960 * RETURN     : int32_t type of status
1961 *              0  -- success
1962 *              -1 -- failure
1963 * NOTE       : Assume the parms struct buf is already mapped to server via
1964 *              domain socket. Parameters to be get from server are already
1965 *              filled in by upper layer caller. After this call, corresponding
1966 *              fields of requested parameters will be filled in by server with
1967 *              detailed information.
1968 *==========================================================================*/
1969static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
1970                                               uint32_t ch_id,
1971                                               uint32_t s_id,
1972                                               cam_stream_parm_buffer_t *parms)
1973{
1974    int32_t rc = -1;
1975    mm_camera_obj_t * my_obj = NULL;
1976    uint32_t strid = get_main_camera_handle(s_id);
1977    uint32_t aux_strid = get_aux_camera_handle(s_id);
1978
1979    LOGD("E camera_handle = %d,ch_id = %d,s_id = %d",
1980          camera_handle, ch_id, s_id);
1981    if (strid) {
1982        pthread_mutex_lock(&g_intf_lock);
1983        uint32_t handle = get_main_camera_handle(camera_handle);
1984        uint32_t chid = get_main_camera_handle(ch_id);
1985
1986        my_obj = mm_camera_util_get_camera_by_handler(handle);
1987        if(my_obj) {
1988            pthread_mutex_lock(&my_obj->cam_lock);
1989            pthread_mutex_unlock(&g_intf_lock);
1990            rc = mm_camera_get_stream_parms(my_obj, chid, strid, parms);
1991        } else {
1992            pthread_mutex_unlock(&g_intf_lock);
1993        }
1994    }
1995
1996    if (aux_strid) {
1997        pthread_mutex_lock(&g_intf_lock);
1998        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1999        uint32_t aux_chid = get_aux_camera_handle(ch_id);
2000
2001        my_obj = mm_camera_util_get_camera_head(aux_handle);
2002        if (my_obj) {
2003            pthread_mutex_lock(&my_obj->muxer_lock);
2004            pthread_mutex_unlock(&g_intf_lock);
2005            rc = mm_camera_muxer_get_stream_parms(aux_handle, aux_chid,
2006                    aux_strid, parms, my_obj);
2007        } else {
2008            pthread_mutex_unlock(&g_intf_lock);
2009        }
2010    }
2011    LOGD("X rc = %d", rc);
2012    return rc;
2013}
2014
2015/*===========================================================================
2016 * FUNCTION   : mm_camera_intf_map_stream_buf
2017 *
2018 * DESCRIPTION: mapping stream buffer via domain socket to server
2019 *
2020 * PARAMETERS :
2021 *   @camera_handle: camera handle
2022 *   @ch_id        : channel handle
2023 *   @s_id         : stream handle
2024 *   @buf_type     : type of buffer to be mapped. could be following values:
2025 *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
2026 *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
2027 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2028 *   @buf_idx      : index of buffer within the stream buffers, only valid if
2029 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
2030 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2031 *   @plane_idx    : plane index. If all planes share the same fd,
2032 *                   plane_idx = -1; otherwise, plean_idx is the
2033 *                   index to plane (0..num_of_planes)
2034 *   @fd           : file descriptor of the buffer
2035 *   @size         : size of the buffer
2036 *
2037 * RETURN     : int32_t type of status
2038 *              0  -- success
2039 *              -1 -- failure
2040 *==========================================================================*/
2041static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
2042        uint32_t ch_id, uint32_t stream_id, uint8_t buf_type,
2043        uint32_t buf_idx, int32_t plane_idx, int fd,
2044        size_t size, void *buffer)
2045{
2046    int32_t rc = -1;
2047    mm_camera_obj_t * my_obj = NULL;
2048    uint32_t strid = get_main_camera_handle(stream_id);
2049    uint32_t aux_strid = get_aux_camera_handle(stream_id);
2050
2051    LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
2052            camera_handle, ch_id, stream_id, buf_idx, plane_idx);
2053
2054    if (strid) {
2055        pthread_mutex_lock(&g_intf_lock);
2056        uint32_t handle = get_main_camera_handle(camera_handle);
2057        uint32_t chid = get_main_camera_handle(ch_id);
2058        my_obj = mm_camera_util_get_camera_by_handler(handle);
2059
2060        if(my_obj) {
2061            pthread_mutex_lock(&my_obj->cam_lock);
2062            pthread_mutex_unlock(&g_intf_lock);
2063            rc = mm_camera_map_stream_buf(my_obj, chid, strid,
2064                    buf_type, buf_idx, plane_idx,
2065                    fd, size, buffer);
2066        } else {
2067            pthread_mutex_unlock(&g_intf_lock);
2068        }
2069    }
2070
2071    if (aux_strid) {
2072        pthread_mutex_lock(&g_intf_lock);
2073        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2074        uint32_t aux_chid = get_aux_camera_handle(ch_id);
2075        my_obj = mm_camera_util_get_camera_head(aux_handle);
2076        if (my_obj) {
2077            pthread_mutex_lock(&my_obj->muxer_lock);
2078            pthread_mutex_unlock(&g_intf_lock);
2079            rc = mm_camera_muxer_map_stream_buf(aux_handle, aux_chid,
2080                    aux_strid, buf_type, buf_idx, plane_idx, fd, size,
2081                    buffer, my_obj);
2082        } else {
2083            pthread_mutex_unlock(&g_intf_lock);
2084        }
2085    }
2086
2087    LOGD("X rc = %d", rc);
2088    return rc;
2089}
2090
2091/*===========================================================================
2092 * FUNCTION   : mm_camera_intf_map_stream_bufs
2093 *
2094 * DESCRIPTION: mapping stream buffers via domain socket to server
2095 *
2096 * PARAMETERS :
2097 *   @camera_handle: camera handle
2098 *   @ch_id        : channel handle
2099 *   @buf_map_list : list of buffers to be mapped
2100 *
2101 * RETURN     : int32_t type of status
2102 *              0  -- success
2103 *              -1 -- failure
2104 *==========================================================================*/
2105static int32_t mm_camera_intf_map_stream_bufs(uint32_t camera_handle,
2106                                              uint32_t ch_id,
2107                                              const cam_buf_map_type_list *buf_map_list)
2108{
2109    int32_t rc = -1;
2110    uint32_t i;
2111    mm_camera_obj_t * my_obj = NULL;
2112    cam_buf_map_type_list m_buf_list, aux_buf_list;
2113
2114    LOGD("E camera_handle = %d, ch_id = %d",
2115          camera_handle, ch_id);
2116
2117    memset(&m_buf_list, 0, sizeof(m_buf_list));
2118    memset(&aux_buf_list, 0, sizeof(m_buf_list));
2119    for (i = 0; i < buf_map_list->length; i++) {
2120        uint32_t strid = get_main_camera_handle(buf_map_list->buf_maps[i].stream_id);
2121        uint32_t aux_strid = get_aux_camera_handle(buf_map_list->buf_maps[i].stream_id);
2122        if (strid) {
2123            m_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i];
2124            m_buf_list.buf_maps[aux_buf_list.length].stream_id = strid;
2125            m_buf_list.length++;
2126        }
2127        if (aux_strid) {
2128            aux_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i];
2129            aux_buf_list.buf_maps[aux_buf_list.length].stream_id = aux_strid;
2130            aux_buf_list.length++;
2131        }
2132    }
2133
2134    if(m_buf_list.length != 0) {
2135        pthread_mutex_lock(&g_intf_lock);
2136        uint32_t handle = get_main_camera_handle(camera_handle);
2137        uint32_t chid = get_main_camera_handle(ch_id);
2138        my_obj = mm_camera_util_get_camera_by_handler(handle);
2139        if(my_obj) {
2140            pthread_mutex_lock(&my_obj->cam_lock);
2141            pthread_mutex_unlock(&g_intf_lock);
2142            rc = mm_camera_map_stream_bufs(my_obj, chid, &m_buf_list);
2143        }else{
2144            pthread_mutex_unlock(&g_intf_lock);
2145        }
2146    }
2147
2148    if(aux_buf_list.length != 0) {
2149        pthread_mutex_lock(&g_intf_lock);
2150        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2151        uint32_t aux_chid = get_aux_camera_handle(ch_id);
2152        my_obj = mm_camera_util_get_camera_head(aux_handle);
2153        if (my_obj != NULL) {
2154            pthread_mutex_lock(&my_obj->muxer_lock);
2155            pthread_mutex_unlock(&g_intf_lock);
2156            rc = mm_camera_muxer_map_stream_bufs(aux_handle,aux_chid,
2157                    &aux_buf_list, my_obj);
2158        } else {
2159            pthread_mutex_unlock(&g_intf_lock);
2160        }
2161    }
2162    LOGD("X rc = %d", rc);
2163    return rc;
2164}
2165
2166/*===========================================================================
2167 * FUNCTION   : mm_camera_intf_unmap_stream_buf
2168 *
2169 * DESCRIPTION: unmapping stream buffer via domain socket to server
2170 *
2171 * PARAMETERS :
2172 *   @camera_handle: camera handle
2173 *   @ch_id        : channel handle
2174 *   @s_id         : stream handle
2175 *   @buf_type     : type of buffer to be unmapped. could be following values:
2176 *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
2177 *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
2178 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2179 *   @buf_idx      : index of buffer within the stream buffers, only valid if
2180 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
2181 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2182 *   @plane_idx    : plane index. If all planes share the same fd,
2183 *                   plane_idx = -1; otherwise, plean_idx is the
2184 *                   index to plane (0..num_of_planes)
2185 *
2186 * RETURN     : int32_t type of status
2187 *              0  -- success
2188 *              -1 -- failure
2189 *==========================================================================*/
2190static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
2191                                               uint32_t ch_id,
2192                                               uint32_t stream_id,
2193                                               uint8_t buf_type,
2194                                               uint32_t buf_idx,
2195                                               int32_t plane_idx)
2196{
2197    int32_t rc = -1;
2198    mm_camera_obj_t * my_obj = NULL;
2199    uint32_t strid = get_main_camera_handle(stream_id);
2200    uint32_t aux_strid = get_aux_camera_handle(stream_id);
2201
2202
2203    LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
2204              camera_handle, ch_id, stream_id, buf_idx, plane_idx);
2205
2206    if (aux_strid) {
2207        pthread_mutex_lock(&g_intf_lock);
2208        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2209        uint32_t aux_chid = get_aux_camera_handle(ch_id);
2210        my_obj = mm_camera_util_get_camera_head(aux_handle);
2211        if (my_obj) {
2212            pthread_mutex_lock(&my_obj->muxer_lock);
2213            pthread_mutex_unlock(&g_intf_lock);
2214            rc = mm_camera_muxer_unmap_stream_buf(aux_handle, aux_chid,
2215                   aux_strid, buf_type, buf_idx,
2216                   plane_idx, my_obj);
2217        } else {
2218            pthread_mutex_unlock(&g_intf_lock);
2219        }
2220    }
2221
2222    if (strid) {
2223        pthread_mutex_lock(&g_intf_lock);
2224        uint32_t handle = get_main_camera_handle(camera_handle);
2225        uint32_t chid = get_main_camera_handle(ch_id);
2226        my_obj = mm_camera_util_get_camera_by_handler(handle);
2227        if(my_obj) {
2228            pthread_mutex_lock(&my_obj->cam_lock);
2229            pthread_mutex_unlock(&g_intf_lock);
2230            rc = mm_camera_unmap_stream_buf(my_obj, chid, strid,
2231                    buf_type, buf_idx, plane_idx);
2232        }else{
2233            pthread_mutex_unlock(&g_intf_lock);
2234        }
2235    }
2236
2237    LOGD("X rc = %d", rc);
2238    return rc;
2239}
2240
2241/*===========================================================================
2242 * FUNCTION   : mm_camera_intf_get_session_id
2243 *
2244 * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
2245 *
2246 * PARAMETERS :
2247 *   @camera_handle: camera handle
2248 *   @sessionid: session id to be retrieved from server
2249 *
2250 * RETURN     : int32_t type of status
2251 *              0  -- success
2252 *              -1 -- failure
2253 * NOTE       : if this call succeeds, we will get a valid session id.
2254 *==========================================================================*/
2255static int32_t mm_camera_intf_get_session_id(uint32_t camera_handle,
2256                                                       uint32_t* sessionid)
2257{
2258    int32_t rc = -1;
2259    mm_camera_obj_t * my_obj = NULL;
2260    uint32_t handle = get_main_camera_handle(camera_handle);
2261    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2262
2263    if (handle) {
2264        pthread_mutex_lock(&g_intf_lock);
2265        my_obj = mm_camera_util_get_camera_by_handler(handle);
2266
2267        if(my_obj) {
2268            pthread_mutex_lock(&my_obj->cam_lock);
2269            pthread_mutex_unlock(&g_intf_lock);
2270            *sessionid = my_obj->sessionid;
2271            pthread_mutex_unlock(&my_obj->cam_lock);
2272            rc = 0;
2273        } else {
2274            pthread_mutex_unlock(&g_intf_lock);
2275        }
2276    } else if (aux_handle){
2277        pthread_mutex_lock(&g_intf_lock);
2278        my_obj = mm_camera_util_get_camera_head(aux_handle);
2279        if (my_obj) {
2280            pthread_mutex_lock(&my_obj->muxer_lock);
2281            pthread_mutex_unlock(&g_intf_lock);
2282            rc = mm_camera_muxer_get_session_id(aux_handle, sessionid, my_obj);
2283        } else {
2284            pthread_mutex_unlock(&g_intf_lock);
2285        }
2286    }
2287    return rc;
2288}
2289
2290/*===========================================================================
2291 * FUNCTION   : mm_camera_intf_set_dual_cam_cmd
2292 *
2293 * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
2294 *
2295 * PARAMETERS :
2296 *   @camera_handle: camera handle
2297 *   @related_cam_info: pointer to the related cam info to be sent to the server
2298 *
2299 * RETURN     : int32_t type of status
2300 *              0  -- success
2301 *              -1 -- failure
2302 * NOTE       : if this call succeeds, we will get linking established in back end
2303 *==========================================================================*/
2304static int32_t mm_camera_intf_set_dual_cam_cmd(uint32_t camera_handle)
2305{
2306    int32_t rc = -1;
2307    mm_camera_obj_t * my_obj = NULL;
2308    uint32_t handle = get_main_camera_handle(camera_handle);
2309    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2310
2311    if (handle) {
2312        pthread_mutex_lock(&g_intf_lock);
2313        my_obj = mm_camera_util_get_camera_by_handler(handle);
2314
2315        if(my_obj) {
2316            pthread_mutex_lock(&my_obj->cam_lock);
2317            pthread_mutex_unlock(&g_intf_lock);
2318            rc = mm_camera_set_dual_cam_cmd(my_obj);
2319        } else {
2320            pthread_mutex_unlock(&g_intf_lock);
2321        }
2322    }
2323
2324    if (aux_handle) {
2325        pthread_mutex_lock(&g_intf_lock);
2326        my_obj = mm_camera_util_get_camera_head(aux_handle);
2327        if (my_obj) {
2328            pthread_mutex_lock(&my_obj->muxer_lock);
2329            pthread_mutex_unlock(&g_intf_lock);
2330            rc = mm_camera_muxer_set_dual_cam_cmd(
2331                    aux_handle, my_obj);
2332        } else {
2333            pthread_mutex_unlock(&g_intf_lock);
2334        }
2335    }
2336    return rc;
2337}
2338
2339/*===========================================================================
2340 * FUNCTION   : get_sensor_info
2341 *
2342 * DESCRIPTION: get sensor info like facing(back/front) and mount angle
2343 *
2344 * PARAMETERS :
2345 *
2346 * RETURN     :
2347 *==========================================================================*/
2348void get_sensor_info()
2349{
2350    int rc = 0;
2351    int dev_fd = -1;
2352    struct media_device_info mdev_info;
2353    int num_media_devices = 0;
2354    size_t num_cameras = 0;
2355
2356    LOGD("E");
2357    while (1) {
2358        char dev_name[32];
2359        snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
2360        dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
2361        if (dev_fd < 0) {
2362            LOGD("Done discovering media devices\n");
2363            break;
2364        }
2365        num_media_devices++;
2366        memset(&mdev_info, 0, sizeof(mdev_info));
2367        rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
2368        if (rc < 0) {
2369            LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno));
2370            close(dev_fd);
2371            dev_fd = -1;
2372            num_cameras = 0;
2373            break;
2374        }
2375
2376        if(strncmp(mdev_info.model,  MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
2377            close(dev_fd);
2378            dev_fd = -1;
2379            continue;
2380        }
2381
2382        unsigned int num_entities = 1;
2383        while (1) {
2384            struct media_entity_desc entity;
2385            uint32_t temp;
2386            uint32_t mount_angle;
2387            uint32_t facing;
2388            int32_t type = 0;
2389            uint8_t is_yuv;
2390
2391            memset(&entity, 0, sizeof(entity));
2392            entity.id = num_entities++;
2393            rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
2394            if (rc < 0) {
2395                LOGD("Done enumerating media entities\n");
2396                rc = 0;
2397                break;
2398            }
2399            if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
2400                entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
2401                temp = entity.flags >> 8;
2402                mount_angle = (temp & 0xFF) * 90;
2403                facing = ((entity.flags & CAM_SENSOR_FACING_MASK) ?
2404                        CAMERA_FACING_FRONT:CAMERA_FACING_BACK);
2405
2406                if (entity.flags & CAM_SENSOR_TYPE_MASK) {
2407                    type = CAM_TYPE_AUX;
2408                } else {
2409                    type = CAM_TYPE_MAIN;
2410                }
2411
2412                is_yuv = ((entity.flags & CAM_SENSOR_FORMAT_MASK) ?
2413                        CAM_SENSOR_YUV:CAM_SENSOR_RAW);
2414                LOGL("index = %u flag = %x mount_angle = %u "
2415                        "facing = %u type: %u is_yuv = %u\n",
2416                        (unsigned int)num_cameras, (unsigned int)temp,
2417                        (unsigned int)mount_angle, (unsigned int)facing,
2418                        (unsigned int)type, (uint8_t)is_yuv);
2419                g_cam_ctrl.info[num_cameras].facing = (int)facing;
2420                g_cam_ctrl.info[num_cameras].orientation = (int)mount_angle;
2421                g_cam_ctrl.cam_type[num_cameras] = type;
2422                g_cam_ctrl.is_yuv[num_cameras] = is_yuv;
2423                LOGD("dev_info[id=%zu,name='%s']\n",
2424                         num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
2425                num_cameras++;
2426                continue;
2427            }
2428        }
2429        close(dev_fd);
2430        dev_fd = -1;
2431    }
2432
2433    LOGD("num_cameras=%d\n", g_cam_ctrl.num_cam);
2434    return;
2435}
2436
2437/*===========================================================================
2438 * FUNCTION   : sort_camera_info
2439 *
2440 * DESCRIPTION: sort camera info to keep back cameras idx is smaller than front cameras idx
2441 *
2442 * PARAMETERS : number of cameras
2443 *
2444 * RETURN     :
2445 *==========================================================================*/
2446void sort_camera_info(int num_cam)
2447{
2448    int idx = 0, i;
2449    struct camera_info temp_info[MM_CAMERA_MAX_NUM_SENSORS];
2450    cam_sync_type_t temp_type[MM_CAMERA_MAX_NUM_SENSORS];
2451    cam_sync_mode_t temp_mode[MM_CAMERA_MAX_NUM_SENSORS];
2452    uint8_t temp_is_yuv[MM_CAMERA_MAX_NUM_SENSORS];
2453    char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];
2454    uint32_t cam_idx[MM_CAMERA_MAX_NUM_SENSORS] = {0};
2455    uint8_t b_prime_idx = 0, b_aux_idx = 0, f_prime_idx = 0, f_aux_idx = 0;
2456    int8_t expose_aux = 0;
2457    char prop[PROPERTY_VALUE_MAX];
2458
2459    memset(temp_info, 0, sizeof(temp_info));
2460    memset(temp_dev_name, 0, sizeof(temp_dev_name));
2461    memset(temp_type, 0, sizeof(temp_type));
2462    memset(temp_mode, 0, sizeof(temp_mode));
2463    memset(temp_is_yuv, 0, sizeof(temp_is_yuv));
2464
2465    memset(prop, 0, sizeof(prop));
2466    property_get("persist.camera.expose.aux", prop, "0");
2467    expose_aux = atoi(prop);
2468
2469    /* Order of the camera exposed is
2470        0  - Back Main Camera
2471        1  - Front Main Camera
2472        ++  - Back Aux Camera
2473        ++  - Front Aux Camera
2474        ++  - Back Main + Back Aux camera
2475        ++  - Front Main + Front Aux camera
2476        ++  - Secure Camera
2477       */
2478    for (i = 0; i < num_cam; i++) {
2479        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
2480            (g_cam_ctrl.cam_type[i] == CAM_TYPE_MAIN)) {
2481            temp_info[idx] = g_cam_ctrl.info[i];
2482            temp_type[idx] = CAM_TYPE_MAIN;
2483            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
2484            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
2485            cam_idx[idx] = idx;
2486            b_prime_idx = idx;
2487            LOGH("Found Back Main Camera: i: %d idx: %d", i, idx);
2488            memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
2489                MM_CAMERA_DEV_NAME_LEN);
2490            idx++;
2491        }
2492    }
2493
2494    for (i = 0; i < num_cam; i++) {
2495        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
2496            (g_cam_ctrl.cam_type[i] == CAM_TYPE_MAIN)) {
2497            temp_info[idx] = g_cam_ctrl.info[i];
2498            temp_type[idx] = CAM_TYPE_MAIN;
2499            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
2500            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
2501            cam_idx[idx] = idx;
2502            f_prime_idx = idx;
2503            LOGH("Found Front Main Camera: i: %d idx: %d", i, idx);
2504            memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
2505                MM_CAMERA_DEV_NAME_LEN);
2506            idx++;
2507        }
2508    }
2509
2510    for (i = 0; i < num_cam; i++) {
2511        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
2512            (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
2513            && expose_aux) {
2514            temp_info[idx] = g_cam_ctrl.info[i];
2515            temp_type[idx] = CAM_TYPE_MAIN;
2516            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
2517            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
2518            cam_idx[idx] = idx;
2519            b_aux_idx = idx;
2520            LOGH("Found Back Aux Camera: i: %d idx: %d", i, idx);
2521            memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
2522                MM_CAMERA_DEV_NAME_LEN);
2523            idx++;
2524        }
2525    }
2526
2527    for (i = 0; i < num_cam; i++) {
2528        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
2529            (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
2530            && expose_aux) {
2531            temp_info[idx] = g_cam_ctrl.info[i];
2532            temp_type[idx] = CAM_TYPE_MAIN;
2533            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
2534            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
2535            cam_idx[idx] = idx;
2536            f_aux_idx = idx;
2537            LOGH("Found front Aux Camera: i: %d idx: %d", i, idx);
2538            memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
2539                MM_CAMERA_DEV_NAME_LEN);
2540            idx++;
2541        }
2542    }
2543
2544    for (i = 0; i < num_cam; i++) {
2545        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
2546            (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
2547            && expose_aux) { // Need Main check here after sensor change
2548            temp_info[idx] = g_cam_ctrl.info[i];
2549            temp_type[idx] = CAM_TYPE_MAIN | CAM_TYPE_AUX;
2550            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
2551            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
2552            cam_idx[idx] = (b_aux_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | b_prime_idx;
2553            LOGH("Found Back Main+AUX Camera: i: %d idx: %d", i, idx);
2554            memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
2555                MM_CAMERA_DEV_NAME_LEN);
2556            idx++;
2557        }
2558    }
2559
2560    for (i = 0; i < num_cam; i++) {
2561        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
2562            (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
2563            &&expose_aux) { // Need Main check here after sensor change
2564            temp_info[idx] = g_cam_ctrl.info[i];
2565            temp_type[idx] = CAM_TYPE_MAIN | CAM_TYPE_AUX;
2566            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
2567            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
2568            cam_idx[idx] = (f_aux_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | f_prime_idx;
2569            LOGH("Found Back Main Camera: i: %d idx: %d", i, idx);
2570            memcpy(temp_dev_name[idx],g_cam_ctrl.video_dev_name[i],
2571                MM_CAMERA_DEV_NAME_LEN);
2572            idx++;
2573        }
2574    }
2575
2576    /*NOTE: Add logic here to modify cameraID again here*/
2577
2578    if (idx != 0) {
2579        memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info));
2580        memcpy(g_cam_ctrl.cam_type, temp_type, sizeof(temp_type));
2581        memcpy(g_cam_ctrl.cam_mode, temp_mode, sizeof(temp_mode));
2582        memcpy(g_cam_ctrl.is_yuv, temp_is_yuv, sizeof(temp_is_yuv));
2583        memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name));
2584        memcpy(g_cam_ctrl.cam_index, cam_idx, (sizeof(uint32_t) * MM_CAMERA_MAX_NUM_SENSORS));
2585        //Set num cam based on the cameras exposed finally via dual/aux properties.
2586        g_cam_ctrl.num_cam = idx;
2587        for (i = 0; i < idx; i++) {
2588            LOGI("Camera id: %d facing: %d, type: %d is_yuv: %d",
2589                i, g_cam_ctrl.info[i].facing, g_cam_ctrl.cam_type[i], g_cam_ctrl.is_yuv[i]);
2590        }
2591    }
2592    LOGI("Number of cameras %d sorted %d", num_cam, idx);
2593    return;
2594}
2595
2596/*===========================================================================
2597 * FUNCTION   : get_num_of_cameras
2598 *
2599 * DESCRIPTION: get number of cameras
2600 *
2601 * PARAMETERS :
2602 *
2603 * RETURN     : number of cameras supported
2604 *==========================================================================*/
2605uint8_t get_num_of_cameras()
2606{
2607    int rc = 0;
2608    int dev_fd = -1;
2609    struct media_device_info mdev_info;
2610    int num_media_devices = 0;
2611    int8_t num_cameras = 0;
2612    char subdev_name[32];
2613    int32_t sd_fd = -1;
2614    struct sensor_init_cfg_data cfg;
2615    char prop[PROPERTY_VALUE_MAX];
2616
2617    LOGD("E");
2618
2619    property_get("vold.decrypt", prop, "0");
2620    int decrypt = atoi(prop);
2621    if (decrypt == 1)
2622     return 0;
2623    pthread_mutex_lock(&g_intf_lock);
2624
2625    memset (&g_cam_ctrl, 0, sizeof (g_cam_ctrl));
2626#ifndef DAEMON_PRESENT
2627    if (mm_camera_load_shim_lib() < 0) {
2628        LOGE ("Failed to module shim library");
2629        return 0;
2630    }
2631#endif /* DAEMON_PRESENT */
2632
2633    while (1) {
2634        uint32_t num_entities = 1U;
2635        char dev_name[32];
2636
2637        snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
2638        dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
2639        if (dev_fd < 0) {
2640            LOGD("Done discovering media devices\n");
2641            break;
2642        }
2643        num_media_devices++;
2644        rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
2645        if (rc < 0) {
2646            LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno));
2647            close(dev_fd);
2648            dev_fd = -1;
2649            break;
2650        }
2651
2652        if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
2653          sizeof(mdev_info.model)) != 0) {
2654            close(dev_fd);
2655            dev_fd = -1;
2656            continue;
2657        }
2658
2659        while (1) {
2660            struct media_entity_desc entity;
2661            memset(&entity, 0, sizeof(entity));
2662            entity.id = num_entities++;
2663            LOGD("entity id %d", entity.id);
2664            rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
2665            if (rc < 0) {
2666                LOGD("Done enumerating media entities");
2667                rc = 0;
2668                break;
2669            }
2670            LOGD("entity name %s type %d group id %d",
2671                entity.name, entity.type, entity.group_id);
2672            if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
2673                entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
2674                snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
2675                break;
2676            }
2677        }
2678        close(dev_fd);
2679        dev_fd = -1;
2680    }
2681
2682    /* Open sensor_init subdev */
2683    sd_fd = open(subdev_name, O_RDWR);
2684    if (sd_fd < 0) {
2685        LOGE("Open sensor_init subdev failed");
2686        return FALSE;
2687    }
2688
2689    cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
2690    cfg.cfg.setting = NULL;
2691    if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
2692        LOGE("failed");
2693    }
2694    close(sd_fd);
2695    dev_fd = -1;
2696
2697    num_media_devices = 0;
2698    while (1) {
2699        uint32_t num_entities = 1U;
2700        char dev_name[32];
2701
2702        snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
2703        dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
2704        if (dev_fd < 0) {
2705            LOGD("Done discovering media devices: %s\n", strerror(errno));
2706            break;
2707        }
2708        num_media_devices++;
2709        memset(&mdev_info, 0, sizeof(mdev_info));
2710        rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
2711        if (rc < 0) {
2712            LOGE("Error: ioctl media_dev failed: %s\n", strerror(errno));
2713            close(dev_fd);
2714            dev_fd = -1;
2715            num_cameras = 0;
2716            break;
2717        }
2718
2719        if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
2720            close(dev_fd);
2721            dev_fd = -1;
2722            continue;
2723        }
2724
2725        while (1) {
2726            struct media_entity_desc entity;
2727            memset(&entity, 0, sizeof(entity));
2728            entity.id = num_entities++;
2729            rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
2730            if (rc < 0) {
2731                LOGD("Done enumerating media entities\n");
2732                rc = 0;
2733                break;
2734            }
2735            if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
2736                strlcpy(g_cam_ctrl.video_dev_name[num_cameras],
2737                     entity.name, sizeof(entity.name));
2738                LOGI("dev_info[id=%d,name='%s']\n",
2739                    (int)num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
2740                num_cameras++;
2741                break;
2742            }
2743        }
2744        close(dev_fd);
2745        dev_fd = -1;
2746        if (num_cameras >= MM_CAMERA_MAX_NUM_SENSORS) {
2747            LOGW("Maximum number of camera reached %d", num_cameras);
2748            break;
2749        }
2750    }
2751    g_cam_ctrl.num_cam = num_cameras;
2752
2753    get_sensor_info();
2754    sort_camera_info(g_cam_ctrl.num_cam);
2755    /* unlock the mutex */
2756    pthread_mutex_unlock(&g_intf_lock);
2757    LOGI("num_cameras=%d\n", (int)g_cam_ctrl.num_cam);
2758    return(uint8_t)g_cam_ctrl.num_cam;
2759}
2760
2761/*===========================================================================
2762 * FUNCTION   : mm_camera_intf_process_advanced_capture
2763 *
2764 * DESCRIPTION: Configures channel advanced capture mode
2765 *
2766 * PARAMETERS :
2767 *   @camera_handle: camera handle
2768 *   @type : advanced capture type
2769 *   @ch_id        : channel handle
2770 *   @trigger  : 1 for start and 0 for cancel/stop
2771 *   @value  : input capture configaration
2772 *
2773 * RETURN     : int32_t type of status
2774 *              0  -- success
2775 *              -1 -- failure
2776 *==========================================================================*/
2777static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
2778        uint32_t ch_id, mm_camera_advanced_capture_t type,
2779        int8_t trigger, void *in_value)
2780{
2781    int32_t rc = -1;
2782    mm_camera_obj_t * my_obj = NULL;
2783    uint32_t chid = get_main_camera_handle(ch_id);
2784    uint32_t aux_chid = get_aux_camera_handle(ch_id);
2785
2786    LOGD("E camera_handler = %d,ch_id = %d",
2787          camera_handle, ch_id);
2788
2789    if (chid) {
2790        pthread_mutex_lock(&g_intf_lock);
2791        uint32_t handle = get_main_camera_handle(camera_handle);
2792        my_obj = mm_camera_util_get_camera_by_handler(handle);
2793
2794        if(my_obj) {
2795            pthread_mutex_lock(&my_obj->cam_lock);
2796            pthread_mutex_unlock(&g_intf_lock);
2797            rc = mm_camera_channel_advanced_capture(my_obj, chid, type,
2798                    (uint32_t)trigger, in_value);
2799        } else {
2800            pthread_mutex_unlock(&g_intf_lock);
2801        }
2802    }
2803
2804    if (aux_chid) {
2805        pthread_mutex_lock(&g_intf_lock);
2806        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2807        my_obj = mm_camera_util_get_camera_head(aux_handle);
2808        if (my_obj) {
2809            pthread_mutex_lock(&my_obj->muxer_lock);
2810            pthread_mutex_unlock(&g_intf_lock);
2811            rc = mm_camera_muxer_process_advanced_capture(aux_handle,
2812                    aux_chid, type, (uint32_t)trigger, in_value, my_obj);
2813        } else {
2814            pthread_mutex_unlock(&g_intf_lock);
2815        }
2816    }
2817    LOGH("X rc = %d ch_id = %u", rc, ch_id);
2818    return rc;
2819}
2820
2821/*===========================================================================
2822 * FUNCTION   : mm_camera_intf_register_stream_buf_cb
2823 *
2824 * DESCRIPTION: Register special callback for stream buffer
2825 *
2826 * PARAMETERS :
2827 *   @camera_handle: camera handle
2828 *   @ch_id        : channel handle
2829 *   @stream_id    : stream handle
2830 *   @buf_cb       : callback function
2831 *   @buf_type     :SYNC/ASYNC
2832 *   @userdata     : userdata pointer
2833 *
2834 * RETURN     : int32_t type of status
2835 *              0  -- success
2836 *              1 -- failure
2837 *==========================================================================*/
2838static int32_t mm_camera_intf_register_stream_buf_cb(uint32_t camera_handle,
2839        uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
2840        mm_camera_stream_cb_type cb_type, void *userdata)
2841{
2842    int32_t rc = 0;
2843    mm_camera_obj_t * my_obj = NULL;
2844    uint32_t strid = get_main_camera_handle(stream_id);
2845    uint32_t aux_strid = get_aux_camera_handle(stream_id);
2846
2847    LOGD("E handle = %u ch_id = %u",
2848          camera_handle, ch_id);
2849
2850    if (strid) {
2851        pthread_mutex_lock(&g_intf_lock);
2852        uint32_t handle = get_main_camera_handle(camera_handle);
2853        uint32_t chid = get_main_camera_handle(ch_id);
2854        my_obj = mm_camera_util_get_camera_by_handler(handle);
2855
2856        if(my_obj) {
2857            pthread_mutex_lock(&my_obj->cam_lock);
2858            pthread_mutex_unlock(&g_intf_lock);
2859            rc = mm_camera_reg_stream_buf_cb(my_obj, chid, strid,
2860                    buf_cb, cb_type, userdata);
2861        } else {
2862            pthread_mutex_unlock(&g_intf_lock);
2863        }
2864    }
2865
2866    if (aux_strid) {
2867        pthread_mutex_lock(&g_intf_lock);
2868        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
2869        uint32_t aux_chid = get_aux_camera_handle(ch_id);
2870        my_obj = mm_camera_util_get_camera_head(aux_handle);
2871
2872        if (my_obj) {
2873            pthread_mutex_lock(&my_obj->muxer_lock);
2874            pthread_mutex_unlock(&g_intf_lock);
2875            rc = mm_camera_muxer_register_stream_buf_cb(aux_handle,
2876                    aux_chid, aux_strid,
2877                    buf_cb, cb_type, userdata, my_obj);
2878        } else {
2879            pthread_mutex_unlock(&g_intf_lock);
2880        }
2881    }
2882    return (int32_t)rc;
2883}
2884
2885/*===========================================================================
2886 * FUNCTION   : mm_camera_intf_register_frame_sync
2887 *
2888 * DESCRIPTION: start frame buffer sync for the stream
2889 *
2890 * PARAMETERS :
2891 *   @camera_handle: camera handle
2892 *   @ch_id        : channel handle
2893 *   @stream_id    : stream handle
2894 *   @sync_attr     : frame sync attr
2895 *
2896 * RETURN     : int32_t type of status
2897 *              0  -- success
2898 *              1 -- failure
2899 *==========================================================================*/
2900static int32_t mm_camera_intf_reg_frame_sync(uint32_t camera_handle,
2901            uint32_t ch_id, uint32_t stream_id,
2902            mm_camera_intf_frame_sync_t *sync_attr)
2903{
2904    int32_t rc = 0;
2905    mm_camera_obj_t * my_obj = NULL;
2906
2907    LOGD("E handle = %u ch_id = %u stream_id = %u", camera_handle, ch_id, stream_id);
2908
2909    pthread_mutex_lock(&g_intf_lock);
2910    uint32_t handle = get_main_camera_handle(camera_handle);
2911    my_obj = mm_camera_util_get_camera_by_handler(handle);
2912    if(my_obj) {
2913        pthread_mutex_lock(&my_obj->muxer_lock);
2914        pthread_mutex_unlock(&g_intf_lock);
2915        rc = mm_camera_muxer_reg_frame_sync(my_obj,
2916                 ch_id, stream_id, sync_attr);
2917    } else {
2918        pthread_mutex_unlock(&g_intf_lock);
2919    }
2920    return (int32_t)rc;
2921}
2922
2923/*===========================================================================
2924 * FUNCTION   : mm_camera_intf_handle_frame_sync_cb
2925 *
2926 * DESCRIPTION: Handle callback request type incase of frame sync mode
2927 *
2928 * PARAMETERS :
2929 *   @camera_handle: camera handle
2930 *   @ch_id        : channel handle
2931 *   @stream_id    : stream handle
2932 *   @req_type    : callback request type
2933 *
2934 * RETURN     : int32_t type of status
2935 *              0  -- success
2936 *              1 -- failure
2937 *==========================================================================*/
2938static int32_t mm_camera_intf_handle_frame_sync_cb(uint32_t camera_handle,
2939        uint32_t ch_id, uint32_t stream_id, mm_camera_cb_req_type req_type)
2940{
2941    int32_t rc = 0;
2942    mm_camera_obj_t * my_obj = NULL;
2943
2944    uint32_t handle = get_main_camera_handle(camera_handle);
2945    uint32_t m_chid = get_main_camera_handle(ch_id);
2946    uint32_t m_strid = get_main_camera_handle(stream_id);
2947    LOGD("E handle = %u ch_id = %u stream_id = %u",
2948            camera_handle, ch_id, stream_id);
2949
2950    pthread_mutex_lock(&g_intf_lock);
2951    my_obj = mm_camera_util_get_camera_by_handler(handle);
2952    if(my_obj) {
2953        pthread_mutex_lock(&my_obj->cam_lock);
2954        pthread_mutex_unlock(&g_intf_lock);
2955        rc = mm_camera_handle_frame_sync_cb(my_obj, m_chid, m_strid, req_type);
2956    } else {
2957        pthread_mutex_unlock(&g_intf_lock);
2958    }
2959    LOGH("stream_id = %u rc = %d", stream_id, rc);
2960    return (int32_t)rc;
2961}
2962
2963struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType)
2964{
2965    *pCamType = g_cam_ctrl.cam_type[camera_id];
2966    return &g_cam_ctrl.info[camera_id];
2967}
2968
2969uint8_t is_dual_camera_by_idx(uint32_t camera_id)
2970{
2971    return ((g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_MAIN)
2972            && (g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_AUX));
2973}
2974
2975uint8_t is_dual_camera_by_handle(uint32_t handle)
2976{
2977    return ((handle >> MM_CAMERA_HANDLE_SHIFT_MASK)
2978            ? 1 : 0);
2979}
2980
2981uint32_t get_aux_camera_handle(uint32_t handle)
2982{
2983    return mm_camera_util_get_handle_by_num(1, handle);
2984}
2985
2986uint32_t get_main_camera_handle(uint32_t handle)
2987{
2988    return mm_camera_util_get_handle_by_num(0, handle);
2989}
2990
2991uint8_t is_yuv_sensor(uint32_t camera_id)
2992{
2993    return g_cam_ctrl.is_yuv[camera_id];
2994}
2995
2996uint8_t validate_handle(uint32_t src_handle, uint32_t handle)
2997{
2998    if ((src_handle == 0) || (handle == 0)) {
2999        return 0;
3000    }
3001    return ((src_handle == handle)
3002            || (get_main_camera_handle(src_handle) == handle)
3003            || (get_aux_camera_handle(src_handle) == handle)
3004            || (get_main_camera_handle(handle) == src_handle)
3005            || (get_aux_camera_handle(handle) == src_handle));
3006}
3007
3008/* camera ops v-table */
3009static mm_camera_ops_t mm_camera_ops = {
3010    .query_capability = mm_camera_intf_query_capability,
3011    .register_event_notify = mm_camera_intf_register_event_notify,
3012    .close_camera = mm_camera_intf_close,
3013    .set_parms = mm_camera_intf_set_parms,
3014    .get_parms = mm_camera_intf_get_parms,
3015    .do_auto_focus = mm_camera_intf_do_auto_focus,
3016    .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
3017    .prepare_snapshot = mm_camera_intf_prepare_snapshot,
3018    .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
3019    .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
3020    .map_buf = mm_camera_intf_map_buf,
3021    .map_bufs = mm_camera_intf_map_bufs,
3022    .unmap_buf = mm_camera_intf_unmap_buf,
3023    .add_channel = mm_camera_intf_add_channel,
3024    .delete_channel = mm_camera_intf_del_channel,
3025    .get_bundle_info = mm_camera_intf_get_bundle_info,
3026    .add_stream = mm_camera_intf_add_stream,
3027    .link_stream = mm_camera_intf_link_stream,
3028    .delete_stream = mm_camera_intf_del_stream,
3029    .config_stream = mm_camera_intf_config_stream,
3030    .qbuf = mm_camera_intf_qbuf,
3031    .cancel_buffer = mm_camera_intf_cancel_buf,
3032    .get_queued_buf_count = mm_camera_intf_get_queued_buf_count,
3033    .map_stream_buf = mm_camera_intf_map_stream_buf,
3034    .map_stream_bufs = mm_camera_intf_map_stream_bufs,
3035    .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
3036    .set_stream_parms = mm_camera_intf_set_stream_parms,
3037    .get_stream_parms = mm_camera_intf_get_stream_parms,
3038    .start_channel = mm_camera_intf_start_channel,
3039    .stop_channel = mm_camera_intf_stop_channel,
3040    .request_super_buf = mm_camera_intf_request_super_buf,
3041    .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
3042    .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
3043    .configure_notify_mode = mm_camera_intf_configure_notify_mode,
3044    .process_advanced_capture = mm_camera_intf_process_advanced_capture,
3045    .get_session_id = mm_camera_intf_get_session_id,
3046    .set_dual_cam_cmd = mm_camera_intf_set_dual_cam_cmd,
3047    .flush = mm_camera_intf_flush,
3048    .register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb,
3049    .register_frame_sync = mm_camera_intf_reg_frame_sync,
3050    .handle_frame_sync_cb = mm_camera_intf_handle_frame_sync_cb
3051};
3052
3053/*===========================================================================
3054 * FUNCTION   : camera_open
3055 *
3056 * DESCRIPTION: open a camera by camera index
3057 *
3058 * PARAMETERS :
3059 *   @camera_idx  : camera index. should within range of 0 to num_of_cameras
3060 *   @camera_vtbl : ptr to a virtual table containing camera handle and operation table.
3061 *
3062 * RETURN     : int32_t type of status
3063 *              0  -- success
3064 *              non-zero error code -- failure
3065 *==========================================================================*/
3066int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl)
3067{
3068    int32_t rc = 0;
3069    mm_camera_obj_t *cam_obj = NULL;
3070    uint32_t cam_idx = camera_idx;
3071    uint32_t aux_idx = 0;
3072    uint8_t is_multi_camera = 0;
3073
3074#ifdef QCAMERA_REDEFINE_LOG
3075    mm_camera_debug_open();
3076#endif
3077
3078    LOGD("E camera_idx = %d\n", camera_idx);
3079    if (is_dual_camera_by_idx(camera_idx)) {
3080        is_multi_camera = 1;
3081        cam_idx = mm_camera_util_get_handle_by_num(0,
3082                g_cam_ctrl.cam_index[camera_idx]);
3083        aux_idx = (get_aux_camera_handle(g_cam_ctrl.cam_index[camera_idx])
3084                >> MM_CAMERA_HANDLE_SHIFT_MASK);
3085        LOGH("Dual Camera: Main ID = %d Aux ID = %d", cam_idx, aux_idx);
3086    }
3087
3088    if (cam_idx >= (uint32_t)g_cam_ctrl.num_cam) {
3089        LOGE("Invalid camera_idx (%d)", cam_idx);
3090        return -EINVAL;
3091    }
3092
3093    pthread_mutex_lock(&g_intf_lock);
3094    /* opened already */
3095    if(NULL != g_cam_ctrl.cam_obj[cam_idx] &&
3096            g_cam_ctrl.cam_obj[cam_idx]->ref_count != 0) {
3097        pthread_mutex_unlock(&g_intf_lock);
3098        LOGE("Camera %d is already open", cam_idx);
3099        return -EBUSY;
3100    }
3101
3102    cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
3103    if(NULL == cam_obj) {
3104        pthread_mutex_unlock(&g_intf_lock);
3105        LOGE("no mem");
3106        return -EINVAL;
3107    }
3108
3109    /* initialize camera obj */
3110    memset(cam_obj, 0, sizeof(mm_camera_obj_t));
3111    cam_obj->ctrl_fd = -1;
3112    cam_obj->ds_fd = -1;
3113    cam_obj->ref_count++;
3114    cam_obj->my_num = 0;
3115    cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx);
3116    cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
3117    cam_obj->vtbl.ops = &mm_camera_ops;
3118    pthread_mutex_init(&cam_obj->cam_lock, NULL);
3119    pthread_mutex_init(&cam_obj->muxer_lock, NULL);
3120    /* unlock global interface lock, if not, in dual camera use case,
3121      * current open will block operation of another opened camera obj*/
3122    pthread_mutex_lock(&cam_obj->cam_lock);
3123    pthread_mutex_unlock(&g_intf_lock);
3124
3125    rc = mm_camera_open(cam_obj);
3126    if (rc != 0) {
3127        LOGE("mm_camera_open err = %d", rc);
3128        pthread_mutex_destroy(&cam_obj->cam_lock);
3129        pthread_mutex_lock(&g_intf_lock);
3130        g_cam_ctrl.cam_obj[cam_idx] = NULL;
3131        free(cam_obj);
3132        cam_obj = NULL;
3133        pthread_mutex_unlock(&g_intf_lock);
3134        *camera_vtbl = NULL;
3135        return rc;
3136    }
3137
3138    if (is_multi_camera) {
3139        /*Open Aux camer's*/
3140        pthread_mutex_lock(&g_intf_lock);
3141        if(NULL != g_cam_ctrl.cam_obj[aux_idx] &&
3142                g_cam_ctrl.cam_obj[aux_idx]->ref_count != 0) {
3143            pthread_mutex_unlock(&g_intf_lock);
3144            LOGE("Camera %d is already open", aux_idx);
3145            rc = -EBUSY;
3146        } else {
3147            pthread_mutex_lock(&cam_obj->muxer_lock);
3148            pthread_mutex_unlock(&g_intf_lock);
3149            rc = mm_camera_muxer_camera_open(aux_idx, cam_obj);
3150        }
3151        if (rc != 0) {
3152            LOGE("muxer open err = %d", rc);
3153            pthread_mutex_lock(&g_intf_lock);
3154            g_cam_ctrl.cam_obj[cam_idx] = NULL;
3155            pthread_mutex_lock(&cam_obj->cam_lock);
3156            pthread_mutex_unlock(&g_intf_lock);
3157            rc = mm_camera_close(cam_obj);
3158            pthread_mutex_destroy(&cam_obj->cam_lock);
3159            pthread_mutex_destroy(&cam_obj->muxer_lock);
3160            free(cam_obj);
3161            cam_obj = NULL;
3162            *camera_vtbl = NULL;
3163            return rc;
3164        }
3165    }
3166
3167    LOGH("Open succeded: handle = %d", cam_obj->vtbl.camera_handle);
3168    g_cam_ctrl.cam_obj[cam_idx] = cam_obj;
3169    *camera_vtbl = &cam_obj->vtbl;
3170    return 0;
3171}
3172
3173/*===========================================================================
3174 * FUNCTION   : mm_camera_load_shim_lib
3175 *
3176 * DESCRIPTION: Load shim layer library
3177 *
3178 * PARAMETERS :
3179 *
3180 * RETURN     : status of load shim library
3181 *==========================================================================*/
3182int32_t mm_camera_load_shim_lib()
3183{
3184    const char* error = NULL;
3185    void *qdaemon_lib = NULL;
3186
3187    LOGD("E");
3188    qdaemon_lib = dlopen(SHIMLAYER_LIB, RTLD_NOW);
3189    if (!qdaemon_lib) {
3190        error = dlerror();
3191        LOGE("dlopen failed with error %s", error ? error : "");
3192        return -1;
3193    }
3194
3195    *(void **)&mm_camera_shim_module_init =
3196            dlsym(qdaemon_lib, "mct_shimlayer_process_module_init");
3197    if (!mm_camera_shim_module_init) {
3198        error = dlerror();
3199        LOGE("dlsym failed with error code %s", error ? error: "");
3200        dlclose(qdaemon_lib);
3201        return -1;
3202    }
3203
3204    return mm_camera_shim_module_init(&g_cam_ctrl.cam_shim_ops);
3205}
3206
3207/*===========================================================================
3208 * FUNCTION   : mm_camera_module_open_session
3209 *
3210 * DESCRIPTION: wrapper function to call shim layer API to open session.
3211 *
3212 * PARAMETERS :
3213 *   @sessionid  : sessionID to open session
3214 *   @evt_cb     : Event callback function
3215 *
3216 * RETURN     : int32_t type of status
3217 *              0  -- success
3218 *              non-zero error code -- failure
3219 *==========================================================================*/
3220cam_status_t mm_camera_module_open_session(int sessionid,
3221        mm_camera_shim_event_handler_func evt_cb)
3222{
3223    cam_status_t rc = -1;
3224    if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session) {
3225        rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_open_session(
3226                sessionid, evt_cb);
3227    }
3228    return rc;
3229}
3230
3231/*===========================================================================
3232 * FUNCTION   : mm_camera_module_close_session
3233 *
3234 * DESCRIPTION: wrapper function to call shim layer API to close session
3235 *
3236 * PARAMETERS :
3237 *   @sessionid  : sessionID to open session
3238 *
3239 * RETURN     : int32_t type of status
3240 *              0  -- success
3241 *              non-zero error code -- failure
3242 *==========================================================================*/
3243int32_t mm_camera_module_close_session(int session)
3244{
3245    int32_t rc = -1;
3246    if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session) {
3247        rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_close_session(session);
3248    }
3249    return rc;
3250}
3251
3252/*===========================================================================
3253 * FUNCTION   : mm_camera_module_open_session
3254 *
3255 * DESCRIPTION: wrapper function to call shim layer API
3256 *
3257 * PARAMETERS :
3258 *   @sessionid  : sessionID to open session
3259 *   @evt_cb     : Event callback function
3260 *
3261 * RETURN     : int32_t type of status
3262 *              0  -- success
3263 *              non-zero error code -- failure
3264 *==========================================================================*/
3265int32_t mm_camera_module_send_cmd(cam_shim_packet_t *event)
3266{
3267    int32_t rc = -1;
3268    if(g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd) {
3269        rc = g_cam_ctrl.cam_shim_ops.mm_camera_shim_send_cmd(event);
3270    }
3271    return rc;
3272}
3273
3274/*===========================================================================
3275 * FUNCTION   : mm_camera_module_event_handler
3276 *
3277 * DESCRIPTION: call back function for shim layer
3278 *
3279 * PARAMETERS :
3280 *
3281 * RETURN     : status of call back function
3282 *==========================================================================*/
3283int mm_camera_module_event_handler(uint32_t session_id, cam_event_t *event)
3284{
3285    if (!event) {
3286        LOGE("null event");
3287        return FALSE;
3288    }
3289    mm_camera_event_t evt;
3290
3291    LOGD("session_id:%d, cmd:0x%x", session_id, event->server_event_type);
3292    memset(&evt, 0, sizeof(mm_camera_event_t));
3293
3294    evt = *event;
3295    mm_camera_obj_t *my_obj =
3296         mm_camera_util_get_camera_by_session_id(session_id);
3297    if (!my_obj) {
3298        LOGE("my_obj:%p", my_obj);
3299        return FALSE;
3300    }
3301    switch( evt.server_event_type) {
3302       case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
3303       case CAM_EVENT_TYPE_CAC_DONE:
3304       case CAM_EVENT_TYPE_DAEMON_DIED:
3305       case CAM_EVENT_TYPE_INT_TAKE_JPEG:
3306       case CAM_EVENT_TYPE_INT_TAKE_RAW:
3307           mm_camera_enqueue_evt(my_obj, &evt);
3308           break;
3309       default:
3310           LOGE("cmd:%x from shim layer is not handled", evt.server_event_type);
3311           break;
3312   }
3313   return TRUE;
3314}
3315
3316