问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

FFmpeg帧率同步技巧大揭秘!

创作时间:
作者:
@小白创作中心

FFmpeg帧率同步技巧大揭秘!

引用
CSDN
8
来源
1.
https://blog.csdn.net/aiynmimi/article/details/121231246
2.
https://blog.csdn.net/twj1710/article/details/627677
3.
https://blog.csdn.net/jctian000/article/details/88032463
4.
https://ottverse.com/i-p-b-frames-idr-keyframes-differences-usecases/#What_is_a_B-frame
5.
https://trac.ffmpeg.org/wiki/ChangingFrameRate
6.
https://www.cnblogs.com/renhui/articles/12234424.html
7.
https://ottverse.com/i-p-b-frames-idr-keyframes-differences-usecases/#Reference_B-frame_and_Non-Reference_B-frames
8.
https://zh.wikipedia.org/wiki/FFmpeg

在视频处理领域,帧率同步是一个至关重要的技术环节。无论是视频转码、编辑还是播放,准确的帧率同步都能确保音视频的完美协调。而FFmpeg作为一款功能强大的开源多媒体框架,提供了丰富的工具和选项来实现这一目标。本文将深入探讨FFmpeg在帧率同步方面的核心技术,帮助你掌握这一关键技能。

01

基础概念:PTS、DTS与帧类型

在深入讲解FFmpeg的帧率同步机制之前,我们先来了解一下几个基础概念:

  1. PTS(显示时间戳)与DTS(解码时间戳)
  • PTS:表示解码后原始帧的显示时间。
  • DTS:表示压缩帧的解码时间。

在不含B帧的视频中,DTS和PTS是相同的。然而,当视频包含B帧时,由于B帧需要双向预测,解码顺序与显示顺序会出现差异,导致DTS与PTS不同。

  1. I帧、P帧与B帧

视频压缩中常用的三种帧类型:

  • I帧(关键帧):包含完整图像信息,不需要参考其他帧。
  • P帧(预测编码帧):利用之前的I帧或P帧进行预测编码。
  • B帧(双向预测编码帧):利用之前和之后的帧进行预测,不能作为参考帧。

B帧具有更高的压缩率,但需要更多的缓冲时间以及更高的CPU占用率,因此B帧适合本地存储以及视频点播,而不适用对实时性要求较高的直播系统。

  1. 时间基(time_base)

在FFmpeg中,时间基是时间戳的单位。时间戳值乘以时间基,可以得到实际的时刻值(以秒等为单位)。例如,如果一个视频帧的dts是40,pts是160,其time_base是1/1000秒,那么可以计算出此视频帧的解码时刻是40毫秒(40/1000),显示时刻是160毫秒(160/1000)。

FFmpeg中有三种时间基:

  • tbn:对应容器中的时间基,值是AVStream.time_base的倒数。
  • tbc:对应编解码器中的时间基,值是AVCodecContext.time_base的倒数。
  • tbr:从视频流中猜算得到,可能是帧率或场率(帧率的2倍)。
02

FFmpeg帧率同步核心技术

FFmpeg通过精确控制DTS和PTS来实现帧率同步。在处理视频流时,FFmpeg会根据时间基和时间戳来确定每一帧的解码和显示时间。对于包含B帧的视频,由于解码顺序与显示顺序不同,FFmpeg需要通过调整DTS和PTS来确保正确的播放顺序。

例如,考虑一个包含I帧、P帧和B帧的视频序列:

采集顺序:I[0] B[1] B[2] P[3] B[4] B[5] P[6]
解码顺序:I[0] P[3] B[1] B[2] P[6] B[4] B[5]
显示顺序:I[0] B[1] B[2] P[3] B[4] B[5] P[6]

在这个例子中,B[1]帧需要参考I[0]帧和P[3]帧,因此P[3]帧必须在B[1]帧之前解码。这导致了解码顺序和显示顺序的不一致。

03

实践操作:使用FFmpeg改变帧率

FFmpeg提供了两种改变输出帧率的方法:

  1. 使用-r选项
  2. 使用fps滤镜

推荐使用fps滤镜,因为它更可配置,支持5种舍入模式。

改变帧率示例

要将输出帧率更改为30 fps,可以使用以下命令:

ffmpeg -i input.mp4 -filter:v fps=30 output.mp4

如果输入视频是60 fps,FFmpeg会丢弃每一帧来获得30 fps的输出。

验证帧率变化

要验证哪些帧被重复或丢弃,可以生成一个样本视频:

ffmpeg -f lavfi -i testsrc=duration=10:size=854x480:rate=60 \
-vf "drawtext=text=%{n}:fontsize=72:r=60:x=(w-tw)/2:y=h-(2*lh):fontcolor=white:box=1:boxcolor=0x00000000@1" \
-f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 \
-c:v libx264 -preset ultrafast -tune zerolatency -crf 23 -pix_fmt yuv420p \
-c:a aac -b:a 128k \
output.mp4

这个命令会生成一个10秒的测试视频,显示帧编号和时间戳,帮助你直观地看到帧率变化的效果。

04

注意事项

  1. 改变帧率需要重新编码视频,这可能会影响视频质量。建议根据所选编解码器的编码指南设置适当的输出质量和比特率。

  2. 使用fps滤镜时,可以通过设置不同的舍入模式来控制源帧的丢弃或重复方式。具体模式包括:

    • nearest:最接近目标帧率
    • zero:向下取整
    • ceil:向上取整
    • down:向下取整(与zero相同)
    • up:向上取整(与ceil相同)

例如,要使用向下取整模式,可以这样设置:

ffmpeg -i input.mp4 -filter:v "fps=fps=30:round=down" output.mp4

通过以上内容,相信你已经掌握了FFmpeg在帧率同步方面的核心技术。无论是处理直播流媒体还是编辑本地视频,这些知识都将帮助你实现更高质量的音视频同步效果。建议在实际项目中多加练习,熟练掌握FFmpeg的各种功能和参数,以应对不同场景下的需求。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号