项目1:FFMPEG推流器讲解(五):FFMPEG时间戳、时间基、时间转换的讲解

一.本章节介绍

本章节将系统讲解FFMPEG的核心时间概念,涵盖时间基、时间戳及时间转换等关键内容。掌握这些知识点对理解推流技术至关重要,因为音视频合成的本质正是通过这些时间参数的精确转换实现的。

二.F FMPEG 时间基、 时间戳的讲解:

2 .1. 时间基( time_base)

时间基也称之为时间基准,它代表的是每个刻度是多少秒。比方说:视频帧率是25 F PS ****,****那它的时间刻度是{1,25}。相当于1s内划分出25个等分,也就是每隔1/25秒后显示一帧视频数据。具体的如下图所示:

在FFMPEG中时间基准都是用A VR ational结构体来表示:

cpp 复制代码
typedef struct AVRational{
    int num; ///< Numerator
    int den; ///< Denominator
} AVRational;

num:表示分子(numerator的缩写)

den:表示分母(denominator的缩写)

在视频处理中,时间基通常以帧率为单位。例如对于25帧的视频,FFmpeg使用AVRational video_timebase = {1, 25}来表示。

在音频处理中,时间基则以采样率为单位。比如48000Hz的音频采样率,FFmpeg会表示为AVRational audio_timebase = {1, 48000}。

对于封装格式来说:flv 封装格式的 time_base 为{1,1000},ts 封装格式的 time_base 为{1,90000}

从ffplay输出的信息中可以看到多个关于时间基的说明:

  1. tbr:表示基准帧率,通常情况下tbr与fps数值一致

  2. tbn:表示视频流的时间基,例如:

    • TS格式数据的时间基为90000
    • FLV格式视频流的时间基为1000
  3. tbc:表示视频编解码器的时间基,该值通常是帧率的两倍。例如:

    • 当帧率为25fps时,tbc值为50

2 .2. 时间戳(PTS、DTS):

时间戳表示在时间轴上所占的刻度数量,其单位并非具体秒数,而是时间刻度。只有将时间基与时间戳结合使用时,才能准确表达具体时间。

例如: 假设有一把刻度尺:

  • pts = 25个刻度
  • time_base = {1,25}(每个刻度为1/25厘米) 则尺子总长度 = pts × time_base = 25 × 1/25 = 1厘米

视频PTS计算: PTS(Presentation Time Stamp)用于确定解码后视频帧的显示时机。计算公式为:

  • n:第n帧视频
  • timebase:{1, framerate}
  • fps:帧率 pts = n × ((1/timebase)/fps) pts = pts++

示例: n=1, pts=1

n=2, pts=2

n=3, pts=3

音频PTS计算:

  • n:第n帧音频
  • nb_samples:采样个数(AAC默认1024)
  • timebase:{1, samplerate}
  • samplerate:采样率(如48000) num_pkt = samplerate/nb_samples
    pts = n × ((1/timebase)/num_pkt)
    pts = pts+1024

示例(samplerate=48000, nb_sample=1024): n=1, pts=1024

n=2, pts=2048

n=3, pts=3072

注:时间基和时间戳必须配合实用才能具体表达时间否则没用,例如时间戳就好像数字(1,2,3,4,5)但并没有具体的单位,时间基就比如是单位(例如美元,日元 ,人民币),所以这两个必须两个配合实用才行

2.3. D ****TS:****表示的是压缩解码的时间戳,在没有B帧的情况下PTS 等于 DTS。假设编码的里面引入了B帧,则还要计算B帧的时间。

没有B帧:dts = pts

存在B帧:dts = pts + b_time

三.时间转换原理

在FFMPEG中,不同复合流的时间基可能不一致。例如,FLV格式的时间基time_base为{1,1000},而某个视频流的时间基可能是{1,25}。当需要合成MPEGTS文件时,就需要将{1,25}时间基下的时间信息转换为{1,1000}时间基下的表示方式。

在F FMPEG 中用以下的A PI 进行时间基转换:

cpp 复制代码
/**
 * Convert valid timing fields (timestamps / durations) in a packet from one
 * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be
 * ignored.
 *
 * @param pkt packet on which the conversion will be performed
 * @param tb_src source timebase, in which the timing fields in pkt are
 *               expressed
 * @param tb_dst destination timebase, to which the timing fields will be
 *               converted
 */
void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst);

参数说明:

  • 第一个参数:AVPacket结构体指针

  • 第二个参数:源时间基

  • 第三个参数:目标时间基

功能说明:

该API用于将AVPacket的时间基从tb_src转换为tb_dst。以下是H264和AAC时间基转换的示例:

视频H264时间基转MPEGTS时间基:

**转换公式:DST_VIDEO_PTS = VIDEO_PTS * VIDEO_TIME_BASE / DST_TIME_BASE**

H264时间基{1,25} → FLV时间基{1,1000}:
**- 输入pts=1 → 输出pts=40

  • 输入pts=2 → 输出pts=80 (经av_packet_rescale_ts转换)
  • 输入pts=3 → 输出pts=120
  • 输入pts=4 → 输出pts=160**

音频AAC时间基转FLV时间基:

**转换公式:DST_AUDIO_PTS = AUDIO_PTS * AUDIO_TIME_BASE / DST_TIME_BASE**

AAC时间基{1,48000} → FLV时间基{1,1000}:
**- 输入pts=1024 → 输出pts≈21.3

  • 输入pts=2048 → 输出pts≈42.6 (经av_packet_rescale_ts转换)
  • 输入pts=3072 → 输出pts≈64
  • 输入pts=4096 → 输出pts≈85.3**

结论:

  • 视频时间基转换实质是执行公式:DST_VIDEO_PTS = VIDEO_PTS * VIDEO_TIME_BASE / DST_TIME_BASE

  • 音频时间基转换实质是执行公式:DST_AUDIO_PTS = AUDIO_PTS * AUDIO_TIME_BASE / DST_TIME_BASE

图解:

相关推荐
彷徨而立7 小时前
【FFmpeg】HW 解码器销毁时,资源回收顺序
ffmpeg
却道天凉_好个秋9 小时前
音视频学习(六十九):视音频噪声
音视频·噪声
彷徨而立14 小时前
【FFmpeg】如何判断 HW解码器输出的是 硬件帧?
ffmpeg
bluesen14 小时前
WebRTC获取GB28181监控摄像头实时音视频流的实现方法
音视频·webrtc·gb28181·gb/t.28181
派阿喵搞电子14 小时前
基于ffmpeg库,在AGX上编译jetsonFFmpeg库带有硬件加速的h264_nvmpi视频编解码器
ffmpeg·视频编解码
彷徨而立14 小时前
【FFmpeg】HW解码器输出 硬件帧 or 软件帧
ffmpeg
xiaohua0708day15 小时前
关于解决js中MediaRecorder录制的webm视频没有进度条的问题
javascript·音视频
Niuguangshuo15 小时前
音频特征提取算法介绍
算法·音视频