1/* Copyright (c) 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 <dlfcn.h>
39#define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
40#include IOCTL_H
41
42// Camera dependencies
43#include "cam_semaphore.h"
44#include "mm_camera_dbg.h"
45#include "mm_camera_sock.h"
46#include "mm_camera_interface.h"
47#include "mm_camera_muxer.h"
48
49#define MAX_UNMATCHED_FOR_FRAME_SYNC 0
50
51extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler);
52extern mm_channel_t * mm_camera_util_get_channel_by_handler(mm_camera_obj_t *cam_obj,
53        uint32_t handler);
54extern mm_stream_t *mm_channel_util_get_stream_by_handler(mm_channel_t *ch_obj,
55        uint32_t handler);
56extern int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj);
57
58
59/*===========================================================================
60 * FUNCTION   : mm_camera_util_get_index_by_num
61 *
62 * DESCRIPTION: utility function to get index from handle
63 *
64 * PARAMETERS :
65 *   @cam_num : Camera number
66 *   @handler: object handle
67 *
68 * RETURN     : uint8_t type of index derived from handle
69 *==========================================================================*/
70uint8_t mm_camera_util_get_index_by_num(uint8_t cam_num, uint32_t handler)
71{
72    uint8_t idx = 0;
73    idx = ((mm_camera_util_get_handle_by_num(cam_num, handler) >>
74            (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num))
75            & 0x000000ff);
76    return idx;
77}
78
79/*===========================================================================
80 * FUNCTION   : mm_camera_util_get_handle_by_num
81 *
82 * DESCRIPTION: utility function to get handle for specific camera
83 *
84 * PARAMETERS :
85 *   @cam_num : Camera number
86 *   @handler : object handle
87 *
88 * RETURN     : return proper handle based on the object num
89 *==========================================================================*/
90uint32_t mm_camera_util_get_handle_by_num(uint8_t cam_num, uint32_t handler)
91{
92    return (handler & (MM_CAMERA_HANDLE_BIT_MASK <<
93            (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num)));
94}
95
96/*===========================================================================
97 * FUNCTION   : mm_camera_util_generate_handler_by_num
98 *
99 * DESCRIPTION: utility function to generate handler for camera/channel/stream
100 *
101 * PARAMETERS :
102 *   @cam_num : Camera number
103 *   @index   : index of the object to have handler
104 *
105 * RETURN     : uint32_t type of handle that uniquely identify the object
106 *==========================================================================*/
107uint32_t mm_camera_util_generate_handler_by_num(uint8_t cam_num, uint8_t index)
108{
109    uint32_t handler = mm_camera_util_generate_handler(index);
110    handler = (handler << (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num));
111    return handler;
112}
113
114/*===========================================================================
115 * FUNCTION   : mm_camera_util_get_dev_name_by_num
116 *
117 * DESCRIPTION: utility function to get device name from camera handle
118 *
119 * PARAMETERS :
120 *   @cam_handle: camera handle
121 *
122 * RETURN     : char ptr to the device name stored in global variable
123 * NOTE       : caller should not free the char ptr
124 *==========================================================================*/
125const char *mm_camera_util_get_dev_name_by_num(uint8_t cam_num, uint32_t cam_handle)
126{
127    uint32_t handle = (cam_handle >> (cam_num * MM_CAMERA_HANDLE_SHIFT_MASK));
128    return mm_camera_util_get_dev_name(handle);
129}
130
131/*===========================================================================
132 * FUNCTION   : mm_muxer_util_get_camera_by_obj
133 *
134 * DESCRIPTION: utility function to get camera object from object list
135 *
136 * PARAMETERS :
137 *   @cam_handle: camera handle
138 *   @cam_obj     : ptr to a Parent camera object
139 *
140 * RETURN     : ptr to the camera object stored in global variable
141 * NOTE       : caller should not free the camera object ptr
142 *==========================================================================*/
143mm_camera_obj_t* mm_muxer_util_get_camera_by_obj(uint32_t cam_handle,
144        mm_camera_obj_t *cam_obj)
145{
146    mm_camera_obj_t *obj = cam_obj;
147    uint8_t i = 0;
148
149    if (cam_handle == cam_obj->my_hdl) {
150        return cam_obj;
151    }
152
153    if (obj->master_cam_obj != NULL) {
154        obj = obj->master_cam_obj;
155    }
156    for (i = 0; i < obj->num_s_cnt; i++) {
157        if (cam_handle == obj->aux_cam_obj[i]->my_hdl) {
158            obj = obj->aux_cam_obj[i];
159            break;
160        }
161    }
162    return obj;
163}
164
165/*===========================================================================
166 * FUNCTION   : mm_muxer_util_get_channel_by_obj
167 *
168 * DESCRIPTION: utility function to get channel object from camera
169 *
170 * PARAMETERS :
171 *   @ch_id: channel handle
172 *   @cam_obj     : ptr to a Parent camera object
173 *
174 * RETURN     : ptr to the camera object stored in global variable
175 * NOTE       : caller should not free the camera object ptr
176 *==========================================================================*/
177mm_channel_t *mm_muxer_util_get_channel_by_obj(uint32_t ch_id,
178        mm_camera_obj_t *cam_obj)
179{
180    mm_camera_obj_t *obj = cam_obj;
181    mm_channel_t *ch_obj = NULL;
182    uint8_t i = 0;
183
184    if (obj->master_cam_obj != NULL) {
185        obj = obj->master_cam_obj;
186    }
187    while (obj != NULL) {
188        ch_obj = mm_camera_util_get_channel_by_handler(obj, ch_id);
189        if (ch_obj != NULL) {
190            break;
191        }
192        obj = obj->aux_cam_obj[i++];
193    }
194    return ch_obj;
195}
196
197/*===========================================================================
198 * FUNCTION   : mm_muxer_util_get_stream_by_obj
199 *
200 * DESCRIPTION: utility function to get stream object from camera
201 *
202 * PARAMETERS :
203 *   @stream_id: stream handle
204 *   @cam_obj     : ptr to a Parent camera object
205 *
206 * RETURN     : ptr to the camera object stored in global variable
207 * NOTE       : caller should not free the camera object ptr
208 *==========================================================================*/
209mm_stream_t *mm_muxer_util_get_stream_by_obj(uint32_t stream_id,
210        mm_camera_obj_t *cam_obj)
211{
212    mm_camera_obj_t *obj = cam_obj;
213    mm_stream_t *stream_obj = NULL;
214    uint8_t i = 0, j = 0;
215
216    if (obj->master_cam_obj != NULL) {
217        obj = obj->master_cam_obj;
218    }
219
220    while ((obj != NULL) && (stream_obj == NULL)) {
221        for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
222            stream_obj = mm_channel_util_get_stream_by_handler(
223                    &cam_obj->ch[i], stream_id);
224            if (stream_obj == NULL) {
225                break;
226            }
227        }
228        obj = obj->aux_cam_obj[j++];
229    }
230    return stream_obj;
231}
232
233/*===========================================================================
234 * FUNCTION   : mm_camera_muxer_camera_open
235 *
236 * DESCRIPTION: open a supporting camera by camera index
237 *
238 * PARAMETERS :
239 *   @cam_idx  : camera index. should within range of 0 to num_of_cameras
240 *   @cam_obj     : ptr to a Parent camera object
241 *
242 * RETURN     : int32_t type of status
243 *              0  -- success
244 *              non-zero error code -- failure
245 *==========================================================================*/
246int32_t mm_camera_muxer_camera_open(uint8_t cam_idx,
247        mm_camera_obj_t *cam_obj)
248{
249    int32_t rc = 0;
250    mm_camera_obj_t *my_obj = NULL;
251    uint8_t my_num = 1;
252
253    my_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
254    if(NULL == my_obj) {
255        pthread_mutex_unlock(&cam_obj->muxer_lock);
256        LOGE("no mem");
257        return -EINVAL;
258    }
259
260    /* initialize camera obj */
261    memset(my_obj, 0, sizeof(mm_camera_obj_t));
262    my_obj->ctrl_fd = -1;
263    my_obj->ds_fd = -1;
264    my_obj->ref_count++;
265    my_obj->my_num = my_num;
266    my_obj->my_hdl = mm_camera_util_generate_handler_by_num(my_num, cam_idx);
267    pthread_mutex_init(&my_obj->cam_lock, NULL);
268    /* unlock global interface lock, if not, in dual camera use case,
269      * current open will block operation of another opened camera obj*/
270    pthread_mutex_lock(&my_obj->cam_lock);
271    pthread_mutex_unlock(&cam_obj->muxer_lock);
272
273    rc = mm_camera_open(my_obj);
274    pthread_mutex_lock(&cam_obj->muxer_lock);
275    if (rc != 0) {
276        LOGE("mm_camera_open err = %d", rc);
277        pthread_mutex_destroy(&my_obj->cam_lock);
278        free(my_obj);
279        my_obj = NULL;
280        pthread_mutex_unlock(&cam_obj->muxer_lock);
281        return rc;
282    } else {
283        LOGD("Open succeded\n");
284        rc  = mm_camera_util_set_camera_object(cam_idx, my_obj);
285        my_obj->vtbl.camera_handle = (cam_obj->my_hdl | my_obj->my_hdl);
286        cam_obj->vtbl.camera_handle = my_obj->vtbl.camera_handle;
287        cam_obj->aux_cam_obj[cam_obj->num_s_cnt++] = my_obj;
288        my_obj->master_cam_obj = cam_obj;
289        cam_obj->master_cam_obj = NULL;
290        pthread_mutex_unlock(&cam_obj->muxer_lock);
291        return rc;
292    }
293}
294
295/*===========================================================================
296 * FUNCTION   : mm_camera_muxer_query_capability
297 *
298 * DESCRIPTION: query camera capability
299 *
300 * PARAMETERS :
301 *   @camera_handle: camera handle
302 *   @cam_obj     : ptr to a Parent camera object
303 *
304 * RETURN     : int32_t type of status
305 *              0  -- success
306 *              -1 -- failure
307 *==========================================================================*/
308int32_t mm_camera_muxer_query_capability(uint32_t camera_handle,
309        mm_camera_obj_t *cam_obj)
310{
311    int32_t rc = 0;
312    mm_camera_obj_t *my_obj = NULL;
313
314    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
315    if(my_obj) {
316        pthread_mutex_lock(&my_obj->cam_lock);
317        pthread_mutex_unlock(&cam_obj->muxer_lock);
318        rc = mm_camera_query_capability(my_obj);
319    } else {
320        pthread_mutex_unlock(&cam_obj->muxer_lock);
321    }
322    LOGD(" rc = %d", rc);
323    return rc;
324}
325
326/*===========================================================================
327 * FUNCTION   : mm_camera_muxer_register_event_notify
328 *
329 * DESCRIPTION: register for event notify
330 *
331 * PARAMETERS :
332 *   @camera_handle: camera handle
333 *   @evt_cb       : callback for event notify
334 *   @user_data    : user data ptr
335 *   @cam_obj     : ptr to a Parent camera object
336 *
337 * RETURN     : int32_t type of status
338 *              0  -- success
339 *              -1 -- failure
340 *==========================================================================*/
341int32_t mm_camera_muxer_register_event_notify(uint32_t camera_handle,
342        mm_camera_event_notify_t evt_cb,
343        void *user_data, mm_camera_obj_t *cam_obj)
344{
345    int32_t rc = 0;
346    mm_camera_obj_t *my_obj = NULL;
347
348    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
349    if(my_obj) {
350        pthread_mutex_lock(&my_obj->cam_lock);
351        pthread_mutex_unlock(&cam_obj->muxer_lock);
352        rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
353    } else {
354        pthread_mutex_unlock(&cam_obj->muxer_lock);
355    }
356    return rc;
357}
358
359/*===========================================================================
360 * FUNCTION   : mm_camera_muxer_close_camera
361 *
362 * DESCRIPTION: close a camera by its handle
363 *
364 * PARAMETERS :
365 *   @camera_handle: camera handle
366 *   @cam_obj     : ptr to a Parent camera object
367 *
368 * RETURN     : int32_t type of status
369 *              0  -- success
370 *              -1 -- failure
371 *==========================================================================*/
372int32_t mm_camera_muxer_close_camera(uint32_t camera_handle,
373        mm_camera_obj_t *cam_obj)
374{
375    int32_t rc = 0;
376    mm_camera_obj_t *my_obj = NULL;
377
378    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
379    if (my_obj){
380        uint8_t cam_idx = mm_camera_util_get_index_by_num(
381                my_obj->my_num, my_obj->my_hdl);
382        my_obj->ref_count--;
383        if(my_obj->ref_count > 0) {
384            LOGD("ref_count=%d\n", my_obj->ref_count);
385            pthread_mutex_unlock(&cam_obj->muxer_lock);
386            rc = 0;
387        } else {
388            rc  = mm_camera_util_set_camera_object(cam_idx, NULL);
389            pthread_mutex_lock(&my_obj->cam_lock);
390            pthread_mutex_unlock(&cam_obj->muxer_lock);
391            rc = mm_camera_close(my_obj);
392            pthread_mutex_destroy(&my_obj->cam_lock);
393            free(my_obj);
394            my_obj = NULL;
395        }
396    } else {
397        pthread_mutex_unlock(&cam_obj->muxer_lock);
398    }
399    return rc;
400}
401
402/*===========================================================================
403 * FUNCTION   : mm_camera_muxer_map_buf
404 *
405 * DESCRIPTION: mapping camera buffer via domain socket to server
406 *
407 * PARAMETERS :
408 *   @camera_handle: camera handle
409 *   @buf_type     : type of buffer to be mapped. could be following values:
410 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
411 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
412 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
413 *   @fd           : file descriptor of the buffer
414 *   @size         : size of the buffer
415 *   @cam_obj     : ptr to a Parent camera object
416 *
417 * RETURN     : int32_t type of status
418 *              0  -- success
419 *              -1 -- failure
420 *==========================================================================*/
421int32_t mm_camera_muxer_map_buf(uint32_t camera_handle, uint8_t buf_type,
422        int fd, size_t size, void *buffer, mm_camera_obj_t *cam_obj)
423{
424    int32_t rc = -1;
425    mm_camera_obj_t * my_obj = NULL;
426    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
427
428    if(my_obj) {
429        pthread_mutex_lock(&my_obj->cam_lock);
430        pthread_mutex_unlock(&cam_obj->muxer_lock);
431        rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
432    }else{
433        pthread_mutex_unlock(&cam_obj->muxer_lock);
434    }
435    return rc;
436}
437
438/*===========================================================================
439 * FUNCTION   : mm_camera_muxer_map_bufs
440 *
441 * DESCRIPTION: mapping camera buffer via domain socket to server
442 *
443 * PARAMETERS :
444 *   @camera_handle: camera handle
445 *   @buf_type     : type of buffer to be mapped. could be following values:
446 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
447 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
448 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
449 *   @cam_obj     : ptr to a Parent camera object
450 *
451 * RETURN     : int32_t type of status
452 *              0  -- success
453 *              -1 -- failure
454 *==========================================================================*/
455int32_t mm_camera_muxer_map_bufs(uint32_t camera_handle,
456        const cam_buf_map_type_list *buf_map_list,
457        mm_camera_obj_t *cam_obj)
458{
459    int32_t rc = -1;
460    mm_camera_obj_t * my_obj = NULL;
461    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
462
463    if(my_obj) {
464        pthread_mutex_lock(&my_obj->cam_lock);
465        pthread_mutex_unlock(&cam_obj->muxer_lock);
466        rc = mm_camera_map_bufs(my_obj, buf_map_list);
467    }else{
468        pthread_mutex_unlock(&cam_obj->muxer_lock);
469    }
470    return rc;
471}
472
473/*===========================================================================
474 * FUNCTION   : mm_camera_muxer_unmap_buf
475 *
476 * DESCRIPTION: unmapping camera buffer via domain socket to server
477 *
478 * PARAMETERS :
479 *   @camera_handle: camera handle
480 *   @buf_type     : type of buffer to be unmapped. could be following values:
481 *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
482 *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
483 *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
484 *   @cam_obj     : ptr to a Parent camera object
485 *
486 * RETURN     : int32_t type of status
487 *              0  -- success
488 *              -1 -- failure
489 *==========================================================================*/
490int32_t mm_camera_muxer_unmap_buf(uint32_t camera_handle,
491        uint8_t buf_type, mm_camera_obj_t *cam_obj)
492{
493    int32_t rc = -1;
494    mm_camera_obj_t * my_obj = NULL;
495    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
496
497    if(my_obj) {
498        pthread_mutex_lock(&my_obj->cam_lock);
499        pthread_mutex_unlock(&cam_obj->muxer_lock);
500        rc = mm_camera_unmap_buf(my_obj, buf_type);
501    }else{
502        pthread_mutex_unlock(&cam_obj->muxer_lock);
503    }
504    return rc;
505}
506
507/*===========================================================================
508 * FUNCTION   : mm_camera_muxer_set_parms
509 *
510 * DESCRIPTION: set parameters per camera
511 *
512 * PARAMETERS :
513 *   @camera_handle: camera handle
514 *   @parms        : ptr to a param struct to be set to server
515 *   @cam_obj     : ptr to a Parent camera object
516 *
517 * RETURN     : int32_t type of status
518 *              0  -- success
519 *              -1 -- failure
520 *==========================================================================*/
521int32_t mm_camera_muxer_set_parms(uint32_t camera_handle,
522        parm_buffer_t *parms, mm_camera_obj_t *cam_obj)
523{
524    int32_t rc = 0;
525    mm_camera_obj_t *my_obj = NULL;
526
527    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
528    if(my_obj) {
529        pthread_mutex_lock(&my_obj->cam_lock);
530        pthread_mutex_unlock(&cam_obj->muxer_lock);
531        rc = mm_camera_set_parms(my_obj, parms);
532    } else {
533        pthread_mutex_unlock(&cam_obj->muxer_lock);
534    }
535    return rc;
536}
537
538/*===========================================================================
539 * FUNCTION   : mm_camera_muxer_get_parms
540 *
541 * DESCRIPTION: get parameters per camera
542 *
543 * PARAMETERS :
544 *   @camera_handle: camera handle
545 *   @parms        : ptr to a param struct to be get from server
546 *   @cam_obj     : ptr to a Parent camera object
547 *
548 * RETURN     : int32_t type of status
549 *              0  -- success
550 *              -1 -- failure
551 *==========================================================================*/
552int32_t mm_camera_muxer_get_parms(uint32_t camera_handle,
553        parm_buffer_t *parms, mm_camera_obj_t *cam_obj)
554{
555    int32_t rc = 0;
556    mm_camera_obj_t *my_obj = NULL;
557
558    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
559    if(my_obj) {
560        pthread_mutex_lock(&my_obj->cam_lock);
561        pthread_mutex_unlock(&cam_obj->muxer_lock);
562        rc = mm_camera_get_parms(my_obj, parms);
563    } else {
564        pthread_mutex_unlock(&cam_obj->muxer_lock);
565    }
566    return rc;
567}
568
569/*===========================================================================
570 * FUNCTION   : mm_camera_muxer_do_auto_focus
571 *
572 * DESCRIPTION: performing auto focus
573 *
574 * PARAMETERS :
575 *   @camera_handle: camera handle
576 *   @cam_obj     : ptr to a Parent camera object
577 *
578 * RETURN     : int32_t type of status
579 *              0  -- success
580 *              -1 -- failure
581 *==========================================================================*/
582int32_t mm_camera_muxer_do_auto_focus(uint32_t camera_handle,
583        mm_camera_obj_t *cam_obj)
584{
585    int32_t rc = 0;
586    mm_camera_obj_t *my_obj = NULL;
587
588    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
589    if(my_obj) {
590        pthread_mutex_lock(&my_obj->cam_lock);
591        pthread_mutex_unlock(&cam_obj->muxer_lock);
592        rc = mm_camera_do_auto_focus(my_obj);
593    } else {
594        pthread_mutex_unlock(&cam_obj->muxer_lock);
595    }
596    return rc;
597}
598
599/*===========================================================================
600 * FUNCTION   : mm_camera_muxer_cancel_auto_focus
601 *
602 * DESCRIPTION: cancel auto focus
603 *
604 * PARAMETERS :
605 *   @camera_handle: camera handle
606 *   @cam_obj     : ptr to a Parent camera object
607 *
608 * RETURN     : int32_t type of status
609 *              0  -- success
610 *              -1 -- failure
611 *==========================================================================*/
612int32_t mm_camera_muxer_cancel_auto_focus(uint32_t camera_handle,
613        mm_camera_obj_t *cam_obj)
614{
615    int32_t rc = 0;
616    mm_camera_obj_t *my_obj = NULL;
617
618    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
619    if(my_obj) {
620        pthread_mutex_lock(&my_obj->cam_lock);
621        pthread_mutex_unlock(&cam_obj->muxer_lock);
622        rc = mm_camera_cancel_auto_focus(my_obj);
623    } else {
624        pthread_mutex_unlock(&cam_obj->muxer_lock);
625    }
626    return rc;
627}
628
629/*===========================================================================
630 * FUNCTION   : mm_camera_muxer_prepare_snapshot
631 *
632 * DESCRIPTION: prepare hardware for snapshot
633 *
634 * PARAMETERS :
635 *   @camera_handle: camera handle
636 *   @do_af_flag   : flag indicating if AF is needed
637 *   @cam_obj     : ptr to a Parent camera object
638 *
639 * RETURN     : int32_t type of status
640 *              0  -- success
641 *              -1 -- failure
642 *==========================================================================*/
643int32_t mm_camera_muxer_prepare_snapshot(uint32_t camera_handle,
644        int32_t do_af_flag, mm_camera_obj_t *cam_obj)
645{
646    int32_t rc = 0;
647    mm_camera_obj_t *my_obj = NULL;
648
649    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
650    if(my_obj) {
651        pthread_mutex_lock(&my_obj->cam_lock);
652        pthread_mutex_unlock(&cam_obj->muxer_lock);
653        rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
654    } else {
655        pthread_mutex_unlock(&cam_obj->muxer_lock);
656    }
657    return rc;
658}
659
660/*===========================================================================
661 * FUNCTION   : mm_camera_muxer_start_zsl_snapshot
662 *
663 * DESCRIPTION: Starts zsl snapshot
664 *
665 * PARAMETERS :
666 *   @camera_handle: camera handle
667 *   @ch_id        : channel handle
668 *   @cam_obj     : ptr to a Parent camera object
669 *
670 * RETURN     : int32_t type of status
671 *              0  -- success
672 *              -1 -- failure
673 *==========================================================================*/
674int32_t mm_camera_muxer_start_zsl_snapshot(uint32_t camera_handle,
675        uint32_t ch_id, mm_camera_obj_t *cam_obj)
676{
677    int32_t rc = 0;
678    mm_camera_obj_t *my_obj = NULL;
679
680    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
681    if(my_obj) {
682        uint32_t my_ch_id = mm_camera_util_get_handle_by_num(my_obj->my_num, ch_id);
683        pthread_mutex_lock(&my_obj->cam_lock);
684        pthread_mutex_unlock(&cam_obj->muxer_lock);
685        rc = mm_camera_start_zsl_snapshot_ch(my_obj, my_ch_id);
686    } else {
687        pthread_mutex_unlock(&cam_obj->muxer_lock);
688    }
689    return rc;
690}
691
692/*===========================================================================
693 * FUNCTION   : mm_camera_muxer_stop_zsl_snapshot
694 *
695 * DESCRIPTION: Starts zsl snapshot
696 *
697 * PARAMETERS :
698 *   @camera_handle: camera handle
699 *   @ch_id        : channel handle
700 *   @cam_obj     : ptr to a Parent camera object
701 *
702 * RETURN     : int32_t type of status
703 *              0  -- success
704 *              -1 -- failure
705 *==========================================================================*/
706int32_t mm_camera_muxer_stop_zsl_snapshot(uint32_t camera_handle,
707        uint32_t ch_id, mm_camera_obj_t *cam_obj)
708{
709    int32_t rc = 0;
710    mm_camera_obj_t *my_obj = NULL;
711
712    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
713    if(my_obj) {
714        uint32_t my_ch_id = mm_camera_util_get_handle_by_num(my_obj->my_num, ch_id);
715        pthread_mutex_lock(&my_obj->cam_lock);
716        pthread_mutex_unlock(&cam_obj->muxer_lock);
717        rc = mm_camera_stop_zsl_snapshot_ch(my_obj, my_ch_id);
718    } else {
719        pthread_mutex_unlock(&cam_obj->muxer_lock);
720    }
721    return rc;
722}
723
724/*===========================================================================
725 * FUNCTION   : mm_camera_muxer_add_channel
726 *
727 * DESCRIPTION: add a channel
728 *
729 * PARAMETERS :
730 *   @camera_handle: camera handle
731 *   @attr         : bundle attribute of the channel if needed
732 *   @channel_cb   : callback function for bundle data notify
733 *   @userdata     : user data ptr
734 *   @cam_obj     : ptr to a Parent camera object
735 *
736 * RETURN     : uint32_t type of channel handle
737 *              0  -- invalid channel handle, meaning the op failed
738 *              >0 -- successfully added a channel with a valid handle
739 *==========================================================================*/
740uint32_t mm_camera_muxer_add_channel(uint32_t camera_handle,
741        mm_camera_channel_attr_t *attr, mm_camera_buf_notify_t channel_cb,
742        void *userdata, uint32_t m_ch_id, mm_camera_obj_t *cam_obj)
743{
744    int32_t ch_id = 0;
745    mm_camera_obj_t *my_obj = NULL;
746
747    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
748    if(my_obj) {
749        pthread_mutex_lock(&my_obj->cam_lock);
750        pthread_mutex_unlock(&cam_obj->muxer_lock);
751        ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
752
753        if (ch_id > 0 && m_ch_id > 0) {
754            mm_camera_frame_sync_t frame_sync;
755            memset(&frame_sync, 0, sizeof(frame_sync));
756            frame_sync.a_cam_obj = my_obj;
757            frame_sync.a_ch_id = ch_id;
758            frame_sync.userdata = userdata;
759            frame_sync.a_stream_id = 0;
760            frame_sync.is_res_shared = 1;
761            if (attr != NULL) {
762                frame_sync.attr = *attr;
763                frame_sync.is_active = 1;
764            }
765            pthread_mutex_lock(&cam_obj->cam_lock);
766            mm_camera_reg_frame_sync(cam_obj, m_ch_id,
767                    0, &frame_sync);
768        }
769    } else {
770        pthread_mutex_unlock(&cam_obj->muxer_lock);
771    }
772    return ch_id;
773}
774
775/*===========================================================================
776 * FUNCTION   : mm_camera_muxer_delete_channel
777 *
778 * DESCRIPTION: delete a channel by its handle
779 *
780 * PARAMETERS :
781 *   @camera_handle: camera handle
782 *   @ch_id        : channel handle
783 *   @cam_obj     : ptr to a Parent camera object
784 *
785 * RETURN     : int32_t type of status
786 *              0  -- success
787 *              -1 -- failure
788 *==========================================================================*/
789int32_t mm_camera_muxer_delete_channel(uint32_t camera_handle, uint32_t ch_id,
790        mm_camera_obj_t *cam_obj)
791{
792    int32_t rc = -1;
793    mm_camera_obj_t *my_obj = NULL;
794
795    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
796    if(my_obj) {
797        pthread_mutex_lock(&my_obj->cam_lock);
798        pthread_mutex_unlock(&cam_obj->muxer_lock);
799        rc = mm_camera_del_channel(my_obj, ch_id);
800    } else {
801        pthread_mutex_unlock(&cam_obj->muxer_lock);
802    }
803    return rc;
804}
805
806/*===========================================================================
807 * FUNCTION   : mm_camera_muxer_get_bundle_info
808 *
809 * DESCRIPTION: query bundle info of the channel
810 *
811 * PARAMETERS :
812 *   @camera_handle: camera handle
813 *   @ch_id        : channel handle
814 *   @bundle_info  : bundle info to be filled in
815 *   @cam_obj     : ptr to a Parent camera object
816 *
817 * RETURN     : int32_t type of status
818 *              0  -- success
819 *              -1 -- failure
820 *==========================================================================*/
821int32_t mm_camera_muxer_get_bundle_info(uint32_t camera_handle, uint32_t ch_id,
822        cam_bundle_config_t *bundle_info, mm_camera_obj_t *cam_obj)
823{
824    int32_t rc = -1;
825    mm_camera_obj_t *my_obj = NULL;
826
827    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
828    if(my_obj) {
829        pthread_mutex_lock(&my_obj->cam_lock);
830        pthread_mutex_unlock(&cam_obj->muxer_lock);
831        rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
832    } else {
833        pthread_mutex_unlock(&cam_obj->muxer_lock);
834    }
835    return rc;
836}
837/*===========================================================================
838 * FUNCTION   : mm_camera_muxer_add_stream
839 *
840 * DESCRIPTION: add a stream into a channel
841 *
842 * PARAMETERS :
843 *   @camera_handle: camera handle
844 *   @ch_id        : channel handle
845 *   @src__ch_id        : src channel handle
846 *   @src_stream_id     :  src stream handle
847 *   @cam_obj     : ptr to a Parent camera object
848 *
849 * RETURN     : uint32_t type of stream handle
850 *              0  -- invalid stream handle, meaning the op failed
851 *              >0 -- successfully added a stream with a valid handle
852 *==========================================================================*/
853uint32_t mm_camera_muxer_add_stream(uint32_t camera_handle,
854        uint32_t ch_id, uint32_t src__ch_id, uint32_t src_stream_id, mm_camera_obj_t *cam_obj)
855{
856    uint32_t stream_id = 0;
857    int32_t rc = 0;
858    mm_camera_obj_t *my_obj = NULL;
859
860    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
861    if(my_obj) {
862        pthread_mutex_lock(&my_obj->cam_lock);
863        pthread_mutex_unlock(&cam_obj->muxer_lock);
864        stream_id = mm_camera_add_stream(my_obj, ch_id);
865        if (stream_id > 0 && src_stream_id > 0) {
866            mm_camera_frame_sync_t frame_sync;
867            memset(&frame_sync, 0, sizeof(frame_sync));
868            frame_sync.a_cam_obj = my_obj;
869            frame_sync.a_ch_id = ch_id;
870            frame_sync.userdata = NULL;
871            frame_sync.a_stream_id = stream_id;
872            frame_sync.buf_cb = NULL;
873            frame_sync.is_res_shared = 1;
874            frame_sync.is_active = 0;
875            pthread_mutex_lock(&cam_obj->cam_lock);
876            rc = mm_camera_reg_frame_sync(cam_obj, src__ch_id,
877                    src_stream_id, &frame_sync);
878            LOGH("Stream frame sync = %d and %d rc = %d",
879                    src_stream_id, stream_id, rc);
880        }
881    } else {
882        pthread_mutex_unlock(&cam_obj->muxer_lock);
883    }
884    return stream_id;
885}
886
887/*===========================================================================
888 * FUNCTION   : mm_camera_muxer_delete_stream
889 *
890 * DESCRIPTION: delete a stream by its handle
891 *
892 * PARAMETERS :
893 *   @camera_handle: camera handle
894 *   @ch_id        : channel handle
895 *   @stream_id    : stream handle
896 *
897 * RETURN     : int32_t type of status
898 *              0  -- success
899 *              -1 -- failure
900 *==========================================================================*/
901int32_t mm_camera_muxer_delete_stream(uint32_t camera_handle,
902        uint32_t ch_id, uint32_t stream_id,
903        mm_camera_obj_t *cam_obj)
904{
905    mm_camera_obj_t *my_obj = NULL;
906    int32_t rc = 0;
907
908    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
909    if(my_obj) {
910        pthread_mutex_lock(&my_obj->cam_lock);
911        pthread_mutex_unlock(&cam_obj->muxer_lock);
912        rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
913    } else {
914        pthread_mutex_unlock(&cam_obj->muxer_lock);
915    }
916    return rc;
917}
918
919/*===========================================================================
920 * FUNCTION   : mm_camera_muxer_link_stream
921 *
922 * DESCRIPTION: link a stream into a new channel
923 *
924 * PARAMETERS :
925 *   @camera_handle: camera handle
926 *   @ch_id        : channel handle
927 *   @stream_id    : stream id
928 *   @linked_ch_id : channel in which the stream will be linked
929 *
930 * RETURN     : int32_t type of stream handle
931 *              0  -- invalid stream handle, meaning the op failed
932 *              >0 -- successfully linked a stream with a valid handle
933 *==========================================================================*/
934int32_t mm_camera_muxer_link_stream(uint32_t camera_handle,
935        uint32_t ch_id, uint32_t stream_id, uint32_t linked_ch_id,
936        mm_camera_obj_t *cam_obj)
937{
938    uint32_t id = 0;
939    mm_camera_obj_t *my_obj = NULL;
940    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
941
942    if(my_obj) {
943        pthread_mutex_lock(&my_obj->cam_lock);
944        pthread_mutex_unlock(&cam_obj->muxer_lock);
945        id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
946    } else {
947        pthread_mutex_unlock(&cam_obj->muxer_lock);
948    }
949    return id;
950}
951
952/*===========================================================================
953 * FUNCTION   : mm_camera_muxer_config_stream
954 *
955 * DESCRIPTION: configure a stream
956 *
957 * PARAMETERS :
958 *   @camera_handle: camera handle
959 *   @ch_id        : channel handle
960 *   @stream_id    : stream handle
961 *   @config       : stream configuration
962 *
963 * RETURN     : int32_t type of status
964 *              0  -- success
965 *              -1 -- failure
966 *==========================================================================*/
967int32_t mm_camera_muxer_config_stream(uint32_t camera_handle,
968        uint32_t ch_id, uint32_t stream_id, mm_camera_stream_config_t *config,
969        mm_camera_obj_t *cam_obj)
970{
971    int32_t rc = -1;
972    mm_camera_obj_t * my_obj = NULL;
973    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
974    mm_camera_stream_config_t aux_config = *config;
975    LOGD("mm_camera_intf_config_stream stream_id = %d",stream_id);
976
977    if(my_obj) {
978        pthread_mutex_lock(&my_obj->cam_lock);
979        pthread_mutex_unlock(&cam_obj->muxer_lock);
980        if (config->stream_info->aux_str_info != NULL) {
981            aux_config.stream_info = config->stream_info->aux_str_info;
982            aux_config.mem_vtbl.get_bufs = NULL;
983            aux_config.mem_vtbl.put_bufs = NULL;
984            aux_config.mem_vtbl.set_config_ops = NULL;
985        }
986        rc = mm_camera_config_stream(my_obj, ch_id, stream_id, &aux_config);
987    } else {
988        pthread_mutex_unlock(&cam_obj->muxer_lock);
989    }
990    return rc;
991}
992
993/*===========================================================================
994 * FUNCTION   : mm_camera_muxer_map_stream_buf
995 *
996 * DESCRIPTION: mapping stream buffer via domain socket to server
997 *
998 * PARAMETERS :
999 *   @camera_handle: camera handle
1000 *   @ch_id        : channel handle
1001 *   @s_id         : stream handle
1002 *   @buf_type     : type of buffer to be mapped. could be following values:
1003 *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1004 *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1005 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1006 *   @buf_idx      : index of buffer within the stream buffers, only valid if
1007 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1008 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1009 *   @plane_idx    : plane index. If all planes share the same fd,
1010 *                   plane_idx = -1; otherwise, plean_idx is the
1011 *                   index to plane (0..num_of_planes)
1012 *   @fd           : file descriptor of the buffer
1013 *   @size         : size of the buffer
1014 *
1015 * RETURN     : int32_t type of status
1016 *              0  -- success
1017 *              -1 -- failure
1018 *==========================================================================*/
1019int32_t mm_camera_muxer_map_stream_buf(uint32_t camera_handle,
1020        uint32_t ch_id, uint32_t stream_id,
1021        uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, int fd,
1022        size_t size, void *buffer, mm_camera_obj_t *cam_obj)
1023{
1024    int32_t rc = -1;
1025    mm_camera_obj_t * my_obj = NULL;
1026    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1027
1028    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1029
1030    LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1031          camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1032
1033    if(my_obj) {
1034        pthread_mutex_lock(&my_obj->cam_lock);
1035        pthread_mutex_unlock(&cam_obj->muxer_lock);
1036        rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
1037                                  buf_type, buf_idx, plane_idx,
1038                                  fd, size, buffer);
1039    }else{
1040        pthread_mutex_unlock(&cam_obj->muxer_lock);
1041    }
1042    return rc;
1043}
1044
1045/*===========================================================================
1046 * FUNCTION   : mm_camera_muxer_map_stream_bufs
1047 *
1048 * DESCRIPTION: mapping stream buffers via domain socket to server
1049 *
1050 * PARAMETERS :
1051 *   @camera_handle: camera handle
1052 *   @ch_id        : channel handle
1053 *   @buf_map_list : list of buffers to be mapped
1054 *
1055 * RETURN     : int32_t type of status
1056 *              0  -- success
1057 *              -1 -- failure
1058 *==========================================================================*/
1059int32_t mm_camera_muxer_map_stream_bufs(uint32_t camera_handle,
1060        uint32_t ch_id, const cam_buf_map_type_list *buf_map_list,
1061        mm_camera_obj_t *cam_obj)
1062{
1063    int32_t rc = -1;
1064    mm_camera_obj_t *my_obj = NULL;
1065    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1066
1067    LOGD("E camera_handle = %d, ch_id = %d",
1068          camera_handle, ch_id);
1069
1070    if(my_obj) {
1071        pthread_mutex_lock(&my_obj->cam_lock);
1072        pthread_mutex_unlock(&cam_obj->muxer_lock);
1073        rc = mm_camera_map_stream_bufs(my_obj, ch_id, buf_map_list);
1074    }else{
1075        pthread_mutex_unlock(&cam_obj->muxer_lock);
1076    }
1077    return rc;
1078}
1079
1080/*===========================================================================
1081 * FUNCTION   : mm_camera_muxer_unmap_stream_buf
1082 *
1083 * DESCRIPTION: unmapping stream buffer via domain socket to server
1084 *
1085 * PARAMETERS :
1086 *   @camera_handle: camera handle
1087 *   @ch_id        : channel handle
1088 *   @s_id         : stream handle
1089 *   @buf_type     : type of buffer to be unmapped. could be following values:
1090 *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1091 *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1092 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1093 *   @buf_idx      : index of buffer within the stream buffers, only valid if
1094 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1095 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1096 *   @plane_idx    : plane index. If all planes share the same fd,
1097 *                   plane_idx = -1; otherwise, plean_idx is the
1098 *                   index to plane (0..num_of_planes)
1099 *
1100 * RETURN     : int32_t type of status
1101 *              0  -- success
1102 *              -1 -- failure
1103 *==========================================================================*/
1104int32_t mm_camera_muxer_unmap_stream_buf(uint32_t camera_handle,
1105        uint32_t ch_id, uint32_t stream_id,
1106        uint8_t buf_type, uint32_t buf_idx,
1107        int32_t plane_idx, mm_camera_obj_t *cam_obj)
1108{
1109    int32_t rc = -1;
1110    mm_camera_obj_t * my_obj = NULL;
1111    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1112
1113    LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1114          camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1115
1116    if(my_obj) {
1117        pthread_mutex_lock(&my_obj->cam_lock);
1118        pthread_mutex_unlock(&cam_obj->muxer_lock);
1119        rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
1120                buf_type, buf_idx, plane_idx);
1121    } else{
1122        pthread_mutex_unlock(&cam_obj->muxer_lock);
1123    }
1124    return rc;
1125}
1126
1127/*===========================================================================
1128 * FUNCTION   : mm_camera_muxer_set_stream_parms
1129 *
1130 * DESCRIPTION: set parameters per stream
1131 *
1132 * PARAMETERS :
1133 *   @camera_handle: camera handle
1134 *   @ch_id        : channel handle
1135 *   @s_id         : stream handle
1136 *   @parms        : ptr to a param struct to be set to server
1137 *
1138 * RETURN     : int32_t type of status
1139 *              0  -- success
1140 *              -1 -- failure
1141 *==========================================================================*/
1142int32_t mm_camera_muxer_set_stream_parms(uint32_t camera_handle,
1143        uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
1144        mm_camera_obj_t *cam_obj)
1145{
1146    int32_t rc = 0;
1147    mm_camera_obj_t * my_obj = NULL;
1148    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1149
1150    if(my_obj) {
1151        pthread_mutex_lock(&my_obj->cam_lock);
1152        pthread_mutex_unlock(&cam_obj->muxer_lock);
1153        rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
1154    } else{
1155        pthread_mutex_unlock(&cam_obj->muxer_lock);
1156    }
1157    return rc;
1158}
1159
1160/*===========================================================================
1161 * FUNCTION   : mm_camera_muxer_get_stream_parms
1162 *
1163 * DESCRIPTION: get parameters per stream
1164 *
1165 * PARAMETERS :
1166 *   @camera_handle: camera handle
1167 *   @ch_id        : channel handle
1168 *   @s_id         : stream handle
1169 *   @parms        : ptr to a param struct to be get from server
1170 *
1171 * RETURN     : int32_t type of status
1172 *              0  -- success
1173 *              -1 -- failure
1174 *==========================================================================*/
1175int32_t mm_camera_muxer_get_stream_parms(uint32_t camera_handle,
1176        uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
1177        mm_camera_obj_t *cam_obj)
1178{
1179    int32_t rc = 0;
1180    mm_camera_obj_t * my_obj = NULL;
1181    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1182
1183    if(my_obj) {
1184        pthread_mutex_lock(&my_obj->cam_lock);
1185        pthread_mutex_unlock(&cam_obj->muxer_lock);
1186        rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
1187    } else{
1188        pthread_mutex_unlock(&cam_obj->muxer_lock);
1189    }
1190    return rc;
1191}
1192
1193/*===========================================================================
1194 * FUNCTION   : mm_camera_muxer_start_channel
1195 *
1196 * DESCRIPTION: start a channel, which will start all streams in the channel
1197 *
1198 * PARAMETERS :
1199 *   @camera_handle: camera handle
1200 *   @ch_id        : channel handle
1201 *
1202 * RETURN     : int32_t type of status
1203 *              0  -- success
1204 *              -1 -- failure
1205 *==========================================================================*/
1206int32_t mm_camera_muxer_start_channel(uint32_t camera_handle,
1207        uint32_t ch_id, mm_camera_obj_t *cam_obj)
1208{
1209    int32_t rc = 0;
1210    mm_camera_obj_t * my_obj = NULL;
1211    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1212
1213    if(my_obj) {
1214        pthread_mutex_lock(&my_obj->cam_lock);
1215        pthread_mutex_unlock(&cam_obj->muxer_lock);
1216        rc = mm_camera_start_channel(my_obj, ch_id);
1217        if (rc == 0) {
1218            rc = mm_camera_start_sensor_stream_on(my_obj, ch_id);
1219        }
1220    } else{
1221        pthread_mutex_unlock(&cam_obj->muxer_lock);
1222    }
1223    return rc;
1224}
1225
1226/*===========================================================================
1227 * FUNCTION   : mm_camera_muxer_stop_channel
1228 *
1229 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1230 *
1231 * PARAMETERS :
1232 *   @camera_handle: camera handle
1233 *   @ch_id        : channel handle
1234 *
1235 * RETURN     : int32_t type of status
1236 *              0  -- success
1237 *              -1 -- failure
1238 *==========================================================================*/
1239int32_t mm_camera_muxer_stop_channel(uint32_t camera_handle,
1240        uint32_t ch_id, mm_camera_obj_t *cam_obj)
1241{
1242    int32_t rc = 0;
1243    mm_camera_obj_t * my_obj = NULL;
1244    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1245
1246    if(my_obj) {
1247        pthread_mutex_lock(&my_obj->cam_lock);
1248        pthread_mutex_unlock(&cam_obj->muxer_lock);
1249        rc = mm_camera_stop_channel(my_obj, ch_id, /*stop_immediately*/FALSE);
1250    } else{
1251        pthread_mutex_unlock(&cam_obj->muxer_lock);
1252    }
1253    return rc;
1254}
1255
1256/*===========================================================================
1257 * FUNCTION   : mm_camera_intf_qbuf
1258 *
1259 * DESCRIPTION: enqueue buffer back to kernel
1260 *
1261 * PARAMETERS :
1262 *   @camera_handle: camera handle
1263 *   @ch_id        : channel handle
1264 *   @buf          : buf ptr to be enqueued
1265 *
1266 * RETURN     : int32_t type of status
1267 *              0  -- success
1268 *              -1 -- failure
1269 *==========================================================================*/
1270int32_t mm_camera_muxer_qbuf(uint32_t camera_handle, uint32_t ch_id,
1271        mm_camera_buf_def_t *buf, mm_camera_obj_t *cam_obj)
1272{
1273    int32_t rc = 0;
1274    mm_camera_obj_t * my_obj = NULL;
1275
1276    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1277    if(my_obj) {
1278        pthread_mutex_lock(&my_obj->cam_lock);
1279        pthread_mutex_unlock(&cam_obj->muxer_lock);
1280        rc = mm_camera_qbuf(my_obj, ch_id, buf);
1281    } else {
1282        pthread_mutex_unlock(&cam_obj->muxer_lock);
1283    }
1284    return rc;
1285}
1286
1287/*===========================================================================
1288 * FUNCTION   : mm_camera_muxer_get_queued_buf_count
1289 *
1290 * DESCRIPTION: returns the queued buffer count
1291 *
1292 * PARAMETERS :
1293 *   @camera_handle: camera handle
1294 *   @ch_id        : channel handle
1295 *   @stream_id : stream id
1296 *
1297 * RETURN     : int32_t - queued buffer count
1298 *
1299 *==========================================================================*/
1300int32_t mm_camera_muxer_get_queued_buf_count(uint32_t camera_handle,
1301        uint32_t ch_id, uint32_t stream_id,
1302        mm_camera_obj_t *cam_obj)
1303{
1304    int32_t rc = 0;
1305    mm_camera_obj_t * my_obj = NULL;
1306
1307    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1308    if(my_obj) {
1309        pthread_mutex_lock(&my_obj->cam_lock);
1310        pthread_mutex_unlock(&cam_obj->muxer_lock);
1311        rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
1312    } else {
1313        pthread_mutex_unlock(&cam_obj->muxer_lock);
1314    }
1315    return rc;
1316}
1317
1318/*===========================================================================
1319 * FUNCTION   : mm_camera_muxer_request_super_buf
1320 *
1321 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1322 *              frames from superbuf queue
1323 *
1324 * PARAMETERS :
1325 *   @ch_id             : channel handle
1326 *   @buf                : request buffer info
1327 *
1328 * RETURN     : int32_t type of status
1329 *              0  -- success
1330 *              -1 -- failure
1331 *==========================================================================*/
1332int32_t mm_camera_muxer_request_super_buf(uint32_t ch_id,
1333        mm_camera_req_buf_t *buf, mm_camera_obj_t *cam_obj)
1334{
1335    int32_t rc = 0;
1336    mm_camera_obj_t * my_obj = cam_obj;
1337    uint32_t chID = get_main_camera_handle(ch_id);
1338
1339    if(my_obj && buf) {
1340        pthread_mutex_lock(&my_obj->cam_lock);
1341        pthread_mutex_unlock(&cam_obj->muxer_lock);
1342        buf->type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
1343        rc = mm_camera_request_super_buf (my_obj, chID, buf);
1344    } else {
1345        pthread_mutex_unlock(&cam_obj->muxer_lock);
1346    }
1347    return rc;
1348}
1349
1350/*===========================================================================
1351 * FUNCTION   : mm_camera_muxer_cancel_super_buf_request
1352 *
1353 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1354 *              frames from superbuf queue
1355 *
1356 * PARAMETERS :
1357 *   @camera_handle: camera handle
1358 *   @ch_id             : channel handle
1359 *   @buf                : request buffer info
1360 *
1361 * RETURN     : int32_t type of status
1362 *              0  -- success
1363 *              -1 -- failure
1364 *==========================================================================*/
1365int32_t mm_camera_muxer_cancel_super_buf_request(uint32_t camera_handle,
1366        uint32_t ch_id,
1367        mm_camera_obj_t *cam_obj)
1368{
1369    int32_t rc = 0;
1370    mm_camera_obj_t * my_obj = NULL;
1371    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1372    uint32_t aux_chID = get_main_camera_handle(ch_id);
1373
1374    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1375    if(my_obj) {
1376        pthread_mutex_lock(&my_obj->cam_lock);
1377        pthread_mutex_unlock(&cam_obj->muxer_lock);
1378        rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
1379    } else {
1380        pthread_mutex_unlock(&cam_obj->muxer_lock);
1381    }
1382
1383    my_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
1384    if(my_obj) {
1385        pthread_mutex_lock(&my_obj->cam_lock);
1386        pthread_mutex_unlock(&cam_obj->muxer_lock);
1387        rc = mm_camera_cancel_super_buf_request(my_obj, aux_chID);
1388    } else {
1389        pthread_mutex_unlock(&cam_obj->muxer_lock);
1390    }
1391    return rc;
1392}
1393
1394/*===========================================================================
1395 * FUNCTION   : mm_camera_muxer_flush_super_buf_queue
1396 *
1397 * DESCRIPTION: flush out all frames in the superbuf queue
1398 *
1399 * PARAMETERS :
1400 *   @camera_handle: camera handle
1401 *   @ch_id        : channel handle
1402 *   @frame_idx    : frame index
1403 *
1404 * RETURN     : int32_t type of status
1405 *              0  -- success
1406 *              -1 -- failure
1407 *==========================================================================*/
1408int32_t mm_camera_muxer_flush_super_buf_queue(uint32_t camera_handle,
1409        uint32_t ch_id,
1410        uint32_t frame_idx, mm_camera_obj_t *cam_obj)
1411{
1412    int32_t rc = 0;
1413    mm_camera_obj_t * my_obj = NULL;
1414    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1415
1416    if(my_obj) {
1417            pthread_mutex_lock(&my_obj->cam_lock);
1418            pthread_mutex_unlock(&cam_obj->muxer_lock);
1419            rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
1420    } else {
1421        pthread_mutex_unlock(&cam_obj->muxer_lock);
1422    }
1423    return rc;
1424}
1425
1426/*===========================================================================
1427 * FUNCTION   : mm_camera_muxer_configure_notify_mode
1428 *
1429 * DESCRIPTION: Configures channel notification mode
1430 *
1431 * PARAMETERS :
1432 *   @camera_handle: camera handle
1433 *   @ch_id        : channel handle
1434 *   @notify_mode  : notification mode
1435 *
1436 * RETURN     : int32_t type of status
1437 *              0  -- success
1438 *              -1 -- failure
1439 *==========================================================================*/
1440int32_t mm_camera_muxer_configure_notify_mode(uint32_t camera_handle,
1441        uint32_t ch_id, mm_camera_super_buf_notify_mode_t notify_mode,
1442        mm_camera_obj_t *cam_obj)
1443{
1444    int32_t rc = 0;
1445    mm_camera_obj_t * my_obj = NULL;
1446    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1447
1448    if(my_obj) {
1449            pthread_mutex_lock(&my_obj->cam_lock);
1450            pthread_mutex_unlock(&cam_obj->muxer_lock);
1451            rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
1452    } else {
1453        pthread_mutex_unlock(&cam_obj->muxer_lock);
1454    }
1455    return rc;
1456}
1457
1458/*===========================================================================
1459 * FUNCTION   : mm_camera_muxer_process_advanced_capture
1460 *
1461 * DESCRIPTION: Configures channel advanced capture mode
1462 *
1463 * PARAMETERS :
1464 *   @camera_handle: camera handle
1465 *   @type : advanced capture type
1466 *   @ch_id        : channel handle
1467 *   @trigger  : 1 for start and 0 for cancel/stop
1468 *   @value  : input capture configaration
1469 *
1470 * RETURN     : int32_t type of status
1471 *              0  -- success
1472 *              -1 -- failure
1473 *==========================================================================*/
1474int32_t mm_camera_muxer_process_advanced_capture(uint32_t camera_handle,
1475         uint32_t ch_id, mm_camera_advanced_capture_t type,
1476         int8_t start_flag, void *in_value, mm_camera_obj_t *cam_obj)
1477{
1478    int32_t rc = 0;
1479    mm_camera_obj_t * my_obj = NULL;
1480
1481    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1482    if(my_obj) {
1483        pthread_mutex_lock(&my_obj->cam_lock);
1484        pthread_mutex_unlock(&cam_obj->muxer_lock);
1485        rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
1486                (uint32_t)start_flag, in_value);
1487    } else {
1488        pthread_mutex_unlock(&cam_obj->muxer_lock);
1489    }
1490    return rc;
1491}
1492
1493/*===========================================================================
1494 * FUNCTION   : mm_camera_muxer_get_session_id
1495 *
1496 * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
1497 *
1498 * PARAMETERS :
1499 *   @camera_handle: camera handle
1500 *   @sessionid: session id to be retrieved from server
1501 *
1502 * RETURN     : int32_t type of status
1503 *              0  -- success
1504 *              -1 -- failure
1505 *==========================================================================*/
1506int32_t mm_camera_muxer_get_session_id(uint32_t camera_handle,
1507        uint32_t* sessionid, mm_camera_obj_t *cam_obj)
1508{
1509    int32_t rc = 0;
1510    mm_camera_obj_t * my_obj = NULL;
1511    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1512
1513    if(my_obj) {
1514        pthread_mutex_lock(&my_obj->cam_lock);
1515        pthread_mutex_unlock(&cam_obj->muxer_lock);
1516        *sessionid = my_obj->sessionid;
1517        pthread_mutex_unlock(&my_obj->cam_lock);
1518        rc = 0;
1519    } else {
1520        pthread_mutex_unlock(&cam_obj->muxer_lock);
1521    }
1522    return rc;
1523}
1524
1525 /*===========================================================================
1526 * FUNCTION   : mm_camera_muxer_flush
1527 *
1528 * DESCRIPTION: flush the current camera state and buffers
1529 *
1530 * PARAMETERS :
1531 *   @camera_handle: camera handle
1532 *
1533 * RETURN     : int32_t type of status
1534 *              0  -- success
1535 *              -1 -- failure
1536 *==========================================================================*/
1537int32_t mm_camera_muxer_flush(uint32_t camera_handle, mm_camera_obj_t *cam_obj)
1538{
1539    int32_t rc = 0;
1540    mm_camera_obj_t * my_obj = NULL;
1541    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1542
1543    if(my_obj) {
1544        pthread_mutex_lock(&my_obj->cam_lock);
1545        pthread_mutex_unlock(&cam_obj->muxer_lock);
1546        rc = mm_camera_flush(my_obj);
1547    } else {
1548        pthread_mutex_unlock(&cam_obj->muxer_lock);
1549    }
1550    return rc;
1551}
1552
1553/*===========================================================================
1554 * FUNCTION   : mm_camera_muxer_register_stream_buf_cb
1555 *
1556 * DESCRIPTION: Register special callback for stream buffer
1557 *
1558 * PARAMETERS :
1559 *   @camera_handle: camera handle
1560 *   @ch_id        : channel handle
1561 *   @stream_id    : stream handle
1562 *   @buf_cb       : callback function
1563 *   @buf_type     :SYNC/ASYNC
1564 *   @userdata     : userdata pointer
1565 *
1566 * RETURN     : int32_t type of status
1567 *              0  -- success
1568 *              1 -- failure
1569 *==========================================================================*/
1570int32_t mm_camera_muxer_register_stream_buf_cb(uint32_t camera_handle,
1571        uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
1572        mm_camera_stream_cb_type cb_type, void *userdata, mm_camera_obj_t *cam_obj)
1573{
1574    int32_t rc = 0;
1575    mm_camera_obj_t * my_obj = NULL;
1576    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1577
1578    if(my_obj) {
1579        pthread_mutex_lock(&my_obj->cam_lock);
1580        pthread_mutex_unlock(&cam_obj->muxer_lock);
1581        rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
1582                buf_cb, cb_type, userdata);
1583    } else {
1584        pthread_mutex_unlock(&cam_obj->muxer_lock);
1585    }
1586    return rc;
1587}
1588
1589/*===========================================================================
1590 * FUNCTION   : mm_camera_muxer_reg_frame_sync
1591 *
1592 * DESCRIPTION: Configure for frame sync.
1593 *
1594 * PARAMETERS :
1595 *   @camera_handle: camera handle
1596 *   @ch_id        : channel handle
1597 *   @stream_id    : stream handle
1598 *   @sync_attr    : Attributes for frame sync
1599 *
1600 * RETURN     : int32_t type of status
1601 *              0  -- success
1602 *              1 -- failure
1603 *==========================================================================*/
1604int32_t mm_camera_muxer_reg_frame_sync(mm_camera_obj_t *cam_obj,
1605        uint32_t ch_id, uint32_t stream_id,
1606        mm_camera_intf_frame_sync_t *sync_attr)
1607{
1608    int32_t rc = 0;
1609    mm_camera_obj_t *a_cam_obj = NULL;
1610
1611    mm_camera_frame_sync_t frame_sync;
1612    if (sync_attr == NULL || cam_obj == NULL) {
1613        pthread_mutex_unlock(&cam_obj->muxer_lock);
1614        return rc;
1615    }
1616
1617    uint32_t chid = get_main_camera_handle(ch_id);
1618    uint32_t aux_handle = get_aux_camera_handle(sync_attr->camera_handle);
1619    uint32_t aux_chid = get_aux_camera_handle(sync_attr->ch_id);
1620    uint32_t strid = 0;
1621    uint32_t aux_strid = 0;
1622    if (stream_id) {
1623        LOGD("Stream frame sync enabled");
1624        strid = get_main_camera_handle(stream_id);
1625        aux_strid = get_aux_camera_handle(sync_attr->stream_id);
1626        if(aux_strid == 0) {
1627            aux_handle = get_main_camera_handle(sync_attr->camera_handle);
1628            aux_chid = get_main_camera_handle(sync_attr->ch_id);
1629            aux_strid = get_main_camera_handle(sync_attr->stream_id);
1630        }
1631    } else {
1632        LOGD("Channel frame sync enabled");
1633        if(aux_chid == 0) {
1634            aux_chid = get_main_camera_handle(sync_attr->ch_id);
1635        }
1636    }
1637    a_cam_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
1638
1639    if(a_cam_obj) {
1640        memset(&frame_sync, 0, sizeof(frame_sync));
1641        frame_sync.a_cam_obj = a_cam_obj;
1642        frame_sync.a_stream_id = aux_strid;
1643        frame_sync.a_ch_id = aux_chid;
1644        frame_sync.userdata = sync_attr->userdata;
1645        frame_sync.buf_cb = sync_attr->buf_cb;
1646        frame_sync.attr = sync_attr->attr;
1647        pthread_mutex_lock(&cam_obj->cam_lock);
1648        pthread_mutex_unlock(&cam_obj->muxer_lock);
1649        rc = mm_camera_reg_frame_sync(cam_obj, chid, strid, &frame_sync);
1650    } else {
1651        pthread_mutex_unlock(&cam_obj->muxer_lock);
1652    }
1653    return rc;
1654}
1655
1656/*===========================================================================
1657 * FUNCTION   : mm_camera_muxer_set_dual_cam_cmd
1658 *
1659 * DESCRIPTION: send event to trigger read on dual camera cmd buffer
1660 *
1661 * PARAMETERS :
1662 *   @camera_handle: camera handle
1663 *   @cam_obj        : header object
1664 *
1665 * RETURN     : int32_t type of status
1666 *              0  -- success
1667 *              1 -- failure
1668 *==========================================================================*/
1669int32_t mm_camera_muxer_set_dual_cam_cmd(uint32_t camera_handle,
1670        mm_camera_obj_t *cam_obj)
1671{
1672    int32_t rc = 0;
1673    mm_camera_obj_t * my_obj = NULL;
1674    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1675
1676    if(my_obj) {
1677        pthread_mutex_lock(&my_obj->cam_lock);
1678        pthread_mutex_unlock(&cam_obj->muxer_lock);
1679        rc = mm_camera_set_dual_cam_cmd(my_obj);
1680    } else {
1681        pthread_mutex_unlock(&cam_obj->muxer_lock);
1682    }
1683    return rc;
1684}
1685
1686/*===========================================================================
1687 * FUNCTION   : mm_camera_muxer_stream_frame_sync
1688 *
1689 * DESCRIPTION: Handle stream buffers for frame sync
1690 *
1691 * PARAMETERS :
1692 *   @super_buf: Stream buffers
1693 *   @user_data        : Stream object
1694 *
1695 * RETURN     : none
1696 *==========================================================================*/
1697void mm_camera_muxer_stream_frame_sync(mm_camera_super_buf_t *super_buf,
1698        void *user_data)
1699{
1700    int32_t rc = 0, i = 0;
1701    mm_stream_t *my_obj = (mm_stream_t *)user_data;
1702    mm_frame_sync_queue_node_t dispatch_buf;
1703
1704    if ((super_buf == NULL) || (super_buf->num_bufs == 0)) {
1705        return;
1706    }
1707
1708    if (my_obj->master_str_obj != NULL) {
1709        my_obj = my_obj->master_str_obj;
1710    }
1711
1712    memset(&dispatch_buf, 0, sizeof(dispatch_buf));
1713    rc = mm_camera_muxer_do_frame_sync(&my_obj->frame_sync.superbuf_queue,
1714            super_buf, &dispatch_buf);
1715    if (rc < 0) {
1716        LOGE("frame sync failed");
1717        return;
1718    }
1719
1720    if (my_obj->frame_sync.super_buf_notify_cb && dispatch_buf.num_objs > 0) {
1721        mm_camera_super_buf_t super_buf;
1722        memset(&super_buf, 0, sizeof(super_buf));
1723        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
1724            if (dispatch_buf.super_buf[i].num_bufs == 1) {
1725                super_buf.bufs[super_buf.num_bufs++] =
1726                        dispatch_buf.super_buf[i].bufs[0];
1727                super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
1728                super_buf.ch_id = my_obj->ch_obj->my_hdl;
1729            }
1730        }
1731        pthread_mutex_lock(&my_obj->cb_lock);
1732        my_obj->frame_sync.super_buf_notify_cb(&super_buf,
1733                my_obj->frame_sync.user_data);
1734        pthread_mutex_unlock(&my_obj->cb_lock);
1735    }
1736}
1737
1738/*===========================================================================
1739 * FUNCTION   : mm_camera_muxer_channel_frame_sync
1740 *
1741 * DESCRIPTION: Handle channel super buffers for frame sync
1742 *
1743 * PARAMETERS :
1744 *   @super_buf: channel buffers
1745 *   @user_data        : channel object
1746 *
1747 * RETURN     : none
1748 *==========================================================================*/
1749void mm_camera_muxer_channel_frame_sync(mm_camera_super_buf_t *super_buf,
1750        void *user_data)
1751{
1752    int32_t rc = 0;
1753    mm_channel_t *ch_obj = (mm_channel_t *)user_data;
1754    mm_channel_t *m_obj = ch_obj;
1755
1756    if ((super_buf == NULL) || (super_buf->num_bufs == 0)) {
1757        return;
1758    }
1759
1760    if (m_obj->master_ch_obj != NULL) {
1761        m_obj = m_obj->master_ch_obj;
1762    }
1763
1764    rc = mm_camera_muxer_do_frame_sync(&m_obj->frame_sync.superbuf_queue,
1765            super_buf, NULL);
1766    mm_camera_muxer_channel_req_data_cb(NULL,
1767                ch_obj);
1768}
1769
1770
1771/*===========================================================================
1772 * FUNCTION   : mm_camera_muxer_channel_req_data_cb
1773 *
1774 * DESCRIPTION: Issue super buffer callback based on request setting
1775 *
1776 * PARAMETERS :
1777 *   @req_buf: buffer request setting
1778 *   @ch_obj        : channel object
1779 *
1780 * RETURN     : none
1781 *==========================================================================*/
1782int32_t mm_camera_muxer_channel_req_data_cb(mm_camera_req_buf_t *req_buf,
1783        mm_channel_t *ch_obj)
1784{
1785    int32_t rc = 0, i;
1786    mm_channel_t *m_obj = (mm_channel_t *)ch_obj;
1787    mm_frame_sync_queue_node_t* super_obj = NULL;
1788    mm_frame_sync_t *frame_sync = NULL;
1789    uint8_t trigger_cb = 0;
1790
1791    if (m_obj->master_ch_obj != NULL) {
1792        m_obj = m_obj->master_ch_obj;
1793    }
1794
1795    frame_sync = &m_obj->frame_sync;
1796    if (req_buf != NULL) {
1797        frame_sync->req_buf.num_buf_requested +=
1798                req_buf->num_buf_requested;
1799        frame_sync->req_buf.type = req_buf->type;
1800    }
1801
1802    while ((frame_sync->req_buf.num_buf_requested > 0)
1803            || (frame_sync->superbuf_queue.attr.notify_mode ==
1804            MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS)) {
1805        super_obj = mm_camera_muxer_frame_sync_dequeue(
1806                &frame_sync->superbuf_queue, frame_sync->req_buf.type);
1807        if (super_obj == NULL) {
1808            break;
1809        }
1810        if (frame_sync->super_buf_notify_cb && super_obj->num_objs != 0) {
1811            if (frame_sync->req_buf.type == MM_CAMERA_REQ_FRAME_SYNC_BUF) {
1812                for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
1813                    if (super_obj->super_buf[i].num_bufs != 0) {
1814                        frame_sync->super_buf_notify_cb(
1815                                &super_obj->super_buf[i],
1816                                frame_sync->user_data);
1817                    }
1818                }
1819                trigger_cb = 1;
1820            } else {
1821                for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
1822                    if (super_obj->super_buf[i].num_bufs != 0) {
1823                        if (super_obj->super_buf[i].ch_id ==
1824                                ch_obj->my_hdl) {
1825                            frame_sync->super_buf_notify_cb(
1826                                    &super_obj->super_buf[i],
1827                                    frame_sync->user_data);
1828                            trigger_cb = 1;
1829                        } else {
1830                            mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
1831                        }
1832                    }
1833                }
1834            }
1835            if ((m_obj->frame_sync.req_buf.num_buf_requested > 0)
1836                    && trigger_cb) {
1837                m_obj->frame_sync.req_buf.num_buf_requested--;
1838            }
1839        }
1840        free(super_obj);
1841    }
1842    return rc;
1843}
1844
1845/*===========================================================================
1846 * FUNCTION   : mm_camera_muxer_frame_sync_dequeue
1847 *
1848 * DESCRIPTION: dequeue object from frame sync queue
1849 *
1850 * PARAMETERS :
1851 *   @queue: ptr to queue to dequeue object
1852 *
1853 * RETURN     : ptr to a node from superbuf queue
1854 *==========================================================================*/
1855mm_frame_sync_queue_node_t *mm_camera_muxer_frame_sync_dequeue(
1856        mm_frame_sync_queue_t *queue, uint8_t matched_only)
1857{
1858    cam_node_t* node = NULL;
1859    struct cam_list *head = NULL;
1860    struct cam_list *pos = NULL;
1861    mm_frame_sync_queue_node_t* super_buf = NULL;
1862
1863    pthread_mutex_lock(&queue->que.lock);
1864    head = &queue->que.head.list;
1865    pos = head->next;
1866    if (pos != head) {
1867        /* get the first node */
1868        node = member_of(pos, cam_node_t, list);
1869        super_buf = (mm_frame_sync_queue_node_t*)node->data;
1870        if ( (NULL != super_buf) &&
1871             (matched_only == TRUE) &&
1872             (super_buf->matched == FALSE) ) {
1873            super_buf = NULL;
1874        }
1875
1876        if (NULL != super_buf) {
1877            queue->que.size--;
1878            cam_list_del_node(&node->list);
1879            free(node);
1880            if (super_buf->matched) {
1881                queue->match_cnt--;
1882            }
1883        }
1884    }
1885    pthread_mutex_unlock(&queue->que.lock);
1886    return super_buf;
1887}
1888
1889/*===========================================================================
1890 * FUNCTION   : mm_camera_muxer_do_frame_sync
1891 *
1892 * DESCRIPTION: function to process object buffers and match with existing frames.
1893 *
1894 * PARAMETERS :
1895 *   @queue: ptr to queue to dequeue object
1896 *   @buffer: Input buffer to match and insert
1897 *   @dispatch_buf        : Ptr to carry matched node
1898 *
1899 * RETURN     : int32_t type of status
1900 *              0  -- success
1901 *              1 -- failure
1902 *==========================================================================*/
1903int32_t mm_camera_muxer_do_frame_sync(
1904        mm_frame_sync_queue_t *queue, mm_camera_super_buf_t *buffer,
1905        mm_frame_sync_queue_node_t *dispatch_buf)
1906{
1907    cam_node_t* node = NULL;
1908    uint8_t buf_s_idx, i, found_super_buf, unmatched_bundles;
1909    struct cam_list *head = NULL;
1910    struct cam_list *pos = NULL;
1911    mm_frame_sync_queue_node_t* super_obj = NULL;
1912    struct cam_list *last_buf = NULL, *insert_before_buf = NULL;
1913
1914    if (buffer == NULL || buffer->num_bufs == 0) {
1915        LOGW("Ivalid Argument");
1916        return -1;
1917    }
1918
1919    for (buf_s_idx = 0; buf_s_idx < queue->num_objs; buf_s_idx++) {
1920        if ((buffer->ch_id == queue->bundled_objs[buf_s_idx]) ||
1921                (buffer->bufs[0]->stream_id == queue->bundled_objs[buf_s_idx])) {
1922            break;
1923        }
1924    }
1925    if (buf_s_idx == queue->num_objs) {
1926        LOGE("buf from stream (%d) not bundled", buffer->bufs[0]->stream_id);
1927        mm_camera_muxer_buf_done(buffer);
1928        return -1;
1929    }
1930
1931    if (buffer->bufs[0]->frame_idx <= queue->expected_frame_id) {
1932        LOGD("old frame. Need to release");
1933        mm_camera_muxer_buf_done(buffer);
1934        return 0;
1935    }
1936
1937    pthread_mutex_lock(&queue->que.lock);
1938    head = &queue->que.head.list;
1939    pos = head->next;
1940    found_super_buf = 0;
1941    unmatched_bundles = 0;
1942    last_buf = NULL;
1943    insert_before_buf = NULL;
1944
1945    while (pos != head) {
1946        node = member_of(pos, cam_node_t, list);
1947        super_obj = (mm_frame_sync_queue_node_t *)node->data;
1948        if (NULL != super_obj) {
1949            if (super_obj->matched == 1) {
1950                /* find a matched super buf, move to next one */
1951                pos = pos->next;
1952                continue;
1953            } else if (buffer->bufs[0]->frame_idx == super_obj->frame_idx) {
1954                found_super_buf = 1;
1955                break;
1956            } else if ((buffer->bufs[0]->frame_idx >= super_obj->frame_idx)
1957                    && (queue->attr.priority ==
1958                    MM_CAMERA_SUPER_BUF_PRIORITY_LOW)) {
1959                found_super_buf = 1;
1960                break;
1961            } else {
1962                unmatched_bundles++;
1963                if ( NULL == last_buf ) {
1964                    if ( super_obj->frame_idx < buffer->bufs[0]->frame_idx) {
1965                        last_buf = pos;
1966                    }
1967                }
1968                if ( NULL == insert_before_buf ) {
1969                    if ( super_obj->frame_idx > buffer->bufs[0]->frame_idx) {
1970                        insert_before_buf = pos;
1971                    }
1972                }
1973                pos = pos->next;
1974            }
1975        }
1976    }
1977
1978    LOGD("found_super_buf = %d id = %d unmatched cnt = %d match cnt = %d expected = %d max = %d",
1979            found_super_buf,
1980            buffer->bufs[0]->frame_idx, unmatched_bundles,
1981            queue->match_cnt, queue->expected_frame_id,
1982            queue->attr.max_unmatched_frames);
1983    if (found_super_buf) {
1984        super_obj->super_buf[buf_s_idx] = *buffer;
1985        super_obj->num_objs++;
1986        if (super_obj->num_objs == queue->num_objs) {
1987            super_obj->matched = 1;
1988            queue->expected_frame_id = super_obj->frame_idx;
1989            if (dispatch_buf != NULL) {
1990                *dispatch_buf = *super_obj;
1991                queue->que.size--;
1992                cam_list_del_node(&node->list);
1993                free(node);
1994                free(super_obj);
1995            } else {
1996                queue->match_cnt++;
1997            }
1998        }
1999        /* Any older unmatched buffer need to be released */
2000        if ( last_buf ) {
2001            while (last_buf != pos ) {
2002                node = member_of(last_buf, cam_node_t, list);
2003                super_obj = (mm_frame_sync_queue_node_t*)node->data;
2004                if (NULL != super_obj) {
2005                    for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2006                        if (super_obj->super_buf[i].num_bufs != 0) {
2007                            mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2008                        }
2009                    }
2010                    queue->que.size--;
2011                    last_buf = last_buf->next;
2012                    cam_list_del_node(&node->list);
2013                    free(node);
2014                    free(super_obj);
2015                }
2016            }
2017        }
2018    } else {
2019        if ((queue->attr.max_unmatched_frames < unmatched_bundles)
2020                && (NULL == last_buf)) {
2021            //incoming frame is older than the last bundled one
2022            mm_camera_muxer_buf_done(buffer);
2023            pthread_mutex_unlock(&queue->que.lock);
2024            return 0;
2025        } else if (queue->attr.max_unmatched_frames < unmatched_bundles) {
2026            //dispatch old buffer. Cannot sync for configured unmatch value
2027            node = member_of(last_buf, cam_node_t, list);
2028            super_obj = (mm_frame_sync_queue_node_t*)node->data;
2029            if (super_obj != NULL) {
2030                queue->expected_frame_id = super_obj->frame_idx;
2031                if (dispatch_buf != NULL) {
2032                    //Dispatch unmatched buffer
2033                    *dispatch_buf = *super_obj;
2034                } else {
2035                    //release unmatched buffers
2036                    for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2037                        if (super_obj->super_buf[i].num_bufs != 0) {
2038                            mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2039                        }
2040                    }
2041                }
2042            }
2043            queue->que.size--;
2044            cam_list_del_node(&node->list);
2045            free(node);
2046            free(super_obj);
2047            super_obj = NULL;
2048        }
2049
2050        //insert the new frame at the appropriate position.
2051        mm_frame_sync_queue_node_t *new_buf = NULL;
2052        cam_node_t* new_node = NULL;
2053        new_buf = (mm_frame_sync_queue_node_t *)
2054                malloc(sizeof(mm_frame_sync_queue_node_t));
2055        if (NULL != new_buf) {
2056            memset(new_buf, 0, sizeof(mm_frame_sync_queue_node_t));
2057            new_buf->super_buf[buf_s_idx] = *buffer;
2058            new_buf->num_objs++;
2059            new_buf->frame_idx = buffer->bufs[0]->frame_idx;
2060            new_buf->matched = 0;
2061            if (new_buf->num_objs == queue->num_objs && super_obj) {
2062                new_buf->matched = 1;
2063                queue->expected_frame_id = super_obj->frame_idx;
2064                if (dispatch_buf != NULL) {
2065                    *dispatch_buf = *new_buf;
2066                    queue->que.size--;
2067                    free(new_buf);
2068                    free(new_node);
2069                } else {
2070                    queue->match_cnt++;
2071                }
2072            } else {
2073                /* enqueue */
2074                new_node = (cam_node_t *)malloc(sizeof(cam_node_t));
2075                if (new_node != NULL) {
2076                    memset(new_node, 0, sizeof(cam_node_t));
2077                    new_node->data = (void *)new_buf;
2078                    if ( insert_before_buf ) {
2079                        cam_list_insert_before_node(&new_node->list, insert_before_buf);
2080                    } else {
2081                        cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
2082                    }
2083                    queue->que.size++;
2084                } else {
2085                    LOGE("Out of memory");
2086                    free(new_buf);
2087                    mm_camera_muxer_buf_done(buffer);
2088                }
2089            }
2090        } else {
2091            if (NULL != new_buf) {
2092                free(new_buf);
2093            }
2094            mm_camera_muxer_buf_done(buffer);
2095        }
2096    }
2097    pthread_mutex_unlock(&queue->que.lock);
2098
2099    /* bufdone overflowed bufs */
2100    while (queue->match_cnt > queue->attr.water_mark) {
2101        super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
2102        if (NULL != super_obj) {
2103            for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2104                if (super_obj->super_buf[i].num_bufs != 0) {
2105                    mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2106                }
2107            }
2108            free(super_obj);
2109        }
2110    }
2111    return 0;
2112}
2113
2114/*===========================================================================
2115 * FUNCTION   : mm_camera_muxer_buf_done
2116 *
2117 * DESCRIPTION: function release super buffer.
2118 *
2119 * PARAMETERS :
2120 *   @buffer: ptr to super buffer to release.
2121 *
2122 * RETURN     : int32_t type of status
2123 *              0  -- success
2124 *              1 -- failure
2125 *==========================================================================*/
2126void mm_camera_muxer_buf_done(mm_camera_super_buf_t *buffer)
2127{
2128    uint8_t i;
2129    mm_camera_obj_t *my_obj = NULL;
2130
2131    if (buffer == NULL) {
2132        LOGW("Null buffer");
2133        return;
2134    }
2135
2136    my_obj = mm_camera_util_get_camera_by_handler(buffer->camera_handle);
2137    if (my_obj != NULL) {
2138        for (i=0; i < buffer->num_bufs; i++) {
2139            if (buffer->bufs[i] != NULL) {
2140                pthread_mutex_lock(&my_obj->cam_lock);
2141                mm_camera_qbuf(my_obj, buffer->ch_id, buffer->bufs[i]);
2142            }
2143        }
2144    }
2145}
2146
2147/*===========================================================================
2148 * FUNCTION   : mm_muxer_frame_sync_queue_init
2149 *
2150 * DESCRIPTION: Inittialize frame sync queue
2151 *
2152 * PARAMETERS :
2153 *   @queue: ptr to frame sync queue
2154 *
2155 * RETURN     : int32_t type of status
2156 *              0  -- success
2157 *              1 -- failure
2158 *==========================================================================*/
2159int32_t mm_muxer_frame_sync_queue_init(mm_frame_sync_queue_t *queue)
2160{
2161    int32_t rc = 0;
2162    queue->expected_frame_id = 0;
2163    queue->match_cnt = 0;
2164    queue->num_objs = 0;
2165    memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
2166    rc = cam_queue_init(&queue->que);
2167    return rc;
2168}
2169
2170/*===========================================================================
2171 * FUNCTION   : mm_muxer_frame_sync_queue_deinit
2172 *
2173 * DESCRIPTION: Inittialize frame sync queue
2174 *
2175 * PARAMETERS :
2176 *   @queue: ptr to frame sync queue
2177 *
2178 * RETURN     : int32_t type of status
2179 *              0  -- success
2180 *              1 -- failure
2181 *==========================================================================*/
2182int32_t mm_muxer_frame_sync_queue_deinit(mm_frame_sync_queue_t *queue)
2183{
2184    int32_t rc = 0;
2185    rc = cam_queue_deinit(&queue->que);
2186    return rc;
2187}
2188
2189/*===========================================================================
2190 * FUNCTION   : mm_camera_muxer_frame_sync_flush
2191 *
2192 * DESCRIPTION: function to flush frame sync queue
2193 *
2194 * PARAMETERS :
2195 *   @queue: ptr to frame sync queue
2196 *
2197 * RETURN     : int32_t type of status
2198 *              0  -- success
2199 *              1 -- failure
2200 *==========================================================================*/
2201int32_t mm_camera_muxer_frame_sync_flush(mm_frame_sync_queue_t *queue)
2202{
2203    int32_t rc = 0, i = 0;
2204    mm_frame_sync_queue_node_t *super_obj = NULL;
2205
2206    super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
2207    while (super_obj != NULL) {
2208        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2209            if (super_obj->super_buf[i].num_bufs != 0) {
2210                mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2211            }
2212        }
2213        free(super_obj);
2214        super_obj = NULL;
2215        super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
2216    }
2217    return rc;
2218}
2219
2220/*===========================================================================
2221 * FUNCTION   : mm_camera_muxer_stream_frame_sync_flush
2222 *
2223 * DESCRIPTION: function to flush frame sync queue
2224 *
2225 * PARAMETERS :
2226 *   @queue: ptr to frame sync queue
2227 *
2228 * RETURN     : int32_t type of status
2229 *              0  -- success
2230 *              1 -- failure
2231 *==========================================================================*/
2232int32_t mm_camera_muxer_stream_frame_sync_flush(mm_stream_t *str_obj)
2233{
2234    int32_t rc = 0;
2235    mm_stream_t *my_obj = str_obj;
2236
2237    if (my_obj->master_str_obj) {
2238        my_obj = my_obj->master_str_obj;
2239    }
2240
2241    rc = mm_camera_muxer_frame_sync_flush(&my_obj->frame_sync.superbuf_queue);
2242    return rc;
2243}
2244
2245/*===========================================================================
2246 * FUNCTION   : mm_camera_muxer_channel_frame_sync_flush
2247 *
2248 * DESCRIPTION: function to flush frame sync queue
2249 *
2250 * PARAMETERS :
2251 *   @queue: ptr to frame sync queue
2252 *
2253 * RETURN     : int32_t type of status
2254 *              0  -- success
2255 *              1 -- failure
2256 *==========================================================================*/
2257int32_t mm_camera_muxer_channel_frame_sync_flush(mm_channel_t *ch_obj)
2258{
2259    int32_t rc = 0;
2260    mm_channel_t *my_obj = ch_obj;
2261
2262    if (ch_obj->master_ch_obj != NULL) {
2263        my_obj = ch_obj->master_ch_obj;
2264    }
2265
2266    rc = mm_camera_muxer_frame_sync_flush(&my_obj->frame_sync.superbuf_queue);
2267    return rc;
2268}
2269
2270/*===========================================================================
2271 * FUNCTION   : mm_camera_muxer_get_stream_buf_cnt
2272 *
2273 * DESCRIPTION: function to calculate buffer count for auxillary streams.
2274 *
2275 * PARAMETERS :
2276 *   @queue: ptr to frame sync queue
2277 *
2278 * RETURN     : int32_t type of status
2279 *              0  -- success
2280 *              1 -- failure
2281 *==========================================================================*/
2282uint32_t mm_camera_muxer_get_stream_buf_cnt(mm_stream_t *str_obj)
2283{
2284    uint32_t buf_cnt = 0;
2285    uint8_t i = 0;
2286    mm_stream_t *my_obj = str_obj;
2287
2288    if (str_obj->master_str_obj != NULL) {
2289        my_obj = str_obj->master_str_obj;
2290    }
2291
2292    buf_cnt = my_obj->buf_num;
2293    for (i = 0; i < my_obj->num_s_cnt; i++) {
2294        if (my_obj->aux_str_obj[i]->is_res_shared) {
2295            buf_cnt += my_obj->aux_str_obj[i]->buf_num;
2296        }
2297    }
2298    if (buf_cnt > CAM_MAX_NUM_BUFS_PER_STREAM) {
2299        buf_cnt = CAM_MAX_NUM_BUFS_PER_STREAM;
2300    }
2301    return buf_cnt;
2302}
2303
2304/*===========================================================================
2305 * FUNCTION   : mm_camera_muxer_get_stream_bufs
2306 *
2307 * DESCRIPTION: function to assign buffers for auxillary streams.
2308 *
2309 * PARAMETERS :
2310 *   @queue: ptr to frame sync queue
2311 *
2312 * RETURN     : int32_t type of status
2313 *              0  -- success
2314 *              1 -- failure
2315 *==========================================================================*/
2316int32_t mm_camera_muxer_get_stream_bufs(mm_stream_t *my_obj)
2317{
2318    int32_t rc = 0;
2319    uint32_t i = 0;
2320    mm_stream_t *master_obj = NULL;
2321
2322    if (my_obj == NULL || my_obj->master_str_obj == NULL
2323            || !my_obj->is_res_shared) {
2324        LOGE("Invalid argument");
2325        return rc;
2326    }
2327    master_obj = my_obj->master_str_obj;
2328
2329    if (master_obj->total_buf_cnt == 0) {
2330        my_obj->buf_idx = 0;
2331        return rc;
2332    }
2333
2334    if ((master_obj->total_buf_cnt -
2335            (master_obj->buf_idx + master_obj->buf_num))
2336            <= 0) {
2337        LOGE("No enough buffer available %d num_bufs = %d",
2338                master_obj->total_buf_cnt, master_obj->buf_num);
2339        return rc;
2340    }
2341
2342    my_obj->total_buf_cnt = master_obj->total_buf_cnt;
2343    my_obj->buf_idx = master_obj->buf_idx + master_obj->buf_num;
2344    if ((my_obj->buf_idx + my_obj->buf_num) > my_obj->total_buf_cnt) {
2345        my_obj->buf_num = my_obj->total_buf_cnt - my_obj->buf_idx;
2346    }
2347
2348    my_obj->buf = master_obj->buf;
2349    for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
2350        my_obj->buf_status[i].initial_reg_flag =
2351                master_obj->buf_status[i].initial_reg_flag;
2352    }
2353    LOGH("Buffer total = %d buf_cnt = %d offsset = %d",my_obj->total_buf_cnt,
2354            my_obj->buf_num, my_obj->buf_idx);
2355    return 0;
2356}
2357
2358/*===========================================================================
2359 * FUNCTION   : mm_camera_muxer_put_stream_bufs
2360 *
2361 * DESCRIPTION: function to release buffers for auxillary streams.
2362 *
2363 * PARAMETERS :
2364 *   @queue: ptr to frame sync queue
2365 *
2366 * RETURN     : int32_t type of status
2367 *              0  -- success
2368 *              1 -- failure
2369 *==========================================================================*/
2370int32_t mm_camera_muxer_put_stream_bufs(mm_stream_t *my_obj)
2371{
2372    int32_t rc = -1;
2373
2374    if (my_obj == NULL || !my_obj->is_res_shared) {
2375        LOGE("Invalid argument");
2376        return rc;
2377    }
2378    my_obj->total_buf_cnt = 0;
2379    return 0;
2380}
2381
2382/*===========================================================================
2383 * FUNCTION   : mm_camera_map_stream_buf_ops
2384 *
2385 * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
2386 *              This function will be passed to upper layer as part of ops table
2387 *              to be used by upper layer when allocating stream buffers and mapping
2388 *              buffers to server via domain socket.
2389 *
2390 * PARAMETERS :
2391 *   @frame_idx    : index of buffer within the stream buffers, only valid if
2392 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
2393 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2394 *   @plane_idx    : plane index. If all planes share the same fd,
2395 *                   plane_idx = -1; otherwise, plean_idx is the
2396 *                   index to plane (0..num_of_planes)
2397 *   @fd           : file descriptor of the buffer
2398 *   @size         : size of the buffer
2399 *   @userdata     : user data ptr (stream object)
2400 *
2401 * RETURN     : int32_t type of status
2402 *              0  -- success
2403 *              -1 -- failure
2404 *==========================================================================*/
2405int32_t mm_camera_map_stream_buf_ops(uint32_t buf_idx,
2406        int32_t plane_idx, int fd, size_t size,
2407        void *buffer, cam_mapping_buf_type type,
2408        void *userdata)
2409{
2410    int32_t rc = 0;
2411    mm_stream_t *my_obj = (mm_stream_t *)userdata;
2412    int32_t i = 0;
2413
2414    switch (type) {
2415        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
2416        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
2417            if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
2418                my_obj = my_obj->aux_str_obj[buf_idx];
2419            }
2420            break;
2421        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
2422        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
2423        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
2424        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
2425            for(i = 0; i < my_obj->num_s_cnt; i++) {
2426                if (my_obj->aux_str_obj[i] != NULL) {
2427                    rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
2428                            type, buf_idx, plane_idx, fd, size, buffer);
2429                }
2430            }
2431            break;
2432        default:
2433            LOGE("Not buffer for stream : %d", type);
2434            rc = -1;
2435            break;
2436    }
2437
2438    if (rc == 0) {
2439        rc = mm_stream_map_buf(my_obj,
2440                type, buf_idx, plane_idx, fd, size, buffer);
2441    }
2442    return rc;
2443}
2444
2445/*===========================================================================
2446 * FUNCTION   : mm_camera_muxer_bundled_map_buf_ops
2447 *
2448 * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
2449 *              This function will be passed to upper layer as part of ops table
2450 *              to be used by upper layer when allocating stream buffers and mapping
2451 *              buffers to server via domain socket.
2452 *
2453 * PARAMETERS :
2454 *   @buf_map_list : list of buffer mapping information
2455 *   @userdata     : user data ptr (stream object)
2456 *
2457 * RETURN     : int32_t type of status
2458 *              0  -- success
2459 *              -1 -- failure
2460 *==========================================================================*/
2461int32_t mm_camera_bundled_map_stream_buf_ops(
2462        const cam_buf_map_type_list *buf_map_list,
2463        void *userdata)
2464{
2465    int32_t rc = 0;
2466    mm_stream_t *my_obj = (mm_stream_t *)userdata;
2467    uint32_t i = 0;
2468
2469    if (buf_map_list == NULL || buf_map_list->length == 0) {
2470        LOGW("Invalid argument");
2471        return rc;
2472    }
2473
2474    uint32_t buf_idx;
2475    cam_mapping_buf_type type = buf_map_list->buf_maps[0].type;
2476    switch (type) {
2477        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
2478        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
2479            buf_idx = buf_map_list->buf_maps[0].frame_idx;
2480            if (buf_idx == 0) {
2481                rc = mm_stream_map_buf(my_obj,
2482                        type, buf_idx,
2483                        buf_map_list->buf_maps[0].plane_idx,
2484                        buf_map_list->buf_maps[0].fd,
2485                        buf_map_list->buf_maps[0].size,
2486                        buf_map_list->buf_maps[0].buffer);
2487                if (rc != 0) {
2488                    LOGE("Failed rc = %d", rc);
2489                }
2490            }
2491            for (i = 1; i < buf_map_list->length; i++) {
2492                buf_idx = buf_map_list->buf_maps[i].frame_idx;
2493                if ((i == buf_idx)
2494                        && (my_obj->aux_str_obj[i] != NULL)) {
2495                    rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
2496                            type, buf_idx,
2497                            buf_map_list->buf_maps[i].plane_idx,
2498                            buf_map_list->buf_maps[i].fd,
2499                            buf_map_list->buf_maps[i].size,
2500                            buf_map_list->buf_maps[i].buffer);
2501                }
2502            }
2503            break;
2504        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
2505        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
2506        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
2507        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
2508            rc = mm_stream_map_bufs(my_obj, buf_map_list);
2509            for(i = 0; i < my_obj->num_s_cnt; i++) {
2510                if (my_obj->aux_str_obj[i] != NULL) {
2511                    rc = mm_stream_map_bufs(my_obj->aux_str_obj[i],
2512                            buf_map_list);
2513                }
2514            }
2515            break;
2516        default:
2517            LOGE("Not buffer for stream : %d", type);
2518            rc = -1;
2519            break;
2520    }
2521    return rc;
2522}
2523
2524/*===========================================================================
2525 * FUNCTION   : mm_camera_muxer_unmap_buf_ops
2526 *
2527 * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
2528 *              This function will be passed to upper layer as part of ops table
2529 *              to be used by upper layer when allocating stream buffers and unmapping
2530 *              buffers to server via domain socket.
2531 *
2532 * PARAMETERS :
2533 *   @frame_idx    : index of buffer within the stream buffers, only valid if
2534 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
2535 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2536 *   @plane_idx    : plane index. If all planes share the same fd,
2537 *                   plane_idx = -1; otherwise, plean_idx is the
2538 *                   index to plane (0..num_of_planes)
2539 *   @userdata     : user data ptr (stream object)
2540 *
2541 * RETURN     : int32_t type of status
2542 *              0  -- success
2543 *              -1 -- failure
2544 *==========================================================================*/
2545int32_t mm_camera_unmap_stream_buf_ops(uint32_t buf_idx,
2546           int32_t plane_idx, cam_mapping_buf_type type, void *userdata)
2547{
2548    int32_t rc = 0;
2549    mm_stream_t *my_obj = (mm_stream_t *)userdata;
2550    int32_t i = 0;
2551
2552    switch (type) {
2553        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
2554        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
2555            if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
2556                my_obj = my_obj->aux_str_obj[buf_idx];
2557            }
2558            break;
2559        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
2560        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
2561        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
2562        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
2563            for(i = 0; i < my_obj->num_s_cnt; i++) {
2564                if (my_obj->aux_str_obj[i] != NULL) {
2565                    rc = mm_stream_unmap_buf(my_obj->aux_str_obj[i],
2566                            type, buf_idx, plane_idx);
2567                }
2568            }
2569            break;
2570        default:
2571            LOGE("Not buffer for stream : %d", type);
2572            rc = -1;
2573            break;
2574    }
2575
2576    if (rc == 0) {
2577        rc = mm_stream_unmap_buf(my_obj,
2578                type, buf_idx, plane_idx);
2579    }
2580    return rc;
2581}
2582
2583
2584