RK3568 应用层 libhwjpeg.so 硬件编解码的使用

        libhwjpeg是RK封装的一个对MJPEG数据进行硬件编解码的so,用起来还是比较方便,相比软编效率也有提升。应用层没有提供接口,所以需要自己封装JNI接口。在SDK/hardware/rockchip/libhwjpeg/test 下有提供硬件编解码的demo,直接照搬过来用即可。以下是我封装的JNI接口
        硬解 

extern "C"
JNIEXPORT jbyteArray JNICALL
Java_com_wirelessmedia_eserver_remotecamera_camerafusion_HwjpegUtil_decodeFrame(JNIEnv *env,jobject thiz,jbyteArray data,jint size) {      
        MpiJpegDecoder *pDecoder = new MpiJpegDecoder();//创建解码器
        /*准备参数,这里RK默认输出的是NV12的数据,询问过RK,对于YUV420 目前输出也只支持
           NV12,如果需要其他格式的可以通过librga进行转换   
        */
        bool ret =pDecoder->prepareDecoder();

        if(!ret) return nullptr;
        
        jbyte *src_data= env->GetByteArrayElements(data, 0); //应用层传递的jpeg buf
        MpiJpegDecoder::OutputFrame_t frameOut; 
        memset(&frameOut, 0, sizeof(MpiJpegDecoder::OutputFrame_t));
        ret = pDecoder->decodePacket((char *)src_data, size, &frameOut);//解码 size为jpeg的buf长度
        if(!ret) return nullptr;
        LOGD("width = %d,height = %d",frameOut.DisplayWidth,frameOut.DisplayHeight);
        /*
            frameOut.MemVirAddr 为解码后的 char*数组 test demo中有介绍
        */
        int len = frameOut.DisplayWidth*frameOut.DisplayHeight*3/2;
        jbyteArray jbyteArray = env->NewByteArray(len);//申明数组,与char字符长度一致
        env->SetByteArrayRegion(jbyteArray, 0, len, (jbyte *) frameOut.MemVirAddr);
        pDecoder->deinitOutputFrame(&frameOut);
        return jbyteArray ;
}
  

        硬编
        

extern "C"
JNIEXPORT jbyteArray JNICALL
Java_com_wirelessmedia_eserver_remotecamera_camerafusion_HwjpegUtil_encodeFrame(JNIEnv *env,jobject thiz,jbyteArray data,jint width,jint height) {  
    MpiJpegEncoder *pEncoder = new MpiJpegEncoder(); //创建编码器
    bool ret = pEncoder->prepareEncoder(); //准备编码器
    if(!ret){
        LOGD("prepareEncoder fail");
        return nullptr;
    }
    //设置参数  这里的输入格式是比较多可以选
    /*
            typedef enum {
        INPUT_FMT_YUV420SP     = MPP_FMT_YUV420SP,
        INPUT_FMT_YUV420P      = MPP_FMT_YUV420P,
        INPUT_FMT_YUV422SP_VU  = MPP_FMT_YUV422SP_VU,
        INPUT_FMT_YUV422_YUYV  = MPP_FMT_YUV422_YUYV,
        INPUT_FMT_YUV422_UYVY  = MPP_FMT_YUV422_UYVY,
        INPUT_FMT_ARGB8888     = MPP_FMT_ARGB8888,
        INPUT_FMT_RGBA8888     = MPP_FMT_RGBA8888,
        INPUT_FMT_ABGR8888     = MPP_FMT_ABGR8888
    } InputFormat;
    */
    ret = pEncoder->updateEncodeCfg(width, height, MpiJpegEncoder::INPUT_FMT_YUV420SP);
    if(!ret){
        LOGD("updateEncodeCfgfail");
        return nullptr;
    }

    jbyte *src_data= env->GetByteArrayElements(data, 0);//传进来的yuv数据 
    MpiJpegEncoder::OutputPacket_t pktOut;
    memset(&pktOut, 0, sizeof(MpiJpegEncoder::OutputPacket_t));
    ret = pEncoder->encodeFrame((char *) src_data, &pktOut); //编码
    if(!ret){
        return nullptr;
    }
    //pktOut.size 是编码后的长度 pktOut.data 编码后的buf 数组
    jbyteArray jbyteArray = env->NewByteArray(pktOut.size);//申明数组,与char字符长度一致
    env->SetByteArrayRegion(jbyteArray, 0, pktOut.size, (jbyte *) pktOut.data);
    pEncoder->deinitOutputPacket(&pktOut);
    return jbyteArray; 
}  

因为整个项目有些涉及到的不仅仅是编码解码,还涉及到很多格式转换,多个摄像头数据的叠加,融合,拼接 缩放等等,如果有小伙伴刚好也是做类似功能,有什么疑问,或者有什么想法我们可以私信交流下~~

猜你喜欢

转载自blog.csdn.net/weixin_35649059/article/details/127610023