libhwjpeg は、MJPEG データのハードウェア エンコードとデコードを実行する RK によってパッケージ化されたもので、ソフトウェア エンコードに比べて比較的使いやすく、効率が向上しています。アプリケーション層はインターフェイスを提供しないため、JNI インターフェイスを自分でカプセル化する必要があります。ハードウェア エンコードとデコードのデモは SDK/hardware/rockchip/libhwjpeg/test に用意されており、コピーして使用することができます。以下は、私がカプセル化した 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;
}
プロジェクト全体には、エンコードとデコードだけでなく、複数のカメラ データのフォーマット変換、重ね合わせ、融合、結合、ズームなどが多く含まれるためです。同じような機能を実行している友人がいたら、何か質問はありますか?プライベートメッセージを通じてあなたの考えを共有できます~~