Android 直播推流流程 : 手机采集视频 / 音频数据 , 视频数据使用 H.264 编码 , 音频数据使用 AAC 编码 , 最后将音视频数据都打包到 RTMP 数据包中 , 使用 RTMP 协议上传到 RTMP 服务器中 ;
Android 端中主要完成手机端采集视频数据操作 , 并将视频数据传递给 JNI , 在 NDK 中使用 x264 将图像转为 H.264 格式的视频 , 最后将 H.264 格式的视频打包到 RTMP 数据包中 , 上传到 RTMP 服务器中 ;
本篇博客中在 NDK 层使用 x264 对 Camera 采集到的数据进行编码 , 将 NV21 格式的视频数据编码为 H.264 格式的数据 , 首先要设置 x264 编码器的参数 ; 1 . 图像数据转换 : Camera 获取的是 NV21 格式的图像数据, 先将 NV21 格式的图像数据转为 I420 格式的图像数据 , 再将 I420 格式的图像数据编码为 H.264 格式的视频数据 ;
2 . 需要使用 x264 开源库 : 上述图像格式转换中 , I420 图像编码为 H.264 视频就需要使用 x264 开源库 , 这是目前性能最好的开源库 ;
3 . x264 编码器参数设置 : 使用 x264 编码 H.264 视频之前 , 首先要创建 x264 编码器 , 然后设置该编码器参数 ;
4 . 头文件导入 : 使用 x264 编码器之前 , 首先导入头文件 ;
5 . x264 编码器参数 x264_param_t 类型 : 是一个结构体类型 ; 1 . 获取 x264 编码器参数步骤 :
① 声明 x264 编码器参数 : 在栈内存中声明 x264 编码器参数 , 之后对其进行赋值 ; ② 获取默认的编码器参数 : 调用 x264_param_default_preset 方法 , 可以获取 x264 编码器默认的参数 ; 2 . 函数 x264_param_default_preset ( ) 解析 :
① 参数 x264_param_t * 设置 : x264_param_t 类型的 x264 编码器参数指针 , 即上面声明的 x264 编码器参数的地址 ; ② 参数 const char *preset 设置 : 设置编码速度 , 这里开发直播 , 需要尽快编码推流 , 这里设置最快的速度 ultrafast ; ③ 参数 const char *tune 设置 : 视频编码场景设置 , 这里选择 zerolatency 无延迟编码 , 同样要求最低延迟 ; ④ 函数原型 :
上述的最快编码速度 ultrafast , 和无延迟编码 zerolatency , 都要求编码速度要尽可能快 , 代价是牺牲了视频的质量 ; 1 . 设置 x264 编码器编码规格 : 每个编码规格都有对应的性能指标要求 , 如下图的表格 , 设置的 32 编码规则表示其中的 3.2 级别的 H.264 参数性能 ;
2 . H.264 编码规格 : 1 . 设置 x264 编码器编码图像数据格式 :
① 编码尺寸设置 : 将 Camera 支持的宽高尺寸 , 设置给该 x264 编码器参数的 i_width , i_height 字段 ; ② 可设置的输入图像格式 : 经过测试 , 只有 X264_CSP_I420 格式能顺利编码成 H.264 视频数据 ;
2 . 设置 x264 编码器编码图像数据格式代码示例 : 码率有三种模式 : X264_RC_CQP 恒定质量 , X264_RC_CRF 恒定码率 , X264_RC_ABR 平均码率 , 这里设置一个平均码率输出 ; 设置 x264 编码器 帧率相关参数 : 设置帧率相关参数 , 帧率是个有理数 , 使用分数形式表示 , 这里分别定义分子和分母 ; 1 . 关键帧解码数据 : 关键帧及后面的帧如何解码 , 需要根据 SPS , PPS 数据进行解码 ;
2 . 关键帧间距 : 这里使用 fps 描述关键帧之间的间距 , 2 秒一个关键帧 ; 3 . B 帧个数 : B 帧解码时, 既要参考前面的帧, 又要参考后面的帧 ;
① B 帧存在的意义 : 减小视频流的大小 ; ② B 帧存在的弊端 : 增加解码时间 ; ③ 直播场景的选择 : 直播中实时性性能很重要 , 因此这里选择不编码 B 帧 , 直接将 B 帧个数设置为 0 ; 4 . 特殊场景考虑 : 当前开发需求是直播 , 用户可能在任意时间进入直播间 ;
① 解码数据 SPS / PPS : 如果关键帧后面没有自带解码数据 , 那么用户如果进入该直播间 , 将无法观看直播 , 建议关键帧携带 SPS / PPS 解码数据 ; ② 关键帧间距 : 如果关键帧间距太长 , 用户在关键帧空档期间进入直播间 , 那么需要等到下一个关键帧到来 , 才能观看直播 , 建议将帧间距设置在 10 秒以内 ; x264 编码器参数设置代码示例 :文章目录
一、 x264 编码器参数设置引入
#include <x264.h>
typedef struct x264_param_t { //... }
二、 获取 x264 编码器参数
// 设置 x264 编码器参数 x264_param_t x264Param;
x264_param_default_preset(&x264Param, "ultrafast", "zerolatency");
static const char * const x264_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };
static const char * const x264_tune_names[] = { "film", "animation", "grain", "stillimage", "psnr", "ssim", "fastdecode", "zerolatency", 0 };
int x264_param_default_preset( x264_param_t *, const char *preset, const char *tune );
三、 设置 x264 编码器编码规格
// 编码规格设定, 32 对应的是 3.2 编码规格, 该规格下有指定的 码率, 帧率要求 x264Param.i_level_idc = 32;
四、 设置 x264 编码器编码图像数据格式
/* Colorspace type */ #define X264_CSP_MASK 0x00ff /* */ #define X264_CSP_NONE 0x0000 /* Invalid mode */ #define X264_CSP_I400 0x0001 /* monochrome 4:0:0 */ #define X264_CSP_I420 0x0002 /* yuv 4:2:0 planar */ #define X264_CSP_YV12 0x0003 /* yvu 4:2:0 planar */ #define X264_CSP_NV12 0x0004 /* yuv 4:2:0, with one y plane and one packed u+v */ #define X264_CSP_NV21 0x0005 /* yuv 4:2:0, with one y plane and one packed v+u */ #define X264_CSP_I422 0x0006 /* yuv 4:2:2 planar */ #define X264_CSP_YV16 0x0007 /* yvu 4:2:2 planar */ #define X264_CSP_NV16 0x0008 /* yuv 4:2:2, with one y plane and one packed u+v */ #define X264_CSP_YUYV 0x0009 /* yuyv 4:2:2 packed */ #define X264_CSP_UYVY 0x000a /* uyvy 4:2:2 packed */ #define X264_CSP_V210 0x000b /* 10-bit yuv 4:2:2 packed in 32 */ #define X264_CSP_I444 0x000c /* yuv 4:4:4 planar */ #define X264_CSP_YV24 0x000d /* yvu 4:4:4 planar */ #define X264_CSP_BGR 0x000e /* packed bgr 24bits */ #define X264_CSP_BGRA 0x000f /* packed bgr 32bits */ #define X264_CSP_RGB 0x0010 /* packed rgb 24bits */ #define X264_CSP_MAX 0x0011 /* end of list */ #define X264_CSP_VFLIP 0x1000 /* the csp is vertically flipped */ #define X264_CSP_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */
// 设置输入到 x264 编码器的数据格式, 宽度, 高度等参数 x264Param.i_csp = X264_CSP_I420; x264Param.i_width = mWidth; x264Param.i_height = mHeight;
五、 设置 x264 编码器 码率相关参数
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;
六、 设置 x264 编码器 帧率相关参数
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; //分母
七、 设置 x264 编码器 编码帧相关参数
/* 关键帧数据 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_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;
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算