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