之前研发童鞋在RK3399平台上调试 MPP编码框架进行1080P分辨率编码传输时,碰到几个问题导致画面有马赛克,主要包括以下几个方面:
问题描述:
- 码率很大, 设置的是512kbps
- 编码后数据异常,32640都不会变的,至少关键帧不会一样的
- 图像底部有马赛克,整体画质也不高
- 帧率过少
针对上面问题,经过查看具体编码码流,确实情况不太好,毕竟业务研发对于编解码参数不太熟悉,所以设置的参数异常了:
针对这些问题,我们对MPP编码框架进行一次调优,在此记录一下,作为参考方便后续童鞋遇到类似问题,防止踩坑。
优化完之后的结果虽然不是最好结果,但是能够满足项目要求,同时也在和RK进行沟通,学习更多的参数设置技巧,这里放一张:
MPP框架:
MPP是媒体处理软件平台(Media Process Platform)的简称,主要作用是隔离不同硬件厂商的实现,通过公共媒体处理接口实现跨平台和调用解决方案。在海思平台上也有类似MPP框架,瑞星微也有自己的MPP框架。
RK MPP框架:
瑞芯微提供的媒体处理软件平台(Media Process Platform,简称 MPP)是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理,其目的是为了屏蔽不 同芯片的差异,为使用者提供统一的视频媒体处理接口(Media Process Interface,缩写 MPI)。MPP 提供的功能包括:
相关代码仓库:
https://github.com/rockchip-linux/mpp
自己学习时候参考如下文档:
https://gitlab.com/rockchip_linux/docs/-/blob/master/Linux/Multimedia/MPP%20%E5%BC%80%E5%8F%91%E5%8F%82%E8%80%83_v0.3.pdf
其基本框架如下:
MPP启动逻辑:
调试的部分代码,有兴趣的小伙伴可以玩一下:
MppEncCfg cfg;
MppCodingType type = MPP_VIDEO_CodingAVC;
int ret = 0;
ret = mpp_create(&m_contex, &m_mpi);
if (ret) {
LOG(ERROR, "mpp create failed. error:%d", ret);
return -1;
}
ret = mpp_init(m_contex, MPP_CTX_ENC, type);
if (ret) {
LOG(ERROR, "mpp init failed. error:%d", ret);
return -1;
}
ret = mpp_enc_cfg_init(&cfg);
if (ret || !cfg) {
LOG(ERROR, "mpp_enc_cfg_init failed error:%d", ret);
return -1;
}
mpp_buffer_get(NULL, &m_buffer, m_param.frame_size);
/* fix input / output frame rate */
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", 0);
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", m_param.fps);
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denom", 1);
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", 0);
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", m_param.fps);
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denom", 1);
/* setup bitrate for different rc_mode */
mpp_enc_cfg_set_s32(cfg, "rc:bps_target", 14400);
mpp_enc_cfg_set_s32(cfg, "prep:width", m_param.width);
mpp_enc_cfg_set_s32(cfg, "prep:height", m_param.height);
mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", m_param.hor_stride);
mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", m_param.ver_stride);
mpp_enc_cfg_set_s32(cfg, "prep:format", m_param.fmt);
mpp_enc_cfg_set_s32(cfg, "rc:mode", MPP_ENC_RC_MODE_FIXQP);
mpp_enc_cfg_set_s32(cfg, "rc:qp_init", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 0);
mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_i", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_i", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_p", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_p", m_param.fix_qp);
mpp_enc_cfg_set_s32(cfg, "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
*/
mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
ret = m_mpi->control(m_contex, MPP_ENC_SET_CFG, cfg);
if (ret) {
LOG(ERROR, "mpi control MPP_ENC_SET_CFG failed error:%d", ret);
mpp_enc_cfg_deinit(cfg);
return -1;
}
mpp_dec_cfg_deinit(cfg);
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。