当前位置: 首页 > news >正文

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);

设置编码码率、质量、定码率变码率.

相关文章:

  • torch.nn.interpolate—torch上采样和下采样操作
  • DBCO-PEG-OPSS/OPSS-PEG-DBCO/二苯并环辛炔聚乙二醇修饰邻吡啶二硫
  • SpringCloud与SpringCloudAlibaba的比较
  • PostgreSQL修炼之道笔记之准备篇(四)
  • Springboot整合Redis集群实战详解
  • 聚乙烯亚胺偶联乳清白蛋白/肌白蛋白/豆清白蛋白/蓖麻蛋白/豌豆白蛋白1b ( PA1b)科研试剂
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • springBoot整合SqlSessionTemplate使用
  • jieba—第三方中文分词函数库
  • Python桌面文件清理脚本
  • STM32开发板在RT-Thread中使用segger_rtt软件包
  • SpringBoot异常处理机制之自定义404、500错误提示页面
  • Debezium系列之:深入理解Debezium是如何处理bigint unsigned类型的字段
  • MySQL基础篇【第四篇】| 连接查询、子查询(嵌套)
  • 【Linux】如何实现虚拟机系统与本地系统的通信连接
  • [Vue CLI 3] 配置解析之 css.extract
  • Android开源项目规范总结
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • JavaScript设计模式之工厂模式
  • jquery cookie
  • js操作时间(持续更新)
  • PHP CLI应用的调试原理
  • RxJS: 简单入门
  • Sass 快速入门教程
  • spring security oauth2 password授权模式
  • 第2章 网络文档
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​你们这样子,耽误我的工作进度怎么办?
  • ​人工智能书单(数学基础篇)
  • #etcd#安装时出错
  • #图像处理
  • $.proxy和$.extend
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (一)认识微服务
  • (转)创业家杂志:UCWEB天使第一步
  • (转)项目管理杂谈-我所期望的新人
  • .gitattributes 文件
  • .Net Redis的秒杀Dome和异步执行
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .Net的DataSet直接与SQL2005交互
  • .NET文档生成工具ADB使用图文教程
  • .NET中winform传递参数至Url并获得返回值或文件
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [ solr入门 ] - 利用solrJ进行检索
  • [C#]无法获取源 https://api.nuge t.org/v3-index存储签名信息解决方法
  • [docker]docker网络-直接路由模式
  • [Fri 26 Jun 2015 ~ Thu 2 Jul 2015] Deep Learning in arxiv
  • [FTP]pureftp部署和优化
  • [IE编程] IE中使网页元素进入编辑模式