RKMPP库快速上手--MPP解码入门
Posted Geek.Fan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RKMPP库快速上手--MPP解码入门相关的知识,希望对你有一定的参考价值。
一、RKMPP整个解码流程简单介绍一下:
1. 创建 MPP context 和 MPP api 接口。 (注意,和RGA一样,多个线程多个实例需要多个独立的的context)
ret = mpp_create(&ctx, &mpi);
if (MPP_OK != ret)
mpp_err("mpp_create failed\\n");
goto MPP_TEST_OUT;
2. 设置一些MPP的模式(这里设置的是 MPP_DEC_SET_PARSER_SPLIT_MODE)
mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE;
param = &need_split;
ret = mpi->control(ctx, mpi_cmd, param);
if (MPP_OK != ret)
mpp_err("mpi->control failed\\n");
goto MPP_TEST_OUT;
常用设置的一些模式解释如下:(其余的可以看MPP自带的开发文档,在doc目录下有详细说明)MPP_DEC_SET_PARSER_SPLIT_MODE : (仅限解码),自动拼包(建议开启),硬编解码器每次解码就是一个Frame,所以如果输入的数据不确定是不是一个Frame(例如可能是一个Slice、一个Nalu或者一个FU-A分包,甚至可能随意读的任意长度数据),那就必须把该模式打开,MPP会自动分包拼包成一个完整Frame送给硬解码器。
MPP_DEC_SET_IMMEDIATE_OUT: (仅限解码)
立即输出模式(不建议开启),如果未开立即输出模式,MPP会按预先设定的节奏间隔输出解码的帧(例如33ms输出一帧)。但是实际硬件解码过程并不是均匀输出的,有时候两帧间隔可能就1ms一下子输出2-3帧,有时候两帧间又会有较长的间隔。如果打开立即输出模式,MPP就会在解码成功后立即输出一帧,那后续处理显示的节奏就需要用户自己控制。该模式适用于一些对实时性要求比较高的客户产品,需要自己把握输出节奏。
MPP_SET_INPUT_BLOCK:
MPP_SET_INTPUT_BLOCK_TIMEOUT:
MPP_SET_OUTPUT_BLOCK:
MPP_SET_OUTPUT_BLOCK_TIMEOUT:
设置输入输出的block模式,如果block模式打开,喂数据时候会block住直到编解码成功入队列或者出队列或者达到TIMEOUT时间,才会返回。
3. 初始化 MPP
ret = mpp_init(ctx, MPP_CTX_DEC, MppCodingType::MPP_VIDEO_CodingAVC);
if (MPP_OK != ret)
mpp_err("mpp_init failed\\n");
goto MPP_TEST_OUT;
初始化编码还是解码,以及编解码的格式。
MPP_CTX_DEC : 解码
MPP_CTX_ENC : 编码
MPP_VIDEO_CodingAVC : H.264
MPP_VIDEO_CodingHEVC : H.265
MPP_VIDEO_CodingVP8 : VP8
MPP_VIDEO_CodingVP9 : VP9
MPP_VIDEO_CodingMJPEG : MJPEG
等等,详细参看rk_mpi.h定义
4. 解码的话到这里初始化就完成了,编码的话需要多设置一些参数
设置编码宽高、对齐后宽高参数
mRcCfg.change = MPP_ENC_RC_CFG_CHANGE_ALL;
/*
* rc_mode - rate control mode
* Mpp balances quality and bit rate by the mode index
* Mpp provide 5 level of balance mode of quality and bit rate
* 1 - only quality mode: only quality parameter takes effect
* 2 - more quality mode: quality parameter takes more effect
* 3 - balance mode : balance quality and bitrate 50 to 50
* 4 - more bitrate mode: bitrate parameter takes more effect
* 5 - only bitrate mode: only bitrate parameter takes effect
*/
if (mIsCBR)
mRcCfg.rc_mode = (MppEncRcMode) MPP_ENC_RC_MODE_CBR;
else
mRcCfg.rc_mode = (MppEncRcMode) MPP_ENC_RC_MODE_VBR;
/*
* quality - quality parameter
* mpp does not give the direct parameter in different protocol.
* mpp provide total 5 quality level 1 ~ 5
* 0 - auto
* 1 - worst
* 2 - worse
* 3 - medium
* 4 - better
* 5 - best
*/
if (mQuality > 4)
mRcCfg.quality = (MppEncRcQuality)MPP_ENC_RC_QUALITY_BEST;
else
mRcCfg.quality = (MppEncRcQuality)mQuality;
int bps = mBps;
switch (mRcCfg.rc_mode)
case MPP_ENC_RC_MODE_CBR:
// constant bitrate has very small bps range of 1/16 bps
mRcCfg.bps_target = bps;
mRcCfg.bps_max = bps * 17 / 16;
mRcCfg.bps_min = bps * 15 / 16;
break;
case MPP_ENC_RC_MODE_VBR:
// variable bitrate has large bps range
mRcCfg.bps_target = bps;
mRcCfg.bps_max = bps * 3 / 2;
mRcCfg.bps_min = bps * 1 / 2;
break;
default:
abort();
/* fix input / output frame rate */
mRcCfg.fps_in_flex = 0;
mRcCfg.fps_in_num = mFps;
mRcCfg.fps_in_denorm = 1;
mRcCfg.fps_out_flex = 0;
mRcCfg.fps_out_num = mFps;
mRcCfg.fps_out_denorm = 1;
mRcCfg.gop = mIInterval; /* i frame interval */
mRcCfg.skip_cnt = 0;
int ret = mMppApi->control(mMppCtx, MPP_ENC_SET_RC_CFG, &mRcCfg);
设置264相关的其他编码参数:
mCodecCfg.h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE |
MPP_ENC_H264_CFG_CHANGE_ENTROPY |
MPP_ENC_H264_CFG_CHANGE_TRANS_8x8 |
MPP_ENC_H264_CFG_CHANGE_QP_LIMIT;
/*
* H.264 profile_idc parameter
* 66 - Baseline profile
* 77 - Main profile
* 100 - High profile
*/
mCodecCfg.h264.profile = 100;
/*
* H.264 level_idc parameter
* 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
* 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
* 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
* 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
* 50 / 51 / 52 - 4K@30fps
*/
mCodecCfg.h264.level = 40;
mCodecCfg.h264.entropy_coding_mode = 1;
mCodecCfg.h264.cabac_init_idc = 0;
mCodecCfg.h264.transform8x8_mode = 1;
if (mRcCfg.rc_mode == MPP_ENC_RC_MODE_CBR)
mCodecCfg.h264.qp_init = 10;
mCodecCfg.h264.qp_min = 4;
mCodecCfg.h264.qp_max = 30;
mCodecCfg.h264.qp_max_step = 16;
int ret = mMppApi->control(mMppCtx, MPP_ENC_SET_CODEC_CFG, &mCodecCfg);
mPrepCfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | MPP_ENC_PREP_CFG_CHANGE_FORMAT;
mPrepCfg.width = mWidth;
mPrepCfg.height = mHeight;
mPrepCfg.hor_stride = mHStride;
mPrepCfg.ver_stride = mVStride;
mPrepCfg.format = mFrameFormat;
int ret = mMppApi->control(mMppCtx, MPP_ENC_SET_PREP_CFG, &mPrepCfg);
设置编码码率、质量、定码率变码率.
以上是关于RKMPP库快速上手--MPP解码入门的主要内容,如果未能解决你的问题,请参考以下文章