#include "VpcUtils.h" #include "depend_headers.h" #define ALIGN_UP(val, align) (((val) % (align) == 0) ? (val) : (((val) / (align) + 1) * (align))) #define CHECK_AND_RETURN(ret, message) \ if(ret != 0) {LOG_ERROR("{}", message); return ret;} #define CHECK_NOT_RETURN(ret, message) \ if(ret != 0) {LOG_ERROR("{}", message);} #define CHECK_AND_RETURN_NOVALUE(ret, message) \ if(ret != 0) {LOG_ERROR("{}", message); return;} #define CHECK_AND_BREAK(ret, message) \ if(ret != 0) {LOG_ERROR("{}", message); break;} VpcUtils::VpcUtils(){ } VpcUtils::~VpcUtils(){ aclError ret; ret = aclrtSetDevice(m_devId); aclrtSetCurrentContext(context_); if (dvppChannelDesc_) { (void)acldvppDestroyChannel(dvppChannelDesc_); (void)acldvppDestroyChannelDesc(dvppChannelDesc_); dvppChannelDesc_ = nullptr; } if(nullptr != stream_){ aclrtDestroyStream(stream_); } if(context_){ aclrtDestroyContext(context_); } aclrtResetDevice(m_devId); /// } int VpcUtils::init(int devId){ m_devId = devId; aclrtSetDevice(m_devId); aclrtCreateContext(&context_, m_devId); CHECK_AND_RETURN(aclrtSetCurrentContext(context_), "aclrtSetCurrentContext failed"); CHECK_AND_RETURN(aclrtCreateStream(&stream_), "aclrtCreateStream failed! "); dvppChannelDesc_ = acldvppCreateChannelDesc(); int ret = ACL_ERROR_NONE; do { ret = acldvppCreateChannel(dvppChannelDesc_); CHECK_AND_BREAK(ret, "acldvppCreateChannel failed !"); ret = acldvppSetChannelDescMode(dvppChannelDesc_, DVPP_CHNMODE_VPC); CHECK_AND_BREAK(ret, "acldvppSetChannelDescMode failed !"); } while (0); return ret; } DvppDataMemory* VpcUtils::convert2bgr(acldvppPicDesc *inputDesc_, int out_width, int out_height, bool key_frame){ aclrtSetDevice(m_devId); aclrtSetCurrentContext(context_); 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(); 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); break; } 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); break; } }while(0); acldvppDestroyPicDesc(outputDesc_); if(ret != ACL_ERROR_NONE){ delete rgbMem; rgbMem = nullptr; } return rgbMem; } DvppDataMemory* VpcUtils::convert2bgr(DvppDataMemory* inMem){ aclrtSetDevice(m_devId); aclrtSetCurrentContext(context_); int out_width = inMem->getWidth(); int out_height = inMem->getHeight(); acldvppPicDesc *inputDesc_= acldvppCreatePicDesc(); 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(); 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); break; } 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); break; } }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){ aclrtSetDevice(m_devId); aclrtSetCurrentContext(context_); 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(); 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); break; } 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); break; } }while(0); acldvppDestroyResizeConfig(resizeConfig_); acldvppDestroyPicDesc(outputDesc_); if(ret != ACL_ERROR_NONE){ delete rgbMem; rgbMem = nullptr; } return rgbMem; }