go语言ffmpeg推流 go语言流媒体开发( 三 )


1)B帧是由前面的I或P帧和后面的P帧来进行预测的;
2)B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;
3)B帧是双向预测编码帧;
4)B帧压缩比最高,因为它只反映丙参考帧间运动主体的变化情况,预测比较准确;
5)B帧不是参考帧,不会造成解码错误的扩散 。
我找了篇文章,可以更好的理解H264
H264基础简介
在视频编码序列中,GOP即Group of picture(图像组) , 指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离(如下图3.1) 。一个I帧所占用的字节数大于一个P?。桓鯬帧所占用的字节数大于一个B?。ㄈ缦峦?.1所示) 。
所以在码率不变的前提下,GOP值越大,P、B帧的数量会越多 , 平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量 。需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧 , 此时实际的GOP值被缩短了 。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大 。同时,由于P、B帧的复杂度大于I?。怨嗟腜、B帧会影响编码效率,使编码效率降低 。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长 。
DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据 。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据 。
这2个概念经常出现在音频视频编码和播放中,其实际意义是,PTS是真正录制和播放的时间戳,而DTS是解码的时间戳 。
对于普通的无B桢视频(H264 Baseline或者VP8),PTS/DTS应该是相等的,因为没有延迟编码 。
对于有B桢的视频,I桢的PTS依然等于DTS, P桢的PTSDTS, B桢的PTSDTS 。
可以简单地这样理解:
若视频没有B帧 , 则I和P都是解码后即刻显示 。
若视频含有B帧,则I是解码后即刻显示,P是先解码后显示,B是后解码先显示 。(B 和P的先、后是相对的) 。
上面说了视频帧、DTS、PTS 相关的概念 。我们都知道在一个媒体流中,除了视频以外,通常还包括音频 。音频的播放,也有 DTS、PTS 的概念,但是音频没有类似视频中 B ?。恍枰蛟げ猓?所以音频帧的 DTS、PTS 顺序是一致的 。
音频视频混合在一起播放,就呈现了我们常常看到的广义的视频 。在音视频一起播放的时候 , 我们通常需要面临一个问题:怎么去同步它们 , 以免出现画不对声的情况 。
要实现音视频同步,通常需要选择一个参考时钟,参考时钟上的时间是线性递增的,编码音视频流时依据参考时钟上的时间给每帧数据打上时间戳 。在播放时 , 读取数据帧上的时间戳,同时参考当前参考时钟上的时间来安排播放 。这里的说的时间戳就是我们前面说的 PTS 。实践中,我们可以选择:同步视频到音频、同步音频到视频、同步音频和视频到外部时钟 。
golang的reexec怎么用使用方法如下是exec.Command函数传入所有命令的字符串,然后调用即可,也可以像我下面一样 , 把参数放到列表里,这样比较方便阅读 。cmd.CombinedOutput会返回golang里面的错误和外部命令(ffmpeg)的输出,需要注意的是,这里的output是stderr和stdout混在一起的

推荐阅读