写点什么

【每天学点‘音视频’】GOP- 关键帧间隔

【每天学点‘音视频’】GOP-关键帧间隔

什么是 GOP

在音视频中 GOP (Group of Picture)表示一组连续的视频帧序列,这个序列中包括 P 帧和 B 帧,通常被提到的是 GOP 长度,通俗的讲就是 I 帧与 I 帧之间的非 I 帧数。P 帧和 B 帧要远远小于 I 帧,这也是视频压缩能节省空间的一个原因所在。


GOP结构I B B P B B P P P IGOP大小为8
复制代码


播放器接收到 I 帧时会播放出画面,有时会遇到首开时间较长的问题,这是因为当播放器如果获取到了 B 帧或 P 帧时,它无法解码,需要进行丢弃,所以会导致首开较长。

如何查看视频的 GOP 长度

方式一:


使用vctrl 工具,可打印出 gop 长度,单位是秒, vctrl 工具只能在 Linux 系统中使用,可以查看点播和直播

./vctrl stream -statsec -pg play 视频


方式二:

ffmpeg -i qiniu-2023-720p-fps-1.mp4 -vf "showinfo" -f null - 2>&1 | grep "pts_time:[0-9.]*" > frame_info.txt
复制代码


在生成的文件frame_info.txt 查看 I 帧之间的间隔 ,查看对应 I 帧对应的 n 做差值,就是 GOP 的大小。


n:2  type:I  (第1个I帧)...n:82 type:I  (第2个I帧)
复制代码


GOP 长度 = 82 - 2 = 80 帧,80/25=3.2s ,25 表示是视频源帧率


可以说 GOP 长度为 80 帧,也可以说 3s

查看视频中是否存在 B 帧

方法一:含义同上述过程


ffmpeg -i qiniu-2023-720p-fps-1.mp4 -vf "showinfo" -f null - 2>&1 | grep "pts_time:[0-9.]*" > frame_info.txt


方法二:

使用以下命令可累出所有帧类型,可以查看视频中是否存在 B 帧


ffprobe -v error -show_frames -select_streams v 视频源 | grep "pict_type”


GOP 越大越好,还是越小越好呢?

  • GOP 越大说明 I 帧与 I 帧之间的 B 帧和 P 帧比较多,比如上面的 GOP 长度为 80 帧,说明视频中 每 82 帧出现一个关键帧( I 帧),较长的 GOP 能够减少关键帧的数量,可以节省存储和带宽,比较合适一些静态场景,视频内容变化较小,比如讲座、监控等。但如果是一些运动场景,如果 GOP 太大,就会导致依赖 P/B 帧的预测误差会累积,会增加解码负担,从而导致画质下降和卡顿等问题。

  • GOP 越小,意味着 I 帧间隔时间短,可实现秒开功能,但也意味着压缩比例低,同样码率情况下视频的质量会有所下降。

  • GOP 的选择依使用场景而定

  • 直播:g 15~30

  • 流媒体:g 30~60

  • 存档:g 100~250(仅限静态内容)

FFmpeg 推流如何避免有 B 帧

使用如下命令

ffmpeg -re -stream_loop -1 -i trailer.mp4 -c copy -c:v libx264 -bf 0 -f flv rtmp://127.0.0.1/ztest/test-01
复制代码
  • 上述参数 -bf 0,表示无 B 帧

  • 如果要启用 B 帧,则使用参数 -bf 2

OBS 如何推不含 B 帧的直播流

可以参考:https://developer.qiniu.com/pili/9886/obs-push-flow-excluding-b-frame-guidelines

FFmpeg 强制关键帧间隔

有一个视频源 GOP 大小不均,GOP 大小为 2、4、5、10s,现在想强制关键帧间隔,使之平均,使用 ffmpeg 强制每 30 帧一个 I 帧


ffmpeg -i trailer.mp4 -g 30 -c:v libx264 trailer01.mp4
复制代码


-g 30:设置 GOP=30根据帧率调整,如 30fps 视频 = 1 秒一个 I 帧)。


在低延迟场景中,通常缩短 GOP,增加 I 帧频率。现在可以通过命令查看强制关键帧间隔之后的文件中的 GOP 大小。强制关键帧间隔之后的 GOP 大小为 1.25,因为原视频的帧率为 24fps,强制 GOP 为 30,则 30/24 = 1.25s



可以通过以下命令检查原始编码参数


➜  ~ ffprobe -v error -show_entries stream=codec_name,r_frame_rate -of csv trailer.mp4stream,h264,24/1stream,aac,0/0
复制代码

总结

GOP 就是一组连续的视频帧序列,两个 I 帧之间的间隔叫做一个 GOP,GOP 大小 就是 I 帧之间的非 I 帧数。

发布于: 刚刚阅读数: 5
用户头像

出来乍到的程序猿,有一颗成为IT精英的梦想 2020-08-28 加入

座右铭:不想当开发的测试,不是一个好测试✌️。 我是一个致力于测试开发的博主,主要职责:测试开发、CI/CD,偶尔跟着开发学习音视频知识,希望输出的内容可以帮助和我一样初入职场,经验不足的小白。

评论

发布
暂无评论
【每天学点‘音视频’】GOP-关键帧间隔_ffmpeg_小曾同学.com_InfoQ写作社区