camera: intel: ipu6: Bypass still tnr when total gain < threshold
Read the threshold gain in xml
skip the extra frame request from psysprocessor
bypass the tnr7us process in GPUExecutor
BUG=b:149068439, b:149068672
TEST=Full tested pass for camera functions.
Change-Id: I8fabbfbec26fa92e1d1e2e3f91d494c5a974c97b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2594540
Tested-by: Zong Li <zong.li@intel.com>
Reviewed-by: Ren-Pei Zeng <kamesan@chromium.org>
Commit-Queue: Ren-Pei Zeng <kamesan@chromium.org>
diff --git a/camera/hal/intel/ipu6/src/core/PSysProcessor.cpp b/camera/hal/intel/ipu6/src/core/PSysProcessor.cpp
index 6bc03b7..b317173 100644
--- a/camera/hal/intel/ipu6/src/core/PSysProcessor.cpp
+++ b/camera/hal/intel/ipu6/src/core/PSysProcessor.cpp
@@ -793,7 +793,8 @@
LOG2("@%s, seq %ld, hold raw %d, last still seq %ld, still %d", __func__, sequence,
mHoldRawBuffers, mLastStillTnrSequence, hasStill);
- if (hasStill && sequence != (mLastStillTnrSequence + 1) && mHoldRawBuffers) {
+ bool bypass = mPSysDAGs[mCurConfigMode]->isBypassStillTnr(sequence);
+ if (!bypass && hasStill && sequence != (mLastStillTnrSequence + 1) && mHoldRawBuffers) {
CameraBufferPortMap fakeTaskBuffers = *dstBuffers;
for (const auto& item : fakeTaskBuffers) {
if (item.second && item.second->getStreamUsage() != CAMERA_STREAM_STILL_CAPTURE) {
diff --git a/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.cpp b/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.cpp
index 14ff2c5..b65e1b3 100644
--- a/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.cpp
+++ b/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.cpp
@@ -55,6 +55,7 @@
mLastSequence(UINT32_MAX),
mUseInternalTnrBuffer(useTnrOutBuffer),
mOutBufferSize(0) {
+ mStillTnrTG = PlatformData::getTnrThresholdGain(mCameraId);
LOG1("@%s %s", __func__, mName.c_str());
}
@@ -225,6 +226,27 @@
return false;
}
+int GPUExecutor::getTotalGain(int64_t seq, float* totalGain) {
+ CheckError(!totalGain, UNKNOWN_ERROR, "Invalid input");
+ AiqResult* aiqResults =
+ const_cast<AiqResult*>(AiqResultStorage::getInstance(mCameraId)->getAiqResult(seq));
+ CheckError(!aiqResults, UNKNOWN_ERROR, "Cannot find available aiq result.");
+
+ *totalGain = (aiqResults->mAeResults.exposures[0].exposure->analog_gain *
+ aiqResults->mAeResults.exposures[0].exposure->digital_gain);
+ return OK;
+}
+
+bool GPUExecutor::isBypassStillTnr(int64_t seq) {
+ if (mStreamId != STILL_STREAM_ID) return false;
+
+ float totalGain = 0.0f;
+ int ret = getTotalGain(seq, &totalGain);
+ CheckError(ret, true, "@%s, Failed to get total gain", __func__);
+ if (totalGain <= mStillTnrTG) return true;
+ return false;
+}
+
int GPUExecutor::allocTnrOutBufs(uint32_t bufSize) {
mOutBufferSize = bufSize;
@@ -446,7 +468,7 @@
uint32_t sequence = inBuf->getSequence();
int ret = OK;
- if (mIntelTNR) {
+ if (mIntelTNR && !isBypassStillTnr(sequence)) {
ret = updateTnrISPConfig(mTnr7usParam, sequence);
CheckError(ret != OK, UNKNOWN_ERROR, " %s Failed to update TNR parameters", __func__);
}
@@ -459,7 +481,7 @@
: outBuf->getBufferAddr();
if (!outPtr) return UNKNOWN_ERROR;
- if (!mIntelTNR) {
+ if (!mIntelTNR || isBypassStillTnr(sequence)) {
MEMCPY_S(outPtr, bufferSize, inBuf->getBufferAddr(), inBuf->getBufferSize());
if (memoryType == V4L2_MEMORY_DMABUF) {
CameraBuffer::unmapDmaBufferAddr(outPtr, bufferSize);
@@ -534,21 +556,13 @@
if (mStreamId != STILL_STREAM_ID) {
// still stream will update params in tnr7us, skip async update
- AiqResult* aiqResults = const_cast<AiqResult*>(
- AiqResultStorage::getInstance(mCameraId)->getAiqResult(sequence));
- if (aiqResults == nullptr) {
- LOGW("%s: no result for sequence %ld! use the latest instead", __func__, sequence);
- aiqResults =
- const_cast<AiqResult*>(AiqResultStorage::getInstance(mCameraId)->getAiqResult());
- CheckError((aiqResults == nullptr), UNKNOWN_ERROR, "Cannot find available aiq result.");
- }
+ float totalGain = 0.0f;
+ ret = getTotalGain(sequence, &totalGain);
+ CheckError(ret, UNKNOWN_ERROR, "@%s, Failed to get total gain", __func__);
- int gain = static_cast<int>(aiqResults->mAeResults.exposures[0].exposure->analog_gain *
- aiqResults->mAeResults.exposures[0].exposure->digital_gain);
-
- // update tnr param when total gain changes, gain set to analog_gain * digital_gain.
+ // update tnr param when total gain changes
bool isTnrParamForceUpdate = icamera::PlatformData::isTnrParamForceUpdate();
- ret = mIntelTNR->asyncParamUpdate(gain, isTnrParamForceUpdate);
+ ret = mIntelTNR->asyncParamUpdate(static_cast<int>(totalGain), isTnrParamForceUpdate);
}
LOG2("Exit %s executor name:%s, sequence: %u", __func__, mName.c_str(), inBuf->getSequence());
diff --git a/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.h b/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.h
index d8a598d..4ad8781 100644
--- a/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.h
+++ b/camera/hal/intel/ipu6/src/core/psysprocessor/GPUExecutor.h
@@ -44,6 +44,7 @@
// fetch TNR reference buffer for user output, return true if found successfully
virtual bool fetchTnrOutBuffer(int64_t seq, std::shared_ptr<CameraBuffer> buf);
+ virtual bool isBypassStillTnr(int64_t seq);
private:
int createPGs();
@@ -53,6 +54,7 @@
int updateTnrISPConfig(Tnr7Param* pbuffer, uint32_t sequence);
int allocTnrOutBufs(uint32_t bufSize);
int dumpTnrParameters(uint32_t sequence);
+ int getTotalGain(int64_t seq, float *totalGain);
int runTnrFrame(const std::shared_ptr<CameraBuffer>& inBuf,
std::shared_ptr<CameraBuffer> outbuf);
@@ -65,6 +67,8 @@
* should require this lock. */
static std::mutex mGPULock;
int mOutBufferSize;
+ // threshold gain for still tnr, only run still tnr when gain > TG
+ float mStillTnrTG;
std::mutex mTnrOutBufMapLock; // used to guard mTnrOutBufMap
// first: sequence of source buffer, second: the reference buffer address
std::map<int64_t, void*> mTnrOutBufMap;
diff --git a/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.cpp b/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.cpp
index 4900490..e0d979d 100644
--- a/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.cpp
+++ b/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.cpp
@@ -35,6 +35,7 @@
#endif
mDefaultMainInputPort(MAIN_PORT),
mVideoTnrExecutor(nullptr),
+ mStillTnrExecutor(nullptr),
mRunAicAfterQbuf(false)
{
LOG1("@%s, mCameraId:%d", __func__, mCameraId);
@@ -142,6 +143,7 @@
executor = new GPUExecutor(mCameraId, item, cfg->exclusivePgs, this, gc,
useTnrOutBuffer);
if (streamId == VIDEO_STREAM_ID) mVideoTnrExecutor = executor;
+ else if (streamId == STILL_STREAM_ID) mStillTnrExecutor = executor;
} else {
executor = new PipeExecutor(mCameraId, item, cfg->exclusivePgs, this, gc);
}
@@ -200,6 +202,11 @@
return mVideoTnrExecutor != nullptr ? mVideoTnrExecutor->fetchTnrOutBuffer(seq, buf) : false;
}
+bool PSysDAG::isBypassStillTnr(int64_t seq)
+{
+ return mStillTnrExecutor != nullptr ? mStillTnrExecutor->isBypassStillTnr(seq) : true;
+}
+
int PSysDAG::linkAndConfigExecutors()
{
for (auto& consumer : mExecutorsPool) {
diff --git a/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.h b/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.h
index 2ce3b18..9c41eba 100644
--- a/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.h
+++ b/camera/hal/intel/ipu6/src/core/psysprocessor/PSysDAG.h
@@ -95,6 +95,7 @@
int prepareIpuParams(long sequence, bool forceUpdate = false, TaskInfo *task = nullptr);
bool fetchTnrOutBuffer(int64_t seq, std::shared_ptr<CameraBuffer> buf);
+ bool isBypassStillTnr(int64_t seq);
/**
* Use to handle the frame done event from the executors.
@@ -140,6 +141,7 @@
std::unordered_map<PipeExecutor*, int32_t> mExecutorStreamId;
std::map<Port, std::vector<int32_t> > mOutputPortToStreamIds;
PipeExecutor* mVideoTnrExecutor;
+ PipeExecutor* mStillTnrExecutor;
// A lock for protecting task data from being accessed by different threads.
Mutex mTaskLock;
diff --git a/camera/hal/intel/ipu6/src/core/psysprocessor/PipeLiteExecutor.h b/camera/hal/intel/ipu6/src/core/psysprocessor/PipeLiteExecutor.h
index 5122c3b..16452c6 100644
--- a/camera/hal/intel/ipu6/src/core/psysprocessor/PipeLiteExecutor.h
+++ b/camera/hal/intel/ipu6/src/core/psysprocessor/PipeLiteExecutor.h
@@ -49,6 +49,7 @@
void notifyStop();
virtual bool fetchTnrOutBuffer(int64_t seq, std::shared_ptr<CameraBuffer> buf) { return false; }
+ virtual bool isBypassStillTnr(int64_t seq) { return true; }
int releaseStatsBuffer(const std::shared_ptr<CameraBuffer> &statsBuf);
void setStreamId(int streamId) { mStreamId = streamId; }
diff --git a/camera/hal/intel/ipu6/src/platformdata/CameraParser.cpp b/camera/hal/intel/ipu6/src/platformdata/CameraParser.cpp
index 857a586..444555c 100644
--- a/camera/hal/intel/ipu6/src/platformdata/CameraParser.cpp
+++ b/camera/hal/intel/ipu6/src/platformdata/CameraParser.cpp
@@ -483,6 +483,9 @@
} else if (strcmp(name, "tnrExtraFrameNum") == 0) {
int val = atoi(atts[1]);
pCurrentCam->mTnrExtraFrameNum = val > 0 ? val : DEFAULT_TNR_EXTRA_FRAME_NUM;
+ } else if (strcmp(name, "tnrThresholdGain") == 0) {
+ float val = atof(atts[1]);
+ pCurrentCam->mTnrThresholdGain = val > 0 ? val : DEFAULT_TNR_THRESHOLD_GAIN;
}
}
diff --git a/camera/hal/intel/ipu6/src/platformdata/PlatformData.cpp b/camera/hal/intel/ipu6/src/platformdata/PlatformData.cpp
index 13ecb1f..d534f12 100644
--- a/camera/hal/intel/ipu6/src/platformdata/PlatformData.cpp
+++ b/camera/hal/intel/ipu6/src/platformdata/PlatformData.cpp
@@ -1394,4 +1394,9 @@
{
return getInstance()->mStaticCfg.mCameras[cameraId].mTnrExtraFrameNum;
}
+
+float PlatformData::getTnrThresholdGain(int cameraId)
+{
+ return getInstance()->mStaticCfg.mCameras[cameraId].mTnrThresholdGain;
+}
} // namespace icamera
diff --git a/camera/hal/intel/ipu6/src/platformdata/PlatformData.h b/camera/hal/intel/ipu6/src/platformdata/PlatformData.h
index aa6499a..5a2ab1c 100644
--- a/camera/hal/intel/ipu6/src/platformdata/PlatformData.h
+++ b/camera/hal/intel/ipu6/src/platformdata/PlatformData.h
@@ -53,6 +53,8 @@
#define FACE_ENGINE_DEFAULT_RUNNING_INTERVAL 1
#define DEFAULT_TNR_EXTRA_FRAME_NUM 2
+#define DEFAULT_TNR_THRESHOLD_GAIN 2.0f
+
/* Max number of the RAW buffer number is 32.
* Max number size of the pipeline depth is 6.
* Max setting count should be larger than raw buffer number + pipeline depth.
@@ -142,7 +144,8 @@
mSwProcessingAlignWithIsp(false),
mMaxNvmDataSize(0),
mVideoStreamNum(DEFAULT_VIDEO_STREAM_NUM),
- mTnrExtraFrameNum(DEFAULT_TNR_EXTRA_FRAME_NUM)
+ mTnrExtraFrameNum(DEFAULT_TNR_EXTRA_FRAME_NUM),
+ mTnrThresholdGain(DEFAULT_TNR_THRESHOLD_GAIN)
{
}
@@ -232,6 +235,7 @@
std::vector<IGraphType::ScalerInfo> mScalerInfo;
int mVideoStreamNum;
int mTnrExtraFrameNum;
+ float mTnrThresholdGain;
};
std::vector<CameraInfo> mCameras;
@@ -1194,5 +1198,9 @@
* the extra frame count for still stream
*/
static int getTnrExtraFrameCount(int cameraId);
+ /**
+ * the threshold gain to trigger still tnr
+ */
+ static float getTnrThresholdGain(int cameraId);
};
} /* namespace icamera */
diff --git a/camera/hal/intel/ipu6/src/platformdata/gc/IGraphConfig.h b/camera/hal/intel/ipu6/src/platformdata/gc/IGraphConfig.h
index 8771706..b932da6 100644
--- a/camera/hal/intel/ipu6/src/platformdata/gc/IGraphConfig.h
+++ b/camera/hal/intel/ipu6/src/platformdata/gc/IGraphConfig.h
@@ -40,16 +40,13 @@
namespace icamera {
-/**
- * Stream id associated with still capture.
- */
-static const int32_t STILL_STREAM_ID = 60000;
-/**
- * Stream id associated with video stream.
- */
#ifdef TNR7_CM
+// Stream id associated with still capture.
+static const int32_t STILL_STREAM_ID = 60009;
+// Stream id associated with video stream.
static const int32_t VIDEO_STREAM_ID = 60006;
#else
+static const int32_t STILL_STREAM_ID = 60000;
static const int32_t VIDEO_STREAM_ID = 60001;
#endif