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);