/** * 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); } ImageData* DvppProcessx::Crop_naked(ImageData& src, uint32_t xmin, uint32_t ymin, uint32_t xmax, uint32_t ymax, uint32_t width, uint32_t height) { DvppCropAndPastex cropandpasteOp(stream_, dvppChannelDesc_, width, height); return cropandpasteOp.Crop_naked(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; }*/