diff options
author | Xin Li <delphij@google.com> | 2020-09-10 17:22:34 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-09-10 17:22:34 +0000 |
commit | 251f430d51525ba14aae361f09405db25295ae38 (patch) | |
tree | 36ffe6a959960f8999247768e40a2fe1813cae32 | |
parent | cce973829603e9cb0846189a91d8cb0113371009 (diff) | |
parent | c609498b6d2e1cea19c6e71c776cd2b701e08f7b (diff) | |
download | camera-251f430d51525ba14aae361f09405db25295ae38.tar.gz |
Merge "Merge Android R"
-rwxr-xr-x | msm8998/QCamera2/Android.mk | 3 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL/test/qcamera_test.cpp | 16 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3Channel.cpp | 85 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3Channel.h | 2 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.cpp | 157 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.h | 19 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3HWI.cpp | 208 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3HWI.h | 9 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3PostProc.cpp | 27 | ||||
-rw-r--r-- | msm8998/QCamera2/HAL3/QCamera3PostProc.h | 2 | ||||
-rw-r--r-- | msm8998/QCamera2/QCamera2Hal.cpp | 4 | ||||
-rw-r--r-- | msm8998/QCamera2/stack/common/cam_intf.h | 3 | ||||
-rw-r--r-- | msm8998/QCamera2/util/QCameraPerf.cpp | 141 |
13 files changed, 501 insertions, 175 deletions
diff --git a/msm8998/QCamera2/Android.mk b/msm8998/QCamera2/Android.mk index dc3391e..dadec46 100755 --- a/msm8998/QCamera2/Android.mk +++ b/msm8998/QCamera2/Android.mk @@ -146,9 +146,10 @@ LOCAL_C_INCLUDES += \ $(SRC_DISPLAY_HAL_DIR)/libqservice LOCAL_SHARED_LIBRARIES := liblog libhardware libutils libcutils libdl libsync LOCAL_SHARED_LIBRARIES += libmmcamera_interface libmmjpeg_interface libui libcamera_metadata -LOCAL_SHARED_LIBRARIES += libqdMetaData libqservice libbinder +LOCAL_SHARED_LIBRARIES += libqdMetaData libqservice libbinder libbinder_ndk LOCAL_SHARED_LIBRARIES += libbase libcutils libdl libhdrplusclient LOCAL_SHARED_LIBRARIES += libhidlbase libutils android.hardware.power@1.2 +LOCAL_SHARED_LIBRARIES += android.hardware.power-ndk_platform LOCAL_SHARED_LIBRARIES += libtinyxml2 ifeq ($(TARGET_TS_MAKEUP),true) LOCAL_SHARED_LIBRARIES += libts_face_beautify_hal libts_detected_face_hal diff --git a/msm8998/QCamera2/HAL/test/qcamera_test.cpp b/msm8998/QCamera2/HAL/test/qcamera_test.cpp index 8de3172..d433302 100644 --- a/msm8998/QCamera2/HAL/test/qcamera_test.cpp +++ b/msm8998/QCamera2/HAL/test/qcamera_test.cpp @@ -97,8 +97,8 @@ const char CameraContext::KEY_ZSL[] = "zsl"; *==========================================================================*/ void CameraContext::previewCallback(const sp<IMemory>& mem) { - printf("PREVIEW Callback %p", mem->pointer()); - uint8_t *ptr = (uint8_t*) mem->pointer(); + printf("PREVIEW Callback %p", mem->unsecurePointer()); + uint8_t *ptr = (uint8_t*) mem->unsecurePointer(); if (NULL != ptr) { printf("PRV_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", ptr[0], @@ -186,7 +186,7 @@ status_t CameraContext::saveFile(const sp<IMemory>& mem, String8 path) return BAD_VALUE; } - buff = (unsigned char *)mem->pointer(); + buff = (unsigned char *)mem->unsecurePointer(); if (!buff) { printf("Buffer pointer is invalid\n"); close(fd); @@ -289,7 +289,7 @@ status_t CameraContext::decodeJPEG(const sp<IMemory>& mem, SkBitmap *skBM) const void *buff = NULL; size_t size; - buff = (const void *)mem->pointer(); + buff = (const void *)mem->unsecurePointer(); size= mem->size(); switch(prefConfig) { @@ -341,7 +341,7 @@ status_t CameraContext::decodeJPEG(const sp<IMemory>& mem, SkBitmap *skBM) const void *buff = NULL; size_t size; - buff = (const void *)mem->pointer(); + buff = (const void *)mem->unsecurePointer(); size= mem->size(); switch(prefConfig) { @@ -923,11 +923,11 @@ void CameraContext::postData(int32_t msgType, // its jpeg sections if ((mInterpr->camera[0]->mWidthTmp * mInterpr->camera[0]->mHeightTmp) > (mInterpr->camera[1]->mWidthTmp * mInterpr->camera[1]->mHeightTmp)) { - buff = (unsigned char *)PiPPtrTmp->pointer(); + buff = (unsigned char *)PiPPtrTmp->unsecurePointer(); size= PiPPtrTmp->size(); } else if ((mInterpr->camera[0]->mWidthTmp * mInterpr->camera[0]->mHeightTmp) < (mInterpr->camera[1]->mWidthTmp * mInterpr->camera[1]->mHeightTmp)) { - buff = (unsigned char *)PiPPtrTmp->pointer(); + buff = (unsigned char *)PiPPtrTmp->unsecurePointer(); size= PiPPtrTmp->size(); } else { printf("Cannot take PiP. Images are with the same width" @@ -1057,7 +1057,7 @@ void CameraContext::dataCallbackTimestamp(nsecs_t timestamp, status_t err = NO_ERROR; ANativeWindowBuffer* anb = NULL; - dstBuff = (void *) dataPtr->pointer(); + dstBuff = (void *) dataPtr->unsecurePointer(); if (NULL == dstBuff) { printf("Cannot access destination buffer!!!\n"); mInterpr->ViVUnlock(); 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 @@ void QCamera3PicChannel::putStreamBufs() 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 @@ int32_t QCamera3PicChannel::queueJpegSetting(uint32_t index, metadata_buffer_t * 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 @@ int32_t QCamera3PicChannel::queueJpegSetting(uint32_t index, metadata_buffer_t * } } - return m_postprocessor.processJpegSettingData(settings); + return NO_ERROR; } @@ -4313,9 +4326,6 @@ int32_t QCamera3PicChannel::returnYuvBufferAndEncode(mm_camera_buf_def_t *frame, 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 @@ int32_t QCamera3PicChannel::returnYuvBufferAndEncode(mm_camera_buf_def_t *frame, // 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 @@ public: 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/QCamera3CropRegionMapper.cpp b/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.cpp index 94a398b..ab206d0 100644 --- a/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.cpp +++ b/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.cpp @@ -31,6 +31,8 @@ #define ATRACE_TAG ATRACE_TAG_CAMERA #define LOG_TAG "QCamera3CropRegionMapper" +#include <cmath> + // Camera dependencies #include "QCamera3CropRegionMapper.h" #include "QCamera3HWI.h" @@ -121,22 +123,41 @@ void QCamera3CropRegionMapper::update(uint32_t active_array_w, * @crop_top : y coordinate of top left corner of rectangle * @crop_width : width of rectangle * @crop_height : height of rectangle + * @zoom_ratio : zoom ratio to be reverted for the input rectangles * * RETURN : none *==========================================================================*/ void QCamera3CropRegionMapper::toActiveArray(int32_t& crop_left, int32_t& crop_top, - int32_t& crop_width, int32_t& crop_height) + int32_t& crop_width, int32_t& crop_height, float zoom_ratio) { if (mSensorW == 0 || mSensorH == 0 || mActiveArrayW == 0 || mActiveArrayH == 0) { LOGE("sensor/active array sizes are not initialized!"); return; } + if (zoom_ratio < MIN_ZOOM_RATIO) { + LOGE("Invalid zoom ratio %f", zoom_ratio); + return; + } + + // Map back to activeArray space + float left = crop_left * mActiveArrayW / mSensorW; + float top = crop_top * mActiveArrayH / mSensorH; + float width = crop_width * mActiveArrayW / mSensorW; + float height = crop_height * mActiveArrayH / mSensorH; - crop_left = crop_left * mActiveArrayW / mSensorW; - crop_top = crop_top * mActiveArrayH / mSensorH; - crop_width = crop_width * mActiveArrayW / mSensorW; - crop_height = crop_height * mActiveArrayH / mSensorH; + // Revert zoom_ratio, so that now the crop rectangle is separate from + // zoom_ratio. The coordinate is within the active array space which covers + // the post-zoom FOV. + left = left * zoom_ratio - (zoom_ratio - 1) * 0.5f * mActiveArrayW; + top = top * zoom_ratio - (zoom_ratio - 1) * 0.5f * mActiveArrayH; + width = width * zoom_ratio; + height = height * zoom_ratio; + + crop_left = std::round(left); + crop_top = std::round(top); + crop_width = std::round(width); + crop_height = std::round(height); boundToSize(crop_left, crop_top, crop_width, crop_height, mActiveArrayW, mActiveArrayH); @@ -152,12 +173,13 @@ void QCamera3CropRegionMapper::toActiveArray(int32_t& crop_left, int32_t& crop_t * @crop_top : y coordinate of top left corner of rectangle * @crop_width : width of rectangle * @crop_height : height of rectangle + * @zoom_ratio : zoom ratio to be applied to the input rectangles * * RETURN : none *==========================================================================*/ void QCamera3CropRegionMapper::toSensor(int32_t& crop_left, int32_t& crop_top, - int32_t& crop_width, int32_t& crop_height) + int32_t& crop_width, int32_t& crop_height, float zoom_ratio) { if (mSensorW == 0 || mSensorH == 0 || mActiveArrayW == 0 || mActiveArrayH == 0) { @@ -165,20 +187,94 @@ void QCamera3CropRegionMapper::toSensor(int32_t& crop_left, int32_t& crop_top, return; } - crop_left = crop_left * mSensorW / mActiveArrayW; - crop_top = crop_top * mSensorH / mActiveArrayH; - crop_width = crop_width * mSensorW / mActiveArrayW; - crop_height = crop_height * mSensorH / mActiveArrayH; + applyZoomRatioHelper(crop_left, crop_top, crop_width, crop_height, zoom_ratio, + true /*to_sensor*/); +} + +/*=========================================================================== + * FUNCTION : applyZoomRatioHelper + * + * DESCRIPTION: Apply zoom ratio to the crop region, and optionally map + * to sensor coordinate system + * + * PARAMETERS : + * @crop_left : x coordinate of top left corner of rectangle + * @crop_top : y coordinate of top left corner of rectangle + * @crop_width : width of rectangle + * @crop_height : height of rectangle + * @zoom_ratio : zoom ratio to be applied to the input rectangles + * @to_sensor : whether the crop region is to be mapped to sensor coordinate + * system + * + * RETURN : none + *==========================================================================*/ +void QCamera3CropRegionMapper::applyZoomRatioHelper(int32_t& crop_left, int32_t& crop_top, + int32_t& crop_width, int32_t& crop_height, float zoom_ratio, bool to_sensor) +{ + if (zoom_ratio < MIN_ZOOM_RATIO) { + LOGE("Invalid zoom ratio %f", zoom_ratio); + return; + } + + // Apply zoom_ratio to the input rectangle in activeArray space, so that + // crop rectangle already takes zoom_ratio into account (in other words, + // coordinate within the sensor native active array space). + float left = crop_left / zoom_ratio + + 0.5f * mActiveArrayW * (1.0f - 1.0f / zoom_ratio); + float top = crop_top / zoom_ratio + + 0.5f * mActiveArrayH * (1.0f - 1.0f / zoom_ratio); + float width = crop_width / zoom_ratio; + float height = crop_height / zoom_ratio; + + if (to_sensor) { + // Map to sensor space. + left = left * mSensorW / mActiveArrayW; + top = top * mSensorH / mActiveArrayH; + width = width * mSensorW / mActiveArrayW; + height = height * mSensorH / mActiveArrayH; + } + + crop_left = std::round(left); + crop_top = std::round(top); + crop_width = std::round(width); + crop_height = std::round(height); LOGD("before bounding left %d, top %d, width %d, height %d", crop_left, crop_top, crop_width, crop_height); boundToSize(crop_left, crop_top, crop_width, crop_height, - mSensorW, mSensorH); + to_sensor ? mSensorW : mActiveArrayW, + to_sensor ? mSensorH : mActiveArrayH); LOGD("after bounding left %d, top %d, width %d, height %d", crop_left, crop_top, crop_width, crop_height); } /*=========================================================================== + * FUNCTION : applyZoomRatio + * + * DESCRIPTION: Apply zoom ratio to the crop region + * + * PARAMETERS : + * @crop_left : x coordinate of top left corner of rectangle + * @crop_top : y coordinate of top left corner of rectangle + * @crop_width : width of rectangle + * @crop_height : height of rectangle + * @zoom_ratio : zoom ratio to be applied to the input rectangles + * + * RETURN : none + *==========================================================================*/ +void QCamera3CropRegionMapper::applyZoomRatio(int32_t& crop_left, int32_t& crop_top, + int32_t& crop_width, int32_t& crop_height, float zoom_ratio) +{ + if (mActiveArrayW == 0 || mActiveArrayH == 0) { + LOGE("active array sizes are not initialized!"); + return; + } + + applyZoomRatioHelper(crop_left, crop_top, crop_width, crop_height, zoom_ratio, + false /*to_sensor*/); +} + +/*=========================================================================== * FUNCTION : boundToSize * * DESCRIPTION: Bound a particular rectangle inside a bounding box @@ -199,9 +295,15 @@ void QCamera3CropRegionMapper::boundToSize(int32_t& left, int32_t& top, if (left < 0) { left = 0; } + if (left >= bound_w) { + left = bound_w - 1; + } if (top < 0) { top = 0; } + if (top >= bound_h) { + top = bound_h - 1; + } if ((left + width) > bound_w) { width = bound_w - left; @@ -219,10 +321,11 @@ void QCamera3CropRegionMapper::boundToSize(int32_t& left, int32_t& top, * PARAMETERS : * @x : x coordinate * @y : y coordinate + * @zoom_ratio : zoom ratio to be applied to the input coordinates * * RETURN : none *==========================================================================*/ -void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y) +void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y, float zoom_ratio) { if (mSensorW == 0 || mSensorH == 0 || mActiveArrayW == 0 || mActiveArrayH == 0) { @@ -235,8 +338,20 @@ void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y) x, y, mSensorW, mSensorH); return; } + if (zoom_ratio < MIN_ZOOM_RATIO) { + LOGE("Invalid zoom ratio %f", zoom_ratio); + return; + } + + // Map back to activeArray space x = x * mActiveArrayW / mSensorW; y = y * mActiveArrayH / mSensorH; + + // Revert zoom_ratio, so that now the crop rectangle is separate from + // zoom_ratio. The coordinate is within the active array space which covers + // the post-zoom FOV. + x = x * zoom_ratio - (zoom_ratio - 1) * 0.5f * mActiveArrayW; + y = y * zoom_ratio - (zoom_ratio - 1) * 0.5f * mActiveArrayH; } /*=========================================================================== @@ -247,24 +362,38 @@ void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y) * PARAMETERS : * @x : x coordinate * @y : y coordinate + * @zoom_ratio : zoom ratio to be applied to the input coordinates * * RETURN : none *==========================================================================*/ -void QCamera3CropRegionMapper::toSensor(uint32_t& x, uint32_t& y) +void QCamera3CropRegionMapper::toSensor(uint32_t& x, uint32_t& y, float zoom_ratio) { if (mSensorW == 0 || mSensorH == 0 || mActiveArrayW == 0 || mActiveArrayH == 0) { LOGE("sensor/active array sizes are not initialized!"); return; } - if ((x > static_cast<uint32_t>(mActiveArrayW)) || (y > static_cast<uint32_t>(mActiveArrayH))) { LOGE("invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space", x, y, mSensorW, mSensorH); return; } + if (zoom_ratio < MIN_ZOOM_RATIO) { + LOGE("Invalid zoom ratio %f", zoom_ratio); + return; + } + + // Apply zoom_ratio to the input coordinate in activeArray space, so that + // coordinate already takes zoom_ratio into account (in other words, + // coordinate within the sensor native active array space). + x = x / zoom_ratio + + 0.5f * mActiveArrayW * (1.0f - 1.0f / zoom_ratio); + y = y / zoom_ratio + + 0.5f * mActiveArrayH * (1.0f - 1.0f / zoom_ratio); + + // Map to sensor space. x = x * mSensorW / mActiveArrayW; y = y * mSensorH / mActiveArrayH; } diff --git a/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.h b/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.h index 31c8578..3dd831b 100644 --- a/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.h +++ b/msm8998/QCamera2/HAL3/QCamera3CropRegionMapper.h @@ -45,11 +45,17 @@ public: void update(uint32_t active_array_w, uint32_t active_array_h, uint32_t sensor_w, uint32_t sensor_h); void toActiveArray(int32_t& crop_left, int32_t& crop_top, - int32_t& crop_width, int32_t& crop_height); + int32_t& crop_width, int32_t& crop_height, float zoom_ratio); void toSensor(int32_t& crop_left, int32_t& crop_top, - int32_t& crop_width, int32_t& crop_height); - void toActiveArray(uint32_t& x, uint32_t& y); - void toSensor(uint32_t& x, uint32_t& y); + int32_t& crop_width, int32_t& crop_height, float zoom_ratio); + void toActiveArray(uint32_t& x, uint32_t& y, float zoom_ratio); + void toSensor(uint32_t& x, uint32_t& y, float zoom_ratio); + + // Adjust the crop rectangle to reflect zoom_ratio. For example, if + // zoom_ratio is 2.0, and crop region is active array size, this function + // will scale the crop region to be 2x zoomed. + void applyZoomRatio(int32_t& crop_left, int32_t& crop_top, + int32_t& crop_width, int32_t& crop_height, float zoom_ratio); private: /* sensor output size */ @@ -58,6 +64,11 @@ private: void boundToSize(int32_t& left, int32_t& top, int32_t& width, int32_t& height, int32_t bound_w, int32_t bound_h); + + static constexpr float MIN_ZOOM_RATIO = 0.0001f; + void applyZoomRatioHelper(int32_t& crop_left, int32_t& crop_top, + int32_t& crop_width, int32_t& crop_height, float zoom_ratio, + bool to_sensor); }; }; // namespace qcamera diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp index 4e58fcc..2b14f84 100644 --- a/msm8998/QCamera2/HAL3/QCamera3HWI.cpp +++ b/msm8998/QCamera2/HAL3/QCamera3HWI.cpp @@ -538,6 +538,7 @@ QCamera3HardwareInterface::QCamera3HardwareInterface(uint32_t cameraId, mLastRequestedLensShadingMapMode(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF), mLastRequestedFaceDetectMode(ANDROID_STATISTICS_FACE_DETECT_MODE_OFF), mLastRequestedOisDataMode(ANDROID_STATISTICS_OIS_DATA_MODE_OFF), + mLastRequestedZoomRatio(1.0f), mCurrFeatureState(0), mLdafCalibExist(false), mLastCustIntentFrmNum(-1), @@ -3883,7 +3884,7 @@ void QCamera3HardwareInterface::sendPartialMetadataWithLock( // Extract 3A metadata result.result = translateCbUrgentMetadataToResultMetadata( - metadata, lastUrgentMetadataInBatch, requestIter->frame_number, + metadata, lastUrgentMetadataInBatch, requestIter, isJumpstartMetadata); // Populate metadata result result.frame_number = requestIter->frame_number; @@ -4209,8 +4210,10 @@ void QCamera3HardwareInterface::handleMetadataWithLock( streamDim.width, streamDim.height); cam_eis_crop_info_t eisCrop = iter->crop_info; + //eisCrop already combines zoom_ratio, no + //need to apply it again. mStreamCropMapper.toSensor(eisCrop.delta_x, eisCrop.delta_y, - eisCrop.delta_width, eisCrop.delta_height); + eisCrop.delta_width, eisCrop.delta_height, 1.0f); int32_t crop[4] = { crop_data->crop_info[j].crop.left + eisCrop.delta_x, @@ -4332,11 +4335,12 @@ void QCamera3HardwareInterface::handleDepthDataLocked( } camera3_stream_buffer_t resultBuffer = - {.acquire_fence = -1, - .release_fence = -1, - .status = CAMERA3_BUFFER_STATUS_OK, + {.stream = mDepthChannel->getStream(), .buffer = nullptr, - .stream = mDepthChannel->getStream()}; + .status = CAMERA3_BUFFER_STATUS_OK, + .acquire_fence = -1, + .release_fence = -1, + }; do { depthBuffer = mDepthChannel->getOldestFrame(currentFrameNumber); if (nullptr == depthBuffer) { @@ -4396,11 +4400,11 @@ void QCamera3HardwareInterface::notifyErrorFoPendingDepthData( {.type = CAMERA3_MSG_ERROR, {{0, depthCh->getStream(), CAMERA3_MSG_ERROR_BUFFER}}}; camera3_stream_buffer_t resultBuffer = - {.acquire_fence = -1, - .release_fence = -1, + {.stream = depthCh->getStream(), .buffer = nullptr, - .stream = depthCh->getStream(), - .status = CAMERA3_BUFFER_STATUS_ERROR}; + .status = CAMERA3_BUFFER_STATUS_ERROR, + .acquire_fence = -1, + .release_fence = -1,}; while (nullptr != (depthBuffer = depthCh->getOldestFrame(currentFrameNumber))) { @@ -4588,6 +4592,15 @@ void QCamera3HardwareInterface::handleBufferWithLock( LOGH("result frame_number = %d, buffer = %p", frame_number, buffer->buffer); + if (buffer->status == CAMERA3_BUFFER_STATUS_ERROR) { + camera3_notify_msg_t notify_msg = {}; + notify_msg.type = CAMERA3_MSG_ERROR; + notify_msg.message.error.frame_number = frame_number; + notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER ; + notify_msg.message.error.error_stream = buffer->stream; + orchestrateNotify(¬ify_msg); + } + mPendingBuffersMap.removeBuf(buffer->buffer); mOutputBufferDispatcher.markBufferReady(frame_number, *buffer); @@ -5799,6 +5812,7 @@ no_error: pendingRequest.requestedLensShadingMapMode = requestedLensShadingMapMode; pendingRequest.requestedFaceDetectMode = mLastRequestedFaceDetectMode; pendingRequest.requestedOisDataMode = mLastRequestedOisDataMode; + pendingRequest.zoomRatio = mLastRequestedZoomRatio; if (request->input_buffer) { pendingRequest.input_buffer = (camera3_stream_buffer_t*)malloc(sizeof(camera3_stream_buffer_t)); @@ -5874,11 +5888,13 @@ no_error: ALOGD("%s: frame number %u is an HDR+ request.", __FUNCTION__, frameNumber); } + buffer_handle_t *depth_buffer = nullptr; for (size_t i = 0; i < request->num_output_buffers; i++) { if ((request->output_buffers[i].stream->data_space == HAL_DATASPACE_DEPTH) && (HAL_PIXEL_FORMAT_BLOB == request->output_buffers[i].stream->format)) { + depth_buffer = request->output_buffers[i].buffer; continue; } RequestedBufferInfo requestedBuf; @@ -5915,6 +5931,23 @@ no_error: if(mFlush) { LOGI("mFlush is true"); + + // If depth buffer is requested, return an error depth buffer. The buffer is not + // going to be added to the depth channel so it won't be returned in + // notifyErrorFoPendingDepthData(). + if (depth_buffer != nullptr) { + camera3_stream_buffer_t errorBuffer = + { + .stream = mDepthChannel->getStream(), + .buffer = depth_buffer, + .status = CAMERA3_BUFFER_STATUS_ERROR, + .acquire_fence = -1, + .release_fence = -1, + }; + + mOutputBufferDispatcher.markBufferReady(frameNumber, errorBuffer); + } + pthread_mutex_unlock(&mMutex); return NO_ERROR; } @@ -7384,6 +7417,24 @@ QCamera3HardwareInterface::translateFromHalMetadata( camMetadata.update(ANDROID_SYNC_FRAME_NUMBER, &fwk_frame_number, 1); } + IF_META_AVAILABLE(cam_crop_region_t, hScalerCropRegion, + CAM_INTF_META_SCALER_CROP_REGION, metadata) { + int32_t scalerCropRegion[4]; + scalerCropRegion[0] = hScalerCropRegion->left; + scalerCropRegion[1] = hScalerCropRegion->top; + scalerCropRegion[2] = hScalerCropRegion->width; + scalerCropRegion[3] = hScalerCropRegion->height; + + // Adjust crop region from sensor output coordinate system to active + // array coordinate system. + mCropRegionMapper.toActiveArray(scalerCropRegion[0], scalerCropRegion[1], + scalerCropRegion[2], scalerCropRegion[3], pendingRequest.zoomRatio); + + camMetadata.update(ANDROID_SCALER_CROP_REGION, scalerCropRegion, 4); + } + + camMetadata.update(ANDROID_CONTROL_ZOOM_RATIO, &pendingRequest.zoomRatio, 1); + IF_META_AVAILABLE(cam_fps_range_t, float_range, CAM_INTF_PARM_FPS_RANGE, metadata) { int32_t fps_range[2]; fps_range[0] = (int32_t)float_range->min_fps; @@ -7538,24 +7589,9 @@ QCamera3HardwareInterface::translateFromHalMetadata( CAM_INTF_META_EIS_CROP_INFO, metadata) { mLastEISCropInfo = *eisCropInfo; + //mLastEISCropInfo contains combined zoom_ratio. mCropRegionMapper.toActiveArray(mLastEISCropInfo.delta_x, mLastEISCropInfo.delta_y, - mLastEISCropInfo.delta_width, mLastEISCropInfo.delta_height); - } - - IF_META_AVAILABLE(cam_crop_region_t, hScalerCropRegion, - CAM_INTF_META_SCALER_CROP_REGION, metadata) { - int32_t scalerCropRegion[4]; - scalerCropRegion[0] = hScalerCropRegion->left; - scalerCropRegion[1] = hScalerCropRegion->top; - scalerCropRegion[2] = hScalerCropRegion->width; - scalerCropRegion[3] = hScalerCropRegion->height; - - // Adjust crop region from sensor output coordinate system to active - // array coordinate system. - mCropRegionMapper.toActiveArray(scalerCropRegion[0], scalerCropRegion[1], - scalerCropRegion[2], scalerCropRegion[3]); - - camMetadata.update(ANDROID_SCALER_CROP_REGION, scalerCropRegion, 4); + mLastEISCropInfo.delta_width, mLastEISCropInfo.delta_height, 1.0f/*zoom_ratio*/); } IF_META_AVAILABLE(int64_t, sensorExpTime, CAM_INTF_META_SENSOR_EXPOSURE_TIME, metadata) { @@ -7639,7 +7675,7 @@ QCamera3HardwareInterface::translateFromHalMetadata( // array coordinate system. cam_rect_t rect = faceDetectionInfo->faces[i].face_boundary; mCropRegionMapper.toActiveArray(rect.left, rect.top, - rect.width, rect.height); + rect.width, rect.height, pendingRequest.zoomRatio); convertToRegions(rect, faceRectangles+j, -1); @@ -7673,13 +7709,16 @@ QCamera3HardwareInterface::translateFromHalMetadata( // array coordinate system. mCropRegionMapper.toActiveArray( face_landmarks.left_eye_center.x, - face_landmarks.left_eye_center.y); + face_landmarks.left_eye_center.y, + pendingRequest.zoomRatio); mCropRegionMapper.toActiveArray( face_landmarks.right_eye_center.x, - face_landmarks.right_eye_center.y); + face_landmarks.right_eye_center.y, + pendingRequest.zoomRatio); mCropRegionMapper.toActiveArray( face_landmarks.mouth_center.x, - face_landmarks.mouth_center.y); + face_landmarks.mouth_center.y, + pendingRequest.zoomRatio); convertLandmarks(face_landmarks, faceLandmarks+k); @@ -8114,7 +8153,7 @@ QCamera3HardwareInterface::translateFromHalMetadata( // array coordinate system. cam_rect_t hAeRect = hAeRegions->rect; mCropRegionMapper.toActiveArray(hAeRect.left, hAeRect.top, - hAeRect.width, hAeRect.height); + hAeRect.width, hAeRect.height, pendingRequest.zoomRatio); convertToRegions(hAeRect, aeRegions, hAeRegions->weight); camMetadata.update(ANDROID_CONTROL_AE_REGIONS, aeRegions, @@ -8697,7 +8736,7 @@ mm_jpeg_exif_params_t QCamera3HardwareInterface::get3AExifParams() * @lastUrgentMetadataInBatch: Boolean to indicate whether this is the last * urgent metadata in a batch. Always true for * non-batch mode. - * @frame_number : frame number for this urgent metadata + * @requestIter: Pending request iterator * @isJumpstartMetadata: Whether this is a partial metadata for jumpstart, * i.e. even though it doesn't map to a valid partial * frame number, its metadata entries should be kept. @@ -8707,10 +8746,11 @@ mm_jpeg_exif_params_t QCamera3HardwareInterface::get3AExifParams() camera_metadata_t* QCamera3HardwareInterface::translateCbUrgentMetadataToResultMetadata (metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch, - uint32_t frame_number, bool isJumpstartMetadata) + const pendingRequestIterator requestIter, bool isJumpstartMetadata) { CameraMetadata camMetadata; camera_metadata_t *resultMetadata; + uint32_t frame_number = requestIter->frame_number; if (!lastUrgentMetadataInBatch && !isJumpstartMetadata) { /* In batch mode, use empty metadata if this is not the last in batch @@ -8796,7 +8836,7 @@ QCamera3HardwareInterface::translateCbUrgentMetadataToResultMetadata // Adjust crop region from sensor output coordinate system to active // array coordinate system. mCropRegionMapper.toActiveArray(hAfRect.left, hAfRect.top, - hAfRect.width, hAfRect.height); + hAfRect.width, hAfRect.height, requestIter->zoomRatio); convertToRegions(hAfRect, afRegions, hAfRegions->weight); camMetadata.update(ANDROID_CONTROL_AF_REGIONS, afRegions, @@ -10104,6 +10144,10 @@ int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId) staticInfo.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1); + float zoomRatioRange[] = {1.0f, maxZoom}; + staticInfo.update(ANDROID_CONTROL_ZOOM_RATIO_RANGE, zoomRatioRange, 2); + gCamCapability[cameraId]->max_zoom = maxZoom; + uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY; staticInfo.update(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1); @@ -10884,6 +10928,7 @@ int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId) ANDROID_SENSOR_SENSITIVITY, ANDROID_SHADING_MODE, #ifndef USE_HAL_3_3 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, + ANDROID_CONTROL_ZOOM_RATIO, #endif ANDROID_STATISTICS_FACE_DETECT_MODE, ANDROID_STATISTICS_SHARPNESS_MAP_MODE, ANDROID_STATISTICS_OIS_DATA_MODE, @@ -10964,6 +11009,7 @@ int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId) ANDROID_STATISTICS_OIS_Y_SHIFTS, #ifndef USE_HAL_3_3 ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, + ANDROID_CONTROL_ZOOM_RATIO, #endif NEXUS_EXPERIMENTAL_2016_HYBRID_AE_ENABLE, NEXUS_EXPERIMENTAL_2016_AF_SCENE_CHANGE, @@ -11163,6 +11209,7 @@ int QCamera3HardwareInterface::initStaticMetadata(uint32_t cameraId) #ifndef USE_HAL_3_3 ANDROID_SENSOR_OPAQUE_RAW_SIZE, ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE, + ANDROID_CONTROL_ZOOM_RATIO_RANGE, #endif ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS, ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP, @@ -12193,6 +12240,9 @@ camera_metadata_t* QCamera3HardwareInterface::translateCapabilityToMetadata(int scaler_crop_region[3] = gCamCapability[mCameraId]->active_array_size.height; settings.update(ANDROID_SCALER_CROP_REGION, scaler_crop_region, 4); + float zoom_ratio = 1.0f; + settings.update(ANDROID_CONTROL_ZOOM_RATIO, &zoom_ratio, 1); + static const uint8_t antibanding_mode = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &antibanding_mode, 1); @@ -13427,9 +13477,16 @@ int QCamera3HardwareInterface::translateFwkMetadataToHalMetadata( scalerCropRegion.width = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[2]; scalerCropRegion.height = frame_settings.find(ANDROID_SCALER_CROP_REGION).data.i32[3]; + if (frame_settings.exists(ANDROID_CONTROL_ZOOM_RATIO)) { + mLastRequestedZoomRatio = frame_settings.find(ANDROID_CONTROL_ZOOM_RATIO).data.f[0]; + mLastRequestedZoomRatio = MIN(MAX(mLastRequestedZoomRatio, 1.0f), + gCamCapability[mCameraId]->max_zoom); + LOGD("setting zoomRatio %f", mLastRequestedZoomRatio); + } + // Map coordinate system from active array to sensor output. mCropRegionMapper.toSensor(scalerCropRegion.left, scalerCropRegion.top, - scalerCropRegion.width, scalerCropRegion.height); + scalerCropRegion.width, scalerCropRegion.height, mLastRequestedZoomRatio); if (ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_SCALER_CROP_REGION, scalerCropRegion)) { @@ -13633,11 +13690,12 @@ int QCamera3HardwareInterface::translateFwkMetadataToHalMetadata( // Map coordinate system from active array to sensor output. mCropRegionMapper.toSensor(roi.rect.left, roi.rect.top, roi.rect.width, - roi.rect.height); + roi.rect.height, mLastRequestedZoomRatio); if (scalerCropSet) { reset = resetIfNeededROI(&roi, &scalerCropRegion); } + if (reset && ADD_SET_PARAM_ENTRY_TO_BATCH(hal_metadata, CAM_INTF_META_AEC_ROI, roi)) { rc = BAD_VALUE; } @@ -13650,7 +13708,7 @@ int QCamera3HardwareInterface::translateFwkMetadataToHalMetadata( // Map coordinate system from active array to sensor output. mCropRegionMapper.toSensor(roi.rect.left, roi.rect.top, roi.rect.width, - roi.rect.height); + roi.rect.height, mLastRequestedZoomRatio); if (scalerCropSet) { reset = resetIfNeededROI(&roi, &scalerCropRegion); @@ -15167,8 +15225,11 @@ int32_t QCamera3HardwareInterface::notifyErrorForPendingRequests() pendingBuffer = mPendingBuffersMap.mPendingBuffersInRequest.erase(pendingBuffer); } else if (pendingBuffer == mPendingBuffersMap.mPendingBuffersInRequest.end() || ((pendingRequest != mPendingRequestsList.end()) && - (pendingBuffer->frame_number > pendingRequest->frame_number))) { - // If the buffers for this frame were sent already, notify about a result error. + (pendingBuffer->frame_number > pendingRequest->frame_number || + (pendingBuffer->frame_number == pendingRequest->frame_number && + pendingBuffer->mPendingBufferList.size() < pendingRequest->num_buffers)))) { + // If some or all buffers for this frame were sent already, notify about a result error, + // as well as remaining buffer errors. camera3_notify_msg_t notify_msg; memset(¬ify_msg, 0, sizeof(camera3_notify_msg_t)); notify_msg.type = CAMERA3_MSG_ERROR; @@ -15185,20 +15246,41 @@ int32_t QCamera3HardwareInterface::notifyErrorForPendingRequests() orchestrateResult(&result); } + if (pendingBuffer != mPendingBuffersMap.mPendingBuffersInRequest.end() && + pendingBuffer->frame_number == pendingRequest->frame_number) { + for (const auto &info : pendingBuffer->mPendingBufferList) { + // Send a buffer error for this frame number. + camera3_notify_msg_t notify_msg; + memset(¬ify_msg, 0, sizeof(camera3_notify_msg_t)); + notify_msg.type = CAMERA3_MSG_ERROR; + notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_BUFFER; + notify_msg.message.error.error_stream = info.stream; + notify_msg.message.error.frame_number = pendingBuffer->frame_number; + orchestrateNotify(¬ify_msg); + + camera3_stream_buffer_t buffer = {}; + buffer.acquire_fence = -1; + buffer.release_fence = -1; + buffer.buffer = info.buffer; + buffer.status = CAMERA3_BUFFER_STATUS_ERROR; + buffer.stream = info.stream; + mOutputBufferDispatcher.markBufferReady(pendingBuffer->frame_number, buffer); + } + pendingBuffer = mPendingBuffersMap.mPendingBuffersInRequest.erase(pendingBuffer); + } mShutterDispatcher.clear(pendingRequest->frame_number); pendingRequest = mPendingRequestsList.erase(pendingRequest); } else { // If both buffers and result metadata weren't sent yet, notify about a request error // and return buffers with error. - for (auto &info : pendingBuffer->mPendingBufferList) { - camera3_notify_msg_t notify_msg; - memset(¬ify_msg, 0, sizeof(camera3_notify_msg_t)); - notify_msg.type = CAMERA3_MSG_ERROR; - notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST; - notify_msg.message.error.error_stream = info.stream; - notify_msg.message.error.frame_number = pendingBuffer->frame_number; - orchestrateNotify(¬ify_msg); + camera3_notify_msg_t notify_msg; + memset(¬ify_msg, 0, sizeof(camera3_notify_msg_t)); + notify_msg.type = CAMERA3_MSG_ERROR; + notify_msg.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST; + notify_msg.message.error.frame_number = pendingBuffer->frame_number; + orchestrateNotify(¬ify_msg); + for (auto &info : pendingBuffer->mPendingBufferList) { camera3_stream_buffer_t buffer = {}; buffer.acquire_fence = -1; buffer.release_fence = -1; @@ -15892,11 +15974,29 @@ bool QCamera3HardwareInterface::trySubmittingHdrPlusRequestLocked( hdrPlusRequest->frameworkOutputBuffers.emplace(pbStreamId, request.output_buffers[i]); } + float zoomRatio = 1.0f; + camera_metadata_ro_entry zoomRatioEntry = metadata.find(ANDROID_CONTROL_ZOOM_RATIO); + if (zoomRatioEntry.count == 1) { + zoomRatio = MIN(MAX(zoomRatioEntry.data.f[0], 1.0f), gCamCapability[mCameraId]->max_zoom); + } + + // Capture requests should not be modified. + CameraMetadata updatedMetadata(metadata); + camera_metadata_entry entry = updatedMetadata.find(ANDROID_SCALER_CROP_REGION); if (isEISCropInSnapshotNeeded(metadata)) { int32_t scalerRegion[4] = {0, 0, gCamCapability[mCameraId]->active_array_size.width, gCamCapability[mCameraId]->active_array_size.height}; - if (metadata.exists(ANDROID_SCALER_CROP_REGION)) { + if (entry.count == 4) { auto currentScalerRegion = metadata.find(ANDROID_SCALER_CROP_REGION).data.i32; + scalerRegion[0] = currentScalerRegion[0]; + scalerRegion[1] = currentScalerRegion[1]; + scalerRegion[2] = currentScalerRegion[2]; + scalerRegion[3] = currentScalerRegion[3]; + + // Apply zoom ratio to generate new crop region + mCropRegionMapper.applyZoomRatio(scalerRegion[0], scalerRegion[1], + scalerRegion[2], scalerRegion[3], zoomRatio); + scalerRegion[0] = currentScalerRegion[0] + mLastEISCropInfo.delta_x; scalerRegion[1] = currentScalerRegion[1] + mLastEISCropInfo.delta_y; scalerRegion[2] = currentScalerRegion[2] - mLastEISCropInfo.delta_width; @@ -15908,8 +16008,6 @@ bool QCamera3HardwareInterface::trySubmittingHdrPlusRequestLocked( scalerRegion[3] -= mLastEISCropInfo.delta_height; } - // Capture requests should not be modified. - CameraMetadata updatedMetadata(metadata); if (isCropValid(scalerRegion[0], scalerRegion[1], scalerRegion[2], scalerRegion[3], gCamCapability[mCameraId]->active_array_size.width, gCamCapability[mCameraId]->active_array_size.height)) { @@ -15917,11 +16015,13 @@ bool QCamera3HardwareInterface::trySubmittingHdrPlusRequestLocked( } else { LOGE("Invalid EIS compensated crop region"); } - - res = gHdrPlusClient->submitCaptureRequest(&pbRequest, updatedMetadata); } else { - res = gHdrPlusClient->submitCaptureRequest(&pbRequest, metadata); + if (entry.count == 4) { + mCropRegionMapper.applyZoomRatio(entry.data.i32[0], entry.data.i32[1], + entry.data.i32[2], entry.data.i32[3], zoomRatio); + } } + res = gHdrPlusClient->submitCaptureRequest(&pbRequest, updatedMetadata); if (res != OK) { ALOGE("%s: %d: Submitting a capture request failed: %s (%d)", __FUNCTION__, __LINE__, diff --git a/msm8998/QCamera2/HAL3/QCamera3HWI.h b/msm8998/QCamera2/HAL3/QCamera3HWI.h index c5c59fe..f46fa83 100644 --- a/msm8998/QCamera2/HAL3/QCamera3HWI.h +++ b/msm8998/QCamera2/HAL3/QCamera3HWI.h @@ -320,9 +320,6 @@ public: metadata_buffer_t *parm, uint32_t snapshotStreamId); int translateFwkMetadataToHalMetadata(const camera_metadata_t *frameworkMetadata, metadata_buffer_t *hal_metadata, uint32_t snapshotStreamId, int64_t minFrameDuration); - camera_metadata_t* translateCbUrgentMetadataToResultMetadata ( - metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch, - uint32_t frame_number, bool isJumpstartMetadata); camera_metadata_t* saveRequestSettings(const CameraMetadata& jpegMetadata, camera3_capture_request_t *request); int initParameters(); @@ -648,6 +645,7 @@ private: uint8_t requestedFaceDetectMode; // Face detect mode for this request. bool partialResultDropped; // Whether partial metadata is dropped. uint8_t requestedOisDataMode; // OIS data mode for this request. + float zoomRatio; } PendingRequestInfo; typedef struct { uint32_t frame_number; @@ -741,6 +739,8 @@ private: uint8_t mLastRequestedFaceDetectMode; // Last OIS data mode framework requested. uint8_t mLastRequestedOisDataMode; + // Last zoom ratio framework requested + float mLastRequestedZoomRatio; cam_feature_mask_t mCurrFeatureState; /* Ldaf calibration data */ @@ -814,6 +814,9 @@ private: bool pprocDone, bool lastMetadataInBatch, const bool *enableZsl); + camera_metadata_t* translateCbUrgentMetadataToResultMetadata ( + metadata_buffer_t *metadata, bool lastUrgentMetadataInBatch, + const pendingRequestIterator requestIter, bool isJumpstartMetadata); State mState; //Dual camera related params 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 @@ int32_t QCamera3PostProcessor::processPPData(mm_camera_super_buf_t *frame) // 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 @@ void QCamera3PostProcessor::releaseJpegJobData(qcamera_hal3_jpeg_data_t *job) } 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 @@ typedef struct { 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 @@ public: 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); diff --git a/msm8998/QCamera2/QCamera2Hal.cpp b/msm8998/QCamera2/QCamera2Hal.cpp index daf6b0a..06ee2a1 100644 --- a/msm8998/QCamera2/QCamera2Hal.cpp +++ b/msm8998/QCamera2/QCamera2Hal.cpp @@ -46,13 +46,13 @@ static hw_module_t camera_common = { camera_module_t HAL_MODULE_INFO_SYM = { .common = camera_common, .get_number_of_cameras = qcamera::QCamera2Factory::get_number_of_cameras, - .get_physical_camera_info = qcamera::QCamera2Factory::get_physical_camera_info, - .is_stream_combination_supported = qcamera::QCamera2Factory::is_stream_combination_supported, .get_camera_info = qcamera::QCamera2Factory::get_camera_info, .set_callbacks = qcamera::QCamera2Factory::set_callbacks, .get_vendor_tag_ops = qcamera::QCamera3VendorTags::get_vendor_tag_ops, .open_legacy = NULL, .set_torch_mode = qcamera::QCamera2Factory::set_torch_mode, .init = NULL, + .get_physical_camera_info = qcamera::QCamera2Factory::get_physical_camera_info, + .is_stream_combination_supported = qcamera::QCamera2Factory::is_stream_combination_supported, .reserved = {0} }; diff --git a/msm8998/QCamera2/stack/common/cam_intf.h b/msm8998/QCamera2/stack/common/cam_intf.h index 5117863..20602d3 100644 --- a/msm8998/QCamera2/stack/common/cam_intf.h +++ b/msm8998/QCamera2/stack/common/cam_intf.h @@ -658,6 +658,9 @@ typedef struct cam_capability{ /*White balance calibration data*/ cam_wb_calibration_t wb_cal; + /*Max zoom ratio*/ + float max_zoom; + } cam_capability_t; typedef enum { diff --git a/msm8998/QCamera2/util/QCameraPerf.cpp b/msm8998/QCamera2/util/QCameraPerf.cpp index d570e31..cb28a50 100644 --- a/msm8998/QCamera2/util/QCameraPerf.cpp +++ b/msm8998/QCamera2/util/QCameraPerf.cpp @@ -37,65 +37,80 @@ #include <stdlib.h> #include <dlfcn.h> #include <utils/Timers.h> + +#include <aidl/android/hardware/power/Boost.h> +#include <aidl/android/hardware/power/IPower.h> +#include <aidl/android/hardware/power/Mode.h> +#include <android/binder_manager.h> +#include <android-base/properties.h> + // Camera dependencies #include "QCameraPerf.h" #include "QCameraTrace.h" -#include <android-base/properties.h> - extern "C" { #include "mm_camera_dbg.h" } namespace qcamera { -using android::hidl::base::V1_0::IBase; -using android::hardware::hidl_death_recipient; +using aidl::android::hardware::power::Boost; +using aidl::android::hardware::power::Mode; +// Protect gPowerHal_1_2_ and gPowerHal_Aidl_ +static android::sp<android::hardware::power::V1_2::IPower> gPowerHal_1_2_ = nullptr; +static std::shared_ptr<aidl::android::hardware::power::IPower> gPowerHal_Aidl_ = nullptr; static std::mutex gPowerHalMutex; -static sp<IPower> gPowerHal = nullptr; -static void getPowerHalLocked(); - -// struct PowerHalDeathRecipient; -struct PowerHalDeathRecipient : virtual public hidl_death_recipient { - // hidl_death_recipient interface - virtual void serviceDied(uint64_t, const wp<IBase>&) override { - std::lock_guard<std::mutex> lock(gPowerHalMutex); - ALOGE("PowerHAL just died"); - gPowerHal = nullptr; - getPowerHalLocked(); - } +static const std::string kInstance = + std::string() + aidl::android::hardware::power::IPower::descriptor + "/default"; + +namespace { + constexpr int kDefaultBoostDurationMs = 1000; + constexpr int kDisableBoostDurationMs = -1; +} + +enum hal_version { + NONE, + HIDL_1_2, + AIDL, }; -sp<PowerHalDeathRecipient> gPowerHalDeathRecipient = nullptr; +// Connnect PowerHAL +static hal_version connectPowerHalLocked() { + static bool gPowerHalHidlExists = true; + static bool gPowerHalAidlExists = true; -// The caller must be holding gPowerHalMutex. -static void getPowerHalLocked() { - if (gPowerHal != nullptr) { - return; + if (!gPowerHalHidlExists && !gPowerHalAidlExists) { + return NONE; } - gPowerHal = IPower::getService(); + if (gPowerHalHidlExists) { + if (!gPowerHal_1_2_) { + gPowerHal_1_2_ = + android::hardware::power::V1_2::IPower::getService(); + } + if (gPowerHal_1_2_) { + ALOGV("Successfully connected to Power Hal Hidl service."); + return HIDL_1_2; + } else { + gPowerHalHidlExists = false; + } + } - if (gPowerHal == nullptr) { - ALOGE("Unable to get Power service."); - } else { - if (gPowerHalDeathRecipient == nullptr) { - gPowerHalDeathRecipient = new PowerHalDeathRecipient(); + if (gPowerHalAidlExists) { + if (!gPowerHal_Aidl_) { + ndk::SpAIBinder pwBinder = ndk::SpAIBinder(AServiceManager_getService(kInstance.c_str())); + gPowerHal_Aidl_ = aidl::android::hardware::power::IPower::fromBinder(pwBinder); } - hardware::Return<bool> linked = gPowerHal->linkToDeath( - gPowerHalDeathRecipient, 0x451F /* cookie */); - if (!linked.isOk()) { - ALOGE("Transaction error in linking to PowerHAL death: %s", - linked.description().c_str()); - gPowerHal = nullptr; - } else if (!linked) { - ALOGW("Unable to link to PowerHal death notifications"); - gPowerHal = nullptr; + if (gPowerHal_Aidl_) { + ALOGV("Successfully connected to Power Hal Aidl service."); + return AIDL; } else { - ALOGD("Link to death notification successful"); + gPowerHalAidlExists = false; } } + + return NONE; } typedef enum { @@ -637,12 +652,12 @@ QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton() if (mInstance) { #ifdef HAS_MULTIMEDIA_HINTS std::lock_guard<std::mutex> lock(gPowerHalMutex); - getPowerHalLocked(); - if (gPowerHal == nullptr) { + if (connectPowerHalLocked() == NONE) { ALOGE("Couldn't load PowerHAL module"); + } else { + error = false; } - else - #endif + #else { /* Retrieve the name of the vendor extension library */ void *dlHandle = NULL; @@ -671,6 +686,7 @@ QCameraPerfLockIntf* QCameraPerfLockIntf::createSingleton() LOGE("Unable to load lib: %s", value); } } + #endif if (error && mInstance) { delete mInstance; mInstance = NULL; @@ -727,16 +743,41 @@ QCameraPerfLockIntf::~QCameraPerfLockIntf() bool QCameraPerfLockIntf::powerHint(PowerHint hint, int32_t data) { std::lock_guard<std::mutex> lock(gPowerHalMutex); - getPowerHalLocked(); - if (gPowerHal == nullptr) { - ALOGE("Couldn't do powerHint because of HAL error."); - return false; - } - auto ret = gPowerHal->powerHintAsync_1_2(hint, data); - if (!ret.isOk()) { - ALOGE("powerHint failed error: %s", ret.description().c_str()); + switch(connectPowerHalLocked()) { + case NONE: + return false; + case HIDL_1_2: + { + auto ret = gPowerHal_1_2_->powerHintAsync_1_2(hint, data); + if (!ret.isOk()) { + ALOGE("powerHint failed, error: %s", + ret.description().c_str()); + gPowerHal_1_2_ = nullptr; + } + return ret.isOk(); + } + case AIDL: + { + bool ret = false; + if (hint == PowerHint::CAMERA_LAUNCH) { + int32_t durationMs = data ? kDefaultBoostDurationMs : kDisableBoostDurationMs; + ret = gPowerHal_Aidl_->setBoost(Boost::CAMERA_LAUNCH, durationMs).isOk(); + } else if (hint == PowerHint::CAMERA_SHOT) { + ret = gPowerHal_Aidl_->setBoost(Boost::CAMERA_SHOT, data).isOk(); + } else if (hint == PowerHint::CAMERA_STREAMING) { + // Only CAMERA_STREAMING_MID is used + ret = gPowerHal_Aidl_->setMode(Mode::CAMERA_STREAMING_MID, static_cast<bool>(data)).isOk(); + } + if (!ret) { + ALOGE("Failed to set power hint: %s.", toString(hint).c_str()); + gPowerHal_Aidl_ = nullptr; + } + return ret; + } + default: + ALOGE("Unknown HAL state"); + return false; } - return ret.isOk(); } }; // namespace qcamera |