Merge "QCamera3: Limit HDR+ requests" into oc-mr1-dev
diff --git a/msm8998/QCamera2/HAL3/QCamera3Channel.cpp b/msm8998/QCamera2/HAL3/QCamera3Channel.cpp
index 0d9d3f6..6307aaa 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3Channel.cpp
@@ -101,6 +101,7 @@
     mNRMode = 0;
 
     mYUVDump = property_get_int32("persist.camera.dumpimg", 0);
+    mMapStreamBuffers = mYUVDump;
 }
 
 /*===========================================================================
@@ -185,7 +186,8 @@
                                                m_handle,
                                                m_camOps,
                                                &mPaddingInfo,
-                                               this);
+                                               this,
+                                               mMapStreamBuffers);
     if (pStream == NULL) {
         LOGE("No mem for Stream");
         return NO_MEMORY;
@@ -1250,7 +1252,7 @@
 
     src_frame->src_frame = *pInputBuffer;
     rc = mOfflineMemory.getBufDef(reproc_cfg->input_stream_plane_info.plane_info,
-            src_frame->input_buffer, input_index);
+            src_frame->input_buffer, input_index, mMapStreamBuffers);
     if (rc != 0) {
         return rc;
     }
@@ -1281,7 +1283,7 @@
 
     mm_camera_buf_def_t meta_buf;
     cam_frame_len_offset_t offset = meta_planes.plane_info;
-    rc = mOfflineMetaMemory.getBufDef(offset, meta_buf, metaBufIdx);
+    rc = mOfflineMetaMemory.getBufDef(offset, meta_buf, metaBufIdx, true /*virtualAddr*/);
     if (NO_ERROR != rc) {
         return rc;
     }
@@ -2101,6 +2103,7 @@
                                 userData, numBuffers),
                         mMemory(NULL), mDepthDataPresent(false)
 {
+    mMapStreamBuffers = true;
 }
 
 QCamera3MetadataChannel::~QCamera3MetadataChannel()
@@ -2244,6 +2247,7 @@
     char prop[PROPERTY_VALUE_MAX];
     property_get("persist.camera.raw.debug.dump", prop, "0");
     mRawDump = atoi(prop);
+    mMapStreamBuffers = (mRawDump || mIsRaw16);
 }
 
 QCamera3RawChannel::~QCamera3RawChannel()
@@ -4064,7 +4068,7 @@
     mStreams[0]->getFrameOffset(offset);
 
     // Get a buffer from YUV memory.
-    rc = mYuvMemory->getBufDef(offset, *frame, bufIdx);
+    rc = mYuvMemory->getBufDef(offset, *frame, bufIdx, mMapStreamBuffers);
     if (rc != 0) {
         ALOGE("%s: Getting a frame failed: %s (%d).", __FUNCTION__, strerror(-rc), rc);
         return rc;
@@ -4976,7 +4980,7 @@
         return BAD_VALUE;
     }
 
-    if (NULL == frame->input_buffer.buffer) {
+    if (0 > frame->input_buffer.fd) {
         LOGE("No input buffer available");
         return BAD_VALUE;
     }
@@ -5260,7 +5264,8 @@
             m_handle,
             m_camOps,
             &mPaddingInfo,
-            (QCamera3Channel*)this);
+            (QCamera3Channel*)this,
+            false/*mapStreamBuffers*/);
     if (pStream == NULL) {
         LOGE("No mem for Stream");
         return NO_MEMORY;
diff --git a/msm8998/QCamera2/HAL3/QCamera3Channel.h b/msm8998/QCamera2/HAL3/QCamera3Channel.h
index 4a8c358..871d6ad 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Channel.h
+++ b/msm8998/QCamera2/HAL3/QCamera3Channel.h
@@ -184,6 +184,7 @@
     uint32_t mSkipMode;
     uint32_t mDumpSkipCnt;
     uint8_t mNRMode;
+    bool    mMapStreamBuffers; // Whether to mmap all stream buffers
 };
 
 /* QCamera3ProcessingChannel is used to handle all streams that are directly
diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
index df81a48..7861a95 100644
--- a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp
@@ -273,7 +273,9 @@
     { ANDROID_CONTROL_AE_MODE_ON,                   CAM_FLASH_MODE_OFF },
     { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH,        CAM_FLASH_MODE_AUTO},
     { ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,      CAM_FLASH_MODE_ON  },
-    { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE, CAM_FLASH_MODE_AUTO}
+    { ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE, CAM_FLASH_MODE_AUTO},
+    { (camera_metadata_enum_android_control_ae_mode_t)
+      NEXUS_EXPERIMENTAL_2016_CONTROL_AE_MODE_EXTERNAL_FLASH, CAM_FLASH_MODE_OFF }
 };
 
 const QCamera3HardwareInterface::QCameraMap<
@@ -7267,12 +7269,11 @@
                         faceScores[i] = (uint8_t)faceDetectionInfo->faces[i].score;
                         // Adjust crop region from sensor output coordinate system to active
                         // array coordinate system.
-                        cam_rect_t& rect = faceDetectionInfo->faces[i].face_boundary;
+                        cam_rect_t rect = faceDetectionInfo->faces[i].face_boundary;
                         mCropRegionMapper.toActiveArray(rect.left, rect.top,
                                 rect.width, rect.height);
 
-                        convertToRegions(faceDetectionInfo->faces[i].face_boundary,
-                                faceRectangles+j, -1);
+                        convertToRegions(rect, faceRectangles+j, -1);
 
                         LOGL("FD_DEBUG : Frame[%d] Face[%d] : top-left (%d, %d), "
                                 "bottom-right (%d, %d)",
@@ -7299,19 +7300,20 @@
                                 CAM_INTF_META_FACE_LANDMARK, metadata) {
 
                             for (size_t i = 0; i < numFaces; i++) {
+                                cam_face_landmarks_info_t face_landmarks = landmarks->face_landmarks[i];
                                 // Map the co-ordinate sensor output coordinate system to active
                                 // array coordinate system.
                                 mCropRegionMapper.toActiveArray(
-                                        landmarks->face_landmarks[i].left_eye_center.x,
-                                        landmarks->face_landmarks[i].left_eye_center.y);
+                                        face_landmarks.left_eye_center.x,
+                                        face_landmarks.left_eye_center.y);
                                 mCropRegionMapper.toActiveArray(
-                                        landmarks->face_landmarks[i].right_eye_center.x,
-                                        landmarks->face_landmarks[i].right_eye_center.y);
+                                        face_landmarks.right_eye_center.x,
+                                        face_landmarks.right_eye_center.y);
                                 mCropRegionMapper.toActiveArray(
-                                        landmarks->face_landmarks[i].mouth_center.x,
-                                        landmarks->face_landmarks[i].mouth_center.y);
+                                        face_landmarks.mouth_center.x,
+                                        face_landmarks.mouth_center.y);
 
-                                convertLandmarks(landmarks->face_landmarks[i], faceLandmarks+k);
+                                convertLandmarks(face_landmarks, faceLandmarks+k);
 
                                 LOGL("FD_DEBUG LANDMARK : Frame[%d] Face[%d] : "
                                         "left-eye (%d, %d), right-eye (%d, %d), mouth (%d, %d)",
@@ -7742,16 +7744,17 @@
         int32_t aeRegions[REGIONS_TUPLE_COUNT];
         // Adjust crop region from sensor output coordinate system to active
         // array coordinate system.
-        mCropRegionMapper.toActiveArray(hAeRegions->rect.left, hAeRegions->rect.top,
-                hAeRegions->rect.width, hAeRegions->rect.height);
+        cam_rect_t hAeRect = hAeRegions->rect;
+        mCropRegionMapper.toActiveArray(hAeRect.left, hAeRect.top,
+                hAeRect.width, hAeRect.height);
 
-        convertToRegions(hAeRegions->rect, aeRegions, hAeRegions->weight);
+        convertToRegions(hAeRect, aeRegions, hAeRegions->weight);
         camMetadata.update(ANDROID_CONTROL_AE_REGIONS, aeRegions,
                 REGIONS_TUPLE_COUNT);
         LOGD("Metadata : ANDROID_CONTROL_AE_REGIONS: FWK: [%d,%d,%d,%d] HAL: [%d,%d,%d,%d]",
                  aeRegions[0], aeRegions[1], aeRegions[2], aeRegions[3],
-                hAeRegions->rect.left, hAeRegions->rect.top, hAeRegions->rect.width,
-                hAeRegions->rect.height);
+                hAeRect.left, hAeRect.top, hAeRect.width,
+                hAeRect.height);
     }
 
     if (!pendingRequest.focusStateSent) {
@@ -8318,19 +8321,20 @@
 
     IF_META_AVAILABLE(cam_area_t, hAfRegions, CAM_INTF_META_AF_ROI, metadata) {
         /*af regions*/
+        cam_rect_t hAfRect = hAfRegions->rect;
         int32_t afRegions[REGIONS_TUPLE_COUNT];
         // Adjust crop region from sensor output coordinate system to active
         // array coordinate system.
-        mCropRegionMapper.toActiveArray(hAfRegions->rect.left, hAfRegions->rect.top,
-                hAfRegions->rect.width, hAfRegions->rect.height);
+        mCropRegionMapper.toActiveArray(hAfRect.left, hAfRect.top,
+                hAfRect.width, hAfRect.height);
 
-        convertToRegions(hAfRegions->rect, afRegions, hAfRegions->weight);
+        convertToRegions(hAfRect, afRegions, hAfRegions->weight);
         camMetadata.update(ANDROID_CONTROL_AF_REGIONS, afRegions,
                 REGIONS_TUPLE_COUNT);
         LOGD("Metadata : ANDROID_CONTROL_AF_REGIONS: FWK: [%d,%d,%d,%d] HAL: [%d,%d,%d,%d]",
                  afRegions[0], afRegions[1], afRegions[2], afRegions[3],
-                hAfRegions->rect.left, hAfRegions->rect.top, hAfRegions->rect.width,
-                hAfRegions->rect.height);
+                hAfRect.left, hAfRect.top, hAfRect.width,
+                hAfRect.height);
     }
 
     // AF region confidence
diff --git a/msm8998/QCamera2/HAL3/QCamera3Mem.cpp b/msm8998/QCamera2/HAL3/QCamera3Mem.cpp
index c7b39d0..4298bbe 100755
--- a/msm8998/QCamera2/HAL3/QCamera3Mem.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3Mem.cpp
@@ -218,13 +218,14 @@
  *   @offset  : [input] frame buffer offset
  *   @bufDef  : [output] reference to struct to store buffer definition
  *   @index   : [input] index of the buffer
+ *   @virtualAddr : [input] Whether to fill out virtual address
  *
  * RETURN     : int32_t type of status
  *              NO_ERROR  -- success
  *              none-zero failure code
  *==========================================================================*/
 int32_t QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
-        mm_camera_buf_def_t &bufDef, uint32_t index)
+        mm_camera_buf_def_t &bufDef, uint32_t index, bool virtualAddr)
 {
     Mutex::Autolock lock(mLock);
 
@@ -236,7 +237,7 @@
     bufDef.fd = mMemInfo[index].fd;
     bufDef.frame_len = mMemInfo[index].size;
     bufDef.mem_info = (void *)this;
-    bufDef.buffer = getPtrLocked(index);
+    bufDef.buffer = virtualAddr ? getPtrLocked(index) : nullptr;
     bufDef.planes_buf.num_planes = (int8_t)offset.num_planes;
     bufDef.buf_idx = (uint8_t)index;
 
@@ -745,6 +746,7 @@
     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
         mBufferHandle[i] = NULL;
         mPrivateHandle[i] = NULL;
+        mPtr[i] = nullptr;
     }
 }
 
@@ -779,7 +781,6 @@
 {
     status_t ret = NO_ERROR;
     struct ion_fd_data ion_info_fd;
-    void *vaddr = NULL;
     int32_t colorSpace = ITU_R_601_FR;
     int32_t idx = -1;
 
@@ -833,18 +834,7 @@
             mPrivateHandle[idx]->size;
     mMemInfo[idx].handle = ion_info_fd.handle;
 
-    vaddr = mmap(NULL,
-            mMemInfo[idx].size,
-            PROT_READ | PROT_WRITE,
-            MAP_SHARED,
-            mMemInfo[idx].fd, 0);
-    if (vaddr == MAP_FAILED) {
-        mMemInfo[idx].handle = 0;
-        ret = NO_MEMORY;
-    } else {
-        mPtr[idx] = vaddr;
-        mBufferCount++;
-    }
+    mBufferCount++;
 
 end:
     LOGD("X ");
@@ -865,8 +855,10 @@
  *==========================================================================*/
 int32_t QCamera3GrallocMemory::unregisterBufferLocked(size_t idx)
 {
-    munmap(mPtr[idx], mMemInfo[idx].size);
-    mPtr[idx] = NULL;
+    if (mPtr[idx] != nullptr) {
+        munmap(mPtr[idx], mMemInfo[idx].size);
+        mPtr[idx] = nullptr;
+    }
 
     struct ion_handle_data ion_handle;
     memset(&ion_handle, 0, sizeof(ion_handle));
@@ -1230,6 +1222,23 @@
         return NULL;
     }
 
+    if (mPtr[index] == nullptr) {
+        void *vaddr = NULL;
+        vaddr = mmap(NULL,
+                mMemInfo[index].size,
+                PROT_READ | PROT_WRITE,
+                MAP_SHARED,
+                mMemInfo[index].fd, 0);
+
+        if (vaddr == MAP_FAILED) {
+            LOGE("mmap failed for buffer index %d, size %d: %s(%d)",
+                    index, mMemInfo[index].size, strerror(errno), errno);
+            return NULL;
+        } else {
+            mPtr[index] = vaddr;
+        }
+    }
+
     return mPtr[index];
 }
 
diff --git a/msm8998/QCamera2/HAL3/QCamera3Mem.h b/msm8998/QCamera2/HAL3/QCamera3Mem.h
index 00a4ee3..14224e4 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Mem.h
+++ b/msm8998/QCamera2/HAL3/QCamera3Mem.h
@@ -78,7 +78,7 @@
     virtual ~QCamera3Memory();
 
     int32_t getBufDef(const cam_frame_len_offset_t &offset,
-            mm_camera_buf_def_t &bufDef, uint32_t index);
+            mm_camera_buf_def_t &bufDef, uint32_t index, bool virtualAddr);
 
 protected:
     struct QCamera3MemInfo {
diff --git a/msm8998/QCamera2/HAL3/QCamera3Stream.cpp b/msm8998/QCamera2/HAL3/QCamera3Stream.cpp
index 3cb2298..b2f7e2d 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Stream.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3Stream.cpp
@@ -278,7 +278,8 @@
                              uint32_t chId,
                              mm_camera_ops_t *camOps,
                              cam_padding_info_t *paddingInfo,
-                             QCamera3Channel *channel) :
+                             QCamera3Channel *channel,
+                             bool mapStreamBuffers) :
         mCamHandle(camHandle),
         mChannelHandle(chId),
         mHandle(0),
@@ -300,7 +301,8 @@
         mCurrentBatchBufDef(NULL),
         mBufsStaged(0),
         mFreeBatchBufQ(NULL, this),
-        mNRMode(0)
+        mNRMode(0),
+        mMapStreamBuffers(mapStreamBuffers)
 {
     mMemVtbl.user_data = this;
     mMemVtbl.get_bufs = get_bufs;
@@ -780,15 +782,17 @@
 
         if (BAD_INDEX != bufSize) {
             LOGD("Map streamBufIdx: %d", index);
+            void* buffer = (mMapStreamBuffers ?
+                            mStreamBufs->getPtr(index) : NULL);
             rc = mMemOps->map_ops(index, -1, mStreamBufs->getFd(index),
-                    (size_t)bufSize, mStreamBufs->getPtr(index),
+                    (size_t)bufSize, buffer,
                     CAM_MAPPING_BUF_TYPE_STREAM_BUF, mMemOps->userdata);
             if (rc < 0) {
                 LOGE("Failed to map camera buffer %d", index);
                 return rc;
             }
 
-            rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index);
+            rc = mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[index], index, mMapStreamBuffers);
             if (NO_ERROR != rc) {
                 LOGE("Couldn't find camera buffer definition");
                 mMemOps->unmap_ops(index, -1, CAM_MAPPING_BUF_TYPE_STREAM_BUF, mMemOps->userdata);
@@ -947,8 +951,10 @@
         if (mStreamBufs->valid(i)) {
             ssize_t bufSize = mStreamBufs->getSize(i);
             if (BAD_INDEX != bufSize) {
+                void* buffer = (mMapStreamBuffers ?
+                        mStreamBufs->getPtr(i) : NULL);
                 rc = ops_tbl->map_ops(i, -1, mStreamBufs->getFd(i),
-                        (size_t)bufSize, mStreamBufs->getPtr(i),
+                        (size_t)bufSize, buffer,
                         CAM_MAPPING_BUF_TYPE_STREAM_BUF,
                         ops_tbl->userdata);
                 if (rc < 0) {
@@ -999,7 +1005,7 @@
     memset(mBufDefs, 0, mNumBufs * sizeof(mm_camera_buf_def_t));
     for (uint32_t i = 0; i < mNumBufs; i++) {
         if (mStreamBufs->valid(i)) {
-            mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i);
+            mStreamBufs->getBufDef(mFrameLenOffset, mBufDefs[i], i, mMapStreamBuffers);
         }
     }
 
@@ -1389,8 +1395,9 @@
         if (mNumBatchBufs) {
             //For USER_BUF, size = number_of_container bufs instead of the total
             //buf size
+            void* buffer = (mMapStreamBuffers ? mStreamBufs->getPtr(i) : NULL);
             rc = ops_tbl->map_ops(i, -1, mStreamBatchBufs->getFd(i),
-                    (size_t)mNumBatchBufs, mStreamBatchBufs->getPtr(i),
+                    (size_t)mNumBatchBufs, buffer,
                     CAM_MAPPING_BUF_TYPE_STREAM_USER_BUF,
                     ops_tbl->userdata);
             if (rc < 0) {
diff --git a/msm8998/QCamera2/HAL3/QCamera3Stream.h b/msm8998/QCamera2/HAL3/QCamera3Stream.h
index e61f842..2fbe444 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Stream.h
+++ b/msm8998/QCamera2/HAL3/QCamera3Stream.h
@@ -59,7 +59,8 @@
                   uint32_t chId,
                   mm_camera_ops_t *camOps,
                   cam_padding_info_t *paddingInfo,
-                  QCamera3Channel *channel);
+                  QCamera3Channel *channel,
+                  bool mapStreamBuffers);
     virtual ~QCamera3Stream();
     virtual int32_t init(cam_stream_type_t streamType,
                          cam_format_t streamFormat,
@@ -137,6 +138,8 @@
     QCameraQueue mFreeBatchBufQ; //Buffer queue containing empty batch buffers
     uint8_t mNRMode; // Initial noise reduction mode
 
+    bool mMapStreamBuffers; // Whether to mmap every stream buffers
+
     static int32_t get_bufs(
                      cam_frame_len_offset_t *offset,
                      uint8_t *num_bufs,
diff --git a/msm8998/QCamera2/HAL3/QCamera3StreamMem.cpp b/msm8998/QCamera2/HAL3/QCamera3StreamMem.cpp
index 7c83c68..5412abd 100644
--- a/msm8998/QCamera2/HAL3/QCamera3StreamMem.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3StreamMem.cpp
@@ -226,20 +226,21 @@
  *   @offset  : [input] frame buffer offset
  *   @bufDef  : [output] reference to struct to store buffer definition
  *   @index   : [input] index of the buffer
+ *   @virtualAddr : [input] whether to fill out virtual address
  *
  * RETURN     : int32_t type of status
  *              NO_ERROR  -- success
  *              none-zero failure code
  *==========================================================================*/
 int32_t QCamera3StreamMem::getBufDef(const cam_frame_len_offset_t &offset,
-        mm_camera_buf_def_t &bufDef, uint32_t index)
+        mm_camera_buf_def_t &bufDef, uint32_t index, bool virtualAddr)
 {
     int32_t ret = NO_ERROR;
 
     if (index < mMaxHeapBuffers)
-        ret = mHeapMem.getBufDef(offset, bufDef, index);
+        ret = mHeapMem.getBufDef(offset, bufDef, index, virtualAddr);
     else
-        ret = mGrallocMem.getBufDef(offset, bufDef, index);
+        ret = mGrallocMem.getBufDef(offset, bufDef, index, virtualAddr);
 
     bufDef.mem_info = (void *)this;
 
diff --git a/msm8998/QCamera2/HAL3/QCamera3StreamMem.h b/msm8998/QCamera2/HAL3/QCamera3StreamMem.h
index ae1898c..cbe3ea6 100644
--- a/msm8998/QCamera2/HAL3/QCamera3StreamMem.h
+++ b/msm8998/QCamera2/HAL3/QCamera3StreamMem.h
@@ -59,7 +59,8 @@
     int cleanInvalidateCache(uint32_t index);
     int cleanCache(uint32_t index);
     int32_t getBufDef(const cam_frame_len_offset_t &offset,
-            mm_camera_buf_def_t &bufDef, uint32_t index);
+            mm_camera_buf_def_t &bufDef, uint32_t index,
+            bool virtualAddr);
     void *getPtr(uint32_t index);
 
     bool valid(uint32_t index);