/** * 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_cropandpaste.h" #include "sy_errorinfo.h" using namespace std; DvppCropAndPaste::DvppCropAndPaste(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; } DvppCropAndPaste::~DvppCropAndPaste() { DestroyCropAndPasteResource(); } int DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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 DvppCropAndPaste::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; } }