QCamera2: Avoid switching the reprocess type during HDR+

The final encoding pass during HDR+ processing will try
to avoid offline processing by switching the reprocess
type of the post-processor to "REPROCESS_TYPE_NONE".
Non-HDR+ requests will usually use
"REPROCESS_TYPE_JPEG" so the post-processor might need
to stop and restart. In most cases this will not cause
any major side effects because HDR+ and non-HDR+
processing rarely overlaps. However if an overlap is present,
then processing like Jpeg encoding can be affected and
capture results may never return.
Avoid this scenario by pushing the HDR+ buffers directly
in the post-processor jpeg queue. The reprocess type
must remain unchanged as long as there any pending
requests.

Bug: 154828114
Test: Camera CTS

Change-Id: I6a01ad665a5fb25023b4d69d4f64625b372248a7
diff --git a/msm8998/QCamera2/HAL3/QCamera3Channel.cpp b/msm8998/QCamera2/HAL3/QCamera3Channel.cpp
index 04048ea..8d2e7f1 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Channel.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3Channel.cpp
@@ -4098,7 +4098,6 @@
 
 int32_t QCamera3PicChannel::queueJpegSetting(uint32_t index, metadata_buffer_t *metadata)
 {
-    QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)mUserData;
     jpeg_settings_t *settings =
             (jpeg_settings_t *)malloc(sizeof(jpeg_settings_t));
 
@@ -4107,8 +4106,22 @@
         return -ENOMEM;
     }
 
+    auto ret = initializeJpegSetting(index, metadata, settings);
+    if (ret != NO_ERROR) {
+        return ret;
+    }
+
+    return m_postprocessor.processJpegSettingData(settings);
+}
+
+int32_t QCamera3PicChannel::initializeJpegSetting(uint32_t index, metadata_buffer_t *metadata,
+        jpeg_settings_t *settings) {
+    if ((settings == nullptr) || (metadata == nullptr)) {
+        return BAD_VALUE;
+    }
     memset(settings, 0, sizeof(jpeg_settings_t));
 
+    QCamera3HardwareInterface* hal_obj = (QCamera3HardwareInterface*)mUserData;
     settings->out_buf_index = index;
 
     settings->jpeg_orientation = 0;
@@ -4184,7 +4197,7 @@
         }
     }
 
-    return m_postprocessor.processJpegSettingData(settings);
+    return NO_ERROR;
 }
 
 
@@ -4313,9 +4326,6 @@
     dim.height = (int32_t)mYuvHeight;
     setReprocConfig(reproc_cfg, nullptr, metadata.get(), mStreamFormat, dim);
 
-    // Override reprocess type to just JPEG encoding without reprocessing.
-    reproc_cfg.reprocess_type = REPROCESS_TYPE_NONE;
-
     // Get the index of the output jpeg buffer.
     int index = mMemory.getMatchBufIndex((void*)outBuffer);
     if(index < 0) {
@@ -4343,52 +4353,55 @@
     // Start postprocessor
     startPostProc(reproc_cfg);
 
-    // Queue jpeg settings
-    rc = queueJpegSetting((uint32_t)index, metadata.get());
-    if (rc != OK) {
-        ALOGE("%s: Queueing Jpeg setting for frame number (%u) buffer index (%d) failed: %s (%d)",
-                __FUNCTION__, frameNumber, index, strerror(-rc), rc);
-        return rc;
+    qcamera_hal3_jpeg_data_t *jpeg_job =
+            (qcamera_hal3_jpeg_data_t *) calloc(1, sizeof(qcamera_hal3_jpeg_data_t));
+    if (jpeg_job == NULL) {
+        LOGE("No memory for jpeg job");
+        return NO_MEMORY;
+    }
+
+    jpeg_job->jpeg_settings = (jpeg_settings_t *) calloc(1, sizeof(jpeg_settings_t));
+    if (jpeg_job->jpeg_settings == nullptr) {
+        LOGE("out of memory allocating jpeg_settings");
+        return NO_MEMORY;
+    }
+
+    auto ret = initializeJpegSetting(index, metadata.get(), jpeg_job->jpeg_settings);
+    if (ret != NO_ERROR) {
+        return ret;
     }
 
     // Allocate a buffer for the YUV input. It will be freed in QCamera3PostProc.
-    mm_camera_super_buf_t *src_frame =
+    jpeg_job->src_frame =
             (mm_camera_super_buf_t *)calloc(1, sizeof(mm_camera_super_buf_t));
-    if (src_frame == nullptr) {
+    if (jpeg_job->src_frame == nullptr) {
         LOGE("%s: No memory for src frame", __FUNCTION__);
         return NO_MEMORY;
     }
-    src_frame->camera_handle = m_camHandle;
-    src_frame->ch_id = getMyHandle();
-    src_frame->num_bufs = 1;
-    src_frame->bufs[0] = frame;
-
-    // Start processing the YUV buffer.
-    ALOGD("%s: %d: Post-process started", __FUNCTION__, __LINE__);
-    rc = m_postprocessor.processData(src_frame);
-    if (rc != OK) {
-        ALOGE("%s: Post processing frame (frame number: %u, jpeg buffer: %d) failed: %s (%d)",
-            __FUNCTION__, frameNumber, index, strerror(-rc), rc);
-        return rc;
-    }
+    jpeg_job->src_frame->camera_handle = m_camHandle;
+    jpeg_job->src_frame->ch_id = getMyHandle();
+    jpeg_job->src_frame->num_bufs = 1;
+    jpeg_job->src_frame->bufs[0] = frame;
 
     // Allocate a buffer for the metadata. It will be freed in QCamera3PostProc.
-    mm_camera_super_buf_t *metadataBuf =
+    jpeg_job->src_metadata =
             (mm_camera_super_buf_t *)calloc(1, sizeof(mm_camera_super_buf_t));
-    if (metadata == nullptr) {
+    if (jpeg_job->src_metadata == nullptr) {
         LOGE("%s: No memory for metadata", __FUNCTION__);
         return NO_MEMORY;
     }
-    metadataBuf->camera_handle = m_camHandle;
-    metadataBuf->ch_id = getMyHandle();
-    metadataBuf->num_bufs = 1;
-    metadataBuf->bufs[0] = metaFrame;
-    metadataBuf->bufs[0]->buffer = metadata.get();
+    jpeg_job->src_metadata->camera_handle = m_camHandle;
+    jpeg_job->src_metadata->ch_id = getMyHandle();
+    jpeg_job->src_metadata->num_bufs = 1;
+    jpeg_job->src_metadata->bufs[0] = metaFrame;
+    jpeg_job->src_metadata->bufs[0]->buffer = metadata.get();
+    jpeg_job->metadata = metadata.get();
 
-    // Start processing the metadata
-    rc = m_postprocessor.processPPMetadata(metadataBuf);
+    // Start processing the jpeg job
+    jpeg_job->hdr_plus_processing = true;
+    rc = m_postprocessor.processJpegJob(jpeg_job);
     if (rc != OK) {
-        ALOGE("%s: Post processing metadata (frame number: %u, jpeg buffer: %d) failed: %s (%d)",
+        ALOGE("%s: Post processing jpeg (frame number: %u, jpeg buffer: %d) failed: %s (%d)",
                 __FUNCTION__, frameNumber, index, strerror(-rc), rc);
         return rc;
     }
diff --git a/msm8998/QCamera2/HAL3/QCamera3Channel.h b/msm8998/QCamera2/HAL3/QCamera3Channel.h
index a441427..1a17512 100644
--- a/msm8998/QCamera2/HAL3/QCamera3Channel.h
+++ b/msm8998/QCamera2/HAL3/QCamera3Channel.h
@@ -597,6 +597,8 @@
 
 private:
     int32_t queueJpegSetting(uint32_t out_buf_index, metadata_buffer_t *metadata);
+    int32_t initializeJpegSetting(uint32_t index, metadata_buffer_t *metadata,
+            jpeg_settings_t *settings);
 
 public:
     cam_dimension_t m_max_pic_dim;
diff --git a/msm8998/QCamera2/HAL3/QCamera3PostProc.cpp b/msm8998/QCamera2/HAL3/QCamera3PostProc.cpp
index d76c4eb..c0a743c 100644
--- a/msm8998/QCamera2/HAL3/QCamera3PostProc.cpp
+++ b/msm8998/QCamera2/HAL3/QCamera3PostProc.cpp
@@ -796,8 +796,29 @@
     // free pp job buf
     free(job);
 
-    // enqueu reprocessed frame to jpeg input queue
-    m_inputJpegQ.enqueue((void *)jpeg_job);
+    return processJpegJob(jpeg_job);
+}
+
+/*===========================================================================
+ * FUNCTION   : processJpegJob
+ *
+ * DESCRIPTION: process received jpeg job.
+ *
+ * PARAMETERS :
+ *   @job    : received jpeg job.
+ *
+ * RETURN     : int32_t type of status
+ *              NO_ERROR  -- success
+ *              none-zero failure code
+ *
+ *==========================================================================*/
+int32_t QCamera3PostProcessor::processJpegJob(qcamera_hal3_jpeg_data_t *job) {
+    if (job == nullptr) {
+        return BAD_VALUE;
+    }
+
+    // queue job to jpeg input queue
+    m_inputJpegQ.enqueue((void *)job);
 
     // wait up data proc thread
     m_dataProcTh.sendCmd(CAMERA_CMD_TYPE_DO_NEXT_JOB, FALSE, FALSE);
@@ -1014,7 +1035,7 @@
         }
 
         if (NULL != job->src_frame) {
-            if (NULL != m_pReprocChannel) {
+            if (NULL != m_pReprocChannel && !job->hdr_plus_processing) {
                 rc = m_pReprocChannel->bufDone(job->src_frame);
                 if (NO_ERROR != rc)
                     LOGE("bufDone error: %d", rc);
diff --git a/msm8998/QCamera2/HAL3/QCamera3PostProc.h b/msm8998/QCamera2/HAL3/QCamera3PostProc.h
index 6c71f5b..36201b7 100644
--- a/msm8998/QCamera2/HAL3/QCamera3PostProc.h
+++ b/msm8998/QCamera2/HAL3/QCamera3PostProc.h
@@ -70,6 +70,7 @@
     metadata_buffer_t *metadata;
     mm_camera_super_buf_t *src_metadata;
     jpeg_settings_t *jpeg_settings;
+    bool hdr_plus_processing;
 } qcamera_hal3_jpeg_data_t;
 
 typedef struct {
@@ -124,6 +125,7 @@
     int32_t processData(mm_camera_super_buf_t *input,
             buffer_handle_t *output, uint32_t frameNumber);
     int32_t processData(mm_camera_super_buf_t *input);
+    int32_t processJpegJob(qcamera_hal3_jpeg_data_t *job);
     int32_t processPPData(mm_camera_super_buf_t *frame);
     int32_t processPPMetadata(mm_camera_super_buf_t *reproc_meta);
     int32_t processJpegSettingData(jpeg_settings_t *jpeg_settings);