Home | History | Annotate | Download | only in HAL
      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 
     44 extern "C" {
     45 #include "mm_camera_dbg.h"
     46 }
     47 
     48 /* Muxer implementation */
     49 using namespace android;
     50 namespace qcamera {
     51 
     52 QCameraMuxer *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  *==========================================================================*/
    103 void 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  *==========================================================================*/
    125 QCameraMuxer::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  *==========================================================================*/
    167 QCameraMuxer::~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  *==========================================================================*/
    199 int 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  *==========================================================================*/
    218 int 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  *==========================================================================*/
    247 int 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  *==========================================================================*/
    268 int 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  *==========================================================================*/
    300 int 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  *==========================================================================*/
    328 int 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  *==========================================================================*/
    371 void 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  *==========================================================================*/
    441 void 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  *==========================================================================*/
    470 void 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  *==========================================================================*/
    499 int 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  *==========================================================================*/
    534 int 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  *==========================================================================*/
    630 void 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  *==========================================================================*/
    664 int 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  *==========================================================================*/
    700 int 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  *==========================================================================*/
    738 int 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  *==========================================================================*/
    857 void 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  *==========================================================================*/
    944 int 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  *==========================================================================*/
    978 void 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  *==========================================================================*/
   1014 int 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  *==========================================================================*/
   1055 int 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  *==========================================================================*/
   1096 int 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  *==========================================================================*/
   1298 int 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  *==========================================================================*/
   1342 int 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  *==========================================================================*/
   1433 char* 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  *==========================================================================*/
   1481 void 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  *==========================================================================*/
   1519 int 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  *==========================================================================*/
   1589 void 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  *==========================================================================*/
   1622 int 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  *==========================================================================*/
   1660 int 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  *==========================================================================*/
   1748 int 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  *==========================================================================*/
   1889 int 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  *==========================================================================*/
   1907 int 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  *==========================================================================*/
   1946 int32_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  *==========================================================================*/
   1968 int32_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  *==========================================================================*/
   1990 int32_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  *==========================================================================*/
   2013 int32_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  *==========================================================================*/
   2033 void* 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  *==========================================================================*/
   2051 int32_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  *==========================================================================*/
   2071 void* 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  *==========================================================================*/
   2089 int 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  *==========================================================================*/
   2185 qcamera_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  *==========================================================================*/
   2205 qcamera_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  *==========================================================================*/
   2228 int32_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  *==========================================================================*/
   2252 int32_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  *==========================================================================*/
   2282 void 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  *==========================================================================*/
   2430 bool 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  *==========================================================================*/
   2457 bool 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  *==========================================================================*/
   2483 void 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  *==========================================================================*/
   2508 void* 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  *==========================================================================*/
   2645 void 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  *==========================================================================*/
   2691 int32_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
   2786 camera_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