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

实现JPEGE功能

  • 使用DvppGetOutParameter接口获取内存大小,由用户指定输出内存,由用户自行释放内存,调用示例如下 。
    void TEST_JPEGE_CUSTOM_MEMORY()
    {
        sJpegeIn  inData;
        sJpegeOut outData;
    
        inData.width         = g_width;
        inData.height        = g_high;
        inData.heightAligned = g_high; // no need to align
        inData.format        = (eEncodeFormat)g_format;
        inData.level         = 100;
    
        inData.stride  = ALIGN_UP(inData.width * 2, 16);
        inData.bufSize = inData.stride * inData.heightAligned;
        if (JPGENC_FORMAT_YUV420 == (inData.format & JPGENC_FORMAT_BIT)) {
            inData.stride  = ALIGN_UP(inData.width, 16);
            inData.bufSize = inData.stride * inData.heightAligned * 3 / 2;
        }
    
        void* addrOrig = HIAI_DVPP_DMalloc(inData.bufSize);
        if (addrOrig == nullptr) {
            HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "can not alloc input buffer");
            return;
        }
        inData.buf = reinterpret_cast<unsigned char*>(addrOrig);
    
        unsigned char* tmpAddr = nullptr;
    
        do {
            // load img file
            FILE* fpIn = fopen(g_inFileName, "rb");
            if (nullptr == fpIn) {
                HIAI_ENGINE_LOG(HIAI_OPEN_FILE_ERROR, "can not open input file");
                break;
            }
            // only copy valid image data, other part is pending
            if (JPGENC_FORMAT_YUV420 == (inData.format & JPGENC_FORMAT_BIT)) {
                // for yuv420semi-planar format, like nv12 / nv21
                HIAI_ENGINE_LOG("input yuv 420 data");
                // for y data
                for (uint32_t j = 0; j < inData.height; j++) {
                    fread(inData.buf + j * inData.stride, 1, inData.width, fpIn);
                }
                // for uv data
                for (uint32_t j = inData.heightAligned; j < inData.heightAligned + inData.height / 2; j++) {
                    fread(inData.buf + j * inData.stride, 1, inData.width, fpIn);
                }
            } else {
                // for yuv422packed format, like uyvy / vyuy / yuyv / yvyu
                HIAI_ENGINE_LOG("input yuv 422 data");
                for (uint32_t j = 0; j < inData.height; j++) {
                    fread(inData.buf + j * inData.stride, 1, inData.width * 2, fpIn);
                }
            }
            fclose(fpIn);
            fpIn = nullptr;
    
            int32_t ret = DvppGetOutParameter((void*)(&inData), (void*)(&outData), GET_JPEGE_OUT_PARAMETER);
            if (ret != 0) {
                HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "call DvppGetOutParameter process failed");
                break;
            }
            // 此处获得的jpgSize为估算值,实际数据长度可能要小于这个值
            // 最终jpgSize大小,以调用DvppCtl接口以后,此字段才为真正的编码后的jpgSize大小
            HIAI_ENGINE_LOG("outdata size is %d", outData.jpgSize);
            tmpAddr = (unsigned char*)HIAI_DVPP_DMalloc(outData.jpgSize);
            if (tmpAddr == nullptr) {
                HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "can not alloc output buffer");
                break;
            }
            uint32_t size = outData.jpgSize;
    
            // call jpege process
            dvppapi_ctl_msg dvppApiCtlMsg;
            dvppApiCtlMsg.in = (void *)&inData;
            dvppApiCtlMsg.in_size = sizeof(inData);
            dvppApiCtlMsg.out = (void *)&outData;
            dvppApiCtlMsg.out_size = sizeof(outData);
    
            if(!IsHandleJpegeCtlSucc(dvppApiCtlMsg, tmpAddr, size, &outData)) {
                break;
            }
        } while (0); // for resource inData.buf
        if (addrOrig != nullptr) {
            HIAI_DVPP_DFree(addrOrig);
            addrOrig = nullptr;
        }
        if (tmpAddr != nullptr) { // 注意:释放内存时需要使用tmpAddr,因为outData.jpgData在JPEGE处理后会有地址偏移
            HIAI_DVPP_DFree(tmpAddr);
            tmpAddr = nullptr;
        }
    }
    
  • 不由用户指定输出内存时,DVPP内部申请内存,需由用户调用cbFree()回调函数释放内存,调用示例如下。
    void JpegeProcess()
    {
        sJpegeIn  inData;
        sJpegeOut outData;
    
        inData.width         = g_width;
        inData.height        = g_high;
        inData.heightAligned = g_high; // no need to align
        inData.format        = (eEncodeFormat)g_format;
        inData.level         = 100;
    
        if (JPGENC_FORMAT_YUV420 == (inData.format & JPGENC_FORMAT_BIT)) {
            inData.stride  = ALIGN_UP(inData.width, 16);
            inData.bufSize = inData.stride * inData.heightAligned * 3 / 2;
        } else {
            inData.stride  = ALIGN_UP(inData.width * 2, 16);
            inData.bufSize = inData.stride * inData.heightAligned;
        }
    
        void* addrOrig = HIAI_DVPP_DMalloc(inData.bufSize);
    
        if (addrOrig == nullptr) {
            HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "can not alloc input buffer");
            return;
        }
        inData.buf = reinterpret_cast<unsigned char*>(addrOrig);
    
        do {
            // load img file
            FILE* fpIn = fopen(g_inFileName, "rb");
            if (fpIn == nullptr) {
                HIAI_ENGINE_LOG(HIAI_OPEN_FILE_ERROR, "can not open input file");
                break;
            }
            // only copy valid image data, other part is pending
            if (JPGENC_FORMAT_YUV420 == (inData.format & JPGENC_FORMAT_BIT)) {
                // for yuv420semi-planar format, like nv12 / nv21
                HIAI_ENGINE_LOG("input yuv 420 data");
                // for y data
                for (uint32_t j = 0; j < inData.height; j++) {
                    fread(inData.buf + j * inData.stride, 1, inData.width, fpIn);
                }
                // for uv data
                for (uint32_t j = inData.heightAligned; j < inData.heightAligned + inData.height / 2; j++) {
                    fread(inData.buf + j * inData.stride, 1, inData.width, fpIn);
                }
            } else {
                // for yuv422packed format, like uyvy / vyuy / yuyv / yvyu
                HIAI_ENGINE_LOG("input yuv 422 data");
                for (uint32_t j = 0; j < inData.height; j++) {
                    fread(inData.buf + j * inData.stride, 1, inData.width * 2, fpIn );
                }
    
            }
            fclose(fpIn);
            fpIn = nullptr;
    
            // call jpege process
            dvppapi_ctl_msg dvppApiCtlMsg;
            dvppApiCtlMsg.in = (void*)&inData;
            dvppApiCtlMsg.in_size = sizeof(inData);
            dvppApiCtlMsg.out = (void*)&outData;
            dvppApiCtlMsg.out_size = sizeof(outData);
    
            IDVPPAPI *pidvppapi = nullptr;
            CreateDvppApi(pidvppapi);
            if (pidvppapi == nullptr) {
                HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "can not open dvppapi engine");
                break;
            }
    
            JpegeProcessBranch(pidvppapi, dvppApiCtlMsg, outData);
    
            DestroyDvppApi(pidvppapi);
    
        } while (0); // for resource inData.buf
        if (addrOrig != nullptr) {
            HIAI_DVPP_DFree(addrOrig);
            addrOrig = nullptr;
        }
    }
    
    /*
     * only handle jpege process.
     */
    void JpegeProcessBranch(IDVPPAPI*& pidvppapi, dvppapi_ctl_msg& dvppApiCtlMsg, sJpegeOut& outData)
    {
        do {
            for (int i = 0;i < g_loop; i++) { // same picture loop test
                if (DvppCtl(pidvppapi, DVPP_CTL_JPEGE_PROC, &dvppApiCtlMsg)) {
                    HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "call jpeg encoder fail");
                    break;
                }
                if (i < g_loop - 1) {
                    outData.cbFree();
                    outData.jpgData = nullptr;
                }
            }
            stringstream outFile;
            outFile << g_outFileName << "_t" << std::this_thread::get_id() << ".jpg";
    
            FILE* fpOut = fopen(outFile.str().c_str(), "wb");
            if (fpOut != nullptr) {
                fwrite(outData.jpgData, 1, outData.jpgSize, fpOut);
                fflush(fpOut);
                fclose(fpOut);
                fpOut = nullptr;
            } else {
                HIAI_ENGINE_LOG(HIAI_JPEGE_CTL_ERROR, "call not save result file %s ", outFile.str().c_str());
            }
    
            outData.cbFree();
            outData.jpgData = nullptr;
            HIAI_ENGINE_LOG(HIAI_OK, "jpeg encode process completed");
        } while (0); // for resource pddvppapi
    }
分享:

    相关文档

    相关产品