blob: b65e1b354550d5ecabfcd1209ccc7d0e233286c5 [file] [log] [blame]
/*
* Copyright (C) 2020 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "GPUExecutor"
#include "GPUExecutor.h"
extern "C" {
#include <ia_cipf_css/ia_cipf_css.h>
#include <ia_pal_types_isp_ids_autogen.h>
}
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "3a/AiqResult.h"
#include "3a/AiqResultStorage.h"
#include "FormatUtils.h"
#include "PSysDAG.h"
#include "SyncManager.h"
#include "ia_pal_output_data.h"
#include "iutils/CameraDump.h"
using std::map;
using std::shared_ptr;
using std::string;
using std::vector;
#define external_gpu_stage_uid(id) ia_fourcc(((id & 0xFF00) >> 8), id, 'E', 'X')
namespace icamera {
std::mutex GPUExecutor::mGPULock;
GPUExecutor::GPUExecutor(int cameraId, const ExecutorPolicy& policy, vector<string> exclusivePGs,
PSysDAG* psysDag, shared_ptr<IGraphConfig> gc, bool useTnrOutBuffer)
: PipeExecutor(cameraId, policy, exclusivePGs, psysDag, gc),
mTnr7usParam(nullptr),
mIntelTNR(nullptr),
mLastSequence(UINT32_MAX),
mUseInternalTnrBuffer(useTnrOutBuffer),
mOutBufferSize(0) {
mStillTnrTG = PlatformData::getTnrThresholdGain(mCameraId);
LOG1("@%s %s", __func__, mName.c_str());
}
GPUExecutor::~GPUExecutor() {
LOG1("@%s %s", __func__, mName.c_str());
mPGExecutors.clear();
}
int GPUExecutor::initPipe() {
LOG1("@%s:%s", __func__, getName());
CheckError(mGraphConfig == nullptr, BAD_VALUE, "%s, the graph config is NULL, BUG!", __func__);
vector<IGraphType::PipelineConnection> connVector;
int ret = mGraphConfig->pipelineGetConnections(mPGNames, &connVector);
CheckError(ret != OK || connVector.empty(), ret, "Failed to get connections for executor:%s",
mName.c_str());
ret = createPGs();
CheckError(ret != OK, ret, "Failed to create PGs for executor: %s", mName.c_str());
ret = analyzeConnections(connVector);
CheckError(ret != OK, ret, "Failed to analyze connections for executor: %s", mName.c_str());
assignDefaultPortsForTerminals();
return OK;
}
// GPU executor doesn't have HW pg, create pg according to graph settings
int GPUExecutor::createPGs() {
LOG1("@%s:%s", __func__, getName());
for (auto const& pgName : mPGNames) {
int pgId = mGraphConfig->getPgIdByPgName(pgName);
CheckError(pgId == -1, BAD_VALUE, "Cannot get PG ID for %s", pgName.c_str());
ExecutorUnit pgUnit;
pgUnit.pgId = pgId;
// GPU Executor doesn't have pg
pgUnit.pg = nullptr;
pgUnit.stageId = external_gpu_stage_uid(pgId);
mPGExecutors.push_back(pgUnit);
}
return OK;
}
int GPUExecutor::start() {
LOG1("%s executor:%s", __func__, mName.c_str());
mProcessThread = new ProcessThread(this);
CheckError(mPGExecutors.empty(), UNKNOWN_ERROR, "PGExecutors couldn't be empty");
ExecutorUnit* tnrUnit = &mPGExecutors[0];
int ret = OK;
if (!tnrUnit->inputTerminals.empty()) {
ia_uid term = tnrUnit->inputTerminals.at(0);
CheckError(mTerminalsDesc.find(term) == mTerminalsDesc.end(), NO_INIT,
"Can't find TerminalDescriptor");
const FrameInfo& frameInfo = mTerminalsDesc[term].frameDesc;
mIntelTNR = std::unique_ptr<IntelTNR7US>(new IntelTNR7US(mCameraId));
TnrType type = mStreamId == VIDEO_STREAM_ID ? TNR_INSTANCE0 : TNR_INSTANCE1;
ret = mIntelTNR->init(frameInfo.mWidth, frameInfo.mHeight, type);
if (ret) {
mIntelTNR = nullptr;
// when failed to init tnr, executor will run without tnr effect
LOGW("%s executor:%s init tnr failed", __func__, mName.c_str());
}
}
AutoMutex l(mBufferQueueLock);
ret = allocBuffers();
CheckError(ret, UNKNOWN_ERROR, "@%s: allocBuffers failed", __func__);
dumpPGs();
mThreadRunning = true;
mProcessThread->run(mName.c_str(), PRIORITY_NORMAL);
return ret;
}
void GPUExecutor::stop() {
LOG1("%s executor:%s", __func__, mName.c_str());
mProcessThread->requestExitAndWait();
// Thread is not running. It is safe to clear the Queue
releaseBuffers();
clearBufferQueues();
delete mProcessThread;
mIntelTNR = nullptr;
}
int GPUExecutor::allocBuffers() {
LOG1("%s executor:%s", __func__, mName.c_str());
releaseBuffers();
// Allocate buffers for producer executor (external)
// don't need to check mPGExecutors and inputTerminals, already check before
ia_uid term = mPGExecutors[0].inputTerminals.at(0);
Port inputPort = mTerminalsDesc[term].assignedPort;
int srcFmt = mTerminalsDesc[term].frameDesc.mFormat;
int srcWidth = mTerminalsDesc[term].frameDesc.mWidth;
int srcHeight = mTerminalsDesc[term].frameDesc.mHeight;
int size = PGCommon::getFrameSize(srcFmt, srcWidth, srcHeight, true);
for (int i = 0; i < MAX_BUFFER_COUNT; i++) {
shared_ptr<CameraBuffer> buf;
if (mIntelTNR) {
buf = std::make_shared<CameraBuffer>(mCameraId, BUFFER_USAGE_PSYS_INPUT,
V4L2_MEMORY_USERPTR, size, i, srcFmt);
CheckError(!buf, NO_MEMORY, "@%s: fail to alloc CameraBuffer", __func__);
void* buffer = mIntelTNR->allocCamBuf(size, i);
CheckError(!buffer, NO_MEMORY, "@%s: fail to alloc shared memory", __func__);
buf->setUserBufferInfo(srcFmt, srcWidth, srcHeight, buffer);
} else {
buf = CameraBuffer::create(mCameraId, BUFFER_USAGE_PSYS_INPUT, V4L2_MEMORY_USERPTR,
size, i, srcFmt, srcWidth, srcHeight);
}
mInternalBuffers[inputPort].push_back(buf);
mBufferProducer->qbuf(inputPort, buf);
}
if (mIntelTNR) {
int ret = allocTnrOutBufs(size);
CheckError(ret, UNKNOWN_ERROR, "@%s: alloc tnr reference buffer failed", __func__);
mTnr7usParam = mIntelTNR->allocTnr7ParamBuf();
CheckError(!mTnr7usParam, NO_MEMORY, "@%s: Allocate Param buffer failed", __func__);
CLEAR(*mTnr7usParam);
}
// Allocate internal output buffers to support pipe execution without user output buffer
for (auto const& item : mOutputFrameInfo) {
int fmt = item.second.format;
int width = item.second.width;
int height = item.second.height;
int size = CameraUtils::getFrameSize(fmt, width, height, true);
shared_ptr<CameraBuffer> buf = CameraBuffer::create(
mCameraId, BUFFER_USAGE_PSYS_INPUT, V4L2_MEMORY_USERPTR, size, 0, fmt, width, height);
CheckError(!buf, NO_MEMORY, "@%s: Allocate internal output buffer failed", __func__);
mInternalOutputBuffers[item.first] = buf;
}
return OK;
}
bool GPUExecutor::fetchTnrOutBuffer(int64_t seq, std::shared_ptr<CameraBuffer> buf) {
if (!mUseInternalTnrBuffer) return false;
std::unique_lock<std::mutex> lock(mTnrOutBufMapLock);
if (mTnrOutBufMap.find(seq) != mTnrOutBufMap.end()) {
void* pSrcBuf = (buf->getMemory() == V4L2_MEMORY_DMABUF)
? CameraBuffer::mapDmaBufferAddr(buf->getFd(), buf->getBufferSize())
: buf->getBufferAddr();
CheckError(!pSrcBuf, false, "%s, pSrcBuf is nullptr", __func__);
LOG2("%s, sequence %ld is used for output", __func__, seq);
MEMCPY_S(pSrcBuf, buf->getBufferSize(), mTnrOutBufMap[seq], mOutBufferSize);
if (buf->getMemory() == V4L2_MEMORY_DMABUF) {
CameraBuffer::unmapDmaBufferAddr(pSrcBuf, buf->getBufferSize());
}
return true;
}
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;
/* for yuv still stream, we use maxRaw buffer to do reprocessing, and for real still stream, 2
* tnr buffers are enough */
int maxTnrOutBufCount = (mStreamId == VIDEO_STREAM_ID && mUseInternalTnrBuffer)
? PlatformData::getMaxRawDataNum(mCameraId)
: DEFAULT_TNR7US_BUFFER_COUNT;
std::unique_lock<std::mutex> lock(mTnrOutBufMapLock);
for (int i = 0; i < maxTnrOutBufCount; i++) {
void* buffer = mIntelTNR->allocCamBuf(bufSize, MAX_BUFFER_COUNT + i);
// will release all buffer in freeAllBufs
CheckError(!buffer, UNKNOWN_ERROR, "@%s, alloc reference buffer fails", __func__);
int index = i * (-1) - 1; // initialize index as -1, -2, ...
mTnrOutBufMap[index] = buffer;
}
return OK;
}
void GPUExecutor::releaseBuffers() {
if (mIntelTNR) {
mIntelTNR->freeAllBufs();
}
mTnrOutBufMap.clear();
// Release internel frame buffers
mInternalOutputBuffers.clear();
mInternalBuffers.clear();
}
int GPUExecutor::processNewFrame() {
PERF_CAMERA_ATRACE();
int ret = OK;
CameraBufferPortMap inBuffers, outBuffers;
// Wait frame buffers.
{
ConditionLock lock(mBufferQueueLock);
ret = waitFreeBuffersInQueue(lock, inBuffers, outBuffers);
// Already stopped
if (!mThreadRunning) return -1;
if (ret != OK) return OK; // Wait frame buffer error should not involve thread exit.
CheckError(inBuffers.empty() || outBuffers.empty(), UNKNOWN_ERROR,
"Failed to get input or output buffers.");
for (auto& output : mOutputQueue) {
output.second.pop();
}
for (auto& input : mInputQueue) {
input.second.pop();
}
}
// Check if the executor needs to run the actual pipeline.
// It only needs to run when there is at least one valid output buffer.
if (!hasValidBuffers(outBuffers)) {
// As an output edge, return the inBuffer when has no outBuffer,
for (const auto& item : inBuffers) {
mBufferProducer->qbuf(item.first, item.second);
}
return OK;
}
// Should find first not none input buffer instead of always use the first one.
shared_ptr<CameraBuffer> inBuf = inBuffers.begin()->second;
CheckError(!inBuf, UNKNOWN_ERROR, "@%s: no valid input buffer", __func__);
v4l2_buffer_t inV4l2Buf = *inBuf->getV4L2Buffer().Get();
// Fill real buffer to run pipe
for (auto& item : outBuffers) {
if (item.second.get() == nullptr) {
item.second = mInternalOutputBuffers[item.first];
}
}
std::shared_ptr<CameraBuffer> outBuf = outBuffers.begin()->second;
CheckError(!outBuf, UNKNOWN_ERROR, "@%s: no valid output buffer", __func__);
ret = runTnrFrame(inBuf, outBuf);
CheckError(ret != OK, ret, "@%s: run tnr failed", __func__);
// Remove internal output buffers
for (auto& item : outBuffers) {
if (item.second.get() == mInternalOutputBuffers[item.first].get()) {
item.second = nullptr;
}
}
notifyFrameDone(inV4l2Buf, outBuffers);
// Return buffers for the executor which is NOT an input edge
for (auto const& portBufferPair : inBuffers) {
// Queue buffer to producer
mBufferProducer->qbuf(portBufferPair.first, portBufferPair.second);
}
return OK;
}
/* get the tnr7 tuning data from ISP. PalOutput can help decode IPU tnr parameters from IPU result
** The GPU tnr7 parameters struct is different from IPU tnr parameters struct, so here we copy
** the useful parameter to tnr7 parameters object
*/
int GPUExecutor::updateTnrISPConfig(Tnr7Param* pbuffer, uint32_t sequence) {
int ret = ia_err_none;
if (mAdaptor) {
CLEAR(*pbuffer);
// only video stream pipe has tnr tuning data, still pipe use same tnr tuning data as video
ia_isp_bxt_program_group* pg = mGraphConfig->getProgramGroup(mStreamId);
CheckError(pg == nullptr, UNKNOWN_ERROR, "Can't get IPU program group");
// Get ISP parameters
LOG1(" %s update tnr parameters for sequence %d", __func__, sequence);
ia_binary_data* ipuParameters = mAdaptor->getIpuParameter(sequence, mStreamId);
CheckError(ipuParameters == nullptr, UNKNOWN_ERROR, "Failed to find ISP parameter");
ia_isp_bxt_program_group tmpPg = *pg;
tmpPg.kernel_count = 0;
int blankKernelSize = mAdaptor->getPalOutputDataSize(&tmpPg);
PalOutputData PalOutput(pg);
ia_binary_data tmpTnr7BinData = {0};
tmpTnr7BinData.size = ipuParameters->size - blankKernelSize;
tmpTnr7BinData.data = reinterpret_cast<char*>(ipuParameters->data) + blankKernelSize;
PalOutput.setPublicOutput(&tmpTnr7BinData);
ia_pal_isp_tnr7_bc_1_0_t* pBc;
ia_pal_isp_tnr7_blend_1_0_t* pBlend;
ia_pal_isp_tnr7_ims_1_0_t* pIms;
ret |= PalOutput.getKernelPublicOutput(ia_pal_uuid_isp_tnr7_bc_1_0, (void*&)pBc);
ret |= PalOutput.getKernelPublicOutput(ia_pal_uuid_isp_tnr7_blend_1_0, (void*&)pBlend);
ret |= PalOutput.getKernelPublicOutput(ia_pal_uuid_isp_tnr7_ims_1_0, (void*&)pIms);
CheckError(ret != ia_err_none, UNKNOWN_ERROR, "Can't read isp tnr7 parameters");
tnr7_bc_1_0_t* tnr7_bc = &(pbuffer->bc);
tnr7_blend_1_0_t* tnr7_blend = &(pbuffer->blend);
tnr7_ims_1_0_t* tnr7_ims = &(pbuffer->ims);
// tnr7 ims params
tnr7_ims->enable = pIms->enable;
tnr7_ims->update_limit = pIms->update_limit;
tnr7_ims->update_coeff = pIms->update_coeff;
tnr7_ims->gpu_mode = pIms->gpu_mode;
for (int i = 0; i < sizeof(pIms->d_ml) / sizeof(int32_t); i++) {
tnr7_ims->d_ml[i] = pIms->d_ml[i];
tnr7_ims->d_slopes[i] = pIms->d_slopes[i];
tnr7_ims->d_top[i] = pIms->d_top[i];
tnr7_ims->outofbounds[i] = pIms->outofbounds[i];
}
// tnr7 bc params
tnr7_bc->enable = pBc->enable;
tnr7_bc->is_first_frame = pBc->is_first_frame;
tnr7_bc->do_update = pBc->do_update;
tnr7_bc->gpu_mode = pBc->gpu_mode;
tnr7_bc->tune_sensitivity = pBc->tune_sensitivity;
for (int i = 0; i < sizeof(pBc->coeffs) / sizeof(int32_t); i++) {
tnr7_bc->coeffs[i] = pBc->coeffs[i];
}
tnr7_bc->global_protection = pBc->global_protection;
tnr7_bc->global_protection_motion_level = pBc->global_protection_motion_level;
for (int i = 0; i < sizeof(pBc->global_protection_sensitivity_lut_values) / sizeof(int32_t);
i++) {
tnr7_bc->global_protection_sensitivity_lut_values[i] =
pBc->global_protection_sensitivity_lut_values[i];
}
for (int i = 0; i < sizeof(pBc->global_protection_sensitivity_lut_slopes) / sizeof(int32_t);
i++) {
tnr7_bc->global_protection_sensitivity_lut_slopes[i] =
pBc->global_protection_sensitivity_lut_slopes[i];
}
// tnr7 blend params
tnr7_blend->enable = pBlend->enable;
tnr7_blend->enable_main_output = pBlend->enable_main_output;
tnr7_blend->enable_vision_output = pBlend->enable_vision_output;
tnr7_blend->single_output_mode = pBlend->single_output_mode;
tnr7_blend->spatial_weight_coeff = pBlend->spatial_weight_coeff;
tnr7_blend->max_recursive_similarity = pBlend->max_recursive_similarity;
tnr7_blend->spatial_alpha = pBlend->spatial_alpha;
tnr7_blend->max_recursive_similarity_vsn = pBlend->max_recursive_similarity_vsn;
for (int i = 0; i < sizeof(pBlend->w_out_prev_LUT) / sizeof(int32_t); i++) {
tnr7_blend->w_out_prev_LUT[i] = pBlend->w_out_prev_LUT[i];
tnr7_blend->w_out_spl_LUT[i] = pBlend->w_out_spl_LUT[i];
tnr7_blend->w_vsn_out_prev_LUT[i] = pBlend->w_vsn_out_prev_LUT[i];
tnr7_blend->w_vsn_out_spl_LUT[i] = pBlend->w_vsn_out_spl_LUT[i];
}
for (int i = 0; i < sizeof(pBlend->output_cu_a) / sizeof(int32_t); i++) {
tnr7_blend->output_cu_a[i] = pBlend->output_cu_a[i];
tnr7_blend->output_cu_b[i] = pBlend->output_cu_b[i];
}
for (int i = 0; i < sizeof(pBlend->output_cu_x) / sizeof(int32_t); i++) {
tnr7_blend->output_cu_x[i] = pBlend->output_cu_x[i];
}
}
return ret;
}
int GPUExecutor::runTnrFrame(const std::shared_ptr<CameraBuffer>& inBuf,
std::shared_ptr<CameraBuffer> outBuf) {
PERF_CAMERA_ATRACE();
CheckError(!inBuf->getBufferAddr(), UNKNOWN_ERROR, "%s invalid input buffer", __func__);
if (mPolicyManager) {
// Check if need to wait other executors.
mPolicyManager->wait(mName);
}
LOG2("Enter %s executor name:%s, sequence: %u", __func__, mName.c_str(), inBuf->getSequence());
TRACE_LOG_PROCESS(mName.c_str(), __func__, MAKE_COLOR(inBuf->getSequence()),
inBuf->getSequence());
uint32_t sequence = inBuf->getSequence();
int ret = OK;
if (mIntelTNR && !isBypassStillTnr(sequence)) {
ret = updateTnrISPConfig(mTnr7usParam, sequence);
CheckError(ret != OK, UNKNOWN_ERROR, " %s Failed to update TNR parameters", __func__);
}
int fd = outBuf->getFd();
int memoryType = outBuf->getMemory();
int bufferSize = outBuf->getBufferSize();
void* outPtr = (memoryType == V4L2_MEMORY_DMABUF)
? CameraBuffer::mapDmaBufferAddr(fd, bufferSize)
: outBuf->getBufferAddr();
if (!outPtr) return UNKNOWN_ERROR;
if (!mIntelTNR || isBypassStillTnr(sequence)) {
MEMCPY_S(outPtr, bufferSize, inBuf->getBufferAddr(), inBuf->getBufferSize());
if (memoryType == V4L2_MEMORY_DMABUF) {
CameraBuffer::unmapDmaBufferAddr(outPtr, bufferSize);
}
return OK;
}
if (icamera::PlatformData::isStillTnrPrior()) {
// when running still stream tnr, should skip video tnr to decrease still capture duration.
if (mStreamId == VIDEO_STREAM_ID && !mGPULock.try_lock()) {
MEMCPY_S(outPtr, bufferSize, inBuf->getBufferAddr(), inBuf->getBufferSize());
if (memoryType == V4L2_MEMORY_DMABUF) {
CameraBuffer::unmapDmaBufferAddr(outPtr, bufferSize);
}
mLastSequence = UINT32_MAX;
LOG2("%s executor name:%s, skip frame sequence: %ld", __func__, mName.c_str(),
inBuf->getSequence());
return OK;
} else if (mStreamId == STILL_STREAM_ID) {
mGPULock.lock();
}
}
if (mLastSequence == UINT32_MAX || sequence - mLastSequence >= TNR7US_RESTART_THRESHOLD) {
mTnr7usParam->bc.is_first_frame = 1;
} else {
mTnr7usParam->bc.is_first_frame = 0;
}
void* dstBuf = outPtr;
int dstSize = bufferSize;
int dstFd = fd;
std::map<int64_t, void*>::iterator tnrOutBuf;
// use internal tnr buffer for ZSL and none APP buffer request usage
bool useInternalBuffer = mUseInternalTnrBuffer || memoryType != V4L2_MEMORY_DMABUF;
if (useInternalBuffer) {
std::unique_lock<std::mutex> lock(mTnrOutBufMapLock);
tnrOutBuf = mTnrOutBufMap.begin();
dstBuf = tnrOutBuf->second;
dstSize = mOutBufferSize;
// when use internal tnr buffer, we don't need to use fd map buffer
dstFd = -1;
}
ret = mIntelTNR->runTnrFrame(inBuf->getBufferAddr(), dstBuf, inBuf->getBufferSize(), dstSize,
mTnr7usParam, dstFd);
if (ret == OK) {
if (useInternalBuffer) {
MEMCPY_S(outPtr, bufferSize, tnrOutBuf->second, mOutBufferSize);
}
} else {
LOG2("%s, Just copy source buffer if run TNR failed", __func__);
MEMCPY_S(outPtr, bufferSize, inBuf->getBufferAddr(), inBuf->getBufferSize());
}
if (icamera::PlatformData::isStillTnrPrior()) {
mGPULock.unlock();
}
if (useInternalBuffer) {
std::unique_lock<std::mutex> lock(mTnrOutBufMapLock);
mTnrOutBufMap.erase(tnrOutBuf->first);
mTnrOutBufMap[sequence] = tnrOutBuf->second;
LOG2("%s, outBuf->first %ld, outBuf->second %p", __func__, tnrOutBuf->first,
tnrOutBuf->second);
}
if (memoryType == V4L2_MEMORY_DMABUF) {
CameraBuffer::unmapDmaBufferAddr(outPtr, bufferSize);
}
CheckError(ret != OK, UNKNOWN_ERROR, " %s tnr7us run frame failed", __func__);
mLastSequence = sequence;
if (mStreamId != STILL_STREAM_ID) {
// still stream will update params in tnr7us, skip async update
float totalGain = 0.0f;
ret = getTotalGain(sequence, &totalGain);
CheckError(ret, UNKNOWN_ERROR, "@%s, Failed to get total gain", __func__);
// update tnr param when total gain changes
bool isTnrParamForceUpdate = icamera::PlatformData::isTnrParamForceUpdate();
ret = mIntelTNR->asyncParamUpdate(static_cast<int>(totalGain), isTnrParamForceUpdate);
}
LOG2("Exit %s executor name:%s, sequence: %u", __func__, mName.c_str(), inBuf->getSequence());
return ret;
}
int GPUExecutor::dumpTnrParameters(uint32_t sequence) {
const int DUMP_FILE_SIZE = 0x1000;
std::string dumpFileName =
std::string("/home/tnr7-") + std::to_string(sequence) + std::string(".txt");
LOG1("%s save tnr7 parameters to file %s", __func__, dumpFileName.c_str());
tnr7_bc_1_0_t* tnr7_bc = &(mTnr7usParam->bc);
tnr7_blend_1_0_t* tnr7_blend = &(mTnr7usParam->blend);
tnr7_ims_1_0_t* tnr7_ims = &(mTnr7usParam->ims);
char* dumpData = reinterpret_cast<char*>(malloc(DUMP_FILE_SIZE));
CheckError(dumpData == nullptr, NO_MEMORY, "failed to allocate memory for dump tnr7");
FILE* parFile = fopen(dumpFileName.c_str(), "wb");
if (parFile) {
int shift = 0;
size_t length = snprintf(dumpData + shift, DUMP_FILE_SIZE - shift, "%s\n", "tnr7_bc");
shift += length;
for (int i = 0; i < sizeof(tnr7_bc_1_0_t) / sizeof(int32_t); i++) {
length = snprintf(dumpData + shift, DUMP_FILE_SIZE - shift, "%u\n",
*(reinterpret_cast<int32_t*>(tnr7_bc) + i));
shift += length;
}
length = snprintf(dumpData + shift, DUMP_FILE_SIZE - shift, "%s\n", "tnr7_blend");
shift += length;
for (int i = 0; i < sizeof(tnr7_blend_1_0_t) / sizeof(int32_t); i++) {
length = snprintf(dumpData + shift, DUMP_FILE_SIZE - shift, "%u\n",
*(reinterpret_cast<int32_t*>(tnr7_blend) + i));
shift += length;
}
length = snprintf(dumpData + shift, DUMP_FILE_SIZE - shift, "%s\n", "tnr7_ims");
shift += length;
for (int i = 0; i < sizeof(tnr7_ims_1_0_t) / sizeof(int32_t); i++) {
length = snprintf(dumpData + shift, DUMP_FILE_SIZE - shift, "%u\n",
*(reinterpret_cast<int32_t*>(tnr7_ims) + i));
shift += length;
}
fwrite(dumpData, shift, 1, parFile);
fclose(parFile);
} else {
LOGW("tnr7 failed to open dump file %s", (dumpFileName + std::to_string(sequence)).c_str());
}
free(dumpData);
return OK;
}
} // namespace icamera