diff --git a/.vscode/settings.json b/.vscode/settings.json index 40749ef..4fc8be6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -63,6 +63,60 @@ "istream": "cpp", "functional": "cpp", "tuple": "cpp", - "utility": "cpp" + "utility": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "type_traits": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "shared_mutex": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeinfo": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/bin/libvehicle_analysis.so b/bin/libvehicle_analysis.so index ed61393..1073e0e 100755 --- a/bin/libvehicle_analysis.so +++ b/bin/libvehicle_analysis.so diff --git a/bin/models/car_head_tail/head_tail_256_241220_310P.om b/bin/models/car_head_tail/head_tail_256_241220_310P.om new file mode 100644 index 0000000..bc11cc0 --- /dev/null +++ b/bin/models/car_head_tail/head_tail_256_241220_310P.om diff --git a/build/src/Makefile b/build/src/Makefile index 5a28c41..6f86a43 100644 --- a/build/src/Makefile +++ b/build/src/Makefile @@ -18,6 +18,9 @@ ALGORITHM_PATH = $(PROJ_ALL_PATH)/algorithm INCLUDES = -I$(PROJ_ALL_PATH)/src/common \ -I$(PROJ_ALL_PATH)/src/common/dvpp \ + -I$(PROJ_ALL_PATH)/src/common/cnn_cls \ + -I$(PROJ_ALL_PATH)/src/common/dvppx \ + -I$(PROJ_ALL_PATH)/src/common/model_process \ -I$(CUR_PROJ_PATH)/../va \ -I$(OPENCV_PATH)/include \ -I$(OPENCV_PATH)/include/opencv2 \ @@ -52,6 +55,9 @@ SRCS := $(wildcard $(CUR_PROJ_PATH)/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/ai_engine_module/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/*.cpp) \ $(wildcard $(CUR_PROJ_PATH)/common/dvpp/*.cpp) \ + $(wildcard $(CUR_PROJ_PATH)/common/cnn_cls/*.cpp) \ + $(wildcard $(CUR_PROJ_PATH)/common/dvppx/*.cpp) \ + $(wildcard $(CUR_PROJ_PATH)/common/model_process/*.cpp) \ DIRS := $(notdir $(SRCS)) OBJS := $(patsubst %cpp, %o, $(DIRS)) @@ -73,6 +79,18 @@ $(TARGET):$(OBJS) %.o:$(CUR_PROJ_PATH)/common/dvpp/%.cpp $(XX) $(CXXFLAGS) -c $< +%.o:$(CUR_PROJ_PATH)/common/cnn_cls/%.cpp + $(XX) $(CXXFLAGS) -c $< + +%.o:$(CUR_PROJ_PATH)/common/dvppx/%.cpp + $(XX) $(CXXFLAGS) -c $< + +%.o:$(CUR_PROJ_PATH)/common/model_process/%.cpp + $(XX) $(CXXFLAGS) -c $< + clean: @rm -f $(TARGET) @rm -f $(OBJS) + +cleano: + @rm -f $(OBJS) \ No newline at end of file diff --git a/src/PicAnalysis.cpp b/src/PicAnalysis.cpp new file mode 100644 index 0000000..ad26196 --- /dev/null +++ b/src/PicAnalysis.cpp @@ -0,0 +1,104 @@ +#include "PicAnalysis.h" +#include "./utils/logger.hpp" + + +PicAnalysis::PicAnalysis(/* args */) +{ + aclInit(nullptr); +} + +PicAnalysis::~PicAnalysis() +{ + aclFinalize(); +} + +int PicAnalysis::init(int dev_id) { + + int ret = m_vehicle_analysis.init(dev_id, 16); + if(0 != ret){ + return -1; + } + + head_tail_param ht_param; + ht_param.devId = dev_id; + ht_param.max_batch = 16; + ret = m_head_tail_algorithm.init(ht_param); + if(0 != ret){ + return -1; + } + + ACL_CALL(aclrtCreateContext(&m_ctx, 0), ACL_ERROR_NONE, SY_FAILED); + ACL_CALL(aclrtSetCurrentContext(m_ctx), ACL_ERROR_NONE, SY_FAILED); + + ACL_CALL(aclrtCreateStream(&stream), ACL_SUCCESS, SY_FAILED); + m_dvpp = new DvppProcess(); + m_dvpp->InitResource(stream); + + return 0; +} + +int PicAnalysis::analysis_sync(vector vec_file_path){ + + const int batch_size = vec_file_path.size(); + + vector vec_img; + + int ret = SY_FAILED; + + // ImageData 内部是智能指针,分析未处理完成前不得释放 + ImageData dvpp_data[batch_size]; + for (size_t i = 0; i < vec_file_path.size(); i++) + { + string file_path = vec_file_path[i]; + ImageData src; + ret = Utils::ReadImageFile(src, file_path); //将二进制图像读入内存,并读取宽高信息 + if(ret != SY_SUCCESS){ + LOG_ERROR("ReadImageFile failed!"); + return -1; + } + + ret = m_dvpp->CvtJpegToYuv420sp(dvpp_data[i], src); //解码 + if(ret != SY_SUCCESS){ + LOG_ERROR("CvtJpegToYuv420sp failed!"); + return -1; + } + + sy_img img; + img.w_ = dvpp_data[i].width; + img.h_ = dvpp_data[i].height; + img.data_ = dvpp_data[i].data.get(); + + vec_img.push_back(img); + } + + // m_vehicle_analysis.detect(vec_img); + + vector head_tail_result; + ret = m_head_tail_algorithm.detect(vec_img, head_tail_result); + if (0 != ret) { + LOG_ERROR("m_head_tail_algorithm failed!"); + head_tail_result.clear(); + } + + + return 0; +} + +int PicAnalysis::release() { + ACL_CALL(aclrtSetCurrentContext(m_ctx), ACL_ERROR_NONE, SY_FAILED); + + delete m_dvpp; + m_dvpp = nullptr; + + if (stream != nullptr) { + int ret = aclrtDestroyStream(stream); + if (ret != ACL_SUCCESS) { + LOG_ERROR("destroy stream failed"); + } + stream = nullptr; + } + + aclrtDestroyContext(m_ctx); + + return 0; +} \ No newline at end of file diff --git a/src/PicAnalysis.h b/src/PicAnalysis.h new file mode 100644 index 0000000..643b59c --- /dev/null +++ b/src/PicAnalysis.h @@ -0,0 +1,30 @@ +#include "./ai_engine_module/include.h" +#include "./ai_engine_module/VehicleAnalysis.h" +#include "./ai_engine_module/VehicleHeadTail.h" + +using namespace std; + + +class PicAnalysis +{ +public: + PicAnalysis(/* args */); + ~PicAnalysis(); + + int init(int dev_id); + + // todo 接口定义是二进制流的,这个地方有待修改 + int analysis_sync(vector file_path); + + int release(); + +private: + aclrtContext m_ctx{nullptr}; + aclrtStream stream{nullptr}; + DvppProcess* m_dvpp{nullptr}; + + VehicleAnalysis m_vehicle_analysis; + VehicleHeadTail m_head_tail_algorithm; +}; + + diff --git a/src/ai_engine_module/VehicleAnalysis.cpp b/src/ai_engine_module/VehicleAnalysis.cpp index 052b81c..b9fc23e 100644 --- a/src/ai_engine_module/VehicleAnalysis.cpp +++ b/src/ai_engine_module/VehicleAnalysis.cpp @@ -2,7 +2,6 @@ VehicleAnalysis::VehicleAnalysis() { - va_acl_init(); cout << va_get_version() << endl; } @@ -69,22 +68,9 @@ int VehicleAnalysis::init(int devId, int max_batch_size) { return 0; } -int VehicleAnalysis::detect(vector vec_img) { - - vector imgs; - - for (size_t i = 0; i < vec_img.size(); i++) - { - ImageData dvpp_data = vec_img[i]; - sy_img img; - img.w_ = dvpp_data.width; - img.h_ = dvpp_data.height; - img.data_ = dvpp_data.data.get(); - - imgs.push_back(img); - } +int VehicleAnalysis::detect(vector vec_img) { - int batch_size = imgs.size(); + int batch_size = vec_img.size(); va_result *result=new va_result[batch_size]; for(int b=0;b vec_img) { } ACL_CALL(aclrtSetCurrentContext(ctx), ACL_ERROR_NONE, SY_FAILED); - int ret = va_batch(m_handle, imgs.data(), batch_size, result); + int ret = va_batch(m_handle, vec_img.data(), batch_size, result); for (int b = 0; b < batch_size; b++) { @@ -109,16 +95,6 @@ int VehicleAnalysis::detect(vector vec_img) { std::cout <<"car_count:" <Init("./models/car_head_tail/head_tail_256_241220_310P.om"); + if (ret != SY_SUCCESS) { + delete m_cnn_cls; + m_cnn_cls = nullptr; + LOG_ERROR("sy_hcp model init failed!"); + return SY_FAILED; + } + + max_batch = param.max_batch; + + ACL_CALL(aclrtCreateStream(&stream), ACL_SUCCESS, SY_FAILED); + m_dvpp = new DvppProcessx(); + ret = m_dvpp->InitResource(stream); + if (ret != SY_SUCCESS) { + delete m_dvpp; + m_dvpp = nullptr; + LOG_ERROR("dvpp init failed!"); + return SY_FAILED; + } + + return SY_SUCCESS; +} + +int VehicleHeadTail::detect(vector img_data_array, vector& result){ + + if (m_cnn_cls == NULL) { + LOG_ERROR("HumanCarParse get null handle!"); + return SY_FAILED; + } + + ACL_CALL(aclrtSetCurrentContext(m_ctx), ACL_SUCCESS, SY_FAILED); + + int inputW = m_cnn_cls->GetInputWidth(); + int inputH = m_cnn_cls->GetInputHeight(); + + for (int i = 0; i < img_data_array.size(); i++) { + if (img_data_array[i].data_ == NULL || img_data_array[i].w_ == 0 || img_data_array[i].h_ == 0) { + LOG_ERROR("HumanCarParse Get null input ptr!"); + return SY_FAILED; + } + ImageData resizeImg, src; + ACL_CALL(Utils::CopysyImageDataToDvppV2(src, img_data_array[i]), SY_SUCCESS, SY_FAILED); + ACL_CALL(m_dvpp->CropAndPaste(resizeImg, src, inputW, inputH), SY_SUCCESS, SY_FAILED); + int ret = m_cnn_cls->Inference(resizeImg); + if (ret != SY_SUCCESS) { + LOG_ERROR( "HumanCarParse process error!"); + return SY_MODEL_FORWARD_ERROR; + } + + vector hcpRes; + ret = m_cnn_cls->PostProcess(hcpRes); + if (ret != SY_SUCCESS) { + LOG_ERROR("HumanCarParse postprocess error!"); + return SY_MODEL_GETRESULT_ERROR; + } + if (hcpRes.size() != 2) { + LOG_ERROR("HumanCarParse postprocess error!"); + return SY_MODEL_GETRESULT_ERROR; + } + + HeadTailResult one_result; + one_result.cls = hcpRes[0]; + one_result.confidence = hcpRes[1]; + + result.push_back(one_result); + } + + return SY_SUCCESS; +} + +int VehicleHeadTail::release() { + + ACL_CALL(aclrtSetCurrentContext(m_ctx), ACL_ERROR_NONE, SY_FAILED); + + if (m_cnn_cls) { + delete m_cnn_cls; + m_cnn_cls = nullptr; + } + + if (m_dvpp) { + delete m_dvpp; + m_dvpp = nullptr; + } + + if (stream != nullptr) { + int ret = aclrtDestroyStream(stream); + if (ret != ACL_SUCCESS) { + LOG_ERROR("destroy stream failed"); + } + stream = nullptr; + } + + aclrtDestroyContext(m_ctx); +} \ No newline at end of file diff --git a/src/ai_engine_module/VehicleHeadTail.h b/src/ai_engine_module/VehicleHeadTail.h new file mode 100644 index 0000000..d329622 --- /dev/null +++ b/src/ai_engine_module/VehicleHeadTail.h @@ -0,0 +1,46 @@ +#include "sy_errorinfo.h" +#include "cnn_cls.h" +#include "dvpp_processx.h" +#include +#include +#include "stream_data.h" +#include +#include + +using namespace atlas_utils; +using namespace std; + +typedef struct head_tail_param +{ + int devId; //ָ指定显卡id + int max_batch; + head_tail_param() :devId(0), max_batch(8){}; +} head_tail_param; + +struct HeadTailResult { + int cls; + float confidence; +}; + +class VehicleHeadTail +{ + +public: + VehicleHeadTail(/* args */); + ~VehicleHeadTail(); + + int init(head_tail_param param); + + int detect(vector, vector&); + +private: + int release(); + +private: + aclrtContext m_ctx; + aclrtStream stream; + CnnCls* m_cnn_cls; + DvppProcessx* m_dvpp; + int max_batch; +}; + diff --git a/src/common/cnn_cls/cnn_cls.cpp b/src/common/cnn_cls/cnn_cls.cpp new file mode 100755 index 0000000..564662f --- /dev/null +++ b/src/common/cnn_cls/cnn_cls.cpp @@ -0,0 +1,162 @@ +#include "cnn_cls.h" +#include +#include "acl/acl.h" +#include "model_process.h" +#include "sy_errorinfo.h" +#include +#include +#include + +using namespace std; + +namespace atlas_utils { + +int CnnCls::Init(const char* modelPath) { + ACL_CALL(aclrtGetRunMode(&runMode_), SY_SUCCESS, SY_FAILED);//获取当前昇腾AI软件栈的运行模式,根据不同的运行模式,后续的接口调用方式不同 + ACL_CALL(model_.LoadModelFromFileWithMem(modelPath), SY_SUCCESS, SY_FAILED);//从文件加载离线模型数据,由用户自行管理模型运行的内存 + ACL_CALL(model_.CreateDesc(), SY_SUCCESS, SY_FAILED);//获取模型的描述信息 + ACL_CALL(model_.CreateOutput(outDims_), SY_SUCCESS, SY_FAILED); + ACL_CALL(model_.GetInputDims(inDims_), SY_SUCCESS, SY_FAILED); + modelHeight_ = inDims_[0][1]; + modelWidth_ = inDims_[0][2]; + + return SY_SUCCESS; +} + +// double msecond1() { +// struct timeval tv; +// gettimeofday(&tv, 0); +// return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0); +// } + +int CnnCls::Inference(ImageData& input) { + model_.CreateInput(input.data.get(), input.size); + //double t1, t2; + //t1 = msecond1(); + ACL_CALL(model_.Execute(), SY_SUCCESS, SY_FAILED); + //t2 = msecond1(); + //printf("debug forward time: %.2f\n", t2 - t1); + model_.DestroyInput(); //需调用CreateInput的销毁类接口DestroyInput!!! + return SY_SUCCESS; +} + +int CnnCls::GetInputWidth() { + return modelWidth_; +} + +int CnnCls::GetInputHeight() { + return modelHeight_; +} + +int CnnCls::PostProcess(vector& results) { + aclmdlDataset* modelOutput = model_.GetModelOutputData(); + int outDatasetNum = aclmdlGetDatasetNumBuffers(modelOutput); + for (int i = 0; i < outDatasetNum; i++) { + aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(modelOutput, i); + if (dataBuffer == nullptr) { + return SY_FAILED; + } + uint32_t dataBufferSize = aclGetDataBufferSize(dataBuffer); + void* data = aclGetDataBufferAddr(dataBuffer); + if (data == nullptr) { + return SY_FAILED; + } + + int length = dataBufferSize/sizeof(float); + float outInfo[length]; + + if (runMode_ == ACL_HOST) { + ACL_CALL(aclrtMemcpy(outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_HOST), + ACL_SUCCESS, SY_FAILED); + } else { + ACL_CALL(aclrtMemcpy(outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_DEVICE),ACL_SUCCESS, SY_FAILED); + //return SY_FAILED; + } + + int argmax = std::distance(outInfo, std::max_element(outInfo, outInfo + length)); + if(outInfo[argmax] < config.confThr){ + // printf("outInfo[argmax]:%f\n",outInfo[argmax]); + // printf("config.confThr:%f\n",config.confThr); + results.emplace_back(-1); + results.emplace_back(0); + // INFO_LOG("vColor is low confidence!"); + } + else{ + results.emplace_back(argmax); + results.emplace_back(outInfo[argmax]); + } + /* + for(uint32_t b = 0; b < length; b++) { + + results.emplace_back(outInfo[b]); + }*/ + } + + + return SY_SUCCESS; +} + +int CnnCls::PostProcess_batch(vector>& results) { + aclmdlDataset* modelOutput = model_.GetModelOutputData(); + int outDatasetNum = aclmdlGetDatasetNumBuffers(modelOutput); + const int batchsize = outDims_[0][0]; + + // 结果拷贝 + vector> all_res; + for (int i = 0; i < outDatasetNum; i++) { + aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(modelOutput, i); + if (dataBuffer == nullptr) { + return SY_FAILED; + } + uint32_t dataBufferSize = aclGetDataBufferSize(dataBuffer); + void* data = aclGetDataBufferAddr(dataBuffer); + if (data == nullptr) { + return SY_FAILED; + } + + int length = dataBufferSize/sizeof(float); + float outInfo[length]; + + if (runMode_ == ACL_HOST) { + ACL_CALL(aclrtMemcpy(outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_HOST),ACL_SUCCESS, SY_FAILED); + } else { + ACL_CALL(aclrtMemcpy(outInfo, sizeof(outInfo), data, sizeof(outInfo), ACL_MEMCPY_DEVICE_TO_DEVICE),ACL_SUCCESS, SY_FAILED); + } + + vector res; + res.assign(outInfo, outInfo + length); + all_res.emplace_back(res); + } + + // 按[b][cls]的形式返回 + for (int b = 0; b < batchsize; b ++) { + vector result; + for (const auto& outInfo : all_res) { + int single_length = outInfo.size() / batchsize; + // printf("batchsize:%d,single_length:%d\n",batchsize, single_length); + + int argmax = std::distance(outInfo.begin()+b*single_length, std::max_element(outInfo.begin()+b*single_length, outInfo.begin() + (b+1)*single_length)); + float score = outInfo[b*single_length+argmax]; + if(score < config.confThr) { + // printf("score:%f, confThr\n",score, config.confThr); + result.emplace_back(-1); + result.emplace_back(0); + } + else { + result.emplace_back(argmax); + result.emplace_back(score); + } + } + results.emplace_back(result); + } + + return SY_SUCCESS; +} + +void CnnCls::Release() { + model_.Unload(); + model_.DestroyDesc(); + model_.DestroyOutput(); +} + +} diff --git a/src/common/cnn_cls/cnn_cls.h b/src/common/cnn_cls/cnn_cls.h new file mode 100755 index 0000000..bc77b56 --- /dev/null +++ b/src/common/cnn_cls/cnn_cls.h @@ -0,0 +1,56 @@ +#ifndef _CNNCls_H_ +#define _CNNCls_H_ + +#include +#include "utils.h" +#include "acl/acl.h" +#include "model_process.h" + +using namespace std; + +namespace atlas_utils { + +#ifndef BBOX_WIDTH +#define BBOX_WIDTH 8 +#endif + +#ifndef DATA_TYPE_SIZE +#define DATA_TYPE_SIZE 4 +#endif + +class CnnCls { +public: + struct ConfigParams { + float confThr = 0.0; //显示初始化,有的编译器会不执行默认初始化 + }; + + CnnCls() {} + ~CnnCls() { + Release(); + } + + int Init(const char* modelPath); + int Inference(ImageData& input); + int PostProcess(vector& result); + int PostProcess_batch(vector>& result); + + int GetInputWidth(); + int GetInputHeight(); + + ConfigParams config; + +private: + void Release(); + + vector> outDims_; + vector> inDims_; + ModelProcess model_; + uint32_t modelWidth_; + uint32_t modelHeight_; + aclrtRunMode runMode_; + +}; + +} + +#endif diff --git a/src/common/dvppx/dvpp_cropandpastex.cpp b/src/common/dvppx/dvpp_cropandpastex.cpp new file mode 100755 index 0000000..f52a901 --- /dev/null +++ b/src/common/dvppx/dvpp_cropandpastex.cpp @@ -0,0 +1,525 @@ +/** +* Copyright 2020 Huawei Technologies Co., Ltd +* +* 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. + +* File dvpp_process.cpp +* Description: handle dvpp process +*/ + +#include +#include "acl/acl.h" +#include "utils.h" +#include "dvpp_cropandpastex.h" +#include "sy_errorinfo.h" +using namespace std; + +DvppCropAndPastex::DvppCropAndPastex(aclrtStream& stream, acldvppChannelDesc *dvppChannelDesc, + uint32_t width, uint32_t height) +: stream_(stream), dvppChannelDesc_(dvppChannelDesc), +vpcInputDesc_(nullptr), vpcOutputDesc_(nullptr), +vpcOutBufferDev_(nullptr),vpcOutBufferSize_(0){ + size_.width = width; + size_.height = height; +} + +DvppCropAndPastex::~DvppCropAndPastex() +{ + DestroyCropAndPasteResource(); +} + +int DvppCropAndPastex::InitCropAndPasteInputDesc(ImageData& inputImage) +{ + originalImageWidth_ = inputImage.width; + originalImageHeight_ = inputImage.height; + uint32_t alignWidth = inputImage.alignWidth; + uint32_t alignHeight = inputImage.alignHeight; + // printf("image w %d, h %d, align w%d, h%d",inputImage.width, inputImage.height, alignWidth, alignHeight); + if (alignWidth == 0 || alignHeight == 0) { + ERROR_LOG("InitResizeInputDesc AlignmentHelper failed. image w %d, h %d, align w%d, h%d", + inputImage.width, inputImage.height, alignWidth, alignHeight); + return SY_FAILED; + } + uint32_t inputBufferSize = YUV420SP_SIZE(alignWidth, alignHeight); + vpcInputDesc_ = acldvppCreatePicDesc(); + if (vpcInputDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc vpcInputDesc_ failed"); + return SY_FAILED; + } + + acldvppSetPicDescData(vpcInputDesc_, inputImage.data.get()); // JpegD . vpcResize + acldvppSetPicDescFormat(vpcInputDesc_, format_); + acldvppSetPicDescWidth(vpcInputDesc_, inputImage.width); + acldvppSetPicDescHeight(vpcInputDesc_, inputImage.height); + acldvppSetPicDescWidthStride(vpcInputDesc_, alignWidth); + acldvppSetPicDescHeightStride(vpcInputDesc_, alignHeight); + acldvppSetPicDescSize(vpcInputDesc_, inputBufferSize); + return SY_SUCCESS; +} + +int DvppCropAndPastex::InitCropAndPasteOutputDesc() +{ + int resizeOutWidth = size_.width; + int resizeOutHeight = size_.height; + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth); + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight); + + if (resizeOutWidthStride == 0 || resizeOutHeightStride == 0) { + ERROR_LOG("InitResizeOutputDesc AlignmentHelper failed"); + return SY_FAILED; + } + + vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride); + aclError aclRet = acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_); + //debug======================================================================== + uint32_t size = ALIGN_UP(vpcOutBufferSize_,32) + 32; + aclRet = aclrtMemset(vpcOutBufferDev_,size, 128, size); + // aclRet = aclrtMemset(vpcOutBufferDev_,vpcOutBufferSize_, 0, vpcOutBufferSize_); + //debug end==================================================================== + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppMalloc vpcOutBufferDev_ failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + vpcOutputDesc_ = acldvppCreatePicDesc(); + if (vpcOutputDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc vpcOutputDesc_ failed"); + return SY_FAILED; + } + acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_); + acldvppSetPicDescFormat(vpcOutputDesc_, format_); + acldvppSetPicDescWidth(vpcOutputDesc_, resizeOutWidth); + acldvppSetPicDescHeight(vpcOutputDesc_, resizeOutHeight); + acldvppSetPicDescWidthStride(vpcOutputDesc_, resizeOutWidthStride); + acldvppSetPicDescHeightStride(vpcOutputDesc_, resizeOutHeightStride); + acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_); + + return SY_SUCCESS; +} + +int DvppCropAndPastex::InitRightCropAndPasteOutputDesc() +{ + int resizeOutWidth = size_.width; + int resizeOutHeight = size_.height; + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth); + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight); + if (resizeOutWidthStride == 0 || resizeOutHeightStride == 0) { + ERROR_LOG("InitResizeOutputDesc AlignmentHelper failed"); + return SY_FAILED; + } + + vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride); + //aclError aclRet = acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_); + // if (aclRet != ACL_SUCCESS) { + // ERROR_LOG("acldvppMalloc vpcOutBufferDev_ failed, aclRet = %d", aclRet); + // return SY_FAILED; + // } + vpcOutputDesc_ = acldvppCreatePicDesc(); + if (vpcOutputDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc vpcOutputDesc_ failed"); + return SY_FAILED; + } + acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_ + vpcOutBufferSize_); + acldvppSetPicDescFormat(vpcOutputDesc_, format_); + acldvppSetPicDescWidth(vpcOutputDesc_, resizeOutWidth); + acldvppSetPicDescHeight(vpcOutputDesc_, resizeOutHeight); + acldvppSetPicDescWidthStride(vpcOutputDesc_, resizeOutWidthStride); + acldvppSetPicDescHeightStride(vpcOutputDesc_, resizeOutHeightStride); + acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_); + + return SY_SUCCESS; +} + + +// IN/OUT Desc +int DvppCropAndPastex::InitCropAndPasteResource(ImageData& inputImage) { + format_ = static_cast(PIXEL_FORMAT_YUV_SEMIPLANAR_420); + if (SY_SUCCESS != InitCropAndPasteInputDesc(inputImage)) { + ERROR_LOG("InitCropAndPasteInputDesc failed"); + return SY_FAILED; + } + + if (SY_SUCCESS != InitCropAndPasteOutputDesc()) { + ERROR_LOG("InitCropAndPasteOutputDesc failed"); + return SY_FAILED; + } + + return SY_SUCCESS; +} + +int DvppCropAndPastex::InitRightCropAndPasteResource(ImageData& inputImage) { + format_ = static_cast(PIXEL_FORMAT_YUV_SEMIPLANAR_420); + if (SY_SUCCESS != InitCropAndPasteInputDesc(inputImage)) { + ERROR_LOG("InitCropAndPasteInputDesc failed"); + return SY_FAILED; + } + + if (SY_SUCCESS != InitRightCropAndPasteOutputDesc()) { + ERROR_LOG("InitCropAndPasteOutputDesc failed"); + return SY_FAILED; + } + + return SY_SUCCESS; +} + +int DvppCropAndPastex::ResizeWithPadding(ImageData& resizedImage, ImageData& srcImage) +{ + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) { + ERROR_LOG("Dvpp cropandpaste failed for init error"); + return SY_FAILED; + } + + uint32_t cropLeftOffset = 0; // must even + uint32_t cropTopOffset = 0; // must even + uint32_t cropRightOffset = (((cropLeftOffset + originalImageWidth_) >> 1) << 1) -1; // must odd + uint32_t cropBottomOffset = (((cropTopOffset + originalImageHeight_) >> 1) << 1) -1; // must odd + + cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, + cropTopOffset, cropBottomOffset); + if (cropArea_ == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed"); + return SY_FAILED; + } + // cout << "====================================================" << endl; + // printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset); + + bool widthRatioSmaller = true; + // The scaling ratio is based on the smaller ratio to ensure the smallest edge to fill the targe edge + float resizeRatio = static_cast(size_.width) / srcImage.width; + if (resizeRatio > (static_cast(size_.height) / srcImage.height)) { + resizeRatio = static_cast(size_.height) / srcImage.height; + widthRatioSmaller = false; + } + + const int halfValue = 2; + uint32_t pasteLeftOffset = 0; + uint32_t pasteRightOffset = 0; + uint32_t pasteTopOffset = 0; + uint32_t pasteBottomOffset = 0; + // The left and up must be even, right and down must be odd which is required by acl + if (widthRatioSmaller) { //宽较长 + pasteLeftOffset = 0; // must even + pasteRightOffset = (((pasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd + // pasteTopOffset = ((static_cast((size_.height - srcImage.height * resizeRatio) / halfValue) >> 1) << 1); // must even + // pasteBottomOffset = (((size_.height - pasteTopOffset) >> 1) << 1) -1; // must odd + //debug=============================================================================================== + float pady = ((size_.height - srcImage.height * resizeRatio) / halfValue); + pasteTopOffset = ((static_cast(pady) >> 1) << 1); // must even + pasteBottomOffset = ((static_cast(size_.height - pady) >> 1) << 1) -1; // must odd + // if((int)(size_.height - srcImage.height * resizeRatio) % 2 ==0){ + // pasteBottomOffset = ((static_cast(size_.height - pady) >> 1) << 1) -1; // must odd + // }else{ + // pasteBottomOffset = ((static_cast(size_.height - pady + 1) >> 1) << 1) -1; // must odd + // } + //debug end============================================================================================ + }else{ //高较长 + uint32_t pad = (static_cast((size_.width - srcImage.width * resizeRatio) / halfValue)); + // printf("debug pad:%d\n",pad); + pasteLeftOffset = (pad + 8) / 16 * 16; // must even,作贴图区域时,需16对齐 + // pasteLeftOffset = ALIGN_UP16(pad); // must even,作贴图区域时,需16对齐 + pasteRightOffset = (((size_.width - pad) >> 1) << 1) -1; // must odd + pasteTopOffset = 0; // must even + pasteBottomOffset = (((pasteTopOffset + size_.height) >> 1) << 1) -1; // must odd + + } + + pasteArea_ = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset, + pasteTopOffset, pasteBottomOffset); + if (pasteArea_ == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed"); + return SY_FAILED; + } + // printf("debug paste area: %d %d %d %d\n", pasteLeftOffset, pasteTopOffset, pasteRightOffset, pasteBottomOffset); + // crop and patse pic + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_, + vpcOutputDesc_, cropArea_, pasteArea_, stream_); + //printf("debug crop line:%d\n",__LINE__); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + return SY_FAILED; + } + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + resizedImage.width = size_.width; + resizedImage.height = size_.height; + resizedImage.alignWidth = ALIGN_UP16(size_.width); + resizedImage.alignHeight = ALIGN_UP2(size_.height); + resizedImage.size = vpcOutBufferSize_; + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_); + + DestroyCropAndPasteResource(); + + return SY_SUCCESS; +} + + + +int DvppCropAndPastex::PatchProcess(ImageData& resizedImage, ImageData& srcImage, uint32_t xmin, uint32_t ymin, + uint32_t xmax, uint32_t ymax) +{ + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) { + ERROR_LOG("Dvpp cropandpaste failed for init error"); + return SY_FAILED; + } + + uint32_t cropLeftOffset = ((xmin >> 1) << 1); // must even + uint32_t cropTopOffset = ((ymin >> 1) << 1); // must even + uint32_t cropRightOffset = ((xmax >> 1) << 1) -1; // must odd + uint32_t cropBottomOffset = ((ymax >> 1) << 1) -1; // must odd + + cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, + cropTopOffset, cropBottomOffset); + if (cropArea_ == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed"); + return SY_FAILED; + } + //printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset); + + uint32_t pasteLeftOffset = 0; // must even + uint32_t pasteTopOffset = 0; // must even + uint32_t pasteRightOffset = (((pasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd + uint32_t pasteBottomOffset = (((pasteTopOffset + size_.height) >> 1) << 1) -1; // must odd + + pasteArea_ = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset, + pasteTopOffset, pasteBottomOffset); + if (pasteArea_ == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed"); + return SY_FAILED; + } + //printf("debug paste area: %d %d %d %d\n", pasteLeftOffset, pasteTopOffset, pasteRightOffset, pasteBottomOffset); + + // crop and patse pic + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_, + vpcOutputDesc_, cropArea_, pasteArea_, stream_); + //printf("debug crop line:%d\n",__LINE__); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + resizedImage.width = size_.width; + resizedImage.height = size_.height; + resizedImage.alignWidth = ALIGN_UP16(size_.width); + resizedImage.alignHeight = ALIGN_UP2(size_.height); + resizedImage.size = vpcOutBufferSize_; + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_); + + DestroyCropAndPasteResource(); + + return SY_SUCCESS; +} + +int DvppCropAndPastex::Crop2Process(ImageData& resizedImage, ImageData& leftImage, ImageData& rightImage, ImageData& srcImage) +{ + //left + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) { + ERROR_LOG("Dvpp cropandpaste failed for init error"); + return SY_FAILED; + } + uint32_t lcropLeftOffset = 0; // must even + uint32_t lcropTopOffset = 0; // must even + uint32_t lcropRightOffset = ((srcImage.width/2 >> 1) << 1) -1; // must odd + uint32_t lcropBottomOffset = ((srcImage.height >> 1) << 1) -1; // must odd + cropArea_ = acldvppCreateRoiConfig(lcropLeftOffset, lcropRightOffset,lcropTopOffset, lcropBottomOffset); + if (cropArea_ == nullptr) { + ERROR_LOG("left acldvppCreateRoiConfig cropArea_ failed"); + return SY_FAILED; + } + //printf("debug left crop area: %d %d %d %d\n", lcropLeftOffset, lcropTopOffset, lcropRightOffset, lcropBottomOffset); + + uint32_t lpasteLeftOffset = 0; // must even + uint32_t lpasteTopOffset = 0; // must even + uint32_t lpasteRightOffset = (((lpasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd + uint32_t lpasteBottomOffset = (((lpasteTopOffset + size_.height) >> 1) << 1) -1; // must odd + pasteArea_ = acldvppCreateRoiConfig(lpasteLeftOffset, lpasteRightOffset,lpasteTopOffset, lpasteBottomOffset); + if (pasteArea_ == nullptr) { + ERROR_LOG("left acldvppCreateRoiConfig pasteArea_ failed"); + return SY_FAILED; + } + //printf("debug left paste area: %d %d %d %d\n", lpasteLeftOffset, lpasteTopOffset, lpasteRightOffset, lpasteBottomOffset); + + // crop and patse pic + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_, + vpcOutputDesc_, cropArea_, pasteArea_, stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("left acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("left crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + leftImage.width = size_.width; + leftImage.height = size_.height; + leftImage.alignWidth = ALIGN_UP16(size_.width); + leftImage.alignHeight = ALIGN_UP2(size_.height); + leftImage.size = vpcOutBufferSize_; + leftImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_); + + DestroyCropAndPasteResource(); + + //right + if (SY_SUCCESS != InitRightCropAndPasteResource(srcImage)) { + ERROR_LOG("Dvpp cropandpaste failed for init error"); + return SY_FAILED; + } + + uint32_t rcropLeftOffset = ((srcImage.width/2 >> 1) << 1); // must even + uint32_t rcropTopOffset = 0; // must even + uint32_t rcropRightOffset = ((srcImage.width >> 1) << 1) -1; // must odd + uint32_t rcropBottomOffset = ((srcImage.height >> 1) << 1) -1; // must odd + cropArea_ = acldvppCreateRoiConfig(rcropLeftOffset, rcropRightOffset, rcropTopOffset, rcropBottomOffset); + if (cropArea_ == nullptr) { + ERROR_LOG("right acldvppCreateRoiConfig cropArea_ failed"); + return SY_FAILED; + } + //printf("debug right crop area: %d %d %d %d\n", rcropLeftOffset, rcropTopOffset, rcropRightOffset, rcropBottomOffset); + + uint32_t rpasteLeftOffset = 0; // must even + uint32_t rpasteTopOffset = 0; // must even + uint32_t rpasteRightOffset = (((rpasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd + uint32_t rpasteBottomOffset = (((rpasteTopOffset + size_.height) >> 1) << 1) -1; // must odd + pasteArea_ = acldvppCreateRoiConfig(rpasteLeftOffset, rpasteRightOffset, rpasteTopOffset, rpasteBottomOffset); + if (pasteArea_ == nullptr) { + ERROR_LOG("right acldvppCreateRoiConfig pasteArea_ failed"); + return SY_FAILED; + } + //printf("debug right paste area: %d %d %d %d\n", rpasteLeftOffset, rpasteTopOffset, rpasteRightOffset, rpasteBottomOffset); + + // crop and patse pic + aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_, + vpcOutputDesc_, cropArea_, pasteArea_, stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("right acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("right crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + rightImage.width = size_.width; + rightImage.height = size_.height; + rightImage.alignWidth = ALIGN_UP16(size_.width); + rightImage.alignHeight = ALIGN_UP2(size_.height); + rightImage.size = vpcOutBufferSize_; + rightImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_); + // rightImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_ + vpcOutBufferSize_); + + DestroyCropAndPasteResource(); + + resizedImage.size = leftImage.size + rightImage.size; + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_); + + return SY_SUCCESS; +} + + +int DvppCropAndPastex::Process(ImageData& resizedImage, ImageData& srcImage) +{ + if (SY_SUCCESS != InitCropAndPasteResource(srcImage)) { + ERROR_LOG("Dvpp cropandpaste failed for init error"); + return SY_FAILED; + } + + uint32_t cropLeftOffset = 0; // must even + uint32_t cropTopOffset = 0; // must even + uint32_t cropRightOffset = (((cropLeftOffset + originalImageWidth_) >> 1) << 1) -1; // must odd + uint32_t cropBottomOffset = (((cropTopOffset + originalImageHeight_) >> 1) << 1) -1; // must odd + + cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, + cropTopOffset, cropBottomOffset); + if (cropArea_ == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed"); + return SY_FAILED; + } + //printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset); + + uint32_t pasteLeftOffset = 0; // must even + uint32_t pasteTopOffset = 0; // must even + uint32_t pasteRightOffset = (((pasteLeftOffset + size_.width) >> 1) << 1) -1; // must odd + uint32_t pasteBottomOffset = (((pasteTopOffset + size_.height) >> 1) << 1) -1; // must odd + + pasteArea_ = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset, + pasteTopOffset, pasteBottomOffset); + if (pasteArea_ == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed"); + return SY_FAILED; + } + //printf("debug paste area: %d %d %d %d\n", pasteLeftOffset, pasteTopOffset, pasteRightOffset, pasteBottomOffset); + + // crop and patse pic + aclError aclRet = acldvppVpcCropAndPasteAsync(dvppChannelDesc_, vpcInputDesc_, + vpcOutputDesc_, cropArea_, pasteArea_, stream_); + //printf("debug crop line:%d\n",__LINE__); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + resizedImage.width = size_.width; + resizedImage.height = size_.height; + resizedImage.alignWidth = ALIGN_UP16(size_.width); + resizedImage.alignHeight = ALIGN_UP2(size_.height); + resizedImage.size = vpcOutBufferSize_; + resizedImage.data = SHARED_PRT_DVPP_BUF(vpcOutBufferDev_); + + DestroyCropAndPasteResource(); + + return SY_SUCCESS; +} + + +void DvppCropAndPastex::DestroyCropAndPasteResource() +{ + if (cropArea_ != nullptr) { + (void)acldvppDestroyRoiConfig(cropArea_); + cropArea_ = nullptr; + } + + if (pasteArea_ != nullptr) { + (void)acldvppDestroyRoiConfig(pasteArea_); + pasteArea_ = nullptr; + } + + if (vpcInputDesc_ != nullptr) { + (void)acldvppDestroyPicDesc(vpcInputDesc_); + vpcInputDesc_ = nullptr; + } + + if (vpcOutputDesc_ != nullptr) { + (void)acldvppDestroyPicDesc(vpcOutputDesc_); + vpcOutputDesc_ = nullptr; + } +} diff --git a/src/common/dvppx/dvpp_cropandpastex.h b/src/common/dvppx/dvpp_cropandpastex.h new file mode 100755 index 0000000..b5106cb --- /dev/null +++ b/src/common/dvppx/dvpp_cropandpastex.h @@ -0,0 +1,97 @@ +/** +* Copyright 2020 Huawei Technologies Co., Ltd +* +* 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. + +* File dvpp_process.h +* Description: handle dvpp process +*/ +#pragma once +#include + +#include "acl/acl.h" +#include "acl/ops/acl_dvpp.h" +#include "utils.h" + +class DvppCropAndPastex { +public: + /** + * @brief Constructor + * @param [in] stream: stream + */ + DvppCropAndPastex(aclrtStream &stream, acldvppChannelDesc *dvppChannelDesc, + uint32_t width, uint32_t height); + + /** + * @brief Destructor + */ + ~DvppCropAndPastex(); + + /** + * @brief dvpp global init + * @return result + */ + int InitResource(); + + /** + * @brief init dvpp output para + * @param [in] modelInputWidth: model input width + * @param [in] modelInputHeight: model input height + * @return result + */ + int InitOutputPara(int modelInputWidth, int modelInputHeight); + + /** + * @brief dvpp process + * @return result + */ + int Process(ImageData& resizedImage, ImageData& srcImage); + int Crop2Process(ImageData& resizedImage, ImageData& leftImage, ImageData& rightImage, ImageData& srcImage); + int PatchProcess(ImageData& resizedImage, ImageData& srcImage, uint32_t xmin, uint32_t ymin, + uint32_t xmax, uint32_t ymax); + + int ResizeWithPadding(ImageData& resizedImage, ImageData& srcImage); + +private: + int InitCropAndPasteResource(ImageData& inputImage); + int InitCropAndPasteInputDesc(ImageData& inputImage); + int InitCropAndPasteOutputDesc(); + + int InitRightCropAndPasteResource(ImageData& inputImage); + int InitRightCropAndPasteOutputDesc(); + + void DestroyCropAndPasteResource(); + + aclrtStream stream_; + acldvppChannelDesc *dvppChannelDesc_; + + + // IN/OUT Desc + acldvppPicDesc *vpcInputDesc_; + acldvppPicDesc *vpcOutputDesc_; + + uint32_t originalImageWidth_; + uint32_t originalImageHeight_; + + acldvppRoiConfig *cropArea_; + acldvppRoiConfig *pasteArea_; + + // output buffer + void *vpcOutBufferDev_; + uint32_t vpcOutBufferSize_; + + //model [W][H] + Resolution size_; + acldvppPixelFormat format_; +}; + diff --git a/src/common/dvppx/dvpp_jpegdx.cpp b/src/common/dvppx/dvpp_jpegdx.cpp new file mode 100755 index 0000000..61cd2d1 --- /dev/null +++ b/src/common/dvppx/dvpp_jpegdx.cpp @@ -0,0 +1,135 @@ +/** +* Copyright 2020 Huawei Technologies Co., Ltd +* +* 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. + +* File dvpp_process.cpp +* Description: handle dvpp process +*/ + +#include +#include "acl/acl.h" +#include "dvpp_jpegdx.h" +#include "utils.h" +#include "sy_errorinfo.h" +using namespace std; + +DvppJpegDx::DvppJpegDx(aclrtStream& stream, acldvppChannelDesc *dvppChannelDesc) + : stream_(stream), dvppChannelDesc_(dvppChannelDesc), + decodeOutBufferDev_(nullptr), decodeOutputDesc_(nullptr), + decodeOutWidthStride_(0), decodeOutHeightStride_(0) +{ +} + +DvppJpegDx::~DvppJpegDx() +{ + DestroyDecodeResource(); +} + + +int DvppJpegDx::InitDecodeOutputDesc(ImageData& inputImage) +{ + //230316 ascend310p兼容================================================= + auto socVersion = aclrtGetSocName(); + if (strncmp(socVersion, "Ascend310P3", sizeof("Ascend310P3") - 1) == 0) { + decodeOutWidth_ = ALIGN_UP2(inputImage.width); + decodeOutHeight_ = ALIGN_UP2(inputImage.height); + decodeOutWidthStride_ = ALIGN_UP64(inputImage.width); // 64-byte alignment + decodeOutHeightStride_ = ALIGN_UP16(inputImage.height); // 16-byte alignment + } else { + decodeOutWidth_ = inputImage.width; + decodeOutHeight_ = inputImage.height; + decodeOutWidthStride_ = ALIGN_UP128(inputImage.width); // 128-byte alignment + decodeOutHeightStride_ = ALIGN_UP16(inputImage.height); // 16-byte alignment + } + if (decodeOutWidthStride_ == 0 || decodeOutHeightStride_ == 0) { + ERROR_LOG("InitDecodeOutputDesc AlignmentHelper failed"); + return SY_FAILED; + } + //===================================================================== + + acldvppJpegPredictDecSize(inputImage.data.get(), inputImage.size, + PIXEL_FORMAT_YUV_SEMIPLANAR_420, &decodeOutBufferSize_); + + aclError aclRet = acldvppMalloc(&decodeOutBufferDev_, decodeOutBufferSize_); + //debug======================================================================== + uint32_t size = ALIGN_UP(decodeOutBufferSize_,32) + 32; + aclRet = aclrtMemset(decodeOutBufferDev_,size, 128, size); + // aclRet = aclrtMemset(decodeOutBufferDev_,decodeOutBufferSize_, 0, decodeOutBufferSize_); + //debug end==================================================================== + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppMalloc decodeOutBufferDev_ failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + decodeOutputDesc_ = acldvppCreatePicDesc(); + if (decodeOutputDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc decodeOutputDesc_ failed"); + return SY_FAILED; + } + + acldvppSetPicDescData(decodeOutputDesc_, decodeOutBufferDev_); + acldvppSetPicDescFormat(decodeOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + acldvppSetPicDescWidth(decodeOutputDesc_, decodeOutWidth_); + acldvppSetPicDescHeight(decodeOutputDesc_, decodeOutHeight_); + acldvppSetPicDescWidthStride(decodeOutputDesc_, decodeOutWidthStride_); + acldvppSetPicDescHeightStride(decodeOutputDesc_, decodeOutHeightStride_); + acldvppSetPicDescSize(decodeOutputDesc_, decodeOutBufferSize_); + return SY_SUCCESS; +} + + +int DvppJpegDx::Process(ImageData& dest, ImageData& src) +{ + int ret = InitDecodeOutputDesc(src); + if (ret != SY_SUCCESS) { + ERROR_LOG("InitDecodeOutputDesc failed"); + return SY_FAILED; + } + + ImageData imageDevice; + Utils::CopyImageDataToDvpp(imageDevice, src); + + //TODO: + aclError aclRet = acldvppJpegDecodeAsync(dvppChannelDesc_, reinterpret_cast(imageDevice.data.get()), + imageDevice.size, decodeOutputDesc_, stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppJpegDecodeAsync failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("decode aclrtSynchronizeStream failed, aclRet = %d", aclRet); + return SY_FAILED; + } + + dest.width = decodeOutWidth_; + dest.height = decodeOutHeight_; + dest.alignWidth = decodeOutWidthStride_; + dest.alignHeight = decodeOutHeightStride_; + dest.size = YUV420SP_SIZE(dest.alignWidth, dest.alignHeight); + dest.data = SHARED_PRT_DVPP_BUF(decodeOutBufferDev_); + // cout << "dvpp w:" << dest.width << " h:" << dest.height << " alignw:" << dest.alignWidth <<" alignh:" < +#include +#include "acl/acl.h" +#include "acl/ops/acl_dvpp.h" +#include "utils.h" + + +/** + * DvppProcess + */ +class DvppJpegDx { +public: + /** + * @brief Constructor + * @param [in] stream: stream + */ + DvppJpegDx(aclrtStream &stream, acldvppChannelDesc *dvppChannelDesc); + + /** + * @brief Destructor + */ + ~DvppJpegDx(); + + /** + * @brief dvpp global init + * @return result + */ + int InitResource(); + + /** + * @brief init dvpp output para + * @param [in] modelInputWidth: model input width + * @param [in] modelInputHeight: model input height + * @return result + */ + int InitOutputPara(int modelInputWidth, int modelInputHeight); + + /** + * @brief set jpegd input + * @param [in] inDevBuffer: device buffer of input pic + * @param [in] inDevBufferSize: device buffer size of input pic + * @param [in] inputWidth:width of pic + * @param [in] inputHeight:height of pic + */ + void SetInput4JpegD(uint8_t* inDevBuffer, int inDevBufferSize, int inputWidth, int inputHeight); + int InitDecodeOutputDesc(ImageData& inputImage); + /** + * @brief gett dvpp output + * @param [in] outputBuffer: pointer which points to dvpp output buffer + * @param [out] outputSize: output size + */ + void GetOutput(void **outputBuffer, int &outputSize); + int Process(ImageData& dest, ImageData& src); + /** + * @brief release encode resource + */ + void DestroyEncodeResource(); + +private: + void DestroyDecodeResource(); + void DestroyResource(); + void DestroyOutputPara(); + + aclrtStream stream_; + acldvppChannelDesc *dvppChannelDesc_; + + void* decodeOutBufferDev_; // decode output buffer + acldvppPicDesc *decodeOutputDesc_; //decode output desc + + uint8_t *inDevBuffer_; // input pic dev buffer + uint32_t inDevBufferSizeD_; // input pic size for decode + + void *vpcOutBufferDev_; // vpc output buffer + uint32_t vpcOutBufferSize_; // vpc output size + //230316added + uint32_t decodeOutWidth_; + uint32_t decodeOutHeight_; + uint32_t decodeOutWidthStride_; + uint32_t decodeOutHeightStride_; + uint32_t decodeOutBufferSize_; +}; + diff --git a/src/common/dvppx/dvpp_processx.cpp b/src/common/dvppx/dvpp_processx.cpp new file mode 100755 index 0000000..e3cd0c7 --- /dev/null +++ b/src/common/dvppx/dvpp_processx.cpp @@ -0,0 +1,1038 @@ +/** +* Copyright 2020 Huawei Technologies Co., Ltd +* +* 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. + +* File dvpp_process.cpp +* Description: handle dvpp process +*/ + +#include +#include "acl/acl.h" +#include "dvpp_cropandpastex.h" +#include "dvpp_jpegdx.h" +#include "dvpp_processx.h" +#include "sy_errorinfo.h" + +using namespace std; + +DvppProcessx::DvppProcessx() + : isInitOk_(false), dvppChannelDesc_(nullptr) { + isGlobalContext_ = false; +} + +DvppProcessx::~DvppProcessx() +{ + DestroyResource(); +} + +void DvppProcessx::DestroyResource() +{ + aclError aclRet; + if (dvppChannelDesc_ != nullptr) { + aclRet = acldvppDestroyChannel(dvppChannelDesc_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppDestroyChannel failed, aclRet = %d", aclRet); + } + + (void)acldvppDestroyChannelDesc(dvppChannelDesc_); + dvppChannelDesc_ = nullptr; + } + + //INFO_LOG("end to destroy context"); +} + +int DvppProcessx::InitResource(aclrtStream& stream) +{ + aclError aclRet; + // create vpc channel description + dvppChannelDesc_ = acldvppCreateChannelDesc(); + if (dvppChannelDesc_ == nullptr) { + ERROR_LOG("acldvppCreateChannelDesc failed"); + return SY_FAILED; + } + // create vpc channel + aclRet = acldvppCreateChannel(dvppChannelDesc_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppCreateChannel failed, aclRet = %d", aclRet); + return SY_FAILED; + } + stream_ = stream; + isInitOk_ = true; + //INFO_LOG("dvpp init resource ok"); + return SY_SUCCESS; +} + + +int DvppProcessx::CropAndPaste(ImageData& dest, ImageData& src, + uint32_t width, uint32_t height) { + DvppCropAndPastex cropandpasteOp(stream_, dvppChannelDesc_, width, height); + return cropandpasteOp.Process(dest, src); +} + +int DvppProcessx::Crop2Paste(ImageData& dest, ImageData& leftImage, ImageData& rightImage, + ImageData& src,uint32_t width, uint32_t height) { + DvppCropAndPastex cro2pasteOp(stream_, dvppChannelDesc_, width, height); + return cro2pasteOp.Crop2Process(dest, leftImage, rightImage, src); +} + + +int DvppProcessx::CropAndPadding(ImageData& dest, ImageData& src, + uint32_t width, uint32_t height) { + DvppCropAndPastex cropandpaddingOp(stream_, dvppChannelDesc_, width, height); + return cropandpaddingOp.ResizeWithPadding(dest, src); +} + + +int DvppProcessx::PatchCropAndPaste(ImageData& dest, ImageData& src, uint32_t xmin, uint32_t ymin, + uint32_t xmax, uint32_t ymax, uint32_t width, uint32_t height) { + DvppCropAndPastex patchcropandpasteOp(stream_, dvppChannelDesc_, width, height); + return patchcropandpasteOp.PatchProcess(dest, src, xmin, ymin, xmax, ymax); +} + +int DvppProcessx::CvtJpegToYuv420sp(ImageData& dest, ImageData& src) { + DvppJpegDx jpegD(stream_, dvppChannelDesc_); + return jpegD.Process(dest, src); +} + +// acldvppVpcConvertColorAsync 310/910暂不支持该接口 +int DvppProcessx::ConvertColor(PicDesc& inPicDesc, PicDesc& outPicDesc) +{ + // Input description + acldvppPicDesc* inputDesc = acldvppCreatePicDesc(); + acldvppSetPicDescData(inputDesc, inPicDesc.dataBuffer); + acldvppSetPicDescFormat(inputDesc, inPicDesc.format); + acldvppSetPicDescWidth(inputDesc, inPicDesc.width); + acldvppSetPicDescHeight(inputDesc, inPicDesc.height); + acldvppSetPicDescWidthStride(inputDesc, inPicDesc.widthStride); + acldvppSetPicDescHeightStride(inputDesc, inPicDesc.heightStride); + acldvppSetPicDescSize(inputDesc, inPicDesc.dataSize); + + // Output description + int outWidthStride = ALIGN_UP16(inPicDesc.width) * 3; //Output RGB, so *3 + int outHeightStride = ALIGN_UP2(inPicDesc.height); + outPicDesc.width = inPicDesc.width; + outPicDesc.height = inPicDesc.height; + outPicDesc.widthStride = outWidthStride; + outPicDesc.heightStride = outHeightStride; + outPicDesc.dataSize = outWidthStride * outHeightStride; + aclError ret = acldvppMalloc(&outPicDesc.dataBuffer, outPicDesc.dataSize); + if (ret != ACL_SUCCESS) { + ERROR_LOG("ConvertColor acldvppMalloc failed, errorCode = %d", static_cast(ret)); + return SY_FAILED; + } + + acldvppPicDesc* outputDesc = acldvppCreatePicDesc(); + acldvppSetPicDescData(outputDesc, outPicDesc.dataBuffer); + acldvppSetPicDescFormat(outputDesc, outPicDesc.format); + acldvppSetPicDescWidth(outputDesc, outPicDesc.width); + acldvppSetPicDescHeight(outputDesc, outPicDesc.height); + acldvppSetPicDescWidthStride(outputDesc, outPicDesc.widthStride); + acldvppSetPicDescHeightStride(outputDesc, outPicDesc.heightStride); + acldvppSetPicDescSize(outputDesc, outPicDesc.dataSize); + + // Execute ConvertColor + ret = acldvppVpcConvertColorAsync(dvppChannelDesc_, inputDesc, outputDesc, stream_); + if (ret != ACL_SUCCESS) { + ERROR_LOG("ConvertColor acldvppVpcConvertColorAsync failed, errorCode = %d", static_cast(ret)); + return SY_FAILED; + } + ret = aclrtSynchronizeStream(stream_); + if (ret != ACL_SUCCESS) { + ERROR_LOG("ConvertColor aclrtSynchronizeStream failed, errorCode = %d", static_cast(ret)); + return SY_FAILED; + } + + acldvppDestroyPicDesc(inputDesc); + acldvppDestroyPicDesc(outputDesc); + + return SY_SUCCESS; +} + + + +int DvppProcessx::CropAndPaddingBatch(ImageData* src, ImageData* dest, int batchsize, uint32_t output_width, uint32_t output_height) { + + const uint32_t inputBatchSize_ = batchsize; + const uint32_t outputBatchSize_ = batchsize; + if(inputBatchSize_ <= 0 || outputBatchSize_ <= 0) { + return SY_FAILED; + } + + aclError ret; + + // 输入 + acldvppBatchPicDesc *vpcInputBatchDesc_ = acldvppCreateBatchPicDesc(inputBatchSize_); + if (vpcInputBatchDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed"); + return SY_FAILED; + } + + vector vecInPtr_; + for (uint32_t i = 0; i < inputBatchSize_; i++) { + void *inputBufferDev = src[i].data.get(); + uint32_t inputBufferSize = src[i].size; + + vecInPtr_.push_back(inputBufferDev); + acldvppPicDesc *vpcInputDesc = acldvppGetPicDesc(vpcInputBatchDesc_, i); + (void)acldvppSetPicDescData(vpcInputDesc, inputBufferDev); + (void)acldvppSetPicDescFormat(vpcInputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcInputDesc, src[i].width); + (void)acldvppSetPicDescHeight(vpcInputDesc, src[i].height); + (void)acldvppSetPicDescWidthStride(vpcInputDesc, src[i].alignWidth); + (void)acldvppSetPicDescHeightStride(vpcInputDesc, src[i].alignHeight); + (void)acldvppSetPicDescSize(vpcInputDesc, inputBufferSize); + } + + // 输出 + acldvppBatchPicDesc *outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_); + if (outputBatchPicDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed"); + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + return SY_FAILED; + } + vector vecOutPtr_; + acldvppPicDesc *vpcOutputDesc = nullptr; + acldvppRoiConfig *cropAreas[outputBatchSize_]; + acldvppRoiConfig *pasteAreas[outputBatchSize_]; + for (uint32_t i = 0; i < outputBatchSize_; i++) { + + uint32_t cropLeftOffset = 0; // must even + uint32_t cropTopOffset = 0; // must even + uint32_t cropRightOffset = (((cropLeftOffset + src[i].width) >> 1) << 1) -1; // must odd + uint32_t cropBottomOffset = (((cropTopOffset + src[i].height) >> 1) << 1) -1; // must odd + + cropAreas[i] = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); + if (cropAreas[i] == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed"); + // 释放之前成功的部分 再退出 + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + // printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset); + + bool widthRatioSmaller = true; + // The scaling ratio is based on the smaller ratio to ensure the smallest edge to fill the targe edge + float resizeRatio = static_cast(output_width) / src[i].width; + if (resizeRatio > (static_cast(output_height) / src[i].height)) { + resizeRatio = static_cast(output_height) / src[i].height; + widthRatioSmaller = false; + } + + const int halfValue = 2; + uint32_t pasteLeftOffset = 0, pasteRightOffset = 0, pasteTopOffset = 0, pasteBottomOffset = 0; + // The left and up must be even, right and down must be odd which is required by acl + if (widthRatioSmaller) { //宽较长 + pasteLeftOffset = 0; // must even + pasteRightOffset = (((pasteLeftOffset + output_width) >> 1) << 1) -1; // must odd + //debug=============================================================================================== + float pady = ((output_height - src[i].height * resizeRatio) / halfValue); + pasteTopOffset = ((static_cast(pady) >> 1) << 1); // must even + pasteBottomOffset = ((static_cast(output_height - pady) >> 1) << 1) -1; // must odd + //debug end============================================================================================ + }else { //高较长 + uint32_t pad = (static_cast((output_width - src[i].width * resizeRatio) / halfValue)); + // printf("debug pad:%d\n",pad); + pasteLeftOffset = (pad + 8) / 16 * 16; // must even,作贴图区域时,需16对齐 + pasteRightOffset = (((output_width - pad) >> 1) << 1) -1; // must odd + pasteTopOffset = 0; // must even + pasteBottomOffset = (((pasteTopOffset + output_height) >> 1) << 1) -1; // must odd + } + + pasteAreas[i] = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset, pasteTopOffset, pasteBottomOffset); + if (pasteAreas[i] == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed"); + // 释放之前成功的部分 再退出 + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + + int resizeOutWidth = output_width; + int resizeOutHeight = output_height; + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth); + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight); + + uint32_t vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride); + // uint32_t vpcOutBufferSize_ = ALIGN_UP(YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride),32) + 32; + void *vpcBatchOutputBufferDev = nullptr; + auto ret = acldvppMalloc(&vpcBatchOutputBufferDev, vpcOutBufferSize_); + //debug======================================================================== + ret = aclrtMemset(vpcBatchOutputBufferDev,vpcOutBufferSize_, 128, vpcOutBufferSize_); + //debug end==================================================================== + if (ret != ACL_SUCCESS) { + ERROR_LOG("acldvppMalloc failed, size = %u, errorCode = %d.", vpcOutBufferSize_, static_cast(ret)); + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + vecOutPtr_.push_back(vpcBatchOutputBufferDev); + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + (void)acldvppSetPicDescData(vpcOutputDesc, vpcBatchOutputBufferDev); + (void)acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcOutputDesc, resizeOutWidth); + (void)acldvppSetPicDescHeight(vpcOutputDesc, resizeOutHeight); + (void)acldvppSetPicDescWidthStride(vpcOutputDesc, resizeOutWidthStride); + (void)acldvppSetPicDescHeightStride(vpcOutputDesc, resizeOutHeightStride); + (void)acldvppSetPicDescSize(vpcOutputDesc, vpcOutBufferSize_); + } + + bool bRet = false; + do { + // calculate total number of crop image + uint32_t totalNum = 0; + std::unique_ptr roiNums(new (std::nothrow) uint32_t[inputBatchSize_]); + if (roiNums != nullptr){ + for (int i = 0; i < inputBatchSize_; i++) { + // crop number of images from one source image is outputBatchSize_ / inputBatchSize_ + roiNums[i] = outputBatchSize_ / inputBatchSize_; + totalNum += roiNums[i]; + } + } + // crop number of images from last source image is:outputBatchSize_ / inputBatchSize_ + outputBatchSize_ % inputBatchSize_ + if (outputBatchSize_ % inputBatchSize_ != 0) { + roiNums[inputBatchSize_ - 1] = (outputBatchSize_ - totalNum) + roiNums[inputBatchSize_ - 1]; + } + + aclError aclRet = acldvppVpcBatchCropAndPasteAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums.get(), inputBatchSize_, outputBatchPicDesc_, cropAreas, pasteAreas, stream_); // + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + break; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + break; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + void *outputDataDev = acldvppGetPicDescData(vpcOutputDesc); + uint32_t outputSize = acldvppGetPicDescSize(vpcOutputDesc); + uint32_t width = acldvppGetPicDescWidth(vpcOutputDesc); + uint32_t width_stride = acldvppGetPicDescWidthStride(vpcOutputDesc); + uint32_t height = acldvppGetPicDescHeight(vpcOutputDesc); + uint32_t height_stride = acldvppGetPicDescHeightStride(vpcOutputDesc); + acldvppPixelFormat fmt = acldvppGetPicDescFormat(vpcOutputDesc); + + dest[i].width = width; + dest[i].height = height; + dest[i].alignWidth = width_stride; + dest[i].alignHeight = height_stride; + dest[i].size = outputSize; + dest[i].data = SHARED_PRT_DVPP_BUF(outputDataDev); + } + + bRet = true; + } while (0); + + if (vpcInputBatchDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + vpcInputBatchDesc_ = nullptr; + } + + if (!bRet){ + for(int i = 0; i < vecOutPtr_.size(); i++){ + if (vecOutPtr_[i] != nullptr){ + acldvppFree(vecOutPtr_[i]); + } + } + } + + if (outputBatchPicDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(outputBatchPicDesc_); + outputBatchPicDesc_ = nullptr; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + if (cropAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[i]); + cropAreas[i] = nullptr; + } + if (pasteAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[i]); + pasteAreas[i] = nullptr; + } + } + + return SY_SUCCESS; +} + + +int DvppProcessx::CropAndPasteBatch(ImageData* src, ImageData* dest, int batchsize, uint32_t output_width, uint32_t output_height) { + + const uint32_t inputBatchSize_ = batchsize; + const uint32_t outputBatchSize_ = batchsize; + if(inputBatchSize_ <= 0 || outputBatchSize_ <= 0) { + return SY_FAILED; + } + + aclError ret; + + // 输入 + acldvppBatchPicDesc *vpcInputBatchDesc_ = acldvppCreateBatchPicDesc(inputBatchSize_); + if (vpcInputBatchDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed"); + return SY_FAILED; + } + + vector vecInPtr_; + for (uint32_t i = 0; i < inputBatchSize_; i++) { + void *inputBufferDev = src[i].data.get(); + uint32_t inputBufferSize = src[i].size; + + vecInPtr_.push_back(inputBufferDev); + acldvppPicDesc *vpcInputDesc = acldvppGetPicDesc(vpcInputBatchDesc_, i); + (void)acldvppSetPicDescData(vpcInputDesc, inputBufferDev); + (void)acldvppSetPicDescFormat(vpcInputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcInputDesc, src[i].width); + (void)acldvppSetPicDescHeight(vpcInputDesc, src[i].height); + (void)acldvppSetPicDescWidthStride(vpcInputDesc, src[i].alignWidth); + (void)acldvppSetPicDescHeightStride(vpcInputDesc, src[i].alignHeight); + (void)acldvppSetPicDescSize(vpcInputDesc, inputBufferSize); + } + + // 输出 + acldvppBatchPicDesc *outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_); + if (outputBatchPicDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed"); + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + return SY_FAILED; + } + vector vecOutPtr_; + acldvppPicDesc *vpcOutputDesc = nullptr; + acldvppRoiConfig *cropAreas[outputBatchSize_]; + acldvppRoiConfig *pasteAreas[outputBatchSize_]; + for (uint32_t i = 0; i < outputBatchSize_; i++) { + + uint32_t cropLeftOffset = 0; // must even + uint32_t cropTopOffset = 0; // must even + uint32_t cropRightOffset = (((cropLeftOffset + src[i].width) >> 1) << 1) -1; // must odd + uint32_t cropBottomOffset = (((cropTopOffset + src[i].height) >> 1) << 1) -1; // must odd + + cropAreas[i] = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); + if (cropAreas[i] == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed"); + // 释放之前成功的部分 再退出 + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + // printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset); + + uint32_t pasteLeftOffset = 0; // must even + uint32_t pasteTopOffset = 0; // must even + uint32_t pasteRightOffset = (((pasteLeftOffset + output_width) >> 1) << 1) -1; // must odd + uint32_t pasteBottomOffset = (((pasteTopOffset + output_height) >> 1) << 1) -1; // must odd + + pasteAreas[i] = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset, pasteTopOffset, pasteBottomOffset); + if (pasteAreas[i] == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed"); + // 释放之前成功的部分 再退出 + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + + int resizeOutWidth = output_width; + int resizeOutHeight = output_height; + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth); + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight); + + uint32_t vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride); + // uint32_t vpcOutBufferSize_ = ALIGN_UP(YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride),32) + 32; + void *vpcBatchOutputBufferDev = nullptr; + auto ret = acldvppMalloc(&vpcBatchOutputBufferDev, vpcOutBufferSize_); + //debug======================================================================== + ret = aclrtMemset(vpcBatchOutputBufferDev,vpcOutBufferSize_, 128, vpcOutBufferSize_); + //debug end==================================================================== + if (ret != ACL_SUCCESS) { + ERROR_LOG("acldvppMalloc failed, size = %u, errorCode = %d.", vpcOutBufferSize_, static_cast(ret)); + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + vecOutPtr_.push_back(vpcBatchOutputBufferDev); + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + (void)acldvppSetPicDescData(vpcOutputDesc, vpcBatchOutputBufferDev); + (void)acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcOutputDesc, resizeOutWidth); + (void)acldvppSetPicDescHeight(vpcOutputDesc, resizeOutHeight); + (void)acldvppSetPicDescWidthStride(vpcOutputDesc, resizeOutWidthStride); + (void)acldvppSetPicDescHeightStride(vpcOutputDesc, resizeOutHeightStride); + (void)acldvppSetPicDescSize(vpcOutputDesc, vpcOutBufferSize_); + } + + bool bRet = false; + do { + // calculate total number of crop image + uint32_t totalNum = 0; + std::unique_ptr roiNums(new (std::nothrow) uint32_t[inputBatchSize_]); + if (roiNums != nullptr){ + for (int i = 0; i < inputBatchSize_; i++) { + // crop number of images from one source image is outputBatchSize_ / inputBatchSize_ + roiNums[i] = outputBatchSize_ / inputBatchSize_; + totalNum += roiNums[i]; + } + } + // crop number of images from last source image is:outputBatchSize_ / inputBatchSize_ + outputBatchSize_ % inputBatchSize_ + if (outputBatchSize_ % inputBatchSize_ != 0) { + roiNums[inputBatchSize_ - 1] = (outputBatchSize_ - totalNum) + roiNums[inputBatchSize_ - 1]; + } + + aclError aclRet = acldvppVpcBatchCropAndPasteAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums.get(), inputBatchSize_, outputBatchPicDesc_, cropAreas, pasteAreas, stream_); // + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + break; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + break; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + void *outputDataDev = acldvppGetPicDescData(vpcOutputDesc); + uint32_t outputSize = acldvppGetPicDescSize(vpcOutputDesc); + uint32_t width = acldvppGetPicDescWidth(vpcOutputDesc); + uint32_t width_stride = acldvppGetPicDescWidthStride(vpcOutputDesc); + uint32_t height = acldvppGetPicDescHeight(vpcOutputDesc); + uint32_t height_stride = acldvppGetPicDescHeightStride(vpcOutputDesc); + acldvppPixelFormat fmt = acldvppGetPicDescFormat(vpcOutputDesc); + + /* + acldvppPicDesc *vpcInputDesc_= acldvppCreatePicDesc(); + acldvppSetPicDescData(vpcInputDesc_, vecOutPtr_[i]); + acldvppSetPicDescFormat(vpcInputDesc_, fmt); + acldvppSetPicDescWidth(vpcInputDesc_, width); + acldvppSetPicDescHeight(vpcInputDesc_, height); + acldvppSetPicDescWidthStride(vpcInputDesc_, width_stride); + acldvppSetPicDescHeightStride(vpcInputDesc_, height_stride); + acldvppSetPicDescSize(vpcInputDesc_, outputSize);*/ + + dest[i].width = width; + dest[i].height = height; + dest[i].alignWidth = ALIGN_UP16(width); + dest[i].alignHeight = ALIGN_UP2(height); + dest[i].size = outputSize; + dest[i].data = SHARED_PRT_DVPP_BUF(outputDataDev); + + } + + bRet = true; + } while (0); + + + if (vpcInputBatchDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + vpcInputBatchDesc_ = nullptr; + } + + if (!bRet){ + for(int i = 0; i < vecOutPtr_.size(); i++){ + if (vecOutPtr_[i] != nullptr){ + acldvppFree(vecOutPtr_[i]); + } + } + } + + if (outputBatchPicDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(outputBatchPicDesc_); + outputBatchPicDesc_ = nullptr; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + if (cropAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[i]); + cropAreas[i] = nullptr; + } + if (pasteAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[i]); + pasteAreas[i] = nullptr; + } + } + + return SY_SUCCESS; +} + + +int DvppProcessx::CropAndPasteBatchV2(ImageData* src, ImageData* dest, PicRoi* PicRois, int batchsize, uint32_t output_width, uint32_t output_height) { + + const uint32_t inputBatchSize_ = batchsize; + const uint32_t outputBatchSize_ = batchsize; + if(inputBatchSize_ <= 0 || outputBatchSize_ <= 0) { + return SY_FAILED; + } + + aclError ret; + + // 输入 + acldvppBatchPicDesc *vpcInputBatchDesc_ = acldvppCreateBatchPicDesc(inputBatchSize_); + if (vpcInputBatchDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed"); + return SY_FAILED; + } + + vector vecInPtr_; + for (uint32_t i = 0; i < inputBatchSize_; i++) { + void *inputBufferDev = src[i].data.get(); + uint32_t inputBufferSize = src[i].size; + + vecInPtr_.push_back(inputBufferDev); + acldvppPicDesc *vpcInputDesc = acldvppGetPicDesc(vpcInputBatchDesc_, i); + (void)acldvppSetPicDescData(vpcInputDesc, inputBufferDev); + (void)acldvppSetPicDescFormat(vpcInputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcInputDesc, src[i].width); + (void)acldvppSetPicDescHeight(vpcInputDesc, src[i].height); + (void)acldvppSetPicDescWidthStride(vpcInputDesc, src[i].alignWidth); + (void)acldvppSetPicDescHeightStride(vpcInputDesc, src[i].alignHeight); + (void)acldvppSetPicDescSize(vpcInputDesc, inputBufferSize); + } + + // 输出 + acldvppBatchPicDesc *outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_); + if (outputBatchPicDesc_ == nullptr) { + ERROR_LOG("acldvppCreatePicDesc outBatchPicDesc failed"); + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + return SY_FAILED; + } + vector vecOutPtr_; + acldvppPicDesc *vpcOutputDesc = nullptr; + acldvppRoiConfig *cropAreas[outputBatchSize_]; + acldvppRoiConfig *pasteAreas[outputBatchSize_]; + for (uint32_t i = 0; i < outputBatchSize_; i++) { + + uint32_t cropLeftOffset = ((PicRois[i].xmin >> 1) << 1); // must even + uint32_t cropTopOffset = ((PicRois[i].ymin >> 1) << 1); // must even + uint32_t cropRightOffset = ((PicRois[i].xmax >> 1) << 1) -1; // must odd + uint32_t cropBottomOffset = ((PicRois[i].ymax >> 1) << 1) -1; // must odd + + cropAreas[i] = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); + if (cropAreas[i] == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig cropArea_ failed"); + // 释放之前成功的部分 再退出 + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + // printf("debug crop area: %d %d %d %d\n", cropLeftOffset, cropTopOffset, cropRightOffset, cropBottomOffset); + + uint32_t pasteLeftOffset = 0; // must even + uint32_t pasteTopOffset = 0; // must even + uint32_t pasteRightOffset = (((pasteLeftOffset + output_width) >> 1) << 1) -1; // must odd + uint32_t pasteBottomOffset = (((pasteTopOffset + output_height) >> 1) << 1) -1; // must odd + + pasteAreas[i] = acldvppCreateRoiConfig(pasteLeftOffset, pasteRightOffset, pasteTopOffset, pasteBottomOffset); + if (pasteAreas[i] == nullptr) { + ERROR_LOG("acldvppCreateRoiConfig pasteArea_ failed"); + // 释放之前成功的部分 再退出 + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + + int resizeOutWidth = output_width; + int resizeOutHeight = output_height; + int resizeOutWidthStride = ALIGN_UP16(resizeOutWidth); + int resizeOutHeightStride = ALIGN_UP2(resizeOutHeight); + + uint32_t vpcOutBufferSize_ = YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride); + // uint32_t vpcOutBufferSize_ = ALIGN_UP(YUV420SP_SIZE(resizeOutWidthStride, resizeOutHeightStride),32) + 32; + void *vpcBatchOutputBufferDev = nullptr; + auto ret = acldvppMalloc(&vpcBatchOutputBufferDev, vpcOutBufferSize_); + //debug======================================================================== + ret = aclrtMemset(vpcBatchOutputBufferDev,vpcOutBufferSize_, 128, vpcOutBufferSize_); + //debug end==================================================================== + if (ret != ACL_SUCCESS) { + ERROR_LOG("acldvppMalloc failed, size = %u, errorCode = %d.", vpcOutBufferSize_, static_cast(ret)); + for(int j = 0; j < vecOutPtr_.size(); j++) { + if (vecOutPtr_[j] != nullptr) { acldvppFree(vecOutPtr_[j]); } + if (cropAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[j]); cropAreas[j] = nullptr; + } + if (pasteAreas[j] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[j]); pasteAreas[j] = nullptr; + } + } + return SY_FAILED; + } + vecOutPtr_.push_back(vpcBatchOutputBufferDev); + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + (void)acldvppSetPicDescData(vpcOutputDesc, vpcBatchOutputBufferDev); + (void)acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcOutputDesc, resizeOutWidth); + (void)acldvppSetPicDescHeight(vpcOutputDesc, resizeOutHeight); + (void)acldvppSetPicDescWidthStride(vpcOutputDesc, resizeOutWidthStride); + (void)acldvppSetPicDescHeightStride(vpcOutputDesc, resizeOutHeightStride); + (void)acldvppSetPicDescSize(vpcOutputDesc, vpcOutBufferSize_); + } + + bool bRet = false; + do { + // calculate total number of crop image + uint32_t totalNum = 0; + std::unique_ptr roiNums(new (std::nothrow) uint32_t[inputBatchSize_]); + if (roiNums != nullptr){ + for (int i = 0; i < inputBatchSize_; i++) { + // crop number of images from one source image is outputBatchSize_ / inputBatchSize_ + roiNums[i] = outputBatchSize_ / inputBatchSize_; + totalNum += roiNums[i]; + } + } + // crop number of images from last source image is:outputBatchSize_ / inputBatchSize_ + outputBatchSize_ % inputBatchSize_ + if (outputBatchSize_ % inputBatchSize_ != 0) { + roiNums[inputBatchSize_ - 1] = (outputBatchSize_ - totalNum) + roiNums[inputBatchSize_ - 1]; + } + + aclError aclRet = acldvppVpcBatchCropAndPasteAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums.get(), inputBatchSize_, outputBatchPicDesc_, cropAreas, pasteAreas, stream_); // + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("acldvppVpcCropAndPasteAsync failed, aclRet = %d", aclRet); + break; + } + + aclRet = aclrtSynchronizeStream(stream_); + if (aclRet != ACL_SUCCESS) { + ERROR_LOG("crop and paste aclrtSynchronizeStream failed, aclRet = %d", aclRet); + break; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + void *outputDataDev = acldvppGetPicDescData(vpcOutputDesc); + uint32_t outputSize = acldvppGetPicDescSize(vpcOutputDesc); + uint32_t width = acldvppGetPicDescWidth(vpcOutputDesc); + uint32_t width_stride = acldvppGetPicDescWidthStride(vpcOutputDesc); + uint32_t height = acldvppGetPicDescHeight(vpcOutputDesc); + uint32_t height_stride = acldvppGetPicDescHeightStride(vpcOutputDesc); + acldvppPixelFormat fmt = acldvppGetPicDescFormat(vpcOutputDesc); + + /* + acldvppPicDesc *vpcInputDesc_= acldvppCreatePicDesc(); + acldvppSetPicDescData(vpcInputDesc_, vecOutPtr_[i]); + acldvppSetPicDescFormat(vpcInputDesc_, fmt); + acldvppSetPicDescWidth(vpcInputDesc_, width); + acldvppSetPicDescHeight(vpcInputDesc_, height); + acldvppSetPicDescWidthStride(vpcInputDesc_, width_stride); + acldvppSetPicDescHeightStride(vpcInputDesc_, height_stride); + acldvppSetPicDescSize(vpcInputDesc_, outputSize);*/ + + dest[i].width = width; + dest[i].height = height; + dest[i].alignWidth = ALIGN_UP16(width); + dest[i].alignHeight = ALIGN_UP2(height); + dest[i].size = outputSize; + dest[i].data = SHARED_PRT_DVPP_BUF(outputDataDev); + } + + bRet = true; + } while (0); + + + if (vpcInputBatchDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + vpcInputBatchDesc_ = nullptr; + } + + if (!bRet){ + for(int i = 0; i < vecOutPtr_.size(); i++){ + if (vecOutPtr_[i] != nullptr){ + acldvppFree(vecOutPtr_[i]); + } + } + } + + if (outputBatchPicDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(outputBatchPicDesc_); + outputBatchPicDesc_ = nullptr; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + if (cropAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[i]); + cropAreas[i] = nullptr; + } + if (pasteAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(pasteAreas[i]); + pasteAreas[i] = nullptr; + } + } + + return SY_SUCCESS; +} + + + +/* +vector DvppProcessx::crop_batch(DeviceMemory *devMem, vector objs){ + + vector vec_img_info; + + const uint32_t outputBatchSize_ = objs.size(); + if(outputBatchSize_ <= 0){ + return vec_img_info; + } + + aclError ret; + aclrtSetDevice(deviceId_); + ret = aclrtSetCurrentContext(context_); + + // 输入 + acldvppBatchPicDesc *vpcInputBatchDesc_ = acldvppCreateBatchPicDesc(1); + if (vpcInputBatchDesc_ == nullptr) { + LOG_ERROR("acldvppCreatePicDesc outBatchPicDesc failed"); + return vec_img_info; + } + acldvppPicDesc *vpcInputDesc_ = acldvppGetPicDesc(vpcInputBatchDesc_, 0); + acldvppSetPicDescData(vpcInputDesc_, devMem->getMem()); + acldvppSetPicDescFormat(vpcInputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + acldvppSetPicDescWidth(vpcInputDesc_, devMem->getWidth()); + acldvppSetPicDescHeight(vpcInputDesc_, devMem->getHeight()); + acldvppSetPicDescWidthStride(vpcInputDesc_, devMem->getWidthStride()); + acldvppSetPicDescHeightStride(vpcInputDesc_, devMem->getHeightStride()); + acldvppSetPicDescSize(vpcInputDesc_, devMem->getSize()); + + // 输出 + acldvppBatchPicDesc *outputBatchPicDesc_ = acldvppCreateBatchPicDesc(outputBatchSize_); + if (outputBatchPicDesc_ == nullptr) { + LOG_ERROR("acldvppCreatePicDesc outBatchPicDesc failed"); + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + return vec_img_info; + } + vector vecOutPtr_; + acldvppPicDesc *vpcOutputDesc = nullptr; + acldvppRoiConfig *cropAreas[outputBatchSize_]; + for (uint32_t i = 0; i < outputBatchSize_; i++) { + video_object_info obj = objs[i]; + + // uint32_t cropSizeWidth = (obj.right - obj.left) / 16 * 16; + // uint32_t cropSizeHeight = (obj.bottom - obj.top) / 2 * 2; + uint32_t cropSizeWidth = (obj.right - obj.left + 15) / 16 * 16; //debug by zsh + uint32_t cropSizeHeight = (obj.bottom - obj.top + 1) / 2 * 2; + + uint32_t oddNum = 1; + uint32_t cropLeftOffset = (obj.left + 1) / 2 * 2; // must even + uint32_t cropRightOffset = cropLeftOffset + cropSizeWidth - oddNum; // must odd + uint32_t cropTopOffset = (obj.top + 1) / 2 * 2; // must even + uint32_t cropBottomOffset = cropTopOffset + cropSizeHeight - oddNum; // must odd + + adjustCoordinate(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset, devMem->getWidth(), devMem->getHeight()); + cropSizeWidth = cropRightOffset - cropLeftOffset + oddNum; + cropSizeHeight = cropBottomOffset - cropTopOffset + oddNum; + // LOG_DEBUG("{} ,{} ,{} ,{} ", cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); + + if(cropRightOffset <= cropLeftOffset || cropBottomOffset <= cropTopOffset){ + LOG_ERROR("{} <= {} || {} <= {} ", cropRightOffset, cropLeftOffset, cropBottomOffset, cropTopOffset); + // 释放之前成功的部分 再退出 + for(int i = 0; i < vecOutPtr_.size(); i++){ + if (vecOutPtr_[i] != nullptr){ + acldvppFree(vecOutPtr_[i]); + } + if (cropAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[i]); + cropAreas[i] = nullptr; + } + } + return vec_img_info; + } + + cropAreas[i] = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); + + uint32_t vpcOutBufferSize_ = cropSizeWidth * cropSizeHeight * 3 / 2; + void *vpcBatchOutputBufferDev = nullptr; + auto ret = acldvppMalloc(&vpcBatchOutputBufferDev, vpcOutBufferSize_); + if (ret != ACL_SUCCESS) { + LOG_ERROR("acldvppMalloc failed, size = %u, errorCode = %d.", vpcOutBufferSize_, static_cast(ret)); + // 释放之前成功的部分 再退出 + for(int i = 0; i < vecOutPtr_.size(); i++){ + if (vecOutPtr_[i] != nullptr){ + acldvppFree(vecOutPtr_[i]); + } + if (cropAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[i]); + cropAreas[i] = nullptr; + } + } + return vec_img_info; + } + vecOutPtr_.push_back(vpcBatchOutputBufferDev); + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + (void)acldvppSetPicDescData(vpcOutputDesc, vpcBatchOutputBufferDev); + (void)acldvppSetPicDescFormat(vpcOutputDesc, PIXEL_FORMAT_YUV_SEMIPLANAR_420); + (void)acldvppSetPicDescWidth(vpcOutputDesc, cropSizeWidth); + (void)acldvppSetPicDescHeight(vpcOutputDesc, cropSizeHeight); + (void)acldvppSetPicDescWidthStride(vpcOutputDesc, cropSizeWidth); + (void)acldvppSetPicDescHeightStride(vpcOutputDesc, cropSizeHeight); + (void)acldvppSetPicDescSize(vpcOutputDesc, vpcOutBufferSize_); + } + + aclrtStream stream_; + aclrtCreateStream(&stream_); + + bool bRet = false; + do { + uint32_t roiNums[] = { outputBatchSize_ }; + ret = acldvppVpcBatchCropAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums, 1, outputBatchPicDesc_, cropAreas, stream_); + if (ret != ACL_SUCCESS) { + LOG_ERROR("acldvppVpcBatchCropAsync failed, task_id : {}", devMem->getId()); + break; + } + ret = aclrtSynchronizeStream(stream_); + if (ret != ACL_SUCCESS) { + LOG_ERROR("aclrtSynchronizeStream failed, task_id : {}", devMem->getId()); + break; + } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + video_object_info obj = objs[i]; + + vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + void *outputDataDev = acldvppGetPicDescData(vpcOutputDesc); + uint32_t outputSize = acldvppGetPicDescSize(vpcOutputDesc); + uint32_t width = acldvppGetPicDescWidth(vpcOutputDesc); + uint32_t width_stride = acldvppGetPicDescWidthStride(vpcOutputDesc); + uint32_t height = acldvppGetPicDescHeight(vpcOutputDesc); + uint32_t height_stride = acldvppGetPicDescHeightStride(vpcOutputDesc); + acldvppPixelFormat fmt = acldvppGetPicDescFormat(vpcOutputDesc); + + acldvppPicDesc *vpcInputDesc_= acldvppCreatePicDesc(); + acldvppSetPicDescData(vpcInputDesc_, vecOutPtr_[i]); + acldvppSetPicDescFormat(vpcInputDesc_, fmt); + acldvppSetPicDescWidth(vpcInputDesc_, width); + acldvppSetPicDescHeight(vpcInputDesc_, height); + acldvppSetPicDescWidthStride(vpcInputDesc_, width_stride); + acldvppSetPicDescHeightStride(vpcInputDesc_, height_stride); + acldvppSetPicDescSize(vpcInputDesc_, outputSize); + + vpc_img_info img_info ; + img_info.pic_desc = vpcInputDesc_; + img_info.object_id = obj.object_id; + img_info.task_id = obj.task_id; //该物体属于的任务ID号 + img_info.task_frame_count = obj.task_frame_count; //该物体当前出现的帧号 + img_info.index = obj.index; //该物体所属类别的编号 + img_info.confidence = obj.confidence; //该物体的置信度 + vec_img_info.push_back(img_info); + // vpcOutputDesc = acldvppGetPicDesc(outputBatchPicDesc_, i); + // string file_name = "output"; + // file_name = file_name + to_string(i) + ".jpg"; + // vpc_jpeg_encode(vpcOutputDesc, file_name); + } + + bRet = true; + } while (0); + + if (stream_ != nullptr) { + aclrtDestroyStream(stream_); + } + + aclrtSetCurrentContext(context_); + + if (vpcInputBatchDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); + vpcInputBatchDesc_ = nullptr; + } + + if (!bRet){ + for(int i = 0; i < vecOutPtr_.size(); i++){ + if (vecOutPtr_[i] != nullptr){ + acldvppFree(vecOutPtr_[i]); + } + } + } + + if (outputBatchPicDesc_ != nullptr) { + (void)acldvppDestroyBatchPicDesc(outputBatchPicDesc_); + outputBatchPicDesc_ = nullptr; + } + + // for (size_t i = 0; i < vec_img_info.size(); i++) + // { + // if(vec_img_info[i].pic_desc != nullptr){ + // void *outputDataDev = acldvppGetPicDescData(vec_img_info[i].pic_desc); + // acldvppFree(outputDataDev); + // acldvppDestroyPicDesc(vec_img_info[i].pic_desc); + // } + // } + + for (uint32_t i = 0; i < outputBatchSize_; i++) { + if (cropAreas[i] != nullptr) { + (void)acldvppDestroyRoiConfig(cropAreas[i]); + cropAreas[i] = nullptr; + } + } + + return vec_img_info; +}*/ + diff --git a/src/common/dvppx/dvpp_processx.h b/src/common/dvppx/dvpp_processx.h new file mode 100755 index 0000000..05d58d5 --- /dev/null +++ b/src/common/dvppx/dvpp_processx.h @@ -0,0 +1,85 @@ +/** +* Copyright 2020 Huawei Technologies Co., Ltd +* +* 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. + +* File dvpp_process.h +* Description: handle dvpp process +*/ +#pragma once +#include + +#include "acl/acl.h" +#include "acl/ops/acl_dvpp.h" +#include "utils.h" + + +typedef struct PicDesc { + std::string picName; + + uint32_t width; + uint32_t height; + uint32_t widthStride; + uint32_t heightStride; + + acldvppPixelFormat format; + + uint32_t dataSize; + void* dataBuffer; + + uint32_t predictedJpegDecodeSize; +} PicDesc; + + +typedef struct PicRoi { + uint32_t xmin; + uint32_t ymin; + uint32_t xmax; + uint32_t ymax; +} PicRoi; + + +/** + * DvppProcessx + */ +class DvppProcessx { +public: + DvppProcessx(); + + ~DvppProcessx(); + + int CropAndPadding(ImageData& src, ImageData& dest, + uint32_t width, uint32_t height); + int CropAndPaste(ImageData& src, ImageData& dest, + uint32_t width, uint32_t height); + int PatchCropAndPaste(ImageData& dest, ImageData& src, uint32_t xmin, uint32_t ymin, + uint32_t xmax, uint32_t ymax, uint32_t width, uint32_t height); + int Crop2Paste(ImageData& dest, ImageData& leftImage, ImageData& rightImage, + ImageData& src,uint32_t width, uint32_t height); + int CvtJpegToYuv420sp(ImageData& src, ImageData& dest); + int ConvertColor(PicDesc& inPicDesc, PicDesc& outPicDesc); + int CropAndPaddingBatch(ImageData* src, ImageData* dest, int batchsize, uint32_t width, uint32_t height); + int CropAndPasteBatch(ImageData* src, ImageData* dest, int batchsize, uint32_t width, uint32_t height); + int CropAndPasteBatchV2(ImageData* src, ImageData* dest, PicRoi* PicRois, int batchsize, uint32_t width, uint32_t height); + // vector crop_batch(DeviceMemory *devMem, vector objs); + int InitResource(aclrtStream& stream); + void DestroyResource(); + +protected: + int isInitOk_; + aclrtStream stream_; + acldvppChannelDesc *dvppChannelDesc_; + bool isGlobalContext_; + +}; + diff --git a/src/common/model_process/model_process.cpp b/src/common/model_process/model_process.cpp new file mode 100755 index 0000000..2da8c57 --- /dev/null +++ b/src/common/model_process/model_process.cpp @@ -0,0 +1,338 @@ +#include "model_process.h" +#include +#include "utils.h" +#include "sy_errorinfo.h" +#include + +using namespace std; + +ModelProcess::ModelProcess():loadFlag_(false), modelId_(0), modelMemPtr_(nullptr), modelMemSize_(0), +modelWeightPtr_(nullptr),modelWeightSize_(0), modelDesc_(nullptr), input_(nullptr), output_(nullptr) { +} + +ModelProcess::~ModelProcess() { + Unload(); + DestroyDesc(); + DestroyInput(); + DestroyOutput(); +} + +int ModelProcess::LoadModelFromFileWithMem(const char *modelPath) { + if (loadFlag_) { + return SY_FAILED; + } + + ACL_CALL(aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_), + ACL_SUCCESS, SY_FAILED); + + ACL_CALL(aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST), + ACL_SUCCESS, SY_FAILED); + + ACL_CALL(aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST), + ACL_SUCCESS, SY_FAILED); + + ACL_CALL(aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, + modelMemSize_, modelWeightPtr_, modelWeightSize_), ACL_SUCCESS, SY_FAILED); + + loadFlag_ = true; + + return SY_SUCCESS; +} + +int ModelProcess::CreateDesc() { + modelDesc_ = aclmdlCreateDesc(); + if (modelDesc_ == nullptr) { + return SY_FAILED; + } + + ACL_CALL(aclmdlGetDesc(modelDesc_, modelId_), ACL_SUCCESS, SY_FAILED); + + return SY_SUCCESS; +} + +void ModelProcess::DestroyDesc() { + if (modelDesc_ != nullptr) { + (void)aclmdlDestroyDesc(modelDesc_); + modelDesc_ = nullptr; + } +} + +int ModelProcess::CreateOutput(vector>& dims) { + if (modelDesc_ == nullptr) { + return SY_FAILED; + } + + output_ = aclmdlCreateDataset(); + if (output_ == nullptr) { + return SY_FAILED; + } + + aclError ret; + size_t outputSize = aclmdlGetNumOutputs(modelDesc_); + for (size_t i = 0; i < outputSize; ++i) { + size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i); + + void *outputBuffer = nullptr; + ACL_CALL(aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY), + ACL_SUCCESS, SY_FAILED); + + aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size); + if (outputData == nullptr) { + aclrtFree(outputBuffer); + return SY_FAILED; + } + + ret = aclmdlAddDatasetBuffer(output_, outputData); + if (ret != ACL_SUCCESS) { + aclrtFree(outputBuffer); + aclDestroyDataBuffer(outputData); + return SY_FAILED; + } + + // get output dims + aclmdlIODims outDims; + vector dims_; + ACL_CALL(aclmdlGetOutputDims(modelDesc_, i, &outDims), ACL_SUCCESS, SY_FAILED); + for (int j = 0; j < outDims.dimCount; j++) { + dims_.emplace_back(outDims.dims[j]); + } + dims.emplace_back(dims_); + + } + + return SY_SUCCESS; +} + +void ModelProcess::DestroyOutput() { + if (output_ == nullptr) { + return; + } + + for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { + aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); + void* data = aclGetDataBufferAddr(dataBuffer); + (void)aclrtFree(data); + (void)aclDestroyDataBuffer(dataBuffer); + dataBuffer = nullptr; + } + + (void)aclmdlDestroyDataset(output_); + output_ = nullptr; +} + +// get input dims +int ModelProcess::GetInputDims(vector>& dims) { + if (modelDesc_ == nullptr) { + return SY_FAILED; + } + + aclError ret; + size_t inputSize = aclmdlGetNumInputs(modelDesc_); + //debug=================================== + // uint32_t modelInputSize = aclmdlGetInputSizeByIndex(modelDesc_, 0); + // cout << "modelInputSize:" << modelInputSize << endl; + //debug end=============================== + for (size_t i = 0; i < inputSize; ++i) { + // get output dims + aclmdlIODims inDims; + vector dims_; + ACL_CALL(aclmdlGetInputDims(modelDesc_, i, &inDims), ACL_SUCCESS, SY_FAILED); + for (int j = 0; j < inDims.dimCount; j++) { + dims_.emplace_back(inDims.dims[j]); + } + dims.emplace_back(dims_); + } + + return SY_SUCCESS; +} + +int ModelProcess::CreateInput(void *input, size_t inputsize) { + input_ = aclmdlCreateDataset(); + if (input_ == nullptr) { + return SY_FAILED; + } + + aclDataBuffer* inputData = aclCreateDataBuffer(input, inputsize); + if (inputData == nullptr) { + return SY_FAILED; + } + + aclmdlAddDatasetBuffer(input_, inputData); + if (inputData == nullptr) { + aclDestroyDataBuffer(inputData); + inputData = nullptr; + return SY_FAILED; + } + + return SY_SUCCESS; +} + +int ModelProcess::CreateInputV2(void *input, size_t inputsize) { + input_ = aclmdlCreateDataset(); + if (input_ == nullptr) { + return SY_FAILED; + } + aclError ret; + for(size_t index = 0; index < aclmdlGetNumInputs(modelDesc_); ++index) + { + const char* name = aclmdlGetInputNameByIndex(modelDesc_, index); + size_t inputLen = aclmdlGetInputSizeByIndex(modelDesc_, index); + if(strcmp(name, ACL_DYNAMIC_TENSOR_NAME) == 0) + { + void *data = nullptr; + ret = aclrtMalloc(&data, inputLen, ACL_MEM_MALLOC_HUGE_FIRST); + aclDataBuffer* batchBuffer = aclCreateDataBuffer(data, inputLen); + if (batchBuffer == nullptr) { + (void)aclrtFree(data); + data = nullptr; + return SY_FAILED; + } + ret = aclmdlAddDatasetBuffer(input_, batchBuffer); + if (ret != ACL_SUCCESS) { + ERROR_LOG("add input dataset buffer failed, errorCode = %d.", static_cast(ret)); + aclDestroyDataBuffer(batchBuffer); + batchBuffer = nullptr; + (void)aclrtFree(data); + data = nullptr; + return SY_FAILED; + } + } + else + { + aclDataBuffer* inputData = aclCreateDataBuffer(input, inputsize); + if (inputData == nullptr) { + return SY_FAILED; + } + ret = aclmdlAddDatasetBuffer(input_, inputData); + if (inputData == nullptr) { + aclDestroyDataBuffer(inputData); + inputData = nullptr; + return SY_FAILED; + } + } + } + + return SY_SUCCESS; +} + +int ModelProcess::AddInputBuff(void *input, size_t inputsize) { + aclDataBuffer* inputData = aclCreateDataBuffer(input, inputsize); + if (inputData == nullptr) { + return SY_FAILED; + } + + aclmdlAddDatasetBuffer(input_, inputData); + if (inputData == nullptr) { + aclDestroyDataBuffer(inputData); + inputData = nullptr; + return SY_FAILED; + } + + return SY_SUCCESS; +} + + +void ModelProcess::DestroyInput() { + if (input_ == nullptr) { + return; + } + + for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { + aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); + aclDestroyDataBuffer(dataBuffer); + dataBuffer = nullptr; + } + aclmdlDestroyDataset(input_); + input_ = nullptr; +} + +void ModelProcess::DestroyInputV2() { + if (input_ == nullptr) { + return; + } + + for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { + aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); + if (dataBuffer == nullptr) { + continue; + } + void *data = aclGetDataBufferAddr(dataBuffer); + if (data == nullptr){ + (void)aclDestroyDataBuffer(dataBuffer); + dataBuffer = nullptr; + continue; + } + const char* name = aclmdlGetInputNameByIndex(modelDesc_, i); + if(strcmp(name, ACL_DYNAMIC_TENSOR_NAME) == 0) { + (void)aclrtFree(data); + data = nullptr; + } + + (void)aclDestroyDataBuffer(dataBuffer); + dataBuffer = nullptr; + } + (void)aclmdlDestroyDataset(input_); + input_ = nullptr; +} + +int ModelProcess::Execute() { + aclError ret = aclmdlExecute(modelId_, input_, output_); + if (ret != ACL_SUCCESS) { + ERROR_LOG("execute model failed, modelId is %u %d", modelId_, ret); + return SY_FAILED; + } + // ACL_CALL(aclmdlExecute(modelId_, input_, output_), ACL_SUCCESS, SY_FAILED); + + return SY_SUCCESS; +} + +int ModelProcess::Execute(int batchsize) { + size_t index; + aclError ret = aclmdlGetInputIndexByName(modelDesc_, ACL_DYNAMIC_TENSOR_NAME, &index); + ret = aclmdlSetDynamicBatchSize(modelId_, input_, index, batchsize); + if (ret != ACL_SUCCESS) { + ERROR_LOG("aclmdlSetDynamicBatchSize failed, modelId is %u %d", modelId_, ret); + } + ret = aclmdlExecute(modelId_, input_, output_); + if (ret != ACL_SUCCESS) { + ERROR_LOG("execute model failed, modelId is %u %d", modelId_, ret); + return SY_FAILED; + } + return SY_SUCCESS; +} + +void ModelProcess::Unload() { + if (!loadFlag_) { + return; + } + + aclError ret = aclmdlUnload(modelId_); + if (ret != ACL_SUCCESS) { + return; + } + + if (modelDesc_ != nullptr) { + (void)aclmdlDestroyDesc(modelDesc_); + modelDesc_ = nullptr; + } + + if (modelMemPtr_ != nullptr) { + aclrtFree(modelMemPtr_); + modelMemPtr_ = nullptr; + modelMemSize_ = 0; + } + + if (modelWeightPtr_ != nullptr) { + aclrtFree(modelWeightPtr_); + modelWeightPtr_ = nullptr; + modelWeightSize_ = 0; + } + + loadFlag_ = false; +} + +aclmdlDataset *ModelProcess::GetModelOutputData() { + return output_; +} + + diff --git a/src/common/model_process/model_process.h b/src/common/model_process/model_process.h new file mode 100755 index 0000000..88cdc0f --- /dev/null +++ b/src/common/model_process/model_process.h @@ -0,0 +1,49 @@ +#ifndef _MODEL_PROCESS_H_ +#define _MODEL_PROCESS_H_ + +#include +#include +#include "utils.h" +#include "acl/acl.h" + +class ModelProcess { +public: + ModelProcess(); + ~ModelProcess(); + + int LoadModelFromFileWithMem(const char *modelPath); + void Unload(); + + int CreateDesc(); + void DestroyDesc(); + aclmdlDesc* GetmodelDesc() { return modelDesc_;}; + + int CreateOutput(vector>& dims); + void DestroyOutput(); + + int CreateInput(void *input, size_t inputsize); + int CreateInputV2(void *input, size_t inputsize); + int AddInputBuff(void *input, size_t inputsize); + int GetInputDims(vector>& dims); + + void DestroyInput(); + void DestroyInputV2(); + + int Execute(); + int Execute(int batchsize); + + aclmdlDataset *GetModelOutputData(); + +private: + bool loadFlag_; // model load flag + uint32_t modelId_; + void *modelMemPtr_; + size_t modelMemSize_; + void *modelWeightPtr_; + size_t modelWeightSize_; + aclmdlDesc *modelDesc_; + aclmdlDataset *output_; + aclmdlDataset *input_; +}; + +#endif \ No newline at end of file diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 7b39046..09507b2 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -29,7 +29,8 @@ void* Utils::CopyDataHostToDvpp(void* data, int size) { size, aclRet); return nullptr; } - // INFO_LOG("malloc dvpp memory size %d ok", size); + // INFO_LOG("%d malloc dvpp memory size %d ok", __LINE__, size); + // cout << "data:" << data << endl; // copy input to device memory aclRet = aclrtMemcpy(buffer, size, data, size, ACL_MEMCPY_HOST_TO_DEVICE); if (aclRet != ACL_SUCCESS) { @@ -37,7 +38,7 @@ void* Utils::CopyDataHostToDvpp(void* data, int size) { acldvppFree(buffer); return nullptr; } - //INFO_LOG("copy data to dvpp ok"); + // INFO_LOG("copy data to dvpp ok"); return buffer; } @@ -53,7 +54,7 @@ void* Utils::CopyDataDeviceToDvpp(void* data, int size) { size, aclRet); return nullptr; } - // INFO_LOG("malloc dvpp memory size %d ok", size); + // INFO_LOG("%d malloc dvpp memory size %d ok", __LINE__, size); // copy input to device memory aclRet = aclrtMemcpy(buffer, size, data, size, ACL_MEMCPY_DEVICE_TO_DEVICE); if (aclRet != ACL_SUCCESS) { @@ -61,7 +62,7 @@ void* Utils::CopyDataDeviceToDvpp(void* data, int size) { acldvppFree(buffer); return nullptr; } - //INFO_LOG("copy data to dvpp ok"); + // INFO_LOG("copy data to dvpp ok"); return buffer; } @@ -119,6 +120,46 @@ int Utils::CopysyImageDataToDvpp(ImageData& imageDevice, sy_img srcImage) { return SY_SUCCESS; } + +// vdec +int Utils::CopysyImageDataToDvppV2(ImageData& imageDevice, sy_img srcImage) { + aclError ret = aclrtGetRunMode(&runMode_); + if (ret != ACL_SUCCESS) { + ERROR_LOG("acl get run mode failed"); + return SY_FAILED; + } + + void* buffer = nullptr; + uint32_t alignWidth = ALIGN_UP16(srcImage.w_); // 16-byte alignment + uint32_t alignHeight = ALIGN_UP2(srcImage.h_); // 2-byte alignment + uint32_t size = YUV420SP_SIZE(alignWidth, alignHeight); + // cout << srcImage.w_ << " " << srcImage.h_ << " "<< alignWidth << " "<< alignHeight << " " << size << endl; + if (runMode_ == ACL_HOST) { + buffer = Utils::CopyDataHostToDvpp(srcImage.data_, size); + if (buffer == nullptr) { + ERROR_LOG("Copy image to device failed"); + return SY_FAILED; + } + } + else { + buffer = Utils::CopyDataDeviceToDvpp(srcImage.data_, size); + if (buffer == nullptr) { + ERROR_LOG("Copy image to device failed"); + return SY_FAILED; + } + } + + imageDevice.width = srcImage.w_; + imageDevice.height = srcImage.h_; + imageDevice.alignWidth = alignWidth; + imageDevice.alignHeight = alignHeight; + imageDevice.size = size; + imageDevice.data.reset((uint8_t*)buffer, [](uint8_t* p) { acldvppFree((void *)p); }); + + return SY_SUCCESS; +} + + int Utils::CopyImageDataToDvpp(ImageData& imageDevice, ImageData srcImage) { aclError ret = aclrtGetRunMode(&runMode_); if (ret != ACL_SUCCESS) { @@ -259,6 +300,52 @@ int Utils::ReadImageFile(ImageData& image, std::string fileName) { } +int Utils::ReadPngFile(ImageData& image, std::string fileName) { + struct stat sBuf; + int fileStatus = stat(fileName.data(), &sBuf); + if (fileStatus == -1) { + ERROR_LOG("failed to get file"); + return SY_FAILED; + } + if (S_ISREG(sBuf.st_mode) == 0) { + ERROR_LOG("%s is not a file, please enter a file", fileName.c_str()); + return SY_FAILED; + } + std::ifstream binFile(fileName, std::ifstream::binary); + if (binFile.is_open() == false) { + ERROR_LOG("open file %s failed", fileName.c_str()); + return SY_FAILED; + } + + binFile.seekg(0, binFile.end); + uint32_t binFileBufferLen = binFile.tellg(); + if (binFileBufferLen == 0) { + ERROR_LOG("binfile is empty, filename is %s", fileName.c_str()); + binFile.close(); + return SY_FAILED; + } + + binFile.seekg(0, binFile.beg); + + uint8_t* binFileBufferData = new(std::nothrow) uint8_t[binFileBufferLen]; + if (binFileBufferData == nullptr) { + ERROR_LOG("malloc binFileBufferData failed"); + binFile.close(); + return SY_FAILED; + } + binFile.read((char *)binFileBufferData, binFileBufferLen); + binFile.close(); + + int32_t ch = 0; + acldvppPngGetImageInfo(binFileBufferData, binFileBufferLen, + &(image.width), &(image.height), &ch); + image.data.reset(binFileBufferData, [](uint8_t* p) { delete[](p); }); + image.size = binFileBufferLen; + return SY_SUCCESS; +} + + + float Utils::sigmoid(float val){ return 1.0/(1.0+exp(-val)); } diff --git a/src/common/utils.h b/src/common/utils.h index a5f7f0a..8d1f91f 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -72,9 +72,11 @@ public: static void* CopyDataHostToDevice(void* deviceData, uint32_t dataSize); static void* CopyDataDeviceToDevice(void* deviceData, uint32_t dataSize); static int ReadImageFile(ImageData& image, std::string fileName); + static int ReadPngFile(ImageData& image, std::string fileName); static int CopyImageDataToDevice(ImageData& imageDevice, ImageData srcImage, aclrtRunMode mode); static int CopyImageDataToDvpp(ImageData& imageDevice, ImageData srcImage); static int CopysyImageDataToDvpp(ImageData& imageDevice, sy_img srcImage); + static int CopysyImageDataToDvppV2(ImageData& imageDevice, sy_img srcImage); static void* CopyDataHostToDvpp(void* data, int size); static bool CreateFolder(std::string folderPath, mode_t mode = 0700); static bool WriteImage(unsigned char* data, int32_t size, const char* filename); diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..0f65a7e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,20 @@ +#include "PicAnalysis.h" + +int main() { + + PicAnalysis pic_analysis; + + pic_analysis.init(0); + + vector vec_path; + for (size_t i = 0; i < 10; i++) + { + vec_path.push_back("./test_head_tail.jpg"); + } + + pic_analysis.analysis_sync(vec_path); + + pic_analysis.release(); + + return 0; +} \ No newline at end of file diff --git a/src/src.cpp b/src/src.cpp deleted file mode 100644 index 53f9dbe..0000000 --- a/src/src.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "./ai_engine_module/VehicleAnalysis.h" -#include "./ai_engine_module/include.h" -#include "./utils/logger.hpp" - -int main() { - - VehicleAnalysis va; - va.init(0, 16); - - string filename = "./test.jpg"; - - aclrtStream stream = nullptr; - ACL_CALL(aclrtCreateStream(&stream), ACL_SUCCESS, SY_FAILED); - DvppProcess* dvpp = new DvppProcess(); - dvpp->InitResource(stream); - - const int batchsize = 1; - - vector vec_img; - ImageData dvpp_data; - for (int b = 0; b < batchsize; b++) { - ImageData src; - Utils::ReadImageFile(src, filename); //将二进制图像读入内存,并读取宽高信息 - - ACL_CALL(dvpp->CvtJpegToYuv420sp(dvpp_data, src), SY_SUCCESS, SY_FAILED); //解码 - vec_img.push_back(dvpp_data); - } - - printf("1 \n"); - - va.detect(vec_img); - - - delete dvpp; - dvpp = nullptr; - - if (stream != nullptr) { - int ret = aclrtDestroyStream(stream); - if (ret != ACL_SUCCESS) { - LOG_ERROR("destroy stream failed"); - } - stream = nullptr; - } - - return 0; -} \ No newline at end of file