VpcUtils.cpp 8.76 KB
#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){

    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;
}