#include "VpcUtils.h" #include "depend_headers.h" #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align))) #define ACL_CHECK_AND_ABORT(ret, message) \ if(ret != 0) {LOG_ERROR("{}", message); std::abort();} VpcUtils::VpcUtils(){ } VpcUtils::~VpcUtils(){ release(); } int VpcUtils::init(int devId){ if (context_) { return 1; } m_devId = devId; ACL_CHECK_AND_ABORT(aclrtCreateContext(&context_, m_devId), "aclrtCreateContext failed !"); do { ACL_CHECK_AND_ABORT(aclrtCreateStream(&stream_), "aclrtCreateStream failed !"); dvppChannelDesc_ = acldvppCreateChannelDesc(); ACL_CHECK_AND_ABORT(acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC), "acldvppSetChannelDescMode failed !"); ACL_CHECK_AND_ABORT(acldvppCreateChannel(dvppChannelDesc_), "acldvppCreateChannel failed !"); } while (0); return 0; } void VpcUtils::release() { if(context_){ ACL_CHECK_AND_ABORT(aclrtSetCurrentContext(context_), "aclrtSetCurrentContext failed !"); if (dvppChannelDesc_) { (void)acldvppDestroyChannel(dvppChannelDesc_); (void)acldvppDestroyChannelDesc(dvppChannelDesc_); dvppChannelDesc_ = nullptr; } if(nullptr != stream_){ aclrtDestroyStream(stream_); stream_ = nullptr; } aclrtDestroyContext(context_); context_ = nullptr; } } DvppDataMemory* VpcUtils::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){ ACL_CHECK_AND_ABORT(aclrtSetCurrentContext(context_), "aclrtSetCurrentContext failed !"); int out_buf_width = ALIGN_UP(out_width, 16) * 3; int out_buf_height = ALIGN_UP(out_height, 2); int out_buf_size = out_buf_width * out_buf_height; DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, "", to_string(m_devId), key_frame, 0); void *outBufferDev_ = (void*)rgbMem->getMem(); acldvppPicDesc *outputDesc_= acldvppCreatePicDesc(); if(outputDesc_ == nullptr){ LOG_ERROR("acldvppCreatePicDesc failed !"); std::abort(); } acldvppSetPicDescData(outputDesc_, outBufferDev_); acldvppSetPicDescFormat(outputDesc_, PIXEL_FORMAT_BGR_888); acldvppSetPicDescWidth(outputDesc_, out_width); acldvppSetPicDescHeight(outputDesc_, out_height); acldvppSetPicDescWidthStride(outputDesc_, out_buf_width); acldvppSetPicDescHeightStride(outputDesc_, out_buf_height); acldvppSetPicDescSize(outputDesc_, out_buf_size); aclError ret = ACL_ERROR_NONE; do{ // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 ret = acldvppVpcConvertColorAsync(dvppChannelDesc_, inputDesc_, outputDesc_, stream_); if(ret != ACL_ERROR_NONE){ LOG_ERROR("acldvppVpcConvertColorAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size); std::abort(); } ret = aclrtSynchronizeStream(stream_); if(ret != ACL_ERROR_NONE){ LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size); std::abort(); } }while(0); acldvppDestroyPicDesc(outputDesc_); if(ret != ACL_ERROR_NONE){ delete rgbMem; rgbMem = nullptr; } return rgbMem; } DvppDataMemory* VpcUtils::convert2bgr(DvppDataMemory* inMem){ ACL_CHECK_AND_ABORT(aclrtSetCurrentContext(context_), "aclrtSetCurrentContext failed !"); int out_width = inMem->getWidth(); int out_height = inMem->getHeight(); acldvppPicDesc *inputDesc_= acldvppCreatePicDesc(); if(inputDesc_ == nullptr){ LOG_ERROR("acldvppCreatePicDesc failed !"); std::abort(); } acldvppSetPicDescData(inputDesc_, inMem->getMem()); acldvppSetPicDescFormat(inputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(inputDesc_, out_width); acldvppSetPicDescHeight(inputDesc_, out_height); acldvppSetPicDescWidthStride(inputDesc_, inMem->getWidthStride()); acldvppSetPicDescHeightStride(inputDesc_, inMem->getHeightStride()); acldvppSetPicDescSize(inputDesc_, inMem->getSize()); int out_buf_width = ALIGN_UP(out_width, 16) * 3; int out_buf_height = ALIGN_UP(out_height, 2); int out_buf_size = out_buf_width * out_buf_height; DvppDataMemory* rgbMem = new DvppDataMemory(3, out_buf_width, out_buf_width, out_buf_height, out_buf_height, out_buf_size, inMem->getId(), inMem->getDeviceId(), false, inMem->getFrameNb()); void *outBufferDev_ = (void*)rgbMem->getMem(); acldvppPicDesc *outputDesc_= acldvppCreatePicDesc(); if(outputDesc_ == nullptr){ LOG_ERROR("acldvppCreatePicDesc failed !"); std::abort(); } acldvppSetPicDescData(outputDesc_, outBufferDev_); acldvppSetPicDescFormat(outputDesc_, PIXEL_FORMAT_BGR_888); acldvppSetPicDescWidth(outputDesc_, out_width); acldvppSetPicDescHeight(outputDesc_, out_height); acldvppSetPicDescWidthStride(outputDesc_, out_buf_width); acldvppSetPicDescHeightStride(outputDesc_, out_buf_height); acldvppSetPicDescSize(outputDesc_, out_buf_size); aclError ret = ACL_ERROR_NONE; do{ // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 ret = acldvppVpcConvertColorAsync(dvppChannelDesc_, inputDesc_, outputDesc_, stream_); if(ret != ACL_ERROR_NONE){ LOG_ERROR("acldvppVpcConvertColorAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size); std::abort(); } ret = aclrtSynchronizeStream(stream_); if(ret != ACL_ERROR_NONE){ LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size); std::abort(); } }while(0); acldvppDestroyPicDesc(outputDesc_); acldvppDestroyPicDesc(inputDesc_); if(ret != ACL_ERROR_NONE){ delete rgbMem; rgbMem = nullptr; } return rgbMem; } DvppDataMemory* VpcUtils::resize(acldvppPicDesc *inputDesc_, int out_width, int out_height){ std::lock_guard l(m_resize_mtx); ACL_CHECK_AND_ABORT(aclrtSetCurrentContext(context_), "aclrtSetCurrentContext failed !"); int out_buf_width = ALIGN_UP(out_width, 16); int out_buf_height = ALIGN_UP(out_height, 2); int out_buf_size = out_buf_width * out_buf_height * 3 / 2; DvppDataMemory* rgbMem = new DvppDataMemory(1, out_width, out_buf_width, out_height, out_buf_height, out_buf_size, "", "", false, 0); void *outBufferDev_ = (void*)rgbMem->getMem(); acldvppPicDesc *outputDesc_= acldvppCreatePicDesc(); if(outputDesc_ == nullptr){ LOG_ERROR("acldvppCreatePicDesc failed !"); std::abort(); } acldvppSetPicDescData(outputDesc_, outBufferDev_); acldvppSetPicDescFormat(outputDesc_, acldvppGetPicDescFormat(inputDesc_)); acldvppSetPicDescWidth(outputDesc_, out_width); acldvppSetPicDescHeight(outputDesc_, out_height); acldvppSetPicDescWidthStride(outputDesc_, out_buf_width); acldvppSetPicDescHeightStride(outputDesc_, out_buf_height); acldvppSetPicDescSize(outputDesc_, out_buf_size); acldvppResizeConfig *resizeConfig_ = acldvppCreateResizeConfig(); aclError ret = ACL_ERROR_NONE; do{ // 9. 执行异步色域转换,再调用aclrtSynchronizeStream接口阻塞程序运行,直到指定Stream中的所有任务都完成 ret = acldvppVpcResizeAsync(dvppChannelDesc_, inputDesc_, outputDesc_, resizeConfig_, stream_); if(ret != ACL_ERROR_NONE){ LOG_ERROR("acldvppVpcResizeAsync failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size); std::abort(); } ret = aclrtSynchronizeStream(stream_); if(ret != ACL_ERROR_NONE){ LOG_ERROR("aclrtSynchronizeStream failed - out_width:{} out_height:{} out_buf_width:{} out_buf_height:{} out_buf_size:{}", out_width, out_height, out_buf_width, out_buf_height, out_buf_size); std::abort(); } }while(0); acldvppDestroyResizeConfig(resizeConfig_); acldvppDestroyPicDesc(outputDesc_); if(ret != ACL_ERROR_NONE){ delete rgbMem; rgbMem = nullptr; } return rgbMem; }