|
|
1 概述
|
|
|
HwJpeg 库用于支持 Rockchip 平台 JPEG 硬编解码,是平台 MPP(Media Process Platform)
|
|
|
库 JPEG 编解码逻辑的封装。其中,MpiJpegEncoder 类封装了硬编码相关操作,MpiJpegDecoder
|
|
|
类封装了硬解码相关操作,用于支持图片或 MJPEG 码流解码。
|
|
|
|
|
|
工程包含主要目录:
|
|
|
- inc:HwJpeg 库头文件
|
|
|
- src:HwJpeg 库实现代码
|
|
|
- test:HwJpeg 测试实例
|
|
|
|
|
|
> 工程代码使用 mk 文件组织,在 Android SDK 环境下直接编译使用即可。
|
|
|
|
|
|
2 MpiJpegDecoder
|
|
|
MpiJpegDecoder 类是平台 JPEG 硬解码的封装,支持输入 JPG 图片及 MJPEG 码流,同时支持同步及
|
|
|
异步解码方式。
|
|
|
|
|
|
- decodePacket(char* data, size_t size, OutputFrame_t *aframeOut);
|
|
|
- decodeFile(const char *input_file, const char *output_file);
|
|
|
|
|
|
decodePacket & decodeFile 为同步解码方式,同步解码方式使用简单,阻塞等待解码输出,
|
|
|
OutputFrame_t 为解码输出封装,包含输出帧宽、高、物理地址、虚拟地址等信息。
|
|
|
|
|
|
- sendpacket(char* input_buf, size_t buf_len);
|
|
|
- getoutframe(OutputFrame_t *aframeOut);
|
|
|
|
|
|
sendpacket & getoutframe 用于配合实现异步解码输出,应用端处理开启两个线程,一
|
|
|
个线程送输入 sendpacket,另一个线程异步取输出 getoutframe。
|
|
|
|
|
|
**Note:**
|
|
|
1. HwJpeg 解码默认输出 RAW NV12 数据
|
|
|
2. 平台硬解码器只处理对齐过的 buffer,因此 MpiJpegDecoder 输出的 YUV buffer 经过 16 位对齐。
|
|
|
如果原始宽高非 16 位对齐,直接显示可能出现底部绿边等问题,MpiJpegDecoder 实现代码中 mOutputCrop
|
|
|
用于实现 OutFrame 的裁剪操作,可手动开启,也可以外部获取 OutFrame 句柄再进行相应的裁剪。
|
|
|
3. OutFrame buffer 在解码库内部循环使用,在解码显示完成之后使用 deinitOutputFrame 释放内存。
|
|
|
4. 默认情况下,输出 buffer 使用内部申请的 buffer 轮转池,但是也允许外部传递 dma buffer fd 用作
|
|
|
解码输出,额外传递的 dma buffer fd 由 decodePacket 函数参数 OutputFrame_t->outputPhyAddr 传入。
|
|
|
|
|
|
解码使用示例:
|
|
|
```
|
|
|
MpiJpegDecoder decoder;
|
|
|
MpiJpegDecoder::OutputFrame_t frameOut;
|
|
|
|
|
|
ret = decoder.prepareDecoder();
|
|
|
if (!ret) {
|
|
|
ALOGE("failed to prepare JPEG decoder");
|
|
|
goto DECODE_OUT;
|
|
|
}
|
|
|
|
|
|
memset(&frameOut, 0, sizeof(MpiJpegDecoder::OutputFrame_t));
|
|
|
ret = decoder.decodePacket(buf, size, &frameOut);
|
|
|
if (!ret) {
|
|
|
ALOGE("failed to decode packet");
|
|
|
goto DECODE_OUT;
|
|
|
}
|
|
|
|
|
|
decoder.deinitOutputFrame(&frameOut);
|
|
|
decoder.flushBuffer();
|
|
|
```
|
|
|
|
|
|
3 MpiJpegEncoder
|
|
|
MpiJpegEncoder 类是平台 JPEG 硬编码的封装,目前主要有三类接口提供:
|
|
|
|
|
|
- encodeFrame(char *data, OutputPacket_t *aPktOut);
|
|
|
- encodeFile(const char *input_file, const char *output_file);
|
|
|
|
|
|
encodeFrame & encodeFile 为同步阻塞编码方式,OutputPacket_t 为编码输出封装,
|
|
|
包含输出数据的内存地址信息。
|
|
|
|
|
|
- encode(EncInInfo *aInInfo, EncOutInfo *aOutInfo);
|
|
|
|
|
|
encode 输入数据类型为文件 fd,是为 cameraHal 设计的一套编码方式,输出 JPEG 图片
|
|
|
包含编码缩略图、APP1 EXIF 头信息等。
|
|
|
|
|
|
**Note:**
|
|
|
1. OutputPacket_t buffer 在编码库内部循环使用,在编码处理完成之后使用 deinitOutputPacket 释放内存
|
|
|
|
|
|
编码使用示例:
|
|
|
```
|
|
|
MpiJpegEncoder encoder;
|
|
|
MpiJpegEncoder::OutputPacket_t pktOut;
|
|
|
|
|
|
ret = encoder.prepareEncoder();
|
|
|
if (!ret) {
|
|
|
ALOGE("failed to prepare JPEG encoder");
|
|
|
goto ENCODE_OUT;
|
|
|
}
|
|
|
|
|
|
ret = encoder.updateEncodeCfg(720 /*width*/, 1080 /*height*/,
|
|
|
MpiJpegEncoder::INPUT_FMT_YUV420SP);
|
|
|
if (!ret) {
|
|
|
ALOGE("failed to update encode config");
|
|
|
goto ENCODE_OUT;
|
|
|
}
|
|
|
|
|
|
memset(&pktOut, 0, sizeof(MpiJpegEncoder::OutputPacket_t));
|
|
|
ret = encoder.encodeFrame(buf, &pktOut);
|
|
|
if (!ret) {
|
|
|
ALOGE("failed to encode packet");
|
|
|
goto ENCODE_OUT;
|
|
|
}
|
|
|
|
|
|
/* TODO - Get diaplay for the PacketOut.
|
|
|
* - Pakcet address: pktOut.data
|
|
|
* - Pakcet size: pktOut.size */
|
|
|
|
|
|
/* Output frame buffers within limits, so release frame buffer if one
|
|
|
frame has been display successful. */
|
|
|
encoder.deinitOutputPacket(&pktOut);
|
|
|
```
|