音视频流媒体开发-目录
iOS知识点-目录
Android-目录
Flutter-目录
数据结构与算法-目录
uni-pp-目录
- 推流分析
- 拉流分析
第一章 推流分析
1 推流框架
PCM S16交错 -> float 棋盘格类型
采样率
- 模块初始化顺序
- 采集时间戳
- 音视频编解码
- 音视频编码队列控制
- 关键时间点
1.1 模块初始化顺序
推流模块(网络连接耗时) > 音视频编码模块 >音视频采集模块()
1.2 采集时间戳-帧间隔模式
优点:能输出frame duration稳定的音视频时间戳。
风险:
(1)当系统负载比较重时有可能初学采集间隔不稳定的情况,比如 预计1秒采集25帧图像,但实际采集了20帧,而音视频的时间戳是通过帧 间隔累计的,这样计算出来的时钟就不正确了。
(2)帧间隔涉及到无限小数时,比如预计30帧,通常按帧间隔33毫秒处理, 但实际是33.3333333毫秒。累积3333帧(约111秒)就出现1秒的误差。
1.2 采集时间戳-直接系统时间模式
优点:能够实时纠正时间戳,只要系统正常运转,就能立即恢复正确的时间戳。
风险:帧间隔不均匀,能否正常播放依赖于终端。
比如,假如音频一帧间隔为24毫秒,被采集的回调时间可能为20毫秒,28毫秒,27毫秒,21毫秒。
1.2 采集时间戳-帧间隔+直接系统时间模式
优点:大部分音视频帧的frame duration都稳定。
风险:纠正时间戳时可能会造成画面卡顿的感觉。
1.3 音视频编解码模块
关键点:
- 编码前:pts
- 编码后:dts(发送的时间戳)
- 封装成avframe送编码器后frame的释放
- 接收packet后数据的释放
1.4 音视频队列的控制
- 音频帧数量
- 视频帧数量
- 视频超过阈值时drop帧
- 直到检测到I帧停止
- 音频超过阈值时:
- drop帧;
- 重采样提高缩短播放时间再发送(不能简单进行重采样,需要变速不变调 sonic)
1.5 关键时间点
关键点:
- 采集到的第一帧视频时间
- 采集到的第一帧音频时间
- 视频第一帧编码时间
- 音频第一帧编码时间
- rtmp发送第一帧视频完成时间
- sequence 帧
- i帧
- rtmp发送第一帧音频完成时间
- sequence帧
- 数据帧
1.6 其他
-
发送数据阻塞检测,在RTMP_SendPacket函数前后加打印监 测发送耗时,比如耗时超过200ms打印警告。
-
av队列 队列的监测,帧数, 队列数据持续播放的时间
推流后,拉流端拉流不正常:
A. 使用ffplay或者vlc进行拉流double check,根据不同的错误信息进行排查
1 如果是编码错误则需要dump编码前和编码后的数据,用ffplay进行播放;
2 如果是时间戳的问题则需要调整发送时间戳,检测时间戳是否是递增
第二章 拉流实战
2 拉流框架
- 模块初始化顺序
- 音视频数据队列(packetqueue)控制 3. 音视频解码
- 音频重采样
- 视频尺寸变换
- 音视频帧队列
- 音视频同步
- 关键时间点check
- 其他
2.1 模块初始化顺序
推流模块(网络连接耗时) > 音视频编码模块 >音视频采集模块()
音视频输出模块 >音视频解码模块 > 拉流模块
本质上来讲,就是在数据到来之前准备好一切工作
2.2 音视频数据队列
音视频队列涉及到
- Audio PacketQueue 还没有解码的
- VideoPacketQueue
两者独立
队列设计要点:
- 可控制队列大小
- 根据packet数进行控制
- 根据总的duration进行控制 音频48khz, 21.3毫秒, 21.3*20 = 426ms
- 支持packet的size进行入队列累加,出队列则减,300,200,400,字节累加
- 支持packet数量统计
- 支持packet的duration进行入队列累加,出队列则减
- 支持阻塞和唤醒
目的:
- 统计延迟(缓存时间长度)
2.2 音视频数据队列
音视频队列涉及到
- AudioPacketQueue
- VideoPacketQueue
两者独立
队列设计要点:
- 可控制队列大小
- 根据packet数进行控制
- 根据总的duration进行控制
- 支持packet数量统计
- 支持packet的size进行入队列累加,出队列则减
- 支持packet的duration进行入队列累加,出队列则减
- 支持阻塞和唤醒
2.3 音视频解码
关键点:
- 编码前: dts
- 编码后: pts
- packet释放
- frame释放
- 返回值处理
2.4 音频重采样
音频重采样模块AudioResampler:
注意重采样后不能直接使用linesize进行大小判断,需要使用
int size = av_get_bytes_per_sample((AVSampleFormat)(dstframe->format)) * dstframe->channels * dstframe->nb_samples ;
2.5 视频尺寸变换
图像尺寸变换模块ImageScaler:变换尺寸大小
性能的提升可以考虑 libyuv
2.6 音视频解码后帧队列
FrameQueue 解码后的数据量比较大,需要要控制解码后帧队列的大小 参考ffplay固定大小
#define VIDEO_PICTURE_QUEUE_SIZE 3 // 图像帧缓存数量
#define SUBPICTURE_QUEUE_SIZE 16 // 字幕帧缓存数量
#define SAMPLE_QUEUE_SIZE 9 // 采样帧缓存数量
#define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE))
2.7 音视频同步
Avsync模块
目前只支持audio master的方式。
2.8 各个模块关键时间点的监测
2.9 其他
-
客户端的首帧秒开,本质上就是不做同步先把第一帧显示出来。
-
推流没有问题时,如果拉流不能正常播放:
- 没有声音:dumprtmp拉流后的数据是否可以正常播放
- 声音异常:是否有解码错误报告,重采样前的pcm数据是否正常
- 没有图像:dumprtmp拉流后的数据是否可以正常播放
- 画面异常:是否有解码错误报告,scale前的数据是否正常
服务器首帧秒开:这个功能不能降低延迟
网友评论