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