【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(三)

简介: 【Android RTMP】x264 编码器初始化及设置 ( 获取 x264 编码参数 | 编码规格 | 码率 | 帧率 | B帧个数 | 关键帧间隔 | 关键帧解码数据 SPS PPS )(三)

七、 设置 x264 编码器 编码帧相关参数


1 . 关键帧解码数据 : 关键帧及后面的帧如何解码 , 需要根据 SPS , PPS 数据进行解码 ;



2 . 关键帧间距 : 这里使用 fps 描述关键帧之间的间距 , 2 秒一个关键帧 ;




3 . B 帧个数 : B 帧解码时, 既要参考前面的帧, 又要参考后面的帧 ;



① B 帧存在的意义 : 减小视频流的大小 ;


② B 帧存在的弊端 : 增加解码时间 ;


③ 直播场景的选择 : 直播中实时性性能很重要 , 因此这里选择不编码 B 帧 , 直接将 B 帧个数设置为 0 ;




4 . 特殊场景考虑 : 当前开发需求是直播 , 用户可能在任意时间进入直播间 ;



① 解码数据 SPS / PPS : 如果关键帧后面没有自带解码数据 , 那么用户如果进入该直播间 , 将无法观看直播 , 建议关键帧携带 SPS / PPS 解码数据 ;


② 关键帧间距 : 如果关键帧间距太长 , 用户在关键帧空档期间进入直播间 , 那么需要等到下一个关键帧到来 , 才能观看直播 , 建议将帧间距设置在 10 秒以内 ;


/*
   关键帧数据 I 是否附带 SPS PPS 数据
   编码后, 会输出图像编码后的数据
   第一个图像数据输入到 x264 编码器后, 进行编码
   编码的第一个图像编码出来的数据 肯定是 SPS PPS 关键帧 三种数据
   SPS PPS 作用是告知后续如何解码视频中的图像数据
   第二个图像数据输入到 x264 编码器后, 进行编码
   编码的第二个图像编码出来的数据 是 P 帧
   后续 n 个图像编码出 n 个 P 帧
   第 n + 3 个图像又编码出一个关键帧 I
   任何一个画面都可以编码成关键帧
   直播时建议设置成 1
   因为中途会有新用户加入, 此时该用户的播放器必须拿到 SPS PPS 才能解码画面
   否则无法观看视频
   如果设置成 0, 那么就需要开发者自己维护 SPS PPS 数据
   保证后来的用户可以看到直播画面
 */
x264Param.b_repeat_headers = 1;
// 计算帧间距的依据, 该设置表示使用 fps 帧率计算帧间距
// 两帧之间间隔多少 fps
// 也可以使用时间戳计算帧间距
x264Param.b_vfr_input = 0;
/*
   关键帧的间距, 两个关键帧之间的距离
   fps 表示 1 秒钟画面帧的数量, fps * 2 表示 2 秒钟的帧数
   该设置表示每隔 2 秒, 采集一个关键帧数据
   关键帧间隔时间不能太长
   关键帧间隔不能设置太长, 如设置 10 秒
   当用户1观看直播时, 不影响观看
   当用户2进入房间, 此时刚过去一个关键帧, 10秒内没有关键帧
   该用户需要等待 10 秒后收到关键帧数据后, 才有画面显示出来
 */
x264Param.i_keyint_max = fps * 2;
// 设置 B 帧个数, 这里设置没有 B 帧, 只有 I 帧和 P 帧
// B 帧解码时, 既要参考前面的帧, 又要参考后面的帧
// B 帧能减少传输的数据量, 但同时降低了解码速度, 直播中解码速度必须要快
x264Param.i_bframe = 0;





八、 x264 编码器参数设置代码示例


x264 编码器参数设置代码示例 :


// 设置 x264 编码器参数
    x264_param_t x264Param;
    /*
     * 获取 x264 编码器参数
     * int x264_param_default_preset( x264_param_t *, const char *preset, const char *tune )
     * 参数一 : x264_param_t * : x264 编码参数指针
     *
     * 参数二 : const char *preset : 设置编码速度, 这里开发直播, 需要尽快编码推流,
     * 这里设置最快的速度 ultrafast, 字符串常量, 值从 下面的参数中选择 ;
     * static const char * const x264_preset_names[] = { "ultrafast", "superfast", "veryfast",
     * "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };
     *
     * 参数三 : const char *tune : 视频编码场景设置, 这里选择 zerolatency 无延迟编码
     * static const char * const x264_tune_names[] = { "film", "animation", "grain",
     * "stillimage", "psnr", "ssim", "fastdecode", "zerolatency", 0 };
     *
     * 编码速度快, 意味着牺牲了画面的质量
     */
    x264_param_default_preset(&x264Param, "ultrafast", "zerolatency");
    // 编码规格设定, 32 对应的是 3.2 编码规格, 该规格下有指定的 码率, 帧率要求
    // 参考 https://www.wanweibaike.com/wiki-H.264 中的最大性能级别
    x264Param.i_level_idc = 32;
    // 设置输入到 x264 编码器的数据格式, 宽度, 高度等参数
    x264Param.i_csp = X264_CSP_I420;
    x264Param.i_width = mWidth;
    x264Param.i_height = mHeight;
    /*
       设置码率相关参数
       码率有三种模式 : X264_RC_CQP 恒定质量, X264_RC_CRF 恒定码率, X264_RC_ABR 平均码率
       这里设置一个平均码率输出
     */
    x264Param.rc.i_rc_method = X264_RC_ABR;
    // 设置码率, 单位是 kbps
    x264Param.rc.i_bitrate = bitrate / 1000;
    // 设置最大码率, 单位 kbps, 该配置与 i_vbv_buffer_size 配套使用
    x264Param.rc.i_vbv_max_bitrate = bitrate / 1000 * 1.2;
    // 该配置与 i_vbv_max_bitrate 配置配套使用, 码率控制缓冲区大小
    x264Param.rc.i_vbv_buffer_size = bitrate / 1000;
    // 设置帧率相关参数, 帧率是个有理数, 使用分数形式表示
    x264Param.i_fps_num = fps;  // 分子
    x264Param.i_fps_den = 1;    // 分母
    x264Param.i_timebase_den = x264Param.i_fps_num; //分子
    x264Param.i_timebase_num = x264Param.i_fps_den; //分母
    // 下面是关于帧的先关设置
    /*
       关键帧数据 I 是否附带 SPS PPS 数据
       编码后, 会输出图像编码后的数据
       第一个图像数据输入到 x264 编码器后, 进行编码
       编码的第一个图像编码出来的数据 肯定是 SPS PPS 关键帧 三种数据
       SPS PPS 作用是告知后续如何解码视频中的图像数据
       第二个图像数据输入到 x264 编码器后, 进行编码
       编码的第二个图像编码出来的数据 是 P 帧
       后续 n 个图像编码出 n 个 P 帧
       第 n + 3 个图像又编码出一个关键帧 I
       任何一个画面都可以编码成关键帧
       直播时建议设置成 1
       因为中途会有新用户加入, 此时该用户的播放器必须拿到 SPS PPS 才能解码画面
       否则无法观看视频
       如果设置成 0, 那么就需要开发者自己维护 SPS PPS 数据
       保证后来的用户可以看到直播画面
     */
    x264Param.b_repeat_headers = 1;
    // 计算帧间距的依据, 该设置表示使用 fps 帧率计算帧间距
    // 两帧之间间隔多少 fps
    // 也可以使用时间戳计算帧间距
    x264Param.b_vfr_input = 0;
    /*
       关键帧的间距, 两个关键帧之间的距离
       fps 表示 1 秒钟画面帧的数量, fps * 2 表示 2 秒钟的帧数
       该设置表示每隔 2 秒, 采集一个关键帧数据
       关键帧间隔时间不能太长
       关键帧间隔不能设置太长, 如设置 10 秒
       当用户1观看直播时, 不影响观看
       当用户2进入房间, 此时刚过去一个关键帧, 10秒内没有关键帧
       该用户需要等待 10 秒后收到关键帧数据后, 才有画面显示出来
     */
    x264Param.i_keyint_max = fps * 2;
    // 设置 B 帧个数, 这里设置没有 B 帧, 只有 I 帧和 P 帧
    // B 帧解码时, 既要参考前面的帧, 又要参考后面的帧
    // B 帧能减少传输的数据量, 但同时降低了解码速度, 直播中解码速度必须要快
    x264Param.i_bframe = 0;
    // 是否开启多线程
    x264Param.i_threads = 1;



目录
相关文章
|
22天前
|
XML API Android开发
码农之重学安卓:利用androidx.preference 快速创建一、二级设置菜单(demo)
本文介绍了如何使用androidx.preference库快速创建具有一级和二级菜单的Android设置界面的步骤和示例代码。
48 1
码农之重学安卓:利用androidx.preference 快速创建一、二级设置菜单(demo)
|
15天前
|
Android开发
Android经典实战之Textview文字设置不同颜色、下划线、加粗、超链接等效果
本文介绍了 `SpannableString` 在 Android 开发中的强大功能,包括如何在单个字符串中应用多种样式,如颜色、字体大小、风格等,并提供了详细代码示例,展示如何设置文本颜色、添加点击事件等,助你实现丰富文本效果。
55 3
|
15天前
|
Web App开发 网络协议 Android开发
Android平台一对一音视频通话方案大比拼:WebRTC VS RTMP VS RTSP,谁才是王者?
【9月更文挑战第4天】本文详细对比了在Android平台上实现一对一音视频通话时常用的WebRTC、RTMP及RTSP三种技术方案。从技术原理、性能表现与开发难度等方面进行了深入分析,并提供了示例代码。WebRTC适合追求低延迟和高质量的场景,但开发成本较高;RTMP和RTSP则在简化开发流程的同时仍能保持较好的传输效果,适用于不同需求的应用场景。
36 1
|
18天前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
76 0
|
28天前
|
开发工具 Android开发
Android项目架构设计问题之外部客户方便地设置回调如何解决
Android项目架构设计问题之外部客户方便地设置回调如何解决
16 0
|
4月前
|
存储 算法 安全
AVB数据解析:Android verified boot 2.0 vbmeta 数据结构解析
AVB数据解析:Android verified boot 2.0 vbmeta 数据结构解析
495 0
|
存储 Android开发
【Android 逆向】函数拦截 ( GOT 表数据结构分析 | 函数根据 GOT 表进行跳转的流程 )
【Android 逆向】函数拦截 ( GOT 表数据结构分析 | 函数根据 GOT 表进行跳转的流程 )
146 0
【Android 逆向】函数拦截 ( GOT 表数据结构分析 | 函数根据 GOT 表进行跳转的流程 )
|
机器学习/深度学习 Java Android开发
Android中需要了解的数据结构(一)
Java容器类 Java容器类是java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等。 Java容器主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections) 【文章纯干货 请仔细阅读哦!】   通过上图,可以把握两个基本主体,即Collection和Map。
|
JavaScript Java Android开发
Android中需要了解的数据结构(一)
Java容器类 Java容器类是java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等。Java容器主要可以划分为4个部分:List列表、Set集合、Map映射、工具类(Iterator迭代器、Enumeration枚举类、Arrays和Collections)**【文章纯干货 请仔细阅读哦!】** 通过上图,可以把握两个基本主体,即Collection和Map。
|
API Android开发 Java
Android开发之那些好用的数据结构与API(三)
之前的系列文章 Android开发之那些好用的数据结构与API 和Android开发之那些好用的数据结构与API(二)中,已经介绍了一些,趁热打铁,本次介绍的内容很实用哦~~ 1、RoundedBitmapDrawable RoundedBitmapDrawable 是 android.support.v4.graphics.drawable 里面的一个类,但是记得一定得是21+以上的版本。
781 0