更新时间:2021-03-18 GMT+08:00
分享

实现VPC功能

概念说明

关于抠图、缩放、叠加、上偏移、下偏移、左偏移、右偏移等概念,请参见VPC功能

示例1:仅原图缩放

关键参数设置如下:

  • 抠图区域宽高跟输入图片的真实宽高相同,抠图区域各偏移值的设置如下:
    • 左偏移leftOffset=0
    • 上偏移upOffset=0
    • 右偏移rightOffset - 左偏移leftOffset+1=输入图片真实宽
    • 下偏移downOffset - 上偏移upOffset+1=输入图片真实高
  • 贴图区域宽高是缩放后图片的宽高,可指定贴图区域的位置,例如:
    若指定贴图区域的位置在输出图片的左上角,则贴图区域各偏移值的设置如下:
    • 左偏移leftOffset=0
    • 上偏移upOffset=0
    • 右偏移rightOffset - 左偏移leftOffset+1=缩放后图片的宽
    • 下偏移downOffset - 上偏移upOffset+1=缩放后图片的高
  • 如果是8K的原图缩放,则inputFormat和outputFormat只支持依次设置为INPUT_YUV420_SEMI_PLANNER_UV、OUTPUT_YUV420SP_UV或设置为INPUT_YUV420_SEMI_PLANNER_VU、OUTPUT_YUV420SP_VU;如果是非8K的原图缩放,inputFormat和outputFormat的设置可参考表1

示例代码:

本示例是将yuv420sp格式的图片从1080p缩放到720p。

void NewVpcTest1()
{
    uint32_t inWidthStride = 1920;
    uint32_t inHeightStride = 1080;
    uint32_t outWidthStride = 1280;
    uint32_t outHeightStride = 720;
    uint32_t inBufferSize = inWidthStride * inHeightStride * 3 / 2; // 1080P yuv420sp Image
    uint32_t outBufferSize = outWidthStride * outHeightStride * 3 / 2; // 720P yuv420sp bImage
    uint8_t* inBuffer  = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(inBufferSize)); // Construct an input picture.
    if (inBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc input buffer");
        return;
    }
    uint8_t* outBuffer = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(outBufferSize)); // Construct an output picture.
    if (outBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc output buffer");
        HIAI_DVPP_DFree(inBuffer);
        inBuffer = nullptr;
        return;
    }

    FILE* fp = fopen("dvpp_vpc_1920x1080_nv12.yuv", "rb+");
    if (fp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_ERROR, "fopen file failed");
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }

    fread(inBuffer, 1, inBufferSize, fp);
    fclose(fp);
    fp = nullptr;
    // Construct the input picture configuration.
    std::shared_ptr<VpcUserImageConfigure> imageConfigure(new VpcUserImageConfigure);
    imageConfigure->bareDataAddr = inBuffer;
    imageConfigure->bareDataBufferSize = inBufferSize;
    imageConfigure->widthStride = inWidthStride;
    imageConfigure->heightStride = inHeightStride;
    imageConfigure->inputFormat = INPUT_YUV420_SEMI_PLANNER_UV;
    imageConfigure->outputFormat = OUTPUT_YUV420SP_UV;
    imageConfigure->yuvSumEnable = false;
    imageConfigure->cmdListBufferAddr = nullptr;
    imageConfigure->cmdListBufferSize = 0;
    std::shared_ptr<VpcUserRoiConfigure> roiConfigure(new VpcUserRoiConfigure);
    roiConfigure->next = nullptr;
    VpcUserRoiInputConfigure* inputConfigure = &roiConfigure->inputConfigure;
    // Set the drawing area, [0,0] in the upper left corner of the area,
    // and [1919,1079] in the lower right corner.
    inputConfigure->cropArea.leftOffset  = 0;
    inputConfigure->cropArea.rightOffset = inWidthStride - 1;
    inputConfigure->cropArea.upOffset    = 0;
    inputConfigure->cropArea.downOffset  = inHeightStride - 1;
    VpcUserRoiOutputConfigure* outputConfigure = &roiConfigure->outputConfigure;
    outputConfigure->addr = outBuffer;
    outputConfigure->bufferSize = outBufferSize;
    outputConfigure->widthStride = outWidthStride;
    outputConfigure->heightStride = outHeightStride;
    // Set the map area, coordinate [0,0] in the upper left corner of the map area,
    // and [1279,719] in the lower right corner.
    outputConfigure->outputArea.leftOffset  = 0;
    outputConfigure->outputArea.rightOffset = outWidthStride - 1;
    outputConfigure->outputArea.upOffset    = 0;
    outputConfigure->outputArea.downOffset  = outHeightStride - 1;

    imageConfigure->roiConfigure = roiConfigure.get();

    IDVPPAPI *pidvppapi = nullptr;
    int32_t ret = CreateDvppApi(pidvppapi);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_CREATE_DVPP_ERROR, "create dvpp api fail.");
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }
    dvppapi_ctl_msg dvppApiCtlMsg;
    dvppApiCtlMsg.in = static_cast<void*>(imageConfigure.get());
    dvppApiCtlMsg.in_size = sizeof(VpcUserImageConfigure);
    ret = DvppCtl(pidvppapi, DVPP_CTL_VPC_PROC, &dvppApiCtlMsg);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "call vpc dvppctl process faild!");
        ret = DestroyDvppApi(pidvppapi);
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    } else {
        HIAI_ENGINE_LOG(HIAI_OK, "NewVpcTest1::call vpc dvppctl process success!");
    }

    FILE* outImageFp = fopen("NewVpcTest1Out.yuv", "wb+");
    if (outImageFp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "open NewVpcTest1Out.yuv faild!");
        ret = DestroyDvppApi(pidvppapi);
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }

    fwrite(outBuffer, 1, outBufferSize, outImageFp);

    ret = DestroyDvppApi(pidvppapi);
    DFreeInOutBuffer(inBuffer, outBuffer);
    fclose(outImageFp);
    outImageFp = nullptr;
    return;
}

示例2:抠一张图+缩放

关键参数设置如下:

  • 抠图区域宽高是缩放前图片的宽高,可指定抠图区域的位置,例如:
    若指定抠图区域的位置在输入图片的中间,则抠图区域各偏移值的设置如下:
    • 左偏移leftOffset=100
    • 右偏移rightOffset=499
    • 上偏移upOffset=100
    • 下偏移downOffset=399
    • 右偏移rightOffset - 左偏移leftOffset+1=抠图区域图片的宽
    • 下偏移downOffset - 上偏移upOffset+1=抠图区域图片的高
  • 贴图区域宽高是缩放后图片的宽高,可指定贴图区域的位置,例如:
    若指定贴图区域的位置在输出图片的中间,则贴图区域各偏移值的设置如下:
    • 左偏移leftOffset=256
    • 右偏移rightOffset=399
    • 上偏移upOffset=200
    • 下偏移downOffset=399
    • 右偏移rightOffset - 左偏移leftOffset+1=缩放后图片的宽
    • 下偏移downOffset - 上偏移upOffset+1=缩放后图片的高

示例代码:

本示例是从yuv420sp格式、1080p的图片中抠出一张图,经过缩放后,将缩放后的图片贴到720p的输出图片(由用户申请的空输出内存产生的空白图片)中。如果需要将已有图片作为输出图片,用户需在申请输出内存后,将已有图片读入输出内存,代码示例请参考示例5:叠加

void NewVpcTest2()
{
    uint32_t inWidthStride = 1920;
    uint32_t inHeightStride = 1080;
    uint32_t outWidthStride = 1280;
    uint32_t outHeightStride = 720;
    uint32_t inBufferSize = inWidthStride * inHeightStride * 3 / 2; // 1080P yuv420sp Image
    uint32_t outBufferSize = outWidthStride * outHeightStride * 3 / 2; // 720P yuv420sp Image
    uint8_t* inBuffer  = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(inBufferSize)); //  Construct an input picture.
    if (inBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc input buffer");
        return;
    }
    uint8_t* outBuffer = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(outBufferSize)); //  Construct an output picture.
    if (outBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc output buffer");
        HIAI_DVPP_DFree(inBuffer);
        inBuffer = nullptr;
        return;
    }
    (void)memset_s(outBuffer, outBufferSize, 0x80, outBufferSize);

    FILE* fp = fopen("dvpp_vpc_1920x1080_nv12.yuv", "rb+");
    if (fp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_ERROR, "fopen file failed");
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }

    fread(inBuffer, 1, inBufferSize, fp);
    fclose(fp);
    fp = nullptr;
    // Construct the input picture configuration
    std::shared_ptr<VpcUserImageConfigure> imageConfigure(new VpcUserImageConfigure);
    imageConfigure->bareDataAddr = inBuffer;
    imageConfigure->bareDataBufferSize = inBufferSize;
    imageConfigure->widthStride = inWidthStride;
    imageConfigure->heightStride = inHeightStride;
    imageConfigure->inputFormat = INPUT_YUV420_SEMI_PLANNER_UV;
    imageConfigure->outputFormat = OUTPUT_YUV420SP_UV;
    imageConfigure->yuvSumEnable = false;
    imageConfigure->cmdListBufferAddr = nullptr;
    imageConfigure->cmdListBufferSize = 0;
    std::shared_ptr<VpcUserRoiConfigure> roiConfigure(new VpcUserRoiConfigure);
    roiConfigure->next = nullptr;
    VpcUserRoiInputConfigure* inputConfigure = &roiConfigure->inputConfigure;
    // Set the drawing area, [100,100] in the upper left corner of the area, and [499,499] in the lower right corner.
    inputConfigure->cropArea.leftOffset  = 100;
    inputConfigure->cropArea.rightOffset = 499;
    inputConfigure->cropArea.upOffset    = 100;
    inputConfigure->cropArea.downOffset  = 499;
    VpcUserRoiOutputConfigure* outputConfigure = &roiConfigure->outputConfigure;
    outputConfigure->addr = outBuffer;
    outputConfigure->bufferSize = outBufferSize;
    outputConfigure->widthStride = outWidthStride;
    outputConfigure->heightStride = outHeightStride;
    // Set the map area, [256,200] in the upper left corner of the map area, and [399,399] in the lower right corner.
    outputConfigure->outputArea.leftOffset  = 256; // The offset value must be 16-pixel-aligned.
    outputConfigure->outputArea.rightOffset = 399;
    outputConfigure->outputArea.upOffset    = 200;
    outputConfigure->outputArea.downOffset  = 399;

    imageConfigure->roiConfigure = roiConfigure.get();

    IDVPPAPI *pidvppapi = nullptr;
    int32_t ret = CreateDvppApi(pidvppapi);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_CREATE_DVPP_ERROR, "create dvpp api fail.");
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }
    dvppapi_ctl_msg dvppApiCtlMsg;
    dvppApiCtlMsg.in = static_cast<void*>(imageConfigure.get());
    dvppApiCtlMsg.in_size = sizeof(VpcUserImageConfigure);
    ret = DvppCtl(pidvppapi, DVPP_CTL_VPC_PROC, &dvppApiCtlMsg);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "call vpc dvppctl process faild!");
        ret = DestroyDvppApi(pidvppapi);
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    } else {
        HIAI_ENGINE_LOG(HIAI_OK, "NewVpcTest2::call vpc dvppctl process success!");
    }

    FILE* outImageFp = fopen("NewVpcTest2Out.yuv", "wb+");
    if (outImageFp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_ERROR, "open NewVpcTest2Out.yuv failed");
        DestroyDvppApi(pidvppapi);
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }
    fwrite(outBuffer, 1, outBufferSize, outImageFp);

    ret = DestroyDvppApi(pidvppapi);
    DFreeInOutBuffer(inBuffer, outBuffer);
    fclose(outImageFp);
    outImageFp = nullptr;
    return;
}

示例3:抠多张图+缩放+拼接

关键参数设置:抠图区域上偏移、下偏移、左偏移、右偏移以及贴图区域上偏移、下偏移、左偏移、右偏移的配置,请参见示例2:抠一张图+缩放中的说明。

示例代码:本示例是从yuv420sp格式、1080p的图片中抠出多张图,经过缩放后,将缩放后的多张图片拼接到720p的输出图片(由用户申请的空输出内存产生的空白图片)中,贴图区域拼接的位置由上偏移、下偏移、左偏移、右偏移的值决定。如果需要将已有图片作为输出图片,用户需在申请输出内存后,将已有图片读入输出内存,代码示例请参考示例5:叠加

void NewVpcTest3()
{
    uint32_t inWidthStride = 1920;
    uint32_t inHeightStride = 1080;
    uint32_t outWidthStride = 1280;
    uint32_t outHeightStride = 720;
    uint32_t inBufferSize = inWidthStride * inHeightStride * 3 / 2; // 1080P yuv420sp Image
    uint32_t outBufferSize = outWidthStride * outHeightStride * 3 / 2; // 720P yuv420sp Image
    uint8_t* inBuffer = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(inBufferSize)); // Construct an input picture.
    if (inBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc input buffer");
        return;
    }

    FILE* fp = fopen("dvpp_vpc_1920x1080_nv12.yuv", "rb+");
    if (fp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_ERROR, "fopen file failed");
        HIAI_DVPP_DFree(inBuffer);
        inBuffer = nullptr;
        return;
    }

    fread(inBuffer, 1, inBufferSize, fp);
    fclose(fp);
    fp == nullptr;
    // Construct the input picture configuration.
    std::shared_ptr<VpcUserImageConfigure> imageConfigure(new VpcUserImageConfigure);
    imageConfigure->bareDataAddr = inBuffer;
    imageConfigure->bareDataBufferSize = inBufferSize;
    imageConfigure->widthStride = inWidthStride;
    imageConfigure->heightStride = inHeightStride;
    imageConfigure->inputFormat = INPUT_YUV420_SEMI_PLANNER_UV;
    imageConfigure->outputFormat = OUTPUT_YUV420SP_UV;
    imageConfigure->yuvSumEnable = false;
    imageConfigure->cmdListBufferAddr = nullptr;
    imageConfigure->cmdListBufferSize = 0;
    std::shared_ptr<VpcUserRoiConfigure> lastRoi;
    std::vector<std::shared_ptr<VpcUserRoiConfigure>> roiVector;
    for (uint32_t i = 0; i < 5; i++) {
        std::shared_ptr<VpcUserRoiConfigure> roiConfigure(new VpcUserRoiConfigure);
        roiVector.push_back(roiConfigure);
        roiConfigure->next = nullptr;
        VpcUserRoiInputConfigure* inputConfigure = &roiConfigure->inputConfigure;
        // Set the drawing area.
        inputConfigure->cropArea.leftOffset  = 100 + i * 16;
        inputConfigure->cropArea.rightOffset = 499 + i * 16;
        inputConfigure->cropArea.upOffset    = 100 + i * 16;
        inputConfigure->cropArea.downOffset  = 499 + i * 16;
        VpcUserRoiOutputConfigure* outputConfigure = &roiConfigure->outputConfigure;
        uint8_t* outBuffer = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(outBufferSize)); // Construct an input picture
        if (outBuffer == nullptr) {
            HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc output buffer");
            HIAI_DVPP_DFree(inBuffer);
            inBuffer = nullptr;
            FreeMultipleRio(imageConfigure->roiConfigure);
            return;
        }
        (void)memset_s(outBuffer, outBufferSize, 0x80, outBufferSize);
        outputConfigure->addr = outBuffer;
        outputConfigure->bufferSize = outBufferSize;
        outputConfigure->widthStride = outWidthStride;
        outputConfigure->heightStride = outHeightStride;
        // Set the map area.
        outputConfigure->outputArea.leftOffset  = 256 + i * 16; // The offset value must be 16-pixel-aligned.
        outputConfigure->outputArea.rightOffset = 399 + i * 16;
        outputConfigure->outputArea.upOffset    = 256 + i * 16;
        outputConfigure->outputArea.downOffset  = 399 + i * 16;
        if (i == 0) {
            imageConfigure->roiConfigure = roiConfigure.get();
            lastRoi = roiConfigure;
        } else {
            lastRoi->next = roiConfigure.get();
            lastRoi = roiConfigure;
        }
    }

    IDVPPAPI *pidvppapi = nullptr;
    int32_t ret = CreateDvppApi(pidvppapi);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_CREATE_DVPP_ERROR, "create dvpp api fail.");
        HIAI_DVPP_DFree(inBuffer);
        inBuffer = nullptr;
        FreeMultipleRio(imageConfigure->roiConfigure);
        return;
    }
    dvppapi_ctl_msg dvppApiCtlMsg;
    dvppApiCtlMsg.in = static_cast<void*>(imageConfigure.get());
    dvppApiCtlMsg.in_size = sizeof(VpcUserImageConfigure);
    ret = DvppCtl(pidvppapi, DVPP_CTL_VPC_PROC, &dvppApiCtlMsg);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "call vpc dvppctl process faild!");
        ret = DestroyDvppApi(pidvppapi);
        HIAI_DVPP_DFree(inBuffer);
        inBuffer = nullptr;
        FreeMultipleRio(imageConfigure->roiConfigure);
        return;
    } else {
        HIAI_ENGINE_LOG(HIAI_OK, "NewVpcTest3::call vpc dvppctl process success!");
    }
    FILE* outImageFp = nullptr;
    uint32_t imageCount = 0;
    char fileName[50] = {0};

    while (imageConfigure->roiConfigure != nullptr) {
        int32_t safeFuncRet = sprintf_s(fileName, sizeof(fileName), "NewVpcTest3_%dOut.yuv", imageCount);
        if (safeFuncRet == -1) {
            HIAI_ENGINE_LOG(HIAI_ERROR, "sprintf_s fail, ret = %d", safeFuncRet);
            DestroyDvppApi(pidvppapi);
            HIAI_DVPP_DFree(inBuffer);
            inBuffer = nullptr;
            FreeMultipleRio(imageConfigure->roiConfigure);
            return;
        }
        outImageFp = fopen(fileName, "wb+");
        if (outImageFp == nullptr) {
            HIAI_ENGINE_LOG(HIAI_ERROR, "open %s faild!", fileName);
            DestroyDvppApi(pidvppapi);
            HIAI_DVPP_DFree(inBuffer);
            inBuffer = nullptr;
            FreeMultipleRio(imageConfigure->roiConfigure);
            return;
        }
        fwrite(imageConfigure->roiConfigure->outputConfigure.addr, 1,
            imageConfigure->roiConfigure->outputConfigure.bufferSize, outImageFp);
        fclose(outImageFp);
        outImageFp = nullptr;
        imageConfigure->roiConfigure = imageConfigure->roiConfigure->next;
        imageCount++;
    }
    ret = DestroyDvppApi(pidvppapi);
    HIAI_DVPP_DFree(inBuffer);
    inBuffer = nullptr;
    FreeMultipleRio(imageConfigure->roiConfigure);
    return;
}

示例4,8K缩放功能

对于8K缩放功能,支持缩放、支持YUV420SP NV12与YUV420SP NV21之间的格式转换、不支持抠图。

示例代码:本示例是将yuv420sp格式的图片从8129*8192缩放至4000*4000。

void NewVpcTest4()
{
    uint32_t inWidthStride = 8192; // No need for 128 byte alignment
    uint32_t inHeightStride = 8192; // No need for 16 byte alignment
    uint32_t outWidthStride = 4000; // No need for 128 byte alignment
    uint32_t outHeightStride = 4000; // No need for 16 byte alignment
    uint32_t inBufferSize = inWidthStride * inHeightStride * 3 / 2;
    uint32_t outBufferSize = outWidthStride * outHeightStride * 3 / 2; // Construct dummy data
    uint8_t* inBuffer = (uint8_t*)HIAI_DVPP_DMalloc(inBufferSize); // Construct input image
    if (inBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc roiOutput buffer");
        return;
    }
    uint8_t* outBuffer = (uint8_t*)HIAI_DVPP_DMalloc(outBufferSize); // Construct output image
    if (outBuffer == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "can not alloc roiOutput buffer");
        HIAI_DVPP_DFree(inBuffer);
        inBuffer = nullptr;
        return;
    }

    FILE* fp = fopen("dvpp_vpc_8192x8192_nv12.yuv", "rb+");
    if (fp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_ERROR, "fopen file failed");
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }
    fread(inBuffer, 1, inBufferSize, fp);
    fclose(fp);
    fp = nullptr;
    std::shared_ptr<VpcUserImageConfigure> imageConfigure(new VpcUserImageConfigure);
    imageConfigure->bareDataAddr = inBuffer;
    imageConfigure->bareDataBufferSize = inBufferSize;
    imageConfigure->isCompressData = false;
    imageConfigure->widthStride = inWidthStride;
    imageConfigure->heightStride = inHeightStride;
    imageConfigure->inputFormat = INPUT_YUV420_SEMI_PLANNER_UV;
    imageConfigure->outputFormat = OUTPUT_YUV420SP_UV;
    imageConfigure->yuvSumEnable = false;
    imageConfigure->cmdListBufferAddr = nullptr;
    imageConfigure->cmdListBufferSize = 0;
    std::shared_ptr<VpcUserRoiConfigure> roiConfigure(new VpcUserRoiConfigure);
    roiConfigure->next = nullptr;
    VpcUserRoiInputConfigure* inputConfigure = &roiConfigure->inputConfigure; // Set the roi area
    inputConfigure->cropArea.leftOffset  = 0;
    inputConfigure->cropArea.rightOffset = inWidthStride - 1;
    inputConfigure->cropArea.upOffset = 0;
    inputConfigure->cropArea.downOffset  = inHeightStride - 1;
    VpcUserRoiOutputConfigure* outputConfigure = &roiConfigure->outputConfigure;
    outputConfigure->addr = outBuffer;
    outputConfigure->bufferSize = outBufferSize;
    outputConfigure->widthStride = outWidthStride;
    outputConfigure->heightStride = outHeightStride; // Set the map area
    outputConfigure->outputArea.leftOffset  = 0;
    outputConfigure->outputArea.rightOffset = outWidthStride - 1;
    outputConfigure->outputArea.upOffset = 0;
    outputConfigure->outputArea.downOffset  = outHeightStride - 1;
    imageConfigure->roiConfigure = roiConfigure.get();
    IDVPPAPI *pidvppapi = nullptr;
    int32_t ret = CreateDvppApi(pidvppapi);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_CREATE_DVPP_ERROR, "create dvpp api fail.");
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }
    dvppapi_ctl_msg dvppApiCtlMsg;
    dvppApiCtlMsg.in = static_cast<void*>(imageConfigure.get());
    dvppApiCtlMsg.in_size = sizeof(VpcUserImageConfigure);
    ret = DvppCtl(pidvppapi, DVPP_CTL_VPC_PROC, &dvppApiCtlMsg);
    if (ret != 0) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "call vpc dvppctl process faild!");
        ret = DestroyDvppApi(pidvppapi);
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    } else {
        HIAI_ENGINE_LOG(HIAI_OK, "NewVpcTest4::call vpc dvppctl process success!");
    }

    FILE* outImageFp = fopen("NewVpcTest4Out.yuv", "wb+");
    if (outImageFp == nullptr) {
        HIAI_ENGINE_LOG(HIAI_VPC_CTL_ERROR, "open NewVpcTest4Out.yuv faild!");
        ret = DestroyDvppApi(pidvppapi);
        DFreeInOutBuffer(inBuffer, outBuffer);
        return;
    }
    fwrite(outBuffer, 1, outBufferSize, outImageFp);
    fclose(outImageFp);
    outImageFp = nullptr;
    ret = DestroyDvppApi(pidvppapi);
    DFreeInOutBuffer(inBuffer, outBuffer);
    return;
}

示例5:叠加

如果用户需要将已有图片读入内存用于存放输出图片,将贴图区域叠加在输出图片上,则需要编写代码逻辑将图片读入内存,在申请输出内存代码uint8_t* outBuffer = static_cast<uint8_t*>(HIAI_DVPP_DMalloc(outBufferSize));之后,增加如下代码:
FILE* fpOut = fopen("vpcOut.yuv", "rb+");
if  (fpOut == nullptr) {
    HIAI_ENGINE_LOG(HIAI_ERROR, "fopen file  failed.");
    fclose(fpOut);
    return;
}
fread(outBuffer, 1,  outBufferSize, fpOut);
fclose(fpOut);
分享:

    相关文档

    相关产品