RK平台H264编码参数调试问题汇总

之前研发童鞋在RK3399平台上调试 MPP编码框架进行1080P分辨率编码传输时,碰到几个问题导致画面有马赛克,主要包括以下几个方面:

问题描述:

  1. 码率很大, 设置的是512kbps
  2. 编码后数据异常,32640都不会变的,至少关键帧不会一样的
  3. 图像底部有马赛克,整体画质也不高
  4. 帧率过少

针对上面问题,经过查看具体编码码流,确实情况不太好,毕竟业务研发对于编解码参数不太熟悉,所以设置的参数异常了:

RK平台H264编码参数调试问题汇总

针对这些问题,我们对MPP编码框架进行一次调优,在此记录一下,作为参考方便后续童鞋遇到类似问题,防止踩坑。

优化完之后的结果虽然不是最好结果,但是能够满足项目要求,同时也在和RK进行沟通,学习更多的参数设置技巧,这里放一张:

RK平台H264编码参数调试问题汇总

MPP框架:

MPP是媒体处理软件平台(Media Process Platform)的简称,主要作用是隔离不同硬件厂商的实现,通过公共媒体处理接口实现跨平台和调用解决方案。在海思平台上也有类似MPP框架,瑞星微也有自己的MPP框架。

RK MPP框架:

瑞芯微提供的媒体处理软件平台(Media Process Platform,简称 MPP)是适用于瑞芯微芯片系列的通用媒体处理软件平台。该平台对应用软件屏蔽了芯片相关的复杂底层处理,其目的是为了屏蔽不 同芯片的差异,为使用者提供统一的视频媒体处理接口(Media Process Interface,缩写 MPI)。MPP 提供的功能包括:

RK平台H264编码参数调试问题汇总

相关代码仓库:

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

其基本框架如下:

RK平台H264编码参数调试问题汇总

MPP启动逻辑:

RK平台H264编码参数调试问题汇总

调试的部分代码,有兴趣的小伙伴可以玩一下:

 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 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论