1/* Copyright (c) 2015-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#define LOG_TAG "QCameraMuxer"
31
32// System dependencies
33#include <fcntl.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <utils/Errors.h>
37#define STAT_H <SYSTEM_HEADER_PREFIX/stat.h>
38#include STAT_H
39
40// Camera dependencies
41#include "QCameraMuxer.h"
42#include "QCamera2HWI.h"
43
44extern "C" {
45#include "mm_camera_dbg.h"
46}
47
48/* Muxer implementation */
49using namespace android;
50namespace qcamera {
51
52QCameraMuxer *gMuxer = NULL;
53
54//Error Check Macros
55#define CHECK_MUXER() \
56    if (!gMuxer) { \
57        LOGE("Error getting muxer "); \
58        return; \
59    } \
60
61#define CHECK_MUXER_ERROR() \
62    if (!gMuxer) { \
63        LOGE("Error getting muxer "); \
64        return -ENODEV; \
65    } \
66
67#define CHECK_CAMERA(pCam) \
68    if (!pCam) { \
69        LOGE("Error getting physical camera"); \
70        return; \
71    } \
72
73#define CHECK_CAMERA_ERROR(pCam) \
74    if (!pCam) { \
75        LOGE("Error getting physical camera"); \
76        return -ENODEV; \
77    } \
78
79#define CHECK_HWI(hwi) \
80    if (!hwi) { \
81        LOGE("Error !! HWI not found!!"); \
82        return; \
83    } \
84
85#define CHECK_HWI_ERROR(hwi) \
86    if (!hwi) { \
87        LOGE("Error !! HWI not found!!"); \
88        return -ENODEV; \
89    } \
90
91
92/*===========================================================================
93 * FUNCTION         : getCameraMuxer
94 *
95 * DESCRIPTION     : Creates Camera Muxer if not created
96 *
97 * PARAMETERS:
98 *   @pMuxer               : Pointer to retrieve Camera Muxer
99 *   @num_of_cameras  : Number of Physical Cameras on device
100 *
101 * RETURN             :  NONE
102 *==========================================================================*/
103void QCameraMuxer::getCameraMuxer(
104        QCameraMuxer** pMuxer, uint32_t num_of_cameras)
105{
106    *pMuxer = NULL;
107    if (!gMuxer) {
108        gMuxer = new QCameraMuxer(num_of_cameras);
109    }
110    CHECK_MUXER();
111    *pMuxer = gMuxer;
112    LOGH("gMuxer: %p ", gMuxer);
113    return;
114}
115
116/*===========================================================================
117 * FUNCTION         : QCameraMuxer
118 *
119 * DESCRIPTION     : QCameraMuxer Constructor
120 *
121 * PARAMETERS:
122 *   @num_of_cameras  : Number of Physical Cameras on device
123 *
124 *==========================================================================*/
125QCameraMuxer::QCameraMuxer(uint32_t num_of_cameras)
126    : mJpegClientHandle(0),
127      m_pPhyCamera(NULL),
128      m_pLogicalCamera(NULL),
129      m_pCallbacks(NULL),
130      m_bAuxCameraExposed(FALSE),
131      m_nPhyCameras(num_of_cameras),
132      m_nLogicalCameras(0),
133      m_MainJpegQ(releaseJpegInfo, this),
134      m_AuxJpegQ(releaseJpegInfo, this),
135      m_pRelCamMpoJpeg(NULL),
136      m_pMpoCallbackCookie(NULL),
137      m_pJpegCallbackCookie(NULL),
138      m_bDumpImages(FALSE),
139      m_bMpoEnabled(TRUE),
140      m_bFrameSyncEnabled(FALSE),
141      m_bRecordingHintInternallySet(FALSE)
142{
143    setupLogicalCameras();
144    memset(&mJpegOps, 0, sizeof(mJpegOps));
145    memset(&mJpegMpoOps, 0, sizeof(mJpegMpoOps));
146    memset(&mGetMemoryCb, 0, sizeof(mGetMemoryCb));
147    memset(&mDataCb, 0, sizeof(mDataCb));
148
149    // initialize mutex for MPO composition
150    pthread_mutex_init(&m_JpegLock, NULL);
151    // launch MPO composition thread
152    m_ComposeMpoTh.launch(composeMpoRoutine, this);
153
154    //Check whether dual camera images need to be dumped
155    char prop[PROPERTY_VALUE_MAX];
156    property_get("persist.camera.dual.camera.dump", prop, "0");
157    m_bDumpImages = atoi(prop);
158    LOGH("dualCamera dump images:%d ", m_bDumpImages);
159}
160
161/*===========================================================================
162 * FUNCTION         : ~QCameraMuxer
163 *
164 * DESCRIPTION     : QCameraMuxer Desctructor
165 *
166 *==========================================================================*/
167QCameraMuxer::~QCameraMuxer() {
168    if (m_pLogicalCamera) {
169        delete [] m_pLogicalCamera;
170        m_pLogicalCamera = NULL;
171    }
172    if (m_pPhyCamera) {
173        delete [] m_pPhyCamera;
174        m_pPhyCamera = NULL;
175    }
176
177    if (NULL != m_pRelCamMpoJpeg) {
178        m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg);
179        m_pRelCamMpoJpeg = NULL;
180    }
181    // flush Jpeg Queues
182    m_MainJpegQ.flush();
183    m_AuxJpegQ.flush();
184
185    // stop and exit MPO composition thread
186    m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, TRUE, FALSE);
187    m_ComposeMpoTh.exit();
188
189    pthread_mutex_destroy(&m_JpegLock);
190}
191
192/*===========================================================================
193 * FUNCTION         : get_number_of_cameras
194 *
195 * DESCRIPTION     : Provide number of Logical Cameras
196 *
197 * RETURN             :  Number of logical Cameras
198 *==========================================================================*/
199int QCameraMuxer::get_number_of_cameras()
200{
201    return gMuxer->getNumberOfCameras();
202}
203
204/*===========================================================================
205 * FUNCTION         : get_camera_info
206 *
207 * DESCRIPTION     : get logical camera info
208 *
209 * PARAMETERS:
210 *   @camera_id     : Logical Camera ID
211 *   @info              : Logical Main Camera Info
212 *
213 * RETURN     :
214 *              NO_ERROR  : success
215 *              ENODEV : Camera not found
216 *              other: non-zero failure code
217 *==========================================================================*/
218int QCameraMuxer::get_camera_info(int camera_id, struct camera_info *info)
219{
220    int rc = NO_ERROR;
221    LOGH("E");
222    cam_sync_type_t type;
223    if ((camera_id < 0) || (camera_id >= gMuxer->getNumberOfCameras())) {
224        LOGE("Camera id %d not found!", camera_id);
225        return -ENODEV;
226    }
227    if(info) {
228        rc = gMuxer->getCameraInfo(camera_id, info, &type);
229    }
230    LOGH("X, rc: %d", rc);
231    return rc;
232}
233
234
235/*===========================================================================
236 * FUNCTION         : set_callbacks
237 *
238 * DESCRIPTION     : Not Implemented
239 *
240 * PARAMETERS:
241 *   @callbacks      : Camera Module Callbacks
242 *
243 * RETURN     :
244 *              NO_ERROR  : success
245 *              other: non-zero failure code
246 *==========================================================================*/
247int QCameraMuxer::set_callbacks(__unused const camera_module_callbacks_t *callbacks)
248{
249    // Not implemented
250    return NO_ERROR;
251}
252
253/*===========================================================================
254 * FUNCTION   : camera_device_open
255 *
256 * DESCRIPTION: static function to open a camera device by its ID
257 *
258 * PARAMETERS :
259 *   @modue: hw module
260 *   @id : camera ID
261 *   @hw_device : ptr to struct storing camera hardware device info
262 *
263 * RETURN     :
264 *              NO_ERROR  : success
265 *              BAD_VALUE : Invalid Camera ID
266 *              other: non-zero failure code
267 *==========================================================================*/
268int QCameraMuxer::camera_device_open(
269        __unused const struct hw_module_t *module, const char *id,
270        struct hw_device_t **hw_device)
271{
272    int rc = NO_ERROR;
273    LOGH("id= %d",atoi(id));
274    if (!id) {
275        LOGE("Invalid camera id");
276        return BAD_VALUE;
277    }
278
279    rc =  gMuxer->cameraDeviceOpen(atoi(id), hw_device);
280    LOGH("id= %d, rc: %d", atoi(id), rc);
281    return rc;
282}
283
284/*===========================================================================
285 * FUNCTION   : open_legacy
286 *
287 * DESCRIPTION: static function to open a camera device by its ID
288 *
289 * PARAMETERS :
290 *   @modue: hw module
291 *   @id : camera ID
292 *   @halVersion: hal version
293 *   @hw_device : ptr to struct storing camera hardware device info
294 *
295 * RETURN     :
296 *              NO_ERROR  : success
297 *              BAD_VALUE : Invalid Camera ID
298 *              other: non-zero failure code
299 *==========================================================================*/
300int QCameraMuxer::open_legacy(__unused const struct hw_module_t* module,
301        const char* id, __unused uint32_t halVersion, struct hw_device_t** hw_device)
302{
303    int rc = NO_ERROR;
304    LOGH("id= %d", atoi(id));
305    if (!id) {
306        LOGE("Invalid camera id");
307        return BAD_VALUE;
308    }
309
310    rc =  gMuxer->cameraDeviceOpen(atoi(id), hw_device);
311    LOGH("id= %d, rc: %d", atoi(id), rc);
312    return rc;
313}
314
315/*===========================================================================
316 * FUNCTION   : set_preview_window
317 *
318 * DESCRIPTION: Set Preview window for main camera
319 *
320 * PARAMETERS :
321 *   @device : camera hardware device info
322 *   @window: Preview window ops
323 *
324 * RETURN     :
325 *              NO_ERROR  : success
326 *              other: non-zero failure code
327 *==========================================================================*/
328int QCameraMuxer::set_preview_window(struct camera_device * device,
329        struct preview_stream_ops *window)
330{
331    int rc = NO_ERROR;
332    CHECK_MUXER_ERROR();
333    qcamera_physical_descriptor_t *pCam = NULL;
334    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
335    CHECK_CAMERA_ERROR(cam);
336
337    for (uint32_t i = 0; i < cam->numCameras; i++) {
338        pCam = gMuxer->getPhysicalCamera(cam, i);
339        CHECK_CAMERA_ERROR(pCam);
340
341        // Set preview window only for primary camera
342        if (pCam->mode == CAM_MODE_PRIMARY) {
343            QCamera2HardwareInterface *hwi = pCam->hwi;
344            CHECK_HWI_ERROR(hwi);
345            rc = hwi->set_preview_window(pCam->dev, window);
346            if (rc != NO_ERROR) {
347                LOGE("Error!! setting preview window");
348                return rc;
349            }
350            break;
351        }
352    }
353    return rc;
354}
355
356/*===========================================================================
357 * FUNCTION   : set_callBacks
358 *
359 * DESCRIPTION: Set Framework callbacks to notify various frame data asynchronously
360 *
361 * PARAMETERS :
362 *   @device : camera hardware device info
363 *   @notify_cb: Notification callback
364 *   @data_cb: data callback
365 *   @data_cb_timestamp: data timestamp callback
366 *   @get_memory: callback to obtain memory
367 *   @user : userdata
368 *
369 * RETURN : None
370 *==========================================================================*/
371void QCameraMuxer::set_callBacks(struct camera_device * device,
372        camera_notify_callback notify_cb,
373        camera_data_callback data_cb,
374        camera_data_timestamp_callback data_cb_timestamp,
375        camera_request_memory get_memory,
376        void *user)
377{
378    LOGH("E");
379    CHECK_MUXER();
380    int rc = NO_ERROR;
381    qcamera_physical_descriptor_t *pCam = NULL;
382    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
383    CHECK_CAMERA(cam);
384
385    // Set callbacks to HWI
386    for (uint32_t i = 0; i < cam->numCameras; i++) {
387        pCam = gMuxer->getPhysicalCamera(cam, i);
388        CHECK_CAMERA(pCam);
389
390        QCamera2HardwareInterface *hwi = pCam->hwi;
391        CHECK_HWI(hwi);
392
393        hwi->set_CallBacks(pCam->dev, notify_cb, data_cb, data_cb_timestamp,
394                get_memory, user);
395
396        // Set JPG callbacks
397        // sending the physical camera description with the Jpeg callback
398        // this will be retrieved in callbacks to get the cam instance
399        // delivering JPEGs
400        hwi->setJpegCallBacks(jpeg_data_callback, (void*)pCam);
401
402        if (pCam->mode == CAM_MODE_PRIMARY) {
403            rc = gMuxer->setMainJpegCallbackCookie((void*)(pCam));
404            if(rc != NO_ERROR) {
405                LOGW("Error setting Jpeg callback cookie");
406            }
407        }
408    }
409    // Store callback in Muxer to send data callbacks
410    rc = gMuxer->setDataCallback(data_cb);
411    if(rc != NO_ERROR) {
412        LOGW("Error setting data callback");
413    }
414    // memory callback stored to allocate memory for MPO buffer
415    rc = gMuxer->setMemoryCallback(get_memory);
416    if(rc != NO_ERROR) {
417        LOGW("Error setting memory callback");
418    }
419    // actual user callback cookie is saved in Muxer
420    // this will be used to deliver final MPO callback to the framework
421    rc = gMuxer->setMpoCallbackCookie(user);
422    if(rc != NO_ERROR) {
423        LOGW("Error setting mpo cookie");
424    }
425
426    LOGH("X");
427
428}
429
430/*===========================================================================
431 * FUNCTION   : enable_msg_type
432 *
433 * DESCRIPTION: Enable msg_type to send callbacks
434 *
435 * PARAMETERS :
436 *   @device : camera hardware device info
437 *   @msg_type: callback Message type to be enabled
438 *
439 * RETURN : None
440 *==========================================================================*/
441void QCameraMuxer::enable_msg_type(struct camera_device * device, int32_t msg_type)
442{
443    LOGH("E");
444    CHECK_MUXER();
445    qcamera_physical_descriptor_t *pCam = NULL;
446    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
447    CHECK_CAMERA(cam);
448
449    for (uint32_t i = 0; i < cam->numCameras; i++) {
450        pCam = gMuxer->getPhysicalCamera(cam, i);
451        CHECK_CAMERA(pCam);
452        QCamera2HardwareInterface *hwi = pCam->hwi;
453        CHECK_HWI(hwi);
454        hwi->enable_msg_type(pCam->dev, msg_type);
455    }
456    LOGH("X");
457}
458
459/*===========================================================================
460 * FUNCTION   : disable_msg_type
461 *
462 * DESCRIPTION: disable msg_type to send callbacks
463 *
464 * PARAMETERS :
465 *   @device : camera hardware device info
466 *   @msg_type: callback Message type to be disabled
467 *
468 * RETURN : None
469 *==========================================================================*/
470void QCameraMuxer::disable_msg_type(struct camera_device * device, int32_t msg_type)
471{
472    LOGH("E");
473    CHECK_MUXER();
474    qcamera_physical_descriptor_t *pCam = NULL;
475    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
476    CHECK_CAMERA(cam);
477
478    for (uint32_t i = 0; i < cam->numCameras; i++) {
479        pCam = gMuxer->getPhysicalCamera(cam, i);
480        CHECK_CAMERA(pCam);
481        QCamera2HardwareInterface *hwi = pCam->hwi;
482        CHECK_HWI(hwi);
483        hwi->disable_msg_type(pCam->dev, msg_type);
484    }
485    LOGH("X");
486}
487
488/*===========================================================================
489 * FUNCTION   : msg_type_enabled
490 *
491 * DESCRIPTION: Check if message type enabled
492 *
493 * PARAMETERS :
494 *   @device : camera hardware device info
495 *   @msg_type: message type
496 *
497 * RETURN : true/false
498 *==========================================================================*/
499int QCameraMuxer::msg_type_enabled(struct camera_device * device, int32_t msg_type)
500{
501    LOGH("E");
502    CHECK_MUXER_ERROR();
503    qcamera_physical_descriptor_t *pCam = NULL;
504    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
505    CHECK_CAMERA_ERROR(cam);
506
507    for (uint32_t i = 0; i < cam->numCameras; i++) {
508        pCam = gMuxer->getPhysicalCamera(cam, i);
509        CHECK_CAMERA_ERROR(pCam);
510
511        QCamera2HardwareInterface *hwi = pCam->hwi;
512        CHECK_HWI_ERROR(hwi);
513
514        if (pCam->mode == CAM_MODE_PRIMARY) {
515            return hwi->msg_type_enabled(pCam->dev, msg_type);
516        }
517    }
518    LOGH("X");
519    return false;
520}
521
522/*===========================================================================
523 * FUNCTION   : start_preview
524 *
525 * DESCRIPTION: Starts logical camera preview
526 *
527 * PARAMETERS :
528 *   @device : camera hardware device info
529 *
530 * RETURN     :
531 *              NO_ERROR  : success
532 *              other: non-zero failure code
533 *==========================================================================*/
534int QCameraMuxer::start_preview(struct camera_device * device)
535{
536    LOGH("E");
537    CHECK_MUXER_ERROR();
538    int rc = NO_ERROR;
539    qcamera_physical_descriptor_t *pCam = NULL;
540    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
541    CHECK_CAMERA_ERROR(cam);
542
543    // prepare preview first for all cameras
544    for (uint32_t i = 0; i < cam->numCameras; i++) {
545        pCam = gMuxer->getPhysicalCamera(cam, i);
546        CHECK_CAMERA_ERROR(pCam);
547
548        QCamera2HardwareInterface *hwi = pCam->hwi;
549        CHECK_HWI_ERROR(hwi);
550
551        rc = hwi->prepare_preview(pCam->dev);
552        if (rc != NO_ERROR) {
553            LOGE("Error preparing preview !! ");
554            return rc;
555        }
556    }
557
558    if (cam->numCameras > 1) {
559        uint sessionId = 0;
560        // Set up sync for camera sessions
561        for (uint32_t i = 0; i < cam->numCameras; i++) {
562            pCam = gMuxer->getPhysicalCamera(cam, i);
563            CHECK_CAMERA_ERROR(pCam);
564
565            QCamera2HardwareInterface *hwi = pCam->hwi;
566            CHECK_HWI_ERROR(hwi);
567
568            if(pCam->mode == CAM_MODE_PRIMARY) {
569                // bundle primary cam with all aux cameras
570                for (uint32_t j = 0; j < cam->numCameras; j++) {
571                    if (j == cam->nPrimaryPhyCamIndex) {
572                        continue;
573                    }
574                    sessionId = cam->sId[j];
575                    LOGH("Related cam id: %d, server id: %d sync ON"
576                            " related session_id %d",
577                            cam->pId[i], cam->sId[i], sessionId);
578                    rc = hwi->bundleRelatedCameras(true, sessionId);
579                    if (rc != NO_ERROR) {
580                        LOGE("Error Bundling physical cameras !! ");
581                        return rc;
582                    }
583                }
584            }
585
586            if (pCam->mode == CAM_MODE_SECONDARY) {
587                // bundle all aux cam with primary cams
588                sessionId = cam->sId[cam->nPrimaryPhyCamIndex];
589                LOGH("Related cam id: %d, server id: %d sync ON"
590                        " related session_id %d",
591                        cam->pId[i], cam->sId[i], sessionId);
592                rc = hwi->bundleRelatedCameras(true, sessionId);
593                if (rc != NO_ERROR) {
594                    LOGE("Error Bundling physical cameras !! ");
595                    return rc;
596                }
597            }
598        }
599
600        // Remember Sync is ON
601        cam->bSyncOn = true;
602    }
603    // Start Preview for all cameras
604    for (uint32_t i = 0; i < cam->numCameras; i++) {
605        pCam = gMuxer->getPhysicalCamera(cam, i);
606        CHECK_CAMERA_ERROR(pCam);
607
608        QCamera2HardwareInterface *hwi = pCam->hwi;
609        CHECK_HWI_ERROR(hwi);
610        rc = hwi->start_preview(pCam->dev);
611        if (rc != NO_ERROR) {
612            LOGE("Error starting preview !! ");
613            return rc;
614        }
615    }
616    LOGH("X");
617    return rc;
618}
619
620/*===========================================================================
621 * FUNCTION   : stop_preview
622 *
623 * DESCRIPTION: Stops logical camera preview
624 *
625 * PARAMETERS :
626 *   @device : camera hardware device info
627 *
628 * RETURN     : None
629 *==========================================================================*/
630void QCameraMuxer::stop_preview(struct camera_device * device)
631{
632    LOGH("E");
633    CHECK_MUXER();
634    qcamera_physical_descriptor_t *pCam = NULL;
635    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
636    CHECK_CAMERA(cam);
637
638    for (uint32_t i = 0; i < cam->numCameras; i++) {
639        pCam = gMuxer->getPhysicalCamera(cam, i);
640        CHECK_CAMERA(pCam);
641
642        QCamera2HardwareInterface *hwi = pCam->hwi;
643        CHECK_HWI(hwi);
644
645        QCamera2HardwareInterface::stop_preview(pCam->dev);
646    }
647
648    //Flush JPEG Queues. Nodes in Main and Aux JPEGQ are not valid after preview stopped.
649    gMuxer->m_MainJpegQ.flush();
650    gMuxer->m_AuxJpegQ.flush();
651    LOGH(" X");
652}
653
654/*===========================================================================
655 * FUNCTION   : preview_enabled
656 *
657 * DESCRIPTION: Checks preview enabled
658 *
659 * PARAMETERS :
660 *   @device : camera hardware device info
661 *
662 * RETURN     : true/false
663 *==========================================================================*/
664int QCameraMuxer::preview_enabled(struct camera_device * device)
665{
666    LOGH("E");
667    CHECK_MUXER_ERROR();
668    qcamera_physical_descriptor_t *pCam = NULL;
669    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
670    CHECK_CAMERA_ERROR(cam);
671
672    for (uint32_t i = 0; i < cam->numCameras; i++) {
673        pCam = gMuxer->getPhysicalCamera(cam, i);
674        CHECK_CAMERA_ERROR(pCam);
675
676        QCamera2HardwareInterface *hwi = pCam->hwi;
677        CHECK_HWI_ERROR(hwi);
678
679        if (pCam->mode == CAM_MODE_PRIMARY) {
680            return hwi->preview_enabled(pCam->dev);
681        }
682    }
683    LOGH("X");
684    return false;
685}
686
687/*===========================================================================
688 * FUNCTION   : store_meta_data_in_buffers
689 *
690 * DESCRIPTION: Stores metadata in buffers
691 *
692 * PARAMETERS :
693 *   @device : camera hardware device info
694 *   @enable: Enable/disable metadata
695 *
696 * RETURN     :
697 *              NO_ERROR  : success
698 *              other: non-zero failure code
699 *==========================================================================*/
700int QCameraMuxer::store_meta_data_in_buffers(struct camera_device * device, int enable)
701{
702    LOGH("E");
703    CHECK_MUXER_ERROR();
704    int rc = NO_ERROR;
705    qcamera_physical_descriptor_t *pCam = NULL;
706    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
707    CHECK_CAMERA_ERROR(cam);
708
709    for (uint32_t i = 0; i < cam->numCameras; i++) {
710        pCam = gMuxer->getPhysicalCamera(cam, i);
711        CHECK_CAMERA_ERROR(pCam);
712
713        QCamera2HardwareInterface *hwi = pCam->hwi;
714        CHECK_HWI_ERROR(hwi);
715
716        rc = hwi->store_meta_data_in_buffers(pCam->dev, enable);
717        if (rc != NO_ERROR) {
718            LOGE("Error storing metat data !! ");
719            return rc;
720        }
721    }
722    LOGH("X");
723    return rc;
724}
725
726/*===========================================================================
727 * FUNCTION   : start_recording
728 *
729 * DESCRIPTION: Starts recording on camcorder
730 *
731 * PARAMETERS :
732 *   @device : camera hardware device info
733 *
734 * RETURN     :
735 *              NO_ERROR  : success
736 *              other: non-zero failure code
737 *==========================================================================*/
738int QCameraMuxer::start_recording(struct camera_device * device)
739{
740    LOGH("E");
741    CHECK_MUXER_ERROR();
742    int rc = NO_ERROR;
743    bool previewRestartNeeded = false;
744    qcamera_physical_descriptor_t *pCam = NULL;
745    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
746    CHECK_CAMERA_ERROR(cam);
747
748    // In cases where recording hint is not set, hwi->start_recording will
749    // internally restart the preview.
750    // To take the preview restart control in muxer,
751    // 1. call pre_start_recording first
752    for (uint32_t i = 0; i < cam->numCameras; i++) {
753        pCam = gMuxer->getPhysicalCamera(cam, i);
754        CHECK_CAMERA_ERROR(pCam);
755
756        QCamera2HardwareInterface *hwi = pCam->hwi;
757        CHECK_HWI_ERROR(hwi);
758
759        rc = hwi->pre_start_recording(pCam->dev);
760        if (rc != NO_ERROR) {
761            LOGE("Error preparing recording start!! ");
762            return rc;
763        }
764    }
765
766    // 2. Check if preview restart is needed. Check all cameras.
767    for (uint32_t i = 0; i < cam->numCameras; i++) {
768        pCam = gMuxer->getPhysicalCamera(cam, i);
769        CHECK_CAMERA_ERROR(pCam);
770
771        QCamera2HardwareInterface *hwi = pCam->hwi;
772        CHECK_HWI_ERROR(hwi);
773
774        if (hwi->isPreviewRestartNeeded()) {
775            previewRestartNeeded = hwi->isPreviewRestartNeeded();
776            break;
777        }
778    }
779
780    if (previewRestartNeeded) {
781        // 3. if preview restart needed. stop the preview first
782        for (uint32_t i = 0; i < cam->numCameras; i++) {
783            pCam = gMuxer->getPhysicalCamera(cam, i);
784            CHECK_CAMERA_ERROR(pCam);
785
786            QCamera2HardwareInterface *hwi = pCam->hwi;
787            CHECK_HWI_ERROR(hwi);
788
789            rc = hwi->restart_stop_preview(pCam->dev);
790            if (rc != NO_ERROR) {
791                LOGE("Error in restart stop preview!! ");
792                return rc;
793            }
794        }
795
796        //4. Update the recording hint value to TRUE
797        for (uint32_t i = 0; i < cam->numCameras; i++) {
798            pCam = gMuxer->getPhysicalCamera(cam, i);
799            CHECK_CAMERA_ERROR(pCam);
800
801            QCamera2HardwareInterface *hwi = pCam->hwi;
802            CHECK_HWI_ERROR(hwi);
803
804            rc = hwi->setRecordingHintValue(TRUE);
805            if (rc != NO_ERROR) {
806                LOGE("Error in setting recording hint value!! ");
807                return rc;
808            }
809            gMuxer->m_bRecordingHintInternallySet = TRUE;
810        }
811
812        // 5. start the preview
813        for (uint32_t i = 0; i < cam->numCameras; i++) {
814            pCam = gMuxer->getPhysicalCamera(cam, i);
815            CHECK_CAMERA_ERROR(pCam);
816
817            QCamera2HardwareInterface *hwi = pCam->hwi;
818            CHECK_HWI_ERROR(hwi);
819
820            rc = hwi->restart_start_preview(pCam->dev);
821            if (rc != NO_ERROR) {
822                LOGE("Error in restart start preview!! ");
823                return rc;
824            }
825        }
826    }
827
828    for (uint32_t i = 0; i < cam->numCameras; i++) {
829        pCam = gMuxer->getPhysicalCamera(cam, i);
830        CHECK_CAMERA_ERROR(pCam);
831
832        QCamera2HardwareInterface *hwi = pCam->hwi;
833        CHECK_HWI_ERROR(hwi);
834
835        if (pCam->mode == CAM_MODE_PRIMARY) {
836            rc = hwi->start_recording(pCam->dev);
837            if (rc != NO_ERROR) {
838                LOGE("Error starting recording!! ");
839            }
840            break;
841        }
842    }
843    LOGH("X");
844    return rc;
845}
846
847/*===========================================================================
848 * FUNCTION   : stop_recording
849 *
850 * DESCRIPTION: Stops recording on camcorder
851 *
852 * PARAMETERS :
853 *   @device : camera hardware device info
854 *
855 * RETURN     : None
856 *==========================================================================*/
857void QCameraMuxer::stop_recording(struct camera_device * device)
858{
859
860    int rc = NO_ERROR;
861    LOGH("E");
862
863    CHECK_MUXER();
864    qcamera_physical_descriptor_t *pCam = NULL;
865    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
866    CHECK_CAMERA(cam);
867
868    for (uint32_t i = 0; i < cam->numCameras; i++) {
869        pCam = gMuxer->getPhysicalCamera(cam, i);
870        CHECK_CAMERA(pCam);
871
872        QCamera2HardwareInterface *hwi = pCam->hwi;
873        CHECK_HWI(hwi);
874
875        if (pCam->mode == CAM_MODE_PRIMARY) {
876            QCamera2HardwareInterface::stop_recording(pCam->dev);
877            break;
878        }
879    }
880
881    // If recording hint is set internally to TRUE,
882    // we need to set it to FALSE.
883    // preview restart is needed in between
884    if (gMuxer->m_bRecordingHintInternallySet) {
885        // stop the preview first
886        for (uint32_t i = 0; i < cam->numCameras; i++) {
887            pCam = gMuxer->getPhysicalCamera(cam, i);
888            CHECK_CAMERA(pCam);
889
890            QCamera2HardwareInterface *hwi = pCam->hwi;
891            CHECK_HWI(hwi);
892
893            rc = hwi->restart_stop_preview(pCam->dev);
894            if (rc != NO_ERROR) {
895                LOGE("Error in restart stop preview!! ");
896                return;
897            }
898        }
899
900        // Update the recording hint value to FALSE
901        for (uint32_t i = 0; i < cam->numCameras; i++) {
902            pCam = gMuxer->getPhysicalCamera(cam, i);
903            CHECK_CAMERA(pCam);
904
905            QCamera2HardwareInterface *hwi = pCam->hwi;
906            CHECK_HWI(hwi);
907
908            rc = hwi->setRecordingHintValue(FALSE);
909            if (rc != NO_ERROR) {
910                LOGE("Error in setting recording hint value!! ");
911                return;
912            }
913            gMuxer->m_bRecordingHintInternallySet = FALSE;
914        }
915
916        // start the preview
917        for (uint32_t i = 0; i < cam->numCameras; i++) {
918            pCam = gMuxer->getPhysicalCamera(cam, i);
919            CHECK_CAMERA(pCam);
920
921            QCamera2HardwareInterface *hwi = pCam->hwi;
922            CHECK_HWI(hwi);
923
924            rc = hwi->restart_start_preview(pCam->dev);
925            if (rc != NO_ERROR) {
926                LOGE("Error in restart start preview!! ");
927                return;
928            }
929        }
930    }
931    LOGH("X");
932}
933
934/*===========================================================================
935 * FUNCTION   : recording_enabled
936 *
937 * DESCRIPTION: Checks for recording enabled
938 *
939 * PARAMETERS :
940 *   @device : camera hardware device info
941 *
942 * RETURN     : true/false
943 *==========================================================================*/
944int QCameraMuxer::recording_enabled(struct camera_device * device)
945{
946    LOGH("E");
947    CHECK_MUXER_ERROR();
948    qcamera_physical_descriptor_t *pCam = NULL;
949    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
950    CHECK_CAMERA_ERROR(cam);
951
952    for (uint32_t i = 0; i < cam->numCameras; i++) {
953        pCam = gMuxer->getPhysicalCamera(cam, i);
954        CHECK_CAMERA_ERROR(pCam);
955
956        QCamera2HardwareInterface *hwi = pCam->hwi;
957        CHECK_HWI_ERROR(hwi);
958
959        if (pCam->mode == CAM_MODE_PRIMARY) {
960            return hwi->recording_enabled(pCam->dev);
961        }
962    }
963    LOGH("X");
964    return false;
965}
966
967/*===========================================================================
968 * FUNCTION   : release_recording_frame
969 *
970 * DESCRIPTION: Release the recording frame
971 *
972 * PARAMETERS :
973 *   @device : camera hardware device info
974 *   @opaque: Frame to be released
975 *
976  * RETURN     : None
977 *==========================================================================*/
978void QCameraMuxer::release_recording_frame(struct camera_device * device,
979                const void *opaque)
980{
981    LOGH("E");
982    CHECK_MUXER();
983    qcamera_physical_descriptor_t *pCam = NULL;
984    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
985    CHECK_CAMERA(cam);
986
987    for (uint32_t i = 0; i < cam->numCameras; i++) {
988        pCam = gMuxer->getPhysicalCamera(cam, i);
989        CHECK_CAMERA(pCam);
990
991        QCamera2HardwareInterface *hwi = pCam->hwi;
992        CHECK_HWI(hwi);
993
994        if (pCam->mode == CAM_MODE_PRIMARY) {
995            QCamera2HardwareInterface::release_recording_frame(pCam->dev, opaque);
996            break;
997        }
998    }
999    LOGH("X");
1000}
1001
1002/*===========================================================================
1003 * FUNCTION   : auto_focus
1004 *
1005 * DESCRIPTION: Performs auto focus on camera
1006 *
1007 * PARAMETERS :
1008 *   @device : camera hardware device info
1009 *
1010 * RETURN     :
1011 *              NO_ERROR  : success
1012 *              other: non-zero failure code
1013 *==========================================================================*/
1014int QCameraMuxer::auto_focus(struct camera_device * device)
1015{
1016    LOGH("E");
1017    CHECK_MUXER_ERROR();
1018    int rc = NO_ERROR;
1019    qcamera_physical_descriptor_t *pCam = NULL;
1020    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1021    CHECK_CAMERA_ERROR(cam);
1022
1023    for (uint32_t i = 0; i < cam->numCameras; i++) {
1024        pCam = gMuxer->getPhysicalCamera(cam, i);
1025        CHECK_CAMERA_ERROR(pCam);
1026
1027        QCamera2HardwareInterface *hwi = pCam->hwi;
1028        CHECK_HWI_ERROR(hwi);
1029        // Call auto focus on main camera
1030        if (pCam->mode == CAM_MODE_PRIMARY) {
1031            rc = QCamera2HardwareInterface::auto_focus(pCam->dev);
1032            if (rc != NO_ERROR) {
1033                LOGE("Error auto focusing !! ");
1034                return rc;
1035            }
1036            break;
1037        }
1038    }
1039    LOGH("X");
1040    return rc;
1041}
1042
1043/*===========================================================================
1044 * FUNCTION   : cancel_auto_focus
1045 *
1046 * DESCRIPTION: Cancels auto focus
1047 *
1048 * PARAMETERS :
1049 *   @device : camera hardware device info
1050 *
1051 * RETURN     :
1052 *              NO_ERROR  : success
1053 *              other: non-zero failure code
1054 *==========================================================================*/
1055int QCameraMuxer::cancel_auto_focus(struct camera_device * device)
1056{
1057    LOGH("E");
1058    CHECK_MUXER_ERROR();
1059    int rc = NO_ERROR;
1060    qcamera_physical_descriptor_t *pCam = NULL;
1061    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1062    CHECK_CAMERA_ERROR(cam);
1063
1064    for (uint32_t i = 0; i < cam->numCameras; i++) {
1065        pCam = gMuxer->getPhysicalCamera(cam, i);
1066        CHECK_CAMERA_ERROR(pCam);
1067
1068        QCamera2HardwareInterface *hwi = pCam->hwi;
1069        CHECK_HWI_ERROR(hwi);
1070        // Cancel auto focus on primary camera
1071        if (pCam->mode == CAM_MODE_PRIMARY) {
1072            rc = QCamera2HardwareInterface::cancel_auto_focus(pCam->dev);
1073            if (rc != NO_ERROR) {
1074                LOGE("Error cancelling auto focus !! ");
1075                return rc;
1076            }
1077            break;
1078        }
1079    }
1080    LOGH("X");
1081    return rc;
1082}
1083
1084/*===========================================================================
1085 * FUNCTION   : take_picture
1086 *
1087 * DESCRIPTION: Take snapshots on device
1088 *
1089 * PARAMETERS :
1090 *   @device : camera hardware device info
1091 *
1092 * RETURN     :
1093 *              NO_ERROR  : success
1094 *              other: non-zero failure code
1095 *==========================================================================*/
1096int QCameraMuxer::take_picture(struct camera_device * device)
1097{
1098    LOGH("E");
1099    CHECK_MUXER_ERROR();
1100    int rc = NO_ERROR;
1101    bool previewRestartNeeded = false;
1102    qcamera_physical_descriptor_t *pCam = NULL;
1103    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1104    CHECK_CAMERA_ERROR(cam);
1105
1106    char prop[PROPERTY_VALUE_MAX];
1107    property_get("persist.camera.dual.camera.mpo", prop, "1");
1108    gMuxer->m_bMpoEnabled = atoi(prop);
1109    // If only one Physical Camera included in Logical, disable MPO
1110    int numOfAcitvePhyCam = 0;
1111    gMuxer->getActiveNumOfPhyCam(cam, numOfAcitvePhyCam);
1112    if (gMuxer->m_bMpoEnabled && numOfAcitvePhyCam <= 1) {
1113        gMuxer->m_bMpoEnabled = 0;
1114    }
1115    LOGH("dualCamera MPO Enabled:%d ", gMuxer->m_bMpoEnabled);
1116
1117    if (!gMuxer->mJpegClientHandle) {
1118        // set up jpeg handles
1119        pCam = gMuxer->getPhysicalCamera(cam, 0);
1120        CHECK_CAMERA_ERROR(pCam);
1121
1122        QCamera2HardwareInterface *hwi = pCam->hwi;
1123        CHECK_HWI_ERROR(hwi);
1124
1125        rc = hwi->getJpegHandleInfo(&gMuxer->mJpegOps, &gMuxer->mJpegMpoOps,
1126                &gMuxer->mJpegClientHandle);
1127        if (rc != NO_ERROR) {
1128            LOGE("Error retrieving jpeg handle!");
1129            return rc;
1130        }
1131
1132        for (uint32_t i = 1; i < cam->numCameras; i++) {
1133            pCam = gMuxer->getPhysicalCamera(cam, i);
1134            CHECK_CAMERA_ERROR(pCam);
1135
1136            QCamera2HardwareInterface *hwi = pCam->hwi;
1137            CHECK_HWI_ERROR(hwi);
1138
1139            rc = hwi->setJpegHandleInfo(&gMuxer->mJpegOps, &gMuxer->mJpegMpoOps,
1140                    gMuxer->mJpegClientHandle);
1141            if (rc != NO_ERROR) {
1142                LOGE("Error setting jpeg handle %d!", i);
1143                return rc;
1144            }
1145        }
1146    }
1147
1148    // prepare snapshot for main camera
1149    for (uint32_t i = 0; i < cam->numCameras; i++) {
1150        pCam = gMuxer->getPhysicalCamera(cam, i);
1151        CHECK_CAMERA_ERROR(pCam);
1152
1153        QCamera2HardwareInterface *hwi = pCam->hwi;
1154        CHECK_HWI_ERROR(hwi);
1155
1156        if (pCam->mode == CAM_MODE_PRIMARY) {
1157            rc = hwi->prepare_snapshot(pCam->dev);
1158            if (rc != NO_ERROR) {
1159                LOGE("Error preparing for snapshot !! ");
1160                return rc;
1161            }
1162        }
1163        // set Mpo composition for each session
1164        rc = hwi->setMpoComposition(gMuxer->m_bMpoEnabled);
1165        //disable MPO if AOST features are enabled
1166        if (rc != NO_ERROR) {
1167            gMuxer->m_bMpoEnabled = 0;
1168            rc = NO_ERROR;
1169        }
1170    }
1171
1172    // initialize Jpeg Queues
1173    gMuxer->m_MainJpegQ.init();
1174    gMuxer->m_AuxJpegQ.init();
1175    gMuxer->m_ComposeMpoTh.sendCmd(
1176            CAMERA_CMD_TYPE_START_DATA_PROC, FALSE, FALSE);
1177
1178    // In cases where recording hint is set, preview is running,
1179    // hwi->take_picture will internally restart the preview.
1180    // To take the preview restart control in muxer,
1181    // 1. call pre_take_picture first
1182    for (uint32_t i = 0; i < cam->numCameras; i++) {
1183        pCam = gMuxer->getPhysicalCamera(cam, i);
1184        CHECK_CAMERA_ERROR(pCam);
1185
1186        QCamera2HardwareInterface *hwi = pCam->hwi;
1187        CHECK_HWI_ERROR(hwi);
1188
1189        // no need to call pre_take_pic on Aux if not MPO (for AOST,liveshot...etc.)
1190        if ( (gMuxer->m_bMpoEnabled == 1) || (pCam->mode == CAM_MODE_PRIMARY) ) {
1191            rc = hwi->pre_take_picture(pCam->dev);
1192            if (rc != NO_ERROR) {
1193                LOGE("Error preparing take_picture!! ");
1194                return rc;
1195            }
1196        }
1197    }
1198
1199    // 2. Check if preview restart is needed. Check all cameras.
1200    for (uint32_t i = 0; i < cam->numCameras; i++) {
1201        pCam = gMuxer->getPhysicalCamera(cam, i);
1202        CHECK_CAMERA_ERROR(pCam);
1203
1204        QCamera2HardwareInterface *hwi = pCam->hwi;
1205        CHECK_HWI_ERROR(hwi);
1206
1207        if (hwi->isPreviewRestartNeeded()) {
1208            previewRestartNeeded = hwi->isPreviewRestartNeeded();
1209            break;
1210        }
1211    }
1212
1213    if (previewRestartNeeded) {
1214        // 3. if preview restart needed. stop the preview first
1215        for (uint32_t i = 0; i < cam->numCameras; i++) {
1216            pCam = gMuxer->getPhysicalCamera(cam, i);
1217            CHECK_CAMERA_ERROR(pCam);
1218
1219            QCamera2HardwareInterface *hwi = pCam->hwi;
1220            CHECK_HWI_ERROR(hwi);
1221
1222            rc = hwi->restart_stop_preview(pCam->dev);
1223            if (rc != NO_ERROR) {
1224                LOGE("Error in restart stop preview!! ");
1225                return rc;
1226            }
1227        }
1228
1229        //4. Update the recording hint value to FALSE
1230        for (uint32_t i = 0; i < cam->numCameras; i++) {
1231            pCam = gMuxer->getPhysicalCamera(cam, i);
1232            CHECK_CAMERA_ERROR(pCam);
1233
1234            QCamera2HardwareInterface *hwi = pCam->hwi;
1235            CHECK_HWI_ERROR(hwi);
1236
1237            rc = hwi->setRecordingHintValue(FALSE);
1238            if (rc != NO_ERROR) {
1239                LOGE("Error in setting recording hint value!! ");
1240                return rc;
1241            }
1242        }
1243
1244        // 5. start the preview
1245        for (uint32_t i = 0; i < cam->numCameras; i++) {
1246            pCam = gMuxer->getPhysicalCamera(cam, i);
1247            CHECK_CAMERA_ERROR(pCam);
1248
1249            QCamera2HardwareInterface *hwi = pCam->hwi;
1250            CHECK_HWI_ERROR(hwi);
1251
1252            rc = hwi->restart_start_preview(pCam->dev);
1253            if (rc != NO_ERROR) {
1254                LOGE("Error in restart start preview!! ");
1255                return rc;
1256            }
1257        }
1258    }
1259
1260    // As frame sync for dual cameras is enabled, the take picture call
1261    // for secondary camera is handled only till HAL level to init corresponding
1262    // pproc channel and update statemachine.
1263    // This call is forwarded to mm-camera-intf only for primary camera
1264    // Primary camera should receive the take picture call after all secondary
1265    // camera statemachines are updated
1266    for (int32_t i = cam->numCameras-1 ; i >= 0; i--) {
1267        pCam = gMuxer->getPhysicalCamera(cam, i);
1268        CHECK_CAMERA_ERROR(pCam);
1269
1270        QCamera2HardwareInterface *hwi = pCam->hwi;
1271        CHECK_HWI_ERROR(hwi);
1272
1273        // no need to call take_pic on Aux if not MPO (for AOST)
1274        if ( (gMuxer->m_bMpoEnabled == 1) || (pCam->mode == CAM_MODE_PRIMARY) ) {
1275            rc = QCamera2HardwareInterface::take_picture(pCam->dev);
1276            if (rc != NO_ERROR) {
1277                LOGE("Error taking picture !! ");
1278                return rc;
1279            }
1280        }
1281    }
1282    LOGH("X");
1283    return rc;
1284}
1285
1286/*===========================================================================
1287 * FUNCTION   : cancel_picture
1288 *
1289 * DESCRIPTION: Cancel the take picture call
1290 *
1291 * PARAMETERS :
1292 *   @device : camera hardware device info
1293 *
1294 * RETURN     :
1295 *              NO_ERROR  : success
1296 *              other: non-zero failure code
1297 *==========================================================================*/
1298int QCameraMuxer::cancel_picture(struct camera_device * device)
1299{
1300    LOGH("E");
1301    CHECK_MUXER_ERROR();
1302    int rc = NO_ERROR;
1303    qcamera_physical_descriptor_t *pCam = NULL;
1304    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1305    CHECK_CAMERA_ERROR(cam);
1306
1307    for (uint32_t i = 0; i < cam->numCameras; i++) {
1308        pCam = gMuxer->getPhysicalCamera(cam, i);
1309        CHECK_CAMERA_ERROR(pCam);
1310
1311        QCamera2HardwareInterface *hwi = pCam->hwi;
1312        CHECK_HWI_ERROR(hwi);
1313
1314        rc = QCamera2HardwareInterface::cancel_picture(pCam->dev);
1315        if (rc != NO_ERROR) {
1316            LOGE("Error cancelling picture !! ");
1317            return rc;
1318        }
1319    }
1320    gMuxer->m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC, FALSE, FALSE);
1321    // flush Jpeg Queues
1322    gMuxer->m_MainJpegQ.flush();
1323    gMuxer->m_AuxJpegQ.flush();
1324
1325    LOGH("X");
1326    return rc;
1327}
1328
1329/*===========================================================================
1330 * FUNCTION   : set_parameters
1331 *
1332 * DESCRIPTION: Sets the parameters on camera
1333 *
1334 * PARAMETERS :
1335 *   @device : camera hardware device info
1336 *   @parms : Parameters to be set on camera
1337 *
1338 * RETURN     :
1339 *              NO_ERROR  : success
1340 *              other: non-zero failure code
1341 *==========================================================================*/
1342int QCameraMuxer::set_parameters(struct camera_device * device,
1343        const char *parms)
1344
1345{
1346    LOGH("E");
1347    CHECK_MUXER_ERROR();
1348    int rc = NO_ERROR;
1349    qcamera_physical_descriptor_t *pCam = NULL;
1350    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1351    bool needRestart = false;
1352    CHECK_CAMERA_ERROR(cam);
1353
1354    for (uint32_t i = 0; i < cam->numCameras; i++) {
1355        pCam = gMuxer->getPhysicalCamera(cam, i);
1356        CHECK_CAMERA_ERROR(pCam);
1357
1358        QCamera2HardwareInterface *hwi = pCam->hwi;
1359        CHECK_HWI_ERROR(hwi);
1360
1361        rc = QCamera2HardwareInterface::set_parameters(pCam->dev, parms);
1362        if (rc != NO_ERROR) {
1363            LOGE("Error setting parameters !! ");
1364            return rc;
1365        }
1366
1367        needRestart |= hwi->getNeedRestart();
1368    }
1369
1370    if (needRestart) {
1371        for (uint32_t i = 0; i < cam->numCameras; i++) {
1372            pCam = gMuxer->getPhysicalCamera(cam, i);
1373            CHECK_CAMERA_ERROR(pCam);
1374
1375            QCamera2HardwareInterface *hwi = pCam->hwi;
1376            CHECK_HWI_ERROR(hwi);
1377
1378            LOGD("stopping preview for cam %d", i);
1379            rc = QCamera2HardwareInterface::stop_after_set_params(pCam->dev);
1380            if (rc != NO_ERROR) {
1381                LOGE("Error stopping camera rc=%d!! ", rc);
1382                return rc;
1383            }
1384        }
1385    }
1386
1387    for (uint32_t i = 0; i < cam->numCameras; i++) {
1388        pCam = gMuxer->getPhysicalCamera(cam, i);
1389        CHECK_CAMERA_ERROR(pCam);
1390
1391        QCamera2HardwareInterface *hwi = pCam->hwi;
1392        CHECK_HWI_ERROR(hwi);
1393
1394        LOGD("commiting parameters for cam %d", i);
1395        rc = QCamera2HardwareInterface::commit_params(pCam->dev);
1396        if (rc != NO_ERROR) {
1397            LOGE("Error committing parameters rc=%d!! ", rc);
1398            return rc;
1399        }
1400    }
1401
1402    if (needRestart) {
1403        for (uint32_t i = 0; i < cam->numCameras; i++) {
1404            pCam = gMuxer->getPhysicalCamera(cam, i);
1405            CHECK_CAMERA_ERROR(pCam);
1406
1407            QCamera2HardwareInterface *hwi = pCam->hwi;
1408            CHECK_HWI_ERROR(hwi);
1409
1410            LOGD("restarting preview for cam %d", i);
1411            rc = QCamera2HardwareInterface::restart_after_set_params(pCam->dev);
1412            if (rc != NO_ERROR) {
1413                LOGE("Error restarting camera rc=%d!! ", rc);
1414                return rc;
1415            }
1416        }
1417    }
1418
1419    LOGH(" X");
1420    return rc;
1421}
1422
1423/*===========================================================================
1424 * FUNCTION   : get_parameters
1425 *
1426 * DESCRIPTION: Gets the parameters on camera
1427 *
1428 * PARAMETERS :
1429 *   @device : camera hardware device info
1430 *
1431 * RETURN     : Parameter string or NULL
1432 *==========================================================================*/
1433char* QCameraMuxer::get_parameters(struct camera_device * device)
1434{
1435    LOGH("E");
1436
1437    if (!gMuxer)
1438        return NULL;
1439
1440    char* ret = NULL;
1441    qcamera_physical_descriptor_t *pCam = NULL;
1442    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1443    if (!cam) {
1444        LOGE("Error getting logical camera");
1445        return NULL;
1446    }
1447
1448    for (uint32_t i = 0; i < cam->numCameras; i++) {
1449        pCam = gMuxer->getPhysicalCamera(cam, i);
1450        if (!pCam) {
1451            LOGE("Error getting physical camera");
1452            return NULL;
1453        }
1454        QCamera2HardwareInterface *hwi = pCam->hwi;
1455        if (!hwi) {
1456            LOGE("Allocation of hardware interface failed");
1457            return NULL;
1458        }
1459        if (pCam->mode == CAM_MODE_PRIMARY) {
1460            // Get only primary camera parameters
1461            ret = QCamera2HardwareInterface::get_parameters(pCam->dev);
1462            break;
1463        }
1464    }
1465
1466    LOGH("X");
1467    return ret;
1468}
1469
1470/*===========================================================================
1471 * FUNCTION   : put_parameters
1472 *
1473 * DESCRIPTION: Puts parameters on camera
1474 *
1475 * PARAMETERS :
1476 *   @device : camera hardware device info
1477 *   @parm : parameters
1478 *
1479 * RETURN     : None
1480 *==========================================================================*/
1481void QCameraMuxer::put_parameters(struct camera_device * device, char *parm)
1482{
1483    LOGH("E");
1484    CHECK_MUXER();
1485    qcamera_physical_descriptor_t *pCam = NULL;
1486    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1487    CHECK_CAMERA(cam);
1488
1489    for (uint32_t i = 0; i < cam->numCameras; i++) {
1490        pCam = gMuxer->getPhysicalCamera(cam, i);
1491        CHECK_CAMERA(pCam);
1492
1493        QCamera2HardwareInterface *hwi = pCam->hwi;
1494        CHECK_HWI(hwi);
1495
1496        if (pCam->mode == CAM_MODE_PRIMARY) {
1497            // Parameters are not used in HWI and hence freed
1498            QCamera2HardwareInterface::put_parameters(pCam->dev, parm);
1499            break;
1500        }
1501    }
1502    LOGH("X");
1503}
1504
1505/*===========================================================================
1506 * FUNCTION   : send_command
1507 *
1508 * DESCRIPTION: Send command to camera
1509 *
1510 * PARAMETERS :
1511 *   @device : camera hardware device info
1512 *   @cmd : Command
1513 *   @arg1/arg2 : command arguments
1514 *
1515 * RETURN     :
1516 *              NO_ERROR  : success
1517 *              other: non-zero failure code
1518 *==========================================================================*/
1519int QCameraMuxer::send_command(struct camera_device * device,
1520        int32_t cmd, int32_t arg1, int32_t arg2)
1521{
1522    LOGH("E");
1523    CHECK_MUXER_ERROR();
1524    int rc = NO_ERROR;
1525    qcamera_physical_descriptor_t *pCam = NULL;
1526    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1527    CHECK_CAMERA_ERROR(cam);
1528
1529    for (uint32_t i = 0; i < cam->numCameras; i++) {
1530        pCam = gMuxer->getPhysicalCamera(cam, i);
1531        CHECK_CAMERA_ERROR(pCam);
1532
1533        QCamera2HardwareInterface *hwi = pCam->hwi;
1534        CHECK_HWI_ERROR(hwi);
1535
1536        rc = QCamera2HardwareInterface::send_command(pCam->dev, cmd, arg1, arg2);
1537        if (rc != NO_ERROR) {
1538            LOGE("Error sending command !! ");
1539            return rc;
1540        }
1541    }
1542
1543        switch (cmd) {
1544#ifndef VANILLA_HAL
1545        case CAMERA_CMD_LONGSHOT_ON:
1546            for (uint32_t i = 0; i < cam->numCameras; i++) {
1547                pCam = gMuxer->getPhysicalCamera(cam, i);
1548                CHECK_CAMERA_ERROR(pCam);
1549
1550                QCamera2HardwareInterface *hwi = pCam->hwi;
1551                CHECK_HWI_ERROR(hwi);
1552
1553                rc = QCamera2HardwareInterface::send_command_restart(pCam->dev,
1554                        cmd, arg1, arg2);
1555                if (rc != NO_ERROR) {
1556                    LOGE("Error sending command restart !! ");
1557                    return rc;
1558                }
1559            }
1560        break;
1561        case CAMERA_CMD_LONGSHOT_OFF:
1562            gMuxer->m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_STOP_DATA_PROC,
1563                    FALSE, FALSE);
1564            // flush Jpeg Queues
1565            gMuxer->m_MainJpegQ.flush();
1566            gMuxer->m_AuxJpegQ.flush();
1567        break;
1568#endif
1569        default:
1570            // do nothing
1571            rc = NO_ERROR;
1572        break;
1573        }
1574
1575    LOGH("X");
1576    return rc;
1577}
1578
1579/*===========================================================================
1580 * FUNCTION   : release
1581 *
1582 * DESCRIPTION: Release the camera
1583 *
1584 * PARAMETERS :
1585 *   @device : camera hardware device info
1586 *
1587 * RETURN     : None
1588 *==========================================================================*/
1589void QCameraMuxer::release(struct camera_device * device)
1590{
1591    LOGH("E");
1592    CHECK_MUXER();
1593    qcamera_physical_descriptor_t *pCam = NULL;
1594    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1595    CHECK_CAMERA(cam);
1596
1597    for (uint32_t i = 0; i < cam->numCameras; i++) {
1598        pCam = gMuxer->getPhysicalCamera(cam, i);
1599        CHECK_CAMERA(pCam);
1600
1601        QCamera2HardwareInterface *hwi = pCam->hwi;
1602        CHECK_HWI(hwi);
1603
1604        QCamera2HardwareInterface::release(pCam->dev);
1605    }
1606    LOGH("X");
1607}
1608
1609/*===========================================================================
1610 * FUNCTION   : dump
1611 *
1612 * DESCRIPTION: Dump the camera info
1613 *
1614 * PARAMETERS :
1615 *   @device : camera hardware device info
1616 *   @fd : fd
1617 *
1618 * RETURN     :
1619 *              NO_ERROR  : success
1620 *              other: non-zero failure code
1621 *==========================================================================*/
1622int QCameraMuxer::dump(struct camera_device * device, int fd)
1623{
1624    LOGH("E");
1625    CHECK_MUXER_ERROR();
1626    int rc = NO_ERROR;
1627    qcamera_physical_descriptor_t *pCam = NULL;
1628    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(device);
1629    CHECK_CAMERA_ERROR(cam);
1630
1631    for (uint32_t i = 0; i < cam->numCameras; i++) {
1632        pCam = gMuxer->getPhysicalCamera(cam, i);
1633        CHECK_CAMERA_ERROR(pCam);
1634
1635        QCamera2HardwareInterface *hwi = pCam->hwi;
1636        CHECK_HWI_ERROR(hwi);
1637
1638        rc = QCamera2HardwareInterface::dump(pCam->dev, fd);
1639        if (rc != NO_ERROR) {
1640            LOGE("Error dumping");
1641            return rc;
1642        }
1643    }
1644    LOGH("X");
1645    return rc;
1646}
1647
1648/*===========================================================================
1649 * FUNCTION   : close_camera_device
1650 *
1651 * DESCRIPTION: Close the camera
1652 *
1653 * PARAMETERS :
1654 *   @hw_dev : camera hardware device info
1655 *
1656 * RETURN     :
1657 *              NO_ERROR  : success
1658 *              other: non-zero failure code
1659 *==========================================================================*/
1660int QCameraMuxer::close_camera_device(hw_device_t *hw_dev)
1661{
1662    LOGH("E");
1663    CHECK_MUXER_ERROR();
1664    int rc = NO_ERROR;
1665    qcamera_physical_descriptor_t *pCam = NULL;
1666    camera_device_t *cam_dev = (camera_device_t*)hw_dev;
1667    qcamera_logical_descriptor_t *cam = gMuxer->getLogicalCamera(cam_dev);
1668    CHECK_CAMERA_ERROR(cam);
1669
1670    // Unlink camera sessions
1671    if (cam->bSyncOn) {
1672        if (cam->numCameras > 1) {
1673            uint sessionId = 0;
1674            // unbundle primary camera with all aux cameras
1675            for (uint32_t i = 0; i < cam->numCameras; i++) {
1676                pCam = gMuxer->getPhysicalCamera(cam, i);
1677                CHECK_CAMERA_ERROR(pCam);
1678
1679                QCamera2HardwareInterface *hwi = pCam->hwi;
1680                CHECK_HWI_ERROR(hwi);
1681
1682                if(pCam->mode == CAM_MODE_PRIMARY) {
1683                    // bundle primary cam with all aux cameras
1684                    for (uint32_t j = 0; j < cam->numCameras; j++) {
1685                        if (j == cam->nPrimaryPhyCamIndex) {
1686                            continue;
1687                        }
1688                        sessionId = cam->sId[j];
1689                        LOGH("Related cam id: %d, server id: %d sync OFF"
1690                                " related session_id %d",
1691                                cam->pId[i], cam->sId[i], sessionId);
1692                        rc = hwi->bundleRelatedCameras(false, sessionId);
1693                        if (rc != NO_ERROR) {
1694                            LOGE("Error Bundling physical cameras !! ");
1695                            break;
1696                        }
1697                    }
1698                }
1699
1700                if (pCam->mode == CAM_MODE_SECONDARY) {
1701                    // unbundle all aux cam with primary cams
1702                    sessionId = cam->sId[cam->nPrimaryPhyCamIndex];
1703                    LOGH("Related cam id: %d, server id: %d sync OFF"
1704                            " related session_id %d",
1705                            cam->pId[i], cam->sId[i], sessionId);
1706                    rc = hwi->bundleRelatedCameras(false, sessionId);
1707                    if (rc != NO_ERROR) {
1708                        LOGE("Error Bundling physical cameras !! ");
1709                        break;
1710                    }
1711                }
1712            }
1713        }
1714        cam->bSyncOn = false;
1715    }
1716
1717    // Attempt to close all cameras regardless of unbundle results
1718    for (uint32_t i = 0; i < cam->numCameras; i++) {
1719        pCam = gMuxer->getPhysicalCamera(cam, i);
1720        CHECK_CAMERA_ERROR(pCam);
1721
1722        hw_device_t *dev = (hw_device_t*)(pCam->dev);
1723        LOGH("hw device %x, hw %x", dev, pCam->hwi);
1724
1725        rc = QCamera2HardwareInterface::close_camera_device(dev);
1726        if (rc != NO_ERROR) {
1727            LOGE("Error closing camera");
1728        }
1729        pCam->hwi = NULL;
1730        pCam->dev = NULL;
1731    }
1732
1733    // Reset JPEG client handle
1734    gMuxer->setJpegHandle(0);
1735    LOGH("X, rc: %d", rc);
1736    return rc;
1737}
1738
1739/*===========================================================================
1740 * FUNCTION         : setupLogicalCameras
1741 *
1742 * DESCRIPTION     : Creates Camera Muxer if not created
1743 *
1744 * RETURN     :
1745 *              NO_ERROR  : success
1746 *              other: non-zero failure code
1747 *==========================================================================*/
1748int QCameraMuxer::setupLogicalCameras()
1749{
1750    int rc = NO_ERROR;
1751    char prop[PROPERTY_VALUE_MAX];
1752    int i = 0;
1753    int primaryType = CAM_TYPE_MAIN;
1754
1755    LOGH("[%d] E: rc = %d", rc);
1756    // Signifies whether AUX camera has to be exposed as physical camera
1757    property_get("persist.camera.aux.camera", prop, "0");
1758    m_bAuxCameraExposed = atoi(prop);
1759
1760    // Signifies whether AUX camera needs to be swapped
1761    property_get("persist.camera.auxcamera.swap", prop, "0");
1762    int swapAux = atoi(prop);
1763    if (swapAux != 0) {
1764        primaryType = CAM_TYPE_AUX;
1765    }
1766
1767    // Check for number of camera present on device
1768    if (!m_nPhyCameras || (m_nPhyCameras > MM_CAMERA_MAX_NUM_SENSORS)) {
1769        LOGE("Error!! Invalid number of cameras: %d",
1770                 m_nPhyCameras);
1771        return BAD_VALUE;
1772    }
1773
1774    m_pPhyCamera = new qcamera_physical_descriptor_t[m_nPhyCameras];
1775    if (!m_pPhyCamera) {
1776        LOGE("Error allocating camera info buffer!!");
1777        return NO_MEMORY;
1778    }
1779    memset(m_pPhyCamera, 0x00,
1780            (m_nPhyCameras * sizeof(qcamera_physical_descriptor_t)));
1781    uint32_t cameraId = 0;
1782    m_nLogicalCameras = 0;
1783
1784    // Enumerate physical cameras and logical
1785    for (i = 0; i < m_nPhyCameras ; i++, cameraId++) {
1786        camera_info *info = &m_pPhyCamera[i].cam_info;
1787        rc = QCamera2HardwareInterface::getCapabilities(cameraId,
1788                info, &m_pPhyCamera[i].type);
1789        m_pPhyCamera[i].id = cameraId;
1790        m_pPhyCamera[i].device_version = CAMERA_DEVICE_API_VERSION_1_0;
1791        m_pPhyCamera[i].mode = CAM_MODE_PRIMARY;
1792
1793        if (!m_bAuxCameraExposed && (m_pPhyCamera[i].type != primaryType)) {
1794            m_pPhyCamera[i].mode = CAM_MODE_SECONDARY;
1795            LOGH("Camera ID: %d, Aux Camera, type: %d, facing: %d",
1796 cameraId, m_pPhyCamera[i].type,
1797                    m_pPhyCamera[i].cam_info.facing);
1798        }
1799        else {
1800            m_nLogicalCameras++;
1801            LOGH("Camera ID: %d, Main Camera, type: %d, facing: %d",
1802 cameraId, m_pPhyCamera[i].type,
1803                    m_pPhyCamera[i].cam_info.facing);
1804        }
1805    }
1806
1807    if (!m_nLogicalCameras) {
1808        // No Main camera detected, return from here
1809        LOGE("Error !!!! detecting main camera!!");
1810        delete [] m_pPhyCamera;
1811        m_pPhyCamera = NULL;
1812        return -ENODEV;
1813    }
1814    // Allocate Logical Camera descriptors
1815    m_pLogicalCamera = new qcamera_logical_descriptor_t[m_nLogicalCameras];
1816    if (!m_pLogicalCamera) {
1817        LOGE("Error !!!! allocating camera info buffer!!");
1818        delete [] m_pPhyCamera;
1819        m_pPhyCamera = NULL;
1820        return  NO_MEMORY;
1821    }
1822    memset(m_pLogicalCamera, 0x00,
1823            (m_nLogicalCameras * sizeof(qcamera_logical_descriptor_t)));
1824    // Assign MAIN cameras for each logical camera
1825    int index = 0;
1826    for (i = 0; i < m_nPhyCameras ; i++) {
1827        if (m_pPhyCamera[i].mode == CAM_MODE_PRIMARY) {
1828            m_pLogicalCamera[index].nPrimaryPhyCamIndex = 0;
1829            m_pLogicalCamera[index].id = index;
1830            m_pLogicalCamera[index].device_version = CAMERA_DEVICE_API_VERSION_1_0;
1831            m_pLogicalCamera[index].pId[0] = i;
1832            m_pLogicalCamera[index].type[0] = CAM_TYPE_MAIN;
1833            m_pLogicalCamera[index].mode[0] = CAM_MODE_PRIMARY;
1834            m_pLogicalCamera[index].facing = m_pPhyCamera[i].cam_info.facing;
1835            m_pLogicalCamera[index].numCameras++;
1836            LOGH("Logical Main Camera ID: %d, facing: %d,"
1837                    "Phy Id: %d type: %d mode: %d",
1838 m_pLogicalCamera[index].id,
1839                    m_pLogicalCamera[index].facing,
1840                    m_pLogicalCamera[index].pId[0],
1841                    m_pLogicalCamera[index].type[0],
1842                    m_pLogicalCamera[index].mode[0]);
1843
1844            index++;
1845        }
1846    }
1847    //Now assign AUX cameras to logical camera
1848    for (i = 0; i < m_nPhyCameras ; i++) {
1849        if (m_pPhyCamera[i].mode == CAM_MODE_SECONDARY) {
1850            for (int j = 0; j < m_nLogicalCameras; j++) {
1851                int n = m_pLogicalCamera[j].numCameras;
1852                ///@note n can only be 1 at this point
1853                if ((n < MAX_NUM_CAMERA_PER_BUNDLE) &&
1854                        (m_pLogicalCamera[j].facing ==
1855                        m_pPhyCamera[i].cam_info.facing)) {
1856                    m_pLogicalCamera[j].pId[n] = i;
1857                    m_pLogicalCamera[j].type[n] = CAM_TYPE_AUX;
1858                    m_pLogicalCamera[j].mode[n] = CAM_MODE_SECONDARY;
1859                    m_pLogicalCamera[j].numCameras++;
1860                    LOGH("Aux %d for Logical Camera ID: %d,"
1861                        "aux phy id:%d, type: %d mode: %d",
1862 n, j, m_pLogicalCamera[j].pId[n],
1863                        m_pLogicalCamera[j].type[n], m_pLogicalCamera[j].mode[n]);
1864                }
1865            }
1866        }
1867    }
1868    //Print logical and physical camera tables
1869    for (i = 0; i < m_nLogicalCameras ; i++) {
1870        for (uint8_t j = 0; j < m_pLogicalCamera[i].numCameras; j++) {
1871            LOGH("Logical Camera ID: %d, index: %d, "
1872                    "facing: %d, Phy Id: %d type: %d mode: %d",
1873 i, j, m_pLogicalCamera[i].facing,
1874                    m_pLogicalCamera[i].pId[j], m_pLogicalCamera[i].type[j],
1875                    m_pLogicalCamera[i].mode[j]);
1876        }
1877    }
1878    LOGH("[%d] X: rc = %d", rc);
1879    return rc;
1880}
1881
1882/*===========================================================================
1883 * FUNCTION   : getNumberOfCameras
1884 *
1885 * DESCRIPTION: query number of logical cameras detected
1886 *
1887 * RETURN     : number of cameras detected
1888 *==========================================================================*/
1889int QCameraMuxer::getNumberOfCameras()
1890{
1891    return m_nLogicalCameras;
1892}
1893
1894/*===========================================================================
1895 * FUNCTION   : getCameraInfo
1896 *
1897 * DESCRIPTION: query camera information with its ID
1898 *
1899 * PARAMETERS :
1900 *   @camera_id : camera ID
1901 *   @info      : ptr to camera info struct
1902 *
1903 * RETURN     : int32_t type of status
1904 *              NO_ERROR  -- success
1905 *              none-zero failure code
1906 *==========================================================================*/
1907int QCameraMuxer::getCameraInfo(int camera_id,
1908        struct camera_info *info, __unused cam_sync_type_t *p_cam_type)
1909{
1910    int rc = NO_ERROR;
1911    LOGH("E, camera_id = %d", camera_id);
1912    cam_sync_type_t cam_type = CAM_TYPE_MAIN;
1913
1914    if (!m_nLogicalCameras || (camera_id >= m_nLogicalCameras) ||
1915            !info || (camera_id < 0)) {
1916        LOGE("m_nLogicalCameras: %d, camera id: %d",
1917                m_nLogicalCameras, camera_id);
1918        return -ENODEV;
1919    }
1920
1921    if (!m_pLogicalCamera || !m_pPhyCamera) {
1922        LOGE("Error! Cameras not initialized!");
1923        return NO_INIT;
1924    }
1925    uint32_t phy_id =
1926            m_pLogicalCamera[camera_id].pId[
1927            m_pLogicalCamera[camera_id].nPrimaryPhyCamIndex];
1928    rc = QCamera2HardwareInterface::getCapabilities(phy_id, info, &cam_type);
1929    LOGH("X");
1930    return rc;
1931}
1932
1933/*===========================================================================
1934 * FUNCTION   : setCallbacks
1935 *
1936 * DESCRIPTION: set callback functions to send asynchronous notifications to
1937 *              frameworks.
1938 *
1939 * PARAMETERS :
1940 *   @callbacks : callback function pointer
1941 *
1942 * RETURN     : int32_t type of status
1943 *              NO_ERROR  -- success
1944 *              none-zero failure code
1945 *==========================================================================*/
1946int32_t QCameraMuxer::setCallbacks(const camera_module_callbacks_t *callbacks)
1947{
1948    if(callbacks) {
1949        m_pCallbacks = callbacks;
1950        return NO_ERROR;
1951    } else {
1952        return BAD_TYPE;
1953    }
1954}
1955
1956/*===========================================================================
1957 * FUNCTION   : setDataCallback
1958 *
1959 * DESCRIPTION: set data callback function for snapshots
1960 *
1961 * PARAMETERS :
1962 *   @data_cb : callback function pointer
1963 *
1964 * RETURN     : int32_t type of status
1965 *              NO_ERROR  -- success
1966 *              none-zero failure code
1967 *==========================================================================*/
1968int32_t QCameraMuxer::setDataCallback(camera_data_callback data_cb)
1969{
1970    if(data_cb) {
1971        mDataCb = data_cb;
1972        return NO_ERROR;
1973    } else {
1974        return BAD_TYPE;
1975    }
1976}
1977
1978/*===========================================================================
1979 * FUNCTION   : setMemoryCallback
1980 *
1981 * DESCRIPTION: set get memory callback for memory allocations
1982 *
1983 * PARAMETERS :
1984 *   @get_memory : callback function pointer
1985 *
1986 * RETURN     : int32_t type of status
1987 *              NO_ERROR  -- success
1988 *              none-zero failure code
1989 *==========================================================================*/
1990int32_t QCameraMuxer::setMemoryCallback(camera_request_memory get_memory)
1991{
1992    if(get_memory) {
1993        mGetMemoryCb = get_memory;
1994        return NO_ERROR;
1995    } else {
1996        return BAD_TYPE;
1997    }
1998}
1999
2000/*===========================================================================
2001 * FUNCTION   : setMpoCallbackCookie
2002 *
2003 * DESCRIPTION: set mpo callback cookie. will be used for sending final MPO callbacks
2004 *                     to framework
2005 *
2006 * PARAMETERS :
2007 *   @mpoCbCookie : callback function pointer
2008 *
2009 * RETURN     : int32_t type of status
2010 *              NO_ERROR  -- success
2011 *              none-zero failure code
2012 *==========================================================================*/
2013int32_t QCameraMuxer::setMpoCallbackCookie(void* mpoCbCookie)
2014{
2015    if(mpoCbCookie) {
2016        m_pMpoCallbackCookie = mpoCbCookie;
2017        return NO_ERROR;
2018    } else {
2019        return BAD_TYPE;
2020    }
2021}
2022
2023/*===========================================================================
2024 * FUNCTION   : getMpoCallbackCookie
2025 *
2026 * DESCRIPTION: gets the mpo callback cookie. will be used for sending final MPO callbacks
2027 *                     to framework
2028 *
2029 * PARAMETERS :none
2030 *
2031 * RETURN     :void ptr to the mpo callback cookie
2032 *==========================================================================*/
2033void* QCameraMuxer::getMpoCallbackCookie(void)
2034{
2035    return m_pMpoCallbackCookie;
2036}
2037
2038/*===========================================================================
2039 * FUNCTION   : setMainJpegCallbackCookie
2040 *
2041 * DESCRIPTION: set jpeg callback cookie.
2042 *                     set to phy cam instance of the primary related cam instance
2043 *
2044 * PARAMETERS :
2045 *   @jpegCbCookie : ptr to jpeg cookie
2046 *
2047 * RETURN     : int32_t type of status
2048 *              NO_ERROR  -- success
2049 *              none-zero failure code
2050 *==========================================================================*/
2051int32_t QCameraMuxer::setMainJpegCallbackCookie(void* jpegCbCookie)
2052{
2053    if(jpegCbCookie) {
2054        m_pJpegCallbackCookie = jpegCbCookie;
2055        return NO_ERROR;
2056    } else {
2057        return BAD_TYPE;
2058    }
2059}
2060
2061/*===========================================================================
2062 * FUNCTION   : getMainJpegCallbackCookie
2063 *
2064 * DESCRIPTION: gets the jpeg callback cookie for primary related cam instance
2065 *                     set to phy cam instance of the primary related cam instance
2066 *
2067 * PARAMETERS :none
2068 *
2069 * RETURN     :void ptr to the jpeg callback cookie
2070 *==========================================================================*/
2071void* QCameraMuxer::getMainJpegCallbackCookie(void)
2072{
2073    return m_pJpegCallbackCookie;
2074}
2075
2076/*===========================================================================
2077 * FUNCTION   : cameraDeviceOpen
2078 *
2079 * DESCRIPTION: open a camera device with its ID
2080 *
2081 * PARAMETERS :
2082 *   @camera_id : camera ID
2083 *   @hw_device : ptr to struct storing camera hardware device info
2084 *
2085 * RETURN     : int32_t type of status
2086 *              NO_ERROR  -- success
2087 *              none-zero failure code
2088 *==========================================================================*/
2089int QCameraMuxer::cameraDeviceOpen(int camera_id,
2090        struct hw_device_t **hw_device)
2091{
2092    int rc = NO_ERROR;
2093    uint32_t phyId = 0;
2094    qcamera_logical_descriptor_t *cam = NULL;
2095
2096    if (camera_id < 0 || camera_id >= m_nLogicalCameras) {
2097        LOGE("Camera id %d not found!", camera_id);
2098        return -ENODEV;
2099    }
2100
2101    if ( NULL == m_pLogicalCamera) {
2102        LOGE("Hal descriptor table is not initialized!");
2103        return NO_INIT;
2104    }
2105
2106    char prop[PROPERTY_VALUE_MAX];
2107    property_get("persist.camera.dc.frame.sync", prop, "1");
2108    m_bFrameSyncEnabled = atoi(prop);
2109
2110    // Get logical camera
2111    cam = &m_pLogicalCamera[camera_id];
2112
2113    if (m_pLogicalCamera[camera_id].device_version ==
2114            CAMERA_DEVICE_API_VERSION_1_0) {
2115        // HW Dev Holders
2116        hw_device_t *hw_dev[cam->numCameras];
2117
2118        if (m_pPhyCamera[cam->pId[0]].type != CAM_TYPE_MAIN) {
2119            LOGE("Physical camera at index 0 is not main!");
2120            return UNKNOWN_ERROR;
2121        }
2122
2123        // Open all physical cameras
2124        for (uint32_t i = 0; i < cam->numCameras; i++) {
2125            phyId = cam->pId[i];
2126            QCamera2HardwareInterface *hw =
2127                    new QCamera2HardwareInterface((uint32_t)phyId);
2128            if (!hw) {
2129                LOGE("Allocation of hardware interface failed");
2130                return NO_MEMORY;
2131            }
2132            hw_dev[i] = NULL;
2133
2134            // Make Camera HWI aware of its mode
2135            cam_sync_related_sensors_event_info_t info;
2136            info.sync_control = CAM_SYNC_RELATED_SENSORS_ON;
2137            info.mode = m_pPhyCamera[phyId].mode;
2138            info.type = m_pPhyCamera[phyId].type;
2139            info.is_frame_sync_enabled = m_bFrameSyncEnabled;
2140            rc = hw->setRelatedCamSyncInfo(&info);
2141            if (rc != NO_ERROR) {
2142                LOGE("setRelatedCamSyncInfo failed %d", rc);
2143                delete hw;
2144                return rc;
2145            }
2146
2147            rc = hw->openCamera(&hw_dev[i]);
2148            if (rc != NO_ERROR) {
2149                delete hw;
2150                return rc;
2151            }
2152            hw->getCameraSessionId(&m_pPhyCamera[phyId].camera_server_id);
2153            m_pPhyCamera[phyId].dev = reinterpret_cast<camera_device_t*>(hw_dev[i]);
2154            m_pPhyCamera[phyId].hwi = hw;
2155            cam->sId[i] = m_pPhyCamera[phyId].camera_server_id;
2156            LOGH("camera id %d server id : %d hw device %x, hw %x",
2157                     phyId, cam->sId[i], hw_dev[i], hw);
2158        }
2159    } else {
2160        LOGE("Device version for camera id %d invalid %d",
2161                 camera_id, m_pLogicalCamera[camera_id].device_version);
2162        return BAD_VALUE;
2163    }
2164
2165    cam->dev.common.tag = HARDWARE_DEVICE_TAG;
2166    cam->dev.common.version = HARDWARE_DEVICE_API_VERSION(1, 0);
2167    cam->dev.common.close = close_camera_device;
2168    cam->dev.ops = &mCameraMuxerOps;
2169    cam->dev.priv = (void*)cam;
2170    *hw_device = &cam->dev.common;
2171    return rc;
2172}
2173
2174
2175/*===========================================================================
2176 * FUNCTION   : getLogicalCamera
2177 *
2178 * DESCRIPTION: Get logical camera descriptor
2179 *
2180 * PARAMETERS :
2181 *   @device : camera hardware device info
2182 *
2183 * RETURN     : logical camera descriptor or NULL
2184 *==========================================================================*/
2185qcamera_logical_descriptor_t* QCameraMuxer::getLogicalCamera(
2186        struct camera_device * device)
2187{
2188    if(device && device->priv){
2189        return (qcamera_logical_descriptor_t*)(device->priv);
2190    }
2191    return NULL;
2192}
2193
2194/*===========================================================================
2195 * FUNCTION   : getPhysicalCamera
2196 *
2197 * DESCRIPTION: Get physical camera descriptor
2198 *
2199 * PARAMETERS :
2200 *   @log_cam : Logical camera descriptor
2201 *   @index : physical camera index
2202 *
2203 * RETURN     : physical camera descriptor or NULL
2204 *==========================================================================*/
2205qcamera_physical_descriptor_t* QCameraMuxer::getPhysicalCamera(
2206        qcamera_logical_descriptor_t* log_cam, uint32_t index)
2207{
2208    if(!log_cam){
2209        return NULL;
2210    }
2211    return &m_pPhyCamera[log_cam->pId[index]];
2212}
2213
2214/*===========================================================================
2215 * FUNCTION   : getActiveNumOfPhyCam
2216 *
2217 * DESCRIPTION: Get active physical camera number in Logical Camera
2218 *
2219 * PARAMETERS :
2220 *   @log_cam :   Logical camera descriptor
2221 *   @numOfAcitvePhyCam :  number of active physical camera in Logical Camera.
2222 *
2223 * RETURN     :
2224 *                NO_ERROR  : success
2225 *                ENODEV : Camera not found
2226 *                other: non-zero failure code
2227 *==========================================================================*/
2228int32_t QCameraMuxer::getActiveNumOfPhyCam(
2229        qcamera_logical_descriptor_t* log_cam, int& numOfAcitvePhyCam)
2230{
2231    CHECK_CAMERA_ERROR(log_cam);
2232
2233    numOfAcitvePhyCam = log_cam->numCameras;
2234    return NO_ERROR;
2235}
2236
2237
2238/*===========================================================================
2239 * FUNCTION   : sendEvtNotify
2240 *
2241 * DESCRIPTION: send event notify to HWI for error callbacks
2242 *
2243 * PARAMETERS :
2244 *   @msg_type: msg type to be sent
2245 *   @ext1    : optional extension1
2246 *   @ext2    : optional extension2
2247 *
2248 * RETURN     : int32_t type of status
2249 *              NO_ERROR  -- success
2250 *              none-zero failure code
2251 *==========================================================================*/
2252int32_t QCameraMuxer::sendEvtNotify(int32_t msg_type, int32_t ext1,
2253        int32_t ext2)
2254{
2255    LOGH("E");
2256
2257    CHECK_MUXER_ERROR();
2258
2259    qcamera_physical_descriptor_t *pCam = NULL;
2260    pCam = (qcamera_physical_descriptor_t*)(gMuxer->getMainJpegCallbackCookie());
2261
2262    CHECK_CAMERA_ERROR(pCam);
2263
2264    QCamera2HardwareInterface *hwi = pCam->hwi;
2265    CHECK_HWI_ERROR(hwi);
2266
2267    LOGH("X");
2268    return pCam->hwi->sendEvtNotify(msg_type, ext1, ext2);
2269}
2270
2271/*===========================================================================
2272 * FUNCTION   : composeMpo
2273 *
2274 * DESCRIPTION: Composition of the 2 MPOs
2275 *
2276 * PARAMETERS : none
2277 *   @main_Jpeg: pointer to info to Main Jpeg
2278 *   @aux_Jpeg : pointer to info to Aux JPEG
2279 *
2280  * RETURN : none
2281 *==========================================================================*/
2282void QCameraMuxer::composeMpo(cam_compose_jpeg_info_t* main_Jpeg,
2283        cam_compose_jpeg_info_t* aux_Jpeg)
2284{
2285    LOGH("E Main Jpeg %p Aux Jpeg %p", main_Jpeg, aux_Jpeg);
2286
2287    CHECK_MUXER();
2288    if(main_Jpeg == NULL || aux_Jpeg == NULL) {
2289        LOGE("input buffers invalid, ret = NO_MEMORY");
2290        gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2291        return;
2292    }
2293
2294    pthread_mutex_lock(&m_JpegLock);
2295
2296    m_pRelCamMpoJpeg = mGetMemoryCb(-1, main_Jpeg->buffer->size +
2297            aux_Jpeg->buffer->size, 1, m_pMpoCallbackCookie);
2298    if (NULL == m_pRelCamMpoJpeg) {
2299        LOGE("getMemory for mpo, ret = NO_MEMORY");
2300        gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2301        pthread_mutex_unlock(&m_JpegLock);
2302        return;
2303    }
2304
2305    // fill all structures to send for composition
2306    mm_jpeg_mpo_info_t mpo_compose_info;
2307    mpo_compose_info.num_of_images = 2;
2308    mpo_compose_info.primary_image.buf_filled_len = main_Jpeg->buffer->size;
2309    mpo_compose_info.primary_image.buf_vaddr =
2310            (uint8_t*)(main_Jpeg->buffer->data);
2311    mpo_compose_info.aux_images[0].buf_filled_len = aux_Jpeg->buffer->size;
2312    mpo_compose_info.aux_images[0].buf_vaddr =
2313            (uint8_t*)(aux_Jpeg->buffer->data);
2314    mpo_compose_info.output_buff.buf_vaddr =
2315            (uint8_t*)m_pRelCamMpoJpeg->data;
2316    mpo_compose_info.output_buff.buf_filled_len = 0;
2317    mpo_compose_info.output_buff_size = main_Jpeg->buffer->size +
2318            aux_Jpeg->buffer->size;
2319
2320    LOGD("MPO buffer size %d\n"
2321            "expected size %d, mpo_compose_info.output_buff_size %d",
2322             m_pRelCamMpoJpeg->size,
2323            main_Jpeg->buffer->size + aux_Jpeg->buffer->size,
2324            mpo_compose_info.output_buff_size);
2325
2326    LOGD("MPO primary buffer filled lengths\n"
2327            "mpo_compose_info.primary_image.buf_filled_len %d\n"
2328            "mpo_compose_info.primary_image.buf_vaddr %p",
2329            mpo_compose_info.primary_image.buf_filled_len,
2330            mpo_compose_info.primary_image.buf_vaddr);
2331
2332    LOGD("MPO aux buffer filled lengths\n"
2333            "mpo_compose_info.aux_images[0].buf_filled_len %d"
2334            "mpo_compose_info.aux_images[0].buf_vaddr %p",
2335            mpo_compose_info.aux_images[0].buf_filled_len,
2336            mpo_compose_info.aux_images[0].buf_vaddr);
2337
2338    if(m_bDumpImages) {
2339        LOGD("Dumping Main Image for MPO");
2340        char buf_main[QCAMERA_MAX_FILEPATH_LENGTH];
2341        memset(buf_main, 0, sizeof(buf_main));
2342        snprintf(buf_main, sizeof(buf_main),
2343                QCAMERA_DUMP_FRM_LOCATION "Main.jpg");
2344
2345        int file_fd_main = open(buf_main, O_RDWR | O_CREAT, 0777);
2346        if (file_fd_main >= 0) {
2347            ssize_t written_len = write(file_fd_main,
2348                    mpo_compose_info.primary_image.buf_vaddr,
2349                    mpo_compose_info.primary_image.buf_filled_len);
2350            fchmod(file_fd_main, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2351            LOGD("written number of bytes for main Image %zd\n",
2352                     written_len);
2353            close(file_fd_main);
2354        }
2355
2356        LOGD("Dumping Aux Image for MPO");
2357        char buf_aux[QCAMERA_MAX_FILEPATH_LENGTH];
2358        memset(buf_aux, 0, sizeof(buf_aux));
2359        snprintf(buf_aux, sizeof(buf_aux),
2360                QCAMERA_DUMP_FRM_LOCATION "Aux.jpg");
2361
2362        int file_fd_aux = open(buf_aux, O_RDWR | O_CREAT, 0777);
2363        if (file_fd_aux >= 0) {
2364            ssize_t written_len = write(file_fd_aux,
2365                    mpo_compose_info.aux_images[0].buf_vaddr,
2366                    mpo_compose_info.aux_images[0].buf_filled_len);
2367            fchmod(file_fd_aux, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2368            LOGD("written number of bytes for Aux Image %zd\n",
2369                     written_len);
2370            close(file_fd_aux);
2371        }
2372    }
2373
2374    int32_t rc = mJpegMpoOps.compose_mpo(&mpo_compose_info);
2375    LOGD("Compose mpo returned %d", rc);
2376
2377    if(rc != NO_ERROR) {
2378        LOGE("ComposeMpo failed, ret = %d", rc);
2379        gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2380        pthread_mutex_unlock(&m_JpegLock);
2381        return;
2382    }
2383
2384    if(m_bDumpImages) {
2385        char buf_mpo[QCAMERA_MAX_FILEPATH_LENGTH];
2386        memset(buf_mpo, 0, sizeof(buf_mpo));
2387        snprintf(buf_mpo, sizeof(buf_mpo),
2388                QCAMERA_DUMP_FRM_LOCATION "Composed.MPO");
2389
2390        int file_fd_mpo = open(buf_mpo, O_RDWR | O_CREAT, 0777);
2391        if (file_fd_mpo >= 0) {
2392            ssize_t written_len = write(file_fd_mpo,
2393                    m_pRelCamMpoJpeg->data,
2394                    m_pRelCamMpoJpeg->size);
2395            fchmod(file_fd_mpo, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
2396            LOGD("written number of bytes for MPO Image %zd\n",
2397                     written_len);
2398            close(file_fd_mpo);
2399        }
2400    }
2401
2402    mDataCb(main_Jpeg->msg_type,
2403            m_pRelCamMpoJpeg,
2404            main_Jpeg->index,
2405            main_Jpeg->metadata,
2406            m_pMpoCallbackCookie);
2407
2408    if (NULL != m_pRelCamMpoJpeg) {
2409        m_pRelCamMpoJpeg->release(m_pRelCamMpoJpeg);
2410        m_pRelCamMpoJpeg = NULL;
2411    }
2412
2413    pthread_mutex_unlock(&m_JpegLock);
2414    LOGH("X");
2415    return;
2416}
2417
2418/*===========================================================================
2419 * FUNCTION   : matchFrameId
2420 *
2421 * DESCRIPTION: function to match frame ids within queue nodes
2422 *
2423 * PARAMETERS :
2424 *   @data: pointer to queue node to be matched for condition
2425 *   @user_data: caller can add more info here
2426 *   @match_data : value to be matched against
2427 *
2428 * RETURN     : true or false based on whether match was successful or not
2429 *==========================================================================*/
2430bool QCameraMuxer::matchFrameId(void *data, __unused void *user_data,
2431        void *match_data)
2432{
2433    LOGH("E");
2434
2435    if (!data || !match_data) {
2436        return false;
2437    }
2438
2439    cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data;
2440    uint32_t frame_idx = *((uint32_t *) match_data);
2441    LOGH("X");
2442    return node->frame_idx == frame_idx;
2443}
2444
2445/*===========================================================================
2446 * FUNCTION   : findPreviousJpegs
2447 *
2448 * DESCRIPTION: Finds Jpegs in the queue with index less than delivered one
2449 *
2450 * PARAMETERS :
2451 *   @data: pointer to queue node to be matched for condition
2452 *   @user_data: caller can add more info here
2453 *   @match_data : value to be matched against
2454 *
2455 * RETURN     : true or false based on whether match was successful or not
2456 *==========================================================================*/
2457bool QCameraMuxer::findPreviousJpegs(void *data, __unused void *user_data,
2458        void *match_data)
2459{
2460    LOGH("E");
2461
2462    if (!data || !match_data) {
2463        return false;
2464    }
2465    cam_compose_jpeg_info_t * node = (cam_compose_jpeg_info_t *) data;
2466    uint32_t frame_idx = *((uint32_t *) match_data);
2467    LOGH("X");
2468    return node->frame_idx < frame_idx;
2469}
2470
2471/*===========================================================================
2472 * FUNCTION   : releaseJpegInfo
2473 *
2474 * DESCRIPTION: callback function for the release of individual nodes
2475 *                     in the JPEG queues.
2476 *
2477 * PARAMETERS :
2478 *   @data      : ptr to the data to be released
2479 *   @user_data : caller can add more info here
2480 *
2481 * RETURN     : None
2482 *==========================================================================*/
2483void QCameraMuxer::releaseJpegInfo(void *data, __unused void *user_data)
2484{
2485    LOGH("E");
2486
2487    cam_compose_jpeg_info_t *jpegInfo = (cam_compose_jpeg_info_t *)data;
2488    if(jpegInfo && jpegInfo->release_cb) {
2489        if (jpegInfo->release_data != NULL) {
2490            jpegInfo->release_cb(jpegInfo->release_data,
2491                    jpegInfo->release_cookie,
2492                    NO_ERROR);
2493        }
2494    }
2495    LOGH("X");
2496}
2497
2498/*===========================================================================
2499 * FUNCTION   : composeMpoRoutine
2500 *
2501 * DESCRIPTION: specialized thread for MPO composition
2502 *
2503 * PARAMETERS :
2504 *   @data   : pointer to the thread owner
2505 *
2506 * RETURN     : void* to thread
2507 *==========================================================================*/
2508void* QCameraMuxer::composeMpoRoutine(__unused void *data)
2509{
2510    LOGH("E");
2511    if (!gMuxer) {
2512        LOGE("Error getting muxer ");
2513        return NULL;
2514    }
2515
2516    int running = 1;
2517    int ret;
2518    uint8_t is_active = FALSE;
2519    QCameraCmdThread *cmdThread = &gMuxer->m_ComposeMpoTh;
2520    cmdThread->setName("CAM_ComposeMpo");
2521
2522    do {
2523        do {
2524            ret = cam_sem_wait(&cmdThread->cmd_sem);
2525            if (ret != 0 && errno != EINVAL) {
2526                LOGE("cam_sem_wait error (%s)", strerror(errno));
2527                return NULL;
2528            }
2529        } while (ret != 0);
2530
2531        // we got notified about new cmd avail in cmd queue
2532        camera_cmd_type_t cmd = cmdThread->getCmd();
2533        switch (cmd) {
2534        case CAMERA_CMD_TYPE_START_DATA_PROC:
2535            {
2536                LOGH("start ComposeMpo processing");
2537                is_active = TRUE;
2538
2539                // signal cmd is completed
2540                cam_sem_post(&cmdThread->sync_sem);
2541            }
2542            break;
2543        case CAMERA_CMD_TYPE_STOP_DATA_PROC:
2544            {
2545                LOGH("stop ComposeMpo processing");
2546                is_active = FALSE;
2547
2548                // signal cmd is completed
2549                cam_sem_post(&cmdThread->sync_sem);
2550            }
2551            break;
2552        case CAMERA_CMD_TYPE_DO_NEXT_JOB:
2553            {
2554                if (is_active == TRUE) {
2555                    LOGH("Mpo Composition Requested");
2556                    cam_compose_jpeg_info_t *main_jpeg_node = NULL;
2557                    cam_compose_jpeg_info_t *aux_jpeg_node = NULL;
2558                    bool foundMatch = false;
2559                    while (!gMuxer->m_MainJpegQ.isEmpty() &&
2560                            !gMuxer->m_AuxJpegQ.isEmpty()) {
2561                        main_jpeg_node = (cam_compose_jpeg_info_t *)
2562                                gMuxer->m_MainJpegQ.dequeue();
2563                        if (main_jpeg_node != NULL) {
2564                            LOGD("main_jpeg_node found frame idx %d"
2565                                    "ptr %p buffer_ptr %p buffer_size %d",
2566                                     main_jpeg_node->frame_idx,
2567                                    main_jpeg_node,
2568                                    main_jpeg_node->buffer->data,
2569                                    main_jpeg_node->buffer->size);
2570                            // find matching aux node in Aux Jpeg Queue
2571                            aux_jpeg_node =
2572                                    (cam_compose_jpeg_info_t *) gMuxer->
2573                                    m_AuxJpegQ.dequeue();
2574                            if (aux_jpeg_node != NULL) {
2575                                LOGD("aux_jpeg_node found frame idx %d"
2576                                        "ptr %p buffer_ptr %p buffer_size %d",
2577                                         aux_jpeg_node->frame_idx,
2578                                        aux_jpeg_node,
2579                                        aux_jpeg_node->buffer->data,
2580                                        aux_jpeg_node->buffer->size);
2581                                foundMatch = true;
2582                                // start MPO composition
2583                                gMuxer->composeMpo(main_jpeg_node,
2584                                        aux_jpeg_node);
2585                            }
2586                        }
2587                        if (main_jpeg_node != NULL) {
2588                            if ( main_jpeg_node->release_cb ) {
2589                                main_jpeg_node->release_cb(
2590                                        main_jpeg_node->release_data,
2591                                        main_jpeg_node->release_cookie,
2592                                        NO_ERROR);
2593                            }
2594                            free(main_jpeg_node);
2595                            main_jpeg_node = NULL;
2596                        } else {
2597                            LOGH("Mpo Match not found");
2598                        }
2599                        if (aux_jpeg_node != NULL) {
2600                            if (aux_jpeg_node->release_cb) {
2601                                aux_jpeg_node->release_cb(
2602                                        aux_jpeg_node->release_data,
2603                                        aux_jpeg_node->release_cookie,
2604                                        NO_ERROR);
2605                            }
2606                            free(aux_jpeg_node);
2607                            aux_jpeg_node = NULL;
2608                        } else {
2609                            LOGH("Mpo Match not found");
2610                        }
2611                    }
2612                }
2613            break;
2614            }
2615        case CAMERA_CMD_TYPE_EXIT:
2616            LOGH("ComposeMpo thread exit");
2617            running = 0;
2618            break;
2619        default:
2620            break;
2621        }
2622    } while (running);
2623    LOGH("X");
2624    return NULL;
2625}
2626
2627/*===========================================================================
2628 * FUNCTION   : jpeg_data_callback
2629 *
2630 * DESCRIPTION: JPEG data callback for snapshot
2631 *
2632 * PARAMETERS :
2633 *   @msg_type : callback msg type
2634 *   @data : data ptr of the buffer
2635 *   @index : index of the frame
2636 *   @metadata : metadata associated with the buffer
2637 *   @user : callback cookie returned back to the user
2638 *   @frame_idx : frame index for matching frames
2639 *   @release_cb : callback function for releasing the data memory
2640 *   @release_cookie : cookie for the release callback function
2641 *   @release_data :pointer indicating what needs to be released
2642 *
2643 * RETURN : none
2644 *==========================================================================*/
2645void QCameraMuxer::jpeg_data_callback(int32_t msg_type,
2646           const camera_memory_t *data, unsigned int index,
2647           camera_frame_metadata_t *metadata, void *user,
2648           uint32_t frame_idx, camera_release_callback release_cb,
2649           void *release_cookie, void *release_data)
2650{
2651    LOGH("E");
2652    CHECK_MUXER();
2653
2654    if(data != NULL) {
2655        LOGH("jpeg received: data %p size %d data ptr %p frameIdx %d",
2656                 data, data->size, data->data, frame_idx);
2657        int rc = gMuxer->storeJpeg(((qcamera_physical_descriptor_t*)(user))->type,
2658                msg_type, data, index, metadata, user, frame_idx, release_cb,
2659                release_cookie, release_data);
2660        if(rc != NO_ERROR) {
2661            gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2662        }
2663    } else {
2664        gMuxer->sendEvtNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
2665    }
2666    LOGH("X");
2667    return;
2668}
2669
2670/*===========================================================================
2671 * FUNCTION   : storeJpeg
2672 *
2673 * DESCRIPTION: Stores jpegs from multiple related cam instances into a common Queue
2674 *
2675 * PARAMETERS :
2676 *   @cam_type : indicates whether main or aux camera sent the Jpeg callback
2677 *   @msg_type : callback msg type
2678 *   @data : data ptr of the buffer
2679 *   @index : index of the frame
2680 *   @metadata : metadata associated with the buffer
2681 *   @user : callback cookie returned back to the user
2682 *   @frame_idx : frame index for matching frames
2683 *   @release_cb : callback function for releasing the data memory
2684 *   @release_cookie : cookie for the release callback function
2685 *   @release_data :pointer indicating what needs to be released
2686 *
2687 * RETURN     : int32_t type of status
2688 *              NO_ERROR  -- success
2689 *              none-zero failure code
2690 *==========================================================================*/
2691int32_t QCameraMuxer::storeJpeg(cam_sync_type_t cam_type,
2692        int32_t msg_type, const camera_memory_t *data, unsigned int index,
2693        camera_frame_metadata_t *metadata, void *user,uint32_t frame_idx,
2694        camera_release_callback release_cb, void *release_cookie,
2695        void *release_data)
2696{
2697    LOGH("E jpeg received: data %p size %d data ptr %p frameIdx %d",
2698             data, data->size, data->data, frame_idx);
2699
2700    CHECK_MUXER_ERROR();
2701
2702    if (!m_bMpoEnabled) {
2703        if (cam_type == CAM_TYPE_MAIN) {
2704            // send data callback only incase of main camera
2705            // aux image is ignored and released back
2706            mDataCb(msg_type,
2707                    data,
2708                    index,
2709                    metadata,
2710                    m_pMpoCallbackCookie);
2711        }
2712        if (release_cb) {
2713            release_cb(release_data, release_cookie, NO_ERROR);
2714        }
2715        LOGH("X");
2716        return NO_ERROR;
2717    }
2718
2719    cam_compose_jpeg_info_t* pJpegFrame =
2720            (cam_compose_jpeg_info_t*)malloc(sizeof(cam_compose_jpeg_info_t));
2721    if (!pJpegFrame) {
2722        LOGE("Allocation failed for MPO nodes");
2723        return NO_MEMORY;
2724    }
2725    memset(pJpegFrame, 0, sizeof(*pJpegFrame));
2726
2727    pJpegFrame->msg_type = msg_type;
2728    pJpegFrame->buffer = const_cast<camera_memory_t*>(data);
2729    pJpegFrame->index = index;
2730    pJpegFrame->metadata = metadata;
2731    pJpegFrame->user = user;
2732    pJpegFrame->valid = true;
2733    pJpegFrame->frame_idx = frame_idx;
2734    pJpegFrame->release_cb = release_cb;
2735    pJpegFrame->release_cookie = release_cookie;
2736    pJpegFrame->release_data = release_data;
2737    if(cam_type == CAM_TYPE_MAIN) {
2738        if (m_MainJpegQ.enqueue((void *)pJpegFrame)) {
2739            LOGD("Main FrameIdx %d", pJpegFrame->frame_idx);
2740            if (m_MainJpegQ.getCurrentSize() > 0) {
2741                LOGD("Trigger Compose");
2742                m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
2743            }
2744        } else {
2745            LOGE("Enqueue Failed for Main Jpeg Q");
2746            if ( pJpegFrame->release_cb ) {
2747                // release other buffer also here
2748                pJpegFrame->release_cb(
2749                        pJpegFrame->release_data,
2750                        pJpegFrame->release_cookie,
2751                        NO_ERROR);
2752            }
2753            free(pJpegFrame);
2754            pJpegFrame = NULL;
2755            return NO_MEMORY;
2756        }
2757
2758    } else {
2759        if (m_AuxJpegQ.enqueue((void *)pJpegFrame)) {
2760            LOGD("Aux FrameIdx %d", pJpegFrame->frame_idx);
2761            if (m_AuxJpegQ.getCurrentSize() > 0) {
2762                LOGD("Trigger Compose");
2763                m_ComposeMpoTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
2764            }
2765        } else {
2766            LOGE("Enqueue Failed for Aux Jpeg Q");
2767            if ( pJpegFrame->release_cb ) {
2768                // release other buffer also here
2769                pJpegFrame->release_cb(
2770                        pJpegFrame->release_data,
2771                        pJpegFrame->release_cookie,
2772                        NO_ERROR);
2773            }
2774            free(pJpegFrame);
2775            pJpegFrame = NULL;
2776            return NO_MEMORY;
2777        }
2778    }
2779    LOGH("X");
2780
2781    return NO_ERROR;
2782}
2783
2784
2785// Muxer Ops
2786camera_device_ops_t QCameraMuxer::mCameraMuxerOps = {
2787    .set_preview_window =        QCameraMuxer::set_preview_window,
2788    .set_callbacks =             QCameraMuxer::set_callBacks,
2789    .enable_msg_type =           QCameraMuxer::enable_msg_type,
2790    .disable_msg_type =          QCameraMuxer::disable_msg_type,
2791    .msg_type_enabled =          QCameraMuxer::msg_type_enabled,
2792
2793    .start_preview =             QCameraMuxer::start_preview,
2794    .stop_preview =              QCameraMuxer::stop_preview,
2795    .preview_enabled =           QCameraMuxer::preview_enabled,
2796    .store_meta_data_in_buffers= QCameraMuxer::store_meta_data_in_buffers,
2797
2798    .start_recording =           QCameraMuxer::start_recording,
2799    .stop_recording =            QCameraMuxer::stop_recording,
2800    .recording_enabled =         QCameraMuxer::recording_enabled,
2801    .release_recording_frame =   QCameraMuxer::release_recording_frame,
2802
2803    .auto_focus =                QCameraMuxer::auto_focus,
2804    .cancel_auto_focus =         QCameraMuxer::cancel_auto_focus,
2805
2806    .take_picture =              QCameraMuxer::take_picture,
2807    .cancel_picture =            QCameraMuxer::cancel_picture,
2808
2809    .set_parameters =            QCameraMuxer::set_parameters,
2810    .get_parameters =            QCameraMuxer::get_parameters,
2811    .put_parameters =            QCameraMuxer::put_parameters,
2812    .send_command =              QCameraMuxer::send_command,
2813
2814    .release =                   QCameraMuxer::release,
2815    .dump =                      QCameraMuxer::dump,
2816};
2817
2818
2819}; // namespace android
2820