#include #include #include #include #include #include #include #include #include #include #include #include "acl/acl.h" #include "acl/ops/acl_dvpp.h" #include "vpc_util.h" #include "JpegUtil.h" #include "../decoder/interface/DeviceMemory.hpp" #include "../common/logger.hpp" void VPCUtil::release() { aclError ret; // ret = aclrtSetDevice(deviceId_); // aclrtSetCurrentContext(context_); ret = acldvppDestroyChannel(dvppChannelDesc_); ret = acldvppDestroyChannelDesc(dvppChannelDesc_); if (context_ != nullptr) { ret = aclrtDestroyContext(context_); if (ret != ACL_SUCCESS) { LOG_ERROR("destroy context failed"); } context_ = nullptr; } LOG_INFO("end to destroy context"); ret = aclrtResetDevice(deviceId_); if (ret != ACL_SUCCESS) { LOG_ERROR("reset device failed"); } LOG_INFO("end to reset device is %d", deviceId_); } vpc_img_info VPCUtil::crop(DeviceMemory *devMem, video_object_info obj) { vpc_img_info img_info ; uint32_t cropSizeWidth = (obj.right - obj.left) / 16 * 16; uint32_t cropSizeHeight = (obj.bottom - obj.top) / 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 if(cropRightOffset <= cropLeftOffset || cropBottomOffset <= cropTopOffset){ return img_info; } // LOG_INFO("crop src {} ({}, {}, {}, {})", obj.object_id, obj.left, obj.right, obj.top, obj.bottom); // LOG_INFO("crop {} ({}, {}, {}, {})", obj.object_id, cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); acldvppRoiConfig *cropArea_ = acldvppCreateRoiConfig(cropLeftOffset, cropRightOffset, cropTopOffset, cropBottomOffset); acldvppPicDesc *vpcInputDesc_ = acldvppCreatePicDesc(); 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()); /* processdecode */ uint32_t vpcOutBufferSize_ = cropSizeWidth * cropSizeHeight * 3 / 2; void *vpcOutBufferDev_ = nullptr; acldvppMalloc(&vpcOutBufferDev_, vpcOutBufferSize_); acldvppPicDesc *vpcOutputDesc_ = acldvppCreatePicDesc(); acldvppSetPicDescData(vpcOutputDesc_, vpcOutBufferDev_); acldvppSetPicDescFormat(vpcOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(vpcOutputDesc_, cropSizeWidth); acldvppSetPicDescHeight(vpcOutputDesc_, cropSizeHeight); acldvppSetPicDescWidthStride(vpcOutputDesc_, cropSizeWidth); acldvppSetPicDescHeightStride(vpcOutputDesc_, cropSizeHeight); acldvppSetPicDescSize(vpcOutputDesc_, vpcOutBufferSize_); aclrtStream stream_; aclrtCreateStream(&stream_); int ret = acldvppVpcCropAsync(dvppChannelDesc_, vpcInputDesc_, vpcOutputDesc_, cropArea_, stream_); ret = aclrtSynchronizeStream(stream_); if (stream_ != nullptr) { aclrtDestroyStream(stream_); } acldvppDestroyPicDesc(vpcInputDesc_); /* DestroycropResource */ (void)acldvppDestroyRoiConfig(cropArea_); cropArea_ = nullptr; img_info.pic_desc = vpcOutputDesc_; 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; //该物体的置信度 // (void)acldvppDestroyPicDesc(vpcOutputDesc_); // vpcOutputDesc_ = nullptr; // if (vpcOutBufferDev_ != nullptr) { // (void)acldvppFree(vpcOutBufferDev_); // vpcOutBufferDev_ = nullptr; // } return img_info; } int VPCUtil::init(int32_t devId){ deviceId_ = devId; aclError ret; aclrtSetDevice(deviceId_); aclrtCreateContext(&context_, deviceId_); // channel 准备 dvppChannelDesc_ = acldvppCreateChannelDesc(); ret = acldvppCreateChannel(dvppChannelDesc_); } vector VPCUtil::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 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 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_); uint32_t roiNums[] = { outputBatchSize_ }; ret = acldvppVpcBatchCropAsync(dvppChannelDesc_, vpcInputBatchDesc_, roiNums, 1, outputBatchPicDesc_, cropAreas, stream_); ret = aclrtSynchronizeStream(stream_); if (stream_ != nullptr) { aclrtDestroyStream(stream_); } 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); } aclrtSetCurrentContext(context_); if (vpcInputBatchDesc_ != nullptr) { (void)acldvppDestroyBatchPicDesc(vpcInputBatchDesc_); vpcInputBatchDesc_ = nullptr; } // 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; } vpc_img_info VPCUtil::vpc_devMem2vpcImg(DeviceMemory *devMem){ vpc_img_info img_info ; int nBufferSize = devMem->getSize(); void *devBuffer = nullptr; auto ret = acldvppMalloc(&devBuffer, nBufferSize); if (ret != ACL_SUCCESS) { LOG_ERROR("acldvppMalloc failed, size = %u, errorCode = %d.", nBufferSize, static_cast(ret)); // 这里应释放之前成功的部分 再退出 return img_info; } aclrtMemcpy(devBuffer, nBufferSize, devMem->getMem(), nBufferSize, ACL_MEMCPY_DEVICE_TO_DEVICE); acldvppPicDesc *vpcInputDesc_= acldvppCreatePicDesc(); acldvppSetPicDescData(vpcInputDesc_, devBuffer); 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()); img_info.pic_desc = vpcInputDesc_; img_info.object_id = -1; img_info.task_id = devMem->getId(); //该物体属于的任务ID号 img_info.index = -1; //该物体所属类别的编号 img_info.confidence = 0.0; //该物体的置信度 return img_info; } void VPCUtil::vpc_pic_desc_release(acldvppPicDesc* pic_desc){ void *outputDataDev = acldvppGetPicDescData(pic_desc); acldvppFree(outputDataDev); acldvppDestroyPicDesc(pic_desc); } void VPCUtil::vpc_img_release(vpc_img_info img_info){ if(img_info.pic_desc != nullptr){ void *outputDataDev = acldvppGetPicDescData(img_info.pic_desc); acldvppFree(outputDataDev); acldvppDestroyPicDesc(img_info.pic_desc); } } void VPCUtil::vpc_imgList_release(vector& imgList){ for(int i=0; i < imgList.size(); i++){ vpc_img_release(imgList[i]); } imgList.clear(); }