merge in nyc-mr1-release history after reset to nyc-mr1-dev
diff --git a/msmcobalt/QCamera2/Android.mk b/msmcobalt/QCamera2/Android.mk
index 6278c36..1bb6e8f 100644
--- a/msmcobalt/QCamera2/Android.mk
+++ b/msmcobalt/QCamera2/Android.mk
@@ -64,6 +64,9 @@
 LOCAL_CFLAGS += -DUSE_HAL_3_3
 endif
 
+#Enable to simulate B+B snapshot use case. Will be removed later
+#LOCAL_CFLAGS += -DDUAL_CAM_TEST
+
 #use media extension
 ifeq ($(TARGET_USES_MEDIA_EXTENSIONS), true)
 LOCAL_CFLAGS += -DUSE_MEDIA_EXTENSIONS
diff --git a/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp b/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp
index c0f7736..f0eaf5e 100644
--- a/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp
+++ b/msmcobalt/QCamera2/HAL/QCamera2HWI.cpp
@@ -62,6 +62,8 @@
 #define CAMERA_MIN_CAMERA_BATCH_BUFFERS  6
 #define CAMERA_ISP_PING_PONG_BUFFERS     2
 #define MIN_UNDEQUEUED_BUFFERS           1 // This is required if preview window is not set
+#define CAMERA_MIN_DISPLAY_BUFFERS       2
+#define CAMERA_DEFAULT_FPS               30000
 
 #define HDR_CONFIDENCE_THRESHOLD 0.4
 
@@ -1605,6 +1607,7 @@
     : mCameraId(cameraId),
       mCameraHandle(NULL),
       mCameraOpened(false),
+      mDualCamera(false),
       m_bRelCamCalibValid(false),
       mPreviewWindow(NULL),
       mMsgEnabled(0),
@@ -1681,6 +1684,8 @@
     mCameraDevice.ops = &mCameraOps;
     mCameraDevice.priv = this;
 
+    mDualCamera = is_dual_camera_by_idx(cameraId);
+
     pthread_mutex_init(&m_lock, NULL);
     pthread_cond_init(&m_cond, NULL);
 
@@ -1728,6 +1733,7 @@
          }
          dlclose(lib_surface_utils);
     }
+    prev_zoomLevel = 0;
 }
 
 /*===========================================================================
@@ -1926,6 +1932,11 @@
                 (void *) this);
     }
 
+    mActiveCamera = MM_CAMERA_TYPE_MAIN;
+    if (isDualCamera()) {
+        mActiveCamera |= MM_CAMERA_TYPE_AUX;
+    }
+
     // Init params in the background
     // 1. It's safe to queue init job, even if alloc job is not yet complete.
     // It will be queued to the same thread, so the alloc is guaranteed to
@@ -2299,27 +2310,39 @@
 
 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
 
+
 /*===========================================================================
- * FUNCTION   : initCapabilities
+ * FUNCTION   : getCapabilities
  *
- * DESCRIPTION: initialize camera capabilities in static data struct
+ * DESCRIPTION: query camera capability from back-end
  *
  * PARAMETERS :
- *   @cameraId  : camera Id
+ *   @ops        : mm-interface ops structure
+ *   @cam_handle  : camera handle for which we need capability
  *
- * RETURN     : int32_t type of status
- *              NO_ERROR  -- success
- *              none-zero failure code
+ * RETURN     : ptr type of capability structure
+ *              capability for success
+ *              NULL for failure
  *==========================================================================*/
-int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
-        mm_camera_vtbl_t *cameraHandle)
+cam_capability_t *QCamera2HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
+        uint32_t cam_handle)
 {
-    ATRACE_CALL();
     int rc = NO_ERROR;
     QCameraHeapMemory *capabilityHeap = NULL;
+    cam_capability_t *cap_ptr = NULL;
+
+    if (ops == NULL) {
+        LOGE("Invalid arguments");
+        return NULL;
+    }
+
+    capabilityHeap = new QCameraHeapMemory(1);
+    if (capabilityHeap == NULL) {
+        LOGE("creation of capabilityHeap failed");
+        return NULL;
+    }
 
     /* Allocate memory for capability buffer */
-    capabilityHeap = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
     rc = capabilityHeap->allocate(1, sizeof(cam_capability_t), NON_SECURE);
     if(rc != OK) {
         LOGE("No memory for cappability");
@@ -2337,48 +2360,103 @@
             bufMapList, capabilityHeap->getPtr(0));
 
     if (rc == NO_ERROR) {
-        rc = cameraHandle->ops->map_bufs(cameraHandle->camera_handle,
+        rc = ops->map_bufs(cam_handle,
                 &bufMapList);
     }
-
     if(rc < 0) {
         LOGE("failed to map capability buffer");
         goto map_failed;
     }
 
     /* Query Capability */
-    rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
+    rc = ops->query_capability(cam_handle);
     if(rc < 0) {
         LOGE("failed to query capability");
+        rc = FAILED_TRANSACTION;
         goto query_failed;
     }
-    gCamCapability[cameraId] =
-            (cam_capability_t *)malloc(sizeof(cam_capability_t));
 
-    if (!gCamCapability[cameraId]) {
+    cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
+    if (cap_ptr == NULL) {
         LOGE("out of memory");
+        rc = NO_MEMORY;
         goto query_failed;
     }
-    memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
-                                        sizeof(cam_capability_t));
+
+    memset(cap_ptr, 0, sizeof(cam_capability_t));
+    memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
 
     int index;
     for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
-        cam_analysis_info_t *p_analysis_info =
-                &gCamCapability[cameraId]->analysis_info[index];
+        cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
         p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
         p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
     }
 
-    rc = NO_ERROR;
-
 query_failed:
-    cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
-                            CAM_MAPPING_BUF_TYPE_CAPABILITY);
+    ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
 map_failed:
     capabilityHeap->deallocate();
-    delete capabilityHeap;
 allocate_failed:
+    delete capabilityHeap;
+
+    if (rc != NO_ERROR) {
+        return NULL;
+    } else {
+        return cap_ptr;
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : initCapabilities
+ *
+ * DESCRIPTION: initialize camera capabilities in static data struct
+ *
+ * PARAMETERS :
+ *   @cameraId  : camera Id
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int QCamera2HardwareInterface::initCapabilities(uint32_t cameraId,
+        mm_camera_vtbl_t *cameraHandle)
+{
+    ATRACE_CALL();
+    int rc = 0;
+    uint32_t handle = 0;
+
+    rc = camera_open((uint8_t)cameraId, &cameraHandle);
+    if (rc) {
+        LOGE("camera_open failed. rc = %d", rc);
+        goto open_failed;
+    }
+    if (!cameraHandle) {
+        LOGE("camera_open failed. cameraHandle = %p", cameraHandle);
+        goto open_failed;
+    }
+
+    handle = get_main_camera_handle(cameraHandle->camera_handle);
+    gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
+    if (gCamCapability[cameraId] == NULL) {
+        rc = FAILED_TRANSACTION;
+        goto failed_op;
+    }
+
+    if (is_dual_camera_by_idx(cameraId)) {
+        handle = get_aux_camera_handle(cameraHandle->camera_handle);
+        gCamCapability[cameraId]->aux_cam_cap =
+                getCapabilities(cameraHandle->ops, handle);
+        if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
+            rc = FAILED_TRANSACTION;
+            free(gCamCapability[cameraId]);
+            goto failed_op;
+        }
+    }
+failed_op:
+    cameraHandle->ops->close_camera(cameraHandle->camera_handle);
+    cameraHandle = NULL;
+open_failed:
     return rc;
 }
 
@@ -2427,6 +2505,47 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : getBufNumForAux
+ *
+ * DESCRIPTION: return number of stream buffers needed for aux camera given stream type
+ *
+ * PARAMETERS :
+ *   @stream_type  : type of stream
+ *
+ * RETURN     : number of buffers needed
+ * NOTE     :  Based on the use cases and auxillary camera type,
+                    we can decide buffer count
+ *==========================================================================*/
+uint8_t QCamera2HardwareInterface::getBufNumForAux(cam_stream_type_t stream_type)
+{
+    if (!isDualCamera()) {
+        return 0;
+    }
+
+    uint8_t bufferCnt = 1;
+    switch (stream_type) {
+    case CAM_STREAM_TYPE_PREVIEW:
+    case CAM_STREAM_TYPE_VIDEO:
+    case CAM_STREAM_TYPE_SNAPSHOT:
+    case CAM_STREAM_TYPE_METADATA:
+    case CAM_STREAM_TYPE_CALLBACK:
+    case CAM_STREAM_TYPE_ANALYSIS:
+    case CAM_STREAM_TYPE_POSTVIEW:
+    case CAM_STREAM_TYPE_RAW:
+    case CAM_STREAM_TYPE_OFFLINE_PROC:
+    case CAM_STREAM_TYPE_DEFAULT:
+    case CAM_STREAM_TYPE_MAX:
+        //For wide & tele, we use same buffer count premary and aux streams.
+        bufferCnt = getBufNumRequired(stream_type);
+        break;
+    default:
+        break;
+    }
+    LOGH("Buffer Cnt for Aux Camera : %d", bufferCnt);
+    return bufferCnt;
+}
+
+/*===========================================================================
  * FUNCTION   : getBufNumRequired
  *
  * DESCRIPTION: return number of stream buffers needed for given stream type
@@ -2443,6 +2562,7 @@
     char value[PROPERTY_VALUE_MAX];
     bool raw_yuv = false;
     int persist_cnt = 0;
+    int minPrevFps, maxPrevFps;
 
     int zslQBuffers = mParameters.getZSLQueueDepth();
 
@@ -2514,6 +2634,11 @@
                     && (!mParameters.isHfrMode())) {
                 bufferCnt += EXTRA_ZSL_PREVIEW_STREAM_BUF;
             }
+            //Adding Extra preview buffers for 60FPS usecase.
+            mParameters.getPreviewFpsRange(&minPrevFps, &maxPrevFps);
+            if (maxPrevFps > CAMERA_DEFAULT_FPS) {
+                bufferCnt += CAMERA_MIN_DISPLAY_BUFFERS;
+            }
 
             // Add the display minUndequeCount count on top of camera requirement
             bufferCnt += minUndequeCount;
@@ -2696,6 +2821,86 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : getStreamRefCount
+ *
+ * DESCRIPTION: return number of instance of stream of stream type
+ *
+ * PARAMETERS :
+ *   @stream_type  : type of stream
+ *
+ * RETURN     : number of stream instances
+ * NOTE      :  Based on the use cases and auxillary camera type,
+                     we can decide stream reference count.
+                     For example in wide and tele use case, we duplicate all stream
+                     streams from premary to auxillary.
+ *==========================================================================*/
+uint8_t QCamera2HardwareInterface::getStreamRefCount(cam_stream_type_t stream_type)
+{
+    uint8_t ref_cnt = 1;
+    switch (stream_type) {
+    case CAM_STREAM_TYPE_PREVIEW:
+    case CAM_STREAM_TYPE_SNAPSHOT:
+    case CAM_STREAM_TYPE_VIDEO:
+    case CAM_STREAM_TYPE_METADATA:
+    case CAM_STREAM_TYPE_ANALYSIS:
+    case CAM_STREAM_TYPE_CALLBACK:
+        if (isDualCamera()) {
+            ref_cnt++;
+        }
+        break;
+    case CAM_STREAM_TYPE_POSTVIEW:
+    case CAM_STREAM_TYPE_RAW:
+    case CAM_STREAM_TYPE_OFFLINE_PROC:
+    case CAM_STREAM_TYPE_DEFAULT:
+    case CAM_STREAM_TYPE_MAX:
+    default:
+        break;
+    }
+    return ref_cnt;
+}
+
+/*===========================================================================
+ * FUNCTION   : getCamHandleForChannel
+ *
+ * DESCRIPTION: return actual camera handle based on use case
+ *
+ * PARAMETERS :
+ *   @ch_type  : type of channel
+ *
+ * RETURN     : uint32_t type camera handle
+ * NOTE :  Based on the use cases and auxillary camera type, we can decide cam handle for channel.
+                 Incase, we want to avoid any channel for auxillary camera, we can decide here
+ *==========================================================================*/
+uint32_t QCamera2HardwareInterface::getCamHandleForChannel(qcamera_ch_type_enum_t ch_type)
+{
+    uint32_t handle = 0;
+    if (!isDualCamera()) {
+        return mCameraHandle->camera_handle;
+    }
+
+    /*Based on the use case, decide camera handle for channel*/
+    switch (ch_type) {
+    case QCAMERA_CH_TYPE_ZSL:
+    case QCAMERA_CH_TYPE_CAPTURE:
+    case QCAMERA_CH_TYPE_PREVIEW:
+    case QCAMERA_CH_TYPE_VIDEO:
+    case QCAMERA_CH_TYPE_SNAPSHOT:
+    case QCAMERA_CH_TYPE_RAW:
+    case QCAMERA_CH_TYPE_METADATA:
+    case QCAMERA_CH_TYPE_ANALYSIS:
+    case QCAMERA_CH_TYPE_CALLBACK:
+    case QCAMERA_CH_TYPE_MAX:
+    default:
+        handle = mCameraHandle->camera_handle;
+        break;
+    case QCAMERA_CH_TYPE_REPROCESSING:
+        handle = get_main_camera_handle(mCameraHandle->camera_handle);
+        break;
+    }
+    return handle;
+}
+
+/*===========================================================================
  * FUNCTION   : allocateStreamBuf
  *
  * DESCRIPTION: alocate stream buffers
@@ -2992,9 +3197,9 @@
 }
 
 /*===========================================================================
- * FUNCTION   : allocateStreamInfoBuf
+ * FUNCTION   : initStreamInfoBuf
  *
- * DESCRIPTION: alocate stream info buffer
+ * DESCRIPTION: initialize stream info buffer based on stream type
  *
  * PARAMETERS :
  *   @stream_type  : type of stream
@@ -3002,36 +3207,20 @@
  * RETURN     : ptr to a memory obj that holds stream info buffer.
  *              NULL if failed
  *==========================================================================*/
-QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
-        cam_stream_type_t stream_type)
+int QCamera2HardwareInterface::initStreamInfoBuf(cam_stream_type_t stream_type,
+            cam_stream_info_t *streamInfo)
 {
     int rc = NO_ERROR;
-    char value[PROPERTY_VALUE_MAX];
-    bool raw_yuv = false;
     int32_t dt = 0;
     int32_t vc = 0;
 
-
-    QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
-    if (!streamInfoBuf) {
-        LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
-        return NULL;
-    }
-
-    rc = streamInfoBuf->allocate(1, sizeof(cam_stream_info_t), NON_SECURE);
-    if (rc < 0) {
-        LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
-        delete streamInfoBuf;
-        return NULL;
-    }
-
-    cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
     memset(streamInfo, 0, sizeof(cam_stream_info_t));
     streamInfo->stream_type = stream_type;
     rc = mParameters.getStreamFormat(stream_type, streamInfo->fmt);
     rc = mParameters.getStreamDimension(stream_type, streamInfo->dim);
     rc = mParameters.getStreamRotation(stream_type, streamInfo->pp_config, streamInfo->dim);
     streamInfo->num_bufs = getBufNumRequired(stream_type);
+    streamInfo->buf_cnt = streamInfo->num_bufs;
     streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
     streamInfo->is_secure = NON_SECURE;
 
@@ -3049,19 +3238,22 @@
                         + mParameters.getNumOfExtraBuffersForImageProc());
         }
         break;
-    case CAM_STREAM_TYPE_RAW:
-        property_get("persist.camera.raw_yuv", value, "0");
-        raw_yuv = atoi(value) > 0 ? true : false;
-        if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
-            streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
-        } else {
-            streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
-            streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
-        }
-        if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
-            streamInfo->is_secure = SECURE;
-        } else {
-            streamInfo->is_secure = NON_SECURE;
+    case CAM_STREAM_TYPE_RAW: {
+            char value[PROPERTY_VALUE_MAX];
+            bool raw_yuv = false;
+            property_get("persist.camera.raw_yuv", value, "0");
+            raw_yuv = atoi(value) > 0 ? true : false;
+            if ((mParameters.isZSLMode()) || (isRdiMode()) || (raw_yuv)) {
+                streamInfo->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
+            } else {
+                streamInfo->streaming_mode = CAM_STREAMING_MODE_BURST;
+                streamInfo->num_of_burst = mParameters.getNumOfSnapshots();
+            }
+            if (mParameters.isSecureMode() && mParameters.isRdiMode()) {
+                streamInfo->is_secure = SECURE;
+            } else {
+                streamInfo->is_secure = NON_SECURE;
+            }
         }
         if (CAM_FORMAT_META_RAW_10BIT == streamInfo->fmt) {
             mParameters.updateDtVc(&dt, &vc);
@@ -3163,6 +3355,7 @@
                 CAM_QCOM_FEATURE_SCALE)
             streamInfo->pp_config.feature_mask |= CAM_QCOM_FEATURE_SCALE;
     }
+    streamInfo->aux_str_info = NULL;
 
     LOGH("type %d, fmt %d, dim %dx%d, num_bufs %d mask = 0x%x is_type %d\n",
            stream_type, streamInfo->fmt, streamInfo->dim.width,
@@ -3170,6 +3363,66 @@
            streamInfo->pp_config.feature_mask,
            streamInfo->is_type);
 
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : allocateStreamInfoBuf
+ *
+ * DESCRIPTION: alocate stream info buffer
+ *
+ * PARAMETERS :
+ *   @stream_type  : type of stream
+ *   @bufCount       : stream info buffer count
+ *
+ * RETURN     : ptr to a memory obj that holds stream info buffer.
+ *              NULL if failed
+ *==========================================================================*/
+QCameraHeapMemory *QCamera2HardwareInterface::allocateStreamInfoBuf(
+        cam_stream_type_t stream_type, uint8_t bufCount)
+{
+    int rc = NO_ERROR;
+
+    QCameraHeapMemory *streamInfoBuf = new QCameraHeapMemory(QCAMERA_ION_USE_CACHE);
+    if (!streamInfoBuf) {
+        LOGE("allocateStreamInfoBuf: Unable to allocate streamInfo object");
+        return NULL;
+    }
+
+    if (bufCount > MM_CAMERA_MAX_CAM_CNT) {
+        LOGE("buffer count should be lesser than max camera : %d", bufCount);
+        return NULL;
+    }
+    rc = streamInfoBuf->allocate(bufCount, sizeof(cam_stream_info_t), NON_SECURE);
+    if (rc < 0) {
+        LOGE("allocateStreamInfoBuf: Failed to allocate stream info memory");
+        delete streamInfoBuf;
+        return NULL;
+    }
+
+    for (uint8_t i = 0; i < bufCount; i++) {
+        cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(i);
+        memset(streamInfo, 0, sizeof(cam_stream_info_t));
+        rc = initStreamInfoBuf(stream_type, streamInfo);
+        if (rc < 0) {
+            LOGE("initStreamInfoBuf failed");
+            delete streamInfoBuf;
+            return NULL;
+        }
+    }
+
+    cam_stream_info_t *streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(0);
+    if (bufCount == MM_CAMERA_MAX_CAM_CNT) {
+        cam_stream_info_t *s_streamInfo = (cam_stream_info_t *)streamInfoBuf->getPtr(1);
+        streamInfo->aux_str_info = s_streamInfo;
+    }
+
+    if (streamInfo->aux_str_info != NULL) {
+        /*Update StreamInfo for Aux camera*/
+        streamInfo->aux_str_info->buf_cnt = getBufNumForAux(stream_type);
+        streamInfo->num_bufs += streamInfo->aux_str_info->buf_cnt;
+        streamInfo->aux_str_info->num_bufs += streamInfo->aux_str_info->buf_cnt;
+    }
     return streamInfoBuf;
 }
 
@@ -4503,6 +4756,12 @@
         return rc;
     }
 
+#ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed
+    if(mActiveCamera == (MM_CAMERA_TYPE_MAIN | MM_CAMERA_TYPE_AUX)) {
+        numSnapshots = 1;
+    }
+#endif
+
     if (mAdvancedCaptureConfigured) {
         numSnapshots = mParameters.getBurstCountForAdvancedCapture();
     }
@@ -6636,6 +6895,160 @@
     return m_postprocessor.processJpegEvt(jpeg_evt);
 }
 
+
+/*===========================================================================
+ * FUNCTION   : processDCFOVControl
+ *
+ * DESCRIPTION: Fill Dual camera FOV control
+ *
+ * PARAMETERS : none
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCamera2HardwareInterface::processDCFOVControl()
+{
+    int32_t zoomLevel;
+    uint32_t camState = mActiveCamera;
+
+    if (!isDualCamera()) {
+        return NO_ERROR;
+    }
+
+    /*FOV control block needs to integrated here to decide dual camera
+    switch operation.
+    We can access application parameter, metadata buffer,
+    parameter buffer used for back-end here*/
+    zoomLevel = mParameters.getParmZoomLevel();
+    if (zoomLevel < 20) {
+        //WIDE Zone
+        LOGH("WIDE ZONE : %d and  %d", zoomLevel, prev_zoomLevel);
+        if (camState & MM_CAMERA_TYPE_AUX) {
+            //Suspend Aux
+            camState &= (~MM_CAMERA_TYPE_AUX);
+        }
+        if (!(camState & MM_CAMERA_TYPE_MAIN)) {
+            //Activate Main
+            camState |= MM_CAMERA_TYPE_MAIN;
+        }
+    } else if (zoomLevel > 60) {
+        //TELE Zone
+        LOGH("TELE ZONE : %d and  %d", zoomLevel, prev_zoomLevel);
+        if (!(camState & MM_CAMERA_TYPE_AUX)) {
+            //Activate Aux
+            camState |= MM_CAMERA_TYPE_AUX;
+        }
+        if (camState & MM_CAMERA_TYPE_MAIN) {
+            //Suspend Main
+            camState &= (~MM_CAMERA_TYPE_MAIN);
+        }
+    } else {
+        //Dual Zone
+        LOGH("DUAL ZONE : %d and  %d", zoomLevel, prev_zoomLevel);
+        if (!(camState & MM_CAMERA_TYPE_AUX)) {
+            //Activate Aux
+            camState |= MM_CAMERA_TYPE_AUX;
+        }
+        if (!(camState & MM_CAMERA_TYPE_MAIN)) {
+            //Activate Main
+            camState |= MM_CAMERA_TYPE_MAIN;
+        }
+    }
+
+    if (camState != 0 && camState != mActiveCamera) {
+        processCameraControl(camState);
+    }
+
+    if (zoomLevel >= 40 && prev_zoomLevel < 40) {
+        //Switch camera
+        switchCameraCb();
+        prev_zoomLevel = zoomLevel;
+    } else if (prev_zoomLevel >= 40 && zoomLevel  < 40){
+       switchCameraCb();
+       prev_zoomLevel = zoomLevel;
+    }
+    return 0;
+}
+
+/*===========================================================================
+ * FUNCTION   : processCameraControl
+ *
+ * DESCRIPTION: Suspend and resume camera
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCamera2HardwareInterface::processCameraControl(uint32_t camState)
+{
+    int32_t ret = NO_ERROR;
+
+    //Set camera controls to parameter and back-end
+    ret = mParameters.setCameraControls(camState, TRUE);
+
+    //Update camera status to internal channel
+    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
+        if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
+            ret = m_channels[i]->processCameraControl(camState);
+            if (ret != NO_ERROR) {
+                LOGE("Channel Switch Failed");
+                break;
+            }
+        }
+    }
+    if (ret == NO_ERROR) {
+        if (camState == MM_CAMERA_TYPE_MAIN) {
+            m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
+        } else if (camState == MM_CAMERA_TYPE_AUX) {
+            m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
+        }
+    }
+    LOGH("mActiveCamera = %d to %d", mActiveCamera, camState);
+    mActiveCamera = camState;
+    return ret;
+}
+
+/*===========================================================================
+ * FUNCTION   : switchCameraCb
+ *
+ * DESCRIPTION: switch camera's in case of dual camera
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCamera2HardwareInterface::switchCameraCb()
+{
+    int32_t ret = NO_ERROR;
+
+    for (int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
+        if (m_channels[i] != NULL && m_channels[i]->isDualChannel()) {
+            ret = m_channels[i]->switchChannelCb();
+            if (ret != NO_ERROR) {
+                LOGE("Channel Switch Failed");
+                break;
+            }
+        }
+    }
+    if (ret == NO_ERROR && mActiveCamera == MM_CAMERA_DUAL_CAM) {
+        if (get_aux_camera_handle(mCameraHandle->camera_handle)
+                == m_ActiveHandle) {
+            m_ActiveHandle = get_main_camera_handle(mCameraHandle->camera_handle);
+        } else if (get_main_camera_handle(mCameraHandle->camera_handle)
+                == m_ActiveHandle) {
+            m_ActiveHandle = get_aux_camera_handle(mCameraHandle->camera_handle);
+        } else {
+            m_ActiveHandle = mCameraHandle->camera_handle;
+        }
+    }
+    return ret;
+}
+
 /*===========================================================================
  * FUNCTION   : lockAPI
  *
@@ -6808,6 +7221,7 @@
     rc = mParameters.updateRAW(max_dim);
     return rc;
 }
+
 /*===========================================================================
  * FUNCTION   : addStreamToChannel
  *
@@ -6829,16 +7243,18 @@
                                                       void *userData)
 {
     int32_t rc = NO_ERROR;
+    QCameraHeapMemory *pStreamInfo = NULL;
 
     if (streamType == CAM_STREAM_TYPE_RAW) {
         prepareRawStream(pChannel);
     }
-    QCameraHeapMemory *pStreamInfo = allocateStreamInfoBuf(streamType);
+
+    pStreamInfo = allocateStreamInfoBuf(streamType, getStreamRefCount(streamType));
     if (pStreamInfo == NULL) {
         LOGE("no mem for stream info buf");
         return NO_MEMORY;
     }
-    uint8_t minStreamBufNum = getBufNumRequired(streamType);
+
     bool bDynAllocBuf = false;
     if (isZSLMode() && streamType == CAM_STREAM_TYPE_SNAPSHOT) {
         bDynAllocBuf = true;
@@ -6885,7 +7301,6 @@
     rc = pChannel->addStream(*this,
             pStreamInfo,
             NULL,
-            minStreamBufNum,
             &padding_info,
             streamCB, userData,
             bDynAllocBuf,
@@ -6925,8 +7340,8 @@
         m_channels[QCAMERA_CH_TYPE_PREVIEW] = NULL;
     }
 
-    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
-                                  mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_PREVIEW);
+    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for preview channel");
         return NO_MEMORY;
@@ -6941,7 +7356,7 @@
 
     // meta data stream always coexists with preview if applicable
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
-                            metadata_stream_cb_routine, this);
+            metadata_stream_cb_routine, this);
     if (rc != NO_ERROR) {
         LOGE("add metadata stream failed, ret = %d", rc);
         return rc;
@@ -6949,11 +7364,11 @@
 
     if (isRdiMode()) {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_RAW,
-                                rdi_mode_stream_cb_routine, this);
+                rdi_mode_stream_cb_routine, this);
     } else {
         if (isNoDisplayMode()) {
             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
-                                    nodisplay_preview_stream_cb_routine, this);
+                    nodisplay_preview_stream_cb_routine, this);
         } else {
             rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                                     preview_stream_cb_routine, this);
@@ -6961,8 +7376,10 @@
             int whiteLevel, cleanLevel;
             if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
 #endif
-            pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
-                    synchronous_stream_cb_routine);
+            if (!isDualCamera()) {
+                pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
+                        synchronous_stream_cb_routine);
+            }
         }
     }
 
@@ -7022,8 +7439,8 @@
         m_channels[QCAMERA_CH_TYPE_VIDEO] = NULL;
     }
 
-    pChannel = new QCameraVideoChannel(mCameraHandle->camera_handle,
-                                       mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_VIDEO);
+    pChannel = new QCameraVideoChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for video channel");
         return NO_MEMORY;
@@ -7050,7 +7467,8 @@
     }
 
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_VIDEO,
-                            video_stream_cb_routine, this);
+            video_stream_cb_routine, this);
+
     if (rc != NO_ERROR) {
         LOGE("add video stream failed, ret = %d", rc);
         delete pChannel;
@@ -7085,8 +7503,8 @@
         m_channels[QCAMERA_CH_TYPE_SNAPSHOT] = NULL;
     }
 
-    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
-                                  mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_SNAPSHOT);
+    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for snapshot channel");
         return NO_MEMORY;
@@ -7141,8 +7559,8 @@
         m_channels[QCAMERA_CH_TYPE_RAW] = NULL;
     }
 
-    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
-                                  mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_RAW);
+    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for raw channel");
         return NO_MEMORY;
@@ -7223,7 +7641,8 @@
         m_channels[QCAMERA_CH_TYPE_ZSL] = NULL;
     }
 
-    pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ZSL);
+    pChannel = new QCameraPicChannel(handle,
                                      mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for ZSL channel");
@@ -7265,7 +7684,7 @@
 
     // meta data stream always coexists with preview if applicable
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
-                            metadata_stream_cb_routine, this);
+            metadata_stream_cb_routine, this);
     if (rc != NO_ERROR) {
         LOGE("add metadata stream failed, ret = %d", rc);
         delete pChannel;
@@ -7274,7 +7693,7 @@
 
     if (isNoDisplayMode()) {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
-                                nodisplay_preview_stream_cb_routine, this);
+                nodisplay_preview_stream_cb_routine, this);
     } else {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
                                 preview_stream_cb_routine, this);
@@ -7282,8 +7701,10 @@
         int whiteLevel, cleanLevel;
         if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
 #endif
-        pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
-                synchronous_stream_cb_routine);
+        if (!isDualCamera()) {
+            pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
+                    synchronous_stream_cb_routine);
+        }
     }
     if (rc != NO_ERROR) {
         LOGE("add preview stream failed, ret = %d", rc);
@@ -7292,7 +7713,7 @@
     }
 
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_SNAPSHOT,
-                            NULL, this);
+            NULL, this);
     if (rc != NO_ERROR) {
         LOGE("add snapshot stream failed, ret = %d", rc);
         delete pChannel;
@@ -7353,8 +7774,8 @@
         m_channels[QCAMERA_CH_TYPE_CAPTURE] = NULL;
     }
 
-    pChannel = new QCameraPicChannel(mCameraHandle->camera_handle,
-                                  mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CAPTURE);
+    pChannel = new QCameraPicChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for capture channel");
         return NO_MEMORY;
@@ -7382,7 +7803,7 @@
 
     // meta data stream always coexists with snapshot in regular capture case
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
-                            metadata_stream_cb_routine, this);
+            metadata_stream_cb_routine, this);
     if (rc != NO_ERROR) {
         LOGE("add metadata stream failed, ret = %d", rc);
         return rc;
@@ -7390,8 +7811,7 @@
 
     if (mLongshotEnabled) {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_PREVIEW,
-                                preview_stream_cb_routine, this);
-
+                preview_stream_cb_routine, this);
         if (rc != NO_ERROR) {
             LOGE("add preview stream failed, ret = %d", rc);
             return rc;
@@ -7400,13 +7820,14 @@
         int whiteLevel, cleanLevel;
         if(mParameters.getTsMakeupInfo(whiteLevel, cleanLevel) == false)
 #endif
-        pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
-                synchronous_stream_cb_routine);
+        if (!isDualCamera()) {
+            pChannel->setStreamSyncCB(CAM_STREAM_TYPE_PREVIEW,
+                    synchronous_stream_cb_routine);
+        }
     //Not adding the postview stream to the capture channel if Quadra CFA is enabled.
     } else if (!mParameters.getQuadraCfa()) {
         rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_POSTVIEW,
                                 NULL, this);
-
         if (rc != NO_ERROR) {
             LOGE("add postview stream failed, ret = %d", rc);
             return rc;
@@ -7464,8 +7885,8 @@
         m_channels[QCAMERA_CH_TYPE_METADATA] = NULL;
     }
 
-    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
-                                  mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_METADATA);
+    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for metadata channel");
         return NO_MEMORY;
@@ -7481,7 +7902,7 @@
     }
 
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_METADATA,
-                            metadata_stream_cb_routine, this);
+            metadata_stream_cb_routine, this);
     if (rc != NO_ERROR) {
         LOGE("add metadata stream failed, ret = %d", rc);
         delete pChannel;
@@ -7513,8 +7934,8 @@
         m_channels[QCAMERA_CH_TYPE_CALLBACK] = NULL;
     }
 
-    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
-            mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_CALLBACK);
+    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for callback channel");
         return NO_MEMORY;
@@ -7562,8 +7983,8 @@
         m_channels[QCAMERA_CH_TYPE_ANALYSIS] = NULL;
     }
 
-    pChannel = new QCameraChannel(mCameraHandle->camera_handle,
-                                  mCameraHandle->ops);
+    uint32_t handle = getCamHandleForChannel(QCAMERA_CH_TYPE_ANALYSIS);
+    pChannel = new QCameraChannel(handle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for metadata channel");
         return NO_MEMORY;
@@ -7577,7 +7998,7 @@
     }
 
     rc = addStreamToChannel(pChannel, CAM_STREAM_TYPE_ANALYSIS,
-                            NULL, this);
+            NULL, this);
     if (rc != NO_ERROR) {
         LOGE("add Analysis stream failed, ret = %d", rc);
         delete pChannel;
@@ -7845,14 +8266,14 @@
     int32_t rc = NO_ERROR;
     QCameraReprocessChannel *pChannel = NULL;
     uint32_t burst_cnt = mParameters.getNumOfSnapshots();
+    uint32_t pHandle = getCamHandleForChannel(QCAMERA_CH_TYPE_REPROCESSING);
 
     if (pInputChannel == NULL) {
         LOGE("input channel obj is NULL");
         return NULL;
     }
 
-    pChannel = new QCameraReprocessChannel(mCameraHandle->camera_handle,
-                                           mCameraHandle->ops);
+    pChannel = new QCameraReprocessChannel(pHandle, mCameraHandle->ops);
     if (NULL == pChannel) {
         LOGE("no mem for reprocess channel");
         return NULL;
@@ -7918,6 +8339,11 @@
         pChannel->setReprocCount(1);
     }
 
+#ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed
+    if (isDualCamera()) {
+        minStreamBufNum += 1;
+    }
+#endif
     // Add non inplace image lib buffers only when ppproc is present,
     // becuase pproc is non inplace and input buffers for img lib
     // are output for pproc and this number of extra buffers is required
@@ -7934,10 +8360,10 @@
     mParameters.getStreamPpMask(CAM_STREAM_TYPE_SNAPSHOT, snapshot_feature_mask);
 
     pp_config.feature_mask &= ~snapshot_feature_mask;
-    LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx",
-            snapshot_feature_mask, pp_config.feature_mask);
+    LOGH("Snapshot feature mask: 0x%llx, reproc feature mask: 0x%llx minStreamBufNum = %d",
+            snapshot_feature_mask, pp_config.feature_mask, minStreamBufNum);
 
-    bool offlineReproc = isRegularCapture();
+    bool offlineReproc = needOfflineReprocessing();
     if (m_postprocessor.mOfflineDataBufs != NULL) {
         offlineReproc = TRUE;
     }
@@ -8018,9 +8444,10 @@
     streamInfoBuf->reprocess_config.pp_type = CAM_OFFLINE_REPROCESS_TYPE;
     streamInfoBuf->reprocess_config.offline = img_config;
     streamInfoBuf->reprocess_config.pp_feature_config = pp_feature;
+    streamInfoBuf->num_bufs = img_config.num_of_bufs;
 
     rc = pChannel->addStream(*this,
-            pStreamInfo, NULL, img_config.num_of_bufs,
+            pStreamInfo, NULL,
             &gCamCapability[mCameraId]->padding_info,
             stream_cb, userdata, false);
 
@@ -8326,7 +8753,7 @@
 {
     for(int i = 0; i < QCAMERA_CH_TYPE_MAX; i++) {
         if (m_channels[i] != NULL &&
-            m_channels[i]->getMyHandle() == channelHandle) {
+            (validate_handle(m_channels[i]->getMyHandle(), channelHandle))) {
             return m_channels[i];
         }
     }
@@ -9865,7 +10292,12 @@
                     break;
                 case CMD_DEF_PARAM_ALLOC:
                     {
-                        int32_t rc = pme->mParameters.allocate();
+                        int32_t rc = NO_ERROR;
+                        if (pme->isDualCamera()) {
+                            rc = pme->mParameters.allocate(MM_CAMERA_MAX_CAM_CNT);
+                        } else {
+                            rc = pme->mParameters.allocate();
+                        }
                         // notify routine would not be initialized by this time.
                         // So, just update error job status
                         if (rc != NO_ERROR) {
@@ -10373,6 +10805,26 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : needOfflineReprocessing
+ *
+ * DESCRIPTION: Check for offline reprocessing
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : true - regular capture
+ *              false - other type of capture
+ *==========================================================================*/
+bool QCamera2HardwareInterface::needOfflineReprocessing()
+{
+    bool ret = false;
+    if (isRegularCapture()
+            || isDualCamera()) {
+        ret = true;
+    }
+    return ret;
+}
+
+/*===========================================================================
  * FUNCTION   : getLogLevel
  *
  * DESCRIPTION: Reads the log level property into a variable
@@ -10530,4 +10982,32 @@
     return measured;
 }
 
+/*===========================================================================
+ * FUNCTION   : fillDualCameraFOVControl
+ *
+ * DESCRIPTION: Function to process FOV ctrl event from statemachine thread.
+ *
+ * PARAMETERS : none
+ *
+ * RETURN     : none
+ *==========================================================================*/
+void QCamera2HardwareInterface::fillDualCameraFOVControl()
+{
+    qcamera_sm_internal_evt_payload_t *payload =
+       (qcamera_sm_internal_evt_payload_t *)
+       malloc(sizeof(qcamera_sm_internal_evt_payload_t));
+    if (NULL != payload) {
+        memset(payload, 0, sizeof(qcamera_sm_internal_evt_payload_t));
+        payload->evt_type = QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL;
+        int32_t rc = processEvt(QCAMERA_SM_EVT_EVT_INTERNAL, payload);
+        if (rc != NO_ERROR) {
+            LOGE("processEvt Dual camera fill FOV control failed");
+            free(payload);
+            payload = NULL;
+        }
+    } else {
+        LOGE("No memory for Dual camera fill FOV control event");
+    }
+}
+
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCamera2HWI.h b/msmcobalt/QCamera2/HAL/QCamera2HWI.h
index 7e4556d..c5d0985 100644
--- a/msmcobalt/QCamera2/HAL/QCamera2HWI.h
+++ b/msmcobalt/QCamera2/HAL/QCamera2HWI.h
@@ -81,6 +81,7 @@
     QCAMERA_CH_TYPE_METADATA,
     QCAMERA_CH_TYPE_ANALYSIS,
     QCAMERA_CH_TYPE_CALLBACK,
+    QCAMERA_CH_TYPE_REPROCESSING,
     QCAMERA_CH_TYPE_MAX
 } qcamera_ch_type_enum_t;
 
@@ -92,10 +93,10 @@
 
 #define QCAMERA_DUMP_FRM_PREVIEW             1
 #define QCAMERA_DUMP_FRM_VIDEO               (1<<1)
-#define QCAMERA_DUMP_FRM_SNAPSHOT            (1<<2)
+#define QCAMERA_DUMP_FRM_INPUT_JPEG          (1<<2)
 #define QCAMERA_DUMP_FRM_THUMBNAIL           (1<<3)
 #define QCAMERA_DUMP_FRM_RAW                 (1<<4)
-#define QCAMERA_DUMP_FRM_JPEG                (1<<5)
+#define QCAMERA_DUMP_FRM_OUTPUT_JPEG         (1<<5)
 #define QCAMERA_DUMP_FRM_INPUT_REPROCESS     (1<<6)
 
 #define QCAMERA_DUMP_FRM_MASK_ALL    0x000000ff
@@ -267,6 +268,8 @@
     static int getCapabilities(uint32_t cameraId,
             struct camera_info *info, cam_sync_type_t *cam_type);
     static int initCapabilities(uint32_t cameraId, mm_camera_vtbl_t *cameraHandle);
+    static cam_capability_t *getCapabilities(mm_camera_ops_t *ops,
+            uint32_t cam_handle);
     cam_capability_t *getCamHalCapabilities();
 
     // Implementation of QCameraAllocator
@@ -274,8 +277,8 @@
             size_t size, int stride, int scanline, uint8_t &bufferCnt);
     virtual int32_t allocateMoreStreamBuf(QCameraMemory *mem_obj,
             size_t size, uint8_t &bufferCnt);
-
-    virtual QCameraHeapMemory *allocateStreamInfoBuf(cam_stream_type_t stream_type);
+    virtual QCameraHeapMemory *allocateStreamInfoBuf(
+            cam_stream_type_t stream_type, uint8_t bufCount = 1);
     virtual QCameraHeapMemory *allocateMiscBuf(cam_stream_info_t *streamInfo);
     virtual QCameraMemory *allocateStreamUserBuf(cam_stream_info_t *streamInfo);
     virtual void waitForDeferredAlloc(cam_stream_type_t stream_type);
@@ -293,6 +296,8 @@
     friend class QCameraCbNotifier;
     friend class QCameraMuxer;
 
+    int32_t initStreamInfoBuf(cam_stream_type_t stream_type,
+            cam_stream_info_t *streamInfo);
     void setJpegCallBacks(jpeg_data_callback jpegCb,
             void *callbackCookie);
     int32_t initJpegHandle();
@@ -369,6 +374,7 @@
     bool isCaptureShutterEnabled();
     bool needDebugFps();
     bool isRegularCapture();
+    bool needOfflineReprocessing();
     bool isCACEnabled();
     bool is4k2kResolution(cam_dimension_t* resolution);
     bool isPreviewRestartEnabled();
@@ -402,6 +408,7 @@
     int32_t transAwbMetaToParams(cam_awb_params_t &awb_params);
     int32_t processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info);
     int32_t processAEInfo(cam_3a_params_t &ae_params);
+    int32_t processDCFOVControl();
 
     int32_t sendEvtNotify(int32_t msg_type, int32_t ext1, int32_t ext2);
     int32_t sendDataNotify(int32_t msg_type,
@@ -466,6 +473,7 @@
     bool isRetroPicture() {return bRetroPicture; };
     bool isHDRMode() {return mParameters.isHDREnabled();};
     uint8_t getBufNumRequired(cam_stream_type_t stream_type);
+    uint8_t getBufNumForAux(cam_stream_type_t stream_type);
     bool needFDMetadata(qcamera_ch_type_enum_t channel_type);
     int32_t configureOnlineRotation(QCameraChannel &ch);
     int32_t declareSnapshotStreams();
@@ -569,12 +577,20 @@
     void setDisplayFrameSkip(uint32_t start = 0, uint32_t end = 0);
     /*Verifies if frameId is valid to skip*/
     bool isDisplayFrameToSkip(uint32_t frameId);
-
+    bool isDualCamera() { return mDualCamera; };
+    void fillDualCameraFOVControl();
+    uint8_t getStreamRefCount(cam_stream_type_t stream_type);
+    uint32_t getCamHandleForChannel(qcamera_ch_type_enum_t ch_type);
+    int32_t switchCameraCb();
+    int32_t processCameraControl(uint32_t camState);
 private:
     camera_device_t   mCameraDevice;
     uint32_t          mCameraId;
     mm_camera_vtbl_t *mCameraHandle;
+    uint32_t m_ActiveHandle;
+    uint32_t mActiveCamera;
     bool mCameraOpened;
+    bool mDualCamera;
 
     cam_jpeg_metadata_t mJpegMetadata;
     bool m_bRelCamCalibValid;
@@ -793,6 +809,7 @@
     //The offset between BOOTTIME and MONOTONIC timestamps
     nsecs_t mBootToMonoTimestampOffset;
     bool bDepthAFCallbacks;
+    int32_t prev_zoomLevel;
 };
 
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp b/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp
index 537d537..a117b1a 100644
--- a/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp
+++ b/msmcobalt/QCamera2/HAL/QCamera2HWICallbacks.cpp
@@ -72,16 +72,19 @@
     bool dump_raw = false;
     bool log_matching = false;
     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
+
     if (pme == NULL ||
-        pme->mCameraHandle == NULL ||
-        pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
+        pme->mCameraHandle == 0 ||
+        !validate_handle(pme->mCameraHandle->camera_handle,
+        recvd_frame->camera_handle)) {
        LOGE("camera obj not valid");
        return;
     }
 
     QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_ZSL];
     if (pChannel == NULL ||
-        pChannel->getMyHandle() != recvd_frame->ch_id) {
+            !validate_handle(pChannel->getMyHandle(),
+            recvd_frame->ch_id)) {
         LOGE("ZSL channel doesn't exist, return here");
         return;
     }
@@ -180,7 +183,7 @@
             break;
         }
     }
-    //
+
     // whether need FD Metadata along with Snapshot frame in ZSL mode
     if(pme->needFDMetadata(QCAMERA_CH_TYPE_ZSL)){
         //Need Face Detection result for snapshot frames
@@ -390,7 +393,8 @@
 
     QCameraChannel *pChannel = pme->m_channels[QCAMERA_CH_TYPE_CAPTURE];
     if (pChannel == NULL ||
-        pChannel->getMyHandle() != recvd_frame->ch_id) {
+            !validate_handle(pChannel->getMyHandle(),
+            recvd_frame->ch_id)) {
         LOGE("Capture channel doesn't exist, return here");
         return;
     }
@@ -638,9 +642,11 @@
     ATRACE_CALL();
     LOGH("[KPI Perf]: E");
     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
+
     if (pme == NULL ||
-        pme->mCameraHandle == NULL ||
-        pme->mCameraHandle->camera_handle != recvd_frame->camera_handle){
+            pme->mCameraHandle == 0 ||
+            !validate_handle(pme->mCameraHandle->camera_handle,
+            recvd_frame->camera_handle)) {
         LOGE("camera obj not valid");
         return;
     }
@@ -1403,9 +1409,9 @@
     LOGD("[KPI Perf] : BEGIN");
     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
     if (pme == NULL ||
-        pme->mCameraHandle == NULL ||
-        pme->mCameraHandle->camera_handle != super_frame->camera_handle){
-        LOGE("camera obj not valid");
+            pme->mCameraHandle == 0 ||
+            !validate_handle(pme->mCameraHandle->camera_handle,
+            super_frame->camera_handle)) {
         // simply free super frame
         free(super_frame);
         return;
@@ -1568,9 +1574,13 @@
             cbArg.msg_type = CAMERA_MSG_VIDEO_FRAME;
             cbArg.data = video_mem;
 
-            // Convert Boottime from camera to Monotime for video if needed.
-            // Otherwise, mBootToMonoTimestampOffset value will be 0.
-            timeStamp = timeStamp - pme->mBootToMonoTimestampOffset;
+            // For VT usecase, ISP uses AVtimer not CLOCK_BOOTTIME as time source.
+            // So do not change video timestamp.
+            if (!pme->mParameters.isAVTimerEnabled()) {
+                // Convert Boottime from camera to Monotime for video if needed.
+                // Otherwise, mBootToMonoTimestampOffset value will be 0.
+                timeStamp = timeStamp - pme->mBootToMonoTimestampOffset;
+            }
             LOGD("Final video buffer TimeStamp : %lld ", timeStamp);
             cbArg.timestamp = timeStamp;
             int32_t rc = pme->m_cbNotifier.notifyCallback(cbArg);
@@ -1624,7 +1634,9 @@
         pChannel = pme->m_channels[QCAMERA_CH_TYPE_SNAPSHOT];
     }
 
-    if ((pChannel == NULL) || (pChannel->getMyHandle() != super_frame->ch_id)) {
+    if ((pChannel == NULL)
+            || (!validate_handle(pChannel->getMyHandle(),
+            super_frame->ch_id))) {
         LOGE("Snapshot channel doesn't exist, return here");
         return;
     }
@@ -1632,11 +1644,6 @@
     property_get("persist.camera.dumpmetadata", value, "0");
     int32_t enabled = atoi(value);
     if (enabled) {
-        if (pChannel == NULL ||
-            pChannel->getMyHandle() != super_frame->ch_id) {
-            LOGE("Capture channel doesn't exist, return here");
-            return;
-        }
         mm_camera_buf_def_t *pMetaFrame = NULL;
         QCameraStream *pStream = NULL;
         for (uint32_t i = 0; i < super_frame->num_bufs; i++) {
@@ -1759,7 +1766,7 @@
         return;
     }
 
-    if (pChannel->getMyHandle() != super_frame->ch_id) {
+    if (!validate_handle(pChannel->getMyHandle(), super_frame->ch_id)) {
         LOGE("Invalid Input super buffer");
         pChannel->bufDone(super_frame);
         return;
@@ -2037,10 +2044,11 @@
     ATRACE_CALL();
     LOGD("[KPI Perf] : BEGIN");
     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
+
     if (pme == NULL ||
-        pme->mCameraHandle == NULL ||
-        pme->mCameraHandle->camera_handle != super_frame->camera_handle){
-        LOGE("camera obj not valid");
+            pme->mCameraHandle == 0 ||
+            !validate_handle(pme->mCameraHandle->camera_handle,
+            super_frame->camera_handle)) {
         // simply free super frame
         free(super_frame);
         return;
@@ -2456,7 +2464,11 @@
       LOGD("touch_ae_status: %d", *touch_ae_status);
     }
 
-    stream->bufDone(frame->buf_idx);
+    if (pme->isDualCamera()) {
+        pme->fillDualCameraFOVControl();
+    }
+
+    stream->bufDone(super_frame);
     free(super_frame);
 
     LOGD("[KPI Perf] : END");
@@ -2523,9 +2535,9 @@
     QCamera2HardwareInterface *pme = (QCamera2HardwareInterface *)userdata;
 
     if (pme == NULL ||
-            pme->mCameraHandle == NULL ||
-            pme->mCameraHandle->camera_handle != super_frame->camera_handle) {
-        LOGE("camera obj not valid");
+            pme->mCameraHandle == 0 ||
+            !validate_handle(pme->mCameraHandle->camera_handle,
+            super_frame->camera_handle)) {
         // simply free super frame
         free(super_frame);
         return;
@@ -2586,7 +2598,7 @@
     memset(buf, 0, sizeof(buf));
     memset(&dim, 0, sizeof(dim));
 
-    if(((enabled & QCAMERA_DUMP_FRM_JPEG) && data) ||
+    if(((enabled & QCAMERA_DUMP_FRM_OUTPUT_JPEG) && data) ||
         ((true == m_bIntJpegEvtPending) && data)) {
         frm_num = ((enabled & 0xffff0000) >> 16);
         if(frm_num == 0) {
@@ -2812,7 +2824,7 @@
                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
                         }
                         break;
-                    case QCAMERA_DUMP_FRM_SNAPSHOT:
+                    case QCAMERA_DUMP_FRM_INPUT_JPEG:
                         {
                             if (!mParameters.isPostProcScaling()) {
                                 mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
@@ -2853,7 +2865,7 @@
                                     dumpFrmCnt, dim.width, dim.height, frame->frame_idx);
                         }
                         break;
-                    case QCAMERA_DUMP_FRM_JPEG:
+                    case QCAMERA_DUMP_FRM_OUTPUT_JPEG:
                         {
                             mParameters.getStreamDimension(CAM_STREAM_TYPE_SNAPSHOT, dim);
                             snprintf(buf, sizeof(buf), "%dj_%dx%d_%d.yuv",
diff --git a/msmcobalt/QCamera2/HAL/QCameraAllocator.h b/msmcobalt/QCamera2/HAL/QCameraAllocator.h
index ca15a6a..c3cec49 100644
--- a/msmcobalt/QCamera2/HAL/QCameraAllocator.h
+++ b/msmcobalt/QCamera2/HAL/QCameraAllocator.h
@@ -50,7 +50,8 @@
             size_t size, int stride, int scanline, uint8_t &bufferCnt) = 0;
     virtual int32_t allocateMoreStreamBuf(QCameraMemory *mem_obj,
             size_t size, uint8_t &bufferCnt) = 0;
-    virtual QCameraHeapMemory *allocateStreamInfoBuf(cam_stream_type_t stream_type) = 0;
+    virtual QCameraHeapMemory *allocateStreamInfoBuf(
+            cam_stream_type_t stream_type, uint8_t bufCount = 1) = 0;
     virtual QCameraHeapMemory *allocateMiscBuf(cam_stream_info_t *streamInfo) = 0;
     virtual QCameraMemory *allocateStreamUserBuf(cam_stream_info_t *streamInfo) = 0;
     virtual void waitForDeferredAlloc(cam_stream_type_t stream_type) = 0;
diff --git a/msmcobalt/QCamera2/HAL/QCameraChannel.cpp b/msmcobalt/QCamera2/HAL/QCameraChannel.cpp
index 233474c..1ca121b 100644
--- a/msmcobalt/QCamera2/HAL/QCameraChannel.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraChannel.cpp
@@ -61,8 +61,9 @@
     m_camOps = cam_ops;
     m_bIsActive = false;
     m_bAllowDynBufAlloc = false;
-
+    mDualChannel = is_dual_camera_by_handle(cam_handle);
     m_handle = 0;
+    mActiveHandle = 0;
 }
 
 /*===========================================================================
@@ -79,8 +80,9 @@
     m_camHandle = 0;
     m_camOps = NULL;
     m_bIsActive = false;
-
+    mDualChannel = 0;
     m_handle = 0;
+    mActiveHandle = 0;
 }
 
 /*===========================================================================
@@ -99,14 +101,15 @@
     }
     for (size_t i = 0; i < mStreams.size(); i++) {
         if (mStreams[i] != NULL) {
-                if (m_handle == mStreams[i]->getChannelHandle()) {
-                    delete mStreams[i];
-                }
+            if (validate_handle(m_handle, mStreams[i]->getChannelHandle())) {
+                delete mStreams[i];
+            }
         }
     }
     mStreams.clear();
     m_camOps->delete_channel(m_camHandle, m_handle);
     m_handle = 0;
+    mActiveHandle = 0;
 }
 
 /*===========================================================================
@@ -124,7 +127,8 @@
         stop();
     }
     for (size_t i = 0; i < mStreams.size(); i++) {
-        if ((mStreams[i] != NULL) && (m_handle == mStreams[i]->getChannelHandle())) {
+        if ((mStreams[i] != NULL) &&
+                (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
             mStreams[i]->deleteStream();
         }
     }
@@ -183,10 +187,58 @@
         LOGE("Add channel failed");
         return UNKNOWN_ERROR;
     }
+    mActiveHandle = m_handle;
+    mActiveCamera = MM_CAMERA_TYPE_MAIN;
+    if (isDualChannel()) {
+        mActiveCamera |= MM_CAMERA_TYPE_AUX;
+    }
     return NO_ERROR;
 }
 
 /*===========================================================================
+ * FUNCTION   : getChHandleForStream
+ *
+ * DESCRIPTION: return actual channel handle based on use case per stream
+ *
+ * PARAMETERS :
+ *   @ch_type  : type of channel
+ *
+ * RETURN     : number of buffers needed
+ * NOTE :  Based on the use cases and auxillary camera type,
+           we can decide channel handle for streams.
+           Incase, we want to avoid any stream for auxillary camera,
+           we can decide here.
+ *==========================================================================*/
+uint32_t QCameraChannel::getChHandleForStream(cam_stream_type_t stream_type)
+{
+    uint32_t handle = m_handle;
+    if (!mDualChannel) {
+        return m_handle;
+    }
+
+    /*Based on the use case, decide channel handle for channel*/
+    switch (stream_type) {
+    case CAM_STREAM_TYPE_PREVIEW:
+    case CAM_STREAM_TYPE_SNAPSHOT:
+    case CAM_STREAM_TYPE_VIDEO:
+    case CAM_STREAM_TYPE_METADATA:
+    case CAM_STREAM_TYPE_ANALYSIS:
+    case CAM_STREAM_TYPE_CALLBACK:
+        handle = m_handle;
+        break;
+    case CAM_STREAM_TYPE_POSTVIEW:
+    case CAM_STREAM_TYPE_RAW:
+    case CAM_STREAM_TYPE_OFFLINE_PROC:
+    case CAM_STREAM_TYPE_DEFAULT:
+    case CAM_STREAM_TYPE_MAX:
+    default:
+        handle = get_main_camera_handle(m_handle);
+        break;
+    }
+    return handle;
+}
+
+/*===========================================================================
  * FUNCTION   : addStream
  *
  * DESCRIPTION: add a stream into channel
@@ -208,9 +260,9 @@
  *==========================================================================*/
 int32_t QCameraChannel::addStream(QCameraAllocator &allocator,
         QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
-        uint8_t minStreamBufNum, cam_padding_info_t *paddingInfo,
-        stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf,
-        bool bDeffAlloc, cam_rotation_t online_rotation)
+        cam_padding_info_t *paddingInfo, stream_cb_routine stream_cb,
+        void *userdata, bool bDynAllocBuf, bool bDeffAlloc,
+        cam_rotation_t online_rotation)
 {
     int32_t rc = NO_ERROR;
     if (mStreams.size() >= MAX_STREAM_NUM_IN_BUNDLE) {
@@ -236,9 +288,10 @@
         return NO_MEMORY;
     }
 
-    rc = pStream->init(streamInfoBuf, miscBuf, minStreamBufNum,
+    rc = pStream->init(streamInfoBuf, miscBuf,
                        stream_cb, userdata, bDynAllocBuf);
     if (rc == 0) {
+        Mutex::Autolock lock(mStreamLock);
         mStreams.add(pStream);
     } else {
         delete pStream;
@@ -275,6 +328,7 @@
         LOGE("Linking of stream failed");
         rc = INVALID_OPERATION;
     } else {
+        Mutex::Autolock lock(mStreamLock);
         mStreams.add(stream);
     }
 
@@ -300,44 +354,20 @@
         LOGW("Attempt to start active channel");
         return rc;
     }
-    if (mStreams.size() > 1) {
-        // there is more than one stream in the channel
-        // we need to notify mctl that all streams in this channel need to be bundled
-        cam_bundle_config_t bundleInfo;
-        memset(&bundleInfo, 0, sizeof(bundleInfo));
-        rc = m_camOps->get_bundle_info(m_camHandle, m_handle, &bundleInfo);
-        if (rc != NO_ERROR) {
-            LOGE("get_bundle_info failed");
-            return rc;
-        }
-        if (bundleInfo.num_of_streams > 1) {
-            for (int i = 0; i < bundleInfo.num_of_streams; i++) {
-                QCameraStream *pStream = getStreamByServerID(bundleInfo.stream_ids[i]);
-                if (pStream != NULL) {
-                    if ((pStream->isTypeOf(CAM_STREAM_TYPE_METADATA))
-                            || (pStream->isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) {
-                        // Skip metadata for reprocess now because PP module cannot handle meta data
-                        // May need furthur discussion if Imaginglib need meta data
-                        continue;
-                    }
 
-                    cam_stream_parm_buffer_t param;
-                    memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
-                    param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
-                    param.bundleInfo = bundleInfo;
-                    rc = pStream->setParameter(param);
-                    if (rc != NO_ERROR) {
-                        LOGE("stream setParameter for set bundle failed");
-                        return rc;
-                    }
-                }
-            }
+    // there is more than one stream in the channel
+    // we need to notify mctl that all streams in this channel need to be bundled
+    for (size_t i = 0; i < mStreams.size(); i++) {
+        if ((mStreams[i] != NULL) &&
+                (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
+            mStreams[i]->setBundleInfo();
         }
     }
 
+
     for (size_t i = 0; i < mStreams.size(); i++) {
         if ((mStreams[i] != NULL) &&
-                (m_handle == mStreams[i]->getChannelHandle())) {
+                (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
             mStreams[i]->start();
         }
     }
@@ -346,7 +376,7 @@
     if (rc != NO_ERROR) {
         for (size_t i = 0; i < mStreams.size(); i++) {
             if ((mStreams[i] != NULL) &&
-                    (m_handle == mStreams[i]->getChannelHandle())) {
+                (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
                 mStreams[i]->stop();
             }
         }
@@ -382,14 +412,17 @@
         return NO_INIT;
     }
 
-    while(i < mStreams.size()) {
-        if (mStreams[i] != NULL) {
-            if (m_handle == mStreams[i]->getChannelHandle()) {
-                mStreams[i]->stop();
-                i++;
-            } else {
-                // Remove linked stream from stream list
-                mStreams.removeAt(i);
+    {
+        Mutex::Autolock lock(mStreamLock);
+        while(i < mStreams.size()) {
+            if (mStreams[i] != NULL) {
+                if (validate_handle(m_handle, mStreams[i]->getChannelHandle())) {
+                    mStreams[i]->stop();
+                    i++;
+                } else {
+                    // Remove linked stream from stream list
+                    mStreams.removeAt(i);
+                }
             }
         }
     }
@@ -417,9 +450,10 @@
     int32_t rc = NO_ERROR;
     for (uint32_t i = 0; i < recvd_frame->num_bufs; i++) {
         if (recvd_frame->bufs[i] != NULL) {
-            for (size_t j = 0; j < mStreams.size(); j++) {
+            for (uint32_t j = 0; j < mStreams.size(); j++) {
                 if (mStreams[j] != NULL &&
-                        mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
+                         (validate_handle(mStreams[j]->getMyHandle(),
+                         recvd_frame->bufs[i]->stream_id))) {
                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
                     break; // break loop j
                 }
@@ -451,9 +485,10 @@
         index = -1;
         if ((recvd_frame->bufs[i] != NULL) &&
                 (recvd_frame->bufs[i]->stream_id == stream_id)) {
-            for (size_t j = 0; j < mStreams.size(); j++) {
+            for (uint32_t j = 0; j < mStreams.size(); j++) {
                 if ((mStreams[j] != NULL) &&
-                        (mStreams[j]->getMyHandle() == stream_id)) {
+                        (validate_handle(mStreams[j]->getMyHandle(),
+                        recvd_frame->bufs[i]->stream_id))) {
                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
                     index = i;
                     break; // break loop j
@@ -490,9 +525,10 @@
                                         cam_crop_data_t &crop_info)
 {
     int32_t rc = NO_ERROR;
+    Mutex::Autolock lock(mStreamLock);
     for (size_t i = 0; i < mStreams.size(); i++) {
         if ((mStreams[i] != NULL) &&
-                (m_handle == mStreams[i]->getChannelHandle())) {
+                (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
             rc = mStreams[i]->processZoomDone(previewWindow, crop_info);
         }
     }
@@ -512,7 +548,8 @@
 QCameraStream *QCameraChannel::getStreamByHandle(uint32_t streamHandle)
 {
     for (size_t i = 0; i < mStreams.size(); i++) {
-        if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
+        if (mStreams[i] != NULL &&
+                (validate_handle(mStreams[i]->getMyHandle(), streamHandle))) {
             return mStreams[i];
         }
     }
@@ -576,11 +613,12 @@
 int32_t QCameraChannel::UpdateStreamBasedParameters(QCameraParametersIntf &param)
 {
     int32_t rc = NO_ERROR;
+    Mutex::Autolock lock(mStreamLock);
     if (param.isPreviewFlipChanged()) {
         // try to find preview stream
         for (size_t i = 0; i < mStreams.size(); i++) {
             if ((mStreams[i] != NULL) &&
-                    (m_handle == mStreams[i]->getChannelHandle()) &&
+                    (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_PREVIEW) ||
                     (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_PREVIEW))) ) {
                 cam_stream_parm_buffer_t param_buf;
@@ -599,7 +637,7 @@
         // try to find video stream
         for (size_t i = 0; i < mStreams.size(); i++) {
             if ((mStreams[i] != NULL) &&
-                    (m_handle == mStreams[i]->getChannelHandle()) &&
+                    (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_VIDEO) ||
                     (mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_VIDEO))) ) {
                 cam_stream_parm_buffer_t param_buf;
@@ -618,7 +656,7 @@
         // try to find snapshot/postview stream
         for (size_t i = 0; i < mStreams.size(); i++) {
             if (mStreams[i] != NULL &&
-                    (m_handle == mStreams[i]->getChannelHandle()) &&
+                    (validate_handle(m_handle, mStreams[i]->getChannelHandle())) &&
                     (mStreams[i]->isTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
                      mStreams[i]->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT) ||
                      mStreams[i]->isTypeOf(CAM_STREAM_TYPE_POSTVIEW) ||
@@ -639,6 +677,84 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : processCameraControl
+ *
+ * DESCRIPTION:  Suspend and resume camera
+ *
+ * PARAMETERS :
+ *   @camState   : Camera start. MAIN/AUX/MAIN&AUX
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraChannel::processCameraControl(uint32_t camState)
+{
+    int32_t ret = NO_ERROR;
+
+    for (size_t i = 0; i < mStreams.size(); i++) {
+        if (mStreams[i] != NULL && mStreams[i]->isDualStream()) {
+            ret = mStreams[i]->processCameraControl(camState);
+            if (ret != NO_ERROR) {
+                LOGE("Stream Switch Failed");
+                break;
+            }
+        }
+    }
+
+    if (ret == NO_ERROR) {
+        if (camState == MM_CAMERA_TYPE_MAIN) {
+            mActiveHandle = get_main_camera_handle(m_handle);
+        } else if (camState == MM_CAMERA_TYPE_AUX) {
+            mActiveHandle = get_aux_camera_handle(m_handle);
+        } else {
+            mActiveHandle = m_handle;
+        }
+    }
+    mActiveCamera = camState;
+    return ret;
+}
+
+/*===========================================================================
+ * FUNCTION   : switchChannelCb
+ *
+ * DESCRIPTION: switch channel's in case of dual camera
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraChannel::switchChannelCb()
+{
+    int32_t ret = NO_ERROR;
+
+    for (size_t i = 0; i < mStreams.size(); i++) {
+        if (mStreams[i] != NULL && mStreams[i]->isDualStream()) {
+            ret = mStreams[i]->switchStreamCb();
+            if (ret != NO_ERROR) {
+                LOGE("Stream Switch Failed");
+                break;
+            }
+        }
+    }
+
+    if (ret == NO_ERROR && mActiveCamera == MM_CAMERA_DUAL_CAM) {
+        if (get_aux_camera_handle(m_handle)
+                == mActiveHandle) {
+            mActiveHandle = get_main_camera_handle(m_handle);
+        } else if (get_main_camera_handle(m_handle)
+                == mActiveHandle) {
+            mActiveHandle = get_aux_camera_handle(m_handle);
+        } else {
+            mActiveHandle = m_handle;
+        }
+    }
+    return ret;
+}
+
+/*===========================================================================
  * FUNCTION   : QCameraPicChannel
  *
  * DESCRIPTION: constructor of QCameraPicChannel
@@ -697,7 +813,7 @@
  *==========================================================================*/
 int32_t QCameraPicChannel::takePicture (mm_camera_req_buf_t *buf)
 {
-    int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf);
+    int32_t rc = m_camOps->request_super_buf(m_camHandle, mActiveHandle, buf);
     return rc;
 }
 
@@ -755,7 +871,7 @@
 {
     int32_t rc = NO_ERROR;
 
-    rc = m_camOps->process_advanced_capture(m_camHandle, m_handle, type,
+    rc = m_camOps->process_advanced_capture(m_camHandle, mActiveHandle, type,
             1, config);
     return rc;
 }
@@ -835,7 +951,7 @@
  *==========================================================================*/
 int32_t QCameraVideoChannel::takePicture(mm_camera_req_buf_t *buf)
 {
-    int32_t rc = m_camOps->request_super_buf(m_camHandle, m_handle, buf);
+    int32_t rc = m_camOps->request_super_buf(m_camHandle, mActiveHandle, buf);
     return rc;
 }
 
@@ -982,7 +1098,6 @@
     padding.offset_info.offset_y = 0;
 
     LOGD("num of src stream = %d", pSrcChannel->getNumOfStreams());
-
     for (uint32_t i = 0; i < pSrcChannel->getNumOfStreams(); i++) {
         cam_pp_feature_config_t pp_featuremask = featureConfig;
         pStream = pSrcChannel->getStreamByIndex(i);
@@ -1101,6 +1216,7 @@
                 streamInfo->num_of_burst = burstNum;
             }
             streamInfo->num_bufs = minStreamBufNum;
+            streamInfo->buf_cnt = streamInfo->num_bufs;
 
             cam_stream_reproc_config_t rp_cfg;
             memset(&rp_cfg, 0, sizeof(cam_stream_reproc_config_t));
@@ -1187,23 +1303,37 @@
             }
 
             // save source stream handler
-            mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
+            if (mDualChannel) {
+                mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
+            } else if (get_main_camera_handle(pStream->getMyHandle())) {
+                mSrcStreamHandles[mStreams.size()] =
+                        get_main_camera_handle(pStream->getMyHandle());
+            } else if (get_aux_camera_handle(pStream->getMyHandle())) {
+                mSrcStreamHandles[mStreams.size()] =
+                        get_aux_camera_handle(pStream->getMyHandle());
+            } else {
+                LOGE("Invalid Handle. ");
+                rc = BAD_VALUE;
+                break;
+            }
 
+            mSrcStreamHandles[mStreams.size()] = pStream->getMyHandle();
             pMiscBuf = allocator.allocateMiscBuf(streamInfo);
 
-            LOGH("Configure Reprocessing: stream = %d, res = %dX%d, fmt = %d, type = %d",
+            LOGH("Configure Reprocessing: stream = %d, res = %dX%d, fmt = %d,"
+                    "type = %d buf_cnt = %d",
                     pStream->getMyOriginalType(), streamInfo->dim.width,
-                    streamInfo->dim.height, streamInfo->fmt, type);
+                    streamInfo->dim.height, streamInfo->fmt, type, minStreamBufNum);
 
             // add reprocess stream
             if (streamInfo->reprocess_config.pp_feature_config.feature_mask
                     & CAM_QCOM_FEATURE_ROTATION) {
                 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
-                        minStreamBufNum, &padding, NULL, NULL, false, false,
+                        &padding, NULL, NULL, false, false,
                         streamInfo->reprocess_config.pp_feature_config.rotation);
             } else {
                 rc = addStream(allocator, pStreamInfoBuf, pMiscBuf,
-                        minStreamBufNum, &padding, NULL, NULL, false, false);
+                        &padding, NULL, NULL, false, false);
             }
             if (rc != NO_ERROR) {
                 LOGE("add reprocess stream failed, ret = %d", rc);
@@ -1233,7 +1363,7 @@
     QCameraStream *pStream = NULL;
 
     for (size_t i = 0; i < mStreams.size(); i++) {
-        if (mSrcStreamHandles[i] == srcHandle) {
+        if (validate_handle(mSrcStreamHandles[i], srcHandle)) {
             pStream = mStreams[i];
             break;
         }
@@ -1419,7 +1549,7 @@
     for (uint32_t i = 0; i < frame->num_bufs; i++) {
         pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
         if ((pStream != NULL) &&
-                (m_handle == pStream->getChannelHandle())) {
+                (validate_handle(m_handle,pStream->getChannelHandle()))) {
             if (mParameter.getofflineRAW() &&
                     !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
@@ -1472,6 +1602,8 @@
                         }
                     }
                 }
+            } else {
+                LOGE("Metadata NULL");
             }
 
             rc = doReprocessOffline (frame->bufs[i], meta_buf, pStream);
@@ -1515,7 +1647,8 @@
 
     for (uint32_t i = 0; i < frame->num_bufs; i++) {
         QCameraStream *pStream = getStreamBySrouceHandle(frame->bufs[i]->stream_id);
-        if ((pStream != NULL) && (m_handle == pStream->getChannelHandle())) {
+        if ((pStream != NULL) &&
+                (validate_handle(m_handle, pStream->getChannelHandle()))) {
             if (mParameter.getofflineRAW() && !((pStream->isOrignalTypeOf(CAM_STREAM_TYPE_RAW))
                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_POSTVIEW))
                     || (pStream->isOrignalTypeOf(CAM_STREAM_TYPE_METADATA)))) {
@@ -1585,7 +1718,7 @@
     uint32_t buf_idx = 0;
     for (size_t i = 0; i < mStreams.size(); i++) {
         if ((mStreams[i] != NULL) &&
-                (m_handle != mStreams[i]->getChannelHandle())) {
+                (validate_handle(m_handle, mStreams[i]->getChannelHandle()))) {
             continue;
         }
         rc = mStreams[i]->mapBuf(CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF,
diff --git a/msmcobalt/QCamera2/HAL/QCameraChannel.h b/msmcobalt/QCamera2/HAL/QCameraChannel.h
index 65112e0..825b8b2 100644
--- a/msmcobalt/QCamera2/HAL/QCameraChannel.h
+++ b/msmcobalt/QCamera2/HAL/QCameraChannel.h
@@ -54,7 +54,7 @@
     // Owner of memory is transferred from the caller to the caller with this call.
     virtual int32_t addStream(QCameraAllocator& allocator,
             QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
-            uint8_t minStreamBufnum, cam_padding_info_t *paddingInfo,
+            cam_padding_info_t *paddingInfo,
             stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf,
             bool bDeffAlloc = false, cam_rotation_t online_rotation = ROTATE_0);
     virtual int32_t linkStream(QCameraChannel *ch, QCameraStream *stream);
@@ -74,6 +74,10 @@
     int32_t setStreamSyncCB (cam_stream_type_t stream_type,
             stream_cb_routine stream_cb);
     bool isActive() { return m_bIsActive; }
+    uint32_t getChHandleForStream(cam_stream_type_t stream_type);
+    int32_t switchChannelCb();
+    int32_t processCameraControl(uint32_t camState);
+    bool isDualChannel(){return mDualChannel;};
 protected:
     uint32_t m_camHandle;
     mm_camera_ops_t *m_camOps;
@@ -81,9 +85,13 @@
     bool m_bAllowDynBufAlloc; // if buf allocation can be in two steps
 
     uint32_t m_handle;
+    uint32_t mActiveHandle;
+    uint32_t mActiveCamera;
     Vector<QCameraStream *> mStreams;
     mm_camera_buf_notify_t mDataCB;
     void *mUserData;
+    Mutex mStreamLock;
+    bool mDualChannel;
 };
 
 // burst pic channel: i.e. zsl burst mode
diff --git a/msmcobalt/QCamera2/HAL/QCameraMem.cpp b/msmcobalt/QCamera2/HAL/QCameraMem.cpp
index 2a805a6..29bdc92 100644
--- a/msmcobalt/QCamera2/HAL/QCameraMem.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraMem.cpp
@@ -140,7 +140,7 @@
     custom_data.cmd = cmd;
     custom_data.arg = (unsigned long)&cache_inv_data;
 
-    LOGH("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
+    LOGD("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
           cache_inv_data.vaddr, cache_inv_data.fd,
          (unsigned long)cache_inv_data.handle, cache_inv_data.length,
          mMemInfo[index].main_ion_fd);
@@ -771,7 +771,7 @@
 {
     if (index >= mBufferCount) {
         LOGE("index out of bound");
-        return (void *)BAD_INDEX;
+        return (void *)NULL;
     }
     return mPtr[index];
 }
@@ -1259,7 +1259,7 @@
 {
     if (index >= mBufferCount) {
         LOGE("index out of bound");
-        return (void *)BAD_INDEX;
+        return NULL;
     }
     if (mCameraMemory[index] == 0) {
         return NULL;
@@ -2420,7 +2420,7 @@
 {
     if (index >= mMappableBuffers) {
         LOGE("index out of bound");
-        return (void *)BAD_INDEX;
+        return (void *)NULL;
     }
     return mCameraMemory[index]->data;
 }
diff --git a/msmcobalt/QCamera2/HAL/QCameraParameters.cpp b/msmcobalt/QCamera2/HAL/QCameraParameters.cpp
old mode 100755
new mode 100644
index b506e76..0c756c3
--- a/msmcobalt/QCamera2/HAL/QCameraParameters.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraParameters.cpp
@@ -897,6 +897,7 @@
       m_pCamOpsTbl(NULL),
       m_pParamHeap(NULL),
       m_pParamBuf(NULL),
+      m_pParamBufAux(NULL),
       m_pRelCamSyncHeap(NULL),
       m_pRelCamSyncBuf(NULL),
       m_bFrameSyncEnabled(false),
@@ -1017,6 +1018,7 @@
     mJpegRotation = 0;
     mVideoBatchSize = 0;
     m_bOEMFeatEnabled = isOEMFeat1PropEnabled();
+    m_bDualCamera = 0;
 }
 
 /*===========================================================================
@@ -1036,6 +1038,7 @@
     m_pCamOpsTbl(NULL),
     m_pParamHeap(NULL),
     m_pParamBuf(NULL),
+    m_pParamBufAux(NULL),
     m_pRelCamSyncHeap(NULL),
     m_pRelCamSyncBuf(NULL),
     m_bFrameSyncEnabled(false),
@@ -1125,6 +1128,7 @@
     mBufBatchCnt = 0;
     mVideoBatchSize = 0;
     m_bOEMFeatEnabled = isOEMFeat1PropEnabled();
+    m_bDualCamera = 0;
 }
 
 /*===========================================================================
@@ -3940,7 +3944,7 @@
             setOfflineRAW(FALSE);
         }
          if (initCommit) {
-             if (initBatchUpdate(m_pParamBuf) < 0) {
+             if (initBatchUpdate() < 0) {
                  LOGE("Failed to initialize group update table");
                  return FAILED_TRANSACTION;
              }
@@ -3990,7 +3994,7 @@
     Quadra sensor in normal mode. If more then switch to Quadra CFA mode else
     remain in normal zsl mode */
     params.getPictureSize(&width, &height);
-    if (width > m_pCapability->raw_dim[0].width &&
+    if (width > m_pCapability->raw_dim[0].width ||
         height > m_pCapability->raw_dim[0].height) {
         LOGI("Quadra CFA mode selected");
         m_bQuadraCfa = TRUE;
@@ -4134,17 +4138,22 @@
         if (prev_str == NULL || strcmp(str, prev_str) != 0) {
             m_bNeedRestart = true;
             set(KEY_TS_MAKEUP, str);
-            const char *str1 = params.get(KEY_TS_MAKEUP_WHITEN);
-            if (str1 != NULL) {
-                set(KEY_TS_MAKEUP_WHITEN, str1);
+        }
+        str = params.get(KEY_TS_MAKEUP_WHITEN);
+        prev_str = get(KEY_TS_MAKEUP_WHITEN);
+        if (prev_str == NULL || strcmp(str, prev_str) != 0) {
+            if (str != NULL) {
+                set(KEY_TS_MAKEUP_WHITEN, str);
             }
-            const char *str2 = params.get(KEY_TS_MAKEUP_CLEAN);
-            if (str2 != NULL) {
-                set(KEY_TS_MAKEUP_CLEAN, str2);
+        }
+        str = params.get(KEY_TS_MAKEUP_CLEAN);
+        prev_str = get(KEY_TS_MAKEUP_CLEAN);
+        if (prev_str == NULL || strcmp(str, prev_str) != 0) {
+            if (str != NULL) {
+                set(KEY_TS_MAKEUP_CLEAN, str);
             }
         }
     }
-
     return NO_ERROR;
 }
 
@@ -4306,7 +4315,9 @@
     }
 
     LOGH("nBurstNum = %d, nExpnum = %d", nBurstNum, nExpnum);
-    set(KEY_QC_NUM_SNAPSHOT_PER_SHUTTER, nBurstNum * nExpnum);
+    if (!isDualCamera()) {
+        set(KEY_QC_NUM_SNAPSHOT_PER_SHUTTER, nBurstNum * nExpnum);
+    }
     return NO_ERROR;
 }
 
@@ -4497,7 +4508,7 @@
 int32_t QCameraParameters::updateZSLModeValue(bool value)
 {
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -5167,7 +5178,7 @@
     m_bNeedRestart = false;
     QCameraParameters params(p);
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         rc = BAD_TYPE;
         goto UPDATE_PARAM_DONE;
@@ -5303,7 +5314,7 @@
  *==========================================================================*/
 int32_t QCameraParameters::initDefaultParameters()
 {
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -6190,7 +6201,6 @@
     setMaxPicSize(pic_dim);
 
     setManualCaptureMode(CAM_MANUAL_CAPTURE_TYPE_OFF);
-
     return rc;
 }
 
@@ -6205,7 +6215,7 @@
  *              NO_ERROR  -- success
  *              none-zero failure code
  *==========================================================================*/
-int32_t QCameraParameters::allocate()
+int32_t QCameraParameters::allocate(uint8_t bufCount)
 {
     int32_t rc = NO_ERROR;
 
@@ -6219,14 +6229,13 @@
         return NO_MEMORY;
     }
 
-    rc = m_pParamHeap->allocate(1, sizeof(parm_buffer_t), NON_SECURE);
+    rc = m_pParamHeap->allocate(bufCount, sizeof(parm_buffer_t), NON_SECURE);
     if(rc != OK) {
         rc = NO_MEMORY;
         LOGE("Error!! Param buffers have not been allocated");
         delete m_pParamHeap;
         m_pParamHeap = NULL;
     }
-
     return rc;
 }
 
@@ -6260,25 +6269,43 @@
         goto TRANS_INIT_ERROR1;
     }
 
-    //Map memory for parameters buffer
+    m_bDualCamera = is_dual_camera_by_handle(mmOps->camera_handle);
     cam_buf_map_type_list bufMapList;
     rc = QCameraBufferMaps::makeSingletonBufMapList(
             CAM_MAPPING_BUF_TYPE_PARM_BUF, 0 /*stream id*/,
             0 /*buffer index*/, -1 /*plane index*/, 0 /*cookie*/,
             m_pParamHeap->getFd(0), sizeof(parm_buffer_t), bufMapList,
                     m_pParamHeap->getPtr(0));
-
     if (rc == NO_ERROR) {
         rc = m_pCamOpsTbl->ops->map_bufs(m_pCamOpsTbl->camera_handle,
                 &bufMapList);
     }
-
     if(rc < 0) {
         LOGE("failed to map SETPARM buffer");
         rc = FAILED_TRANSACTION;
         goto TRANS_INIT_ERROR2;
     }
-    m_pParamBuf = (parm_buffer_t*) DATA_PTR(m_pParamHeap,0);
+
+    m_pParamBuf = (parm_buffer_t*) DATA_PTR(m_pParamHeap, 0);
+    if (isDualCamera()) {
+        memset(&bufMapList, 0, sizeof(cam_buf_map_type_list));
+        rc = QCameraBufferMaps::makeSingletonBufMapList(
+                CAM_MAPPING_BUF_TYPE_PARM_BUF, 0 /*stream id*/,
+                0 /*buffer index*/, -1 /*plane index*/, 0 /*cookie*/,
+                m_pParamHeap->getFd(1), sizeof(parm_buffer_t), bufMapList,
+                        m_pParamHeap->getPtr(1));
+        if (rc == NO_ERROR) {
+            rc = m_pCamOpsTbl->ops->map_bufs(
+                    get_aux_camera_handle(m_pCamOpsTbl->camera_handle),
+                    &bufMapList);
+        }
+        if(rc < 0) {
+            LOGE("failed to map SETPARM buffer");
+            rc = FAILED_TRANSACTION;
+            goto TRANS_INIT_ERROR2;
+        }
+        m_pParamBufAux = (parm_buffer_t*)DATA_PTR(m_pParamHeap, 1);
+    }
 
     // Check if it is dual camera mode
     if(m_relCamSyncInfo.sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
@@ -6346,6 +6373,14 @@
  *==========================================================================*/
 void QCameraParameters::deinit()
 {
+    if (NULL != m_pParamHeap) {
+        m_pParamHeap->deallocate();
+        delete m_pParamHeap;
+        m_pParamHeap = NULL;
+        m_pParamBuf = NULL;
+        m_pParamBufAux = NULL;
+    }
+
     if (!m_bInited) {
         return;
     }
@@ -6358,7 +6393,6 @@
         m_pCamOpsTbl->ops->unmap_buf(
                              m_pCamOpsTbl->camera_handle,
                              CAM_MAPPING_BUF_TYPE_PARM_BUF);
-
         if (m_relCamSyncInfo.sync_control == CAM_SYNC_RELATED_SENSORS_ON) {
             m_pCamOpsTbl->ops->unmap_buf(
                     m_pCamOpsTbl->camera_handle,
@@ -6367,12 +6401,6 @@
     }
 
     m_pCapability = NULL;
-    if (NULL != m_pParamHeap) {
-        m_pParamHeap->deallocate();
-        delete m_pParamHeap;
-        m_pParamHeap = NULL;
-        m_pParamBuf = NULL;
-    }
     if (NULL != m_pRelCamSyncHeap) {
         m_pRelCamSyncHeap->deallocate();
         delete m_pRelCamSyncHeap;
@@ -6380,7 +6408,6 @@
         m_pRelCamSyncBuf = NULL;
     }
 
-    m_AdjustFPS = NULL;
     m_tempMap.clear();
     m_pCamOpsTbl = NULL;
     m_AdjustFPS = NULL;
@@ -6492,7 +6519,7 @@
         return NO_INIT;
     }
 
-    int32_t rc = initBatchUpdate(m_pParamBuf);
+    int32_t rc = initBatchUpdate();
     if ( rc != NO_ERROR ) {
         LOGE("Failed to initialize group update table");
         return rc;
@@ -7326,7 +7353,7 @@
     int32_t rc = NO_ERROR;
     int8_t value = enable ? 1 : 0;
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -7397,7 +7424,7 @@
 
     const char *flash_mode_str = lookupNameByValue(FLASH_MODES_MAP,
             PARAM_MAP_SIZE(FLASH_MODES_MAP), flash_mode);
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -7675,7 +7702,7 @@
     memset(&m_captureFrameConfig, 0, sizeof(cam_capture_frame_config_t));
 
     if (commitSettings) {
-        if(initBatchUpdate(m_pParamBuf) < 0 ) {
+        if(initBatchUpdate() < 0 ) {
             LOGE("Failed to initialize group update table");
             return BAD_TYPE;
         }
@@ -7750,7 +7777,7 @@
     memset(&m_captureFrameConfig, 0, sizeof(cam_capture_frame_config_t));
 
     if (commitSettings) {
-        if(initBatchUpdate(m_pParamBuf) < 0 ) {
+        if(initBatchUpdate() < 0 ) {
             LOGE("Failed to initialize group update table");
             return BAD_TYPE;
         }
@@ -8382,7 +8409,7 @@
         updateParamEntry(KEY_QC_OIS, VALUE_DISABLE);
     }
 
-    if (initBatchUpdate(m_pParamBuf) < 0 ) {
+    if (initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -9120,7 +9147,7 @@
 {
     int32_t rc = NO_ERROR;
     LOGH("Setting Lock %d", lock3A);
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -9177,7 +9204,7 @@
 {
     LOGH("E");
     int32_t rc = NO_ERROR;
-    if (initBatchUpdate(m_pParamBuf) < 0 ) {
+    if (initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -9272,7 +9299,7 @@
 {
 
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -9615,7 +9642,7 @@
 int32_t QCameraParameters::setAEBracketing()
 {
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -9649,7 +9676,7 @@
 int32_t QCameraParameters::setHDRAEBracket(cam_exp_bracketing_t hdrBracket)
 {
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -9767,14 +9794,14 @@
     int32_t value;
 
     if (commitSettings) {
-      if(initBatchUpdate(m_pParamBuf) < 0 ) {
+      if(initBatchUpdate() < 0 ) {
           LOGE("Failed to initialize group update table");
           return BAD_TYPE;
       }
     }
-
+    // Turn Off Flash if any of the below AOST features are enabled
     if (isHDREnabled() || m_bAeBracketingEnabled || m_bAFBracketingOn ||
-          m_bOptiZoomOn || m_bReFocusOn || m_bStillMoreOn) {
+          m_bOptiZoomOn || m_bReFocusOn || (m_bStillMoreOn && !m_bSeeMoreOn)) {
         value = CAM_FLASH_MODE_OFF;
     } else if (m_bChromaFlashOn) {
         value = CAM_FLASH_MODE_ON;
@@ -11362,7 +11389,7 @@
 int32_t QCameraParameters::updateRecordingHintValue(int32_t value)
 {
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -11407,7 +11434,7 @@
     }
 
     // set parm for histogram
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -11452,7 +11479,7 @@
         return NO_INIT;
     }
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -11554,7 +11581,7 @@
            faceProcMask,requested_faces);
 
     if (initCommit) {
-        if(initBatchUpdate(m_pParamBuf) < 0 ) {
+        if(initBatchUpdate() < 0 ) {
             LOGE("Failed to initialize group update table");
             return BAD_TYPE;
         }
@@ -11600,7 +11627,7 @@
         return NO_INIT;
     }
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -11661,7 +11688,7 @@
         max_dim = m_pCapability->raw_dim[0];
     }
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -11677,7 +11704,7 @@
         return rc;
     }
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -12128,7 +12155,7 @@
         return BAD_TYPE;
     }
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -12174,14 +12201,871 @@
  *              NO_ERROR  -- success
  *              none-zero failure code
  *==========================================================================*/
-int32_t QCameraParameters::initBatchUpdate(parm_buffer_t *p_table)
+int32_t QCameraParameters::initBatchUpdate()
 {
     m_tempMap.clear();
-    clear_metadata_buffer(p_table);
+    clear_metadata_buffer(m_pParamBuf);
+    clear_metadata_buffer(m_pParamBufAux);
     return NO_ERROR;
 }
 
 /*===========================================================================
+ * FUNCTION   : getPointerofParam
+ *
+ * DESCRIPTION:
+ *
+ * PARAMETERS :
+ *    @meta_id : parameter / meta id enum
+ *    @metadata: metadata buffer pointer
+ *
+ * RETURN     :Pointer of member_variable_<meta_ID>
+ *
+ *==========================================================================*/
+void * QCameraParameters::getPointerofParam(cam_intf_parm_type_t meta_id,
+        metadata_buffer_t* metadata)
+{
+    switch(meta_id) {
+        case CAM_INTF_META_HISTOGRAM:
+            return POINTER_OF_META(CAM_INTF_META_HISTOGRAM, metadata);
+        case CAM_INTF_META_FACE_DETECTION:
+            return POINTER_OF_META(CAM_INTF_META_FACE_DETECTION, metadata);
+        case CAM_INTF_META_FACE_RECOG:
+            return POINTER_OF_META(CAM_INTF_META_FACE_RECOG, metadata);
+        case CAM_INTF_META_FACE_BLINK:
+            return POINTER_OF_META(CAM_INTF_META_FACE_BLINK, metadata);
+        case CAM_INTF_META_FACE_GAZE:
+            return POINTER_OF_META(CAM_INTF_META_FACE_GAZE, metadata);
+        case CAM_INTF_META_FACE_SMILE:
+            return POINTER_OF_META(CAM_INTF_META_FACE_SMILE, metadata);
+        case CAM_INTF_META_FACE_LANDMARK:
+            return POINTER_OF_META(CAM_INTF_META_FACE_LANDMARK, metadata);
+        case CAM_INTF_META_FACE_CONTOUR:
+            return POINTER_OF_META(CAM_INTF_META_FACE_CONTOUR, metadata);
+        case CAM_INTF_META_AUTOFOCUS_DATA:
+            return POINTER_OF_META(CAM_INTF_META_AUTOFOCUS_DATA, metadata);
+        case CAM_INTF_META_CROP_DATA:
+            return POINTER_OF_META(CAM_INTF_META_CROP_DATA, metadata);
+        case CAM_INTF_META_PREP_SNAPSHOT_DONE:
+            return POINTER_OF_META(CAM_INTF_META_PREP_SNAPSHOT_DONE, metadata);
+        case CAM_INTF_META_GOOD_FRAME_IDX_RANGE:
+            return POINTER_OF_META(CAM_INTF_META_GOOD_FRAME_IDX_RANGE, metadata);
+        case CAM_INTF_META_ASD_HDR_SCENE_DATA:
+            return POINTER_OF_META(CAM_INTF_META_ASD_HDR_SCENE_DATA, metadata);
+        case CAM_INTF_META_ASD_SCENE_INFO:
+            return POINTER_OF_META(CAM_INTF_META_ASD_SCENE_INFO, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_ISP:
+            return POINTER_OF_META(CAM_INTF_META_CHROMATIX_LITE_ISP, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_PP:
+            return POINTER_OF_META(CAM_INTF_META_CHROMATIX_LITE_PP, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_AE:
+            return POINTER_OF_META(CAM_INTF_META_CHROMATIX_LITE_AE, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_AWB:
+            return POINTER_OF_META(CAM_INTF_META_CHROMATIX_LITE_AWB, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_AF:
+            return POINTER_OF_META(CAM_INTF_META_CHROMATIX_LITE_AF, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_ASD:
+            return POINTER_OF_META(CAM_INTF_META_CHROMATIX_LITE_ASD, metadata);
+        case CAM_INTF_META_FRAME_NUMBER_VALID:
+            return POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
+        case CAM_INTF_META_URGENT_FRAME_NUMBER_VALID:
+            return POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER_VALID,
+                   metadata);
+        case CAM_INTF_META_FRAME_DROPPED:
+            return POINTER_OF_META(CAM_INTF_META_FRAME_DROPPED, metadata);
+        case CAM_INTF_META_FRAME_NUMBER:
+            return POINTER_OF_META(CAM_INTF_META_FRAME_NUMBER, metadata);
+        case CAM_INTF_META_URGENT_FRAME_NUMBER:
+            return POINTER_OF_META(CAM_INTF_META_URGENT_FRAME_NUMBER, metadata);
+        case CAM_INTF_META_COLOR_CORRECT_MODE:
+            return POINTER_OF_META(CAM_INTF_META_COLOR_CORRECT_MODE, metadata);
+        case CAM_INTF_META_COLOR_CORRECT_TRANSFORM:
+            return POINTER_OF_META(CAM_INTF_META_COLOR_CORRECT_TRANSFORM, metadata);
+        case CAM_INTF_META_COLOR_CORRECT_GAINS:
+            return POINTER_OF_META(CAM_INTF_META_COLOR_CORRECT_GAINS, metadata);
+        case CAM_INTF_META_PRED_COLOR_CORRECT_TRANSFORM:
+            return POINTER_OF_META(CAM_INTF_META_PRED_COLOR_CORRECT_TRANSFORM,
+                   metadata);
+        case CAM_INTF_META_PRED_COLOR_CORRECT_GAINS:
+            return POINTER_OF_META(CAM_INTF_META_PRED_COLOR_CORRECT_GAINS, metadata);
+        case CAM_INTF_META_AEC_ROI:
+            return POINTER_OF_META(CAM_INTF_META_AEC_ROI, metadata);
+        case CAM_INTF_META_CURRENT_SCENE:
+            return POINTER_OF_META(CAM_INTF_META_CURRENT_SCENE, metadata);
+        case CAM_INTF_META_AEC_STATE:
+            return POINTER_OF_META(CAM_INTF_META_AEC_STATE, metadata);
+        case CAM_INTF_PARM_FOCUS_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_FOCUS_MODE, metadata);
+        case CAM_INTF_PARM_MANUAL_FOCUS_POS:
+            return POINTER_OF_META(CAM_INTF_PARM_MANUAL_FOCUS_POS, metadata);
+        case CAM_INTF_META_AF_ROI:
+            return POINTER_OF_META(CAM_INTF_META_AF_ROI, metadata);
+        case CAM_INTF_META_AF_STATE:
+            return POINTER_OF_META(CAM_INTF_META_AF_STATE, metadata);
+        case CAM_INTF_PARM_WHITE_BALANCE:
+            return POINTER_OF_META(CAM_INTF_PARM_WHITE_BALANCE, metadata);
+        case CAM_INTF_META_AWB_REGIONS:
+            return POINTER_OF_META(CAM_INTF_META_AWB_REGIONS, metadata);
+        case CAM_INTF_META_AWB_STATE:
+            return POINTER_OF_META(CAM_INTF_META_AWB_STATE, metadata);
+        case CAM_INTF_META_BLACK_LEVEL_LOCK:
+            return POINTER_OF_META(CAM_INTF_META_BLACK_LEVEL_LOCK, metadata);
+        case CAM_INTF_META_MODE:
+            return POINTER_OF_META(CAM_INTF_META_MODE, metadata);
+        case CAM_INTF_META_EDGE_MODE:
+            return POINTER_OF_META(CAM_INTF_META_EDGE_MODE, metadata);
+        case CAM_INTF_META_FLASH_POWER:
+            return POINTER_OF_META(CAM_INTF_META_FLASH_POWER, metadata);
+        case CAM_INTF_META_FLASH_FIRING_TIME:
+            return POINTER_OF_META(CAM_INTF_META_FLASH_FIRING_TIME, metadata);
+        case CAM_INTF_META_FLASH_MODE:
+            return POINTER_OF_META(CAM_INTF_META_FLASH_MODE, metadata);
+        case CAM_INTF_META_FLASH_STATE:
+            return POINTER_OF_META(CAM_INTF_META_FLASH_STATE, metadata);
+        case CAM_INTF_META_HOTPIXEL_MODE:
+            return POINTER_OF_META(CAM_INTF_META_HOTPIXEL_MODE, metadata);
+        case CAM_INTF_META_LENS_APERTURE:
+            return POINTER_OF_META(CAM_INTF_META_LENS_APERTURE, metadata);
+        case CAM_INTF_META_LENS_FILTERDENSITY:
+            return POINTER_OF_META(CAM_INTF_META_LENS_FILTERDENSITY, metadata);
+        case CAM_INTF_META_LENS_FOCAL_LENGTH:
+            return POINTER_OF_META(CAM_INTF_META_LENS_FOCAL_LENGTH, metadata);
+        case CAM_INTF_META_LENS_FOCUS_DISTANCE:
+            return POINTER_OF_META(CAM_INTF_META_LENS_FOCUS_DISTANCE, metadata);
+        case CAM_INTF_META_LENS_FOCUS_RANGE:
+            return POINTER_OF_META(CAM_INTF_META_LENS_FOCUS_RANGE, metadata);
+        case CAM_INTF_META_LENS_STATE:
+            return POINTER_OF_META(CAM_INTF_META_LENS_STATE, metadata);
+        case CAM_INTF_META_LENS_OPT_STAB_MODE:
+            return POINTER_OF_META(CAM_INTF_META_LENS_OPT_STAB_MODE, metadata);
+        case CAM_INTF_META_NOISE_REDUCTION_MODE:
+            return POINTER_OF_META(CAM_INTF_META_NOISE_REDUCTION_MODE, metadata);
+        case CAM_INTF_META_NOISE_REDUCTION_STRENGTH:
+            return POINTER_OF_META(CAM_INTF_META_NOISE_REDUCTION_STRENGTH, metadata);
+        case CAM_INTF_META_SCALER_CROP_REGION:
+            return POINTER_OF_META(CAM_INTF_META_SCALER_CROP_REGION, metadata);
+        case CAM_INTF_META_SCENE_FLICKER:
+            return POINTER_OF_META(CAM_INTF_META_SCENE_FLICKER, metadata);
+        case CAM_INTF_META_SENSOR_EXPOSURE_TIME:
+            return POINTER_OF_META(CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata);
+        case CAM_INTF_META_SENSOR_FRAME_DURATION:
+            return POINTER_OF_META(CAM_INTF_META_SENSOR_FRAME_DURATION, metadata);
+        case CAM_INTF_META_SENSOR_SENSITIVITY:
+            return POINTER_OF_META(CAM_INTF_META_SENSOR_SENSITIVITY, metadata);
+        case CAM_INTF_META_SENSOR_TIMESTAMP:
+            return POINTER_OF_META(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
+        case CAM_INTF_META_SHADING_MODE:
+            return POINTER_OF_META(CAM_INTF_META_SHADING_MODE, metadata);
+        case CAM_INTF_META_STATS_FACEDETECT_MODE:
+            return POINTER_OF_META(CAM_INTF_META_STATS_FACEDETECT_MODE, metadata);
+        case CAM_INTF_META_STATS_HISTOGRAM_MODE:
+            return POINTER_OF_META(CAM_INTF_META_STATS_HISTOGRAM_MODE, metadata);
+        case CAM_INTF_META_STATS_SHARPNESS_MAP_MODE:
+            return POINTER_OF_META(CAM_INTF_META_STATS_SHARPNESS_MAP_MODE, metadata);
+        case CAM_INTF_META_STATS_SHARPNESS_MAP:
+            return POINTER_OF_META(CAM_INTF_META_STATS_SHARPNESS_MAP, metadata);
+        case CAM_INTF_META_TONEMAP_CURVES:
+            return POINTER_OF_META(CAM_INTF_META_TONEMAP_CURVES, metadata);
+        case CAM_INTF_META_LENS_SHADING_MAP:
+            return POINTER_OF_META(CAM_INTF_META_LENS_SHADING_MAP, metadata);
+        case CAM_INTF_META_AEC_INFO:
+            return POINTER_OF_META(CAM_INTF_META_AEC_INFO, metadata);
+        case CAM_INTF_META_SENSOR_INFO:
+            return POINTER_OF_META(CAM_INTF_META_SENSOR_INFO, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_AE:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_AE, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_AWB:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_AWB, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_AF:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_AF, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_ASD:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_ASD, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_STATS:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_STATS, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_BESTATS:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_BESTATS, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_BHIST:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_BHIST, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_3A_TUNING:
+            return POINTER_OF_META(CAM_INTF_META_EXIF_DEBUG_3A_TUNING, metadata);
+        case CAM_INTF_PARM_EFFECT:
+            return POINTER_OF_META(CAM_INTF_PARM_EFFECT, metadata);
+        case CAM_INTF_META_PRIVATE_DATA:
+            return POINTER_OF_META(CAM_INTF_META_PRIVATE_DATA, metadata);
+        case CAM_INTF_PARM_HAL_VERSION:
+            return POINTER_OF_META(CAM_INTF_PARM_HAL_VERSION, metadata);
+        case CAM_INTF_PARM_ANTIBANDING:
+            return POINTER_OF_META(CAM_INTF_PARM_ANTIBANDING, metadata);
+        case CAM_INTF_PARM_EXPOSURE_COMPENSATION:
+            return POINTER_OF_META(CAM_INTF_PARM_EXPOSURE_COMPENSATION, metadata);
+        case CAM_INTF_PARM_EV_STEP:
+            return POINTER_OF_META(CAM_INTF_PARM_EV_STEP, metadata);
+        case CAM_INTF_PARM_AEC_LOCK:
+            return POINTER_OF_META(CAM_INTF_PARM_AEC_LOCK, metadata);
+        case CAM_INTF_PARM_FPS_RANGE:
+            return POINTER_OF_META(CAM_INTF_PARM_FPS_RANGE, metadata);
+        case CAM_INTF_PARM_AWB_LOCK:
+            return POINTER_OF_META(CAM_INTF_PARM_AWB_LOCK, metadata);
+        case CAM_INTF_PARM_BESTSHOT_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_BESTSHOT_MODE, metadata);
+        case CAM_INTF_PARM_DIS_ENABLE:
+            return POINTER_OF_META(CAM_INTF_PARM_DIS_ENABLE, metadata);
+        case CAM_INTF_PARM_LED_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_LED_MODE, metadata);
+        case CAM_INTF_META_LED_MODE_OVERRIDE:
+            return POINTER_OF_META(CAM_INTF_META_LED_MODE_OVERRIDE, metadata);
+        case CAM_INTF_PARM_QUERY_FLASH4SNAP:
+            return POINTER_OF_META(CAM_INTF_PARM_QUERY_FLASH4SNAP, metadata);
+        case CAM_INTF_PARM_EXPOSURE:
+            return POINTER_OF_META(CAM_INTF_PARM_EXPOSURE, metadata);
+        case CAM_INTF_PARM_SHARPNESS:
+            return POINTER_OF_META(CAM_INTF_PARM_SHARPNESS, metadata);
+        case CAM_INTF_PARM_CONTRAST:
+            return POINTER_OF_META(CAM_INTF_PARM_CONTRAST, metadata);
+        case CAM_INTF_PARM_SATURATION:
+            return POINTER_OF_META(CAM_INTF_PARM_SATURATION, metadata);
+        case CAM_INTF_PARM_BRIGHTNESS:
+            return POINTER_OF_META(CAM_INTF_PARM_BRIGHTNESS, metadata);
+        case CAM_INTF_PARM_ISO:
+            return POINTER_OF_META(CAM_INTF_PARM_ISO, metadata);
+        case CAM_INTF_PARM_EXPOSURE_TIME:
+            return POINTER_OF_META(CAM_INTF_PARM_EXPOSURE_TIME, metadata);
+        case CAM_INTF_PARM_ZOOM:
+            return POINTER_OF_META(CAM_INTF_PARM_ZOOM, metadata);
+        case CAM_INTF_PARM_ROLLOFF:
+            return POINTER_OF_META(CAM_INTF_PARM_ROLLOFF, metadata);
+        case CAM_INTF_PARM_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_MODE, metadata);
+        case CAM_INTF_PARM_AEC_ALGO_TYPE:
+            return POINTER_OF_META(CAM_INTF_PARM_AEC_ALGO_TYPE, metadata);
+        case CAM_INTF_PARM_FOCUS_ALGO_TYPE:
+            return POINTER_OF_META(CAM_INTF_PARM_FOCUS_ALGO_TYPE, metadata);
+        case CAM_INTF_PARM_AEC_ROI:
+            return POINTER_OF_META(CAM_INTF_PARM_AEC_ROI, metadata);
+        case CAM_INTF_PARM_AF_ROI:
+            return POINTER_OF_META(CAM_INTF_PARM_AF_ROI, metadata);
+        case CAM_INTF_PARM_SCE_FACTOR:
+            return POINTER_OF_META(CAM_INTF_PARM_SCE_FACTOR, metadata);
+        case CAM_INTF_PARM_FD:
+            return POINTER_OF_META(CAM_INTF_PARM_FD, metadata);
+        case CAM_INTF_PARM_MCE:
+            return POINTER_OF_META(CAM_INTF_PARM_MCE, metadata);
+        case CAM_INTF_PARM_HFR:
+            return POINTER_OF_META(CAM_INTF_PARM_HFR, metadata);
+        case CAM_INTF_PARM_REDEYE_REDUCTION:
+            return POINTER_OF_META(CAM_INTF_PARM_REDEYE_REDUCTION, metadata);
+        case CAM_INTF_PARM_WAVELET_DENOISE:
+            return POINTER_OF_META(CAM_INTF_PARM_WAVELET_DENOISE, metadata);
+        case CAM_INTF_PARM_TEMPORAL_DENOISE:
+            return POINTER_OF_META(CAM_INTF_PARM_TEMPORAL_DENOISE, metadata);
+        case CAM_INTF_PARM_HISTOGRAM:
+            return POINTER_OF_META(CAM_INTF_PARM_HISTOGRAM, metadata);
+        case CAM_INTF_PARM_ASD_ENABLE:
+            return POINTER_OF_META(CAM_INTF_PARM_ASD_ENABLE, metadata);
+        case CAM_INTF_PARM_RECORDING_HINT:
+            return POINTER_OF_META(CAM_INTF_PARM_RECORDING_HINT, metadata);
+        case CAM_INTF_PARM_HDR:
+            return POINTER_OF_META(CAM_INTF_PARM_HDR, metadata);
+        case CAM_INTF_PARM_FRAMESKIP:
+            return POINTER_OF_META(CAM_INTF_PARM_FRAMESKIP, metadata);
+        case CAM_INTF_PARM_ZSL_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_ZSL_MODE, metadata);
+        case CAM_INTF_PARM_HDR_NEED_1X:
+            return POINTER_OF_META(CAM_INTF_PARM_HDR_NEED_1X, metadata);
+        case CAM_INTF_PARM_LOCK_CAF:
+            return POINTER_OF_META(CAM_INTF_PARM_LOCK_CAF, metadata);
+        case CAM_INTF_PARM_VIDEO_HDR:
+            return POINTER_OF_META(CAM_INTF_PARM_VIDEO_HDR, metadata);
+        case CAM_INTF_PARM_VT:
+            return POINTER_OF_META(CAM_INTF_PARM_VT, metadata);
+        case CAM_INTF_PARM_SET_AUTOFOCUSTUNING:
+            return POINTER_OF_META(CAM_INTF_PARM_SET_AUTOFOCUSTUNING, metadata);
+        case CAM_INTF_PARM_SET_VFE_COMMAND:
+            return POINTER_OF_META(CAM_INTF_PARM_SET_VFE_COMMAND, metadata);
+        case CAM_INTF_PARM_SET_PP_COMMAND:
+            return POINTER_OF_META(CAM_INTF_PARM_SET_PP_COMMAND, metadata);
+        case CAM_INTF_PARM_MAX_DIMENSION:
+            return POINTER_OF_META(CAM_INTF_PARM_MAX_DIMENSION, metadata);
+        case CAM_INTF_PARM_RAW_DIMENSION:
+            return POINTER_OF_META(CAM_INTF_PARM_RAW_DIMENSION, metadata);
+        case CAM_INTF_PARM_TINTLESS:
+            return POINTER_OF_META(CAM_INTF_PARM_TINTLESS, metadata);
+        case CAM_INTF_PARM_WB_MANUAL:
+            return POINTER_OF_META(CAM_INTF_PARM_WB_MANUAL, metadata);
+        case CAM_INTF_PARM_EZTUNE_CMD:
+            return POINTER_OF_META(CAM_INTF_PARM_EZTUNE_CMD, metadata);
+        case CAM_INTF_PARM_INT_EVT:
+            return POINTER_OF_META(CAM_INTF_PARM_INT_EVT, metadata);
+        case CAM_INTF_PARM_RDI_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_RDI_MODE, metadata);
+        case CAM_INTF_PARM_CDS_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_CDS_MODE, metadata);
+        case CAM_INTF_PARM_BURST_NUM:
+            return POINTER_OF_META(CAM_INTF_PARM_BURST_NUM, metadata);
+        case CAM_INTF_PARM_RETRO_BURST_NUM:
+            return POINTER_OF_META(CAM_INTF_PARM_RETRO_BURST_NUM, metadata);
+        case CAM_INTF_PARM_BURST_LED_ON_PERIOD:
+            return POINTER_OF_META(CAM_INTF_PARM_BURST_LED_ON_PERIOD, metadata);
+        case CAM_INTF_PARM_LONGSHOT_ENABLE:
+            return POINTER_OF_META(CAM_INTF_PARM_LONGSHOT_ENABLE, metadata);
+        case CAM_INTF_META_STREAM_INFO:
+            return POINTER_OF_META(CAM_INTF_META_STREAM_INFO, metadata);
+        case CAM_INTF_META_AEC_MODE:
+            return POINTER_OF_META(CAM_INTF_META_AEC_MODE, metadata);
+        case CAM_INTF_META_TOUCH_AE_RESULT:
+            return POINTER_OF_META(CAM_INTF_META_TOUCH_AE_RESULT, metadata);
+        case CAM_INTF_META_AEC_PRECAPTURE_TRIGGER:
+            return POINTER_OF_META(CAM_INTF_META_AEC_PRECAPTURE_TRIGGER, metadata);
+        case CAM_INTF_META_AF_TRIGGER:
+            return POINTER_OF_META(CAM_INTF_META_AF_TRIGGER, metadata);
+        case CAM_INTF_META_CAPTURE_INTENT:
+            return POINTER_OF_META(CAM_INTF_META_CAPTURE_INTENT, metadata);
+        case CAM_INTF_META_DEMOSAIC:
+            return POINTER_OF_META(CAM_INTF_META_DEMOSAIC, metadata);
+        case CAM_INTF_META_SHARPNESS_STRENGTH:
+            return POINTER_OF_META(CAM_INTF_META_SHARPNESS_STRENGTH, metadata);
+        case CAM_INTF_META_GEOMETRIC_MODE:
+            return POINTER_OF_META(CAM_INTF_META_GEOMETRIC_MODE, metadata);
+        case CAM_INTF_META_GEOMETRIC_STRENGTH:
+            return POINTER_OF_META(CAM_INTF_META_GEOMETRIC_STRENGTH, metadata);
+        case CAM_INTF_META_LENS_SHADING_MAP_MODE:
+            return POINTER_OF_META(CAM_INTF_META_LENS_SHADING_MAP_MODE, metadata);
+        case CAM_INTF_META_ISP_SENSITIVITY:
+            return POINTER_OF_META(CAM_INTF_META_ISP_SENSITIVITY, metadata);
+        case CAM_INTF_META_SHADING_STRENGTH:
+            return POINTER_OF_META(CAM_INTF_META_SHADING_STRENGTH, metadata);
+        case CAM_INTF_META_TONEMAP_MODE:
+            return POINTER_OF_META(CAM_INTF_META_TONEMAP_MODE, metadata);
+        case CAM_INTF_META_AWB_INFO:
+            return POINTER_OF_META(CAM_INTF_META_AWB_INFO, metadata);
+        case CAM_INTF_META_FOCUS_POSITION:
+            return POINTER_OF_META(CAM_INTF_META_FOCUS_POSITION, metadata);
+        case CAM_INTF_META_STREAM_ID:
+            return POINTER_OF_META(CAM_INTF_META_STREAM_ID, metadata);
+        case CAM_INTF_PARM_STATS_DEBUG_MASK:
+            return POINTER_OF_META(CAM_INTF_PARM_STATS_DEBUG_MASK, metadata);
+        case CAM_INTF_PARM_STATS_AF_PAAF:
+            return POINTER_OF_META(CAM_INTF_PARM_STATS_AF_PAAF, metadata);
+        case CAM_INTF_PARM_FOCUS_BRACKETING:
+            return POINTER_OF_META(CAM_INTF_PARM_FOCUS_BRACKETING, metadata);
+        case CAM_INTF_PARM_FLASH_BRACKETING:
+            return POINTER_OF_META(CAM_INTF_PARM_FLASH_BRACKETING, metadata);
+        case CAM_INTF_META_JPEG_GPS_COORDINATES:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_GPS_COORDINATES, metadata);
+        case CAM_INTF_META_JPEG_GPS_PROC_METHODS:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata);
+        case CAM_INTF_META_JPEG_GPS_TIMESTAMP:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata);
+        case CAM_INTF_META_JPEG_QUALITY:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_QUALITY, metadata);
+        case CAM_INTF_META_OTP_WB_GRGB:
+            return POINTER_OF_META(CAM_INTF_META_OTP_WB_GRGB, metadata);
+        case CAM_INTF_META_JPEG_THUMB_QUALITY:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_THUMB_QUALITY, metadata);
+        case CAM_INTF_META_JPEG_THUMB_SIZE:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_THUMB_SIZE, metadata);
+        case CAM_INTF_META_JPEG_ORIENTATION:
+            return POINTER_OF_META(CAM_INTF_META_JPEG_ORIENTATION, metadata);
+        case CAM_INTF_META_PROFILE_TONE_CURVE:
+            return POINTER_OF_META(CAM_INTF_META_PROFILE_TONE_CURVE, metadata);
+        case CAM_INTF_META_NEUTRAL_COL_POINT:
+            return POINTER_OF_META(CAM_INTF_META_NEUTRAL_COL_POINT, metadata);
+        case CAM_INTF_META_SENSOR_ROLLING_SHUTTER_SKEW:
+            return POINTER_OF_META(CAM_INTF_META_SENSOR_ROLLING_SHUTTER_SKEW,
+                   metadata);
+        case CAM_INTF_PARM_CAC:
+            return POINTER_OF_META(CAM_INTF_PARM_CAC, metadata);
+        case CAM_INTF_META_IMG_HYST_INFO:
+            return POINTER_OF_META(CAM_INTF_META_IMG_HYST_INFO, metadata);
+        case CAM_INTF_META_CAC_INFO:
+            return POINTER_OF_META(CAM_INTF_META_CAC_INFO, metadata);
+        case CAM_INTF_META_TEST_PATTERN_DATA:
+            return POINTER_OF_META(CAM_INTF_META_TEST_PATTERN_DATA, metadata);
+        case CAM_INTF_PARM_UPDATE_DEBUG_LEVEL:
+            return POINTER_OF_META(CAM_INTF_PARM_UPDATE_DEBUG_LEVEL, metadata);
+        case CAM_INTF_PARM_ROTATION:
+            return POINTER_OF_META(CAM_INTF_PARM_ROTATION, metadata);
+        case CAM_INTF_PARM_FLIP:
+            return POINTER_OF_META(CAM_INTF_PARM_FLIP, metadata);
+        case CAM_INTF_PARM_TONE_MAP_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_TONE_MAP_MODE, metadata);
+        case CAM_INTF_META_IMGLIB:
+            return POINTER_OF_META(CAM_INTF_META_IMGLIB, metadata);
+        case CAM_INTF_PARM_CAPTURE_FRAME_CONFIG:
+            return POINTER_OF_META(CAM_INTF_PARM_CAPTURE_FRAME_CONFIG, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_SENSOR:
+            return POINTER_OF_META(CAM_INTF_META_SNAP_CROP_INFO_SENSOR, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_CAMIF:
+            return POINTER_OF_META(CAM_INTF_META_SNAP_CROP_INFO_CAMIF, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_ISP:
+            return POINTER_OF_META(CAM_INTF_META_SNAP_CROP_INFO_ISP, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_CPP:
+            return POINTER_OF_META(CAM_INTF_META_SNAP_CROP_INFO_CPP, metadata);
+        case CAM_INTF_PARM_CUSTOM:
+            return POINTER_OF_META(CAM_INTF_PARM_CUSTOM, metadata);
+        case CAM_INTF_PARM_RELATED_SENSORS_CALIBRATION:
+            return POINTER_OF_META(CAM_INTF_PARM_RELATED_SENSORS_CALIBRATION,
+              metadata);
+        case CAM_INTF_META_AF_FOCAL_LENGTH_RATIO:
+            return POINTER_OF_META(CAM_INTF_META_AF_FOCAL_LENGTH_RATIO, metadata);
+        case CAM_INTF_META_DCRF:
+            return POINTER_OF_META(CAM_INTF_META_DCRF, metadata);
+        case CAM_INTF_BUF_DIVERT_INFO:
+            return POINTER_OF_META(CAM_INTF_BUF_DIVERT_INFO, metadata);
+        case CAM_INTF_META_LOW_LIGHT:
+            return POINTER_OF_META(CAM_INTF_META_LOW_LIGHT, metadata);
+        case CAM_INTF_META_IMG_DYN_FEAT:
+            return POINTER_OF_META(CAM_INTF_META_IMG_DYN_FEAT, metadata);
+        case CAM_INTF_AF_STATE_TRANSITION:
+            return POINTER_OF_META(CAM_INTF_AF_STATE_TRANSITION, metadata);
+        case CAM_INTF_PARM_DUAL_LED_CALIBRATION:
+            return POINTER_OF_META(CAM_INTF_PARM_DUAL_LED_CALIBRATION, metadata);
+        case CAM_INTF_PARM_INITIAL_EXPOSURE_INDEX:
+            return POINTER_OF_META(CAM_INTF_PARM_INITIAL_EXPOSURE_INDEX, metadata);
+        case CAM_INTF_PARM_SENSOR_HDR:
+            return POINTER_OF_META(CAM_INTF_PARM_SENSOR_HDR, metadata);
+        case CAM_INTF_PARM_INSTANT_AEC:
+            return POINTER_OF_META(CAM_INTF_PARM_INSTANT_AEC, metadata);
+        case CAM_INTF_PARM_ADV_CAPTURE_MODE:
+            return POINTER_OF_META(CAM_INTF_PARM_ADV_CAPTURE_MODE, metadata);
+        case CAM_INTF_META_VIDEO_STAB_MODE:
+            return POINTER_OF_META(CAM_INTF_META_VIDEO_STAB_MODE, metadata);
+        default:
+            LOGE("meta ID %d is not found", meta_id);
+            return NULL;
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : getSizeofParam
+ *
+ * DESCRIPTION:
+ *
+ * PARAMETERS :
+ *    @meta_id : parameter / meta id enum
+ *
+ * RETURN     :uint32_t size of param/metadata
+ *
+ *==========================================================================*/
+uint32_t QCameraParameters::getSizeofParam(cam_intf_parm_type_t param_id)
+{
+      metadata_buffer_t* metadata = NULL;
+      switch(param_id) {
+        case CAM_INTF_META_HISTOGRAM:
+          return SIZE_OF_PARAM(CAM_INTF_META_HISTOGRAM, metadata);
+        case CAM_INTF_META_FACE_DETECTION:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_DETECTION, metadata);
+        case CAM_INTF_META_FACE_RECOG:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_RECOG, metadata);
+        case CAM_INTF_META_FACE_BLINK:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_BLINK, metadata);
+        case CAM_INTF_META_FACE_GAZE:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_GAZE, metadata);
+        case CAM_INTF_META_FACE_SMILE:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_SMILE, metadata);
+        case CAM_INTF_META_FACE_LANDMARK:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_LANDMARK, metadata);
+        case CAM_INTF_META_FACE_CONTOUR:
+          return SIZE_OF_PARAM(CAM_INTF_META_FACE_CONTOUR, metadata);
+        case CAM_INTF_META_AUTOFOCUS_DATA:
+          return SIZE_OF_PARAM(CAM_INTF_META_AUTOFOCUS_DATA, metadata);
+        case CAM_INTF_META_CROP_DATA:
+          return SIZE_OF_PARAM(CAM_INTF_META_CROP_DATA, metadata);
+        case CAM_INTF_META_PREP_SNAPSHOT_DONE:
+          return SIZE_OF_PARAM(CAM_INTF_META_PREP_SNAPSHOT_DONE, metadata);
+        case CAM_INTF_META_GOOD_FRAME_IDX_RANGE:
+          return SIZE_OF_PARAM(CAM_INTF_META_GOOD_FRAME_IDX_RANGE, metadata);
+        case CAM_INTF_META_ASD_HDR_SCENE_DATA:
+          return SIZE_OF_PARAM(CAM_INTF_META_ASD_HDR_SCENE_DATA, metadata);
+        case CAM_INTF_META_ASD_SCENE_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_ASD_SCENE_INFO, metadata);
+        case CAM_INTF_META_CURRENT_SCENE:
+          return SIZE_OF_PARAM(CAM_INTF_META_CURRENT_SCENE, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_ISP:
+          return SIZE_OF_PARAM(CAM_INTF_META_CHROMATIX_LITE_ISP, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_PP:
+          return SIZE_OF_PARAM(CAM_INTF_META_CHROMATIX_LITE_PP, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_AE:
+          return SIZE_OF_PARAM(CAM_INTF_META_CHROMATIX_LITE_AE, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_AWB:
+          return SIZE_OF_PARAM(CAM_INTF_META_CHROMATIX_LITE_AWB, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_AF:
+          return SIZE_OF_PARAM(CAM_INTF_META_CHROMATIX_LITE_AF, metadata);
+        case CAM_INTF_META_CHROMATIX_LITE_ASD:
+          return SIZE_OF_PARAM(CAM_INTF_META_CHROMATIX_LITE_ASD, metadata);
+        case CAM_INTF_META_FRAME_NUMBER_VALID:
+          return SIZE_OF_PARAM(CAM_INTF_META_FRAME_NUMBER_VALID, metadata);
+        case CAM_INTF_META_URGENT_FRAME_NUMBER_VALID:
+          return SIZE_OF_PARAM(CAM_INTF_META_URGENT_FRAME_NUMBER_VALID, metadata);
+        case CAM_INTF_META_FRAME_DROPPED:
+          return SIZE_OF_PARAM(CAM_INTF_META_FRAME_DROPPED, metadata);
+        case CAM_INTF_META_FRAME_NUMBER:
+          return SIZE_OF_PARAM(CAM_INTF_META_FRAME_NUMBER, metadata);
+        case CAM_INTF_META_URGENT_FRAME_NUMBER:
+          return SIZE_OF_PARAM(CAM_INTF_META_URGENT_FRAME_NUMBER, metadata);
+        case CAM_INTF_META_COLOR_CORRECT_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_COLOR_CORRECT_MODE, metadata);
+        case CAM_INTF_META_COLOR_CORRECT_TRANSFORM:
+          return SIZE_OF_PARAM(CAM_INTF_META_COLOR_CORRECT_TRANSFORM, metadata);
+        case CAM_INTF_META_COLOR_CORRECT_GAINS:
+          return SIZE_OF_PARAM(CAM_INTF_META_COLOR_CORRECT_GAINS, metadata);
+        case CAM_INTF_META_PRED_COLOR_CORRECT_TRANSFORM:
+          return SIZE_OF_PARAM(CAM_INTF_META_PRED_COLOR_CORRECT_TRANSFORM,
+            metadata);
+        case CAM_INTF_META_PRED_COLOR_CORRECT_GAINS:
+          return SIZE_OF_PARAM(CAM_INTF_META_PRED_COLOR_CORRECT_GAINS, metadata);
+        case CAM_INTF_META_AEC_ROI:
+          return SIZE_OF_PARAM(CAM_INTF_META_AEC_ROI, metadata);
+        case CAM_INTF_META_AEC_STATE:
+          return SIZE_OF_PARAM(CAM_INTF_META_AEC_STATE, metadata);
+        case CAM_INTF_PARM_FOCUS_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FOCUS_MODE, metadata);
+        case CAM_INTF_PARM_MANUAL_FOCUS_POS:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_MANUAL_FOCUS_POS, metadata);
+        case CAM_INTF_META_AF_ROI:
+          return SIZE_OF_PARAM(CAM_INTF_META_AF_ROI, metadata);
+        case CAM_INTF_META_AF_STATE:
+          return SIZE_OF_PARAM(CAM_INTF_META_AF_STATE, metadata);
+        case CAM_INTF_PARM_WHITE_BALANCE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_WHITE_BALANCE, metadata);
+        case CAM_INTF_META_AWB_REGIONS:
+          return SIZE_OF_PARAM(CAM_INTF_META_AWB_REGIONS, metadata);
+        case CAM_INTF_META_AWB_STATE:
+          return SIZE_OF_PARAM(CAM_INTF_META_AWB_STATE, metadata);
+        case CAM_INTF_META_BLACK_LEVEL_LOCK:
+          return SIZE_OF_PARAM(CAM_INTF_META_BLACK_LEVEL_LOCK, metadata);
+        case CAM_INTF_META_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_MODE, metadata);
+        case CAM_INTF_META_EDGE_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_EDGE_MODE, metadata);
+        case CAM_INTF_META_FLASH_POWER:
+          return SIZE_OF_PARAM(CAM_INTF_META_FLASH_POWER, metadata);
+        case CAM_INTF_META_FLASH_FIRING_TIME:
+          return SIZE_OF_PARAM(CAM_INTF_META_FLASH_FIRING_TIME, metadata);
+        case CAM_INTF_META_FLASH_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_FLASH_MODE, metadata);
+        case CAM_INTF_META_FLASH_STATE:
+          return SIZE_OF_PARAM(CAM_INTF_META_FLASH_STATE, metadata);
+        case CAM_INTF_META_HOTPIXEL_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_HOTPIXEL_MODE, metadata);
+        case CAM_INTF_META_LENS_APERTURE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_APERTURE, metadata);
+        case CAM_INTF_META_LENS_FILTERDENSITY:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_FILTERDENSITY, metadata);
+        case CAM_INTF_META_LENS_FOCAL_LENGTH:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_FOCAL_LENGTH, metadata);
+        case CAM_INTF_META_LENS_FOCUS_DISTANCE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_FOCUS_DISTANCE, metadata);
+        case CAM_INTF_META_LENS_FOCUS_RANGE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_FOCUS_RANGE, metadata);
+        case CAM_INTF_META_LENS_STATE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_STATE, metadata);
+        case CAM_INTF_META_LENS_OPT_STAB_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_OPT_STAB_MODE, metadata);
+        case CAM_INTF_META_NOISE_REDUCTION_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_NOISE_REDUCTION_MODE, metadata);
+        case CAM_INTF_META_NOISE_REDUCTION_STRENGTH:
+          return SIZE_OF_PARAM(CAM_INTF_META_NOISE_REDUCTION_STRENGTH, metadata);
+        case CAM_INTF_META_SCALER_CROP_REGION:
+          return SIZE_OF_PARAM(CAM_INTF_META_SCALER_CROP_REGION, metadata);
+        case CAM_INTF_META_SCENE_FLICKER:
+          return SIZE_OF_PARAM(CAM_INTF_META_SCENE_FLICKER, metadata);
+        case CAM_INTF_META_SENSOR_EXPOSURE_TIME:
+          return SIZE_OF_PARAM(CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata);
+        case CAM_INTF_META_SENSOR_FRAME_DURATION:
+          return SIZE_OF_PARAM(CAM_INTF_META_SENSOR_FRAME_DURATION, metadata);
+        case CAM_INTF_META_SENSOR_SENSITIVITY:
+          return SIZE_OF_PARAM(CAM_INTF_META_SENSOR_SENSITIVITY, metadata);
+        case CAM_INTF_META_SENSOR_TIMESTAMP:
+          return SIZE_OF_PARAM(CAM_INTF_META_SENSOR_TIMESTAMP, metadata);
+        case CAM_INTF_META_SHADING_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_SHADING_MODE, metadata);
+        case CAM_INTF_META_STATS_FACEDETECT_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_STATS_FACEDETECT_MODE, metadata);
+        case CAM_INTF_META_STATS_HISTOGRAM_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_STATS_HISTOGRAM_MODE, metadata);
+        case CAM_INTF_META_STATS_SHARPNESS_MAP_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_STATS_SHARPNESS_MAP_MODE, metadata);
+        case CAM_INTF_META_STATS_SHARPNESS_MAP:
+          return SIZE_OF_PARAM(CAM_INTF_META_STATS_SHARPNESS_MAP, metadata);
+        case CAM_INTF_META_TONEMAP_CURVES:
+          return SIZE_OF_PARAM(CAM_INTF_META_TONEMAP_CURVES, metadata);
+        case CAM_INTF_META_LENS_SHADING_MAP:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_SHADING_MAP, metadata);
+        case CAM_INTF_META_AEC_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_AEC_INFO, metadata);
+        case CAM_INTF_META_SENSOR_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_SENSOR_INFO, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_AE:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_AE, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_AWB:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_AWB, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_AF:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_AF, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_ASD:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_ASD, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_STATS:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_STATS, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_BESTATS:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_BESTATS, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_BHIST:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_BHIST, metadata);
+        case CAM_INTF_META_EXIF_DEBUG_3A_TUNING:
+          return SIZE_OF_PARAM(CAM_INTF_META_EXIF_DEBUG_3A_TUNING, metadata);
+        case CAM_INTF_PARM_EFFECT:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_EFFECT, metadata);
+        case CAM_INTF_META_PRIVATE_DATA:
+          return SIZE_OF_PARAM(CAM_INTF_META_PRIVATE_DATA, metadata);
+        case CAM_INTF_PARM_HAL_VERSION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_HAL_VERSION, metadata);
+        case CAM_INTF_PARM_ANTIBANDING:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ANTIBANDING, metadata);
+        case CAM_INTF_PARM_EXPOSURE_COMPENSATION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_EXPOSURE_COMPENSATION, metadata);
+        case CAM_INTF_PARM_EV_STEP:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_EV_STEP, metadata);
+        case CAM_INTF_PARM_AEC_LOCK:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_AEC_LOCK, metadata);
+        case CAM_INTF_PARM_FPS_RANGE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FPS_RANGE, metadata);
+        case CAM_INTF_PARM_AWB_LOCK:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_AWB_LOCK, metadata);
+        case CAM_INTF_PARM_BESTSHOT_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_BESTSHOT_MODE, metadata);
+        case CAM_INTF_PARM_DIS_ENABLE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_DIS_ENABLE, metadata);
+        case CAM_INTF_PARM_LED_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_LED_MODE, metadata);
+        case CAM_INTF_META_LED_MODE_OVERRIDE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LED_MODE_OVERRIDE, metadata);
+        case CAM_INTF_PARM_QUERY_FLASH4SNAP:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_QUERY_FLASH4SNAP, metadata);
+        case CAM_INTF_PARM_EXPOSURE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_EXPOSURE, metadata);
+        case CAM_INTF_PARM_SHARPNESS:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SHARPNESS, metadata);
+        case CAM_INTF_PARM_CONTRAST:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_CONTRAST, metadata);
+        case CAM_INTF_PARM_SATURATION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SATURATION, metadata);
+        case CAM_INTF_PARM_BRIGHTNESS:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_BRIGHTNESS, metadata);
+        case CAM_INTF_PARM_ISO:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ISO, metadata);
+        case CAM_INTF_PARM_EXPOSURE_TIME:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_EXPOSURE_TIME, metadata);
+        case CAM_INTF_PARM_ZOOM:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ZOOM, metadata);
+        case CAM_INTF_PARM_ROLLOFF:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ROLLOFF, metadata);
+        case CAM_INTF_PARM_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_MODE, metadata);
+        case CAM_INTF_PARM_AEC_ALGO_TYPE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_AEC_ALGO_TYPE, metadata);
+        case CAM_INTF_PARM_FOCUS_ALGO_TYPE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FOCUS_ALGO_TYPE, metadata);
+        case CAM_INTF_PARM_AEC_ROI:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_AEC_ROI, metadata);
+        case CAM_INTF_PARM_AF_ROI:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_AF_ROI, metadata);
+        case CAM_INTF_PARM_SCE_FACTOR:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SCE_FACTOR, metadata);
+        case CAM_INTF_PARM_FD:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FD, metadata);
+        case CAM_INTF_PARM_MCE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_MCE, metadata);
+        case CAM_INTF_PARM_HFR:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_HFR, metadata);
+        case CAM_INTF_PARM_REDEYE_REDUCTION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_REDEYE_REDUCTION, metadata);
+        case CAM_INTF_PARM_WAVELET_DENOISE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_WAVELET_DENOISE, metadata);
+        case CAM_INTF_PARM_TEMPORAL_DENOISE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_TEMPORAL_DENOISE, metadata);
+        case CAM_INTF_PARM_HISTOGRAM:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_HISTOGRAM, metadata);
+        case CAM_INTF_PARM_ASD_ENABLE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ASD_ENABLE, metadata);
+        case CAM_INTF_PARM_RECORDING_HINT:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_RECORDING_HINT, metadata);
+        case CAM_INTF_PARM_HDR:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_HDR, metadata);
+        case CAM_INTF_PARM_FRAMESKIP:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FRAMESKIP, metadata);
+        case CAM_INTF_PARM_ZSL_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ZSL_MODE, metadata);
+        case CAM_INTF_PARM_HDR_NEED_1X:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_HDR_NEED_1X, metadata);
+        case CAM_INTF_PARM_LOCK_CAF:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_LOCK_CAF, metadata);
+        case CAM_INTF_PARM_VIDEO_HDR:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_VIDEO_HDR, metadata);
+        case CAM_INTF_PARM_VT:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_VT, metadata);
+        case CAM_INTF_PARM_SET_AUTOFOCUSTUNING:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SET_AUTOFOCUSTUNING, metadata);
+        case CAM_INTF_PARM_SET_VFE_COMMAND:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SET_VFE_COMMAND, metadata);
+        case CAM_INTF_PARM_SET_PP_COMMAND:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SET_PP_COMMAND, metadata);
+        case CAM_INTF_PARM_MAX_DIMENSION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_MAX_DIMENSION, metadata);
+        case CAM_INTF_PARM_RAW_DIMENSION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_RAW_DIMENSION, metadata);
+        case CAM_INTF_PARM_TINTLESS:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_TINTLESS, metadata);
+        case CAM_INTF_PARM_WB_MANUAL:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_WB_MANUAL, metadata);
+        case CAM_INTF_PARM_EZTUNE_CMD:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_EZTUNE_CMD, metadata);
+        case CAM_INTF_PARM_INT_EVT:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_INT_EVT, metadata);
+        case CAM_INTF_PARM_RDI_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_RDI_MODE, metadata);
+        case CAM_INTF_PARM_CDS_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_CDS_MODE, metadata);
+        case CAM_INTF_PARM_BURST_NUM:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_BURST_NUM, metadata);
+        case CAM_INTF_PARM_RETRO_BURST_NUM:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_RETRO_BURST_NUM, metadata);
+        case CAM_INTF_PARM_BURST_LED_ON_PERIOD:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_BURST_LED_ON_PERIOD, metadata);
+        case CAM_INTF_PARM_LONGSHOT_ENABLE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_LONGSHOT_ENABLE, metadata);
+        case CAM_INTF_META_STREAM_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_STREAM_INFO, metadata);
+        case CAM_INTF_META_AEC_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_AEC_MODE, metadata);
+        case CAM_INTF_META_TOUCH_AE_RESULT:
+          return SIZE_OF_PARAM(CAM_INTF_META_TOUCH_AE_RESULT, metadata);
+        case CAM_INTF_META_AEC_PRECAPTURE_TRIGGER:
+          return SIZE_OF_PARAM(CAM_INTF_META_AEC_PRECAPTURE_TRIGGER, metadata);
+        case CAM_INTF_META_AF_TRIGGER:
+          return SIZE_OF_PARAM(CAM_INTF_META_AF_TRIGGER, metadata);
+        case CAM_INTF_META_CAPTURE_INTENT:
+          return SIZE_OF_PARAM(CAM_INTF_META_CAPTURE_INTENT, metadata);
+        case CAM_INTF_META_DEMOSAIC:
+          return SIZE_OF_PARAM(CAM_INTF_META_DEMOSAIC, metadata);
+        case CAM_INTF_META_SHARPNESS_STRENGTH:
+          return SIZE_OF_PARAM(CAM_INTF_META_SHARPNESS_STRENGTH, metadata);
+        case CAM_INTF_META_GEOMETRIC_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_GEOMETRIC_MODE, metadata);
+        case CAM_INTF_META_GEOMETRIC_STRENGTH:
+          return SIZE_OF_PARAM(CAM_INTF_META_GEOMETRIC_STRENGTH, metadata);
+        case CAM_INTF_META_LENS_SHADING_MAP_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_LENS_SHADING_MAP_MODE, metadata);
+        case CAM_INTF_META_ISP_SENSITIVITY:
+          return SIZE_OF_PARAM(CAM_INTF_META_ISP_SENSITIVITY, metadata);
+        case CAM_INTF_META_SHADING_STRENGTH:
+          return SIZE_OF_PARAM(CAM_INTF_META_SHADING_STRENGTH, metadata);
+        case CAM_INTF_META_TONEMAP_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_TONEMAP_MODE, metadata);
+        case CAM_INTF_META_AWB_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_AWB_INFO, metadata);
+        case CAM_INTF_META_FOCUS_POSITION:
+          return SIZE_OF_PARAM(CAM_INTF_META_FOCUS_POSITION, metadata);
+        case CAM_INTF_META_STREAM_ID:
+          return SIZE_OF_PARAM(CAM_INTF_META_STREAM_ID, metadata);
+        case CAM_INTF_PARM_STATS_DEBUG_MASK:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_STATS_DEBUG_MASK, metadata);
+        case CAM_INTF_PARM_STATS_AF_PAAF:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_STATS_AF_PAAF, metadata);
+        case CAM_INTF_PARM_FOCUS_BRACKETING:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FOCUS_BRACKETING, metadata);
+        case CAM_INTF_PARM_FLASH_BRACKETING:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FLASH_BRACKETING, metadata);
+        case CAM_INTF_META_JPEG_GPS_COORDINATES:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_GPS_COORDINATES, metadata);
+        case CAM_INTF_META_JPEG_GPS_PROC_METHODS:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_GPS_PROC_METHODS, metadata);
+        case CAM_INTF_META_JPEG_GPS_TIMESTAMP:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_GPS_TIMESTAMP, metadata);
+        case CAM_INTF_META_OTP_WB_GRGB:
+          return SIZE_OF_PARAM(CAM_INTF_META_OTP_WB_GRGB, metadata);
+        case CAM_INTF_META_JPEG_QUALITY:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_QUALITY, metadata);
+        case CAM_INTF_META_JPEG_THUMB_QUALITY:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_THUMB_QUALITY, metadata);
+        case CAM_INTF_META_JPEG_THUMB_SIZE:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_THUMB_SIZE, metadata);
+        case CAM_INTF_META_JPEG_ORIENTATION:
+          return SIZE_OF_PARAM(CAM_INTF_META_JPEG_ORIENTATION, metadata);
+        case CAM_INTF_META_PROFILE_TONE_CURVE:
+          return SIZE_OF_PARAM(CAM_INTF_META_PROFILE_TONE_CURVE, metadata);
+        case CAM_INTF_META_NEUTRAL_COL_POINT:
+          return SIZE_OF_PARAM(CAM_INTF_META_NEUTRAL_COL_POINT, metadata);
+        case CAM_INTF_META_SENSOR_ROLLING_SHUTTER_SKEW:
+          return SIZE_OF_PARAM(CAM_INTF_META_SENSOR_ROLLING_SHUTTER_SKEW,
+                               metadata);
+        case CAM_INTF_PARM_CAC:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_CAC, metadata);
+        case CAM_INTF_META_IMG_HYST_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_IMG_HYST_INFO, metadata);
+        case CAM_INTF_META_CAC_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_META_CAC_INFO, metadata);
+        case CAM_INTF_META_TEST_PATTERN_DATA:
+          return SIZE_OF_PARAM(CAM_INTF_META_TEST_PATTERN_DATA, metadata);
+        case CAM_INTF_PARM_UPDATE_DEBUG_LEVEL:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_UPDATE_DEBUG_LEVEL, metadata);
+        case CAM_INTF_PARM_ROTATION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ROTATION, metadata);
+        case CAM_INTF_PARM_FLIP:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_FLIP, metadata);
+        case CAM_INTF_PARM_TONE_MAP_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_TONE_MAP_MODE, metadata);
+        case CAM_INTF_META_IMGLIB:
+          return SIZE_OF_PARAM(CAM_INTF_META_IMGLIB, metadata);
+        case CAM_INTF_PARM_CAPTURE_FRAME_CONFIG:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_CAPTURE_FRAME_CONFIG, metadata);
+    #ifdef ASF_OSD
+        case CAM_INTF_META_ASF_TRIGGER_REGION:
+          return SIZE_OF_PARAM(CAM_INTF_META_ASF_TRIGGER_REGION, metadata);
+    #endif
+        case CAM_INTF_META_SNAP_CROP_INFO_SENSOR:
+          return SIZE_OF_PARAM(CAM_INTF_META_SNAP_CROP_INFO_SENSOR, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_CAMIF:
+          return SIZE_OF_PARAM(CAM_INTF_META_SNAP_CROP_INFO_CAMIF, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_ISP:
+          return SIZE_OF_PARAM(CAM_INTF_META_SNAP_CROP_INFO_ISP, metadata);
+        case CAM_INTF_META_SNAP_CROP_INFO_CPP:
+          return SIZE_OF_PARAM(CAM_INTF_META_SNAP_CROP_INFO_CPP, metadata);
+        case CAM_INTF_PARM_CUSTOM:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_CUSTOM, metadata);
+        case CAM_INTF_PARM_RELATED_SENSORS_CALIBRATION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_RELATED_SENSORS_CALIBRATION,
+                               metadata);
+        case CAM_INTF_META_AF_FOCAL_LENGTH_RATIO:
+          return SIZE_OF_PARAM(CAM_INTF_META_AF_FOCAL_LENGTH_RATIO, metadata);
+        case CAM_INTF_META_DCRF:
+          return SIZE_OF_PARAM(CAM_INTF_META_DCRF, metadata);
+        case CAM_INTF_BUF_DIVERT_INFO:
+          return SIZE_OF_PARAM(CAM_INTF_BUF_DIVERT_INFO, metadata);
+        case CAM_INTF_META_LOW_LIGHT:
+          return SIZE_OF_PARAM(CAM_INTF_META_LOW_LIGHT, metadata);
+        case CAM_INTF_META_IMG_DYN_FEAT:
+          return SIZE_OF_PARAM(CAM_INTF_META_IMG_DYN_FEAT, metadata);
+        case CAM_INTF_AF_STATE_TRANSITION:
+          return SIZE_OF_PARAM(CAM_INTF_AF_STATE_TRANSITION, metadata);
+        case CAM_INTF_PARM_DUAL_LED_CALIBRATION:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_DUAL_LED_CALIBRATION, metadata);
+        case CAM_INTF_PARM_INITIAL_EXPOSURE_INDEX:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_INITIAL_EXPOSURE_INDEX, metadata);
+        case CAM_INTF_PARM_SENSOR_HDR:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_SENSOR_HDR, metadata);
+        case CAM_INTF_PARM_INSTANT_AEC:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_INSTANT_AEC, metadata);
+        case CAM_INTF_PARM_ADV_CAPTURE_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_PARM_ADV_CAPTURE_MODE, metadata);
+        case CAM_INTF_META_VIDEO_STAB_MODE:
+          return SIZE_OF_PARAM(CAM_INTF_META_VIDEO_STAB_MODE, metadata);
+        default:
+          LOGE("parameter is not found");
+          return 0;
+        }
+        return 0;
+}
+
+
+/*===========================================================================
  * FUNCTION   : commitSetBatch
  *
  * DESCRIPTION: commit all set parameters in the batch work to backend
@@ -12214,8 +13098,19 @@
     }
 
     if (i < CAM_INTF_PARM_MAX) {
-        rc = m_pCamOpsTbl->ops->set_parms(m_pCamOpsTbl->camera_handle, m_pParamBuf);
+        rc = m_pCamOpsTbl->ops->set_parms(get_main_camera_handle(m_pCamOpsTbl->camera_handle),
+            m_pParamBuf);
     }
+
+    if (i < CAM_INTF_PARM_MAX &&
+        isDualCamera()) {
+        rc = commitSetBatchAux();
+        if (rc != NO_ERROR) {
+            LOGE("Failed to set parma for Aux camera");
+            return rc;
+        }
+    }
+
     if (rc == NO_ERROR) {
         // commit change from temp storage into param map
         rc = commitParamChanges();
@@ -12224,6 +13119,60 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : commitSetBatchAux
+ *
+ * DESCRIPTION: commit all Aux set parameters in the batch work to backend
+ *
+ * PARAMETERS : none
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::commitSetBatchAux()
+{
+    int32_t rc = NO_ERROR;
+    uint32_t i = 0;
+    void *main_param;
+    void *aux_param;
+    uint32_t param_length;
+
+    if (NULL == m_pParamBufAux || NULL == m_pParamBuf) {
+        LOGE("Params not initialized");
+        return NO_INIT;
+    }
+
+    /* Loop to check if atleast one entry is valid */
+    for (i = 0; i < CAM_INTF_PARM_MAX; i++) {
+        if(m_pParamBuf->is_valid[i] && !m_pParamBufAux->is_valid[i]) {
+            main_param = getPointerofParam((cam_intf_parm_type_t)i,
+                         m_pParamBuf);
+            aux_param = getPointerofParam((cam_intf_parm_type_t)i,
+                         m_pParamBufAux);
+            if(main_param != NULL && aux_param != NULL) {
+                param_length = getSizeofParam((cam_intf_parm_type_t)i);
+                if (param_length) {
+                    memcpy(aux_param, main_param, getSizeofParam((cam_intf_parm_type_t)i));
+                    m_pParamBufAux->is_valid[i] = 1;
+                }
+            }
+        }
+    }
+
+    if (NULL == m_pCamOpsTbl->ops) {
+        LOGE("Ops not initialized");
+        return NO_INIT;
+    }
+
+    if (i <= CAM_INTF_PARM_MAX) {
+        rc = m_pCamOpsTbl->ops->set_parms(
+                get_aux_camera_handle(m_pCamOpsTbl->camera_handle),
+                m_pParamBufAux);
+    }
+    return rc;
+}
+
+/*===========================================================================
  * FUNCTION   : commitGetBatch
  *
  * DESCRIPTION: commit all get parameters in the batch work to backend
@@ -12260,6 +13209,57 @@
     } else {
         return NO_ERROR;
     }
+
+    if (i < CAM_INTF_PARM_MAX &&
+        is_dual_camera_by_handle(m_pCamOpsTbl->camera_handle)) {
+        rc = commitGetBatchAux();
+        if (rc != NO_ERROR) {
+            LOGE("Failed to get parma for Aux camera");
+            return rc;
+        }
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : commitGetBatchAux
+ *
+ * DESCRIPTION: commit all Aux get parameters in the batch work to backend
+ *
+ * PARAMETERS : none
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::commitGetBatchAux()
+{
+    int32_t rc = NO_ERROR;
+    int32_t i = 0;
+
+    if (NULL == m_pParamBufAux) {
+        LOGE("Params not initialized");
+        return NO_INIT;
+    }
+
+    /* Loop to check if atleast one entry is valid */
+    for(i = 0; i < CAM_INTF_PARM_MAX; i++){
+        if(m_pParamBufAux->is_valid[i])
+            break;
+    }
+
+    if (NULL == m_pCamOpsTbl->ops) {
+        LOGE("Ops not initialized");
+        return NO_INIT;
+    }
+
+    if (i < CAM_INTF_PARM_MAX) {
+        return m_pCamOpsTbl->ops->get_parms(
+                get_aux_camera_handle(m_pCamOpsTbl->camera_handle),
+                m_pParamBufAux);
+    } else {
+        return NO_ERROR;
+    }
     return rc;
 }
 
@@ -12919,7 +13919,7 @@
  *==========================================================================*/
 bool QCameraParameters::sendStreamConfigInfo(cam_stream_size_info_t &stream_config_info) {
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -13293,7 +14293,7 @@
         rotation_info.device_rotation = ROTATE_0;
     }
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -13564,7 +14564,7 @@
         return NO_INIT;
     }
 
-    int32_t rc = initBatchUpdate(m_pParamBuf);
+    int32_t rc = initBatchUpdate();
     if ( rc != NO_ERROR ) {
         LOGE("Failed to initialize group update table");
         return rc;
@@ -14309,7 +15309,7 @@
     LOGH("tone map mode %d ", enable);
 
     if (initCommit) {
-        if (initBatchUpdate(m_pParamBuf) < 0) {
+        if (initBatchUpdate() < 0) {
             LOGE("Failed to initialize group update table");
             return FAILED_TRANSACTION;
         }
@@ -14371,7 +15371,7 @@
 int32_t QCameraParameters::setCDSMode(int32_t cds_mode, bool initCommit)
 {
     if (initCommit) {
-        if (initBatchUpdate(m_pParamBuf) < 0) {
+        if (initBatchUpdate() < 0) {
             LOGE("Failed to initialize group update table");
             return FAILED_TRANSACTION;
         }
@@ -14582,7 +15582,7 @@
 int32_t QCameraParameters::setInstantAEC(uint8_t value, bool initCommit)
 {
     if (initCommit) {
-        if (initBatchUpdate(m_pParamBuf) < 0) {
+        if (initBatchUpdate() < 0) {
             LOGE("Failed to initialize group update table");
             return FAILED_TRANSACTION;
         }
@@ -14672,7 +15672,7 @@
     int32_t rc = NO_ERROR;
     cam_dimension_t meta_stream_size;
 
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -14714,7 +15714,7 @@
 bool QCameraParameters::sendStreamConfigForPickRes
     (cam_stream_size_info_t &stream_config_info) {
     int32_t rc = NO_ERROR;
-    if(initBatchUpdate(m_pParamBuf) < 0 ) {
+    if(initBatchUpdate() < 0 ) {
         LOGE("Failed to initialize group update table");
         return BAD_TYPE;
     }
@@ -14772,4 +15772,115 @@
     return rc;
 }
 
+/*===========================================================================
+ * FUNCTION   : SetAuxParameter
+ *
+ * DESCRIPTION: set AUX parameter
+ *
+ * PARAMETERS : cam_intf_parm_type_t paramType
+ *              void *paramValue
+ *              uint32_t paramLength
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::setAUXParameter(cam_intf_parm_type_t paramType,
+        void *paramValue, uint32_t paramLength)
+{
+    void *auxparam = NULL;
+
+    if (paramValue == NULL) {
+        LOGE("paramValue is NULL.");
+        return BAD_VALUE;
+    }
+    LOGD("Param type %d", paramType);
+
+    if (paramLength > getSizeofParam(paramType)) {
+      LOGE("size is greater for param ", paramType);
+      return BAD_VALUE;
+    }
+
+    auxparam = getPointerofParam(paramType, m_pParamBufAux);
+    if(auxparam != NULL){
+      memcpy(auxparam, paramValue, paramLength);
+      m_pParamBufAux->is_valid[paramType] = 1;
+    }
+    return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION   : SetDualCamera
+ *
+ * DESCRIPTION: set Dual Camera
+ *
+ * PARAMETERS : bool dual camera value
+ *
+ * RETURN     : NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::SetDualCamera(bool value)
+{
+    LOGD("value = %d", value);
+    m_bDualCamera = value;
+    return NO_ERROR;
+}
+
+/*===========================================================================
+ * FUNCTION   : setCameraControls
+ *
+ * DESCRIPTION: activate or deactive camera's
+ *
+ * PARAMETERS : bool dual camera value
+ *
+ * RETURN     : NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraParameters::setCameraControls(int32_t controls, bool initCommit)
+{
+    int32_t rc = NO_ERROR;
+    int32_t cameraControl[MM_CAMERA_MAX_CAM_CNT] = {0};
+
+    if (initCommit) {
+        if (initBatchUpdate() < 0) {
+            LOGE("Failed to initialize group update table");
+            return FAILED_TRANSACTION;
+        }
+    }
+
+    if (controls & MM_CAMERA_TYPE_MAIN) {
+        cameraControl[0] = 1;
+    } else {
+        cameraControl[0] = 0;
+    }
+    if (controls & MM_CAMERA_TYPE_AUX) {
+        cameraControl[1] = 1;
+    } else {
+        cameraControl[1] = 0;
+    }
+    if (ADD_SET_PARAM_ENTRY_TO_BATCH(m_pParamBuf, CAM_INTF_PARM_SUSPEND_RESUME_CAMERAS,
+            *cameraControl)) {
+        LOGE("Failed to instant aec value");
+        return BAD_VALUE;
+    }
+
+    if (initCommit) {
+        rc = commitSetBatch();
+        if (NO_ERROR != rc) {
+            LOGE("Failed to instant aec value");
+            return rc;
+        }
+    }
+
+#ifdef DUAL_CAM_TEST //Temporary macro. Added to simulate B+B snapshot. Will be removed
+    if (controls == MM_CAMERA_DUAL_CAM) {
+        set(KEY_QC_NUM_SNAPSHOT_PER_SHUTTER, 2);
+    } else {
+        set(KEY_QC_NUM_SNAPSHOT_PER_SHUTTER, 1);
+    }
+#endif
+
+    return NO_ERROR;
+}
+
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraParameters.h b/msmcobalt/QCamera2/HAL/QCameraParameters.h
index 615be12..f873f51 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParameters.h
+++ b/msmcobalt/QCamera2/HAL/QCameraParameters.h
@@ -621,7 +621,7 @@
     QCameraParameters(const String8 &params);
     ~QCameraParameters();
 
-    int32_t allocate();
+    int32_t allocate(uint8_t bufCount);
     int32_t init(cam_capability_t *,
                  mm_camera_vtbl_t *,
                  QCameraAdjustFPS *);
@@ -714,6 +714,7 @@
     bool isAutoHDREnabled();
     int32_t stopAEBracket();
     int32_t updateRAW(cam_dimension_t max_dim);
+    bool isAVTimerEnabled();
     bool isDISEnabled();
     int32_t setISType();
     cam_is_type_t getVideoISType();
@@ -878,6 +879,9 @@
     bool sendStreamConfigForPickRes(cam_stream_size_info_t &stream_config_info);
     int32_t updateDtVc(int32_t *dt, int32_t *vc);
 
+    int32_t SetDualCamera(bool value);
+    bool isDualCamera() {return m_bDualCamera;};
+    int32_t setCameraControls(int32_t controls, bool initCommit= true);
 private:
     int32_t setPreviewSize(const QCameraParameters& );
     int32_t setVideoSize(const QCameraParameters& );
@@ -1041,7 +1045,6 @@
     bool isTNRPreviewEnabled() {return m_bTNRPreviewOn;};
     bool isTNRVideoEnabled() {return m_bTNRVideoOn;};
     bool getFaceDetectionOption() { return  m_bFaceDetectionOn;}
-    bool isAVTimerEnabled();
     void getLiveSnapshotSize(cam_dimension_t &dim);
     int32_t getRawSize(cam_dimension_t &dim) {dim = m_rawSize; return NO_ERROR;};
     int getAutoFlickerMode();
@@ -1071,9 +1074,17 @@
     int32_t setAdvancedCaptureMode();
 
     // ops for batch set/get params with server
-    int32_t initBatchUpdate(parm_buffer_t *p_table);
+    int32_t initBatchUpdate();
     int32_t commitSetBatch();
     int32_t commitGetBatch();
+    int32_t commitSetBatchAux();
+    int32_t commitGetBatchAux();
+
+    void * getPointerofParam(cam_intf_parm_type_t meta_id,
+            metadata_buffer_t* metadata);
+    uint32_t getSizeofParam(cam_intf_parm_type_t param_id);
+    int32_t setAUXParameter(cam_intf_parm_type_t paramType,
+            void *paramValue, uint32_t paramLength);
 
     // ops to tempororily update parameter entries and commit
     int32_t updateParamEntry(const char *key, const char *value);
@@ -1122,6 +1133,7 @@
     mm_camera_vtbl_t *m_pCamOpsTbl;
     QCameraHeapMemory *m_pParamHeap;
     parm_buffer_t     *m_pParamBuf;  // ptr to param buf in m_pParamHeap
+    parm_buffer_t     *m_pParamBufAux;  // ptr to Aux param buf in m_pParamHeap
     /* heap for mapping dual cam event info */
     QCameraHeapMemory *m_pRelCamSyncHeap;
     /* ptr to sync buffer in m_pRelCamSyncHeap */
@@ -1239,6 +1251,7 @@
     // Number of preview frames, that HAL will hold without displaying, for instant AEC mode.
     uint8_t mAecSkipDisplayFrameBound;
     bool m_bQuadraCfa;
+    bool m_bDualCamera;
 };
 
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp
index d1b2cfb..992cdf2 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.cpp
@@ -62,7 +62,7 @@
 }
 
 
-int32_t QCameraParametersIntf::allocate()
+int32_t QCameraParametersIntf::allocate(uint8_t bufCount)
 {
     Mutex::Autolock lock(mLock);
     mImpl = new QCameraParameters();
@@ -71,7 +71,7 @@
         return NO_MEMORY;
     }
 
-    return mImpl->allocate();
+    return mImpl->allocate(bufCount);
 }
 
 int32_t QCameraParametersIntf::init(cam_capability_t *capabilities,
@@ -590,6 +590,13 @@
     return mImpl->isDISEnabled();
 }
 
+bool QCameraParametersIntf::isAVTimerEnabled()
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->isAVTimerEnabled();
+}
+
 int32_t QCameraParametersIntf::setISType()
 {
     Mutex::Autolock lock(mLock);
@@ -1441,4 +1448,18 @@
     return mImpl->updateDtVc(dt, vc);
 }
 
+int32_t QCameraParametersIntf::SetDualCamera(bool value)
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->SetDualCamera(value);
+}
+
+int32_t QCameraParametersIntf::setCameraControls(int32_t controls, bool initCommit)
+{
+    Mutex::Autolock lock(mLock);
+    CHECK_PARAM_INTF(mImpl);
+    return mImpl->setCameraControls(controls, initCommit);
+}
+
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h
index e4576e3..9efa263 100644
--- a/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h
+++ b/msmcobalt/QCamera2/HAL/QCameraParametersIntf.h
@@ -66,7 +66,7 @@
     QCameraParametersIntf();
     ~QCameraParametersIntf();
 
-    int32_t allocate();
+    int32_t allocate(uint8_t bufCount = 1);
     int32_t init(cam_capability_t *capabilities,
                  mm_camera_vtbl_t *mmOps,
                  QCameraAdjustFPS *adjustFPS);
@@ -160,6 +160,7 @@
     int32_t stopAEBracket();
     int32_t updateRAW(cam_dimension_t max_dim);
     bool isDISEnabled();
+    bool isAVTimerEnabled();
     int32_t setISType();
     cam_is_type_t getVideoISType();
     cam_is_type_t getPreviewISType();
@@ -307,6 +308,8 @@
         cam_feature_mask_t featureMask,
         cam_analysis_info_t *pAnalysisInfo);
     int32_t updateDtVc(int32_t *dt, int32_t *vc);
+    int32_t SetDualCamera(bool value);
+    int32_t setCameraControls(int32_t controls, bool initCommit = true);
 
 private:
     QCameraParameters *mImpl;
diff --git a/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp b/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp
index 8c8cef4..1119c42 100644
--- a/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraPostProc.cpp
@@ -1309,7 +1309,7 @@
     if (pChannel == NULL) {
         for (int8_t i = 0; i < mPPChannelCount; i++) {
             if ((mPPChannels[i] != NULL) &&
-                    (mPPChannels[i]->getMyHandle() == frame->ch_id)) {
+                    (validate_handle(mPPChannels[i]->getMyHandle(), frame->ch_id))) {
                 pChannel = mPPChannels[i];
                 break;
             }
@@ -1650,7 +1650,8 @@
         if ( NULL == pChannel ) {
             for (int8_t i = 0; i < mPPChannelCount; i++) {
                 if ((mPPChannels[i] != NULL) &&
-                        (mPPChannels[i]->getMyHandle() == super_buf->ch_id)) {
+                        (validate_handle(mPPChannels[i]->getMyHandle(),
+                         super_buf->ch_id))) {
                     pChannel = mPPChannels[i];
                     break;
                 }
@@ -1687,7 +1688,8 @@
         if (pChannel == NULL) {
             for (int8_t i = 0; i < mPPChannelCount; i++) {
                 if ((mPPChannels[i] != NULL) &&
-                        (mPPChannels[i]->getMyHandle() == super_buf->ch_id)) {
+                        (validate_handle(mPPChannels[i]->getMyHandle(),
+                        super_buf->ch_id))) {
                     pChannel = mPPChannels[i];
                     break;
                 }
@@ -1925,7 +1927,7 @@
     if (pChannel == NULL) {
         for (int8_t i = 0; i < mPPChannelCount; i++) {
             if ((mPPChannels[i] != NULL) &&
-                    (mPPChannels[i]->getMyHandle() == frame->ch_id)) {
+                    validate_handle(mPPChannels[i]->getMyHandle(), frame->ch_id)) {
                 pChannel = mPPChannels[i];
                 break;
             }
@@ -2100,7 +2102,7 @@
     if (pChannel == NULL) {
         for (int8_t i = 0; i < mPPChannelCount; i++) {
             if ((mPPChannels[i] != NULL) &&
-                    (mPPChannels[i]->getMyHandle() == recvd_frame->ch_id)) {
+                    (validate_handle(mPPChannels[i]->getMyHandle(), recvd_frame->ch_id))) {
                 pChannel = mPPChannels[i];
                 break;
             }
@@ -2143,7 +2145,7 @@
 
     // dump snapshot frame if enabled
     m_parent->dumpFrameToFile(main_stream, main_frame,
-            QCAMERA_DUMP_FRM_SNAPSHOT, (char *)"CPP");
+            QCAMERA_DUMP_FRM_INPUT_JPEG, (char *)"CPP");
 
     // send upperlayer callback for raw image
     camera_memory_t *mem = memObj->getMemory(main_frame->buf_idx, false);
@@ -2565,7 +2567,7 @@
     if (pChannel == NULL) {
         for (int8_t i = 0; i < mPPChannelCount; i++) {
             if ((mPPChannels[i] != NULL) &&
-                    (mPPChannels[i]->getMyHandle() == recvd_frame->ch_id)) {
+                    (validate_handle(mPPChannels[i]->getMyHandle(), recvd_frame->ch_id))) {
                 pChannel = mPPChannels[i];
                 break;
             }
@@ -2624,7 +2626,7 @@
         if (frame->stream_type == CAM_STREAM_TYPE_SNAPSHOT ||
             pStream->isOrignalTypeOf(CAM_STREAM_TYPE_SNAPSHOT)) {
             // for YUV422 NV16 case
-            m_parent->dumpFrameToFile(pStream, frame, QCAMERA_DUMP_FRM_SNAPSHOT);
+            m_parent->dumpFrameToFile(pStream, frame, QCAMERA_DUMP_FRM_INPUT_JPEG);
         } else {
             //Received RAW snapshot taken notification
             m_parent->dumpFrameToFile(pStream, frame, QCAMERA_DUMP_FRM_RAW);
@@ -3125,11 +3127,12 @@
         // Reduces the latency for normal snapshot.
         syncStreamParams(src_frame, src_reproc_frame);
     }
+
     if (mPPChannels[mCurChannelIdx] != NULL) {
         // add into ongoing PP job Q
         ppreq_job->reprocCount = (int8_t) (mCurReprocCount + 1);
 
-        if ((m_parent->isRegularCapture()) || (ppreq_job->offline_buffer)) {
+        if ((m_parent->needOfflineReprocessing()) || (ppreq_job->offline_buffer)) {
             m_bufCountPPQ++;
             if (m_ongoingPPQ.enqueue((void *)ppreq_job)) {
                 pthread_mutex_lock(&m_reprocess_lock);
@@ -3245,7 +3248,6 @@
                         QCAMERA_SM_EVT_STOP_CAPTURE_CHANNEL,
                         NULL);
      }
-
      return rc;
 }
 
@@ -3293,7 +3295,7 @@
     if (pChannel == NULL) {
         for (int8_t i = 0; i < mPPChannelCount; i++) {
             if ((mPPChannels[i] != NULL) &&
-                    (mPPChannels[i]->getMyHandle() == recvd_frame->ch_id)) {
+                    (validate_handle(mPPChannels[i]->getMyHandle(), recvd_frame->ch_id))) {
                 pChannel = mPPChannels[i];
                 break;
             }
diff --git a/msmcobalt/QCamera2/HAL/QCameraStateMachine.cpp b/msmcobalt/QCamera2/HAL/QCameraStateMachine.cpp
index 424307b..e91b840 100644
--- a/msmcobalt/QCamera2/HAL/QCameraStateMachine.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraStateMachine.cpp
@@ -1636,6 +1636,9 @@
             case QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE:
                 rc = m_parent->processZSLCaptureDone();
                 break;
+            case QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL:
+                rc = m_parent->processDCFOVControl();
+                break;
             default:
                 LOGE("Invalid internal event %d in state(%d)",
                              internal_evt->evt_type, m_state);
@@ -1821,6 +1824,9 @@
             case QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE:
                 rc = m_parent->processZSLCaptureDone();
                 break;
+            case QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL:
+                rc = m_parent->processDCFOVControl();
+                break;
             default:
                 LOGE("Invalid internal event %d in state(%d)",
                              internal_evt->evt_type, m_state);
@@ -2218,6 +2224,9 @@
             case QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE:
                 rc = m_parent->processZSLCaptureDone();
                 break;
+            case QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL:
+                rc = m_parent->processDCFOVControl();
+                break;
             default:
                 break;
             }
@@ -2692,6 +2701,9 @@
             case QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE:
                 rc = m_parent->processZSLCaptureDone();
                 break;
+            case QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL:
+                rc = m_parent->processDCFOVControl();
+                break;
             default:
                 break;
             }
@@ -3072,6 +3084,9 @@
             case QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE:
                 rc = m_parent->processZSLCaptureDone();
                 break;
+            case QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL:
+                rc = m_parent->processDCFOVControl();
+                break;
             default:
                 break;
             }
@@ -3581,6 +3596,9 @@
             case QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE:
                 rc = m_parent->processZSLCaptureDone();
                 break;
+            case QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL:
+                rc = m_parent->processDCFOVControl();
+                break;
             default:
                 break;
             }
diff --git a/msmcobalt/QCamera2/HAL/QCameraStateMachine.h b/msmcobalt/QCamera2/HAL/QCameraStateMachine.h
index b02ba06..4c99f50 100644
--- a/msmcobalt/QCamera2/HAL/QCameraStateMachine.h
+++ b/msmcobalt/QCamera2/HAL/QCameraStateMachine.h
@@ -163,6 +163,7 @@
     QCAMERA_INTERNAL_EVT_HDR_UPDATE,         // HDR scene update
     QCAMERA_INTERNAL_EVT_RETRO_AEC_UNLOCK,   // retro burst AEC unlock event
     QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE,   // ZSL capture done event
+    QCAMERA_INTERNAL_EVT_DUAL_CAMERA_FOV_CONTROL,   // FOV Control event
     QCAMERA_INTERNAL_EVT_MAX
 } qcamera_internal_evt_type_t;
 
diff --git a/msmcobalt/QCamera2/HAL/QCameraStream.cpp b/msmcobalt/QCamera2/HAL/QCameraStream.cpp
index efc02b9..ad8a945 100644
--- a/msmcobalt/QCamera2/HAL/QCameraStream.cpp
+++ b/msmcobalt/QCamera2/HAL/QCameraStream.cpp
@@ -314,6 +314,7 @@
         mCamHandle(camHandle),
         mChannelHandle(chId),
         mHandle(0),
+        mActiveHandle(0),
         mCamOps(camOps),
         mStreamInfo(NULL),
         mNumBufs(0),
@@ -342,6 +343,7 @@
         mMapTaskId(0),
         mSyncCBEnabled(false)
 {
+    mDualStream = is_dual_camera_by_handle(chId);
     mMemVtbl.user_data = this;
     if ( !deffered ) {
         mMemVtbl.get_bufs = get_bufs;
@@ -414,9 +416,11 @@
     if (mHandle > 0) {
         mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
         mHandle = 0;
+        mActiveHandle = 0;
     }
     pthread_mutex_destroy(&m_lock);
     pthread_cond_destroy(&m_cond);
+    mDualStream = 0;
 }
 
 /*===========================================================================
@@ -583,8 +587,9 @@
 {
     int32_t rc = NO_ERROR;
     uint32_t i = 0;
-
+    uint32_t activeHandle = mHandle;
     QCameraBufferMaps bufferMaps;
+
     for (i = 0; i < Buf->getCnt(); i++) {
         ssize_t bufSize = Buf->getSize(i);
         if (BAD_INDEX == bufSize) {
@@ -592,7 +597,15 @@
             return BAD_INDEX;
         }
 
-        rc = bufferMaps.enqueue(bufType, mHandle, i /*buf index*/, -1 /*plane index*/,
+        if ((bufType == CAM_MAPPING_BUF_TYPE_STREAM_INFO)
+                || (bufType == CAM_MAPPING_BUF_TYPE_MISC_BUF)) {
+            if (i > 0 && isDualStream()) {
+                activeHandle = get_aux_camera_handle(mHandle);
+            } else {
+                activeHandle = get_main_camera_handle(mHandle);
+            }
+        }
+        rc = bufferMaps.enqueue(bufType, activeHandle, i /*buf index*/, -1 /*plane index*/,
                 0 /*cookie*/, Buf->getFd(i), bufSize, Buf->getPtr(i));
 
         if (rc < 0) {
@@ -679,7 +692,6 @@
  *==========================================================================*/
 int32_t QCameraStream::init(QCameraHeapMemory *streamInfoBuf,
         QCameraHeapMemory *miscBuf,
-        uint8_t minNumBuffers,
         stream_cb_routine stream_cb,
         void *userdata,
         bool bDynallocBuf)
@@ -689,7 +701,7 @@
     // assign and map stream info memory
     mStreamInfoBuf = streamInfoBuf;
     mStreamInfo = reinterpret_cast<cam_stream_info_t *>(mStreamInfoBuf->getPtr(0));
-    mNumBufs = minNumBuffers;
+    mNumBufs = mStreamInfo->num_bufs;
     mDynBufAlloc = bDynallocBuf;
 
     // Calculate buffer size for deffered allocation
@@ -716,6 +728,14 @@
         rc = UNKNOWN_ERROR;
         goto done;
     }
+    mActiveHandle = mHandle;
+    mActiveCamera = MM_CAMERA_TYPE_MAIN;
+    if (isDualStream()) {
+        mActiveCamera |= MM_CAMERA_TYPE_AUX;
+        if (needFrameSync()) {
+            mCamOps->start_stream_frame_sync(mCamHandle, mChannelHandle, mHandle);
+        }
+    }
 
     rc = mapBufs(mStreamInfoBuf, CAM_MAPPING_BUF_TYPE_STREAM_INFO, NULL);
     if (rc < 0) {
@@ -757,6 +777,7 @@
 err1:
     mCamOps->delete_stream(mCamHandle, mChannelHandle, mHandle);
     mHandle = 0;
+    mActiveHandle = 0;
 done:
     return rc;
 }
@@ -998,7 +1019,7 @@
         if (!m_bActive) {
             LOGW("Stream thread is not active, no ops here %d", getMyType());
         } else {
-            bufDone(frame->bufs[0]->buf_idx);
+            bufDone(frame);
         }
         free(frame);
         return NO_ERROR;
@@ -1023,9 +1044,10 @@
     LOGD("\n");
     QCameraStream* stream = (QCameraStream *)userdata;
     if (stream == NULL ||
-        recvd_frame == NULL ||
-        recvd_frame->bufs[0] == NULL ||
-        recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
+            recvd_frame == NULL ||
+            recvd_frame->bufs[0] == NULL ||
+            !validate_handle(stream->getMyHandle(),
+            recvd_frame->bufs[0]->stream_id)) {
         LOGE("Not a valid stream to handle buf");
         return;
     }
@@ -1034,7 +1056,6 @@
     return;
 }
 
-
 /*===========================================================================
  * FUNCTION   : dataNotifyCB
  *
@@ -1053,9 +1074,10 @@
     LOGD("\n");
     QCameraStream* stream = (QCameraStream *)userdata;
     if (stream == NULL ||
-        recvd_frame == NULL ||
-        recvd_frame->bufs[0] == NULL ||
-        recvd_frame->bufs[0]->stream_id != stream->getMyHandle()) {
+            recvd_frame == NULL ||
+            recvd_frame->bufs[0] == NULL  ||
+            !(validate_handle(stream->getMyHandle(),
+            recvd_frame->bufs[0]->stream_id))) {
         LOGE("Not a valid stream to handle buf");
         return;
     }
@@ -1064,7 +1086,7 @@
         (mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
     if (frame == NULL) {
         LOGE("No mem for mm_camera_buf_def_t");
-        stream->bufDone(recvd_frame->bufs[0]->buf_idx);
+        stream->bufDone(recvd_frame);
         return;
     }
     *frame = *recvd_frame;
@@ -1114,7 +1136,7 @@
                         pme->mDataCB(frame, pme, pme->mUserData);
                     } else {
                         // no data cb routine, return buf here
-                        pme->bufDone(frame->bufs[0]->buf_idx);
+                        pme->bufDone(frame);
                         free(frame);
                     }
                 }
@@ -1164,6 +1186,29 @@
 /*===========================================================================
  * FUNCTION   : bufDone
  *
+ * DESCRIPTION: return a stream buf back to kernel
+ *
+ * PARAMETERS :
+ *   @super_buf : stream buf frame to be returned
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::bufDone (mm_camera_super_buf_t *super_buf)
+{
+    int32_t rc = NO_ERROR;
+    for (uint32_t i = 0; i < super_buf->num_bufs; i++) {
+        if (super_buf->bufs[i] != NULL) {
+            rc |= bufDone(super_buf->bufs[i]->buf_idx);
+        }
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : bufDone
+ *
  * DESCRIPTION: return stream buffer to kernel
  *
  * PARAMETERS :
@@ -2681,4 +2726,155 @@
     return UNKNOWN_ERROR;
 }
 
+/*===========================================================================
+ * FUNCTION   : processCameraControl
+ *
+ * DESCRIPTION: Suspend and resume camera
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::processCameraControl(uint32_t camState)
+{
+    int32_t ret = NO_ERROR;
+
+    if (ret == NO_ERROR) {
+        if (camState == MM_CAMERA_TYPE_MAIN) {
+            mActiveHandle = get_main_camera_handle(mHandle);
+        } else if (camState == MM_CAMERA_TYPE_AUX) {
+            mActiveHandle = get_aux_camera_handle(mHandle);
+        }
+        mActiveCamera = camState;
+    }
+    return ret;
+}
+
+/*===========================================================================
+ * FUNCTION   : switchStreamCb
+ *
+ * DESCRIPTION: switch stream's in case of dual camera
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::switchStreamCb()
+{
+    int32_t ret = NO_ERROR;
+
+    if ((getMyType() != CAM_STREAM_TYPE_SNAPSHOT)
+            && (mActiveCamera == MM_CAMERA_DUAL_CAM)) {
+        ret = mCamOps->switch_stream_callback(mCamHandle, mChannelHandle, mHandle);
+    }
+
+    if (get_aux_camera_handle(mHandle)
+            == mActiveHandle) {
+        mActiveHandle = get_main_camera_handle(mHandle);
+    } else if (get_main_camera_handle(mHandle)
+            == mActiveHandle) {
+        mActiveHandle = get_aux_camera_handle(mHandle);
+    } else {
+        mActiveHandle = mHandle;
+    }
+    return ret;
+}
+
+/*===========================================================================
+ * FUNCTION   : needFrameSync
+ *
+ * DESCRIPTION: Function to enable stream frame buffer sync
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+bool QCameraStream::needFrameSync()
+{
+    if (!isDualStream()) {
+        return false;
+    }
+
+    switch (getMyType()) {
+    case CAM_STREAM_TYPE_METADATA:
+        return true;
+        break;
+    default:
+        return false;
+        break;
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : setBundleInfo
+ *
+ * DESCRIPTION: set bundle for this stream to MCT
+ *
+ * PARAMETERS :
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *==========================================================================*/
+int32_t QCameraStream::setBundleInfo()
+{
+    int32_t ret = NO_ERROR;
+    cam_bundle_config_t bundleInfo;
+
+    if ((isTypeOf(CAM_STREAM_TYPE_METADATA))
+            || (isTypeOf(CAM_STREAM_TYPE_OFFLINE_PROC))) {
+        // Skip metadata for reprocess now because PP module cannot handle meta data
+        // May need furthur discussion if Imaginglib need meta data
+        return ret;
+    }
+
+    cam_stream_parm_buffer_t param, aux_param;
+    uint32_t active_handle = get_main_camera_handle(mChannelHandle);
+    memset(&bundleInfo, 0, sizeof(bundleInfo));
+    if (active_handle) {
+        ret = mCamOps->get_bundle_info(mCamHandle, active_handle,
+                &bundleInfo);
+        memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
+        param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
+        param.bundleInfo = bundleInfo;
+    }
+
+    if (isDualStream()) {
+        active_handle = get_aux_camera_handle(mChannelHandle);
+        memset(&bundleInfo, 0, sizeof(bundleInfo));
+        ret = mCamOps->get_bundle_info(mCamHandle, active_handle,
+                &bundleInfo);
+        memset(&aux_param, 0, sizeof(cam_stream_parm_buffer_t));
+        aux_param.type = CAM_STREAM_PARAM_TYPE_SET_BUNDLE_INFO;
+        aux_param.bundleInfo = bundleInfo;
+    }
+    pthread_mutex_lock(&mParameterLock);
+    mStreamInfo->parm_buf = param;
+    if ((aux_param.bundleInfo.num_of_streams > 1)
+            && (mStreamInfo->aux_str_info != NULL)) {
+        mStreamInfo->aux_str_info->parm_buf = aux_param;
+    }
+
+    if ((mStreamInfo->parm_buf.bundleInfo.num_of_streams > 1)
+            || (((mStreamInfo->aux_str_info != NULL) &&
+            (mStreamInfo->aux_str_info->parm_buf.bundleInfo.num_of_streams > 1)))) {
+        ret = mCamOps->set_stream_parms(mCamHandle,
+                mChannelHandle, mHandle,
+                &mStreamInfo->parm_buf);
+    }
+    pthread_mutex_unlock(&mParameterLock);
+    if (ret != NO_ERROR) {
+        LOGE("stream setParameter for set bundle failed");
+        return ret;
+    }
+    return ret;
+}
+
+
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL/QCameraStream.h b/msmcobalt/QCamera2/HAL/QCameraStream.h
index 4200f5d..ed7b1d1 100644
--- a/msmcobalt/QCamera2/HAL/QCameraStream.h
+++ b/msmcobalt/QCamera2/HAL/QCameraStream.h
@@ -61,7 +61,6 @@
     virtual ~QCameraStream();
     virtual int32_t init(QCameraHeapMemory *streamInfoBuf,
             QCameraHeapMemory *miscBuf,
-            uint8_t minStreamBufNum,
             stream_cb_routine stream_cb,
             void *userdata,
             bool bDynallocBuf);
@@ -69,6 +68,7 @@
                                     cam_crop_data_t &crop_info);
     virtual int32_t bufDone(uint32_t index);
     virtual int32_t bufDone(const void *opaque, bool isMetaData);
+    virtual int32_t bufDone(mm_camera_super_buf_t *super_buf);
     virtual int32_t processDataNotify(mm_camera_super_buf_t *bufs);
     virtual int32_t start();
     virtual int32_t stop();
@@ -131,6 +131,11 @@
     void cond_signal(bool forceExit = false);
 
     int32_t setSyncDataCB(stream_cb_routine data_cb);
+    int32_t setBundleInfo();
+    int32_t switchStreamCb();
+    int32_t processCameraControl(uint32_t camState);
+    bool isDualStream(){return mDualStream;};
+    bool needFrameSync();
     //Stream time stamp. We need this for preview stream to update display
     nsecs_t mStreamTimestamp;
 
@@ -153,6 +158,8 @@
     uint32_t mCamHandle;
     uint32_t mChannelHandle;
     uint32_t mHandle; // stream handle from mm-camera-interface
+    uint32_t mActiveHandle;
+    uint32_t mActiveCamera;
     mm_camera_ops_t *mCamOps;
     cam_stream_info_t *mStreamInfo; // ptr to stream info buf
     mm_camera_stream_mem_vtbl_t mMemVtbl;
@@ -263,8 +270,8 @@
     uint32_t mAllocTaskId;
     BackgroundTask mMapTask;
     uint32_t mMapTaskId;
-
     bool mSyncCBEnabled;
+    bool mDualStream;
 };
 
 }; // namespace qcamera
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp b/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp
index 3fa72a3..1b02b86 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3Channel.cpp
@@ -516,7 +516,7 @@
             mDumpSkipCnt = 1;
         }
         if (mDumpSkipCnt % mSkipMode == 0) {
-            if (mDumpFrmCnt <= mFrmNum) {
+            if (mDumpFrmCnt < mFrmNum) {
                 /* Note that the image dimension will be the unrotated stream dimension.
                 * If you feel that the image would have been rotated during reprocess
                 * then swap the dimensions while opening the file
@@ -530,7 +530,7 @@
                         snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"v_%d_%d_%dx%d.yuv",
                             counter, frame->frame_idx, dim.width, dim.height);
                     break;
-                    case QCAMERA_DUMP_FRM_SNAPSHOT:
+                    case QCAMERA_DUMP_FRM_INPUT_JPEG:
                         snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"s_%d_%d_%dx%d.yuv",
                             counter, frame->frame_idx, dim.width, dim.height);
                     break;
@@ -542,6 +542,10 @@
                         snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"c_%d_%d_%dx%d.yuv",
                             counter, frame->frame_idx, dim.width, dim.height);
                     break;
+                    case QCAMERA_DUMP_FRM_OUTPUT_JPEG:
+                        snprintf(buf, sizeof(buf), QCAMERA_DUMP_FRM_LOCATION"j_%d_%d_%dx%d.jpg",
+                            counter, frame->frame_idx, dim.width, dim.height);
+                    break;
                     default :
                         LOGE("dumping not enabled for stream type %d",dump_type);
                     break;
@@ -552,16 +556,21 @@
                 if (file_fd >= 0) {
                     void *data = NULL;
                     fchmod(file_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-                    for (uint32_t i = 0; i < offset.num_planes; i++) {
-                        uint32_t index = offset.mp[i].offset;
-                        if (i > 0) {
-                            index += offset.mp[i-1].len;
-                        }
-                        for (int j = 0; j < offset.mp[i].height; j++) {
-                            data = (void *)((uint8_t *)frame->buffer + index);
-                            written_len += write(file_fd, data,
-                                    (size_t)offset.mp[i].width);
-                            index += (uint32_t)offset.mp[i].stride;
+                    if( dump_type == QCAMERA_DUMP_FRM_OUTPUT_JPEG ) {
+                        written_len = write(file_fd, frame->buffer, frame->frame_len);
+                    }
+                    else {
+                        for (uint32_t i = 0; i < offset.num_planes; i++) {
+                            uint32_t index = offset.mp[i].offset;
+                            if (i > 0) {
+                                index += offset.mp[i-1].len;
+                            }
+                            for (int j = 0; j < offset.mp[i].height; j++) {
+                                data = (void *)((uint8_t *)frame->buffer + index);
+                                written_len += write(file_fd, data,
+                                        (size_t)offset.mp[i].width);
+                                index += (uint32_t)offset.mp[i].stride;
+                            }
                         }
                     }
                     LOGH("written number of bytes %ld\n", written_len);
@@ -623,7 +632,8 @@
  ** RETURN    : format for stream type
  *
  *==========================================================================*/
-cam_format_t QCamera3Channel::getStreamDefaultFormat(cam_stream_type_t type)
+cam_format_t QCamera3Channel::getStreamDefaultFormat(cam_stream_type_t type,
+        uint32_t width, uint32_t height)
 {
     cam_format_t streamFormat;
 
@@ -649,7 +659,10 @@
         }
         break;
     case CAM_STREAM_TYPE_VIDEO:
-        if (isUBWCEnabled()) {
+    {
+        /* Disable UBWC for smaller video resolutions due to CPP downscale
+            limits. Refer cpp_hw_params.h::CPP_DOWNSCALE_LIMIT_UBWC */
+        if (isUBWCEnabled() && (width >= 640) && (height >= 480)) {
             char prop[PROPERTY_VALUE_MAX];
             int pFormat;
             memset(prop, 0, sizeof(prop));
@@ -668,6 +681,7 @@
 #endif
         }
         break;
+    }
     case CAM_STREAM_TYPE_SNAPSHOT:
         streamFormat = CAM_FORMAT_YUV_420_NV21;
         break;
@@ -1350,24 +1364,29 @@
         case HAL_PIXEL_FORMAT_YCbCr_420_888:
             if(stream->stream_type == CAMERA3_STREAM_INPUT){
                 streamType = CAM_STREAM_TYPE_SNAPSHOT;
-                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_SNAPSHOT);
+                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_SNAPSHOT,
+                        stream->width, stream->height);
             } else {
                 streamType = CAM_STREAM_TYPE_CALLBACK;
-                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_CALLBACK);
+                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_CALLBACK,
+                        stream->width, stream->height);
             }
             break;
         case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
             if (stream->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                 streamType = CAM_STREAM_TYPE_VIDEO;
-                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_VIDEO);
+                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_VIDEO,
+                        stream->width, stream->height);
             } else if(stream->stream_type == CAMERA3_STREAM_INPUT ||
                     stream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL ||
                     IS_USAGE_ZSL(stream->usage)){
                 streamType = CAM_STREAM_TYPE_SNAPSHOT;
-                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_SNAPSHOT);
+                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_SNAPSHOT,
+                        stream->width, stream->height);
             } else {
                 streamType = CAM_STREAM_TYPE_PREVIEW;
-                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_PREVIEW);
+                streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_PREVIEW,
+                        stream->width, stream->height);
             }
             break;
         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
@@ -1743,6 +1762,15 @@
                          mCamera3Stream->rotation);
             return -EINVAL;
         }
+
+        // Camera3/HAL3 spec expecting counter clockwise rotation but CPP HW is
+        // doing Clockwise rotation and so swap it.
+        if (mRotation == ROTATE_90) {
+            mRotation = ROTATE_270;
+        } else if (mRotation == ROTATE_270) {
+            mRotation = ROTATE_90;
+        }
+
     } else if (mCamera3Stream->rotation != CAMERA3_STREAM_ROTATION_0) {
         LOGE("Rotation %d is not supported by stream type %d",
                 mCamera3Stream->rotation,
@@ -2072,8 +2100,9 @@
         dumpRawSnapshot(super_frame->bufs[0]);
 
     if (mIsRaw16) {
-        if (getStreamDefaultFormat(CAM_STREAM_TYPE_RAW) ==
-                CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG)
+        cam_format_t streamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_RAW,
+                mCamera3Stream->width, mCamera3Stream->height);
+        if (streamFormat == CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG)
             convertMipiToRaw16(super_frame->bufs[0]);
         else
             convertLegacyToRaw16(super_frame->bufs[0]);
@@ -2545,7 +2574,8 @@
     }
 
     mIsType  = isType;
-    mStreamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_CALLBACK);
+    mStreamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_CALLBACK,
+            mCamera3Stream->width, mCamera3Stream->height);
     streamDim.width = mCamera3Stream->width;
     streamDim.height = mCamera3Stream->height;
 
@@ -3009,6 +3039,22 @@
             if (JPEG_JOB_STATUS_DONE == status) {
                 jpegHeader.jpeg_size = (uint32_t)p_output->buf_filled_len;
                 char* jpeg_buf = (char *)p_output->buf_vaddr;
+                cam_frame_len_offset_t offset;
+                memset(&offset, 0, sizeof(cam_frame_len_offset_t));
+                mm_camera_buf_def_t *jpeg_dump_buffer = NULL;
+                cam_dimension_t dim;
+                dim.width = obj->mCamera3Stream->width;
+                dim.height = obj->mCamera3Stream->height;
+                jpeg_dump_buffer = (mm_camera_buf_def_t *)malloc(sizeof(mm_camera_buf_def_t));
+                if(!jpeg_dump_buffer) {
+                    LOGE("Could not allocate jpeg dump buffer");
+                } else {
+                    jpeg_dump_buffer->buffer = p_output->buf_vaddr;
+                    jpeg_dump_buffer->frame_len = p_output->buf_filled_len;
+                    jpeg_dump_buffer->frame_idx = obj->mMemory.getFrameNumber(bufIdx);
+                    obj->dumpYUV(jpeg_dump_buffer, dim, offset, QCAMERA_DUMP_FRM_OUTPUT_JPEG);
+                    free(jpeg_dump_buffer);
+                }
 
                 ssize_t maxJpegSize = -1;
 
@@ -3158,7 +3204,8 @@
     mYuvHeight = stream->height;
     mStreamType = CAM_STREAM_TYPE_SNAPSHOT;
     // Use same pixelformat for 4K video case
-    mStreamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_SNAPSHOT);
+    mStreamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_SNAPSHOT,
+            stream->width, stream->height);
     int32_t rc = m_postprocessor.initJpeg(jpegEvtHandle, &m_max_pic_dim, this);
     if (rc != 0) {
         LOGE("Init Postprocessor failed");
@@ -3780,7 +3827,7 @@
 
         stream->getFrameDimension(dim);
         stream->getFrameOffset(offset);
-        dumpYUV(frame->bufs[0], dim, offset, QCAMERA_DUMP_FRM_SNAPSHOT);
+        dumpYUV(frame->bufs[0], dim, offset, QCAMERA_DUMP_FRM_INPUT_JPEG);
         /* Since reprocessing is done, send the callback to release the input buffer */
         if (mChannelCB) {
             mChannelCB(NULL, NULL, resultFrameNumber, true, mUserData);
@@ -4703,7 +4750,8 @@
    // Make Analysis same as Preview format
    if (!hw_analysis_supported && mStreamType == CAM_STREAM_TYPE_ANALYSIS &&
            color_arrangement != CAM_FILTER_ARRANGEMENT_Y) {
-        mStreamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_PREVIEW);
+        mStreamFormat = getStreamDefaultFormat(CAM_STREAM_TYPE_PREVIEW,
+                dim->width, dim->height);
    }
 }
 
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3Channel.h b/msmcobalt/QCamera2/HAL3/QCamera3Channel.h
index 84c1679..8a7a479 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3Channel.h
+++ b/msmcobalt/QCamera2/HAL3/QCamera3Channel.h
@@ -57,8 +57,9 @@
 
 #define QCAMERA_DUMP_FRM_PREVIEW          1
 #define QCAMERA_DUMP_FRM_VIDEO            (1<<1)
-#define QCAMERA_DUMP_FRM_SNAPSHOT         (1<<2)
+#define QCAMERA_DUMP_FRM_INPUT_JPEG       (1<<2)
 #define QCAMERA_DUMP_FRM_CALLBACK         (1<<3)
+#define QCAMERA_DUMP_FRM_OUTPUT_JPEG      (1<<5)
 #define QCAMERA_DUMP_FRM_INPUT_REPROCESS  (1<<6)
 
 typedef int64_t nsecs_t;
@@ -118,7 +119,8 @@
     void dumpYUV(mm_camera_buf_def_t *frame, cam_dimension_t dim,
             cam_frame_len_offset_t offset, uint8_t name);
     bool isUBWCEnabled();
-    cam_format_t getStreamDefaultFormat(cam_stream_type_t type);
+    cam_format_t getStreamDefaultFormat(cam_stream_type_t type,
+            uint32_t width, uint32_t height);
 
     void *mUserData;
     cam_padding_info_t mPaddingInfo;
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp b/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp
index 13c265d..db53b59 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3HWI.cpp
@@ -844,6 +844,17 @@
 
     LOGI("[KPI Perf]: E PROFILE_CLOSE_CAMERA camera id %d",
              mCameraId);
+
+    // unmap memory for related cam sync buffer
+    mCameraHandle->ops->unmap_buf(mCameraHandle->camera_handle,
+            CAM_MAPPING_BUF_TYPE_SYNC_RELATED_SENSORS_BUF);
+    if (NULL != m_pRelCamSyncHeap) {
+        m_pRelCamSyncHeap->deallocate();
+        delete m_pRelCamSyncHeap;
+        m_pRelCamSyncHeap = NULL;
+        m_pRelCamSyncBuf = NULL;
+    }
+
     rc = mCameraHandle->ops->close_camera(mCameraHandle->camera_handle);
     mCameraHandle = NULL;
 
@@ -864,13 +875,6 @@
         pthread_mutex_unlock(&gCamLock);
     }
 
-    if (NULL != m_pRelCamSyncHeap) {
-        m_pRelCamSyncHeap->deallocate();
-        delete m_pRelCamSyncHeap;
-        m_pRelCamSyncHeap = NULL;
-        m_pRelCamSyncBuf = NULL;
-    }
-
     if (mExifParams.debug_params) {
         free(mExifParams.debug_params);
         mExifParams.debug_params = NULL;
@@ -1306,6 +1310,37 @@
     }
 }
 
+/*==============================================================================
+ * FUNCTION   : updateTimeStampInPendingBuffers
+ *
+ * DESCRIPTION: update timestamp in display metadata for all pending buffers
+ *              of a frame number
+ *
+ * PARAMETERS :
+ *   @frame_number: frame_number. Timestamp will be set on pending buffers of this frame number
+ *   @timestamp   : timestamp to be set
+ *
+ * RETURN     : None
+ *
+ *==========================================================================*/
+void QCamera3HardwareInterface::updateTimeStampInPendingBuffers(
+        uint32_t frameNumber, nsecs_t timestamp)
+{
+    for (auto req = mPendingBuffersMap.mPendingBuffersInRequest.begin();
+            req != mPendingBuffersMap.mPendingBuffersInRequest.end(); req++) {
+        if (req->frame_number != frameNumber)
+            continue;
+
+        for (auto k = req->mPendingBufferList.begin();
+                k != req->mPendingBufferList.end(); k++ ) {
+            struct private_handle_t *priv_handle =
+                    (struct private_handle_t *) (*(k->buffer));
+            setMetaData(priv_handle, SET_VT_TIMESTAMP, &timestamp);
+        }
+    }
+    return;
+}
+
 /*===========================================================================
  * FUNCTION   : configureStreams
  *
@@ -2156,7 +2191,8 @@
             QCamera3Channel *channel = (QCamera3Channel*) newStream->priv;
             if (channel != NULL && channel->isUBWCEnabled()) {
                 cam_format_t fmt = channel->getStreamDefaultFormat(
-                        mStreamConfigInfo.type[mStreamConfigInfo.num_streams]);
+                        mStreamConfigInfo.type[mStreamConfigInfo.num_streams],
+                        newStream->width, newStream->height);
                 if(fmt == CAM_FORMAT_YUV_420_NV12_UBWC) {
                     newStream->usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
                 }
@@ -3051,6 +3087,11 @@
 
             i->timestamp = capture_time;
 
+            /* Set the timestamp in display metadata so that clients aware of
+               private_handle such as VT can use this un-modified timestamps.
+               Camera framework is unaware of this timestamp and cannot change this */
+            updateTimeStampInPendingBuffers(i->frame_number, i->timestamp);
+
             // Find channel requiring metadata, meaning internal offline postprocess
             // is needed.
             //TODO: for now, we don't support two streams requiring metadata at the same time.
@@ -3142,6 +3183,7 @@
                         j->buffer = NULL;
                     }
                 }
+
                 result.output_buffers = result_buffers;
                 mCallbackOps->process_capture_result(mCallbackOps, &result);
                 LOGD("meta frame_number = %u, capture_time = %lld",
@@ -5581,7 +5623,8 @@
     }
 
     IF_META_AVAILABLE(cam_ir_mode_type_t, ir, CAM_INTF_META_IR_MODE, metadata) {
-        camMetadata.update(QCAMERA3_IR_MODE,(int32_t *) &ir, 1);
+        int32_t fwk_ir = (int32_t) *ir;
+        camMetadata.update(QCAMERA3_IR_MODE, &fwk_ir, 1);
     }
 
     // AEC SPEED
@@ -5737,38 +5780,44 @@
         }
     }
 
-    // DDM debug data through vendor tag
-    cam_ddm_info_t ddm_info;
-    memset(&ddm_info, 0, sizeof(cam_ddm_info_t));
+    // Reprocess and DDM debug data through vendor tag
+    cam_reprocess_info_t repro_info;
+    memset(&repro_info, 0, sizeof(cam_reprocess_info_t));
     IF_META_AVAILABLE(cam_stream_crop_info_t, sensorCropInfo,
             CAM_INTF_META_SNAP_CROP_INFO_SENSOR, metadata) {
-        memcpy(&(ddm_info.sensor_crop_info), sensorCropInfo, sizeof(cam_stream_crop_info_t));
+        memcpy(&(repro_info.sensor_crop_info), sensorCropInfo, sizeof(cam_stream_crop_info_t));
     }
     IF_META_AVAILABLE(cam_stream_crop_info_t, camifCropInfo,
             CAM_INTF_META_SNAP_CROP_INFO_CAMIF, metadata) {
-        memcpy(&(ddm_info.camif_crop_info), camifCropInfo, sizeof(cam_stream_crop_info_t));
+        memcpy(&(repro_info.camif_crop_info), camifCropInfo, sizeof(cam_stream_crop_info_t));
     }
     IF_META_AVAILABLE(cam_stream_crop_info_t, ispCropInfo,
             CAM_INTF_META_SNAP_CROP_INFO_ISP, metadata) {
-        memcpy(&(ddm_info.isp_crop_info), ispCropInfo, sizeof(cam_stream_crop_info_t));
+        memcpy(&(repro_info.isp_crop_info), ispCropInfo, sizeof(cam_stream_crop_info_t));
     }
     IF_META_AVAILABLE(cam_stream_crop_info_t, cppCropInfo,
             CAM_INTF_META_SNAP_CROP_INFO_CPP, metadata) {
-        memcpy(&(ddm_info.cpp_crop_info), cppCropInfo, sizeof(cam_stream_crop_info_t));
+        memcpy(&(repro_info.cpp_crop_info), cppCropInfo, sizeof(cam_stream_crop_info_t));
     }
     IF_META_AVAILABLE(cam_focal_length_ratio_t, ratio,
             CAM_INTF_META_AF_FOCAL_LENGTH_RATIO, metadata) {
-        memcpy(&(ddm_info.af_focal_length_ratio), ratio, sizeof(cam_focal_length_ratio_t));
+        memcpy(&(repro_info.af_focal_length_ratio), ratio, sizeof(cam_focal_length_ratio_t));
     }
     IF_META_AVAILABLE(int32_t, flip, CAM_INTF_PARM_FLIP, metadata) {
-        memcpy(&(ddm_info.pipeline_flip), flip, sizeof(int32_t));
+        memcpy(&(repro_info.pipeline_flip), flip, sizeof(int32_t));
     }
     IF_META_AVAILABLE(cam_rotation_info_t, rotationInfo,
             CAM_INTF_PARM_ROTATION, metadata) {
-        memcpy(&(ddm_info.rotation_info), rotationInfo, sizeof(cam_rotation_info_t));
+        memcpy(&(repro_info.rotation_info), rotationInfo, sizeof(cam_rotation_info_t));
     }
-    camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB,
-            (uint8_t *)&ddm_info, sizeof(cam_ddm_info_t));
+    IF_META_AVAILABLE(cam_area_t, afRoi, CAM_INTF_META_AF_ROI, metadata) {
+        memcpy(&(repro_info.af_roi), afRoi, sizeof(cam_area_t));
+    }
+    IF_META_AVAILABLE(cam_dyn_img_data_t, dynMask, CAM_INTF_META_IMG_DYN_FEAT, metadata) {
+        memcpy(&(repro_info.dyn_mask), dynMask, sizeof(cam_dyn_img_data_t));
+    }
+    camMetadata.update(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
+        (uint8_t *)&repro_info, sizeof(cam_reprocess_info_t));
 
     /* In batch mode, cache the first metadata in the batch */
     if (mBatchSize && firstMetadataInBatch) {
@@ -6382,6 +6431,96 @@
 }
 
 #define DATA_PTR(MEM_OBJ,INDEX) MEM_OBJ->getPtr( INDEX )
+
+/*===========================================================================
+ * FUNCTION   : getCapabilities
+ *
+ * DESCRIPTION: query camera capability from back-end
+ *
+ * PARAMETERS :
+ *   @ops  : mm-interface ops structure
+ *   @cam_handle  : camera handle for which we need capability
+ *
+ * RETURN     : ptr type of capability structure
+ *              capability for success
+ *              NULL for failure
+ *==========================================================================*/
+cam_capability_t *QCamera3HardwareInterface::getCapabilities(mm_camera_ops_t *ops,
+        uint32_t cam_handle)
+{
+    int rc = NO_ERROR;
+    QCamera3HeapMemory *capabilityHeap = NULL;
+    cam_capability_t *cap_ptr = NULL;
+
+    if (ops == NULL) {
+        LOGE("Invalid arguments");
+        return NULL;
+    }
+
+    capabilityHeap = new QCamera3HeapMemory(1);
+    if (capabilityHeap == NULL) {
+        LOGE("creation of capabilityHeap failed");
+        return NULL;
+    }
+
+    /* Allocate memory for capability buffer */
+    rc = capabilityHeap->allocate(sizeof(cam_capability_t));
+    if(rc != OK) {
+        LOGE("No memory for cappability");
+        goto allocate_failed;
+    }
+
+    /* Map memory for capability buffer */
+    memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
+
+    rc = ops->map_buf(cam_handle,
+            CAM_MAPPING_BUF_TYPE_CAPABILITY, capabilityHeap->getFd(0),
+            sizeof(cam_capability_t), capabilityHeap->getPtr(0));
+    if(rc < 0) {
+        LOGE("failed to map capability buffer");
+        rc = FAILED_TRANSACTION;
+        goto map_failed;
+    }
+
+    /* Query Capability */
+    rc = ops->query_capability(cam_handle);
+    if(rc < 0) {
+        LOGE("failed to query capability");
+        rc = FAILED_TRANSACTION;
+        goto query_failed;
+    }
+
+    cap_ptr = (cam_capability_t *)malloc(sizeof(cam_capability_t));
+    if (cap_ptr == NULL) {
+        LOGE("out of memory");
+        rc = NO_MEMORY;
+        goto query_failed;
+    }
+
+    memset(cap_ptr, 0, sizeof(cam_capability_t));
+    memcpy(cap_ptr, DATA_PTR(capabilityHeap, 0), sizeof(cam_capability_t));
+
+    int index;
+    for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
+        cam_analysis_info_t *p_analysis_info = &cap_ptr->analysis_info[index];
+        p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
+        p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
+    }
+
+query_failed:
+    ops->unmap_buf(cam_handle, CAM_MAPPING_BUF_TYPE_CAPABILITY);
+map_failed:
+    capabilityHeap->deallocate();
+allocate_failed:
+    delete capabilityHeap;
+
+    if (rc != NO_ERROR) {
+        return NULL;
+    } else {
+        return cap_ptr;
+    }
+}
+
 /*===========================================================================
  * FUNCTION   : initCapabilities
  *
@@ -6398,7 +6537,7 @@
 {
     int rc = 0;
     mm_camera_vtbl_t *cameraHandle = NULL;
-    QCamera3HeapMemory *capabilityHeap = NULL;
+    uint32_t handle = 0;
 
     rc = camera_open((uint8_t)cameraId, &cameraHandle);
     if (rc) {
@@ -6410,61 +6549,24 @@
         goto open_failed;
     }
 
-    capabilityHeap = new QCamera3HeapMemory(1);
-    if (capabilityHeap == NULL) {
-        LOGE("creation of capabilityHeap failed");
-        goto heap_creation_failed;
-    }
-    /* Allocate memory for capability buffer */
-    rc = capabilityHeap->allocate(sizeof(cam_capability_t));
-    if(rc != OK) {
-        LOGE("No memory for cappability");
-        goto allocate_failed;
+    handle = get_main_camera_handle(cameraHandle->camera_handle);
+    gCamCapability[cameraId] = getCapabilities(cameraHandle->ops, handle);
+    if (gCamCapability[cameraId] == NULL) {
+        rc = FAILED_TRANSACTION;
+        goto failed_op;
     }
 
-    /* Map memory for capability buffer */
-    memset(DATA_PTR(capabilityHeap,0), 0, sizeof(cam_capability_t));
-    rc = cameraHandle->ops->map_buf(cameraHandle->camera_handle,
-                                CAM_MAPPING_BUF_TYPE_CAPABILITY,
-                                capabilityHeap->getFd(0),
-                                sizeof(cam_capability_t),
-                                capabilityHeap->getPtr(0));
-    if(rc < 0) {
-        LOGE("failed to map capability buffer");
-        goto map_failed;
+    if (is_dual_camera_by_idx(cameraId)) {
+        handle = get_aux_camera_handle(cameraHandle->camera_handle);
+        gCamCapability[cameraId]->aux_cam_cap =
+                getCapabilities(cameraHandle->ops, handle);
+        if (gCamCapability[cameraId]->aux_cam_cap == NULL) {
+            rc = FAILED_TRANSACTION;
+            free(gCamCapability[cameraId]);
+            goto failed_op;
+        }
     }
-
-    /* Query Capability */
-    rc = cameraHandle->ops->query_capability(cameraHandle->camera_handle);
-    if(rc < 0) {
-        LOGE("failed to query capability");
-        goto query_failed;
-    }
-    gCamCapability[cameraId] = (cam_capability_t *)malloc(sizeof(cam_capability_t));
-    if (!gCamCapability[cameraId]) {
-        LOGE("out of memory");
-        goto query_failed;
-    }
-    memcpy(gCamCapability[cameraId], DATA_PTR(capabilityHeap,0),
-                                        sizeof(cam_capability_t));
-
-    int index;
-    for (index = 0; index < CAM_ANALYSIS_INFO_MAX; index++) {
-        cam_analysis_info_t *p_analysis_info =
-                &gCamCapability[cameraId]->analysis_info[index];
-        p_analysis_info->analysis_padding_info.offset_info.offset_x = 0;
-        p_analysis_info->analysis_padding_info.offset_info.offset_y = 0;
-    }
-    rc = 0;
-
-query_failed:
-    cameraHandle->ops->unmap_buf(cameraHandle->camera_handle,
-                            CAM_MAPPING_BUF_TYPE_CAPABILITY);
-map_failed:
-    capabilityHeap->deallocate();
-allocate_failed:
-    delete capabilityHeap;
-heap_creation_failed:
+failed_op:
     cameraHandle->ops->close_camera(cameraHandle->camera_handle);
     cameraHandle = NULL;
 open_failed:
@@ -6851,7 +6953,10 @@
     staticInfo.update(ANDROID_TONEMAP_MAX_CURVE_POINTS,
             &gCamCapability[cameraId]->max_tone_map_curve_points, 1);
 
-    uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN;
+    // SOF timestamp is based on monotonic_boottime. So advertize REALTIME timesource
+    // REALTIME defined in HAL3 API is same as linux's CLOCK_BOOTTIME
+    // Ref: kernel/...../msm_isp_util.c: msm_isp_get_timestamp: get_monotonic_boottime
+    uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
     staticInfo.update(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE,
             &timestampSource, 1);
 
@@ -8790,23 +8895,27 @@
         }
     }
 
-    // Add metadata which DDM needs
-    if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB)) {
-        cam_ddm_info_t *ddm_info =
-                (cam_ddm_info_t *)frame_settings.find
-                (QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB).data.u8;
+    // Add metadata which reprocess needs
+    if (frame_settings.exists(QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB)) {
+        cam_reprocess_info_t *repro_info =
+                (cam_reprocess_info_t *)frame_settings.find
+                (QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB).data.u8;
         ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_SENSOR,
-                ddm_info->sensor_crop_info);
+                repro_info->sensor_crop_info);
         ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_CAMIF,
-                ddm_info->camif_crop_info);
+                repro_info->camif_crop_info);
         ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_ISP,
-                ddm_info->isp_crop_info);
+                repro_info->isp_crop_info);
         ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_SNAP_CROP_INFO_CPP,
-                ddm_info->cpp_crop_info);
+                repro_info->cpp_crop_info);
         ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_AF_FOCAL_LENGTH_RATIO,
-                ddm_info->af_focal_length_ratio);
+                repro_info->af_focal_length_ratio);
         ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_FLIP,
-                ddm_info->pipeline_flip);
+                repro_info->pipeline_flip);
+        ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_AF_ROI,
+                repro_info->af_roi);
+        ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_META_IMG_DYN_FEAT,
+                repro_info->dyn_mask);
         /* If there is ANDROID_JPEG_ORIENTATION in frame setting,
            CAM_INTF_PARM_ROTATION metadata then has been added in
            translateToHalMetadata. HAL need to keep this new rotation
@@ -8817,7 +8926,7 @@
             LOGD("CAM_INTF_PARM_ROTATION metadata is added in translateToHalMetadata");
         } else {
             ADD_SET_PARAM_ENTRY_TO_BATCH(reprocParam, CAM_INTF_PARM_ROTATION,
-                    ddm_info->rotation_info);
+                    repro_info->rotation_info);
         }
     }
 
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3HWI.h b/msmcobalt/QCamera2/HAL3/QCamera3HWI.h
index 3f7fb03..62fe6db 100755
--- a/msmcobalt/QCamera2/HAL3/QCamera3HWI.h
+++ b/msmcobalt/QCamera2/HAL3/QCamera3HWI.h
@@ -148,6 +148,8 @@
     camera_metadata_t* translateCapabilityToMetadata(int type);
 
     static int getCamInfo(uint32_t cameraId, struct camera_info *info);
+    static cam_capability_t *getCapabilities(mm_camera_ops_t *ops,
+            uint32_t cam_handle);
     static int initCapabilities(uint32_t cameraId);
     static int initStaticMetadata(uint32_t cameraId);
     static void makeTable(cam_dimension_t *dimTable, size_t size,
@@ -321,6 +323,7 @@
 
     void addToPPFeatureMask(int stream_format, uint32_t stream_idx);
     void updateFpsInPreviewBuffer(metadata_buffer_t *metadata, uint32_t frame_number);
+    void updateTimeStampInPendingBuffers(uint32_t frameNumber, nsecs_t timestamp);
 
     void enablePowerHint();
     void disablePowerHint();
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3Mem.cpp b/msmcobalt/QCamera2/HAL3/QCamera3Mem.cpp
index ebcc3ba..4cdde0e 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3Mem.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3Mem.cpp
@@ -396,7 +396,7 @@
 {
     if (index >= mBufferCount) {
         LOGE("index out of bound");
-        return (void *)BAD_INDEX;
+        return NULL;
     }
     return mPtr[index];
 }
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp
index d8693ea..5b4d88e 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp
+++ b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.cpp
@@ -147,7 +147,7 @@
         qcamera3_hal_privatedata[QCAMERA3_HAL_PRIVATEDATA_END -
         QCAMERA3_HAL_PRIVATEDATA_START] = {
     { "reprocess_flags",      TYPE_BYTE },
-    { "ddm_data_blob",        TYPE_BYTE }
+    { "reprocess_data_blob",  TYPE_BYTE }
 };
 
 vendor_tag_info_t
@@ -240,7 +240,7 @@
 
     // QCAMERA3_HAL_PRIVATEDATA
     (uint32_t)QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS,
-    (uint32_t)QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB,
+    (uint32_t)QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
 
     // QCAMERA3_JPEG_ENCODE_CROP
     (uint32_t)QCAMERA3_JPEG_ENCODE_CROP_ENABLE,
diff --git a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h
index 224a7be..fad5caa 100644
--- a/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h
+++ b/msmcobalt/QCamera2/HAL3/QCamera3VendorTags.h
@@ -161,7 +161,7 @@
     QCAMERA3_DUALCAM_CALIB_META_DATA_END,
 
     QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS = QCAMERA3_HAL_PRIVATEDATA_START,
-    QCAMERA3_HAL_PRIVATEDATA_DDM_DATA_BLOB,
+    QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
     QCAMERA3_HAL_PRIVATEDATA_END,
 
     /* Property Name:  org.codeaurora.qcamera3.jpeg_encode_crop.enable
diff --git a/msmcobalt/QCamera2/QCamera2Factory.cpp b/msmcobalt/QCamera2/QCamera2Factory.cpp
index 33b051a..97e9eb7 100644
--- a/msmcobalt/QCamera2/QCamera2Factory.cpp
+++ b/msmcobalt/QCamera2/QCamera2Factory.cpp
@@ -497,7 +497,14 @@
 {
     int rc = NO_ERROR;
 
-    LOGI("openLegacy halVersion: %d", halVersion);
+#ifdef DUAL_CAM_TEST
+    char prop[PROPERTY_VALUE_MAX];
+    memset(prop, 0, sizeof(prop));
+    property_get("persist.camera.id", prop, "0");
+    cameraId = atoi(prop);
+#endif
+
+    LOGI("openLegacy halVersion: %d cameraId = %d", halVersion, cameraId);
     //Assumption: all cameras can support legacy API version
     if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
         return -ENODEV;
diff --git a/msmcobalt/QCamera2/stack/common/cam_intf.h b/msmcobalt/QCamera2/stack/common/cam_intf.h
index 8b6fecb..696a85d 100755
--- a/msmcobalt/QCamera2/stack/common/cam_intf.h
+++ b/msmcobalt/QCamera2/stack/common/cam_intf.h
@@ -175,7 +175,8 @@
 } cam_jpeg_metadata_t;
 
 /* capability struct definition for HAL 1*/
-typedef struct{
+struct cam_capability;
+typedef struct cam_capability{
     cam_hal_version_t version;
 
     cam_position_t position;                                /* sensor position: front, back */
@@ -561,6 +562,10 @@
     /* Supported IR Mode */
     size_t supported_ir_mode_cnt;
     cam_ir_mode_type_t supported_ir_modes[CAM_IR_MODE_MAX];
+
+    /*Slave capability*/
+    struct cam_capability *aux_cam_cap;
+    cam_sync_type_t cam_sensor_mode;
 } cam_capability_t;
 
 typedef enum {
@@ -620,7 +625,7 @@
 } cam_stream_parm_buffer_t;
 
 /* stream info */
-typedef struct {
+typedef struct cam_stream_info {
     /* stream ID from server */
     uint32_t stream_svr_id;
 
@@ -641,6 +646,9 @@
     /* number of stream bufs will be allocated */
     uint32_t num_bufs;
 
+    /* number of stream bufs allocated for this stream*/
+    uint32_t buf_cnt;
+
     /* streaming type */
     cam_streaming_mode_t streaming_mode;
 
@@ -683,6 +691,8 @@
    /* Subformat for this stream */
     cam_sub_format_type_t sub_format_type;
 
+    /*Stream info for Slave Stream*/
+    struct cam_stream_info *aux_str_info;
 } cam_stream_info_t;
 
 /*****************************************************************************
@@ -712,6 +722,13 @@
     ((LOGE("Unable to set metadata TABLE_PTR:%p META_ID:%d", \
             TABLE_PTR, META_ID)), (-1))) \
 
+#define ADD_SET_PARAM_ENTRY_TO_BATCH_FOR_AUX(TABLE_PTR, AUX_TABLE_PTR, META_ID) \
+    ((NULL != TABLE_PTR || (NULL != AUX_TABLE_PTR)) ? \
+    ((AUX_TABLE_PTR->data.member_variable_##META_ID[ 0 ] = TABLE_PTR->data.member_variable_##META_ID[ 0 ]), \
+    (AUX_TABLE_PTR->is_valid[META_ID] = 1), (0)) : \
+    ((LOGE("Unable to set metadata AUX_TABLE_PTR:%p META_ID:%d", \
+            AUX_TABLE_PTR, META_ID)), (-1))) \
+
 #define ADD_SET_PARAM_ARRAY_TO_BATCH(TABLE_PTR, META_ID, PDATA, COUNT, RCOUNT) \
 { \
     if ((NULL != TABLE_PTR) && \
@@ -1018,6 +1035,8 @@
     INCLUDE(CAM_INTF_PARM_JPEG_ENCODE_CROP,             cam_stream_crop_info_t,      1);
     INCLUDE(CAM_INTF_PARM_JPEG_SCALE_DIMENSION,         cam_dimension_t,             1);
     INCLUDE(CAM_INTF_META_FOCUS_DEPTH_INFO,             uint8_t,                     1);
+    INCLUDE(CAM_INTF_PARM_SUSPEND_RESUME_CAMERAS,       uint32_t,                    2);
+    INCLUDE(CAM_INTF_PARM_CAMERA_MASTER_INFO,           uint32_t,                    2);
 } metadata_data_t;
 
 /* Update clear_metadata_buffer() function when a new is_xxx_valid is added to
@@ -1063,7 +1082,6 @@
 
     uint8_t is_statsdebug_3a_tuning_params_valid;
     cam_q3a_tuning_info_t statsdebug_3a_tuning_data;
-
 } metadata_buffer_t;
 
 typedef metadata_buffer_t parm_buffer_t;
diff --git a/msmcobalt/QCamera2/stack/common/cam_types.h b/msmcobalt/QCamera2/stack/common/cam_types.h
index 18acfe6..a6c91eb 100644
--- a/msmcobalt/QCamera2/stack/common/cam_types.h
+++ b/msmcobalt/QCamera2/stack/common/cam_types.h
@@ -163,13 +163,13 @@
 } cam_status_t;
 
 typedef enum {
-    /* back main camera */
+    /*back main camera*/
     CAM_POSITION_BACK,
-    /* front main camera */
+    /*front main camera*/
     CAM_POSITION_FRONT,
-    /* back aux camera */
+    /*back aux camera*/
     CAM_POSITION_BACK_AUX,
-    /* front aux camera */
+    /*front aux camera*/
     CAM_POSITION_FRONT_AUX
 } cam_position_t;
 
@@ -1651,11 +1651,16 @@
 typedef enum {
     /* Standalone camera (won't be linked) */
     CAM_TYPE_STANDALONE=0,
+
     /* Main camera of the related cam subsystem which controls
        HW sync at sensor level*/
-    CAM_TYPE_MAIN,
+    CAM_TYPE_MAIN = (1 << 0),
+
     /* Aux camera of the related cam subsystem */
-    CAM_TYPE_AUX
+    CAM_TYPE_AUX = (1 << 1),
+
+    /*Secure camera. Is not published*/
+    CAM_TYPE_SECURE = (1 << 2),
 } cam_sync_type_t;
 
 typedef enum {
@@ -2243,6 +2248,10 @@
     CAM_INTF_META_FOCUS_VALUE,
     /*Spot light detection result output from af core*/
     CAM_INTF_META_SPOT_LIGHT_DETECT,
+    /*parameter to control dual camera's from HAL*/
+    CAM_INTF_PARM_SUSPEND_RESUME_CAMERAS,
+    /*Camera module master info*/
+    CAM_INTF_PARM_CAMERA_MASTER_INFO,
     CAM_INTF_PARM_MAX
 } cam_intf_parm_type_t;
 
@@ -2816,7 +2825,7 @@
 } cam_event_t;
 
 typedef struct {
-    /* Information for DDM */
+    /* Information for DDM metadata*/
     cam_stream_crop_info_t   sensor_crop_info; /* sensor crop info */
     cam_stream_crop_info_t   camif_crop_info; /* CAMIF crop info */
     cam_stream_crop_info_t   isp_crop_info; /* ISP crop info */
@@ -2824,7 +2833,10 @@
     cam_focal_length_ratio_t af_focal_length_ratio; /* AF focal length ratio */
     int32_t                  pipeline_flip; /* current pipeline flip and rotational parameters */
     cam_rotation_info_t      rotation_info; /* rotation information */
-} cam_ddm_info_t;
+    cam_area_t               af_roi;        /* AF roi info */
+    /* Information for CPP reprocess */
+    cam_dyn_img_data_t       dyn_mask;      /* Post processing dynamic feature mask */
+} cam_reprocess_info_t;
 
 /***********************************
 * ENUM definition for custom parameter type
diff --git a/msmcobalt/QCamera2/stack/common/mm_camera_interface.h b/msmcobalt/QCamera2/stack/common/mm_camera_interface.h
index 79283a1..25b48b4 100644
--- a/msmcobalt/QCamera2/stack/common/mm_camera_interface.h
+++ b/msmcobalt/QCamera2/stack/common/mm_camera_interface.h
@@ -39,6 +39,7 @@
 
 #define MM_CAMERA_MAX_NUM_SENSORS MSM_MAX_CAMERA_SENSORS
 #define MM_CAMERA_MAX_NUM_FRAMES CAM_MAX_NUM_BUFS_PER_STREAM
+
 /* num of channels allowed in a camera obj */
 #define MM_CAMERA_CHANNEL_MAX 16
 
@@ -48,6 +49,18 @@
 
 #define CEIL_DIVISION(n, d) ((n+d-1)/d)
 
+/*Bit shift to reach next camera in camera handle*/
+#define MM_CAMERA_HANDLE_SHIFT_MASK       16
+#define MM_CAMERA_HANDLE_BIT_MASK         0x0000ffff
+
+typedef enum {
+    MM_CAMERA_TYPE_MAIN       = CAM_TYPE_MAIN,
+    MM_CAMERA_TYPE_AUX        = CAM_TYPE_AUX,
+} mm_camera_obj_type;
+
+#define MM_CAMERA_DUAL_CAM (MM_CAMERA_TYPE_MAIN | MM_CAMERA_TYPE_AUX)
+#define MM_CAMERA_MAX_CAM_CNT 2
+
 /** CAM_DUMP_TO_FILE:
  *  @filename: file name
  *  @name:filename
@@ -180,6 +193,7 @@
     uint32_t num_buf_requested;
     uint32_t num_retro_buf_requested;
     uint8_t primary_only;
+    uint32_t frame_idx; //Client can request frameId to pick from ZSL queue
 } mm_camera_req_buf_t;
 
 typedef cam_event_t mm_camera_event_t;
@@ -385,6 +399,23 @@
     uint8_t user_expected_frame_id;
 } mm_camera_channel_attr_t;
 
+/** mm_camera_intf_frame_sync_t: structure to register frame sync
+*    @camera_handle  : camera handle to be syced
+*    @ch_id          : channel id to be synced
+*    @stream_id      : stream id to be synced
+*    @max_unmatched_frames : Frames to wait for before frame callback
+*    @buf_cb         : callback. can be NULL. NULL uses already registered stream/channel cb
+*    @userdata       : client objects.
+**/
+typedef struct {
+    uint32_t camera_handle;
+    uint32_t ch_id;
+    uint32_t stream_id;
+    uint8_t max_unmatched_frames;
+    mm_camera_buf_notify_t buf_cb;
+    void *userdata;
+} mm_camera_intf_frame_sync_t;
+
 typedef struct {
     /** query_capability: fucntion definition for querying static
      *                    camera capabilities
@@ -854,6 +885,48 @@
     int32_t (*register_stream_buf_cb) (uint32_t camera_handle,
             uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
             mm_camera_stream_cb_type cb_type, void *userdata);
+
+   /** register_stream_frame_sync: fucntion definition for registering frame sync
+     *    @camera_handle : camer handler
+     *    @ch_id : channel handler
+     *    @stream_id : stream handler. Can be 0 to config only channel callback sync
+     *    @sync_attr : pointer to a stream sync configuration structure
+     *  Return value: 0 -- success
+     *                -1 -- failure
+     **/
+    int32_t (*register_frame_sync) (uint32_t camera_handle,
+            uint32_t ch_id, uint32_t stream_id,
+            mm_camera_intf_frame_sync_t *sync_attr);
+
+   /** start_stream_frame_sync:  function definition to start frame buffer sync
+     *    @camera_handle : camer handler
+     *    @ch_id : channel handler
+     *    @stream_id : stream handler
+     *  Return value: 0 -- success
+     *                -1 -- failure
+     **/
+    int32_t (*start_stream_frame_sync) (uint32_t camera_handle,
+            uint32_t ch_id, uint32_t stream_id);
+
+   /** stop_stream_frame_sync:  function definition to stop frame buffer sync
+     *    @camera_handle : camer handler
+     *    @ch_id : channel handler
+     *    @stream_id : stream handler
+     *  Return value: 0 -- success
+     *                -1 -- failure
+     **/
+    int32_t (*stop_stream_frame_sync) (uint32_t camera_handle,
+            uint32_t ch_id, uint32_t stream_id);
+
+   /** switch_stream: function definition to switch stream frame
+     *    @camera_handle : camer handler
+     *    @ch_id : channel handler
+     *    @stream_id : stream handler
+     *  Return value: 0 -- success
+     *                -1 -- failure
+     **/
+    int32_t (*switch_stream_callback) (uint32_t camera_handle,
+            uint32_t ch_id, uint32_t stream_id);
 } mm_camera_ops_t;
 
 /** mm_camera_vtbl_t: virtual table for camera operations
@@ -910,9 +983,24 @@
         cam_stream_buf_plane_info_t *buf_planes);
 
 uint32_t mm_stream_calc_lcm (int32_t num1, int32_t num2);
-
 struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType);
 
 uint8_t is_yuv_sensor(uint32_t camera_id);
 
+/*Dual camera related utility functions*/
+
+/*Query if it is dual camera mode based on the camera index*/
+uint8_t is_dual_camera_by_idx(uint32_t camera_id);
+
+/*Query if it is dual camera mode based on the camera/channel/stream handles*/
+uint8_t is_dual_camera_by_handle(uint32_t handle);
+
+/*Get Primary camera handle for camera/channel/stream*/
+uint32_t get_main_camera_handle(uint32_t handle);
+
+/*Get Auxilary camera handle for camera/channel/stream*/
+uint32_t get_aux_camera_handle(uint32_t handle);
+
+/*Validate 2 handle if it is belong to same instance of camera/channel/stream*/
+uint8_t validate_handle(uint32_t src_handle, uint32_t handle);
 #endif /*__MM_CAMERA_INTERFACE_H__*/
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/Android.mk b/msmcobalt/QCamera2/stack/mm-camera-interface/Android.mk
index 1497fbd..1c55393 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/Android.mk
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/Android.mk
@@ -7,6 +7,7 @@
 MM_CAM_FILES := \
         src/mm_camera_interface.c \
         src/mm_camera.c \
+        src/mm_camera_muxer.c \
         src/mm_camera_channel.c \
         src/mm_camera_stream.c \
         src/mm_camera_thread.c \
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera.h b/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera.h
index 94f158f..a1f0ecf 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera.h
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera.h
@@ -59,6 +59,12 @@
 #define MM_CAMERA_MAX_FUTURE_FRAME_WAIT 100
 #define WAIT_TIMEOUT 5
 
+/*For frame sync */
+#define MAX_OBJS_FOR_FRAME_SYNC   4
+
+/* num of supporting camera*/
+#define MM_CAMERA_MAX_AUX_CAMERA 1
+
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -208,6 +214,9 @@
     MM_STREAM_EVT_GET_PARM,
     MM_STREAM_EVT_DO_ACTION,
     MM_STREAM_EVT_GET_QUEUED_BUF_COUNT,
+    MM_STREAM_EVT_REG_FRAME_SYNC,
+    MM_STREAM_EVT_TRIGGER_FRAME_SYNC,
+    MM_STREAM_EVT_SWITCH_STREAM_CB,
     MM_STREAM_EVT_MAX
 } mm_stream_evt_type_t;
 
@@ -236,6 +245,48 @@
     int8_t map_status;
 } mm_stream_buf_status_t;
 
+/*Structure definition to carry frame sync queue details*/
+typedef struct {
+    /*Number of objects to be synced*/
+    uint8_t num_objs;
+    /*Object handle to be synced*/
+    uint32_t bundled_objs[MAX_OBJS_FOR_FRAME_SYNC];
+    /*Queue*/
+    cam_queue_t que;
+
+    /*queue attributed*/
+    /*Number of frames to wait before process unmatched cb*/
+    uint8_t max_unmatched_frames;
+
+    /*Expected frame for this queue*/
+    uint32_t expected_frame_id;
+
+    /*Parameter to consider during frame sync*/
+    mm_camera_super_buf_priority_t priority;
+} mm_frame_sync_queue_t;
+
+/*Structure definition to carry frame sync details*/
+typedef struct {
+    /* flag to indicate if frame sync is active*/
+    uint8_t is_active;
+
+    /*Frame sync lock. Shared between child and parent stream*/
+    pthread_mutex_t sync_lock;
+
+    /*Limited number of synced frame request*/
+    uint32_t num_buf_requested;
+
+    /*Queue to hold super buffers*/
+    mm_frame_sync_queue_t superbuf_queue;
+
+    /*Callback registered for synced frame*/
+    mm_camera_buf_notify_t super_buf_notify_cb;
+
+    /*Client data*/
+    void *user_data;
+} mm_frame_sync_t;
+
+struct mm_stream;
 typedef struct mm_stream {
     uint32_t my_hdl; /* local stream id */
     uint32_t server_stream_id; /* stream id from server */
@@ -255,12 +306,16 @@
     mm_camera_cmd_thread_t cmd_thread;
 
     /* dataCB registered on this stream obj */
+    uint8_t is_cb_active;
     pthread_mutex_t cb_lock; /* cb lock to protect buf_cb */
     mm_stream_data_cb_t buf_cb[MM_CAMERA_STREAM_BUF_CB_MAX];
 
     /* stream buffer management */
     pthread_mutex_t buf_lock;
-    uint8_t buf_num; /* num of buffers allocated */
+    uint8_t total_buf_cnt; /*Total number of buffer including slave*/
+    uint8_t buf_num; /* num of buffers for this stream */
+    uint8_t buf_idx; /* starting buffer index */
+
     mm_camera_buf_def_t* buf; /* ptr to buf array */
     mm_stream_buf_status_t buf_status[CAM_MAX_NUM_BUFS_PER_STREAM]; /* ptr to buf status array */
 
@@ -269,7 +324,6 @@
     int32_t cur_buf_idx; /* Current container buffer active filling. Used only in Batch mode*/
     uint8_t cur_bufs_staged; /*Number of plane buf freed by HAL for this usr buf*/
 
-
     /* reference to parent channel_obj */
     struct mm_channel* ch_obj;
 
@@ -281,7 +335,6 @@
     uint8_t is_linked; /* flag if stream is linked */
 
     mm_camera_stream_mem_vtbl_t mem_vtbl; /* mem ops tbl */
-
     mm_camera_map_unmap_ops_tbl_t map_ops;
 
     int8_t queued_buffer_count;
@@ -292,6 +345,12 @@
 
     /* Need to wait for buffer mapping before stream-on*/
     pthread_cond_t buf_cond;
+
+    struct mm_stream *master_str_obj; /*Master stream of this stream*/
+    uint8_t num_s_cnt;
+    struct mm_stream *aux_str_obj[MM_CAMERA_MAX_AUX_CAMERA];  /*aux stream of this stream*/
+    mm_frame_sync_t frame_sync;
+    uint8_t is_res_shared;
 } mm_stream_t;
 
 /* mm_channel */
@@ -323,7 +382,7 @@
     MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
     MM_CHANNEL_EVT_SET_STREAM_PARM,
     MM_CHANNEL_EVT_GET_STREAM_PARM,
-    MM_CHANNEL_EVT_DO_STREAM_ACTION,
+    MM_CHANNEL_EVT_DO_ACTION,
     MM_CHANNEL_EVT_DELETE,
     MM_CHANNEL_EVT_AF_BRACKETING,
     MM_CHANNEL_EVT_AE_BRACKETING,
@@ -332,7 +391,10 @@
     MM_CAMERA_EVT_CAPTURE_SETTING,
     MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
     MM_CHANNEL_EVT_MAP_STREAM_BUFS,
-    MM_CHANNEL_EVT_REG_STREAM_BUF_CB
+    MM_CHANNEL_EVT_REG_STREAM_BUF_CB,
+    MM_CHANNEL_EVT_REG_FRAME_SYNC,
+    MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC,
+    MM_CHANNEL_EVT_SWITCH_STREAM_CB,
 } mm_channel_evt_type_t;
 
 typedef struct {
@@ -385,6 +447,7 @@
 typedef struct {
     uint8_t is_active; /* flag to indicate if bundle is valid */
     /* queue to store bundled super buffers */
+    uint8_t is_cb_active;
     mm_channel_queue_t superbuf_queue;
     mm_camera_buf_notify_t super_buf_notify_cb;
     void *user_data;
@@ -431,6 +494,7 @@
     MM_CHANNEL_BRACKETING_STATE_ACTIVE,
 } mm_channel_bracketing_state_t;
 
+struct mm_channel;
 typedef struct mm_channel {
     uint32_t my_hdl;
     mm_channel_state_type_t state;
@@ -487,6 +551,19 @@
     uint32_t capture_frame_id[MAX_CAPTURE_BATCH_NUM];
     cam_capture_frame_config_t frameConfig;
     uint8_t needLowLightZSL;
+
+    /*Capture based on index*/
+    uint8_t cur_req_idx;
+    uint8_t frame_req_cnt;
+    uint32_t requested_frame_id[MAX_CAPTURE_BATCH_NUM];
+
+    /*For channel frame sync*/
+    mm_frame_sync_t frame_sync;
+
+    /*Multiple camera's*/
+    struct mm_channel *master_ch_obj; /*Master channel of this channel*/
+    uint8_t num_s_cnt;
+    struct mm_channel *aux_ch_obj[MM_CAMERA_MAX_AUX_CAMERA];  /*Slave channel of this channel*/
 } mm_channel_t;
 
 typedef struct {
@@ -515,6 +592,7 @@
     int reg_count;
 } mm_camera_evt_obj_t;
 
+struct mm_camera_obj;
 typedef struct mm_camera_obj {
     uint32_t my_hdl;
     int ref_count;
@@ -534,6 +612,12 @@
 
     pthread_mutex_t msg_lock; /* lock for sending msg through socket */
     uint32_t sessionid; /* Camera server session id */
+
+    uint8_t my_num;          /*this camera position in multi mode*/
+    pthread_mutex_t muxer_lock;
+    struct mm_camera_obj *master_cam_obj; /*Master Camera of this camera*/
+    uint8_t num_s_cnt;
+    struct mm_camera_obj *aux_cam_obj[MM_CAMERA_MAX_AUX_CAMERA];  /*Slave Camera of this camera*/
 } mm_camera_obj_t;
 
 typedef struct {
@@ -545,6 +629,7 @@
     cam_sync_type_t cam_type[MM_CAMERA_MAX_NUM_SENSORS];
     cam_sync_mode_t cam_mode[MM_CAMERA_MAX_NUM_SENSORS];
     uint8_t is_yuv[MM_CAMERA_MAX_NUM_SENSORS]; // 1=CAM_SENSOR_YUV, 0=CAM_SENSOR_RAW
+    uint32_t cam_index[MM_CAMERA_MAX_NUM_SENSORS]; //Actual cam index are stored in bits
 } mm_camera_ctrl_t;
 
 typedef enum {
@@ -552,6 +637,32 @@
     mm_camera_sync_call
 } mm_camera_call_type_t;
 
+/*internal structure for registring frame sync*/
+typedef struct {
+    mm_camera_obj_t *a_cam_obj;
+    uint32_t a_ch_id;
+    uint32_t a_stream_id;
+    uint8_t max_unmatched_frames;
+    mm_camera_buf_notify_t buf_cb;
+    uint8_t is_res_shared;
+    mm_camera_super_buf_priority_t priority;
+    void *userdata;
+} mm_camera_frame_sync_t;
+
+/*Payload for reg frame sync event in MCI*/
+typedef struct {
+    uint32_t stream_id;
+    mm_channel_t *a_ch_obj;
+    mm_stream_t *a_str_obj;
+    mm_camera_frame_sync_t *sync_attr;
+} mm_evt_paylod_reg_frame_sync;
+
+/*Payload for strart/stop frame sync event in MCI*/
+typedef struct {
+    uint32_t stream_id;
+    uint8_t enable_frame_sync;
+} mm_evt_paylod_trigger_frame_sync;
+
 /**********************************************************************************
 * external function declare
 ***********************************************************************************/
@@ -638,7 +749,6 @@
 extern int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
         uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
         mm_camera_stream_cb_type cb_type, void *userdata);
-
 extern int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
                                        uint32_t ch_id,
                                        uint32_t stream_id,
@@ -694,6 +804,16 @@
                                         uint32_t* sessionid);
 extern int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj,
                                    cam_sync_related_sensors_event_info_t *parms);
+extern int32_t mm_camera_reg_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_frame_sync_t *sync_attr);
+extern int32_t mm_camera_start_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id);
+extern int32_t mm_camera_stop_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id);
+extern int32_t mm_camera_switch_stream_cb(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id);
+
 
 /* mm_channel */
 extern int32_t mm_channel_fsm_fn(mm_channel_t *my_obj,
@@ -734,7 +854,7 @@
 /* utiltity fucntion declared in mm-camera-inteface2.c
  * and need be used by mm-camera and below*/
 uint32_t mm_camera_util_generate_handler(uint8_t index);
-const char * mm_camera_util_get_dev_name(uint32_t cam_handler);
+const char *mm_camera_util_get_dev_name(uint32_t cam_handler);
 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler);
 
 /* poll/cmd thread functions */
@@ -743,16 +863,12 @@
                                 mm_camera_poll_thread_type_t poll_type);
 extern int32_t mm_camera_poll_thread_release(mm_camera_poll_thread_t *poll_cb);
 extern int32_t mm_camera_poll_thread_add_poll_fd(
-                                mm_camera_poll_thread_t * poll_cb,
-                                uint32_t handler,
-                                int32_t fd,
-                                mm_camera_poll_notify_t nofity_cb,
-                                void *userdata,
-                                mm_camera_call_type_t);
+        mm_camera_poll_thread_t * poll_cb, uint8_t idx, uint32_t handler,
+        int32_t fd, mm_camera_poll_notify_t nofity_cb,
+        void *userdata, mm_camera_call_type_t);
 extern int32_t mm_camera_poll_thread_del_poll_fd(
-                                mm_camera_poll_thread_t * poll_cb,
-                                uint32_t handler,
-                                mm_camera_call_type_t);
+        mm_camera_poll_thread_t * poll_cb, uint8_t idx, uint32_t handler,
+        mm_camera_call_type_t);
 extern int32_t mm_camera_poll_thread_commit_updates(
         mm_camera_poll_thread_t * poll_cb);
 extern int32_t mm_camera_cmd_thread_launch(
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_dbg.h b/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_dbg.h
index 8298c78..8f7babe 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_dbg.h
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_dbg.h
@@ -114,6 +114,9 @@
                    const cam_global_debug_level_t level,
                    const char *func, const int line, const char *fmt, ...);
 
+void mm_camera_debug_open(void);
+void mm_camera_debug_close(void);
+
 #else
 
 #undef LOGD
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_muxer.h b/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_muxer.h
new file mode 100644
index 0000000..6e67276
--- /dev/null
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/inc/mm_camera_muxer.h
@@ -0,0 +1,191 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __MM_CAMERA_MUXER_H__
+#define __MM_CAMERA_MUXER_H__
+
+// System dependencies
+#include <media/msmb_camera.h>
+
+// Camera dependencies
+#include "cam_intf.h"
+#include "mm_camera.h"
+
+/*Frame sync node structure*/
+typedef struct mm_frame_sync_queue_node {
+    /*Number of objects*/
+    uint8_t num_objs;
+    /*Super buffer for different objects*/
+    mm_camera_super_buf_t super_buf[MAX_OBJS_FOR_FRAME_SYNC];
+    /*FrameID of these super buffers*/
+    uint32_t frame_idx;
+    /*Is this matched?*/
+    uint8_t matched;
+} mm_frame_sync_queue_node_t;
+
+
+/*Utility Functions for dual camera*/
+uint8_t mm_camera_util_get_index_by_num(uint8_t cam_num, uint32_t handler);
+uint32_t mm_camera_util_get_handle_by_num(uint8_t num1, uint32_t handle);
+uint32_t mm_camera_util_generate_handler_by_num(uint8_t cam_num, uint8_t index);
+const char *mm_camera_util_get_dev_name_by_num(uint8_t cam_num, uint32_t cam_handle);
+
+/*Function to handle command from client for Auxillary Cameras*/
+int32_t mm_camera_muxer_camera_open(uint8_t camera_idx,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_query_capability(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_register_event_notify(uint32_t camera_handle,
+        mm_camera_event_notify_t evt_cb,
+        void *user_data, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_close_camera(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_map_buf(uint32_t camera_handle, uint8_t buf_type,
+        int fd, size_t size, void *buffer, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_map_bufs(uint32_t camera_handle,
+        const cam_buf_map_type_list *buf_map_list,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_unmap_buf(uint32_t camera_handle,
+        uint8_t buf_type, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_set_parms(uint32_t camera_handle,
+        parm_buffer_t *parms, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_get_parms(uint32_t camera_handle,
+        parm_buffer_t *parms, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_do_auto_focus(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_cancel_auto_focus(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_prepare_snapshot(uint32_t camera_handle,
+        int32_t do_af_flag, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_start_zsl_snapshot(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_stop_zsl_snapshot(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj);
+uint32_t mm_camera_muxer_add_channel(uint32_t camera_handle,
+        mm_camera_channel_attr_t *attr, mm_camera_buf_notify_t channel_cb,
+        void *userdata, uint32_t src_id, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_delete_channel(uint32_t camera_handle, uint32_t ch_id,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_get_bundle_info(uint32_t camera_handle, uint32_t ch_id,
+        cam_bundle_config_t *bundle_info, mm_camera_obj_t *cam_obj);
+uint32_t mm_camera_muxer_add_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t src__ch_id, uint32_t src_stream_id,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_delete_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_link_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id, uint32_t linked_ch_id,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_config_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id, mm_camera_stream_config_t *config,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_map_stream_buf(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, int fd,
+        size_t size, void *buffer, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_map_stream_bufs(uint32_t camera_handle,
+        uint32_t ch_id, const cam_buf_map_type_list *buf_map_list,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_unmap_stream_buf(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        uint8_t buf_type, uint32_t buf_idx,
+        int32_t plane_idx, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_set_stream_parms(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_get_stream_parms(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_start_channel(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_stop_channel(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_qbuf(uint32_t camera_handle, uint32_t ch_id,
+        mm_camera_buf_def_t *buf, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_get_queued_buf_count(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_request_super_buf(uint32_t ch_id,
+        mm_camera_req_buf_t *buf, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_cancel_super_buf_request(uint32_t camera_handle,
+        uint32_t ch_id,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_flush_super_buf_queue(uint32_t camera_handle,
+        uint32_t ch_id,
+        uint32_t frame_idx, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_configure_notify_mode(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_super_buf_notify_mode_t notify_mode,
+        mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_process_advanced_capture(uint32_t camera_handle,
+         uint32_t ch_id, mm_camera_advanced_capture_t type,
+         int8_t start_flag, void *in_value, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_get_session_id(uint32_t camera_handle,
+        uint32_t* sessionid, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_flush(uint32_t camera_handle, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_register_stream_buf_cb(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
+        mm_camera_stream_cb_type cb_type, void *userdata, mm_camera_obj_t *cam_obj);
+int32_t mm_camera_muxer_reg_frame_sync(mm_camera_obj_t *cam_obj,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_intf_frame_sync_t *sync_attr);
+int32_t mm_camera_muxer_start_frame_sync(mm_camera_obj_t *cam_obj,
+        uint32_t ch_id, uint32_t stream_id);
+int32_t mm_camera_muxer_stop_frame_sync(mm_camera_obj_t *cam_obj,
+        uint32_t ch_id, uint32_t stream_id);
+int32_t mm_camera_muxer_switch_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_obj_t *cam_obj);
+
+/*Muxer internal functions*/
+void mm_camera_muxer_stream_frame_sync(mm_camera_super_buf_t *super_buf,
+        void *user_data);
+void mm_camera_muxer_channel_frame_sync(mm_camera_super_buf_t *super_buf,
+        void *user_data);
+int32_t mm_camera_muxer_do_frame_sync(
+        mm_frame_sync_queue_t *queue, mm_camera_super_buf_t *buffer,
+        mm_frame_sync_queue_node_t *dispatch_buf);
+void mm_camera_muxer_buf_done(mm_camera_super_buf_t *buffer);
+int32_t mm_muxer_frame_sync_queue_init(mm_frame_sync_queue_t *queue);
+int32_t mm_muxer_frame_sync_queue_deinit(mm_frame_sync_queue_t *queue);
+int32_t mm_camera_muxer_get_stream_bufs(mm_stream_t *my_obj);
+int32_t mm_camera_muxer_put_stream_bufs(mm_stream_t *my_obj);
+int32_t mm_camera_muxer_stream_frame_sync_flush(mm_stream_t *str_obj);
+int32_t mm_camera_muxer_channel_frame_sync_flush(mm_channel_t *my_obj);
+int32_t mm_camera_map_stream_buf_ops(uint32_t buf_idx,
+        int32_t plane_idx, int fd, size_t size,
+        void *buffer, cam_mapping_buf_type type,
+        void *userdata);
+int32_t mm_camera_bundled_map_stream_buf_ops(
+        const cam_buf_map_type_list *buf_map_list,
+        void *userdata);
+int32_t mm_camera_unmap_stream_buf_ops(uint32_t buf_idx,
+        int32_t plane_idx, cam_mapping_buf_type type, void *userdata);
+
+#endif /*__MM_CAMERA_MUXER_H */
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera.c
index 78ab597..bbe405c 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <sys/stat.h>
 #include <dlfcn.h>
 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
 #include IOCTL_H
@@ -45,6 +46,7 @@
 #include "mm_camera_sock.h"
 #include "mm_camera_interface.h"
 #include "mm_camera.h"
+#include "mm_camera_muxer.h"
 
 #define SET_PARM_BIT32(parm, parm_arr) \
     (parm_arr[parm/32] |= (1<<(parm%32)))
@@ -269,7 +271,9 @@
     if (NULL == my_obj) {
         goto on_error;
     }
-    dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl);
+
+    dev_name_value = mm_camera_util_get_dev_name_by_num(my_obj->my_num,
+            my_obj->my_hdl);
     if (NULL == dev_name_value) {
         goto on_error;
     }
@@ -439,6 +443,10 @@
     }
 #endif
 
+    if (my_obj->master_cam_obj != NULL) {
+        my_obj->master_cam_obj->num_s_cnt--;
+        my_obj->master_cam_obj->aux_cam_obj[my_obj->master_cam_obj->num_s_cnt] = NULL;
+    }
     pthread_mutex_destroy(&my_obj->msg_lock);
     pthread_mutex_destroy(&my_obj->cb_lock);
     pthread_mutex_destroy(&my_obj->evt_lock);
@@ -864,7 +872,7 @@
     if (NULL != ch_obj) {
         /* initialize channel obj */
         memset(ch_obj, 0, sizeof(mm_channel_t));
-        ch_hdl = mm_camera_util_generate_handler(ch_idx);
+        ch_hdl = mm_camera_util_generate_handler_by_num(my_obj->my_num, ch_idx);
         ch_obj->my_hdl = ch_hdl;
         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
         ch_obj->cam_obj = my_obj;
@@ -874,7 +882,6 @@
     }
 
     pthread_mutex_unlock(&my_obj->cam_lock);
-
     return ch_hdl;
 }
 
@@ -909,6 +916,10 @@
                                NULL,
                                NULL);
 
+        if (ch_obj->master_ch_obj != NULL) {
+            ch_obj->master_ch_obj->num_s_cnt--;
+            ch_obj->master_ch_obj->aux_ch_obj[ch_obj->master_ch_obj->num_s_cnt] = NULL;
+        }
         pthread_mutex_destroy(&ch_obj->ch_lock);
         memset(ch_obj, 0, sizeof(mm_channel_t));
     } else {
@@ -1090,8 +1101,8 @@
         uint32_t ch_id)
 {
     int32_t rc = -1;
-    mm_channel_t * ch_obj =
-        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    mm_channel_t *ch_obj =
+            mm_camera_util_get_channel_by_handler(my_obj, ch_id);
 
     if (NULL != ch_obj) {
         pthread_mutex_lock(&ch_obj->ch_lock);
@@ -1530,9 +1541,8 @@
         payload.actions = actions;
 
         rc = mm_channel_fsm_fn(ch_obj,
-                               MM_CHANNEL_EVT_DO_STREAM_ACTION,
-                               (void*)&payload,
-                               NULL);
+                MM_CHANNEL_EVT_DO_ACTION,
+                (void*)&payload, NULL);
     } else {
         pthread_mutex_unlock(&my_obj->cam_lock);
     }
@@ -1731,8 +1741,7 @@
         }
         /* remove evt fd from the polling thraed when unreg the last event */
         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
-                                               my_obj->my_hdl,
-                                               mm_camera_sync_call);
+                0, my_obj->my_hdl, mm_camera_sync_call);
     } else {
         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
         if (rc < 0) {
@@ -1742,11 +1751,8 @@
         }
         /* add evt fd to polling thread when subscribe the first event */
         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
-                                               my_obj->my_hdl,
-                                               my_obj->ctrl_fd,
-                                               mm_camera_event_notify,
-                                               (void*)my_obj,
-                                               mm_camera_sync_call);
+                0, my_obj->my_hdl, my_obj->ctrl_fd, mm_camera_event_notify,
+               (void*)my_obj, mm_camera_sync_call);
     }
     return rc;
 }
@@ -2400,14 +2406,178 @@
     return rc;
 }
 
-#ifdef QCAMERA_REDEFINE_LOG
+/*===========================================================================
+ * FUNCTION   : mm_camera_register_frame_sync
+ *
+ * DESCRIPTION: register/configure frame sync for this camera
+ *
+ * PARAMETERS :
+ *   @my_obj    : camera object
+ *   @ch_id     : channel handle
+ *   @stream_id : stream that will be linked
+ *   @sync_attr : attibutes for sync queue
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+int32_t mm_camera_reg_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_frame_sync_t *sync_attr)
+{
+    int32_t rc = -1;
+    uint32_t sync_id = 0;
+    mm_evt_paylod_reg_frame_sync payload;
 
+    mm_channel_t *ch_obj =
+            mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    mm_channel_t *a_ch_obj = NULL;
+
+    if (sync_attr != NULL && sync_attr->a_cam_obj != NULL) {
+        a_ch_obj = mm_camera_util_get_channel_by_handler(
+                sync_attr->a_cam_obj, sync_attr->a_ch_id);
+    } else {
+        LOGE("Invalid arguments");
+        pthread_mutex_unlock(&my_obj->cam_lock);
+        return rc;
+    }
+
+    if (NULL != ch_obj && a_ch_obj != NULL) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+        memset(&payload, 0, sizeof(payload));
+        payload.stream_id = stream_id;
+        payload.sync_attr = sync_attr;
+        payload.a_ch_obj = a_ch_obj;
+        rc = mm_channel_fsm_fn(ch_obj,
+                MM_CHANNEL_EVT_REG_FRAME_SYNC,
+                (void*)&payload, (void*)&sync_id);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_start_frame_sync
+ *
+ * DESCRIPTION: start frame sync under this camera
+ *
+ * PARAMETERS :
+ *   @my_obj    : camera object
+ *   @ch_id     : channel handle
+ *   @stream_id : stream that will be linked
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+int32_t mm_camera_start_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = -1;
+
+    mm_channel_t *ch_obj =
+            mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+        mm_evt_paylod_trigger_frame_sync payload;
+        payload.enable_frame_sync = 1;
+        payload.stream_id = stream_id;
+        rc = mm_channel_fsm_fn(ch_obj,
+                MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC,
+                (void*)&payload, NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_stop_frame_sync
+ *
+ * DESCRIPTION: stop frame sync under this camera
+ *
+ * PARAMETERS :
+ *   @my_obj    : camera object
+ *   @ch_id     : channel handle
+ *   @stream_id : stream that will be linked
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+int32_t mm_camera_stop_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = -1;
+
+    mm_channel_t *ch_obj =
+            mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+        mm_evt_paylod_trigger_frame_sync payload;
+        payload.enable_frame_sync = 0;
+        payload.stream_id = stream_id;
+        rc = mm_channel_fsm_fn(ch_obj,
+                MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC,
+                (void*)&payload, NULL);
+
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_switch_stream_cb
+ *
+ * DESCRIPTION: switch stream callbacks in case of multiple instance of streams
+ *
+ * PARAMETERS :
+ *   @my_obj    : camera object
+ *   @ch_id     : channel handle
+ *   @stream_id : stream id
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+int32_t mm_camera_switch_stream_cb(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int rc = -1;
+    mm_channel_t *ch_obj = NULL;
+    ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
+
+    if (NULL != ch_obj) {
+        pthread_mutex_lock(&ch_obj->ch_lock);
+        pthread_mutex_unlock(&my_obj->cam_lock);
+        rc = mm_channel_fsm_fn(ch_obj,
+                MM_CHANNEL_EVT_SWITCH_STREAM_CB,
+                (void *)&stream_id,
+                NULL);
+    } else {
+        pthread_mutex_unlock(&my_obj->cam_lock);
+    }
+
+    return rc;
+}
+
+#ifdef QCAMERA_REDEFINE_LOG
 /*===========================================================================
  * DESCRIPTION: mm camera debug interface
  *
  *==========================================================================*/
 pthread_mutex_t dbg_log_mutex;
 
+static int         cam_soft_assert     = 0;
+static FILE       *cam_log_fd          = NULL;
+static const char *cam_log_filename    = "/data/misc/camera/cam_dbg_log_hal.txt";
+
 #undef LOG_TAG
 #define LOG_TAG "QCamera"
 #define CDBG_MAX_STR_LEN 1024
@@ -2556,6 +2726,27 @@
     ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name,
       cam_dbg_level_to_str[level], func, line, str_buffer);
   }
+
+
+  if (cam_log_fd != NULL) {
+    char new_str_buffer[CDBG_MAX_STR_LEN];
+    pthread_mutex_lock(&dbg_log_mutex);
+
+    struct timeval tv;
+    struct timezone tz;
+    gettimeofday(&tv, &tz);
+
+    struct tm *now;
+    now = gmtime((time_t *)&tv.tv_sec);
+    snprintf(new_str_buffer, CDBG_MAX_STR_LEN, "%2d %02d:%02d:%02d.%03ld %d:%d Camera%s%s %d: %s: %s",
+              now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, tv.tv_usec, getpid(),gettid(),
+              cam_dbg_level_to_str[level], cam_loginfo[module].name,
+              line, func, str_buffer);
+
+    fprintf(cam_log_fd, "%s", new_str_buffer);
+    pthread_mutex_unlock(&dbg_log_mutex);
+  }
+
 }
 
  /** mm_camera_set_dbg_log_properties
@@ -2567,15 +2758,9 @@
 void mm_camera_set_dbg_log_properties(void) {
   int          i;
   unsigned int j;
-  static int   boot_init = 1;
   char         property_value[PROPERTY_VALUE_MAX] = {0};
   char         default_value[PROPERTY_VALUE_MAX]  = {0};
 
-  if (boot_init) {
-      boot_init = 0;
-      pthread_mutex_init(&dbg_log_mutex, 0);
-  }
-
   /* set global and individual module logging levels */
   pthread_mutex_lock(&dbg_log_mutex);
   for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) {
@@ -2605,4 +2790,62 @@
   pthread_mutex_unlock(&dbg_log_mutex);
 }
 
+ /** mm_camera_debug_open
+   *
+   * Open log file if it is enabled
+   *
+   *  Return: N/A
+   **/
+  void mm_camera_debug_open(void) {
+    char         property_value[PROPERTY_VALUE_MAX] = {0};
+
+    pthread_mutex_init(&dbg_log_mutex, 0);
+    mm_camera_set_dbg_log_properties();
+
+    /* configure asserts */
+    property_get("persist.camera.debug.assert", property_value, "0");
+    cam_soft_assert = atoi(property_value);
+
+    /* open default log file according to property setting */
+    if (cam_log_fd == NULL) {
+      property_get("persist.camera.debug.logfile", property_value, "0");
+      if (atoi(property_value)) {
+        /* we always put the current process id at end of log file name */
+        char pid_str[255] = {0};
+        char new_log_file_name[1024] = {0};
+
+        snprintf(pid_str, 255, "_%d", getpid());
+        strlcpy(new_log_file_name, cam_log_filename, sizeof(new_log_file_name));
+        strlcat(new_log_file_name, pid_str, sizeof(new_log_file_name));
+
+        cam_log_fd = fopen(new_log_file_name, "a");
+        if (cam_log_fd == NULL) {
+          ALOGE("Failed to create debug log file %s\n",
+              new_log_file_name);
+        } else {
+          ALOGD("Debug log file %s open\n", new_log_file_name);
+        }
+      } else {
+        property_set("persist.camera.debug.logfile", "0");
+        ALOGD("Debug log file is not enabled");
+        return;
+      }
+    }
+  }
+
+   /** cam_debug_close
+   *
+   *  Release logging resources.
+   *
+   *  Return: N/A
+   **/
+  void mm_camera_debug_close(void) {
+
+    if (cam_log_fd != NULL) {
+      fclose(cam_log_fd);
+      cam_log_fd = NULL;
+    }
+
+    pthread_mutex_destroy(&dbg_log_mutex);
+  }
 #endif
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_channel.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_channel.c
index e75d962..59844b1 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_channel.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_channel.c
@@ -36,6 +36,8 @@
 #include "mm_camera_dbg.h"
 #include "mm_camera_interface.h"
 #include "mm_camera.h"
+#include "mm_camera_muxer.h"
+
 
 extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler);
 extern mm_channel_t * mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,
@@ -58,6 +60,12 @@
                                    uint32_t stream_id);
 uint32_t mm_channel_link_stream(mm_channel_t *my_obj,
         mm_camera_stream_link_t *stream_link);
+uint32_t mm_channel_reg_frame_sync(mm_channel_t *my_obj,
+        mm_evt_paylod_reg_frame_sync *sync);
+int32_t mm_channel_trigger_frame_sync(mm_channel_t *my_obj,
+        mm_evt_paylod_trigger_frame_sync *payload);
+int32_t mm_channel_switch_stream_callback(mm_channel_t *my_obj,
+        uint32_t stream_id);
 int32_t mm_channel_config_stream(mm_channel_t *my_obj,
                                  uint32_t stream_id,
                                  mm_camera_stream_config_t *config);
@@ -163,6 +171,7 @@
 {
     int i;
     mm_stream_t *s_obj = NULL;
+
     for(i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
         if ((MM_STREAM_STATE_NOTUSED != ch_obj->streams[i].state) &&
             (handler == ch_obj->streams[i].my_hdl)) {
@@ -187,7 +196,9 @@
 static void mm_channel_dispatch_super_buf(mm_camera_cmdcb_t *cmd_cb,
                                           void* user_data)
 {
-    mm_channel_t * my_obj = (mm_channel_t *)user_data;
+    mm_channel_t *my_obj = (mm_channel_t *)user_data;
+    mm_channel_t *m_obj = my_obj;
+    uint32_t i = 0;
 
     if (NULL == my_obj) {
         return;
@@ -199,9 +210,29 @@
         return;
     }
 
-    if (my_obj->bundle.super_buf_notify_cb) {
-        my_obj->bundle.super_buf_notify_cb(&cmd_cb->u.superbuf, my_obj->bundle.user_data);
+
+    if (m_obj->master_ch_obj != NULL) {
+        //get master object
+        m_obj = m_obj->master_ch_obj;
     }
+
+    pthread_mutex_lock(&m_obj->frame_sync.sync_lock);
+    if(m_obj->frame_sync.is_active) {
+        //Frame sync enabled on master
+        mm_camera_muxer_channel_frame_sync(&cmd_cb->u.superbuf, m_obj);
+    } else if (my_obj->bundle.super_buf_notify_cb && my_obj->bundle.is_cb_active) {
+        //Super buffer channel callback is active
+        my_obj->bundle.super_buf_notify_cb(&cmd_cb->u.superbuf, my_obj->bundle.user_data);
+    } else {
+        //Nothing enabled. Return this buffer
+        mm_camera_super_buf_t *buffer = &cmd_cb->u.superbuf;
+        for (i=0; i < buffer->num_bufs; i++) {
+            if (buffer->bufs[i] != NULL) {
+                mm_channel_qbuf(my_obj, buffer->bufs[i]);
+            }
+        }
+    }
+    pthread_mutex_unlock(&m_obj->frame_sync.sync_lock);
 }
 
 /*===========================================================================
@@ -241,15 +272,17 @@
                         &cmd_cb->u.buf);
     } else if (MM_CAMERA_CMD_TYPE_REQ_DATA_CB  == cmd_cb->cmd_type) {
         /* skip frames if needed */
-        ch_obj->pending_cnt = cmd_cb->u.req_buf.num_buf_requested;
+        ch_obj->pending_cnt += cmd_cb->u.req_buf.num_buf_requested;
         ch_obj->pending_retro_cnt = cmd_cb->u.req_buf.num_retro_buf_requested;
         ch_obj->req_type = cmd_cb->u.req_buf.type;
         ch_obj->bWaitForPrepSnapshotDone = 0;
+        if (cmd_cb->u.req_buf.frame_idx) {
+            ch_obj->requested_frame_id[ch_obj->frame_req_cnt++] =
+                    cmd_cb->u.req_buf.frame_idx;
+            LOGH("FrameID Request from Q = %d", cmd_cb->u.req_buf.frame_idx);
+        }
 
-        LOGH("pending cnt (%d), retro count (%d)"
-                "req_type (%d) is_primary (%d)",
-                 ch_obj->pending_cnt, ch_obj->pending_retro_cnt,
-                ch_obj->req_type, cmd_cb->u.req_buf.primary_only);
+        LOGH("pending cnt (%d)", ch_obj->pending_cnt);
         if (!ch_obj->pending_cnt || (ch_obj->pending_retro_cnt > ch_obj->pending_cnt)) {
           ch_obj->pending_retro_cnt = ch_obj->pending_cnt;
         }
@@ -485,11 +518,19 @@
             }
             mm_frame_sync_unlock_queues();
         } else {
-           node = mm_channel_superbuf_dequeue(&ch_obj->bundle.superbuf_queue, ch_obj);
+           if (ch_obj->frame_req_cnt == 0) {
+               node = mm_channel_superbuf_dequeue(&ch_obj->bundle.superbuf_queue, ch_obj);
+           } else {
+               uint32_t req_frame = ch_obj->requested_frame_id[ch_obj->cur_req_idx];
+               node = mm_channel_superbuf_dequeue_frame_internal(
+                       &ch_obj->bundle.superbuf_queue,
+                       req_frame);
+           }
            if (node != NULL) {
                if (ch_obj->isConfigCapture &&
                        ((node->frame_idx <
-                        ch_obj->capture_frame_id[ch_obj->cur_capture_idx]))) {
+                        ch_obj->capture_frame_id[ch_obj->cur_capture_idx]))
+                        && (ch_obj->frame_req_cnt == 0)) {
                    uint8_t i;
                    LOGD("Not expected super buffer. frameID = %d expected = %d",
                            node->frame_idx, ch_obj->capture_frame_id[ch_obj->cur_capture_idx]);
@@ -515,6 +556,9 @@
                   ch_obj->pending_retro_cnt--;
                 }
 
+                if (ch_obj->frame_req_cnt != 0) {
+                    ch_obj->cur_req_idx++;
+                }
                 if (((ch_obj->pending_cnt == 0) ||
                       (ch_obj->stopZslSnapshot == 1)) &&
                       (ch_obj->manualZSLSnapshot == FALSE) &&
@@ -528,6 +572,10 @@
                     ch_obj->needLEDFlash = FALSE;
                     ch_obj->bracketingState = MM_CHANNEL_BRACKETING_STATE_OFF;
                     ch_obj->isConfigCapture = FALSE;
+                    ch_obj->cur_req_idx = 0;
+                    ch_obj->frame_req_cnt = 0;
+                    memset(ch_obj->requested_frame_id, 0,
+                            sizeof(uint8_t) * MAX_CAPTURE_BATCH_NUM);
                 }
 
                 if (ch_obj->isConfigCapture) {
@@ -792,6 +840,22 @@
             rc = 0;
         }
         break;
+    case MM_CHANNEL_EVT_REG_FRAME_SYNC:
+        {
+            mm_evt_paylod_reg_frame_sync *frame_sync = NULL;
+            uint32_t s_hdl = 0;
+            frame_sync = (mm_evt_paylod_reg_frame_sync *) in_val;
+            s_hdl = mm_channel_reg_frame_sync(my_obj, frame_sync);
+            *((uint32_t*)out_val) = s_hdl;
+            rc = 0;
+        }
+        break;
+    case MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC:
+        {
+            rc = mm_channel_trigger_frame_sync(my_obj,
+                    (mm_evt_paylod_trigger_frame_sync *)in_val);
+        }
+        break;
     case MM_CHANNEL_EVT_DEL_STREAM:
         {
             uint32_t s_id = *((uint32_t *)in_val);
@@ -850,7 +914,7 @@
             rc = mm_channel_get_stream_parm(my_obj, payload);
         }
         break;
-    case MM_CHANNEL_EVT_DO_STREAM_ACTION:
+    case MM_CHANNEL_EVT_DO_ACTION:
         {
             mm_evt_paylod_do_stream_action_t *payload =
                 (mm_evt_paylod_do_stream_action_t *)in_val;
@@ -981,7 +1045,7 @@
             rc = mm_channel_get_stream_parm(my_obj, payload);
         }
         break;
-    case MM_CHANNEL_EVT_DO_STREAM_ACTION:
+    case MM_CHANNEL_EVT_DO_ACTION:
         {
             mm_evt_paylod_do_stream_action_t *payload =
                 (mm_evt_paylod_do_stream_action_t *)in_val;
@@ -1098,6 +1162,18 @@
                     payload->stream_id, payload->buf_cb);
         }
         break;
+    case MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC:
+        {
+            rc = mm_channel_trigger_frame_sync(my_obj,
+                    (mm_evt_paylod_trigger_frame_sync *)in_val);
+        }
+        break;
+    case MM_CHANNEL_EVT_SWITCH_STREAM_CB:
+        {
+            uint32_t stream_id = *((uint32_t *)in_val);
+            rc = mm_channel_switch_stream_callback(my_obj, stream_id);
+        }
+        break;
      default:
         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
                     my_obj->state, evt, in_val, out_val);
@@ -1169,6 +1245,12 @@
         my_obj->bundle.superbuf_queue.attr = *attr;
     }
 
+    my_obj->num_s_cnt = 0;
+    memset(&my_obj->frame_sync, 0, sizeof(my_obj->frame_sync));
+    pthread_mutex_init(&my_obj->frame_sync.sync_lock, NULL);
+    mm_muxer_frame_sync_queue_init(&my_obj->frame_sync.superbuf_queue);
+    my_obj->bundle.is_cb_active = 1;
+
     LOGD("Launch data poll thread in channel open");
     snprintf(my_obj->poll_thread[0].threadName, THREAD_NAME_SIZE, "CAM_dataPoll");
     mm_camera_poll_thread_launch(&my_obj->poll_thread[0],
@@ -1195,6 +1277,9 @@
     /* stop data poll thread */
     mm_camera_poll_thread_release(&my_obj->poll_thread[0]);
 
+    mm_muxer_frame_sync_queue_deinit(&my_obj->frame_sync.superbuf_queue);
+    pthread_mutex_destroy(&my_obj->frame_sync.sync_lock);
+
     /* memset bundle info */
     memset(&my_obj->bundle, 0, sizeof(mm_channel_bundle_t));
 
@@ -1256,6 +1341,149 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : mm_channel_reg_frame_sync
+ *
+ * DESCRIPTION: register/configure frame sync for stream
+ *
+ * PARAMETERS :
+ *   @my_obj    : camera object
+ *   @ch_id     : channel handle
+ *   @stream_id : stream that will be linked
+ *   @sync_attr    : attibutes for sync queue
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+uint32_t mm_channel_reg_frame_sync(mm_channel_t *my_obj,
+        mm_evt_paylod_reg_frame_sync *sync)
+{
+    uint32_t rc = 0;
+    mm_stream_t * stream_obj = NULL;
+
+    if (NULL == sync || sync->a_ch_obj == NULL) {
+        LOGE("Invalid arguments");
+        return -1;
+    }
+
+    if (sync->stream_id != 0) {
+        //Frame sync reg for stream
+        stream_obj = mm_channel_util_get_stream_by_handler(
+                my_obj, sync->stream_id);
+        sync->a_str_obj = mm_channel_util_get_stream_by_handler(
+                sync->a_ch_obj, sync->sync_attr->a_stream_id);
+        return mm_stream_fsm_fn(stream_obj,
+                MM_STREAM_EVT_REG_FRAME_SYNC,
+                sync,
+                NULL);
+    }
+
+    //Frame sync reg for channel
+    mm_frame_sync_t *frame_sync = &my_obj->frame_sync;
+    pthread_mutex_lock(&frame_sync->sync_lock);
+    mm_frame_sync_queue_t *queue = NULL;
+    if (sync->sync_attr->buf_cb == NULL) {
+        frame_sync->super_buf_notify_cb =
+                my_obj->bundle.super_buf_notify_cb;
+    } else {
+        frame_sync->super_buf_notify_cb = sync->sync_attr->buf_cb;
+    }
+    if (sync->sync_attr->userdata == NULL) {
+        frame_sync->user_data =
+                my_obj->bundle.user_data;
+    } else {
+        frame_sync->user_data = sync->sync_attr->userdata;
+    }
+    queue = &frame_sync->superbuf_queue;
+    queue->max_unmatched_frames =
+            sync->sync_attr->max_unmatched_frames;
+    queue->priority = sync->sync_attr->priority;
+    queue->num_objs = 0;
+    memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
+    queue->bundled_objs[queue->num_objs] = my_obj->my_hdl;
+    queue->num_objs++;
+    queue->bundled_objs[queue->num_objs] = sync->a_ch_obj->my_hdl;
+    queue->num_objs++;
+
+    my_obj->aux_ch_obj[my_obj->num_s_cnt++] = sync->a_ch_obj;
+    sync->a_ch_obj->master_ch_obj = my_obj;
+    pthread_mutex_unlock(&frame_sync->sync_lock);
+    LOGD("stream handle = %d", rc);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_channel_trigger_frame_sync
+ *
+ * DESCRIPTION: start/stop frame sync under this channel
+ *
+ * PARAMETERS :
+ *   @my_obj    : camera object
+ *   @ch_id     : channel handle
+ *   @stream_id : stream that will be linked
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+int32_t mm_channel_trigger_frame_sync(mm_channel_t *my_obj,
+        mm_evt_paylod_trigger_frame_sync *payload)
+{
+    int32_t rc = 0;
+    mm_stream_t * stream_obj = NULL;
+    mm_channel_t *m_obj = my_obj;
+
+    if (m_obj->master_ch_obj != NULL) {
+        m_obj = m_obj->master_ch_obj;
+    }
+
+    if (payload->stream_id != 0) {
+        stream_obj = mm_channel_util_get_stream_by_handler(
+                my_obj, payload->stream_id);
+        return mm_stream_fsm_fn(stream_obj,
+                MM_STREAM_EVT_TRIGGER_FRAME_SYNC,
+                &payload->enable_frame_sync,
+                NULL);
+    }
+
+    uint8_t start_sync = payload->enable_frame_sync;
+    mm_frame_sync_t *frame_sync = &m_obj->frame_sync;
+    pthread_mutex_lock(&frame_sync->sync_lock);
+    frame_sync->is_active = start_sync;
+    pthread_mutex_unlock(&frame_sync->sync_lock);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_channel_switch_stream_callback
+ *
+ * DESCRIPTION: switch stream callbacks in case of multiple instance of streams
+ *
+ * PARAMETERS :
+ *   @my_obj       : camera object
+ *   @ch_id        : channel handle
+ *   @stream_id : stream id
+ *
+ * RETURN    : int32_t type of status
+ *             0  -- success
+ *             1 --  failure
+ *==========================================================================*/
+int32_t mm_channel_switch_stream_callback(mm_channel_t *my_obj,
+        uint32_t stream_id)
+{
+    int32_t rc = -1;
+    mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj, stream_id);
+
+    if (NULL != s_obj) {
+        rc = mm_stream_fsm_fn(s_obj,
+                MM_STREAM_EVT_SWITCH_STREAM_CB,
+                NULL,
+                NULL);
+    }
+    return rc;
+}
+
+/*===========================================================================
  * FUNCTION   : mm_channel_add_stream
  *
  * DESCRIPTION: add a stream into the channel
@@ -1290,14 +1518,9 @@
     /* initialize stream object */
     memset(stream_obj, 0, sizeof(mm_stream_t));
     stream_obj->fd = -1;
-    stream_obj->my_hdl = mm_camera_util_generate_handler(idx);
+    stream_obj->my_hdl = mm_camera_util_generate_handler_by_num (
+            my_obj->cam_obj->my_num, idx);
     stream_obj->ch_obj = my_obj;
-    pthread_mutex_init(&stream_obj->buf_lock, NULL);
-    pthread_mutex_init(&stream_obj->cb_lock, NULL);
-    pthread_mutex_init(&stream_obj->cmd_lock, NULL);
-    pthread_cond_init(&stream_obj->buf_cond, NULL);
-    memset(stream_obj->buf_status, 0,
-            sizeof(stream_obj->buf_status));
     stream_obj->state = MM_STREAM_STATE_INITED;
 
     /* acquire stream */
@@ -1358,6 +1581,7 @@
                           NULL,
                           NULL);
 
+    LOGD("stream handle = %d rc = %d", stream_id, rc);
     return rc;
 }
 
@@ -1812,6 +2036,10 @@
     /* send cam_sem_post to wake up cmd thread to dispatch super buffer */
     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
     if (NULL != node) {
+        if(my_obj->frame_sync.is_active) {
+            my_obj->frame_sync.num_buf_requested =
+                    buf->num_buf_requested;
+        }
         memset(node, 0, sizeof(mm_camera_cmdcb_t));
         node->cmd_type = MM_CAMERA_CMD_TYPE_REQ_DATA_CB;
         node->u.req_buf = *buf;
@@ -2247,16 +2475,14 @@
     }
 
     mm_stream_t* s_obj = mm_channel_util_get_stream_by_handler(my_obj,
-                                                               payload->buf_maps[0].stream_id);
+            payload->buf_maps[0].stream_id);
     if (NULL != s_obj) {
         if (s_obj->ch_obj != my_obj) {
             /* No op. on linked streams */
             return 0;
         }
-
         rc = mm_stream_map_bufs(s_obj, payload);
     }
-
     return rc;
 }
 
@@ -3036,7 +3262,7 @@
  *                : NULL if not found
  *==========================================================================*/
 mm_channel_queue_node_t* mm_channel_superbuf_dequeue_frame_internal(
-        mm_channel_queue_t * queue, uint32_t frame_idx)
+        mm_channel_queue_t *queue, uint32_t frame_idx)
 {
     cam_node_t* node = NULL;
     struct cam_list *head = NULL;
@@ -3056,17 +3282,16 @@
         node = member_of(pos, cam_node_t, list);
         super_buf = (mm_channel_queue_node_t*)node->data;
         if (super_buf && super_buf->matched &&
-                (super_buf->frame_idx == frame_idx)) {
+                (frame_idx <= super_buf->frame_idx)) {
             /* remove from the queue */
             cam_list_del_node(&node->list);
             queue->que.size--;
             queue->match_cnt--;
-            LOGH("Found match frame %d", frame_idx);
+            LOGH("Found best match frame %d requested = %d",
+                    super_buf->frame_idx, frame_idx);
             free(node);
             break;
-        }
-        else {
-            LOGH("match frame not found %d", frame_idx);
+        } else {
             super_buf = NULL;
         }
         pos = pos->next;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c
index cdd9ab9..8537ac1 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_interface.c
@@ -46,20 +46,29 @@
 #include "mm_camera_dbg.h"
 #include "mm_camera_interface.h"
 #include "mm_camera.h"
+#include "mm_camera_muxer.h"
 
 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
-
 static mm_camera_ctrl_t g_cam_ctrl;
 
 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
-static uint16_t g_handler_history_count = 0; /* history count for handler */
+static uint8_t g_handler_history_count = 0; /* history count for handler */
 
 // 16th (starting from 0) bit tells its a BACK or FRONT camera
-#define CAM_SENSOR_FACING_MASK (1U<<16)
+#define CAM_SENSOR_FACING_MASK       (1U<<16)
+
+#ifdef DUAL_CAM_TEST //Temporary macro. Will be removed once we finalize sensor change.
 // 24th (starting from 0) bit tells its a MAIN or AUX camera
-#define CAM_SENSOR_TYPE_MASK (1U<<24)
-// 25th (starting from 0) bit tells its YUV sensor or not
-#define CAM_SENSOR_FORMAT_MASK (1U<<25)
+#define CAM_SENSOR_MODE_MASK_MAIN    (1U<<24)
+#define CAM_SENSOR_MODE_MASK_AUX     (1U<<25)
+#define CAM_SENSOR_MODE_MASK_SECURE  (1U<<26)
+
+// 28th (starting from 0) bit tells its YUV sensor or not
+#define CAM_SENSOR_FORMAT_MASK       (1U<<28)
+#else
+#define CAM_SENSOR_TYPE_MASK         (1U<<24)
+#define CAM_SENSOR_FORMAT_MASK       (1U<<25)
+#endif
 
 /*===========================================================================
  * FUNCTION   : mm_camera_util_generate_handler
@@ -97,7 +106,7 @@
  *==========================================================================*/
 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
 {
-    return (handler&0x000000ff);
+    return (handler & 0x000000ff);
 }
 
 /*===========================================================================
@@ -135,12 +144,62 @@
 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
 {
     mm_camera_obj_t *cam_obj = NULL;
-    uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
+    uint8_t cam_idx = 0;
 
-    if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS &&
-        (NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
-        (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
-        cam_obj = g_cam_ctrl.cam_obj[cam_idx];
+    for (cam_idx = 0; cam_idx < MM_CAMERA_MAX_NUM_SENSORS; cam_idx++) {
+         if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
+                (cam_handle == (uint32_t)g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
+            cam_obj = g_cam_ctrl.cam_obj[cam_idx];
+            break;
+        }
+    }
+    return cam_obj;
+}
+
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_util_set_camera_object
+ *
+ * DESCRIPTION: utility function to set camera object to global structure
+ *
+ * PARAMETERS :
+ *   @cam_idx : index to store cambera object
+ *   @obj     : Camera object to store
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj)
+{
+    int32_t rc = 0;
+    pthread_mutex_lock(&g_intf_lock);
+    if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
+        g_cam_ctrl.cam_obj[cam_idx] = obj;
+    } else {
+        rc = -1;
+    }
+    pthread_mutex_unlock(&g_intf_lock);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_util_get_camera_head_obj
+ *
+ * DESCRIPTION: utility function to get camera object from camera handle
+ *
+ * PARAMETERS :
+ *   @cam_handle: camera handle
+ *
+ * RETURN     : ptr to the master/primary camera object
+ *==========================================================================*/
+mm_camera_obj_t* mm_camera_util_get_camera_head(uint32_t cam_handle)
+{
+    mm_camera_obj_t *cam_obj = NULL;
+
+    cam_obj = mm_camera_util_get_camera_by_handler(cam_handle);
+    if (cam_obj != NULL && cam_obj->master_cam_obj != NULL) {
+        cam_obj = cam_obj->master_cam_obj;
     }
     return cam_obj;
 }
@@ -185,21 +244,43 @@
 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
 {
     int32_t rc = -1;
-    mm_camera_obj_t * my_obj = NULL;
+    mm_camera_obj_t *my_obj = NULL;
+    uint32_t handle = 0;
+    uint32_t aux_handle = 0;
 
     LOGD("E: camera_handler = %d ", camera_handle);
 
     pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    handle = get_main_camera_handle(camera_handle);
+    aux_handle = get_aux_camera_handle(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_query_capability(my_obj);
+    if (handle) {
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_query_capability(my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     } else {
         pthread_mutex_unlock(&g_intf_lock);
     }
-    LOGD("X rc = %d", rc);
+
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_query_capability(aux_handle, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    LOGH("camera_handle = %d rc = %d X", camera_handle, rc);
     return rc;
 }
 
@@ -225,15 +306,33 @@
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_set_parms(my_obj, parms);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_set_parms(aux_handle,
+                    parms, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_set_parms(my_obj, parms);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
 }
@@ -261,18 +360,36 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_get_parms(aux_handle,
+                    parms, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_get_parms(my_obj, parms);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_get_parms(my_obj, parms);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
+
 }
 
 /*===========================================================================
@@ -293,17 +410,34 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_do_auto_focus(my_obj);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_do_auto_focus(aux_handle, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_do_auto_focus(my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("rc = %d camera_handle = %d X", rc, camera_handle);
     return rc;
 }
 
@@ -323,17 +457,33 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_cancel_auto_focus(my_obj);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_cancel_auto_focus(aux_handle, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_cancel_auto_focus(my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("rc = %d camera_handle = %d X", rc, camera_handle);
     return rc;
 }
 
@@ -355,17 +505,37 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_prepare_snapshot(aux_handle,
+                    do_af_flag, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+
+            rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+        return rc;
+    }
+    LOGH("rc = %d camera_handle = %d X", rc, camera_handle);
     return rc;
 }
 
@@ -385,16 +555,33 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_flush(my_obj);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_flush(aux_handle, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_flush(my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
 }
@@ -414,37 +601,69 @@
 static int32_t mm_camera_intf_close(uint32_t camera_handle)
 {
     int32_t rc = -1;
-    uint8_t cam_idx = camera_handle & 0x00ff;
-    mm_camera_obj_t * my_obj = NULL;
+    uint8_t cam_idx = -1;
+    mm_camera_obj_t *my_obj = NULL;
 
     LOGD("E: camera_handler = %d ", camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if (my_obj){
-        my_obj->ref_count--;
-
-        if(my_obj->ref_count > 0) {
-            /* still have reference to obj, return here */
-            LOGD("ref_count=%d\n", my_obj->ref_count);
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
             pthread_mutex_unlock(&g_intf_lock);
-            rc = 0;
+            rc = mm_camera_muxer_close_camera(aux_handle, my_obj);
+        }
+    }
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if (my_obj){
+            if (my_obj->aux_cam_obj[0] != NULL) {
+                /*Close aux cameras*/
+                pthread_mutex_lock(&my_obj->muxer_lock);
+                pthread_mutex_unlock(&g_intf_lock);
+                rc = mm_camera_muxer_close_camera(
+                        my_obj->aux_cam_obj[0]->my_hdl, my_obj);
+                pthread_mutex_lock(&g_intf_lock);
+            }
+
+            cam_idx = mm_camera_util_get_index_by_num(
+                    my_obj->my_num, my_obj->my_hdl);
+            my_obj->ref_count--;
+            if(my_obj->ref_count > 0) {
+                /* still have reference to obj, return here */
+                LOGD("ref_count=%d\n", my_obj->ref_count);
+                pthread_mutex_unlock(&g_intf_lock);
+                rc = 0;
+            } else {
+                /* need close camera here as no other reference
+                 * first empty g_cam_ctrl's referent to cam_obj */
+                g_cam_ctrl.cam_obj[cam_idx] = NULL;
+                pthread_mutex_lock(&my_obj->cam_lock);
+                pthread_mutex_unlock(&g_intf_lock);
+                rc = mm_camera_close(my_obj);
+                pthread_mutex_destroy(&my_obj->cam_lock);
+                pthread_mutex_destroy(&my_obj->muxer_lock);
+                free(my_obj);
+                my_obj = NULL;
+            }
         } else {
-            /* need close camera here as no other reference
-             * first empty g_cam_ctrl's referent to cam_obj */
-            g_cam_ctrl.cam_obj[cam_idx] = NULL;
-
-            pthread_mutex_lock(&my_obj->cam_lock);
-            pthread_mutex_unlock(&g_intf_lock);
-            rc = mm_camera_close(my_obj);
-            pthread_mutex_destroy(&my_obj->cam_lock);
-            free(my_obj);
+             pthread_mutex_unlock(&g_intf_lock);
         }
     } else {
         pthread_mutex_unlock(&g_intf_lock);
     }
 
+    LOGH("camera_handler = %d rc = %d", camera_handle, rc);
+#ifdef QCAMERA_REDEFINE_LOG
+    mm_camera_debug_close();
+#endif
+
     return rc;
 }
 
@@ -472,21 +691,43 @@
                                            mm_camera_buf_notify_t channel_cb,
                                            void *userdata)
 {
-    uint32_t ch_id = 0;
+    uint32_t ch_id = 0, aux_ch_id = 0;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
     LOGD("E camera_handler = %d", camera_handle);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X ch_id = %d", ch_id);
+
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            aux_ch_id = mm_camera_muxer_add_channel(aux_handle, attr,
+                    channel_cb, userdata, ch_id, my_obj);
+            if (aux_ch_id <= 0) {
+                pthread_mutex_lock(&my_obj->cam_lock);
+                mm_camera_del_channel(my_obj, ch_id);
+            } else {
+                ch_id |= aux_ch_id;
+            }
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("camera_handle = %d ch_id = %d X", ch_id);
     return ch_id;
 }
 
@@ -510,19 +751,38 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
     LOGD("E ch_id = %d", ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_del_channel(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            mm_camera_muxer_delete_channel(aux_handle, aux_chid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X");
+
+    if (m_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_del_channel(my_obj, m_chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("rc = %d ch_id = %d X", rc, ch_id);
     return rc;
 }
 
@@ -548,19 +808,41 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
     LOGD("E ch_id = %d", ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_chid && m_chid) {
+        LOGE("Does not support 2 channels for bundle info");
+        return rc;
     }
-    LOGD("X");
+
+    if (aux_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_get_bundle_info(aux_handle, aux_chid,
+                    bundle_info, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (m_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_get_bundle_info(my_obj, m_chid, bundle_info);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGD("rc = %d ch_id = %d X", rc, ch_id);
     return rc;
 }
 
@@ -583,18 +865,34 @@
                                                     void * user_data)
 {
     int32_t rc = -1;
-    mm_camera_obj_t * my_obj = NULL;
-
+    mm_camera_obj_t *my_obj = NULL;
     LOGD("E ");
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_register_event_notify(aux_handle,
+                    evt_cb, user_data, my_obj);
+        }
     }
     LOGD("E rc = %d", rc);
     return rc;
@@ -619,17 +917,41 @@
                                     mm_camera_buf_def_t *buf)
 {
     int32_t rc = -1;
-    mm_camera_obj_t * my_obj = NULL;
+    mm_camera_obj_t *my_obj = NULL;
+    uint32_t strid = 0;
+    uint32_t aux_strid = 0;
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (buf != NULL) {
+        strid = get_main_camera_handle(buf->stream_id);
+        aux_strid = get_aux_camera_handle(buf->stream_id);
+    }
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_qbuf(my_obj, ch_id, buf);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_qbuf(my_obj, chid, buf);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_qbuf(aux_handle, aux_chid, buf, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     LOGD("X evt_type = %d",rc);
     return rc;
@@ -653,16 +975,34 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_main_camera_handle(stream_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_get_queued_buf_count(my_obj, chid, stream_id);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_get_queued_buf_count(aux_handle,
+                    aux_chid, aux_strid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     LOGD("X queued buffer count = %d",rc);
     return rc;
@@ -690,22 +1030,46 @@
 {
     uint32_t id = 0;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_aux_camera_handle(stream_id);
+    uint32_t linked_chid = get_main_camera_handle(linked_ch_id);
+    uint32_t aux_linked_chid = get_aux_camera_handle(linked_ch_id);
 
     LOGD("E handle = %u ch_id = %u",
           camera_handle, ch_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (strid && linked_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t m_chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            id = mm_camera_link_stream(my_obj, m_chid, strid, linked_chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
 
-    LOGD("X stream_id = %u", stream_id);
+    if (aux_strid && aux_linked_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            id = mm_camera_muxer_link_stream(aux_handle, aux_chid,
+                    aux_strid, aux_linked_chid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    LOGH("X ch_id = %d stream_id = %d linked_ch_id = %d id = %d",
+            ch_id, stream_id, linked_ch_id, id);
     return (int32_t)id;
 }
 
@@ -725,23 +1089,47 @@
 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
                                           uint32_t ch_id)
 {
-    uint32_t stream_id = 0;
-    mm_camera_obj_t * my_obj = NULL;
+    uint32_t stream_id = 0, aux_stream_id;
+    mm_camera_obj_t *my_obj = NULL;
+    uint32_t m_ch_id = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
     LOGD("E handle = %d ch_id = %d",
           camera_handle, ch_id);
-
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        stream_id = mm_camera_add_stream(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (m_ch_id) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            stream_id = mm_camera_add_stream(my_obj, m_ch_id);
+       } else {
+            pthread_mutex_unlock(&g_intf_lock);
+       }
     }
-    LOGD("X stream_id = %d", stream_id);
+
+    if (aux_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            aux_stream_id = mm_camera_muxer_add_stream(aux_handle, aux_chid,
+                    m_ch_id, stream_id, my_obj);
+            if (aux_stream_id <= 0) {
+                LOGE("Failed to add stream");
+                pthread_mutex_lock(&my_obj->cam_lock);
+                mm_camera_del_stream(my_obj, m_ch_id, stream_id);
+            } else {
+                stream_id = stream_id | aux_stream_id;
+            }
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("X ch_id = %d stream_id = %d", ch_id, stream_id);
     return stream_id;
 }
 
@@ -766,21 +1154,42 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t m_strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_aux_camera_handle(stream_id);
 
     LOGD("E handle = %d ch_id = %d stream_id = %d",
           camera_handle, ch_id, stream_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            mm_camera_muxer_delete_stream(aux_handle, aux_chid,
+                    aux_strid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    if (m_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t m_chid = get_main_camera_handle(ch_id);
+
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_del_stream(my_obj, m_chid, m_strid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("X stream_id = %d rc = %d", stream_id, rc);
     return rc;
 }
 
@@ -806,23 +1215,43 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_aux_camera_handle(stream_id);
 
     LOGD("E handle = %d, ch_id = %d,stream_id = %d",
           camera_handle, ch_id, stream_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
 
-    LOGD("mm_camera_intf_config_stream stream_id = %d",stream_id);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_config_stream(my_obj, chid, strid, config);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    if (aux_strid && rc == 0) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_config_stream(aux_handle,
+                    aux_chid, aux_strid, config, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("X stream_id = %d rc = %d", stream_id, rc);
     return rc;
 }
 
@@ -844,18 +1273,37 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (chid) {
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        pthread_mutex_lock(&g_intf_lock);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_start_channel(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_start_channel(my_obj, chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    if (aux_chid && rc == 0) {
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        pthread_mutex_lock(&g_intf_lock);
+
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_start_channel(aux_handle, aux_chid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("X ch_id = %d rc = %d", ch_id, rc);
     return rc;
 }
 
@@ -877,19 +1325,39 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (aux_chid) {
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        pthread_mutex_lock(&g_intf_lock);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_stop_channel(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_stop_channel(aux_handle, aux_chid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    if (chid) {
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        pthread_mutex_lock(&g_intf_lock);
+
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_stop_channel(my_obj, chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("X ch_id = %d rc = %d", ch_id, rc);
     return rc;
+
 }
 
 /*===========================================================================
@@ -914,18 +1382,46 @@
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
     pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (aux_chid && chid) {
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if (my_obj && buf) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_request_super_buf(
+                    ch_id, buf, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (chid) {
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
 
-    if(my_obj && buf) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_request_super_buf (my_obj, ch_id, buf);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        if(my_obj && buf) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_request_super_buf (my_obj, chid, buf);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (aux_chid) {
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(aux_handle);
+
+        if(my_obj && buf) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_request_super_buf (my_obj, aux_chid, buf);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    LOGH("X ch_id = %d rc = %d", ch_id, rc);
     return rc;
 }
 
@@ -947,21 +1443,48 @@
                                                        uint32_t ch_id)
 {
     int32_t rc = -1;
-    mm_camera_obj_t * my_obj = NULL;
-
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    pthread_mutex_lock(&g_intf_lock);
+    if (aux_chid && chid) {
+        my_obj = mm_camera_util_get_camera_head(camera_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_cancel_super_buf_request(
+                    camera_handle, ch_id, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (aux_chid) {
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(aux_handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_cancel_super_buf_request(my_obj, chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (chid) {
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_cancel_super_buf_request(my_obj, chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    LOGH("X ch_id = %d rc = %d", ch_id, rc);
     return rc;
 }
 
@@ -984,20 +1507,39 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_flush_super_buf_queue(my_obj, chid, frame_idx);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X rc = %d", rc);
+
+    if (aux_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_flush_super_buf_queue(aux_handle,
+                    aux_chid, frame_idx, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    LOGH("X ch_id = %d rc = %d", ch_id, rc);
     return rc;
 }
 
@@ -1018,19 +1560,38 @@
         uint32_t ch_id)
 {
     int32_t rc = -1;
-    mm_camera_obj_t * my_obj = NULL;
+    mm_camera_obj_t *my_obj = NULL;
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
 
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_ch_id) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_start_zsl_snapshot(aux_handle,
+                    aux_ch_id, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (m_chid) {
+        uint32_t m_handle = get_main_camera_handle(camera_handle);
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(m_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_start_zsl_snapshot_ch(my_obj, m_chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     LOGD("X rc = %d", rc);
     return rc;
@@ -1054,19 +1615,38 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
 
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_ch_id) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_stop_zsl_snapshot(aux_handle, aux_ch_id, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
+
+    if (ch_id) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_stop_zsl_snapshot_ch(my_obj, m_chid);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
     LOGD("X rc = %d", rc);
     return rc;
 }
@@ -1091,18 +1671,38 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_ch_id = get_aux_camera_handle(ch_id);
 
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_ch_id) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_configure_notify_mode(aux_handle, aux_ch_id,
+                    notify_mode, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_config_channel_notify(my_obj, chid,
+                    notify_mode);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     LOGD("X rc = %d", rc);
     return rc;
@@ -1130,17 +1730,32 @@
     uint8_t buf_type, int fd, size_t size, void *buffer)
 {
     int32_t rc = -1;
-    mm_camera_obj_t * my_obj = NULL;
+    mm_camera_obj_t *my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_map_buf(aux_handle, buf_type,
+                    fd, size, buffer, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
 }
@@ -1166,16 +1781,29 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
-
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_map_bufs(my_obj, buf_map_list);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_map_bufs(my_obj, buf_map_list);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_map_bufs(aux_handle, buf_map_list, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
 }
@@ -1201,16 +1829,32 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_unmap_buf(my_obj, buf_type);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_unmap_buf(my_obj, buf_type);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (aux_handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_unmap_buf(aux_handle, buf_type, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
 }
@@ -1240,19 +1884,40 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
-
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    uint32_t strid = get_main_camera_handle(s_id);
+    uint32_t aux_strid = get_aux_camera_handle(s_id);
 
     LOGD("E camera_handle = %d,ch_id = %d,s_id = %d",
           camera_handle, ch_id, s_id);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
-    }else{
-        pthread_mutex_unlock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_set_stream_parms(my_obj, chid, strid, parms);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_set_stream_parms(aux_handle, aux_chid,
+                    aux_strid, parms, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     LOGD("X rc = %d", rc);
     return rc;
@@ -1285,21 +1950,41 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
-
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    uint32_t strid = get_main_camera_handle(s_id);
+    uint32_t aux_strid = get_aux_camera_handle(s_id);
 
     LOGD("E camera_handle = %d,ch_id = %d,s_id = %d",
           camera_handle, ch_id, s_id);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
-    }else{
-        pthread_mutex_unlock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_get_stream_parms(my_obj, chid, strid, parms);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
 
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_get_stream_parms(aux_handle, aux_chid,
+                    aux_strid, parms, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
     LOGD("X rc = %d", rc);
     return rc;
 }
@@ -1337,21 +2022,43 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
-
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    uint32_t strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_aux_camera_handle(stream_id);
 
     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
-          camera_handle, ch_id, stream_id, buf_idx, plane_idx);
+            camera_handle, ch_id, stream_id, buf_idx, plane_idx);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
-                                      buf_type, buf_idx, plane_idx,
-                                      fd, size, buffer);
-    }else{
-        pthread_mutex_unlock(&g_intf_lock);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_map_stream_buf(my_obj, chid, strid,
+                    buf_type, buf_idx, plane_idx,
+                    fd, size, buffer);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_map_stream_buf(aux_handle, aux_chid,
+                    aux_strid, buf_type, buf_idx, plane_idx, fd, size,
+                    buffer, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
 
     LOGD("X rc = %d", rc);
@@ -1377,22 +2084,58 @@
                                               const cam_buf_map_type_list *buf_map_list)
 {
     int32_t rc = -1;
+    uint32_t i;
     mm_camera_obj_t * my_obj = NULL;
-
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    cam_buf_map_type_list m_buf_list, aux_buf_list;
 
     LOGD("E camera_handle = %d, ch_id = %d",
           camera_handle, ch_id);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_map_stream_bufs(my_obj, ch_id, buf_map_list);
-    }else{
-        pthread_mutex_unlock(&g_intf_lock);
+    memset(&m_buf_list, 0, sizeof(m_buf_list));
+    memset(&aux_buf_list, 0, sizeof(m_buf_list));
+    for (i = 0; i < buf_map_list->length; i++) {
+        uint32_t strid = get_main_camera_handle(buf_map_list->buf_maps[i].stream_id);
+        uint32_t aux_strid = get_aux_camera_handle(buf_map_list->buf_maps[i].stream_id);
+        if (strid) {
+            m_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i];
+            m_buf_list.buf_maps[aux_buf_list.length].stream_id = strid;
+            m_buf_list.length++;
+        }
+        if (aux_strid) {
+            aux_buf_list.buf_maps[aux_buf_list.length] = buf_map_list->buf_maps[i];
+            aux_buf_list.buf_maps[aux_buf_list.length].stream_id = aux_strid;
+            aux_buf_list.length++;
+        }
     }
 
+    if(m_buf_list.length != 0) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_map_stream_bufs(my_obj, chid, &m_buf_list);
+        }else{
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if(aux_buf_list.length != 0) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj != NULL) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_map_stream_bufs(aux_handle,aux_chid,
+                    &aux_buf_list, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
     LOGD("X rc = %d", rc);
     return rc;
 }
@@ -1430,20 +2173,42 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_aux_camera_handle(stream_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
     LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
-          camera_handle, ch_id, stream_id, buf_idx, plane_idx);
+              camera_handle, ch_id, stream_id, buf_idx, plane_idx);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
-                                        buf_type, buf_idx, plane_idx);
-    }else{
-        pthread_mutex_unlock(&g_intf_lock);
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_unmap_stream_buf(aux_handle, aux_chid,
+                   aux_strid, buf_type, buf_idx,
+                   plane_idx, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_unmap_stream_buf(my_obj, chid, strid,
+                    buf_type, buf_idx, plane_idx);
+        }else{
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
 
     LOGD("X rc = %d", rc);
@@ -1469,18 +2234,32 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (handle) {
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        *sessionid = my_obj->sessionid;
-        pthread_mutex_unlock(&my_obj->cam_lock);
-        rc = 0;
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            *sessionid = my_obj->sessionid;
+            pthread_mutex_unlock(&my_obj->cam_lock);
+            rc = 0;
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    } else if (aux_handle){
+        pthread_mutex_lock(&g_intf_lock);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_get_session_id(aux_handle, sessionid, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
     return rc;
 }
@@ -1584,6 +2363,7 @@
                 mount_angle = (temp & 0xFF) * 90;
                 facing = ((entity.flags & CAM_SENSOR_FACING_MASK) ?
                         CAMERA_FACING_FRONT:CAMERA_FACING_BACK);
+
                 /* TODO: Need to revisit this logic if front AUX is available. */
                 if ((unsigned int)facing == CAMERA_FACING_FRONT) {
                     type = CAM_TYPE_STANDALONE;
@@ -1592,6 +2372,7 @@
                 } else {
                     type = CAM_TYPE_MAIN;
                 }
+
                 is_yuv = ((entity.flags & CAM_SENSOR_FORMAT_MASK) ?
                         CAM_SENSOR_YUV:CAM_SENSOR_RAW);
                 LOGL("index = %u flag = %x mount_angle = %u "
@@ -1636,6 +2417,8 @@
     cam_sync_mode_t temp_mode[MM_CAMERA_MAX_NUM_SENSORS];
     uint8_t temp_is_yuv[MM_CAMERA_MAX_NUM_SENSORS];
     char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];
+    uint32_t cam_idx[MM_CAMERA_MAX_NUM_SENSORS] = {0};
+    uint8_t prime_cam_idx = 0, aux_cam_idx = 0;
 
     memset(temp_info, 0, sizeof(temp_info));
     memset(temp_dev_name, 0, sizeof(temp_dev_name));
@@ -1657,11 +2440,15 @@
     /* Firstly save the main back cameras info */
     for (i = 0; i < num_cam; i++) {
         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
-            (g_cam_ctrl.cam_type[i] != CAM_TYPE_AUX)) {
+            !(g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
+            && ((g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)
+            || (g_cam_ctrl.cam_type[i] == CAM_TYPE_STANDALONE))) {
             temp_info[idx] = g_cam_ctrl.info[i];
-            temp_type[idx] = g_cam_ctrl.cam_type[i];
+            temp_type[idx] = CAM_TYPE_MAIN;
             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            cam_idx[idx] = idx;
+            prime_cam_idx = idx;
             LOGD("Found Back Main Camera: i: %d idx: %d", i, idx);
             memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
                 MM_CAMERA_DEV_NAME_LEN);
@@ -1671,27 +2458,64 @@
     /* Save the main front cameras info */
     for (i = 0; i < num_cam; i++) {
         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
-            (g_cam_ctrl.cam_type[i] != CAM_TYPE_AUX)) {
+            !(g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX)
+            && ((g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)
+            || (g_cam_ctrl.cam_type[i] == CAM_TYPE_STANDALONE))) {
             temp_info[idx] = g_cam_ctrl.info[i];
-            temp_type[idx] = g_cam_ctrl.cam_type[i];
+            temp_type[idx] = CAM_TYPE_MAIN;
             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            cam_idx[idx] = idx;
             LOGD("Found Front Main Camera: i: %d idx: %d", i, idx);
             memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
                     MM_CAMERA_DEV_NAME_LEN);
         }
     }
 
+    /*Expose Bayer Aux as a valid sensor*/
+    for (i = 0; i < num_cam; i++) {
+        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) {
+            temp_info[idx] = g_cam_ctrl.info[i];
+            temp_type[idx] = CAM_TYPE_MAIN;
+            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
+            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            cam_idx[idx] = idx;
+            LOGD("Found Bayer + Aux: i: %d idx: %d", i, idx);
+            memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
+                MM_CAMERA_DEV_NAME_LEN);
+        }
+    }
+
+    for (i = 0; i < num_cam; i++) {
+        if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) {
+            temp_info[idx] = g_cam_ctrl.info[i];
+            temp_type[idx] = CAM_TYPE_MAIN;
+            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
+            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            cam_idx[idx] = idx;
+            aux_cam_idx = idx;
+            LOGD("Found Bayer + Aux: i: %d idx: %d", i, idx);
+            memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
+                MM_CAMERA_DEV_NAME_LEN);
+        }
+    }
+
     /* Expose YUV AUX camera if persist.camera.aux.yuv is set to 1.
     Otherwsie expose AUX camera if it is not YUV. */
     for (i = 0; i < num_cam; i++) {
         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) &&
-                (g_cam_ctrl.cam_type[i] == CAM_TYPE_AUX) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) &&
+                !(g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) &&
                 (is_yuv_aux_cam_exposed || !(g_cam_ctrl.is_yuv[i]))) {
             temp_info[idx] = g_cam_ctrl.info[i];
-            temp_type[idx] = g_cam_ctrl.cam_type[i];
+            temp_type[idx] = CAM_TYPE_AUX;
             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            cam_idx[idx] = idx;
             LOGD("Found back Aux Camera: i: %d idx: %d", i, idx);
             memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
                 MM_CAMERA_DEV_NAME_LEN);
@@ -1702,24 +2526,45 @@
     Otherwsie expose AUX camera if it is not YUV. */
     for (i = 0; i < num_cam; i++) {
         if ((g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) &&
-                (g_cam_ctrl.cam_type[i] == CAM_TYPE_AUX) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) &&
+                !(g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN) &&
                 (is_yuv_aux_cam_exposed || !(g_cam_ctrl.is_yuv[i]))) {
             temp_info[idx] = g_cam_ctrl.info[i];
-            temp_type[idx] = g_cam_ctrl.cam_type[i];
+            temp_type[idx] = CAM_TYPE_AUX;
             temp_mode[idx] = g_cam_ctrl.cam_mode[i];
             temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            cam_idx[idx] = idx;
             LOGD("Found Front Aux Camera: i: %d idx: %d", i, idx);
             memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
                 MM_CAMERA_DEV_NAME_LEN);
         }
     }
 
-    if (idx <= num_cam) {
+    /*Expose AUX + MAIN camera*/
+    for (i = 0; i < num_cam; i++) {
+        if (((g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) ||
+                (g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT)) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_AUX) &&
+                (g_cam_ctrl.cam_type[i] & CAM_TYPE_MAIN)) {
+            temp_info[idx] = g_cam_ctrl.info[i];
+            temp_type[idx] = CAM_TYPE_AUX | CAM_TYPE_MAIN;
+            temp_mode[idx] = g_cam_ctrl.cam_mode[i];
+            temp_is_yuv[idx] = g_cam_ctrl.is_yuv[i];
+            //Assuming primary is back
+            cam_idx[idx] = (aux_cam_idx << MM_CAMERA_HANDLE_SHIFT_MASK) | prime_cam_idx;
+            LOGD("Add additional Bayer + Aux: i: %d idx: %d", i, idx);
+            memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
+                MM_CAMERA_DEV_NAME_LEN);
+        }
+    }
+
+    if (idx != 0) {
         memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info));
         memcpy(g_cam_ctrl.cam_type, temp_type, sizeof(temp_type));
         memcpy(g_cam_ctrl.cam_mode, temp_mode, sizeof(temp_mode));
         memcpy(g_cam_ctrl.is_yuv, temp_is_yuv, sizeof(temp_is_yuv));
         memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name));
+        memcpy(g_cam_ctrl.cam_index, cam_idx, (sizeof(uint32_t) * MM_CAMERA_MAX_NUM_SENSORS));
         //Set num cam based on the cameras exposed finally via dual/aux properties.
         g_cam_ctrl.num_cam = idx;
         for (i = 0; i < idx; i++) {
@@ -1832,7 +2677,6 @@
     close(sd_fd);
     dev_fd = -1;
 
-
     num_media_devices = 0;
     while (1) {
         uint32_t num_entities = 1U;
@@ -1919,21 +2763,41 @@
 {
     int32_t rc = -1;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_chid = get_aux_camera_handle(ch_id);
 
     LOGD("E camera_handler = %d,ch_id = %d",
           camera_handle, ch_id);
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
 
-    if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
-        pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
-                (uint32_t)trigger, in_value);
-    } else {
-        pthread_mutex_unlock(&g_intf_lock);
+    if (chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
+
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_channel_advanced_capture(my_obj, chid, type,
+                    (uint32_t)trigger, in_value);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
     }
-    LOGD("X ");
+
+    if (aux_chid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_process_advanced_capture(aux_handle,
+                    aux_chid, type, (uint32_t)trigger, in_value, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    LOGH("X rc = %d ch_id = %d", rc, ch_id);
     return rc;
 }
 
@@ -1960,35 +2824,246 @@
 {
     int32_t rc = 0;
     mm_camera_obj_t * my_obj = NULL;
+    uint32_t strid = get_main_camera_handle(stream_id);
+    uint32_t aux_strid = get_aux_camera_handle(stream_id);
 
     LOGD("E handle = %u ch_id = %u",
           camera_handle, ch_id);
 
-    pthread_mutex_lock(&g_intf_lock);
-    my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
+    if (strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t handle = get_main_camera_handle(camera_handle);
+        uint32_t chid = get_main_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_by_handler(handle);
 
+        if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_reg_stream_buf_cb(my_obj, chid, strid,
+                    buf_cb, cb_type, userdata);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+
+    if (aux_strid) {
+        pthread_mutex_lock(&g_intf_lock);
+        uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+        uint32_t aux_chid = get_aux_camera_handle(ch_id);
+        my_obj = mm_camera_util_get_camera_head(aux_handle);
+
+        if (my_obj) {
+            pthread_mutex_lock(&my_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_register_stream_buf_cb(aux_handle,
+                    aux_chid, aux_strid,
+                    buf_cb, cb_type, userdata, my_obj);
+        } else {
+            pthread_mutex_unlock(&g_intf_lock);
+        }
+    }
+    return (int32_t)rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_intf_register_frame_sync
+ *
+ * DESCRIPTION: start frame buffer sync for the stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *   @sync_attr     : frame sync attr
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+static int32_t mm_camera_intf_reg_frame_sync(uint32_t camera_handle,
+            uint32_t ch_id, uint32_t stream_id,
+            mm_camera_intf_frame_sync_t *sync_attr)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    LOGD("E handle = %u ch_id = %u stream_id = %u", camera_handle, ch_id, stream_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    my_obj = mm_camera_util_get_camera_by_handler(handle);
     if(my_obj) {
-        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_lock(&my_obj->muxer_lock);
         pthread_mutex_unlock(&g_intf_lock);
-        rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
-                buf_cb, cb_type, userdata);
+        rc = mm_camera_muxer_reg_frame_sync(my_obj,
+                 ch_id, stream_id, sync_attr);
     } else {
         pthread_mutex_unlock(&g_intf_lock);
     }
     return (int32_t)rc;
 }
 
+/*===========================================================================
+ * FUNCTION   : mm_camera_intf_start_stream_frame_sync
+ *
+ * DESCRIPTION: start frame buffer sync for the stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+static int32_t mm_camera_intf_start_stream_frame_sync(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    LOGD("E handle = %u ch_id = %u stream_id = %u",
+            camera_handle, ch_id, stream_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t m_stream = get_main_camera_handle(stream_id);
+    my_obj = mm_camera_util_get_camera_by_handler(handle);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->muxer_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_muxer_start_frame_sync(my_obj,
+                 m_chid, m_stream);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    LOGH("stream_id = %d rc = %d", stream_id, rc);
+    return (int32_t)rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_intf_stop_stream_frame_sync
+ *
+ * DESCRIPTION: stop frame buffer sync for the stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+static int32_t mm_camera_intf_stop_stream_frame_sync(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    LOGD("E handle = %u ch_id = %u stream_id = %u",
+            camera_handle, ch_id, stream_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t m_stream = get_main_camera_handle(stream_id);
+    my_obj = mm_camera_util_get_camera_by_handler(handle);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->muxer_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_muxer_stop_frame_sync(my_obj,
+                 m_chid, m_stream);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    LOGH("stream_id = %d rc = %d", stream_id, rc);
+    return (int32_t)rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_intf_switch_stream
+ *
+ * DESCRIPTION: switch between stream in case of multi streams
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+static int32_t mm_camera_intf_switch_stream_cb(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    uint32_t handle = get_main_camera_handle(camera_handle);
+    uint32_t m_chid = get_main_camera_handle(ch_id);
+    uint32_t m_strid = get_main_camera_handle(stream_id);
+    LOGD("E handle = %u ch_id = %u stream_id = %u",
+            camera_handle, ch_id, stream_id);
+
+    pthread_mutex_lock(&g_intf_lock);
+    my_obj = mm_camera_util_get_camera_by_handler(handle);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&g_intf_lock);
+        rc = mm_camera_switch_stream_cb(my_obj, m_chid, m_strid);
+    } else {
+        pthread_mutex_unlock(&g_intf_lock);
+    }
+    LOGH("stream_id = %d rc = %d", stream_id, rc);
+    return (int32_t)rc;
+}
+
 struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType)
 {
     *pCamType = g_cam_ctrl.cam_type[camera_id];
     return &g_cam_ctrl.info[camera_id];
 }
 
+uint8_t is_dual_camera_by_idx(uint32_t camera_id)
+{
+    return ((g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_MAIN)
+            && (g_cam_ctrl.cam_type[camera_id] & CAM_TYPE_AUX));
+}
+
+uint8_t is_dual_camera_by_handle(uint32_t handle)
+{
+    return ((handle >> MM_CAMERA_HANDLE_SHIFT_MASK)
+            ? 1 : 0);
+}
+
+uint32_t get_aux_camera_handle(uint32_t handle)
+{
+    return mm_camera_util_get_handle_by_num(1, handle);
+}
+
+uint32_t get_main_camera_handle(uint32_t handle)
+{
+    return mm_camera_util_get_handle_by_num(0, handle);
+}
+
 uint8_t is_yuv_sensor(uint32_t camera_id)
 {
     return g_cam_ctrl.is_yuv[camera_id];
 }
 
+uint8_t validate_handle(uint32_t src_handle, uint32_t handle)
+{
+    return ((src_handle == handle)
+            || (get_main_camera_handle(src_handle) == handle)
+            || (get_aux_camera_handle(src_handle) == handle)
+            || (get_main_camera_handle(handle) == src_handle)
+            || (get_aux_camera_handle(handle) == src_handle));
+}
+
 /* camera ops v-table */
 static mm_camera_ops_t mm_camera_ops = {
     .query_capability = mm_camera_intf_query_capability,
@@ -2028,7 +3103,11 @@
     .get_session_id = mm_camera_intf_get_session_id,
     .sync_related_sensors = mm_camera_intf_sync_related_sensors,
     .flush = mm_camera_intf_flush,
-    .register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb
+    .register_stream_buf_cb = mm_camera_intf_register_stream_buf_cb,
+    .register_frame_sync = mm_camera_intf_reg_frame_sync,
+    .start_stream_frame_sync = mm_camera_intf_start_stream_frame_sync,
+    .stop_stream_frame_sync = mm_camera_intf_stop_stream_frame_sync,
+    .switch_stream_callback = mm_camera_intf_switch_stream_cb
 };
 
 /*===========================================================================
@@ -2048,26 +3127,36 @@
 {
     int32_t rc = 0;
     mm_camera_obj_t *cam_obj = NULL;
+    uint32_t cam_idx = camera_idx;
+    uint32_t aux_idx = 0;
+    uint8_t is_multi_camera = 0;
 
 #ifdef QCAMERA_REDEFINE_LOG
-    mm_camera_set_dbg_log_properties();
+    mm_camera_debug_open();
 #endif
 
     LOGD("E camera_idx = %d\n", camera_idx);
-    if (camera_idx >= g_cam_ctrl.num_cam) {
-        LOGE("Invalid camera_idx (%d)", camera_idx);
+    if (is_dual_camera_by_idx(camera_idx)) {
+        is_multi_camera = 1;
+        cam_idx = mm_camera_util_get_handle_by_num(0,
+                g_cam_ctrl.cam_index[camera_idx]);
+        aux_idx = (get_aux_camera_handle(g_cam_ctrl.cam_index[camera_idx])
+                >> MM_CAMERA_HANDLE_SHIFT_MASK);
+        LOGH("Dual Camera: Main ID = %d Aux ID = %d", cam_idx, aux_idx);
+    }
+
+    if (cam_idx >= (uint32_t)g_cam_ctrl.num_cam) {
+        LOGE("Invalid camera_idx (%d)", cam_idx);
         return -EINVAL;
     }
 
     pthread_mutex_lock(&g_intf_lock);
     /* opened already */
-    if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
-        /* Add reference */
-        g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
+    if(NULL != g_cam_ctrl.cam_obj[cam_idx] &&
+            g_cam_ctrl.cam_obj[cam_idx]->ref_count != 0) {
         pthread_mutex_unlock(&g_intf_lock);
-        LOGD("opened alreadyn");
-        *camera_vtbl = &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
-        return rc;
+        LOGE("Camera %d is already open", cam_idx);
+        return -EBUSY;
     }
 
     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
@@ -2082,34 +3171,63 @@
     cam_obj->ctrl_fd = -1;
     cam_obj->ds_fd = -1;
     cam_obj->ref_count++;
-    cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
+    cam_obj->my_num = 0;
+    cam_obj->my_hdl = mm_camera_util_generate_handler(cam_idx);
     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
     cam_obj->vtbl.ops = &mm_camera_ops;
     pthread_mutex_init(&cam_obj->cam_lock, NULL);
+    pthread_mutex_init(&cam_obj->muxer_lock, NULL);
     /* unlock global interface lock, if not, in dual camera use case,
       * current open will block operation of another opened camera obj*/
     pthread_mutex_lock(&cam_obj->cam_lock);
     pthread_mutex_unlock(&g_intf_lock);
 
     rc = mm_camera_open(cam_obj);
-
-    pthread_mutex_lock(&g_intf_lock);
     if (rc != 0) {
         LOGE("mm_camera_open err = %d", rc);
         pthread_mutex_destroy(&cam_obj->cam_lock);
-        g_cam_ctrl.cam_obj[camera_idx] = NULL;
+        pthread_mutex_lock(&g_intf_lock);
+        g_cam_ctrl.cam_obj[cam_idx] = NULL;
         free(cam_obj);
         cam_obj = NULL;
         pthread_mutex_unlock(&g_intf_lock);
         *camera_vtbl = NULL;
         return rc;
-    } else {
-        LOGD("Open succeded\n");
-        g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
-        pthread_mutex_unlock(&g_intf_lock);
-        *camera_vtbl = &cam_obj->vtbl;
-        return 0;
     }
+
+    if (is_multi_camera) {
+        /*Open Aux camer's*/
+        pthread_mutex_lock(&g_intf_lock);
+        if(NULL != g_cam_ctrl.cam_obj[aux_idx] &&
+                g_cam_ctrl.cam_obj[aux_idx]->ref_count != 0) {
+            pthread_mutex_unlock(&g_intf_lock);
+            LOGE("Camera %d is already open", aux_idx);
+            rc = -EBUSY;
+        } else {
+            pthread_mutex_lock(&cam_obj->muxer_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_muxer_camera_open(aux_idx, cam_obj);
+        }
+        if (rc != 0) {
+            LOGE("muxer open err = %d", rc);
+            pthread_mutex_lock(&g_intf_lock);
+            g_cam_ctrl.cam_obj[cam_idx] = NULL;
+            pthread_mutex_lock(&cam_obj->cam_lock);
+            pthread_mutex_unlock(&g_intf_lock);
+            rc = mm_camera_close(cam_obj);
+            pthread_mutex_destroy(&cam_obj->cam_lock);
+            pthread_mutex_destroy(&cam_obj->muxer_lock);
+            free(cam_obj);
+            cam_obj = NULL;
+            *camera_vtbl = NULL;
+            return rc;
+        }
+    }
+
+    LOGH("Open succeded: handle = %d", cam_obj->vtbl.camera_handle);
+    g_cam_ctrl.cam_obj[cam_idx] = cam_obj;
+    *camera_vtbl = &cam_obj->vtbl;
+    return 0;
 }
 
 /*===========================================================================
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_muxer.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_muxer.c
new file mode 100644
index 0000000..b9a05a2
--- /dev/null
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_muxer.c
@@ -0,0 +1,2533 @@
+/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// To remove
+#include <cutils/properties.h>
+
+// System dependencies
+#include <pthread.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
+#include IOCTL_H
+
+// Camera dependencies
+#include "cam_semaphore.h"
+#include "mm_camera_dbg.h"
+#include "mm_camera_sock.h"
+#include "mm_camera_interface.h"
+#include "mm_camera_muxer.h"
+
+#define MAX_UNMATCHED_FOR_FRAME_SYNC 0
+
+extern mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler);
+extern mm_channel_t * mm_camera_util_get_channel_by_handler(mm_camera_obj_t *cam_obj,
+        uint32_t handler);
+extern mm_stream_t *mm_channel_util_get_stream_by_handler(mm_channel_t *ch_obj,
+        uint32_t handler);
+extern int32_t mm_camera_util_set_camera_object(uint8_t cam_idx, mm_camera_obj_t *obj);
+
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_util_get_index_by_num
+ *
+ * DESCRIPTION: utility function to get index from handle
+ *
+ * PARAMETERS :
+ *   @cam_num : Camera number
+ *   @handler: object handle
+ *
+ * RETURN     : uint8_t type of index derived from handle
+ *==========================================================================*/
+uint8_t mm_camera_util_get_index_by_num(uint8_t cam_num, uint32_t handler)
+{
+    uint8_t idx = 0;
+    idx = ((mm_camera_util_get_handle_by_num(cam_num, handler) >>
+            (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num))
+            & 0x000000ff);
+    return idx;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_util_get_handle_by_num
+ *
+ * DESCRIPTION: utility function to get handle for specific camera
+ *
+ * PARAMETERS :
+ *   @cam_num : Camera number
+ *   @handler : object handle
+ *
+ * RETURN     : return proper handle based on the object num
+ *==========================================================================*/
+uint32_t mm_camera_util_get_handle_by_num(uint8_t cam_num, uint32_t handler)
+{
+    return (handler & (MM_CAMERA_HANDLE_BIT_MASK <<
+            (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num)));
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_util_generate_handler_by_num
+ *
+ * DESCRIPTION: utility function to generate handler for camera/channel/stream
+ *
+ * PARAMETERS :
+ *   @cam_num : Camera number
+ *   @index   : index of the object to have handler
+ *
+ * RETURN     : uint32_t type of handle that uniquely identify the object
+ *==========================================================================*/
+uint32_t mm_camera_util_generate_handler_by_num(uint8_t cam_num, uint8_t index)
+{
+    uint32_t handler = mm_camera_util_generate_handler(index);
+    handler = (handler << (MM_CAMERA_HANDLE_SHIFT_MASK * cam_num));
+    return handler;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_util_get_dev_name_by_num
+ *
+ * DESCRIPTION: utility function to get device name from camera handle
+ *
+ * PARAMETERS :
+ *   @cam_handle: camera handle
+ *
+ * RETURN     : char ptr to the device name stored in global variable
+ * NOTE       : caller should not free the char ptr
+ *==========================================================================*/
+const char *mm_camera_util_get_dev_name_by_num(uint8_t cam_num, uint32_t cam_handle)
+{
+    uint32_t handle = (cam_handle >> (cam_num * MM_CAMERA_HANDLE_SHIFT_MASK));
+    return mm_camera_util_get_dev_name(handle);
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_muxer_util_get_camera_by_obj
+ *
+ * DESCRIPTION: utility function to get camera object from object list
+ *
+ * PARAMETERS :
+ *   @cam_handle: camera handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : ptr to the camera object stored in global variable
+ * NOTE       : caller should not free the camera object ptr
+ *==========================================================================*/
+mm_camera_obj_t* mm_muxer_util_get_camera_by_obj(uint32_t cam_handle,
+        mm_camera_obj_t *cam_obj)
+{
+    mm_camera_obj_t *obj = cam_obj;
+    uint8_t i = 0;
+
+    if (cam_handle == cam_obj->my_hdl) {
+        return cam_obj;
+    }
+
+    if (obj->master_cam_obj != NULL) {
+        obj = obj->master_cam_obj;
+    }
+    for (i = 0; i < obj->num_s_cnt; i++) {
+        if (cam_handle == obj->aux_cam_obj[i]->my_hdl) {
+            obj = obj->aux_cam_obj[i];
+            break;
+        }
+    }
+    return obj;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_muxer_util_get_channel_by_obj
+ *
+ * DESCRIPTION: utility function to get channel object from camera
+ *
+ * PARAMETERS :
+ *   @ch_id: channel handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : ptr to the camera object stored in global variable
+ * NOTE       : caller should not free the camera object ptr
+ *==========================================================================*/
+mm_channel_t *mm_muxer_util_get_channel_by_obj(uint32_t ch_id,
+        mm_camera_obj_t *cam_obj)
+{
+    mm_camera_obj_t *obj = cam_obj;
+    mm_channel_t *ch_obj = NULL;
+    uint8_t i = 0;
+
+    if (obj->master_cam_obj != NULL) {
+        obj = obj->master_cam_obj;
+    }
+    while (obj != NULL) {
+        ch_obj = mm_camera_util_get_channel_by_handler(obj, ch_id);
+        if (ch_obj != NULL) {
+            break;
+        }
+        obj = obj->aux_cam_obj[i++];
+    }
+    return ch_obj;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_muxer_util_get_stream_by_obj
+ *
+ * DESCRIPTION: utility function to get stream object from camera
+ *
+ * PARAMETERS :
+ *   @stream_id: stream handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : ptr to the camera object stored in global variable
+ * NOTE       : caller should not free the camera object ptr
+ *==========================================================================*/
+mm_stream_t *mm_muxer_util_get_stream_by_obj(uint32_t stream_id,
+        mm_camera_obj_t *cam_obj)
+{
+    mm_camera_obj_t *obj = cam_obj;
+    mm_stream_t *stream_obj = NULL;
+    uint8_t i = 0, j = 0;
+
+    if (obj->master_cam_obj != NULL) {
+        obj = obj->master_cam_obj;
+    }
+
+    while ((obj != NULL) && (stream_obj == NULL)) {
+        for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
+            stream_obj = mm_channel_util_get_stream_by_handler(
+                    &cam_obj->ch[i], stream_id);
+            if (stream_obj == NULL) {
+                break;
+            }
+        }
+        obj = obj->aux_cam_obj[j++];
+    }
+    return stream_obj;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_camera_open
+ *
+ * DESCRIPTION: open a supporting camera by camera index
+ *
+ * PARAMETERS :
+ *   @cam_idx  : camera index. should within range of 0 to num_of_cameras
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              non-zero error code -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_camera_open(uint8_t cam_idx,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+    uint8_t my_num = 1;
+
+    my_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
+    if(NULL == my_obj) {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        LOGE("no mem");
+        return -EINVAL;
+    }
+
+    /* initialize camera obj */
+    memset(my_obj, 0, sizeof(mm_camera_obj_t));
+    my_obj->ctrl_fd = -1;
+    my_obj->ds_fd = -1;
+    my_obj->ref_count++;
+    my_obj->my_num = my_num;
+    my_obj->my_hdl = mm_camera_util_generate_handler_by_num(my_num, cam_idx);
+    pthread_mutex_init(&my_obj->cam_lock, NULL);
+    /* unlock global interface lock, if not, in dual camera use case,
+      * current open will block operation of another opened camera obj*/
+    pthread_mutex_lock(&my_obj->cam_lock);
+    pthread_mutex_unlock(&cam_obj->muxer_lock);
+
+    rc = mm_camera_open(my_obj);
+    pthread_mutex_lock(&cam_obj->muxer_lock);
+    if (rc != 0) {
+        LOGE("mm_camera_open err = %d", rc);
+        pthread_mutex_destroy(&my_obj->cam_lock);
+        free(my_obj);
+        my_obj = NULL;
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        return rc;
+    } else {
+        LOGD("Open succeded\n");
+        rc  = mm_camera_util_set_camera_object(cam_idx, my_obj);
+        my_obj->vtbl.camera_handle = (cam_obj->my_hdl | my_obj->my_hdl);
+        cam_obj->vtbl.camera_handle = my_obj->vtbl.camera_handle;
+        cam_obj->aux_cam_obj[cam_obj->num_s_cnt++] = my_obj;
+        my_obj->master_cam_obj = cam_obj;
+        cam_obj->master_cam_obj = NULL;
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        return rc;
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_query_capability
+ *
+ * DESCRIPTION: query camera capability
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_query_capability(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_query_capability(my_obj);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    LOGD(" rc = %d", rc);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_register_event_notify
+ *
+ * DESCRIPTION: register for event notify
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @evt_cb       : callback for event notify
+ *   @user_data    : user data ptr
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_register_event_notify(uint32_t camera_handle,
+        mm_camera_event_notify_t evt_cb,
+        void *user_data, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_close_camera
+ *
+ * DESCRIPTION: close a camera by its handle
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_close_camera(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if (my_obj){
+        uint8_t cam_idx = mm_camera_util_get_index_by_num(
+                my_obj->my_num, my_obj->my_hdl);
+        my_obj->ref_count--;
+        if(my_obj->ref_count > 0) {
+            LOGD("ref_count=%d\n", my_obj->ref_count);
+            pthread_mutex_unlock(&cam_obj->muxer_lock);
+            rc = 0;
+        } else {
+            rc  = mm_camera_util_set_camera_object(cam_idx, NULL);
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&cam_obj->muxer_lock);
+            rc = mm_camera_close(my_obj);
+            pthread_mutex_destroy(&my_obj->cam_lock);
+            free(my_obj);
+            my_obj = NULL;
+        }
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_map_buf
+ *
+ * DESCRIPTION: mapping camera buffer via domain socket to server
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @buf_type     : type of buffer to be mapped. could be following values:
+ *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
+ *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
+ *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
+ *   @fd           : file descriptor of the buffer
+ *   @size         : size of the buffer
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_map_buf(uint32_t camera_handle, uint8_t buf_type,
+        int fd, size_t size, void *buffer, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_map_buf(my_obj, buf_type, fd, size, buffer);
+    }else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_map_bufs
+ *
+ * DESCRIPTION: mapping camera buffer via domain socket to server
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @buf_type     : type of buffer to be mapped. could be following values:
+ *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
+ *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
+ *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_map_bufs(uint32_t camera_handle,
+        const cam_buf_map_type_list *buf_map_list,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_map_bufs(my_obj, buf_map_list);
+    }else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_unmap_buf
+ *
+ * DESCRIPTION: unmapping camera buffer via domain socket to server
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @buf_type     : type of buffer to be unmapped. could be following values:
+ *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
+ *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
+ *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_unmap_buf(uint32_t camera_handle,
+        uint8_t buf_type, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_unmap_buf(my_obj, buf_type);
+    }else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_set_parms
+ *
+ * DESCRIPTION: set parameters per camera
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @parms        : ptr to a param struct to be set to server
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_set_parms(uint32_t camera_handle,
+        parm_buffer_t *parms, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_set_parms(my_obj, parms);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_parms
+ *
+ * DESCRIPTION: get parameters per camera
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @parms        : ptr to a param struct to be get from server
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_get_parms(uint32_t camera_handle,
+        parm_buffer_t *parms, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_get_parms(my_obj, parms);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_do_auto_focus
+ *
+ * DESCRIPTION: performing auto focus
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_do_auto_focus(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_do_auto_focus(my_obj);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_cancel_auto_focus
+ *
+ * DESCRIPTION: cancel auto focus
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_cancel_auto_focus(uint32_t camera_handle,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_cancel_auto_focus(my_obj);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_prepare_snapshot
+ *
+ * DESCRIPTION: prepare hardware for snapshot
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @do_af_flag   : flag indicating if AF is needed
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_prepare_snapshot(uint32_t camera_handle,
+        int32_t do_af_flag, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_start_zsl_snapshot
+ *
+ * DESCRIPTION: Starts zsl snapshot
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_start_zsl_snapshot(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        uint32_t my_ch_id = mm_camera_util_get_handle_by_num(my_obj->my_num, ch_id);
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_start_zsl_snapshot_ch(my_obj, my_ch_id);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_stop_zsl_snapshot
+ *
+ * DESCRIPTION: Starts zsl snapshot
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_stop_zsl_snapshot(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        uint32_t my_ch_id = mm_camera_util_get_handle_by_num(my_obj->my_num, ch_id);
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_stop_zsl_snapshot_ch(my_obj, my_ch_id);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_add_channel
+ *
+ * DESCRIPTION: add a channel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @attr         : bundle attribute of the channel if needed
+ *   @channel_cb   : callback function for bundle data notify
+ *   @userdata     : user data ptr
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : uint32_t type of channel handle
+ *              0  -- invalid channel handle, meaning the op failed
+ *              >0 -- successfully added a channel with a valid handle
+ *==========================================================================*/
+uint32_t mm_camera_muxer_add_channel(uint32_t camera_handle,
+        mm_camera_channel_attr_t *attr, mm_camera_buf_notify_t channel_cb,
+        void *userdata, uint32_t m_ch_id, mm_camera_obj_t *cam_obj)
+{
+    int32_t ch_id = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
+
+        if (ch_id > 0 && m_ch_id > 0) {
+            mm_camera_frame_sync_t frame_sync;
+            memset(&frame_sync, 0, sizeof(frame_sync));
+            frame_sync.a_cam_obj = my_obj;
+            frame_sync.a_ch_id = ch_id;
+            frame_sync.userdata = userdata;
+            frame_sync.a_stream_id = 0;
+            frame_sync.max_unmatched_frames = 0;
+            frame_sync.priority = MM_CAMERA_SUPER_BUF_PRIORITY_LOW;
+            frame_sync.buf_cb = channel_cb;
+            pthread_mutex_lock(&cam_obj->cam_lock);
+            mm_camera_reg_frame_sync(cam_obj, m_ch_id,
+                    0, &frame_sync);
+        }
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return ch_id;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_delete_channel
+ *
+ * DESCRIPTION: delete a channel by its handle
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_delete_channel(uint32_t camera_handle, uint32_t ch_id,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_del_channel(my_obj, ch_id);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_bundle_info
+ *
+ * DESCRIPTION: query bundle info of the channel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @bundle_info  : bundle info to be filled in
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_get_bundle_info(uint32_t camera_handle, uint32_t ch_id,
+        cam_bundle_config_t *bundle_info, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_add_stream
+ *
+ * DESCRIPTION: add a stream into a channel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @src__ch_id        : src channel handle
+ *   @src_stream_id     :  src stream handle
+ *   @cam_obj     : ptr to a Parent camera object
+ *
+ * RETURN     : uint32_t type of stream handle
+ *              0  -- invalid stream handle, meaning the op failed
+ *              >0 -- successfully added a stream with a valid handle
+ *==========================================================================*/
+uint32_t mm_camera_muxer_add_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t src__ch_id, uint32_t src_stream_id, mm_camera_obj_t *cam_obj)
+{
+    int32_t stream_id = 0;
+    int32_t rc = 0;
+    mm_camera_obj_t *my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        stream_id = mm_camera_add_stream(my_obj, ch_id);
+        if (stream_id > 0 && src_stream_id > 0) {
+            mm_camera_frame_sync_t frame_sync;
+            memset(&frame_sync, 0, sizeof(frame_sync));
+            frame_sync.a_cam_obj = my_obj;
+            frame_sync.a_ch_id = ch_id;
+            frame_sync.userdata = NULL;
+            frame_sync.a_stream_id = stream_id;
+            frame_sync.max_unmatched_frames = 0;
+            frame_sync.buf_cb = NULL;
+            frame_sync.is_res_shared = 1;
+            pthread_mutex_lock(&cam_obj->cam_lock);
+            rc = mm_camera_reg_frame_sync(cam_obj, src__ch_id,
+                    src_stream_id, &frame_sync);
+            LOGH("Stream frame sync = %d and %d rc = %d",
+                    src_stream_id, stream_id, rc);
+        }
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return stream_id;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_delete_stream
+ *
+ * DESCRIPTION: delete a stream by its handle
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_delete_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_obj_t *cam_obj)
+{
+    mm_camera_obj_t *my_obj = NULL;
+    int32_t rc = 0;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_link_stream
+ *
+ * DESCRIPTION: link a stream into a new channel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream id
+ *   @linked_ch_id : channel in which the stream will be linked
+ *
+ * RETURN     : int32_t type of stream handle
+ *              0  -- invalid stream handle, meaning the op failed
+ *              >0 -- successfully linked a stream with a valid handle
+ *==========================================================================*/
+int32_t mm_camera_muxer_link_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id, uint32_t linked_ch_id,
+        mm_camera_obj_t *cam_obj)
+{
+    uint32_t id = 0;
+    mm_camera_obj_t *my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return id;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_config_stream
+ *
+ * DESCRIPTION: configure a stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *   @config       : stream configuration
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_config_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id, mm_camera_stream_config_t *config,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    mm_camera_stream_config_t aux_config = *config;
+    LOGD("mm_camera_intf_config_stream stream_id = %d",stream_id);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        if (config->stream_info->aux_str_info != NULL) {
+            aux_config.stream_info = config->stream_info->aux_str_info;
+        }
+        aux_config.mem_vtbl.get_bufs = NULL;
+        aux_config.mem_vtbl.put_bufs = NULL;
+        aux_config.mem_vtbl.set_config_ops = NULL;
+        rc = mm_camera_config_stream(my_obj, ch_id, stream_id, &aux_config);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_map_stream_buf
+ *
+ * DESCRIPTION: mapping stream buffer via domain socket to server
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @s_id         : stream handle
+ *   @buf_type     : type of buffer to be mapped. could be following values:
+ *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
+ *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
+ *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
+ *   @buf_idx      : index of buffer within the stream buffers, only valid if
+ *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
+ *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
+ *   @plane_idx    : plane index. If all planes share the same fd,
+ *                   plane_idx = -1; otherwise, plean_idx is the
+ *                   index to plane (0..num_of_planes)
+ *   @fd           : file descriptor of the buffer
+ *   @size         : size of the buffer
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_map_stream_buf(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx, int fd,
+        size_t size, void *buffer, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
+          camera_handle, ch_id, stream_id, buf_idx, plane_idx);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
+                                  buf_type, buf_idx, plane_idx,
+                                  fd, size, buffer);
+    }else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_map_stream_bufs
+ *
+ * DESCRIPTION: mapping stream buffers via domain socket to server
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @buf_map_list : list of buffers to be mapped
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_map_stream_bufs(uint32_t camera_handle,
+        uint32_t ch_id, const cam_buf_map_type_list *buf_map_list,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t *my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    LOGD("E camera_handle = %d, ch_id = %d",
+          camera_handle, ch_id);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_map_stream_bufs(my_obj, ch_id, buf_map_list);
+    }else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_unmap_stream_buf
+ *
+ * DESCRIPTION: unmapping stream buffer via domain socket to server
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @s_id         : stream handle
+ *   @buf_type     : type of buffer to be unmapped. could be following values:
+ *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
+ *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
+ *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
+ *   @buf_idx      : index of buffer within the stream buffers, only valid if
+ *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
+ *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
+ *   @plane_idx    : plane index. If all planes share the same fd,
+ *                   plane_idx = -1; otherwise, plean_idx is the
+ *                   index to plane (0..num_of_planes)
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_unmap_stream_buf(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        uint8_t buf_type, uint32_t buf_idx,
+        int32_t plane_idx, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = -1;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    LOGD("E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
+          camera_handle, ch_id, stream_id, buf_idx, plane_idx);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
+                buf_type, buf_idx, plane_idx);
+    } else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_set_stream_parms
+ *
+ * DESCRIPTION: set parameters per stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @s_id         : stream handle
+ *   @parms        : ptr to a param struct to be set to server
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_set_stream_parms(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
+    } else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_stream_parms
+ *
+ * DESCRIPTION: get parameters per stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @s_id         : stream handle
+ *   @parms        : ptr to a param struct to be get from server
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_get_stream_parms(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t s_id, cam_stream_parm_buffer_t *parms,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
+    } else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_start_channel
+ *
+ * DESCRIPTION: start a channel, which will start all streams in the channel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_start_channel(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_start_channel(my_obj, ch_id);
+    } else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_stop_channel
+ *
+ * DESCRIPTION: stop a channel, which will stop all streams in the channel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_stop_channel(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_stop_channel(my_obj, ch_id);
+    } else{
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_intf_qbuf
+ *
+ * DESCRIPTION: enqueue buffer back to kernel
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @buf          : buf ptr to be enqueued
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_qbuf(uint32_t camera_handle, uint32_t ch_id,
+        mm_camera_buf_def_t *buf, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_qbuf(my_obj, ch_id, buf);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_queued_buf_count
+ *
+ * DESCRIPTION: returns the queued buffer count
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id : stream id
+ *
+ * RETURN     : int32_t - queued buffer count
+ *
+ *==========================================================================*/
+int32_t mm_camera_muxer_get_queued_buf_count(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_request_super_buf
+ *
+ * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
+ *              frames from superbuf queue
+ *
+ * PARAMETERS :
+ *   @ch_id             : channel handle
+ *   @buf                : request buffer info
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_request_super_buf(uint32_t ch_id,
+        mm_camera_req_buf_t *buf, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = cam_obj;
+    uint32_t chID = get_main_camera_handle(ch_id);
+
+    if(my_obj && buf) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_start_frame_sync(my_obj,
+                chID, 0);
+        LOGH("Start Frame Sync chid = %d rc = %d", chID, rc);
+        pthread_mutex_lock(&my_obj->cam_lock);
+        rc = mm_camera_request_super_buf (my_obj, chID, buf);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_cancel_super_buf_request
+ *
+ * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
+ *              frames from superbuf queue
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id             : channel handle
+ *   @buf                : request buffer info
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_cancel_super_buf_request(uint32_t camera_handle,
+        uint32_t ch_id,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    uint32_t aux_handle = get_aux_camera_handle(camera_handle);
+    uint32_t aux_chID = get_main_camera_handle(ch_id);
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
+        pthread_mutex_lock(&my_obj->cam_lock);
+        mm_camera_stop_frame_sync(my_obj,
+                ch_id, 0);
+        
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+
+    my_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_cancel_super_buf_request(my_obj, aux_chID);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_flush_super_buf_queue
+ *
+ * DESCRIPTION: flush out all frames in the superbuf queue
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @frame_idx    : frame index
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_flush_super_buf_queue(uint32_t camera_handle,
+        uint32_t ch_id,
+        uint32_t frame_idx, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&cam_obj->muxer_lock);
+            rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_configure_notify_mode
+ *
+ * DESCRIPTION: Configures channel notification mode
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @notify_mode  : notification mode
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_configure_notify_mode(uint32_t camera_handle,
+        uint32_t ch_id, mm_camera_super_buf_notify_mode_t notify_mode,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+            pthread_mutex_lock(&my_obj->cam_lock);
+            pthread_mutex_unlock(&cam_obj->muxer_lock);
+            rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_process_advanced_capture
+ *
+ * DESCRIPTION: Configures channel advanced capture mode
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @type : advanced capture type
+ *   @ch_id        : channel handle
+ *   @trigger  : 1 for start and 0 for cancel/stop
+ *   @value  : input capture configaration
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_process_advanced_capture(uint32_t camera_handle,
+         uint32_t ch_id, mm_camera_advanced_capture_t type,
+         int8_t start_flag, void *in_value, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
+                (uint32_t)start_flag, in_value);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_session_id
+ *
+ * DESCRIPTION: retrieve the session ID from the kernel for this HWI instance
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @sessionid: session id to be retrieved from server
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_get_session_id(uint32_t camera_handle,
+        uint32_t* sessionid, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        *sessionid = my_obj->sessionid;
+        pthread_mutex_unlock(&my_obj->cam_lock);
+        rc = 0;
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+ /*===========================================================================
+ * FUNCTION   : mm_camera_muxer_flush
+ *
+ * DESCRIPTION: flush the current camera state and buffers
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_flush(uint32_t camera_handle, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_flush(my_obj);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_register_stream_buf_cb
+ *
+ * DESCRIPTION: Register special callback for stream buffer
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *   @buf_cb       : callback function
+ *   @buf_type     :SYNC/ASYNC
+ *   @userdata     : userdata pointer
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_register_stream_buf_cb(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
+        mm_camera_stream_cb_type cb_type, void *userdata, mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
+                buf_cb, cb_type, userdata);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_reg_frame_sync
+ *
+ * DESCRIPTION: Configure for frame sync.
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *   @sync_attr    : Attributes for frame sync
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_reg_frame_sync(mm_camera_obj_t *cam_obj,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_intf_frame_sync_t *sync_attr)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t *a_cam_obj = NULL;
+
+    mm_camera_frame_sync_t frame_sync;
+    if (sync_attr == NULL || cam_obj == NULL) {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        return rc;
+    }
+
+    uint32_t chid = get_main_camera_handle(ch_id);
+    uint32_t aux_handle = get_aux_camera_handle(sync_attr->camera_handle);
+    uint32_t aux_chid = get_aux_camera_handle(sync_attr->ch_id);
+    uint32_t strid = 0;
+    uint32_t aux_strid = 0;
+    if (stream_id) {
+        LOGD("Stream frame sync enabled");
+        strid = get_main_camera_handle(stream_id);
+        aux_strid = get_aux_camera_handle(sync_attr->stream_id);
+        if(aux_strid == 0) {
+            aux_handle = get_main_camera_handle(sync_attr->camera_handle);
+            aux_chid = get_main_camera_handle(sync_attr->ch_id);
+            aux_strid = get_main_camera_handle(sync_attr->stream_id);
+        }
+    } else {
+        LOGD("Channel frame sync enabled");
+        if(aux_chid == 0) {
+            aux_chid = get_main_camera_handle(sync_attr->ch_id);
+        }
+    }
+    a_cam_obj = mm_muxer_util_get_camera_by_obj(aux_handle, cam_obj);
+
+    if(a_cam_obj) {
+        memset(&frame_sync, 0, sizeof(frame_sync));
+        frame_sync.a_cam_obj = a_cam_obj;
+        frame_sync.a_stream_id = aux_strid;
+        frame_sync.a_ch_id = aux_chid;
+        frame_sync.userdata = sync_attr->userdata;
+        frame_sync.buf_cb = sync_attr->buf_cb;
+        frame_sync.max_unmatched_frames = sync_attr->max_unmatched_frames;
+        frame_sync.is_res_shared = 1;
+        pthread_mutex_lock(&cam_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        rc = mm_camera_reg_frame_sync(cam_obj, chid, strid, &frame_sync);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_start_frame_sync
+ *
+ * DESCRIPTION: start frame buffer sync for the stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_start_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = 0;
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&my_obj->muxer_lock);
+        LOGD("ch_id = %d stream_id = %d", ch_id, stream_id);
+        rc = mm_camera_start_frame_sync(my_obj,
+                ch_id, stream_id);
+    } else {
+        pthread_mutex_unlock(&my_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_stop_frame_sync
+ *
+ * DESCRIPTION: stop frame buffer sync for the stream
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_stop_frame_sync(mm_camera_obj_t *my_obj,
+        uint32_t ch_id, uint32_t stream_id)
+{
+    int32_t rc = 0;
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&my_obj->muxer_lock);
+        LOGD("ch_id = %d stream_id = %d", ch_id, stream_id);
+        rc = mm_camera_stop_frame_sync(my_obj,
+                ch_id, stream_id);
+    } else {
+        pthread_mutex_unlock(&my_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_switch_stream
+ *
+ * DESCRIPTION: switch between stream in case of multi streams
+ *
+ * PARAMETERS :
+ *   @camera_handle: camera handle
+ *   @ch_id        : channel handle
+ *   @stream_id    : stream handle
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_switch_stream(uint32_t camera_handle,
+        uint32_t ch_id, uint32_t stream_id,
+        mm_camera_obj_t *cam_obj)
+{
+    int32_t rc = 0;
+    mm_camera_obj_t * my_obj = NULL;
+    my_obj = mm_muxer_util_get_camera_by_obj(camera_handle, cam_obj);
+
+    if(my_obj) {
+        pthread_mutex_lock(&my_obj->cam_lock);
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+        LOGD("ch_id = %d stream_id = %d", ch_id, stream_id);
+        //TODO
+        //rc = mm_camera_reg_stream_buf_cb(my_obj, ch_id, stream_id,
+        //        buf_cb, cb_type, userdata);
+    } else {
+        pthread_mutex_unlock(&cam_obj->muxer_lock);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_stream_frame_sync
+ *
+ * DESCRIPTION: Handle stream buffers for frame sync
+ *
+ * PARAMETERS :
+ *   @super_buf: Stream buffers
+ *   @user_data        : Stream object
+ *
+ * RETURN     : none
+ *==========================================================================*/
+void mm_camera_muxer_stream_frame_sync(mm_camera_super_buf_t *super_buf,
+        void *user_data)
+{
+    int32_t rc = 0, i = 0;
+    mm_stream_t *my_obj = (mm_stream_t *)user_data;
+    mm_frame_sync_queue_node_t dispatch_buf;
+
+    if (my_obj->master_str_obj != NULL) {
+        my_obj = my_obj->master_str_obj;
+    }
+
+    memset(&dispatch_buf, 0, sizeof(dispatch_buf));
+    rc = mm_camera_muxer_do_frame_sync(&my_obj->frame_sync.superbuf_queue,
+            super_buf, &dispatch_buf);
+    if (rc < 0) {
+        LOGE("frame sync failed");
+        return;
+    }
+
+    if (my_obj->frame_sync.super_buf_notify_cb && dispatch_buf.num_objs > 0) {
+        mm_camera_super_buf_t super_buf;
+        memset(&super_buf, 0, sizeof(super_buf));
+        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
+            if (dispatch_buf.super_buf[i].num_bufs == 1) {
+                super_buf.bufs[super_buf.num_bufs++] =
+                        dispatch_buf.super_buf[i].bufs[0];
+                super_buf.camera_handle |= dispatch_buf.super_buf[i].camera_handle;
+                super_buf.ch_id |= dispatch_buf.super_buf[i].ch_id;
+            }
+        }
+        my_obj->frame_sync.super_buf_notify_cb(&super_buf,
+                my_obj->frame_sync.user_data);
+
+        if (my_obj->frame_sync.num_buf_requested != 0) {
+            my_obj->frame_sync.num_buf_requested--;
+            if (my_obj->frame_sync.num_buf_requested == 0) {
+                my_obj->frame_sync.is_active = 0;
+            }
+        }
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_channel_frame_sync
+ *
+ * DESCRIPTION: Handle channel super buffers for frame sync
+ *
+ * PARAMETERS :
+ *   @super_buf: channel buffers
+ *   @user_data        : channel object
+ *
+ * RETURN     : none
+ *==========================================================================*/
+void mm_camera_muxer_channel_frame_sync(mm_camera_super_buf_t *super_buf,
+        void *user_data)
+{
+    int32_t rc = 0, i = 0;
+    mm_camera_super_buf_notify_mode_t notify_mode;
+    mm_channel_t *m_obj = (mm_channel_t *)user_data;
+    mm_channel_t *s_obj = m_obj;
+    mm_frame_sync_queue_node_t dispatch_buf;
+
+    if ((super_buf == NULL) && (super_buf->num_bufs == 0)) {
+        return;
+    }
+
+    if (m_obj->master_ch_obj != NULL) {
+        m_obj = m_obj->master_ch_obj;
+    }
+
+    notify_mode = m_obj->bundle.superbuf_queue.attr.notify_mode;
+    if (notify_mode == MM_CAMERA_SUPER_BUF_NOTIFY_BURST
+            && (super_buf->ch_id == m_obj->my_hdl)) {
+        mm_camera_req_buf_t req_buf;
+        memset(&req_buf, 0, sizeof(req_buf));
+        req_buf.num_buf_requested = 1;
+        req_buf.frame_idx = super_buf->bufs[0]->frame_idx;
+        s_obj = m_obj->aux_ch_obj[0];
+        pthread_mutex_lock(&s_obj->cam_obj->cam_lock);
+        mm_camera_request_super_buf(s_obj->cam_obj,
+                s_obj->my_hdl, &req_buf);
+    }
+
+    memset(&dispatch_buf, 0, sizeof(dispatch_buf));
+    rc = mm_camera_muxer_do_frame_sync(&m_obj->frame_sync.superbuf_queue,
+            super_buf, &dispatch_buf);
+
+    if (m_obj->frame_sync.super_buf_notify_cb && rc == 0 && dispatch_buf.num_objs > 1) {
+        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
+            if (dispatch_buf.super_buf[i].num_bufs != 0) {
+                LOGH("Super buffer frameID : %d",
+                        dispatch_buf.super_buf[i].bufs[0]->frame_idx);
+                m_obj->frame_sync.super_buf_notify_cb(&dispatch_buf.super_buf[i],
+                        m_obj->frame_sync.user_data);
+            }
+        }
+        if (m_obj->frame_sync.num_buf_requested > 0) {
+            m_obj->frame_sync.num_buf_requested--;
+            if (m_obj->frame_sync.num_buf_requested == 0) {
+                LOGH("Stop Frame Sync chid = %d", m_obj->my_hdl);
+                m_obj->frame_sync.is_active = 0;
+            }
+        }
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_frame_sync_dequeue
+ *
+ * DESCRIPTION: dequeue object from frame sync queue
+ *
+ * PARAMETERS :
+ *   @queue: ptr to queue to dequeue object
+ *   @dispatch_buf        : Ptr to carry dequeued node
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_frame_sync_dequeue(
+        mm_frame_sync_queue_t *queue, mm_frame_sync_queue_node_t *dispatch_buf)
+{
+    int32_t rc = 0;
+    cam_node_t* node = NULL;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+    mm_frame_sync_queue_node_t* super_buf = NULL;
+
+    pthread_mutex_lock(&queue->que.lock);
+    head = &queue->que.head.list;
+    pos = head->next;
+    if (pos != head) {
+        /* get the first node */
+        node = member_of(pos, cam_node_t, list);
+        super_buf = (mm_frame_sync_queue_node_t*)node->data;
+        if (NULL != super_buf) {
+            *dispatch_buf = *super_buf;
+            queue->que.size--;
+            cam_list_del_node(&node->list);
+            free(node);
+            free(super_buf);
+        }
+    }
+    pthread_mutex_unlock(&queue->que.lock);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_do_frame_sync
+ *
+ * DESCRIPTION: function to process object buffers and match with existing frames.
+ *
+ * PARAMETERS :
+ *   @queue: ptr to queue to dequeue object
+ *   @buffer: Input buffer to match and insert
+ *   @dispatch_buf        : Ptr to carry matched node
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_do_frame_sync(
+        mm_frame_sync_queue_t *queue, mm_camera_super_buf_t *buffer,
+        mm_frame_sync_queue_node_t *dispatch_buf)
+{
+    cam_node_t* node = NULL;
+    uint8_t buf_s_idx, found_super_buf, unmatched_bundles;
+    struct cam_list *head = NULL;
+    struct cam_list *pos = NULL;
+    mm_frame_sync_queue_node_t* super_buf = NULL;
+    struct cam_list *last_buf = NULL, *insert_before_buf = NULL;
+
+    if (buffer == NULL || buffer->num_bufs == 0) {
+        LOGW("Ivalid Argument");
+        return -1;
+    }
+
+    for (buf_s_idx = 0; buf_s_idx < queue->num_objs; buf_s_idx++) {
+        if ((buffer->ch_id == queue->bundled_objs[buf_s_idx]) ||
+                (buffer->bufs[0]->stream_id == queue->bundled_objs[buf_s_idx])) {
+            break;
+        }
+    }
+    if (buf_s_idx == queue->num_objs) {
+        LOGE("buf from stream (%d) not bundled", buffer->bufs[0]->stream_id);
+        mm_camera_muxer_buf_done(buffer);
+        return -1;
+    }
+
+    if (buffer->bufs[0]->frame_idx <= queue->expected_frame_id) {
+        LOGD("old frame. Need to release");
+        mm_camera_muxer_buf_done(buffer);
+        return 0;
+    }
+
+    pthread_mutex_lock(&queue->que.lock);
+    head = &queue->que.head.list;
+    pos = head->next;
+    found_super_buf = 0;
+    unmatched_bundles = 0;
+    last_buf = NULL;
+    insert_before_buf = NULL;
+
+    while (pos != head) {
+        node = member_of(pos, cam_node_t, list);
+        super_buf = (mm_frame_sync_queue_node_t *)node->data;
+
+        if (NULL != super_buf) {
+            if (buffer->bufs[0]->frame_idx == super_buf->frame_idx) {
+                found_super_buf = 1;
+                break;
+            } else if ((buffer->bufs[0]->frame_idx >= super_buf->frame_idx)
+                    && (queue->priority == MM_CAMERA_SUPER_BUF_PRIORITY_LOW)) {
+                found_super_buf = 1;
+                break;
+            } else {
+                unmatched_bundles++;
+                if ( NULL == last_buf ) {
+                    if ( super_buf->frame_idx < buffer->bufs[0]->frame_idx) {
+                        last_buf = pos;
+                    }
+                }
+                if ( NULL == insert_before_buf ) {
+                    if ( super_buf->frame_idx > buffer->bufs[0]->frame_idx) {
+                        insert_before_buf = pos;
+                    }
+                }
+                pos = pos->next;
+            }
+        }
+    }
+
+    LOGD("found_super_buf = %d id = %d unmatched = %d max = %d", found_super_buf,
+            buffer->bufs[0]->frame_idx, unmatched_bundles,
+            queue->max_unmatched_frames);
+    if ( found_super_buf ) {
+        super_buf->super_buf[buf_s_idx] = *buffer;
+        super_buf->num_objs++;
+        if (super_buf->num_objs == queue->num_objs) {
+            super_buf->matched = 1;
+            *dispatch_buf = *super_buf;
+            queue->que.size--;
+            cam_list_del_node(&node->list);
+            free(node);
+            free(super_buf);
+        }
+    } else {
+        if ((queue->max_unmatched_frames < unmatched_bundles)
+                && (NULL == last_buf)) {
+            //incoming frame is older than the last bundled one
+            mm_camera_muxer_buf_done(buffer);
+        } else if (queue->max_unmatched_frames < unmatched_bundles) {
+            //dispatch old buffer. Cannot sync for configured unmatch value
+            node = member_of(last_buf, cam_node_t, list);
+            super_buf = (mm_frame_sync_queue_node_t*)node->data;
+            *dispatch_buf = *super_buf;
+            queue->que.size--;
+            cam_list_del_node(&node->list);
+            free(node);
+            free(super_buf);
+        }
+
+        //insert the new frame at the appropriate position.
+        mm_frame_sync_queue_node_t *new_buf = NULL;
+        cam_node_t* new_node = NULL;
+
+        new_buf = (mm_frame_sync_queue_node_t *)malloc(sizeof(mm_frame_sync_queue_node_t));
+        if (NULL != new_buf) {
+            memset(new_buf, 0, sizeof(mm_channel_queue_node_t));
+            new_buf->super_buf[buf_s_idx] = *buffer;
+            new_buf->num_objs++;
+            new_buf->frame_idx = buffer->bufs[0]->frame_idx;
+            if (new_buf->num_objs == queue->num_objs) {
+                new_buf->matched = 1;
+                *dispatch_buf = *new_buf;
+                queue->que.size--;
+                free(new_buf);
+                free(new_node);
+            } else {
+                /* enqueue */
+                new_node = (cam_node_t *)malloc(sizeof(cam_node_t));
+                memset(new_node, 0, sizeof(cam_node_t));
+                new_node->data = (void *)new_buf;
+                if ( insert_before_buf ) {
+                    cam_list_insert_before_node(&new_node->list, insert_before_buf);
+                } else {
+                    cam_list_add_tail_node(&new_node->list, &queue->que.head.list);
+                }
+                queue->que.size++;
+            }
+        } else {
+            if (NULL != new_buf) {
+                free(new_buf);
+            }
+            mm_camera_muxer_buf_done(buffer);
+        }
+    }
+
+    if (dispatch_buf != NULL && dispatch_buf->num_objs != 0) {
+       queue->expected_frame_id = queue->expected_frame_id;
+    }
+    pthread_mutex_unlock(&queue->que.lock);
+    return 0;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_buf_done
+ *
+ * DESCRIPTION: function release super buffer.
+ *
+ * PARAMETERS :
+ *   @buffer: ptr to super buffer to release.
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+void mm_camera_muxer_buf_done(mm_camera_super_buf_t *buffer)
+{
+    uint8_t i;
+    mm_camera_obj_t *my_obj = NULL;
+
+    if (buffer == NULL) {
+        LOGW("Null buffer");
+        return;
+    }
+
+    my_obj = mm_camera_util_get_camera_by_handler(buffer->camera_handle);
+    for (i=0; i < buffer->num_bufs; i++) {
+        if (buffer->bufs[i] != NULL) {
+            mm_camera_qbuf(my_obj, buffer->ch_id, buffer->bufs[i]);
+        }
+    }
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_muxer_frame_sync_queue_init
+ *
+ * DESCRIPTION: Inittialize frame sync queue
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_muxer_frame_sync_queue_init(mm_frame_sync_queue_t *queue)
+{
+    int32_t rc = 0;
+    queue->expected_frame_id = 0;
+    queue->num_objs = 0;
+    memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
+    rc = cam_queue_init(&queue->que);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_muxer_frame_sync_queue_deinit
+ *
+ * DESCRIPTION: Inittialize frame sync queue
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_muxer_frame_sync_queue_deinit(mm_frame_sync_queue_t *queue)
+{
+    int32_t rc = 0;
+    rc = cam_queue_deinit(&queue->que);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_stream_frame_sync_flush
+ *
+ * DESCRIPTION: function to flush frame sync queue
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_stream_frame_sync_flush(mm_stream_t *str_obj)
+{
+    int32_t rc = 0, i = 0;
+    mm_stream_t *my_obj = str_obj;
+    mm_frame_sync_queue_node_t super_buf;
+    memset(&super_buf, 0, sizeof(super_buf));
+
+    if (my_obj->master_str_obj) {
+        my_obj = my_obj->master_str_obj;
+    }
+
+    rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
+    while (super_buf.num_objs != 0 && rc != 0) {
+        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
+            mm_camera_super_buf_t dispatch_buf;
+            memset(&dispatch_buf, 0, sizeof(dispatch_buf));
+            if (super_buf.super_buf[i].num_bufs == 1) {
+                dispatch_buf.bufs[dispatch_buf.num_bufs++] =
+                        super_buf.super_buf[i].bufs[0];
+                dispatch_buf.camera_handle |= super_buf.super_buf[i].camera_handle;
+                dispatch_buf.ch_id |= super_buf.super_buf[i].ch_id;
+                my_obj->frame_sync.super_buf_notify_cb(&dispatch_buf,
+                        my_obj->frame_sync.user_data);
+            }
+        }
+        rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_channel_frame_sync_flush
+ *
+ * DESCRIPTION: function to flush frame sync queue
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_channel_frame_sync_flush(mm_channel_t *my_obj)
+{
+    int32_t rc = 0, i = 0;
+    mm_frame_sync_queue_node_t super_buf;
+    memset(&super_buf, 0, sizeof(super_buf));
+
+    if (my_obj->master_ch_obj) {
+        my_obj = my_obj->master_ch_obj;
+    }
+
+    rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
+    while (super_buf.num_objs != 0 && rc != 0) {
+        for (i = 0; i < MAX_OBJS_FOR_FRAME_SYNC; i++) {
+            if (super_buf.super_buf[i].num_bufs == 1) {
+                mm_camera_muxer_buf_done(&super_buf.super_buf[i]);
+            }
+        }
+        rc = mm_camera_muxer_frame_sync_dequeue(&my_obj->frame_sync.superbuf_queue, &super_buf);
+    }
+
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_stream_buf_cnt
+ *
+ * DESCRIPTION: function to calculate buffer count for auxillary streams.
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+uint32_t mm_camera_muxer_get_stream_buf_cnt(mm_stream_t *str_obj)
+{
+    uint32_t buf_cnt = 0;
+    uint8_t i = 0;
+    mm_stream_t *my_obj = str_obj;
+
+    if (str_obj->master_str_obj != NULL) {
+        my_obj = str_obj->master_str_obj;
+    }
+
+    buf_cnt = my_obj->buf_num;
+    for (i = 0; i < my_obj->num_s_cnt; i++) {
+        if (my_obj->aux_str_obj[i]->is_res_shared) {
+            buf_cnt += my_obj->aux_str_obj[i]->buf_num;
+        }
+    }
+    if (buf_cnt > CAM_MAX_NUM_BUFS_PER_STREAM) {
+        buf_cnt = CAM_MAX_NUM_BUFS_PER_STREAM;
+    }
+    return buf_cnt;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_get_stream_bufs
+ *
+ * DESCRIPTION: function to assign buffers for auxillary streams.
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_get_stream_bufs(mm_stream_t *my_obj)
+{
+    int32_t rc = 0;
+    uint32_t i = 0;
+    mm_stream_t *master_obj = NULL;
+
+    if (my_obj == NULL || my_obj->master_str_obj == NULL
+            || !my_obj->is_res_shared) {
+        LOGE("Invalid argument");
+        return rc;
+    }
+    master_obj = my_obj->master_str_obj;
+
+    if (master_obj->total_buf_cnt == 0) {
+        my_obj->buf_idx = 0;
+        return rc;
+    }
+
+    if ((master_obj->total_buf_cnt -
+            (master_obj->buf_idx + master_obj->buf_num))
+            <= 0) {
+        LOGE("No enough buffer available %d num_bufs = %d",
+                master_obj->total_buf_cnt, master_obj->buf_num);
+        return rc;
+    }
+
+    my_obj->total_buf_cnt = master_obj->total_buf_cnt;
+    my_obj->buf_idx = master_obj->buf_idx + master_obj->buf_num;
+    if ((my_obj->buf_idx + my_obj->buf_num) > my_obj->total_buf_cnt) {
+        my_obj->buf_num = my_obj->total_buf_cnt - my_obj->buf_idx;
+    }
+
+    my_obj->buf = master_obj->buf;
+    for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
+        my_obj->buf_status[i].initial_reg_flag =
+                master_obj->buf_status[i].initial_reg_flag;
+    }
+    LOGH("Buffer total = %d buf_cnt = %d offsset = %d",my_obj->total_buf_cnt,
+            my_obj->buf_num, my_obj->buf_idx);
+    return 0;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_put_stream_bufs
+ *
+ * DESCRIPTION: function to release buffers for auxillary streams.
+ *
+ * PARAMETERS :
+ *   @queue: ptr to frame sync queue
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_muxer_put_stream_bufs(mm_stream_t *my_obj)
+{
+    int32_t rc = -1;
+
+    if (my_obj == NULL || !my_obj->is_res_shared) {
+        LOGE("Invalid argument");
+        return rc;
+    }
+    my_obj->total_buf_cnt = 0;
+    return 0;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_map_stream_buf_ops
+ *
+ * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
+ *              This function will be passed to upper layer as part of ops table
+ *              to be used by upper layer when allocating stream buffers and mapping
+ *              buffers to server via domain socket.
+ *
+ * PARAMETERS :
+ *   @frame_idx    : index of buffer within the stream buffers, only valid if
+ *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
+ *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
+ *   @plane_idx    : plane index. If all planes share the same fd,
+ *                   plane_idx = -1; otherwise, plean_idx is the
+ *                   index to plane (0..num_of_planes)
+ *   @fd           : file descriptor of the buffer
+ *   @size         : size of the buffer
+ *   @userdata     : user data ptr (stream object)
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_map_stream_buf_ops(uint32_t buf_idx,
+        int32_t plane_idx, int fd, size_t size,
+        void *buffer, cam_mapping_buf_type type,
+        void *userdata)
+{
+    int32_t rc = 0;
+    mm_stream_t *my_obj = (mm_stream_t *)userdata;
+    int32_t i = 0;
+
+    switch (type) {
+        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
+        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
+            if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
+                my_obj = my_obj->aux_str_obj[buf_idx];
+            }
+            break;
+        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
+        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
+        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
+        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
+            for(i = 0; i < my_obj->num_s_cnt; i++) {
+                if (my_obj->aux_str_obj[i] != NULL) {
+                    rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
+                            type, buf_idx, plane_idx, fd, size, buffer);
+                }
+            }
+            break;
+        default:
+            LOGE("Not buffer for stream : %d", type);
+            rc = -1;
+            break;
+    }
+
+    if (rc == 0) {
+        rc = mm_stream_map_buf(my_obj,
+                type, buf_idx, plane_idx, fd, size, buffer);
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_bundled_map_buf_ops
+ *
+ * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
+ *              This function will be passed to upper layer as part of ops table
+ *              to be used by upper layer when allocating stream buffers and mapping
+ *              buffers to server via domain socket.
+ *
+ * PARAMETERS :
+ *   @buf_map_list : list of buffer mapping information
+ *   @userdata     : user data ptr (stream object)
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_bundled_map_stream_buf_ops(
+        const cam_buf_map_type_list *buf_map_list,
+        void *userdata)
+{
+    int32_t rc = 0;
+    mm_stream_t *my_obj = (mm_stream_t *)userdata;
+    uint32_t i = 0;
+
+    if (buf_map_list == NULL || buf_map_list->length == 0) {
+        LOGW("Invalid argument");
+        return rc;
+    }
+
+    uint32_t buf_idx;
+    cam_mapping_buf_type type = buf_map_list->buf_maps[0].type;
+    switch (type) {
+        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
+        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
+            buf_idx = buf_map_list->buf_maps[0].frame_idx;
+            if (buf_idx == 0) {
+                rc = mm_stream_map_buf(my_obj,
+                        type, buf_idx,
+                        buf_map_list->buf_maps[0].plane_idx,
+                        buf_map_list->buf_maps[0].fd,
+                        buf_map_list->buf_maps[0].size,
+                        buf_map_list->buf_maps[0].buffer);
+                if (rc != 0) {
+                    LOGE("Failed rc = %d", rc);
+                }
+            }
+            for (i = 1; i < buf_map_list->length; i++) {
+                buf_idx = buf_map_list->buf_maps[i].frame_idx;
+                if ((i == buf_idx)
+                        && (my_obj->aux_str_obj[i] != NULL)) {
+                    rc = mm_stream_map_buf(my_obj->aux_str_obj[i],
+                            type, buf_idx,
+                            buf_map_list->buf_maps[i].plane_idx,
+                            buf_map_list->buf_maps[i].fd,
+                            buf_map_list->buf_maps[i].size,
+                            buf_map_list->buf_maps[i].buffer);
+                }
+            }
+            break;
+        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
+        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
+        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
+        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
+            rc = mm_stream_map_bufs(my_obj, buf_map_list);
+            for(i = 0; i < my_obj->num_s_cnt; i++) {
+                if (my_obj->aux_str_obj[i] != NULL) {
+                    rc = mm_stream_map_bufs(my_obj->aux_str_obj[i],
+                            buf_map_list);
+                }
+            }
+            break;
+        default:
+            LOGE("Not buffer for stream : %d", type);
+            rc = -1;
+            break;
+    }
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_camera_muxer_unmap_buf_ops
+ *
+ * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
+ *              This function will be passed to upper layer as part of ops table
+ *              to be used by upper layer when allocating stream buffers and unmapping
+ *              buffers to server via domain socket.
+ *
+ * PARAMETERS :
+ *   @frame_idx    : index of buffer within the stream buffers, only valid if
+ *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
+ *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
+ *   @plane_idx    : plane index. If all planes share the same fd,
+ *                   plane_idx = -1; otherwise, plean_idx is the
+ *                   index to plane (0..num_of_planes)
+ *   @userdata     : user data ptr (stream object)
+ *
+ * RETURN     : int32_t type of status
+ *              0  -- success
+ *              -1 -- failure
+ *==========================================================================*/
+int32_t mm_camera_unmap_stream_buf_ops(uint32_t buf_idx,
+           int32_t plane_idx, cam_mapping_buf_type type, void *userdata)
+{
+    int32_t rc = 0;
+    mm_stream_t *my_obj = (mm_stream_t *)userdata;
+    int32_t i = 0;
+
+    switch (type) {
+        case CAM_MAPPING_BUF_TYPE_STREAM_INFO:
+        case CAM_MAPPING_BUF_TYPE_MISC_BUF:
+            if (buf_idx != 0 && my_obj->aux_str_obj[buf_idx] != NULL) {
+                my_obj = my_obj->aux_str_obj[buf_idx];
+            }
+            break;
+        case CAM_MAPPING_BUF_TYPE_STREAM_BUF:
+        case CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF:
+        case CAM_MAPPING_BUF_TYPE_OFFLINE_META_BUF:
+        case CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF:
+            for(i = 0; i < my_obj->num_s_cnt; i++) {
+                if (my_obj->aux_str_obj[i] != NULL) {
+                    rc = mm_stream_unmap_buf(my_obj->aux_str_obj[i],
+                            type, buf_idx, plane_idx);
+                }
+            }
+            break;
+        default:
+            LOGE("Not buffer for stream : %d", type);
+            rc = -1;
+            break;
+    }
+
+    if (rc == 0) {
+        rc = mm_stream_unmap_buf(my_obj,
+                type, buf_idx, plane_idx);
+    }
+    return rc;
+}
+
+
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
index 70b91a8..fb332ae 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_stream.c
@@ -43,6 +43,7 @@
 #include "mm_camera_dbg.h"
 #include "mm_camera_interface.h"
 #include "mm_camera.h"
+#include "mm_camera_muxer.h"
 
 /* internal function decalre */
 int32_t mm_stream_qbuf(mm_stream_t *my_obj,
@@ -71,6 +72,8 @@
 int32_t mm_stream_write_user_buf(mm_stream_t * my_obj,
         mm_camera_buf_def_t *buf);
 
+int32_t mm_stream_init(mm_stream_t *my_obj);
+int32_t mm_stream_deinit(mm_stream_t *my_obj);
 int32_t mm_stream_config(mm_stream_t *my_obj,
                          mm_camera_stream_config_t *config);
 int32_t mm_stream_reg_buf(mm_stream_t * my_obj);
@@ -133,7 +136,10 @@
                              void * in_val,
                              void * out_val);
 uint32_t mm_stream_get_v4l2_fmt(cam_format_t fmt);
-
+int32_t mm_stream_reg_frame_sync(mm_stream_t *my_obj,
+        mm_evt_paylod_reg_frame_sync *sync);
+int32_t mm_stream_trigger_frame_sync(mm_stream_t *my_obj, uint8_t start_sync);
+int32_t mm_stream_switch_stream_callback(mm_stream_t *my_obj);
 
 /*===========================================================================
  * FUNCTION   : mm_stream_notify_channel
@@ -379,6 +385,7 @@
     mm_stream_t * my_obj = (mm_stream_t *)user_data;
     mm_camera_buf_info_t* buf_info = NULL;
     mm_camera_super_buf_t super_buf;
+    mm_stream_t *m_obj = my_obj;
 
     if (NULL == my_obj) {
         return;
@@ -399,38 +406,51 @@
     super_buf.camera_handle = my_obj->ch_obj->cam_obj->my_hdl;
     super_buf.ch_id = my_obj->ch_obj->my_hdl;
 
-    pthread_mutex_lock(&my_obj->cb_lock);
-    for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
-        if(NULL != my_obj->buf_cb[i].cb
-                && (my_obj->buf_cb[i].cb_type !=
-                MM_CAMERA_STREAM_CB_TYPE_SYNC)) {
-            if (my_obj->buf_cb[i].cb_count != 0) {
-                /* if <0, means infinite CB
-                 * if >0, means CB for certain times
-                 * both case we need to call CB */
+    if (m_obj->master_str_obj != NULL) {
+        m_obj = m_obj->master_str_obj;
+    }
 
-                /* increase buf ref cnt */
-                pthread_mutex_lock(&my_obj->buf_lock);
-                my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
-                pthread_mutex_unlock(&my_obj->buf_lock);
+    pthread_mutex_lock(&m_obj->frame_sync.sync_lock);
+    if (m_obj->frame_sync.is_active) {
+        pthread_mutex_lock(&my_obj->buf_lock);
+        my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
+        pthread_mutex_unlock(&my_obj->buf_lock);
+        mm_camera_muxer_stream_frame_sync(&super_buf, my_obj);
+    } else if (my_obj->is_cb_active) {
+        pthread_mutex_lock(&my_obj->cb_lock);
+        for(i = 0; i < MM_CAMERA_STREAM_BUF_CB_MAX; i++) {
+            if(NULL != my_obj->buf_cb[i].cb
+                    && (my_obj->buf_cb[i].cb_type !=
+                    MM_CAMERA_STREAM_CB_TYPE_SYNC)) {
+                if (my_obj->buf_cb[i].cb_count != 0) {
+                    /* if <0, means infinite CB
+                     * if >0, means CB for certain times
+                     * both case we need to call CB */
 
-                /* callback */
-                my_obj->buf_cb[i].cb(&super_buf,
-                                     my_obj->buf_cb[i].user_data);
-            }
+                    /* increase buf ref cnt */
+                    pthread_mutex_lock(&my_obj->buf_lock);
+                    my_obj->buf_status[buf_info->buf->buf_idx].buf_refcnt++;
+                    pthread_mutex_unlock(&my_obj->buf_lock);
 
-            /* if >0, reduce count by 1 every time we called CB until reaches 0
-             * when count reach 0, reset the buf_cb to have no CB */
-            if (my_obj->buf_cb[i].cb_count > 0) {
-                my_obj->buf_cb[i].cb_count--;
-                if (0 == my_obj->buf_cb[i].cb_count) {
-                    my_obj->buf_cb[i].cb = NULL;
-                    my_obj->buf_cb[i].user_data = NULL;
+                    /* callback */
+                    my_obj->buf_cb[i].cb(&super_buf,
+                            my_obj->buf_cb[i].user_data);
+                }
+
+                /* if >0, reduce count by 1 every time we called CB until reaches 0
+                 * when count reach 0, reset the buf_cb to have no CB */
+                if (my_obj->buf_cb[i].cb_count > 0) {
+                    my_obj->buf_cb[i].cb_count--;
+                    if (0 == my_obj->buf_cb[i].cb_count) {
+                        my_obj->buf_cb[i].cb = NULL;
+                        my_obj->buf_cb[i].user_data = NULL;
+                    }
                 }
             }
         }
+        pthread_mutex_unlock(&my_obj->cb_lock);
     }
-    pthread_mutex_unlock(&my_obj->cb_lock);
+    pthread_mutex_unlock(&m_obj->frame_sync.sync_lock);
 
     /* do buf_done since we increased refcnt by one when has_cb */
     mm_stream_buf_done(my_obj, buf_info->buf);
@@ -530,10 +550,14 @@
             break;
         }
 
-        dev_name_value = mm_camera_util_get_dev_name(my_obj->ch_obj->cam_obj->my_hdl);
+        mm_stream_init(my_obj);
+        uint32_t cam_handle = my_obj->ch_obj->cam_obj->my_hdl;
+        dev_name_value = mm_camera_util_get_dev_name_by_num(
+                my_obj->ch_obj->cam_obj->my_num, cam_handle);
         if (NULL == dev_name_value) {
             LOGE("NULL device name\n");
             rc = -1;
+            mm_stream_deinit(my_obj);
             break;
         }
 
@@ -544,6 +568,7 @@
         if (my_obj->fd < 0) {
             LOGE("open dev returned %d\n", my_obj->fd);
             rc = -1;
+            mm_stream_deinit(my_obj);
             break;
         }
         LOGD("open dev fd = %d\n", my_obj->fd);
@@ -555,6 +580,7 @@
              * close fd */
             close(my_obj->fd);
             my_obj->fd = -1;
+            mm_stream_deinit(my_obj);
             break;
         }
         break;
@@ -623,6 +649,19 @@
             rc = mm_stream_get_parm(my_obj, payload->parms);
         }
         break;
+    case MM_STREAM_EVT_REG_FRAME_SYNC:
+        {
+            mm_evt_paylod_reg_frame_sync *payload =
+                (mm_evt_paylod_reg_frame_sync *)in_val;
+            rc = mm_stream_reg_frame_sync(my_obj, payload);
+        }
+        break;
+    case MM_STREAM_EVT_TRIGGER_FRAME_SYNC:
+        {
+            uint8_t trigger = *((uint8_t *)in_val);
+            rc = mm_stream_trigger_frame_sync(my_obj, trigger);
+        }
+        break;
     default:
         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
                     my_obj->state, evt, in_val, out_val);
@@ -693,6 +732,12 @@
             my_obj->state = MM_STREAM_STATE_BUFFED;
         }
         break;
+    case MM_STREAM_EVT_TRIGGER_FRAME_SYNC:
+        {
+            uint8_t trigger = *((uint8_t *)in_val);
+            rc = mm_stream_trigger_frame_sync(my_obj, trigger);
+        }
+        break;
     default:
         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
                     my_obj->state, evt, in_val, out_val);
@@ -924,6 +969,17 @@
     case MM_STREAM_EVT_DO_ACTION:
         rc = mm_stream_do_action(my_obj, in_val);
         break;
+    case MM_STREAM_EVT_TRIGGER_FRAME_SYNC:
+        {
+            uint8_t trigger = *((uint8_t *)in_val);
+            rc = mm_stream_trigger_frame_sync(my_obj, trigger);
+        }
+        break;
+    case MM_STREAM_EVT_SWITCH_STREAM_CB:
+        {
+            rc = mm_stream_switch_stream_callback(my_obj);
+        }
+        break;
     default:
         LOGE("invalid state (%d) for evt (%d), in(%p), out(%p)",
                     my_obj->state, evt, in_val, out_val);
@@ -932,95 +988,42 @@
     return rc;
 }
 
-/*===========================================================================
- * FUNCTION   : mm_stream_map_buf_ops
- *
- * DESCRIPTION: ops for mapping stream buffer via domain socket to server.
- *              This function will be passed to upper layer as part of ops table
- *              to be used by upper layer when allocating stream buffers and mapping
- *              buffers to server via domain socket.
- *
- * PARAMETERS :
- *   @frame_idx    : index of buffer within the stream buffers, only valid if
- *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
- *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
- *   @plane_idx    : plane index. If all planes share the same fd,
- *                   plane_idx = -1; otherwise, plean_idx is the
- *                   index to plane (0..num_of_planes)
- *   @fd           : file descriptor of the buffer
- *   @size         : size of the buffer
- *   @userdata     : user data ptr (stream object)
- *
- * RETURN     : int32_t type of status
- *              0  -- success
- *              -1 -- failure
- *==========================================================================*/
-static int32_t mm_stream_map_buf_ops(uint32_t frame_idx,
-        int32_t plane_idx, int fd, size_t size,
-        void *buffer, cam_mapping_buf_type type,
-        void *userdata)
+int32_t mm_stream_init(mm_stream_t *my_obj)
 {
-    mm_stream_t *my_obj = (mm_stream_t *)userdata;
-    return mm_stream_map_buf(my_obj,
-            type, frame_idx, plane_idx, fd, size, buffer);
+    int32_t rc = 0;
+    pthread_mutex_init(&my_obj->buf_lock, NULL);
+    pthread_mutex_init(&my_obj->cb_lock, NULL);
+    pthread_mutex_init(&my_obj->cmd_lock, NULL);
+    pthread_cond_init(&my_obj->buf_cond, NULL);
+    memset(my_obj->buf_status, 0,
+            sizeof(my_obj->buf_status));
+    memset(&my_obj->frame_sync, 0, sizeof(my_obj->frame_sync));
+    pthread_mutex_init(&my_obj->frame_sync.sync_lock, NULL);
+    mm_muxer_frame_sync_queue_init(&my_obj->frame_sync.superbuf_queue);
+    if (my_obj->ch_obj->cam_obj->my_num == 0) {
+        my_obj->is_cb_active = 1;
+    } else {
+        my_obj->is_cb_active = 0;
+    }
+    my_obj->is_res_shared = 0;
+    my_obj->map_ops.map_ops = mm_camera_map_stream_buf_ops;
+    my_obj->map_ops.bundled_map_ops = mm_camera_bundled_map_stream_buf_ops;
+    my_obj->map_ops.unmap_ops = mm_camera_unmap_stream_buf_ops;
+    my_obj->map_ops.userdata = my_obj;
+    return rc;
 }
 
-/*===========================================================================
- * FUNCTION   : mm_stream_bundled_map_buf_ops
- *
- * DESCRIPTION: ops for mapping bundled stream buffers via domain socket to server.
- *              This function will be passed to upper layer as part of ops table
- *              to be used by upper layer when allocating stream buffers and mapping
- *              buffers to server via domain socket.
- *
- * PARAMETERS :
- *   @buf_map_list : list of buffer mapping information
- *   @userdata     : user data ptr (stream object)
- *
- * RETURN     : int32_t type of status
- *              0  -- success
- *              -1 -- failure
- *==========================================================================*/
-static int32_t mm_stream_bundled_map_buf_ops(
-        const cam_buf_map_type_list *buf_map_list,
-        void *userdata)
+int32_t mm_stream_deinit(mm_stream_t *my_obj)
 {
-    mm_stream_t *my_obj = (mm_stream_t *)userdata;
-    return mm_stream_map_bufs(my_obj,
-                              buf_map_list);
-}
-
-/*===========================================================================
- * FUNCTION   : mm_stream_unmap_buf_ops
- *
- * DESCRIPTION: ops for unmapping stream buffer via domain socket to server.
- *              This function will be passed to upper layer as part of ops table
- *              to be used by upper layer when allocating stream buffers and unmapping
- *              buffers to server via domain socket.
- *
- * PARAMETERS :
- *   @frame_idx    : index of buffer within the stream buffers, only valid if
- *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
- *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
- *   @plane_idx    : plane index. If all planes share the same fd,
- *                   plane_idx = -1; otherwise, plean_idx is the
- *                   index to plane (0..num_of_planes)
- *   @userdata     : user data ptr (stream object)
- *
- * RETURN     : int32_t type of status
- *              0  -- success
- *              -1 -- failure
- *==========================================================================*/
-static int32_t mm_stream_unmap_buf_ops(uint32_t frame_idx,
-                                       int32_t plane_idx,
-                                       cam_mapping_buf_type type,
-                                       void *userdata)
-{
-    mm_stream_t *my_obj = (mm_stream_t *)userdata;
-    return mm_stream_unmap_buf(my_obj,
-                               type,
-                               frame_idx,
-                               plane_idx);
+    int32_t rc = 0;
+    /* destroy mutex */
+    mm_muxer_frame_sync_queue_deinit(&my_obj->frame_sync.superbuf_queue);
+    pthread_mutex_destroy(&my_obj->frame_sync.sync_lock);
+    pthread_cond_destroy(&my_obj->buf_cond);
+    pthread_mutex_destroy(&my_obj->buf_lock);
+    pthread_mutex_destroy(&my_obj->cb_lock);
+    pthread_mutex_destroy(&my_obj->cmd_lock);
+    return rc;
 }
 
 /*===========================================================================
@@ -1045,7 +1048,13 @@
     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
           my_obj->my_hdl, my_obj->fd, my_obj->state);
     my_obj->stream_info = config->stream_info;
-    my_obj->buf_num = (uint8_t) config->stream_info->num_bufs;
+
+    if (config->stream_info->buf_cnt == 0) {
+        my_obj->buf_num = (uint8_t)config->stream_info->num_bufs;
+    } else {
+        my_obj->buf_num = (uint8_t)config->stream_info->buf_cnt;
+    }
+    my_obj->total_buf_cnt = config->stream_info->num_bufs;
     my_obj->mem_vtbl = config->mem_vtbl;
     my_obj->padding_info = config->padding_info;
 
@@ -1062,21 +1071,25 @@
     my_obj->buf_cb[cb_index].cb_count = -1; /* infinite by default */
     my_obj->buf_cb[cb_index].cb_type = MM_CAMERA_STREAM_CB_TYPE_ASYNC;
 
+    if ((my_obj->frame_sync.superbuf_queue.num_objs != 0)
+            && (my_obj->frame_sync.super_buf_notify_cb == NULL)) {
+        my_obj->frame_sync.super_buf_notify_cb = config->stream_cb;
+    }
+    if ((my_obj->frame_sync.superbuf_queue.num_objs != 0)
+            && (my_obj->frame_sync.user_data == NULL)) {
+        my_obj->frame_sync.user_data = config->userdata;
+    }
+
     rc = mm_stream_sync_info(my_obj);
     if (rc == 0) {
         rc = mm_stream_set_fmt(my_obj);
         if (rc < 0) {
-            LOGE("mm_stream_set_fmt failed %d",
-                     rc);
+            LOGE("mm_stream_set_fmt failed %d", rc);
         }
     }
 
-    my_obj->map_ops.map_ops = mm_stream_map_buf_ops;
-    my_obj->map_ops.bundled_map_ops = mm_stream_bundled_map_buf_ops;
-    my_obj->map_ops.unmap_ops = mm_stream_unmap_buf_ops;
-    my_obj->map_ops.userdata = my_obj;
-
-    if(my_obj->mem_vtbl.set_config_ops != NULL) {
+    if((my_obj->mem_vtbl.set_config_ops != NULL)
+            && (!my_obj->is_res_shared)) {
         my_obj->mem_vtbl.set_config_ops(&my_obj->map_ops,
                 my_obj->mem_vtbl.user_data);
     }
@@ -1084,6 +1097,133 @@
 }
 
 /*===========================================================================
+ * FUNCTION   : mm_stream_reg_frame_sync
+ *
+ * DESCRIPTION: reg stream frame sync
+ *
+ * PARAMETERS :
+ *   @str_obj      : stream object
+ *   @sync  : sync attribute
+ *
+ * RETURN     : uint32_t type of stream handle
+ *              0  -- invalid stream handle, meaning the op failed
+ *              >0 -- successfully added a stream with a valid handle
+ *==========================================================================*/
+int32_t mm_stream_reg_frame_sync(mm_stream_t *str_obj, mm_evt_paylod_reg_frame_sync *sync)
+{
+    int32_t rc = 0;
+    mm_stream_t *my_obj = str_obj;
+
+    if (NULL == sync || sync->a_str_obj == NULL) {
+        LOGE("Invalid stream link");
+        return -1;
+    }
+
+    if (str_obj->master_str_obj != NULL) {
+        my_obj = str_obj->master_str_obj;
+    }
+
+    mm_frame_sync_t *frame_sync = &my_obj->frame_sync;
+    pthread_mutex_lock(&frame_sync->sync_lock);
+    mm_frame_sync_queue_t *queue = NULL;
+
+    frame_sync->super_buf_notify_cb = sync->sync_attr->buf_cb;
+    frame_sync->user_data = sync->sync_attr->userdata;
+    queue = &frame_sync->superbuf_queue;
+    queue->num_objs = 0;
+    memset(&queue->bundled_objs, 0, sizeof(queue->bundled_objs));
+    queue->bundled_objs[queue->num_objs] = my_obj->my_hdl;
+    queue->num_objs++;
+    queue->bundled_objs[queue->num_objs] = sync->a_str_obj->my_hdl;
+    queue->num_objs++;
+    queue->expected_frame_id = 0;
+    queue->max_unmatched_frames = sync->sync_attr->max_unmatched_frames;
+    queue->priority = sync->sync_attr->priority;
+
+    sync->a_str_obj->is_res_shared = sync->sync_attr->is_res_shared;
+    my_obj->aux_str_obj[my_obj->num_s_cnt++] = sync->a_str_obj;
+    sync->a_str_obj->master_str_obj = my_obj;
+    pthread_mutex_unlock(&frame_sync->sync_lock);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_stream_trigger_frame_sync
+ *
+ * DESCRIPTION: start/stop stream frame sync
+ *
+ * PARAMETERS :
+ *   @my_obj  : stream object
+ *   @start_sync  : flag to start/stop frame sync.
+ *
+ * RETURN     : uint32_t type of stream handle
+ *              0  -- invalid stream handle, meaning the op failed
+ *              >0 -- successfully added a stream with a valid handle
+ *==========================================================================*/
+int32_t mm_stream_trigger_frame_sync(mm_stream_t *my_obj, uint8_t start_sync)
+{
+    int32_t rc = 0;
+    mm_stream_t *m_obj = my_obj;
+    mm_frame_sync_t *frame_sync = NULL;
+
+    if (m_obj->master_str_obj != NULL) {
+        m_obj = m_obj->master_str_obj;
+    }
+    frame_sync = &m_obj->frame_sync;
+    pthread_mutex_lock(&frame_sync->sync_lock);
+    if (start_sync == 0 && frame_sync->is_active) {
+        mm_camera_muxer_stream_frame_sync_flush(m_obj);
+    }
+    frame_sync->is_active = start_sync;
+    pthread_mutex_unlock(&frame_sync->sync_lock);
+    return rc;
+}
+
+/*===========================================================================
+ * FUNCTION   : mm_stream_switch_stream_callback
+ *
+ * DESCRIPTION: switch stream callbacks
+ *
+ * PARAMETERS :
+ *   @my_obj  : stream object
+ *
+ * RETURN     : uint32_t type of stream handle
+ *              0  -- invalid stream handle, meaning the op failed
+ *              >0 -- successfully added a stream with a valid handle
+ *==========================================================================*/
+int32_t mm_stream_switch_stream_callback(mm_stream_t *my_obj)
+{
+    int32_t rc = 0;
+    mm_stream_t *m_obj = my_obj;
+    mm_stream_t *s_obj = NULL;
+
+    if (my_obj->master_str_obj != NULL) {
+        m_obj = my_obj->master_str_obj;
+    }
+    if (m_obj->num_s_cnt == 0) {
+        LOGE("No slave stream to switch");
+        return -1;
+    }
+    s_obj = m_obj->aux_str_obj[0];
+
+    pthread_mutex_lock(&m_obj->frame_sync.sync_lock);
+    if (m_obj->frame_sync.is_active) {
+        mm_camera_muxer_stream_frame_sync_flush(m_obj);
+    }
+    m_obj->frame_sync.is_active = 0;
+    pthread_mutex_lock(&m_obj->cb_lock);
+    m_obj->is_cb_active = !m_obj->is_cb_active;
+    pthread_mutex_unlock(&m_obj->cb_lock);
+
+    pthread_mutex_lock(&s_obj->cb_lock);
+    s_obj->is_cb_active = !s_obj->is_cb_active;
+    pthread_mutex_unlock(&s_obj->cb_lock);
+
+    pthread_mutex_unlock(&m_obj->frame_sync.sync_lock);
+    return rc;
+}
+
+/*===========================================================================
  * FUNCTION   : mm_stream_release
  *
  * DESCRIPTION: release a stream resource
@@ -1127,11 +1267,13 @@
         close(my_obj->fd);
     }
 
-    /* destroy mutex */
-    pthread_cond_destroy(&my_obj->buf_cond);
-    pthread_mutex_destroy(&my_obj->buf_lock);
-    pthread_mutex_destroy(&my_obj->cb_lock);
-    pthread_mutex_destroy(&my_obj->cmd_lock);
+    if (my_obj->master_str_obj != NULL) {
+        //Assuming order of stream release is maintained
+        my_obj->master_str_obj->num_s_cnt--;
+        my_obj->master_str_obj->aux_str_obj[
+                my_obj->master_str_obj->num_s_cnt] = NULL;
+    }
+    mm_stream_deinit(my_obj);
 
     /* reset stream obj */
     memset(my_obj, 0, sizeof(mm_stream_t));
@@ -1157,12 +1299,14 @@
     int32_t rc = 0;
     int8_t i;
     enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    uint8_t idx = mm_camera_util_get_index_by_num(
+            my_obj->ch_obj->cam_obj->my_num, my_obj->my_hdl);
 
     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
           my_obj->my_hdl, my_obj->fd, my_obj->state);
 
     pthread_mutex_lock(&my_obj->buf_lock);
-    for (i = 0; i < my_obj->buf_num; i++) {
+    for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
         if ((my_obj->buf_status[i].map_status == 0) &&
                 (my_obj->buf_status[i].in_kernel)) {
             LOGD("waiting for mapping to done: strm fd = %d",
@@ -1187,7 +1331,7 @@
     if (rc < 0) {
         /* remove fd from data poll thread in case of failure */
         mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
-                my_obj->my_hdl, mm_camera_sync_call);
+                idx, my_obj->my_hdl, mm_camera_sync_call);
         return rc;
     }
     mm_camera_obj_t *cam_obj = my_obj->ch_obj->cam_obj;
@@ -1225,7 +1369,7 @@
 error_case:
      /* remove fd from data poll thread in case of failure */
      mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
-             my_obj->my_hdl, mm_camera_sync_call);
+             idx, my_obj->my_hdl, mm_camera_sync_call);
 
     LOGD("X rc = %d",rc);
     return rc;
@@ -1250,9 +1394,11 @@
     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
           my_obj->my_hdl, my_obj->fd, my_obj->state);
 
+    uint8_t idx = mm_camera_util_get_index_by_num(
+            my_obj->ch_obj->cam_obj->my_num, my_obj->my_hdl);
     /* step1: remove fd from data poll thread */
     rc = mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
-            my_obj->my_hdl, mm_camera_sync_call);
+            idx, my_obj->my_hdl, mm_camera_sync_call);
     if (rc < 0) {
         /* The error might be due to async update. In this case
          * wait for all updates to complete before proceeding. */
@@ -1340,7 +1486,8 @@
     }
 
     if ((my_obj->cur_buf_idx < 0)
-            || (my_obj->cur_buf_idx >= my_obj->buf_num)) {
+            || (my_obj->cur_buf_idx >=
+            (my_obj->buf_idx + my_obj->buf_num))) {
         for (i = 0; i < my_obj->buf_num; i++) {
             if ((my_obj->buf_status[i].in_kernel)
                     || (my_obj->buf[i].user_buf.buf_in_use)) {
@@ -1526,12 +1673,12 @@
         pthread_mutex_lock(&my_obj->buf_lock);
         my_obj->queued_buffer_count--;
         if (0 == my_obj->queued_buffer_count) {
-            LOGH("Stoping poll on stream %p type: %d",
-                my_obj, my_obj->stream_info->stream_type);
+            uint8_t idx = mm_camera_util_get_index_by_num(
+                    my_obj->ch_obj->cam_obj->my_num, my_obj->my_hdl);
+            LOGH("Remove Poll stream %p type: %d FD = %d",
+                    my_obj, my_obj->stream_info->stream_type, my_obj->fd);
             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
-                my_obj->my_hdl, mm_camera_async_call);
-            LOGH("Stopped poll on stream %p type: %d",
-                my_obj, my_obj->stream_info->stream_type);
+                    idx, my_obj->my_hdl, mm_camera_async_call);
         }
         pthread_mutex_unlock(&my_obj->buf_lock);
         uint32_t idx = vb.index;
@@ -1548,10 +1695,11 @@
 
         LOGH("VIDIOC_DQBUF buf_index %d, frame_idx %d, stream type %d, rc %d,"
                 "queued: %d, buf_type = %d flags = %d",
-             vb.index, buf_info->buf->frame_idx,
-            my_obj->stream_info->stream_type, rc,
-            my_obj->queued_buffer_count, buf_info->buf->buf_type,
-            buf_info->buf->flags);
+                vb.index, buf_info->buf->frame_idx,
+                my_obj->stream_info->stream_type, rc,
+                my_obj->queued_buffer_count, buf_info->buf->buf_type,
+                buf_info->buf->flags,
+                my_obj->fd);
 
         buf_info->buf->is_uv_subsampled =
             (vb.reserved == V4L2_PIX_FMT_NV14 || vb.reserved == V4L2_PIX_FMT_NV41);
@@ -1697,7 +1845,6 @@
     rc = ioctl(my_obj->fd, VIDIOC_S_PARM, &s_parm);
     LOGD("stream fd=%d, rc=%d, extended_mode=%d",
          my_obj->fd, rc, s_parm.parm.capture.extendedmode);
-
     if (rc == 0) {
         my_obj->server_stream_id = s_parm.parm.capture.extendedmode;
 #ifndef DAEMON_PRESENT
@@ -1777,12 +1924,15 @@
     pthread_mutex_lock(&my_obj->buf_lock);
     my_obj->queued_buffer_count++;
     if (1 == my_obj->queued_buffer_count) {
+        uint8_t idx = mm_camera_util_get_index_by_num(
+                my_obj->ch_obj->cam_obj->my_num, my_obj->my_hdl);
         /* Add fd to data poll thread */
-        LOGH("Starting poll on stream %p type: %d",
-            my_obj,my_obj->stream_info->stream_type);
+        LOGH("Add Poll FD %p type: %d idx = %d num = %d fd = %d",
+                my_obj,my_obj->stream_info->stream_type, idx,
+                my_obj->ch_obj->cam_obj->my_num, my_obj->fd);
         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->ch_obj->poll_thread[0],
-            my_obj->my_hdl, my_obj->fd, mm_stream_data_notify, (void*)my_obj,
-            mm_camera_async_call);
+                idx, my_obj->my_hdl, my_obj->fd, mm_stream_data_notify,
+                (void*)my_obj, mm_camera_async_call);
         if (0 > rc) {
             LOGE("Add poll on stream %p type: %d fd error (rc=%d)",
                  my_obj, my_obj->stream_info->stream_type, rc);
@@ -1800,20 +1950,22 @@
              my_obj->stream_info->stream_type, rc, strerror(errno));
         my_obj->queued_buffer_count--;
         if (0 == my_obj->queued_buffer_count) {
+            uint8_t idx = mm_camera_util_get_index_by_num(
+                    my_obj->ch_obj->cam_obj->my_num, my_obj->my_hdl);
             /* Remove fd from data poll in case of failing
              * first buffer queuing attempt */
             LOGH("Stoping poll on stream %p type: %d",
                 my_obj, my_obj->stream_info->stream_type);
             mm_camera_poll_thread_del_poll_fd(&my_obj->ch_obj->poll_thread[0],
-                my_obj->my_hdl, mm_camera_async_call);
+                    idx, my_obj->my_hdl, mm_camera_async_call);
             LOGH("Stopped poll on stream %p type: %d",
                 my_obj, my_obj->stream_info->stream_type);
         }
     } else {
         LOGH("VIDIOC_QBUF buf_index %d, frame_idx %d stream type %d, rc %d,"
-                " queued: %d, buf_type = %d",
-                 buffer.index, buf->frame_idx, my_obj->stream_info->stream_type, rc,
-                my_obj->queued_buffer_count, buf->buf_type);
+                " queued: %d, buf_type = %d stream-FD = %d",
+                buffer.index, buf->frame_idx, my_obj->stream_info->stream_type, rc,
+                my_obj->queued_buffer_count, buf->buf_type, my_obj->fd);
     }
     pthread_mutex_unlock(&my_obj->buf_lock);
 
@@ -1837,13 +1989,10 @@
 {
     int32_t rc = 0;
     struct v4l2_requestbuffers bufreq;
-    uint8_t buf_num = my_obj->buf_num;
+    uint8_t buf_num = my_obj->total_buf_cnt;
     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
           my_obj->my_hdl, my_obj->fd, my_obj->state);
 
-    LOGD("buf_num = %d, stream type = %d",
-          buf_num, my_obj->stream_info->stream_type);
-
     if(buf_num > MM_CAMERA_MAX_NUM_FRAMES) {
         LOGE("buf num %d > max limit %d\n",
                     buf_num, MM_CAMERA_MAX_NUM_FRAMES);
@@ -1881,7 +2030,7 @@
     uint32_t i;
     int8_t ret = 0;
 
-    for (i = 0; i < my_obj->buf_num; i++) {
+    for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
         if ((my_obj->buf_status[i].map_status == 0)
                 && (my_obj->buf_status[i].in_kernel)) {
             /*do not signal in case if any buffer is not mapped
@@ -1919,7 +2068,7 @@
  *              0  -- success
  *              -1 -- failure
  *==========================================================================*/
-int32_t mm_stream_map_buf(mm_stream_t * my_obj,
+int32_t mm_stream_map_buf(mm_stream_t *my_obj,
         uint8_t buf_type, uint32_t frame_idx,
         int32_t plane_idx, int32_t fd,
         size_t size, void *buffer)
@@ -2140,20 +2289,26 @@
         mm_stream_deinit_bufs(my_obj);
     }
 
-    rc = my_obj->mem_vtbl.get_bufs(&my_obj->frame_offset,
-                                   &my_obj->buf_num,
-                                   &reg_flags,
-                                   &my_obj->buf,
-                                   &my_obj->map_ops,
-                                   my_obj->mem_vtbl.user_data);
+    if (!my_obj->is_res_shared) {
+        rc = my_obj->mem_vtbl.get_bufs(&my_obj->frame_offset,
+                &my_obj->total_buf_cnt, &reg_flags, &my_obj->buf,
+                &my_obj->map_ops, my_obj->mem_vtbl.user_data);
+        if (rc == 0) {
+            for (i = 0; i < my_obj->total_buf_cnt; i++) {
+                my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
+            }
+        }
+    } else {
+        rc = mm_camera_muxer_get_stream_bufs(my_obj);
+    }
 
     if (0 != rc) {
         LOGE("Error get buf, rc = %d\n", rc);
         return rc;
     }
 
-    for (i = 0; i < my_obj->buf_num; i++) {
-        my_obj->buf_status[i].initial_reg_flag = reg_flags[i];
+    LOGH("Buffer count = %d buf id = %d",my_obj->buf_num, my_obj->buf_idx);
+    for (i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++) {
         my_obj->buf[i].stream_id = my_obj->my_hdl;
         my_obj->buf[i].stream_type = my_obj->stream_info->stream_type;
 
@@ -2183,7 +2338,7 @@
     reg_flags = NULL;
 
     /* update in stream info about number of stream buffers */
-    my_obj->stream_info->num_bufs = my_obj->buf_num;
+    my_obj->stream_info->num_bufs = my_obj->total_buf_cnt;
 
     return rc;
 }
@@ -2204,8 +2359,6 @@
 int32_t mm_stream_deinit_bufs(mm_stream_t * my_obj)
 {
     int32_t rc = 0;
-
-    mm_camera_map_unmap_ops_tbl_t ops_tbl;
     LOGD("E, my_handle = 0x%x, fd = %d, state = %d",
           my_obj->my_hdl, my_obj->fd, my_obj->state);
 
@@ -2214,23 +2367,21 @@
         return rc;
     }
 
-    /* release bufs */
-    ops_tbl.map_ops = mm_stream_map_buf_ops;
-    ops_tbl.bundled_map_ops = mm_stream_bundled_map_buf_ops;
-    ops_tbl.unmap_ops = mm_stream_unmap_buf_ops;
-    ops_tbl.userdata = my_obj;
+    if ((!my_obj->is_res_shared) &&
+            (my_obj->mem_vtbl.put_bufs != NULL)) {
+        rc = my_obj->mem_vtbl.put_bufs(&my_obj->map_ops,
+                my_obj->mem_vtbl.user_data);
+        if (my_obj->plane_buf != NULL) {
+            free(my_obj->plane_buf);
+            my_obj->plane_buf = NULL;
+        }
 
-    rc = my_obj->mem_vtbl.put_bufs(&ops_tbl,
-                                   my_obj->mem_vtbl.user_data);
-
-    if (my_obj->plane_buf != NULL) {
-        free(my_obj->plane_buf);
-        my_obj->plane_buf = NULL;
+        free(my_obj->buf);
+        my_obj->buf = NULL;
+    } else {
+        rc = mm_camera_muxer_put_stream_bufs(my_obj);
     }
 
-    free(my_obj->buf);
-    my_obj->buf = NULL;
-
     return rc;
 }
 
@@ -2260,7 +2411,7 @@
     }
 
     my_obj->queued_buffer_count = 0;
-    for(i = 0; i < my_obj->buf_num; i++){
+    for(i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++){
         /* check if need to qbuf initially */
         if (my_obj->buf_status[i].initial_reg_flag) {
             rc = mm_stream_qbuf(my_obj, &my_obj->buf[i]);
@@ -2312,7 +2463,7 @@
 
     /* reset buf reference count */
     pthread_mutex_lock(&my_obj->buf_lock);
-    for(i = 0; i < my_obj->buf_num; i++){
+    for(i = my_obj->buf_idx; i < (my_obj->buf_idx + my_obj->buf_num); i++){
         my_obj->buf_status[i].buf_refcnt = 0;
         my_obj->buf_status[i].in_kernel = 0;
     }
diff --git a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c
index 0c740b4..a49fab1 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-interface/src/mm_camera_thread.c
@@ -396,6 +396,7 @@
  *
  * PARAMETERS :
  *   @poll_cb   : ptr to poll thread object
+ *   @idx       : Object index.
  *   @handler   : stream handle if channel data polling thread,
  *                0 if event polling thread
  *   @fd        : file descriptor need to be added into polling thread
@@ -406,22 +407,10 @@
  * RETURN     : none
  *==========================================================================*/
 int32_t mm_camera_poll_thread_add_poll_fd(mm_camera_poll_thread_t * poll_cb,
-                                          uint32_t handler,
-                                          int32_t fd,
-                                          mm_camera_poll_notify_t notify_cb,
-                                          void* userdata,
-                                          mm_camera_call_type_t call_type)
+        uint8_t idx, uint32_t handler, int32_t fd, mm_camera_poll_notify_t notify_cb,
+        void* userdata, mm_camera_call_type_t call_type)
 {
     int32_t rc = -1;
-    uint8_t idx = 0;
-
-    if (MM_CAMERA_POLL_TYPE_DATA == poll_cb->poll_type) {
-        /* get stream idx from handler if CH type */
-        idx = mm_camera_util_get_index_by_handler(handler);
-    } else {
-        /* for EVT type, only idx=0 is valid */
-        idx = 0;
-    }
 
     if (MAX_STREAM_NUM_IN_BUNDLE > idx) {
         poll_cb->poll_entries[idx].fd = fd;
@@ -447,6 +436,7 @@
  *
  * PARAMETERS :
  *   @poll_cb   : ptr to poll thread object
+ *   @idx       : Object index.
  *   @handler   : stream handle if channel data polling thread,
  *                0 if event polling thread
  *
@@ -455,19 +445,9 @@
  *              -1 -- failure
  *==========================================================================*/
 int32_t mm_camera_poll_thread_del_poll_fd(mm_camera_poll_thread_t * poll_cb,
-                                          uint32_t handler,
-                                          mm_camera_call_type_t call_type)
+        uint8_t idx, uint32_t handler, mm_camera_call_type_t call_type)
 {
     int32_t rc = -1;
-    uint8_t idx = 0;
-
-    if (MM_CAMERA_POLL_TYPE_DATA == poll_cb->poll_type) {
-        /* get stream idx from handler if CH type */
-        idx = mm_camera_util_get_index_by_handler(handler);
-    } else {
-        /* for EVT type, only idx=0 is valid */
-        idx = 0;
-    }
 
     if ((MAX_STREAM_NUM_IN_BUNDLE > idx) &&
         (handler == poll_cb->poll_entries[idx].handler)) {
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
index 8ddad3e..3a3f057 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_app.c
@@ -2152,7 +2152,6 @@
             }
 
             mm_camera_app_wait();
-
             rc = mm_app_stop_capture_raw(&handle->test_obj);
             if (rc != MM_CAMERA_OK) {
                 LOGE("mm_app_stop_capture() err=%d\n",
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c
index 56c0437..29ae5a9 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_main_menu.c
@@ -1944,7 +1944,6 @@
 
             case ACTION_TAKE_RAW_SNAPSHOT:
                 LOGH("\n Take RAW snapshot\n");
-
                 rc = mm_camera_lib_send_command(&lib_handle,
                                                 MM_CAMERA_LIB_DO_AF,
                                                 NULL,
@@ -1954,7 +1953,6 @@
                     LOGE("mm_camera_lib_send_command() err=%d\n",  rc);
                     goto ERROR;
                 }
-
                 rc = mm_camera_lib_send_command(&lib_handle,
                                                 MM_CAMERA_LIB_RAW_CAPTURE,
                                                 NULL,
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
index 4f27719..9703650 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_preview.c
@@ -546,6 +546,7 @@
     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
     stream->s_config.stream_info->dim.width = sizeof(metadata_buffer_t);
     stream->s_config.stream_info->dim.height = 1;
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
@@ -643,6 +644,7 @@
     stream->s_config.stream_info->dim = analysis_dim;
     stream->s_config.padding_info =
         cam_cap->analysis_info[CAM_ANALYSIS_INFO_FD_STILL].analysis_padding_info;
+    stream->s_config.stream_info->num_bufs = num_bufs;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
     if (MM_CAMERA_OK != rc) {
@@ -708,7 +710,7 @@
 
     stream->s_config.stream_info->dim.width = preview_dim.width;
     stream->s_config.stream_info->dim.height = preview_dim.height;
-
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
@@ -810,7 +812,7 @@
 
     stream->s_config.stream_info->dim.width = preview_dim.width;
     stream->s_config.stream_info->dim.height = preview_dim.height;
-
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
@@ -889,6 +891,7 @@
         stream->s_config.stream_info->dim.width = (int32_t)test_obj->buffer_width;
         stream->s_config.stream_info->dim.height = (int32_t)test_obj->buffer_height;
     }
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
@@ -972,6 +975,7 @@
         stream->s_config.stream_info->dim.width = test_obj->buffer_width;
         stream->s_config.stream_info->dim.height = test_obj->buffer_height;
     }
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
     /* Make offset as zero as CPP will not be used  */
     stream->s_config.padding_info.offset_info.offset_x = 0;
@@ -1059,6 +1063,7 @@
         stream->s_config.stream_info->dim.width = test_obj->buffer_width;
         stream->s_config.stream_info->dim.height = test_obj->buffer_height;
     }
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
     /* Make offset as zero as CPP will not be used  */
     stream->s_config.padding_info.offset_info.offset_x = 0;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c
index 4c07f6a..c68424b 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_rdi.c
@@ -166,6 +166,7 @@
         stream->s_config.stream_info->num_of_burst = num_burst;
     }
     stream->s_config.stream_info->fmt = DEFAULT_RAW_FORMAT;
+    stream->s_config.stream_info->num_bufs = num_bufs;
     LOGD(" RAW: w: %d, h: %d ",
        cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
 
@@ -225,6 +226,7 @@
         stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
         stream->s_config.stream_info->num_of_burst = num_burst;
     }
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
     stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
     stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_reprocess.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_reprocess.c
index 4ed4c5d..6bb7ec6 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_reprocess.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_reprocess.c
@@ -151,7 +151,7 @@
     stream->s_config.stream_info->fmt = source_stream_info->fmt;
     stream->s_config.stream_info->dim = source_stream_info->dim;
     stream->s_config.padding_info = cam_cap->padding_info;
-
+    stream->s_config.stream_info->num_bufs = num_bufs;
 
     stream->s_config.stream_info->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
     stream->s_config.stream_info->reprocess_config.online.input_stream_id = source->s_config.stream_info->stream_svr_id;
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
index 69c09d0..a3bc9f6 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_snapshot.c
@@ -513,6 +513,7 @@
     stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
     stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
     stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
diff --git a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
index 1792c27..dd0b139 100644
--- a/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
+++ b/msmcobalt/QCamera2/stack/mm-camera-test/src/mm_qcamera_video.c
@@ -377,7 +377,7 @@
 
     stream->s_config.stream_info->dim.width = preview_dim.width;
     stream->s_config.stream_info->dim.height = preview_dim.height;
-
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
@@ -439,7 +439,7 @@
     /* Make offset as zero as CPP will not be used  */
     stream->s_config.padding_info.offset_info.offset_x = 0;
     stream->s_config.padding_info.offset_info.offset_y = 0;
-
+    stream->s_config.stream_info->num_bufs = num_bufs;
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
     if (MM_CAMERA_OK != rc) {
         LOGE("config preview stream err=%d\n",  rc);
@@ -518,6 +518,7 @@
     stream->s_config.stream_info->fmt = DEFAULT_VIDEO_FORMAT;
     stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
     stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
+    stream->s_config.stream_info->num_bufs = num_bufs;
     stream->s_config.padding_info = cam_cap->padding_info;
 
     rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);