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        }
983        aux_config.mem_vtbl.get_bufs = NULL;
984        aux_config.mem_vtbl.put_bufs = NULL;
985        aux_config.mem_vtbl.set_config_ops = NULL;
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    } else{
1218        pthread_mutex_unlock(&cam_obj->muxer_lock);
1219    }
1220    return rc;
1221}
1222
1223/*===========================================================================
1224 * FUNCTION   : mm_camera_muxer_stop_channel
1225 *
1226 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1227 *
1228 * PARAMETERS :
1229 *   @camera_handle: camera handle
1230 *   @ch_id        : channel handle
1231 *
1232 * RETURN     : int32_t type of status
1233 *              0  -- success
1234 *              -1 -- failure
1235 *==========================================================================*/
1236int32_t mm_camera_muxer_stop_channel(uint32_t camera_handle,
1237        uint32_t ch_id, mm_camera_obj_t *cam_obj)
1238{
1239    int32_t rc = 0;
1240    mm_camera_obj_t * my_obj = NULL;
1241    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1242
1243    if(my_obj) {
1244        pthread_mutex_lock(&my_obj->cam_lock);
1245        pthread_mutex_unlock(&cam_obj->muxer_lock);
1246        rc = mm_camera_stop_channel(my_obj, ch_id);
1247    } else{
1248        pthread_mutex_unlock(&cam_obj->muxer_lock);
1249    }
1250    return rc;
1251}
1252
1253/*===========================================================================
1254 * FUNCTION   : mm_camera_intf_qbuf
1255 *
1256 * DESCRIPTION: enqueue buffer back to kernel
1257 *
1258 * PARAMETERS :
1259 *   @camera_handle: camera handle
1260 *   @ch_id        : channel handle
1261 *   @buf          : buf ptr to be enqueued
1262 *
1263 * RETURN     : int32_t type of status
1264 *              0  -- success
1265 *              -1 -- failure
1266 *==========================================================================*/
1267int32_t mm_camera_muxer_qbuf(uint32_t camera_handle, uint32_t ch_id,
1268        mm_camera_buf_def_t *buf, mm_camera_obj_t *cam_obj)
1269{
1270    int32_t rc = 0;
1271    mm_camera_obj_t * my_obj = NULL;
1272
1273    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1274    if(my_obj) {
1275        pthread_mutex_lock(&my_obj->cam_lock);
1276        pthread_mutex_unlock(&cam_obj->muxer_lock);
1277        rc = mm_camera_qbuf(my_obj, ch_id, buf);
1278    } else {
1279        pthread_mutex_unlock(&cam_obj->muxer_lock);
1280    }
1281    return rc;
1282}
1283
1284/*===========================================================================
1285 * FUNCTION   : mm_camera_muxer_get_queued_buf_count
1286 *
1287 * DESCRIPTION: returns the queued buffer count
1288 *
1289 * PARAMETERS :
1290 *   @camera_handle: camera handle
1291 *   @ch_id        : channel handle
1292 *   @stream_id : stream id
1293 *
1294 * RETURN     : int32_t - queued buffer count
1295 *
1296 *==========================================================================*/
1297int32_t mm_camera_muxer_get_queued_buf_count(uint32_t camera_handle,
1298        uint32_t ch_id, uint32_t stream_id,
1299        mm_camera_obj_t *cam_obj)
1300{
1301    int32_t rc = 0;
1302    mm_camera_obj_t * my_obj = NULL;
1303
1304    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1305    if(my_obj) {
1306        pthread_mutex_lock(&my_obj->cam_lock);
1307        pthread_mutex_unlock(&cam_obj->muxer_lock);
1308        rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
1309    } else {
1310        pthread_mutex_unlock(&cam_obj->muxer_lock);
1311    }
1312    return rc;
1313}
1314
1315/*===========================================================================
1316 * FUNCTION   : mm_camera_muxer_request_super_buf
1317 *
1318 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1319 *              frames from superbuf queue
1320 *
1321 * PARAMETERS :
1322 *   @ch_id             : channel handle
1323 *   @buf                : request buffer info
1324 *
1325 * RETURN     : int32_t type of status
1326 *              0  -- success
1327 *              -1 -- failure
1328 *==========================================================================*/
1329int32_t mm_camera_muxer_request_super_buf(uint32_t ch_id,
1330        mm_camera_req_buf_t *buf, mm_camera_obj_t *cam_obj)
1331{
1332    int32_t rc = 0;
1333    mm_camera_obj_t * my_obj = cam_obj;
1334    uint32_t chID = get_main_camera_handle(ch_id);
1335
1336    if(my_obj && buf) {
1337        pthread_mutex_lock(&my_obj->cam_lock);
1338        pthread_mutex_unlock(&cam_obj->muxer_lock);
1339        buf->type = MM_CAMERA_REQ_FRAME_SYNC_BUF;
1340        rc = mm_camera_request_super_buf (my_obj, chID, buf);
1341    } else {
1342        pthread_mutex_unlock(&cam_obj->muxer_lock);
1343    }
1344    return rc;
1345}
1346
1347/*===========================================================================
1348 * FUNCTION   : mm_camera_muxer_cancel_super_buf_request
1349 *
1350 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1351 *              frames from superbuf queue
1352 *
1353 * PARAMETERS :
1354 *   @camera_handle: camera handle
1355 *   @ch_id             : channel handle
1356 *   @buf                : request buffer info
1357 *
1358 * RETURN     : int32_t type of status
1359 *              0  -- success
1360 *              -1 -- failure
1361 *==========================================================================*/
1362int32_t mm_camera_muxer_cancel_super_buf_request(uint32_t camera_handle,
1363        uint32_t ch_id,
1364        mm_camera_obj_t *cam_obj)
1365{
1366    int32_t rc = 0;
1367    mm_camera_obj_t * my_obj = NULL;
1368    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
1369    uint32_t aux_chID = get_main_camera_handle(ch_id);
1370
1371    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1372    if(my_obj) {
1373        pthread_mutex_lock(&my_obj->cam_lock);
1374        pthread_mutex_unlock(&cam_obj->muxer_lock);
1375        rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
1376    } else {
1377        pthread_mutex_unlock(&cam_obj->muxer_lock);
1378    }
1379
1380    my_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
1381    if(my_obj) {
1382        pthread_mutex_lock(&my_obj->cam_lock);
1383        pthread_mutex_unlock(&cam_obj->muxer_lock);
1384        rc = mm_camera_cancel_super_buf_request(my_obj, aux_chID);
1385    } else {
1386        pthread_mutex_unlock(&cam_obj->muxer_lock);
1387    }
1388    return rc;
1389}
1390
1391/*===========================================================================
1392 * FUNCTION   : mm_camera_muxer_flush_super_buf_queue
1393 *
1394 * DESCRIPTION: flush out all frames in the superbuf queue
1395 *
1396 * PARAMETERS :
1397 *   @camera_handle: camera handle
1398 *   @ch_id        : channel handle
1399 *   @frame_idx    : frame index
1400 *
1401 * RETURN     : int32_t type of status
1402 *              0  -- success
1403 *              -1 -- failure
1404 *==========================================================================*/
1405int32_t mm_camera_muxer_flush_super_buf_queue(uint32_t camera_handle,
1406        uint32_t ch_id,
1407        uint32_t frame_idx, mm_camera_obj_t *cam_obj)
1408{
1409    int32_t rc = 0;
1410    mm_camera_obj_t * my_obj = NULL;
1411    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1412
1413    if(my_obj) {
1414            pthread_mutex_lock(&my_obj->cam_lock);
1415            pthread_mutex_unlock(&cam_obj->muxer_lock);
1416            rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
1417    } else {
1418        pthread_mutex_unlock(&cam_obj->muxer_lock);
1419    }
1420    return rc;
1421}
1422
1423/*===========================================================================
1424 * FUNCTION   : mm_camera_muxer_configure_notify_mode
1425 *
1426 * DESCRIPTION: Configures channel notification mode
1427 *
1428 * PARAMETERS :
1429 *   @camera_handle: camera handle
1430 *   @ch_id        : channel handle
1431 *   @notify_mode  : notification mode
1432 *
1433 * RETURN     : int32_t type of status
1434 *              0  -- success
1435 *              -1 -- failure
1436 *==========================================================================*/
1437int32_t mm_camera_muxer_configure_notify_mode(uint32_t camera_handle,
1438        uint32_t ch_id, mm_camera_super_buf_notify_mode_t notify_mode,
1439        mm_camera_obj_t *cam_obj)
1440{
1441    int32_t rc = 0;
1442    mm_camera_obj_t * my_obj = NULL;
1443    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1444
1445    if(my_obj) {
1446            pthread_mutex_lock(&my_obj->cam_lock);
1447            pthread_mutex_unlock(&cam_obj->muxer_lock);
1448            rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
1449    } else {
1450        pthread_mutex_unlock(&cam_obj->muxer_lock);
1451    }
1452    return rc;
1453}
1454
1455/*===========================================================================
1456 * FUNCTION   : mm_camera_muxer_process_advanced_capture
1457 *
1458 * DESCRIPTION: Configures channel advanced capture mode
1459 *
1460 * PARAMETERS :
1461 *   @camera_handle: camera handle
1462 *   @type : advanced capture type
1463 *   @ch_id        : channel handle
1464 *   @trigger  : 1 for start and 0 for cancel/stop
1465 *   @value  : input capture configaration
1466 *
1467 * RETURN     : int32_t type of status
1468 *              0  -- success
1469 *              -1 -- failure
1470 *==========================================================================*/
1471int32_t mm_camera_muxer_process_advanced_capture(uint32_t camera_handle,
1472         uint32_t ch_id, mm_camera_advanced_capture_t type,
1473         int8_t start_flag, void *in_value, mm_camera_obj_t *cam_obj)
1474{
1475    int32_t rc = 0;
1476    mm_camera_obj_t * my_obj = NULL;
1477
1478    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1479    if(my_obj) {
1480        pthread_mutex_lock(&my_obj->cam_lock);
1481        pthread_mutex_unlock(&cam_obj->muxer_lock);
1482        rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
1483                (uint32_t)start_flag, in_value);
1484    } else {
1485        pthread_mutex_unlock(&cam_obj->muxer_lock);
1486    }
1487    return rc;
1488}
1489
1490/*===========================================================================
1491 * FUNCTION   : mm_camera_muxer_get_session_id
1492 *
1493 * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
1494 *
1495 * PARAMETERS :
1496 *   @camera_handle: camera handle
1497 *   @sessionid: session id to be retrieved from server
1498 *
1499 * RETURN     : int32_t type of status
1500 *              0  -- success
1501 *              -1 -- failure
1502 *==========================================================================*/
1503int32_t mm_camera_muxer_get_session_id(uint32_t camera_handle,
1504        uint32_t* sessionid, mm_camera_obj_t *cam_obj)
1505{
1506    int32_t rc = 0;
1507    mm_camera_obj_t * my_obj = NULL;
1508    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1509
1510    if(my_obj) {
1511        pthread_mutex_lock(&my_obj->cam_lock);
1512        pthread_mutex_unlock(&cam_obj->muxer_lock);
1513        *sessionid = my_obj->sessionid;
1514        pthread_mutex_unlock(&my_obj->cam_lock);
1515        rc = 0;
1516    } else {
1517        pthread_mutex_unlock(&cam_obj->muxer_lock);
1518    }
1519    return rc;
1520}
1521
1522 /*===========================================================================
1523 * FUNCTION   : mm_camera_muxer_flush
1524 *
1525 * DESCRIPTION: flush the current camera state and buffers
1526 *
1527 * PARAMETERS :
1528 *   @camera_handle: camera handle
1529 *
1530 * RETURN     : int32_t type of status
1531 *              0  -- success
1532 *              -1 -- failure
1533 *==========================================================================*/
1534int32_t mm_camera_muxer_flush(uint32_t camera_handle, mm_camera_obj_t *cam_obj)
1535{
1536    int32_t rc = 0;
1537    mm_camera_obj_t * my_obj = NULL;
1538    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1539
1540    if(my_obj) {
1541        pthread_mutex_lock(&my_obj->cam_lock);
1542        pthread_mutex_unlock(&cam_obj->muxer_lock);
1543        rc = mm_camera_flush(my_obj);
1544    } else {
1545        pthread_mutex_unlock(&cam_obj->muxer_lock);
1546    }
1547    return rc;
1548}
1549
1550/*===========================================================================
1551 * FUNCTION   : mm_camera_muxer_register_stream_buf_cb
1552 *
1553 * DESCRIPTION: Register special callback for stream buffer
1554 *
1555 * PARAMETERS :
1556 *   @camera_handle: camera handle
1557 *   @ch_id        : channel handle
1558 *   @stream_id    : stream handle
1559 *   @buf_cb       : callback function
1560 *   @buf_type     :SYNC/ASYNC
1561 *   @userdata     : userdata pointer
1562 *
1563 * RETURN     : int32_t type of status
1564 *              0  -- success
1565 *              1 -- failure
1566 *==========================================================================*/
1567int32_t mm_camera_muxer_register_stream_buf_cb(uint32_t camera_handle,
1568        uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
1569        mm_camera_stream_cb_type cb_type, void *userdata, mm_camera_obj_t *cam_obj)
1570{
1571    int32_t rc = 0;
1572    mm_camera_obj_t * my_obj = NULL;
1573    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1574
1575    if(my_obj) {
1576        pthread_mutex_lock(&my_obj->cam_lock);
1577        pthread_mutex_unlock(&cam_obj->muxer_lock);
1578        rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
1579                buf_cb, cb_type, userdata);
1580    } else {
1581        pthread_mutex_unlock(&cam_obj->muxer_lock);
1582    }
1583    return rc;
1584}
1585
1586/*===========================================================================
1587 * FUNCTION   : mm_camera_muxer_reg_frame_sync
1588 *
1589 * DESCRIPTION: Configure for frame sync.
1590 *
1591 * PARAMETERS :
1592 *   @camera_handle: camera handle
1593 *   @ch_id        : channel handle
1594 *   @stream_id    : stream handle
1595 *   @sync_attr    : Attributes for frame sync
1596 *
1597 * RETURN     : int32_t type of status
1598 *              0  -- success
1599 *              1 -- failure
1600 *==========================================================================*/
1601int32_t mm_camera_muxer_reg_frame_sync(mm_camera_obj_t *cam_obj,
1602        uint32_t ch_id, uint32_t stream_id,
1603        mm_camera_intf_frame_sync_t *sync_attr)
1604{
1605    int32_t rc = 0;
1606    mm_camera_obj_t *a_cam_obj = NULL;
1607
1608    mm_camera_frame_sync_t frame_sync;
1609    if (sync_attr == NULL || cam_obj == NULL) {
1610        pthread_mutex_unlock(&cam_obj->muxer_lock);
1611        return rc;
1612    }
1613
1614    uint32_t chid = get_main_camera_handle(ch_id);
1615    uint32_t aux_handle = get_aux_camera_handle(sync_attr->camera_handle);
1616    uint32_t aux_chid = get_aux_camera_handle(sync_attr->ch_id);
1617    uint32_t strid = 0;
1618    uint32_t aux_strid = 0;
1619    if (stream_id) {
1620        LOGD("Stream frame sync enabled");
1621        strid = get_main_camera_handle(stream_id);
1622        aux_strid = get_aux_camera_handle(sync_attr->stream_id);
1623        if(aux_strid == 0) {
1624            aux_handle = get_main_camera_handle(sync_attr->camera_handle);
1625            aux_chid = get_main_camera_handle(sync_attr->ch_id);
1626            aux_strid = get_main_camera_handle(sync_attr->stream_id);
1627        }
1628    } else {
1629        LOGD("Channel frame sync enabled");
1630        if(aux_chid == 0) {
1631            aux_chid = get_main_camera_handle(sync_attr->ch_id);
1632        }
1633    }
1634    a_cam_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
1635
1636    if(a_cam_obj) {
1637        memset(&frame_sync, 0, sizeof(frame_sync));
1638        frame_sync.a_cam_obj = a_cam_obj;
1639        frame_sync.a_stream_id = aux_strid;
1640        frame_sync.a_ch_id = aux_chid;
1641        frame_sync.userdata = sync_attr->userdata;
1642        frame_sync.buf_cb = sync_attr->buf_cb;
1643        frame_sync.attr = sync_attr->attr;
1644        pthread_mutex_lock(&cam_obj->cam_lock);
1645        pthread_mutex_unlock(&cam_obj->muxer_lock);
1646        rc = mm_camera_reg_frame_sync(cam_obj, chid, strid, &frame_sync);
1647    } else {
1648        pthread_mutex_unlock(&cam_obj->muxer_lock);
1649    }
1650    return rc;
1651}
1652
1653/*===========================================================================
1654 * FUNCTION   : mm_camera_muxer_set_dual_cam_cmd
1655 *
1656 * DESCRIPTION: send event to trigger read on dual camera cmd buffer
1657 *
1658 * PARAMETERS :
1659 *   @camera_handle: camera handle
1660 *   @cam_obj        : header object
1661 *
1662 * RETURN     : int32_t type of status
1663 *              0  -- success
1664 *              1 -- failure
1665 *==========================================================================*/
1666int32_t mm_camera_muxer_set_dual_cam_cmd(uint32_t camera_handle,
1667        mm_camera_obj_t *cam_obj)
1668{
1669    int32_t rc = 0;
1670    mm_camera_obj_t * my_obj = NULL;
1671    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
1672
1673    if(my_obj) {
1674        pthread_mutex_lock(&my_obj->cam_lock);
1675        pthread_mutex_unlock(&cam_obj->muxer_lock);
1676        rc = mm_camera_set_dual_cam_cmd(my_obj);
1677    } else {
1678        pthread_mutex_unlock(&cam_obj->muxer_lock);
1679    }
1680    return rc;
1681}
1682
1683/*===========================================================================
1684 * FUNCTION   : mm_camera_muxer_stream_frame_sync
1685 *
1686 * DESCRIPTION: Handle stream buffers for frame sync
1687 *
1688 * PARAMETERS :
1689 *   @super_buf: Stream buffers
1690 *   @user_data        : Stream object
1691 *
1692 * RETURN     : none
1693 *==========================================================================*/
1694void mm_camera_muxer_stream_frame_sync(mm_camera_super_buf_t *super_buf,
1695        void *user_data)
1696{
1697    int32_t rc = 0, i = 0;
1698    mm_stream_t *my_obj = (mm_stream_t *)user_data;
1699    mm_frame_sync_queue_node_t dispatch_buf;
1700
1701    if ((super_buf == NULL) || (super_buf->num_bufs == 0)) {
1702        return;
1703    }
1704
1705    if (my_obj->master_str_obj != NULL) {
1706        my_obj = my_obj->master_str_obj;
1707    }
1708
1709    memset(&dispatch_buf, 0, sizeof(dispatch_buf));
1710    rc = mm_camera_muxer_do_frame_sync(&my_obj->frame_sync.superbuf_queue,
1711            super_buf, &dispatch_buf);
1712    if (rc < 0) {
1713        LOGE("frame sync failed");
1714        return;
1715    }
1716
1717    if (my_obj->frame_sync.super_buf_notify_cb && dispatch_buf.num_objs > 0) {
1718        mm_camera_super_buf_t super_buf;
1719        memset(&super_buf, 0, sizeof(super_buf));
1720        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
1721            if (dispatch_buf.super_buf[i].num_bufs == 1) {
1722                super_buf.bufs[super_buf.num_bufs++] =
1723                        dispatch_buf.super_buf[i].bufs[0];
1724                super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
1725                super_buf.ch_id = my_obj->ch_obj->my_hdl;
1726            }
1727        }
1728        pthread_mutex_lock(&my_obj->cb_lock);
1729        my_obj->frame_sync.super_buf_notify_cb(&super_buf,
1730                my_obj->frame_sync.user_data);
1731        pthread_mutex_unlock(&my_obj->cb_lock);
1732    }
1733}
1734
1735/*===========================================================================
1736 * FUNCTION   : mm_camera_muxer_channel_frame_sync
1737 *
1738 * DESCRIPTION: Handle channel super buffers for frame sync
1739 *
1740 * PARAMETERS :
1741 *   @super_buf: channel buffers
1742 *   @user_data        : channel object
1743 *
1744 * RETURN     : none
1745 *==========================================================================*/
1746void mm_camera_muxer_channel_frame_sync(mm_camera_super_buf_t *super_buf,
1747        void *user_data)
1748{
1749    int32_t rc = 0;
1750    mm_channel_t *ch_obj = (mm_channel_t *)user_data;
1751    mm_channel_t *m_obj = ch_obj;
1752
1753    if ((super_buf == NULL) || (super_buf->num_bufs == 0)) {
1754        return;
1755    }
1756
1757    if (m_obj->master_ch_obj != NULL) {
1758        m_obj = m_obj->master_ch_obj;
1759    }
1760
1761    rc = mm_camera_muxer_do_frame_sync(&m_obj->frame_sync.superbuf_queue,
1762            super_buf, NULL);
1763    mm_camera_muxer_channel_req_data_cb(NULL,
1764                ch_obj);
1765}
1766
1767
1768/*===========================================================================
1769 * FUNCTION   : mm_camera_muxer_channel_req_data_cb
1770 *
1771 * DESCRIPTION: Issue super buffer callback based on request setting
1772 *
1773 * PARAMETERS :
1774 *   @req_buf: buffer request setting
1775 *   @ch_obj        : channel object
1776 *
1777 * RETURN     : none
1778 *==========================================================================*/
1779int32_t mm_camera_muxer_channel_req_data_cb(mm_camera_req_buf_t *req_buf,
1780        mm_channel_t *ch_obj)
1781{
1782    int32_t rc = 0, i;
1783    mm_channel_t *m_obj = (mm_channel_t *)ch_obj;
1784    mm_frame_sync_queue_node_t* super_obj = NULL;
1785    mm_frame_sync_t *frame_sync = NULL;
1786    uint8_t trigger_cb = 0;
1787
1788    if (m_obj->master_ch_obj != NULL) {
1789        m_obj = m_obj->master_ch_obj;
1790    }
1791
1792    frame_sync = &m_obj->frame_sync;
1793    if (req_buf != NULL) {
1794        frame_sync->req_buf.num_buf_requested +=
1795                req_buf->num_buf_requested;
1796        frame_sync->req_buf.type = req_buf->type;
1797    }
1798
1799    while ((frame_sync->req_buf.num_buf_requested > 0)
1800            || (frame_sync->superbuf_queue.attr.notify_mode ==
1801            MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS)) {
1802        super_obj = mm_camera_muxer_frame_sync_dequeue(
1803                &frame_sync->superbuf_queue, frame_sync->req_buf.type);
1804        if (super_obj == NULL) {
1805            break;
1806        }
1807        if (frame_sync->super_buf_notify_cb && super_obj->num_objs != 0) {
1808            if (frame_sync->req_buf.type == MM_CAMERA_REQ_FRAME_SYNC_BUF) {
1809                for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
1810                    if (super_obj->super_buf[i].num_bufs != 0) {
1811                        frame_sync->super_buf_notify_cb(
1812                                &super_obj->super_buf[i],
1813                                frame_sync->user_data);
1814                    }
1815                }
1816                trigger_cb = 1;
1817            } else {
1818                for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
1819                    if (super_obj->super_buf[i].num_bufs != 0) {
1820                        if (super_obj->super_buf[i].ch_id ==
1821                                ch_obj->my_hdl) {
1822                            frame_sync->super_buf_notify_cb(
1823                                    &super_obj->super_buf[i],
1824                                    frame_sync->user_data);
1825                            trigger_cb = 1;
1826                        } else {
1827                            mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
1828                        }
1829                    }
1830                }
1831            }
1832            if ((m_obj->frame_sync.req_buf.num_buf_requested > 0)
1833                    && trigger_cb) {
1834                m_obj->frame_sync.req_buf.num_buf_requested--;
1835            }
1836        }
1837        free(super_obj);
1838    }
1839    return rc;
1840}
1841
1842/*===========================================================================
1843 * FUNCTION   : mm_camera_muxer_frame_sync_dequeue
1844 *
1845 * DESCRIPTION: dequeue object from frame sync queue
1846 *
1847 * PARAMETERS :
1848 *   @queue: ptr to queue to dequeue object
1849 *
1850 * RETURN     : ptr to a node from superbuf queue
1851 *==========================================================================*/
1852mm_frame_sync_queue_node_t *mm_camera_muxer_frame_sync_dequeue(
1853        mm_frame_sync_queue_t *queue, uint8_t matched_only)
1854{
1855    cam_node_t* node = NULL;
1856    struct cam_list *head = NULL;
1857    struct cam_list *pos = NULL;
1858    mm_frame_sync_queue_node_t* super_buf = NULL;
1859
1860    pthread_mutex_lock(&queue->que.lock);
1861    head = &queue->que.head.list;
1862    pos = head->next;
1863    if (pos != head) {
1864        /* get the first node */
1865        node = member_of(pos, cam_node_t, list);
1866        super_buf = (mm_frame_sync_queue_node_t*)node->data;
1867        if ( (NULL != super_buf) &&
1868             (matched_only == TRUE) &&
1869             (super_buf->matched == FALSE) ) {
1870            super_buf = NULL;
1871        }
1872
1873        if (NULL != super_buf) {
1874            queue->que.size--;
1875            cam_list_del_node(&node->list);
1876            free(node);
1877            if (super_buf->matched) {
1878                queue->match_cnt--;
1879            }
1880        }
1881    }
1882    pthread_mutex_unlock(&queue->que.lock);
1883    return super_buf;
1884}
1885
1886/*===========================================================================
1887 * FUNCTION   : mm_camera_muxer_do_frame_sync
1888 *
1889 * DESCRIPTION: function to process object buffers and match with existing frames.
1890 *
1891 * PARAMETERS :
1892 *   @queue: ptr to queue to dequeue object
1893 *   @buffer: Input buffer to match and insert
1894 *   @dispatch_buf        : Ptr to carry matched node
1895 *
1896 * RETURN     : int32_t type of status
1897 *              0  -- success
1898 *              1 -- failure
1899 *==========================================================================*/
1900int32_t mm_camera_muxer_do_frame_sync(
1901        mm_frame_sync_queue_t *queue, mm_camera_super_buf_t *buffer,
1902        mm_frame_sync_queue_node_t *dispatch_buf)
1903{
1904    cam_node_t* node = NULL;
1905    uint8_t buf_s_idx, i, found_super_buf, unmatched_bundles;
1906    struct cam_list *head = NULL;
1907    struct cam_list *pos = NULL;
1908    mm_frame_sync_queue_node_t* super_obj = NULL;
1909    struct cam_list *last_buf = NULL, *insert_before_buf = NULL;
1910
1911    if (buffer == NULL || buffer->num_bufs == 0) {
1912        LOGW("Ivalid Argument");
1913        return -1;
1914    }
1915
1916    for (buf_s_idx = 0; buf_s_idx < queue->num_objs; buf_s_idx++) {
1917        if ((buffer->ch_id == queue->bundled_objs[buf_s_idx]) ||
1918                (buffer->bufs[0]->stream_id == queue->bundled_objs[buf_s_idx])) {
1919            break;
1920        }
1921    }
1922    if (buf_s_idx == queue->num_objs) {
1923        LOGE("buf from stream (%d) not bundled", buffer->bufs[0]->stream_id);
1924        mm_camera_muxer_buf_done(buffer);
1925        return -1;
1926    }
1927
1928    if (buffer->bufs[0]->frame_idx <= queue->expected_frame_id) {
1929        LOGD("old frame. Need to release");
1930        mm_camera_muxer_buf_done(buffer);
1931        return 0;
1932    }
1933
1934    pthread_mutex_lock(&queue->que.lock);
1935    head = &queue->que.head.list;
1936    pos = head->next;
1937    found_super_buf = 0;
1938    unmatched_bundles = 0;
1939    last_buf = NULL;
1940    insert_before_buf = NULL;
1941
1942    while (pos != head) {
1943        node = member_of(pos, cam_node_t, list);
1944        super_obj = (mm_frame_sync_queue_node_t *)node->data;
1945        if (NULL != super_obj) {
1946            if (super_obj->matched == 1) {
1947                /* find a matched super buf, move to next one */
1948                pos = pos->next;
1949                continue;
1950            } else if (buffer->bufs[0]->frame_idx == super_obj->frame_idx) {
1951                found_super_buf = 1;
1952                break;
1953            } else if ((buffer->bufs[0]->frame_idx >= super_obj->frame_idx)
1954                    && (queue->attr.priority ==
1955                    MM_CAMERA_SUPER_BUF_PRIORITY_LOW)) {
1956                found_super_buf = 1;
1957                break;
1958            } else {
1959                unmatched_bundles++;
1960                if ( NULL == last_buf ) {
1961                    if ( super_obj->frame_idx < buffer->bufs[0]->frame_idx) {
1962                        last_buf = pos;
1963                    }
1964                }
1965                if ( NULL == insert_before_buf ) {
1966                    if ( super_obj->frame_idx > buffer->bufs[0]->frame_idx) {
1967                        insert_before_buf = pos;
1968                    }
1969                }
1970                pos = pos->next;
1971            }
1972        }
1973    }
1974
1975    LOGD("found_super_buf = %d id = %d unmatched = %d max = %d", found_super_buf,
1976            buffer->bufs[0]->frame_idx, unmatched_bundles,
1977            queue->attr.max_unmatched_frames);
1978    if (found_super_buf) {
1979        super_obj->super_buf[buf_s_idx] = *buffer;
1980        super_obj->num_objs++;
1981        if (super_obj->num_objs == queue->num_objs) {
1982            super_obj->matched = 1;
1983            queue->expected_frame_id = super_obj->frame_idx;
1984            if (dispatch_buf != NULL) {
1985                *dispatch_buf = *super_obj;
1986                queue->que.size--;
1987                cam_list_del_node(&node->list);
1988                free(node);
1989                free(super_obj);
1990            } else {
1991                queue->match_cnt++;
1992            }
1993        }
1994        /* Any older unmatched buffer need to be released */
1995        if ( last_buf ) {
1996            while (last_buf != pos ) {
1997                node = member_of(last_buf, cam_node_t, list);
1998                super_obj = (mm_frame_sync_queue_node_t*)node->data;
1999                if (NULL != super_obj) {
2000                    for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2001                        if (super_obj->super_buf[i].num_bufs != 0) {
2002                            mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2003                        }
2004                    }
2005                    queue->que.size--;
2006                    last_buf = last_buf->next;
2007                    cam_list_del_node(&node->list);
2008                    free(node);
2009                    free(super_obj);
2010                }
2011            }
2012        }
2013    } else {
2014        if ((queue->attr.max_unmatched_frames < unmatched_bundles)
2015                && (NULL == last_buf)) {
2016            //incoming frame is older than the last bundled one
2017            mm_camera_muxer_buf_done(buffer);
2018            pthread_mutex_unlock(&queue->que.lock);
2019            return 0;
2020        } else if (queue->attr.max_unmatched_frames < unmatched_bundles) {
2021            //dispatch old buffer. Cannot sync for configured unmatch value
2022            node = member_of(last_buf, cam_node_t, list);
2023            super_obj = (mm_frame_sync_queue_node_t*)node->data;
2024            queue->expected_frame_id = super_obj->frame_idx;
2025            if (dispatch_buf != NULL && super_obj != NULL) {
2026                //Dispatch unmatched buffer
2027                *dispatch_buf = *super_obj;
2028            } else if (super_obj != NULL){
2029                //release unmatched buffers
2030                for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2031                    if (super_obj->super_buf[i].num_bufs != 0) {
2032                        mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2033                    }
2034                }
2035            }
2036            queue->que.size--;
2037            cam_list_del_node(&node->list);
2038            free(node);
2039            free(super_obj);
2040        }
2041
2042        //insert the new frame at the appropriate position.
2043        mm_frame_sync_queue_node_t *new_buf = NULL;
2044        cam_node_t* new_node = NULL;
2045        new_buf = (mm_frame_sync_queue_node_t *)
2046                malloc(sizeof(mm_frame_sync_queue_node_t));
2047        if (NULL != new_buf) {
2048            memset(new_buf, 0, sizeof(mm_frame_sync_queue_node_t));
2049            new_buf->super_buf[buf_s_idx] = *buffer;
2050            new_buf->num_objs++;
2051            new_buf->frame_idx = buffer->bufs[0]->frame_idx;
2052            new_buf->matched = 0;
2053            if (new_buf->num_objs == queue->num_objs) {
2054                new_buf->matched = 1;
2055                queue->expected_frame_id = super_obj->frame_idx;
2056                if (dispatch_buf != NULL) {
2057                    *dispatch_buf = *new_buf;
2058                    queue->que.size--;
2059                    free(new_buf);
2060                    free(new_node);
2061                } else {
2062                    queue->match_cnt++;
2063                }
2064            } else {
2065                /* enqueue */
2066                new_node = (cam_node_t *)malloc(sizeof(cam_node_t));
2067                if (new_node != NULL) {
2068                    memset(new_node, 0, sizeof(cam_node_t));
2069                    new_node->data = (void *)new_buf;
2070                    if ( insert_before_buf ) {
2071                        cam_list_insert_before_node(&new_node->list, insert_before_buf);
2072                    } else {
2073                        cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
2074                    }
2075                    queue->que.size++;
2076                } else {
2077                    LOGE("Out of memory");
2078                    free(new_buf);
2079                    mm_camera_muxer_buf_done(buffer);
2080                }
2081            }
2082        } else {
2083            if (NULL != new_buf) {
2084                free(new_buf);
2085            }
2086            mm_camera_muxer_buf_done(buffer);
2087        }
2088    }
2089    pthread_mutex_unlock(&queue->que.lock);
2090
2091    /* bufdone overflowed bufs */
2092    while (queue->match_cnt > queue->attr.water_mark) {
2093        super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
2094        if (NULL != super_obj) {
2095            for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2096                if (super_obj->super_buf[i].num_bufs != 0) {
2097                    mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2098                }
2099            }
2100            free(super_obj);
2101        }
2102    }
2103    return 0;
2104}
2105
2106/*===========================================================================
2107 * FUNCTION   : mm_camera_muxer_buf_done
2108 *
2109 * DESCRIPTION: function release super buffer.
2110 *
2111 * PARAMETERS :
2112 *   @buffer: ptr to super buffer to release.
2113 *
2114 * RETURN     : int32_t type of status
2115 *              0  -- success
2116 *              1 -- failure
2117 *==========================================================================*/
2118void mm_camera_muxer_buf_done(mm_camera_super_buf_t *buffer)
2119{
2120    uint8_t i;
2121    mm_camera_obj_t *my_obj = NULL;
2122
2123    if (buffer == NULL) {
2124        LOGW("Null buffer");
2125        return;
2126    }
2127
2128    my_obj = mm_camera_util_get_camera_by_handler(buffer->camera_handle);
2129    if (my_obj != NULL) {
2130        for (i=0; i < buffer->num_bufs; i++) {
2131            if (buffer->bufs[i] != NULL) {
2132                pthread_mutex_lock(&my_obj->cam_lock);
2133                mm_camera_qbuf(my_obj, buffer->ch_id, buffer->bufs[i]);
2134            }
2135        }
2136    }
2137}
2138
2139/*===========================================================================
2140 * FUNCTION   : mm_muxer_frame_sync_queue_init
2141 *
2142 * DESCRIPTION: Inittialize frame sync queue
2143 *
2144 * PARAMETERS :
2145 *   @queue: ptr to frame sync queue
2146 *
2147 * RETURN     : int32_t type of status
2148 *              0  -- success
2149 *              1 -- failure
2150 *==========================================================================*/
2151int32_t mm_muxer_frame_sync_queue_init(mm_frame_sync_queue_t *queue)
2152{
2153    int32_t rc = 0;
2154    queue->expected_frame_id = 0;
2155    queue->match_cnt = 0;
2156    queue->num_objs = 0;
2157    memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
2158    rc = cam_queue_init(&queue->que);
2159    return rc;
2160}
2161
2162/*===========================================================================
2163 * FUNCTION   : mm_muxer_frame_sync_queue_deinit
2164 *
2165 * DESCRIPTION: Inittialize frame sync queue
2166 *
2167 * PARAMETERS :
2168 *   @queue: ptr to frame sync queue
2169 *
2170 * RETURN     : int32_t type of status
2171 *              0  -- success
2172 *              1 -- failure
2173 *==========================================================================*/
2174int32_t mm_muxer_frame_sync_queue_deinit(mm_frame_sync_queue_t *queue)
2175{
2176    int32_t rc = 0;
2177    rc = cam_queue_deinit(&queue->que);
2178    return rc;
2179}
2180
2181/*===========================================================================
2182 * FUNCTION   : mm_camera_muxer_frame_sync_flush
2183 *
2184 * DESCRIPTION: function to flush frame sync queue
2185 *
2186 * PARAMETERS :
2187 *   @queue: ptr to frame sync queue
2188 *
2189 * RETURN     : int32_t type of status
2190 *              0  -- success
2191 *              1 -- failure
2192 *==========================================================================*/
2193int32_t mm_camera_muxer_frame_sync_flush(mm_frame_sync_queue_t *queue)
2194{
2195    int32_t rc = 0, i = 0;
2196    mm_frame_sync_queue_node_t *super_obj = NULL;
2197
2198    super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
2199    while (super_obj != NULL) {
2200        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
2201            if (super_obj->super_buf[i].num_bufs != 0) {
2202                mm_camera_muxer_buf_done(&super_obj->super_buf[i]);
2203            }
2204        }
2205        free(super_obj);
2206        super_obj = NULL;
2207        super_obj = mm_camera_muxer_frame_sync_dequeue(queue, FALSE);
2208    }
2209    return rc;
2210}
2211
2212/*===========================================================================
2213 * FUNCTION   : mm_camera_muxer_stream_frame_sync_flush
2214 *
2215 * DESCRIPTION: function to flush frame sync queue
2216 *
2217 * PARAMETERS :
2218 *   @queue: ptr to frame sync queue
2219 *
2220 * RETURN     : int32_t type of status
2221 *              0  -- success
2222 *              1 -- failure
2223 *==========================================================================*/
2224int32_t mm_camera_muxer_stream_frame_sync_flush(mm_stream_t *str_obj)
2225{
2226    int32_t rc = 0;
2227    mm_stream_t *my_obj = str_obj;
2228
2229    if (my_obj->master_str_obj) {
2230        my_obj = my_obj->master_str_obj;
2231    }
2232
2233    rc = mm_camera_muxer_frame_sync_flush(&my_obj->frame_sync.superbuf_queue);
2234    return rc;
2235}
2236
2237/*===========================================================================
2238 * FUNCTION   : mm_camera_muxer_channel_frame_sync_flush
2239 *
2240 * DESCRIPTION: function to flush frame sync queue
2241 *
2242 * PARAMETERS :
2243 *   @queue: ptr to frame sync queue
2244 *
2245 * RETURN     : int32_t type of status
2246 *              0  -- success
2247 *              1 -- failure
2248 *==========================================================================*/
2249int32_t mm_camera_muxer_channel_frame_sync_flush(mm_channel_t *ch_obj)
2250{
2251    int32_t rc = 0;
2252    mm_channel_t *my_obj = ch_obj;
2253
2254    if (ch_obj->master_ch_obj != NULL) {
2255        my_obj = ch_obj->master_ch_obj;
2256    }
2257
2258    rc = mm_camera_muxer_frame_sync_flush(&my_obj->frame_sync.superbuf_queue);
2259    return rc;
2260}
2261
2262/*===========================================================================
2263 * FUNCTION   : mm_camera_muxer_get_stream_buf_cnt
2264 *
2265 * DESCRIPTION: function to calculate buffer count for auxillary streams.
2266 *
2267 * PARAMETERS :
2268 *   @queue: ptr to frame sync queue
2269 *
2270 * RETURN     : int32_t type of status
2271 *              0  -- success
2272 *              1 -- failure
2273 *==========================================================================*/
2274uint32_t mm_camera_muxer_get_stream_buf_cnt(mm_stream_t *str_obj)
2275{
2276    uint32_t buf_cnt = 0;
2277    uint8_t i = 0;
2278    mm_stream_t *my_obj = str_obj;
2279
2280    if (str_obj->master_str_obj != NULL) {
2281        my_obj = str_obj->master_str_obj;
2282    }
2283
2284    buf_cnt = my_obj->buf_num;
2285    for (i = 0; i < my_obj->num_s_cnt; i++) {
2286        if (my_obj->aux_str_obj[i]->is_res_shared) {
2287            buf_cnt += my_obj->aux_str_obj[i]->buf_num;
2288        }
2289    }
2290    if (buf_cnt > CAM_MAX_NUM_BUFS_PER_STREAM) {
2291        buf_cnt = CAM_MAX_NUM_BUFS_PER_STREAM;
2292    }
2293    return buf_cnt;
2294}
2295
2296/*===========================================================================
2297 * FUNCTION   : mm_camera_muxer_get_stream_bufs
2298 *
2299 * DESCRIPTION: function to assign buffers for auxillary streams.
2300 *
2301 * PARAMETERS :
2302 *   @queue: ptr to frame sync queue
2303 *
2304 * RETURN     : int32_t type of status
2305 *              0  -- success
2306 *              1 -- failure
2307 *==========================================================================*/
2308int32_t mm_camera_muxer_get_stream_bufs(mm_stream_t *my_obj)
2309{
2310    int32_t rc = 0;
2311    uint32_t i = 0;
2312    mm_stream_t *master_obj = NULL;
2313
2314    if (my_obj == NULL || my_obj->master_str_obj == NULL
2315            || !my_obj->is_res_shared) {
2316        LOGE("Invalid argument");
2317        return rc;
2318    }
2319    master_obj = my_obj->master_str_obj;
2320
2321    if (master_obj->total_buf_cnt == 0) {
2322        my_obj->buf_idx = 0;
2323        return rc;
2324    }
2325
2326    if ((master_obj->total_buf_cnt -
2327            (master_obj->buf_idx + master_obj->buf_num))
2328            <= 0) {
2329        LOGE("No enough buffer available %d num_bufs = %d",
2330                master_obj->total_buf_cnt, master_obj->buf_num);
2331        return rc;
2332    }
2333
2334    my_obj->total_buf_cnt = master_obj->total_buf_cnt;
2335    my_obj->buf_idx = master_obj->buf_idx + master_obj->buf_num;
2336    if ((my_obj->buf_idx + my_obj->buf_num) > my_obj->total_buf_cnt) {
2337        my_obj->buf_num = my_obj->total_buf_cnt - my_obj->buf_idx;
2338    }
2339
2340    my_obj->buf = master_obj->buf;
2341    for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
2342        my_obj->buf_status[i].initial_reg_flag =
2343                master_obj->buf_status[i].initial_reg_flag;
2344    }
2345    LOGH("Buffer total = %d buf_cnt = %d offsset = %d",my_obj->total_buf_cnt,
2346            my_obj->buf_num, my_obj->buf_idx);
2347    return 0;
2348}
2349
2350/*===========================================================================
2351 * FUNCTION   : mm_camera_muxer_put_stream_bufs
2352 *
2353 * DESCRIPTION: function to release buffers for auxillary streams.
2354 *
2355 * PARAMETERS :
2356 *   @queue: ptr to frame sync queue
2357 *
2358 * RETURN     : int32_t type of status
2359 *              0  -- success
2360 *              1 -- failure
2361 *==========================================================================*/
2362int32_t mm_camera_muxer_put_stream_bufs(mm_stream_t *my_obj)
2363{
2364    int32_t rc = -1;
2365
2366    if (my_obj == NULL || !my_obj->is_res_shared) {
2367        LOGE("Invalid argument");
2368        return rc;
2369    }
2370    my_obj->total_buf_cnt = 0;
2371    return 0;
2372}
2373
2374/*===========================================================================
2375 * FUNCTION   : mm_camera_map_stream_buf_ops
2376 *
2377 * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
2378 *              This function will be passed to upper layer as part of ops table
2379 *              to be used by upper layer when allocating stream buffers and mapping
2380 *              buffers to server via domain socket.
2381 *
2382 * PARAMETERS :
2383 *   @frame_idx    : index of buffer within the stream buffers, only valid if
2384 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
2385 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2386 *   @plane_idx    : plane index. If all planes share the same fd,
2387 *                   plane_idx = -1; otherwise, plean_idx is the
2388 *                   index to plane (0..num_of_planes)
2389 *   @fd           : file descriptor of the buffer
2390 *   @size         : size of the buffer
2391 *   @userdata     : user data ptr (stream object)
2392 *
2393 * RETURN     : int32_t type of status
2394 *              0  -- success
2395 *              -1 -- failure
2396 *==========================================================================*/
2397int32_t mm_camera_map_stream_buf_ops(uint32_t buf_idx,
2398        int32_t plane_idx, int fd, size_t size,
2399        void *buffer, cam_mapping_buf_type type,
2400        void *userdata)
2401{
2402    int32_t rc = 0;
2403    mm_stream_t *my_obj = (mm_stream_t *)userdata;
2404    int32_t i = 0;
2405
2406    switch (type) {
2407        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
2408        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
2409            if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
2410                my_obj = my_obj->aux_str_obj[buf_idx];
2411            }
2412            break;
2413        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
2414        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
2415        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
2416        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
2417            for(i = 0; i < my_obj->num_s_cnt; i++) {
2418                if (my_obj->aux_str_obj[i] != NULL) {
2419                    rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
2420                            type, buf_idx, plane_idx, fd, size, buffer);
2421                }
2422            }
2423            break;
2424        default:
2425            LOGE("Not buffer for stream : %d", type);
2426            rc = -1;
2427            break;
2428    }
2429
2430    if (rc == 0) {
2431        rc = mm_stream_map_buf(my_obj,
2432                type, buf_idx, plane_idx, fd, size, buffer);
2433    }
2434    return rc;
2435}
2436
2437/*===========================================================================
2438 * FUNCTION   : mm_camera_muxer_bundled_map_buf_ops
2439 *
2440 * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
2441 *              This function will be passed to upper layer as part of ops table
2442 *              to be used by upper layer when allocating stream buffers and mapping
2443 *              buffers to server via domain socket.
2444 *
2445 * PARAMETERS :
2446 *   @buf_map_list : list of buffer mapping information
2447 *   @userdata     : user data ptr (stream object)
2448 *
2449 * RETURN     : int32_t type of status
2450 *              0  -- success
2451 *              -1 -- failure
2452 *==========================================================================*/
2453int32_t mm_camera_bundled_map_stream_buf_ops(
2454        const cam_buf_map_type_list *buf_map_list,
2455        void *userdata)
2456{
2457    int32_t rc = 0;
2458    mm_stream_t *my_obj = (mm_stream_t *)userdata;
2459    uint32_t i = 0;
2460
2461    if (buf_map_list == NULL || buf_map_list->length == 0) {
2462        LOGW("Invalid argument");
2463        return rc;
2464    }
2465
2466    uint32_t buf_idx;
2467    cam_mapping_buf_type type = buf_map_list->buf_maps[0].type;
2468    switch (type) {
2469        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
2470        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
2471            buf_idx = buf_map_list->buf_maps[0].frame_idx;
2472            if (buf_idx == 0) {
2473                rc = mm_stream_map_buf(my_obj,
2474                        type, buf_idx,
2475                        buf_map_list->buf_maps[0].plane_idx,
2476                        buf_map_list->buf_maps[0].fd,
2477                        buf_map_list->buf_maps[0].size,
2478                        buf_map_list->buf_maps[0].buffer);
2479                if (rc != 0) {
2480                    LOGE("Failed rc = %d", rc);
2481                }
2482            }
2483            for (i = 1; i < buf_map_list->length; i++) {
2484                buf_idx = buf_map_list->buf_maps[i].frame_idx;
2485                if ((i == buf_idx)
2486                        && (my_obj->aux_str_obj[i] != NULL)) {
2487                    rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
2488                            type, buf_idx,
2489                            buf_map_list->buf_maps[i].plane_idx,
2490                            buf_map_list->buf_maps[i].fd,
2491                            buf_map_list->buf_maps[i].size,
2492                            buf_map_list->buf_maps[i].buffer);
2493                }
2494            }
2495            break;
2496        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
2497        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
2498        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
2499        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
2500            rc = mm_stream_map_bufs(my_obj, buf_map_list);
2501            for(i = 0; i < my_obj->num_s_cnt; i++) {
2502                if (my_obj->aux_str_obj[i] != NULL) {
2503                    rc = mm_stream_map_bufs(my_obj->aux_str_obj[i],
2504                            buf_map_list);
2505                }
2506            }
2507            break;
2508        default:
2509            LOGE("Not buffer for stream : %d", type);
2510            rc = -1;
2511            break;
2512    }
2513    return rc;
2514}
2515
2516/*===========================================================================
2517 * FUNCTION   : mm_camera_muxer_unmap_buf_ops
2518 *
2519 * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
2520 *              This function will be passed to upper layer as part of ops table
2521 *              to be used by upper layer when allocating stream buffers and unmapping
2522 *              buffers to server via domain socket.
2523 *
2524 * PARAMETERS :
2525 *   @frame_idx    : index of buffer within the stream buffers, only valid if
2526 *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
2527 *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
2528 *   @plane_idx    : plane index. If all planes share the same fd,
2529 *                   plane_idx = -1; otherwise, plean_idx is the
2530 *                   index to plane (0..num_of_planes)
2531 *   @userdata     : user data ptr (stream object)
2532 *
2533 * RETURN     : int32_t type of status
2534 *              0  -- success
2535 *              -1 -- failure
2536 *==========================================================================*/
2537int32_t mm_camera_unmap_stream_buf_ops(uint32_t buf_idx,
2538           int32_t plane_idx, cam_mapping_buf_type type, void *userdata)
2539{
2540    int32_t rc = 0;
2541    mm_stream_t *my_obj = (mm_stream_t *)userdata;
2542    int32_t i = 0;
2543
2544    switch (type) {
2545        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
2546        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
2547            if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
2548                my_obj = my_obj->aux_str_obj[buf_idx];
2549            }
2550            break;
2551        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
2552        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
2553        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
2554        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
2555            for(i = 0; i < my_obj->num_s_cnt; i++) {
2556                if (my_obj->aux_str_obj[i] != NULL) {
2557                    rc = mm_stream_unmap_buf(my_obj->aux_str_obj[i],
2558                            type, buf_idx, plane_idx);
2559                }
2560            }
2561            break;
2562        default:
2563            LOGE("Not buffer for stream : %d", type);
2564            rc = -1;
2565            break;
2566    }
2567
2568    if (rc == 0) {
2569        rc = mm_stream_unmap_buf(my_obj,
2570                type, buf_idx, plane_idx);
2571    }
2572    return rc;
2573}
2574
2575
2576