merge in mnc-dr-release history after reset to mnc-dr-dev
diff --git a/QCamera2/HAL3/QCamera3Channel.cpp b/QCamera2/HAL3/QCamera3Channel.cpp
index c2b8fc7..999bdb1 100644
--- a/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/QCamera2/HAL3/QCamera3Channel.cpp
@@ -4363,7 +4363,7 @@
 QCamera3StreamMem* QCamera3SupportChannel::getStreamBufs(uint32_t len)
 {
     int rc;
-    mMemory = new QCamera3StreamMem(MIN_STREAMING_BUFFER_NUM);
+    mMemory = new QCamera3StreamMem(mNumBuffers);
     if (!mMemory) {
         ALOGE("%s: unable to create heap memory", __func__);
         return NULL;
diff --git a/QCamera2/HAL3/QCamera3HWI.cpp b/QCamera2/HAL3/QCamera3HWI.cpp
index e8f6af4..7e612b2 100755
--- a/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/QCamera2/HAL3/QCamera3HWI.cpp
@@ -3962,6 +3962,18 @@
           blackLevelAppliedPattern->cam_black_level[2],
           blackLevelAppliedPattern->cam_black_level[3]);
         camMetadata.update(QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN, fwk_blackLevelInd, 4);
+        camMetadata.update(NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL, fwk_blackLevelInd, 4);
+    }
+
+
+    if (gCamCapability[mCameraId]->optical_black_region_count != 0 &&
+        gCamCapability[mCameraId]->optical_black_region_count <= MAX_OPTICAL_BLACK_REGIONS) {
+        int32_t opticalBlackRegions[MAX_OPTICAL_BLACK_REGIONS * 4];
+        for (size_t i = 0; i < gCamCapability[mCameraId]->optical_black_region_count * 4; i++) {
+            opticalBlackRegions[i] = gCamCapability[mCameraId]->optical_black_regions[i];
+        }
+        camMetadata.update(NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
+                opticalBlackRegions, gCamCapability[mCameraId]->optical_black_region_count * 4);
     }
 
     IF_META_AVAILABLE(cam_crop_region_t, hScalerCropRegion,
@@ -4379,11 +4391,7 @@
     // Reprocess crop data
     IF_META_AVAILABLE(cam_crop_data_t, crop_data, CAM_INTF_META_CROP_DATA, metadata) {
         uint8_t cnt = crop_data->num_of_streams;
-        if (pprocDone) {
-            // HAL already does internal reprocessing, either via reprocessing before
-            // JPEG encoding, or offline postprocessing for pproc bypass case.
-            CDBG("%s: Internal offline postprocessing was done, no need for further crop", __func__);
-        } else if ( (0 >= cnt) || (cnt > MAX_NUM_STREAMS)) {
+        if ( (0 >= cnt) || (cnt > MAX_NUM_STREAMS)) {
             // mm-qcamera-daemon only posts crop_data for streams
             // not linked to pproc. So no valid crop metadata is not
             // necessarily an error case.
@@ -4403,10 +4411,20 @@
                     int32_t streams_found = 0;
                     for (size_t i = 0; i < cnt; i++) {
                         if (crop_data->crop_info[i].stream_id == reproc_stream_id) {
-                            crop[0] = crop_data->crop_info[i].crop.left;
-                            crop[1] = crop_data->crop_info[i].crop.top;
-                            crop[2] = crop_data->crop_info[i].crop.width;
-                            crop[3] = crop_data->crop_info[i].crop.height;
+                            if (pprocDone) {
+                                // HAL already does internal reprocessing,
+                                // either via reprocessing before JPEG encoding,
+                                // or offline postprocessing for pproc bypass case.
+                                crop[0] = 0;
+                                crop[1] = 0;
+                                crop[2] = mInputStreamInfo.dim.width;
+                                crop[3] = mInputStreamInfo.dim.height;
+                            } else {
+                                crop[0] = crop_data->crop_info[i].crop.left;
+                                crop[1] = crop_data->crop_info[i].crop.top;
+                                crop[2] = crop_data->crop_info[i].crop.width;
+                                crop[3] = crop_data->crop_info[i].crop.height;
+                            }
                             roi_map.add(crop_data->crop_info[i].roi_map.left);
                             roi_map.add(crop_data->crop_info[i].roi_map.top);
                             roi_map.add(crop_data->crop_info[i].roi_map.width);
@@ -4414,10 +4432,7 @@
                             streams_found++;
                             CDBG("%s: Adding reprocess crop data for stream %dx%d, %dx%d",
                                     __func__,
-                                    crop_data->crop_info[i].crop.left,
-                                    crop_data->crop_info[i].crop.top,
-                                    crop_data->crop_info[i].crop.width,
-                                    crop_data->crop_info[i].crop.height);
+                                    crop[0], crop[1], crop[2], crop[3]);
                             CDBG("%s: Adding reprocess crop roi map for stream %dx%d, %dx%d",
                                     __func__,
                                     crop_data->crop_info[i].roi_map.left,
diff --git a/QCamera2/HAL3/QCamera3VendorTags.cpp b/QCamera2/HAL3/QCamera3VendorTags.cpp
index fbc84c4..91a7fcd 100644
--- a/QCamera2/HAL3/QCamera3VendorTags.cpp
+++ b/QCamera2/HAL3/QCamera3VendorTags.cpp
@@ -51,7 +51,8 @@
         QCAMERA3_TUNING_META_DATA_END,
         QCAMERA3_AV_TIMER_END,
         QCAMERA3_SENSOR_META_DATA_END,
-        QCAMERA3_TEMPORAL_DENOISE_END
+        QCAMERA3_TEMPORAL_DENOISE_END,
+        NEXUS_EXPERIMENTAL_2015_END,
 } ;
 
 typedef struct vendor_tag_info {
@@ -68,7 +69,8 @@
     "org.codeaurora.qcamera3.tuning_meta_data",
     "org.codeaurora.qcamera3.av_timer",
     "org.codeaurora.qcamera3.sensor_meta_data",
-    "org.codeaurora.qcamera3.temporal_denoise"
+    "org.codeaurora.qcamera3.temporal_denoise",
+    "com.google.nexus.experimental2015"
 };
 
 vendor_tag_info_t qcamera3_privatedata[QCAMERA3_PRIVATEDATA_END - QCAMERA3_PRIVATEDATA_START] = {
@@ -113,6 +115,12 @@
     { "process_type", TYPE_INT32 }
 };
 
+vendor_tag_info_t nexus_experimental_2015[NEXUS_EXPERIMENTAL_2015_END -
+        NEXUS_EXPERIMENTAL_2015_START] = {
+    {"sensor.dynamicBlackLevel", TYPE_FLOAT },
+    {"sensor.info.opticallyShieldedRegions", TYPE_INT32 }
+};
+
 vendor_tag_info_t *qcamera3_tag_info[QCAMERA3_SECTIONS_END -
         VENDOR_SECTION] = {
     qcamera3_privatedata,
@@ -122,7 +130,8 @@
     qcamera3_tuning_meta_data,
     qcamera3_av_timer,
     qcamera3_sensor_meta_data,
-    qcamera3_temporal_denoise
+    qcamera3_temporal_denoise,
+    nexus_experimental_2015,
 };
 
 uint32_t qcamera3_all_tags[] = {
@@ -150,9 +159,14 @@
 
     //QCAMERA3_SENSOR_META_DATA
     (uint32_t)QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN,
+
     // QCAMERA3_TEMPORAL_DENOISE
     (uint32_t)QCAMERA3_TEMPORAL_DENOISE_ENABLE,
-    (uint32_t)QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE
+    (uint32_t)QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE,
+
+    //NEXUS_EXPERIMENTAL_2015
+    (uint32_t)NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL,
+    (uint32_t)NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
 };
 
 const vendor_tag_ops_t* QCamera3VendorTags::Ops = NULL;
diff --git a/QCamera2/HAL3/QCamera3VendorTags.h b/QCamera2/HAL3/QCamera3VendorTags.h
index 259953a..601b448 100644
--- a/QCamera2/HAL3/QCamera3VendorTags.h
+++ b/QCamera2/HAL3/QCamera3VendorTags.h
@@ -41,6 +41,7 @@
     QCAMERA3_AV_TIMER,
     QCAMERA3_SENSOR_META_DATA,
     QCAMERA3_TEMPORAL_DENOISE,
+    NEXUS_EXPERIMENTAL_2015,
     QCAMERA3_SECTIONS_END
 };
 
@@ -53,6 +54,7 @@
     QCAMERA3_AV_TIMER_START = QCAMERA3_AV_TIMER << 16,
     QCAMERA3_SENSOR_META_DATA_START = QCAMERA3_SENSOR_META_DATA << 16,
     QCAMERA3_TEMPORAL_DENOISE_START = QCAMERA3_TEMPORAL_DENOISE << 16,
+    NEXUS_EXPERIMENTAL_2015_START = NEXUS_EXPERIMENTAL_2015 <<16
 };
 
 enum qcamera3_ext_tags {
@@ -130,7 +132,11 @@
 
     QCAMERA3_TEMPORAL_DENOISE_ENABLE = QCAMERA3_TEMPORAL_DENOISE_START,
     QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE,
-    QCAMERA3_TEMPORAL_DENOISE_END
+    QCAMERA3_TEMPORAL_DENOISE_END,
+
+    NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL = NEXUS_EXPERIMENTAL_2015_START,
+    NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
+    NEXUS_EXPERIMENTAL_2015_END
 };
 
 // QCAMERA3_OPAQUE_RAW_FORMAT
diff --git a/QCamera2/stack/common/cam_intf.h b/QCamera2/stack/common/cam_intf.h
index fe0cdc0..cb556bd 100644
--- a/QCamera2/stack/common/cam_intf.h
+++ b/QCamera2/stack/common/cam_intf.h
@@ -400,6 +400,14 @@
 
     /* maximum pixel bandwidth shared between cameras */
     uint64_t max_pixel_bandwidth;
+
+    /* Array of K integers, where K%4==0,
+      as a list of rectangles in the pixelArray co-ord system
+      left, top, right, bottom */
+    int32_t optical_black_regions[MAX_OPTICAL_BLACK_REGIONS * 4];
+    /* Count is K/4 */
+    uint8_t optical_black_region_count;
+
 } cam_capability_t;
 
 typedef enum {
diff --git a/QCamera2/stack/common/cam_types.h b/QCamera2/stack/common/cam_types.h
index 862cf78..ccad567 100644
--- a/QCamera2/stack/common/cam_types.h
+++ b/QCamera2/stack/common/cam_types.h
@@ -120,6 +120,8 @@
 
 #define MAX_EEPROM_VERSION_INFO_LEN 32
 
+#define MAX_OPTICAL_BLACK_REGIONS 5
+
 typedef enum {
     CAM_HAL_V1 = 1,
     CAM_HAL_V3 = 3
diff --git a/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c b/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
index 4dc5b14..9fa8b89 100755
--- a/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
+++ b/QCamera2/stack/mm-jpeg-interface/src/mm_jpeg.c
@@ -59,6 +59,11 @@
  */
 #define MM_JPEG_MIN_NOM_RESOLUTION 7680000 /*8MP*/
 
+#ifdef MM_JPEG_USE_PIPELINE
+#undef MM_JPEG_CONCURRENT_SESSIONS_COUNT
+#define MM_JPEG_CONCURRENT_SESSIONS_COUNT 1
+#endif
+
 OMX_ERRORTYPE mm_jpeg_ebd(OMX_HANDLETYPE hComponent,
     OMX_PTR pAppData,
     OMX_BUFFERHEADERTYPE* pBuffer);
@@ -2126,7 +2131,7 @@
       cam_sem_post(&my_obj->job_mgr.job_sem);
   }
 
-  CDBG_HIGH("%s:%d] X", __func__, __LINE__);
+  CDBG_HIGH("%s:%d] job_id %d X", __func__, __LINE__, *job_id);
 
   return rc;
 }
diff --git a/QCamera2/util/QCameraFlash.cpp b/QCamera2/util/QCameraFlash.cpp
old mode 100755
new mode 100644
index 91f5430..2ca8fb4
--- a/QCamera2/util/QCameraFlash.cpp
+++ b/QCamera2/util/QCameraFlash.cpp
@@ -192,6 +192,9 @@
                 close(m_flashFds[camera_id]);
                 m_flashFds[camera_id] = -1;
             }
+
+            /* wait for PMIC to init */
+            usleep(5000);
         }
     }