FFmpeg中的时间戳与时间基

简介

在开发多媒体播放器或直播系统时,音视频的同步是非常关键且复杂的点。要想把音视频同步搞明白,我们必须要了解一些基本的知识。只有了解了这些基本知识,才能为你打下理解音视频同步的基础。
本文将从下面几个主题介绍这些知识点:

  • I/B/P帧
  • PTS/DTS
  • 时间基
  • ffmpeg的内部时间基
  • 不同时间基的换算

I/B/P帧

  • I帧是关键帧,它采用帧内压缩技术;
  • B帧是前后参考帧,它属由帧间压缩技术。也就是说在压缩成 B帧前,它会参考它前面的非压缩视频帧,和后面的非压缩的视频帧,记录下前后两帧都不存放的“残差值”,这样可以达到更好的压缩率;
  • P帧是向前参考帧,也就是它参考的是前一个关键帧的数据。P帧也属于帧间压缩技术,相对于 B帧来说,P帧的压缩率要比B帧低。

但在直播系统中,很少使用B帧。主要的原因是压缩和解码B帧时,由于要双向参考,所以它需要缓冲更多的数据,且使用的CPU也会更高。由于实时性的要求,所以一般不使用它。不过对于播放器来说,会经常遇到带有B帧的H264数据。

PTS/DTS

有了上面 I/B/P帧的概念,我们再来理解 PTS/DTS 就非常容易了。PTS(Presentation TimeStamp)是渲染用的时间戳,也就是说,我们的视频帧是按照 PTS 的时间戳来展示的。DTS(Decoding TimeStamp)解码时间戳,是用于视频解码的。

那为什么有了 PTS 还要有 DTS呢?这就与我们上面所讲的 I/B/P帧有关了。如果我们的视频中没有B帧,那显示的帧的顺序与存放的帧的顺序是一样的,此时PTS与DTS 的值就是一样的,也就没有存在两个时间戳的必要了。视频解码与播放不是一致的

但有了B帧之后,就不是这个样子了。我们举个简单的例子:

第一行,实际应展示的顺序:I    B    B    P
第二行,在缓存区存放顺序:I    P    B    B
第三行,解码器解码的顺序:1    4    2    3
第四行,按实际顺序号展示:1    2    3    4

对于上面这个例子我们作下说明:

  1. 我们实际应该展示的帧的顺序是 I, B, B, P 帧解码后的视频帧。
  2. 但实际上,这些帧到达之后,在缓冲区里就按照第二行的样子存放的。为什么会这样呢?这是由于我上面所讲的,P帧解码时参考的是 I帧,B帧是双向参考帧。也就是说,如果 I帧和P帧没有解码的话,B帧是无法进行解码的。基于此,为了解决这个问题就出现了 PTS和DTS两个时间戳。
  3. 第三行是视频帧真正的解码顺序,先解 I帧,然后是P帧,然后是第一个B帧,最后是第二个B帧。(解码顺序)
  4. 最终的展示顺序是 I帧解码后的视频帧,第一个B帧解码后的视频帧,第二个B帧解码后的视频帧,最后是P帧解码后的视频帖。(展示顺序)

时间基

有了时间戳之后,最终进行展示时还要需要将 PTS时间戳转成以秒为单位的时间。那这里需要向大家介绍一下 ffmpeg的时间基。
时间基是个有点抽象的东西, 在这里不说抽象的概念,我就把它当成时间的单位

例如25帧的视频,如果不存在时间基这个东西, 我们打时间戳应该是这样的,0-40-80-120-...-1000,以此类推,40毫秒一帧图像

可是出现了时间基之后就不能这么处理了;

例如,同样25帧的视频, 时间基设置为1/25, 那这个1/25是什么意思呢? 就是把1秒分成25份, 你的时间戳每增加1,就代表增加了1/25秒;

视频是25帧的, 也就是每帧之间的间隔恰好就是1/25秒, 那么,我们的时间戳就可以每次递增1了;

同理,时间基设置为1/50, 那么我们的时间戳就可以每次递增2了;

时间基其实就是就是时间刻度。我们以帧率为例,如果每秒钟的帧率是 25帧,那么它的时间基(时间刻度)就是 1/25。也就是说每隔1/25 秒后,显示一帧。

所以如我们当前的时间是 100, 时间基是 1/25,那么转成秒的时间是多少呢? 100*(1/时间基),也就是100 * 1/25 = 4秒。是不是非常的简单?

ffmpeg内部时间基

ffmpeg内部有一个时间基。即我们通过所见到的 AV_TIME_BASE。它在ffmpeg内部定义如下,1000 000毫秒:

#define         AV_TIME_BASE   1000000

它还有一种分数所表式法:

#define         AV_TIME_BASE_Q   (AVRational){1, AV_TIME_BASE}

在 ffmpeg中进行换算,将不同时间基的值转成按秒为单位的值计算如下:

timestamp(秒) = pts * av_q2d(time_base)

这里引入了 av_q2d 这个函数,它的定义非常简单:

typedef struct AVRational{
int num; //分子
int den; //分母
} AVRational;

static inline double av_q2d(AVRational a){
/**
* Convert rational to double.
* @param a rational to convert
**/
    return a.num / (double) a.den;
}

不同时间基的换算

ffmpeg有好几种不同的时间基,有时候我们需要在不同的时间基之间做换算。ffmpeg为我们提供了非常方便的函数。即

av_rescale_q()

av_rescale_q(a,b,c)的作用是,把时间戳从一个时基调整到另外一个时基时候用的函数。其中,a 表式要换算的值;b 表式原来的时间基;c表式要转换的时间基。其计算公式为 a * b / c。
既然公式这么简单,我们自己写就OK了,为什么ffmpeg还要单独提供一个函数呢?其实这个看似简单的方法,还要考虑数值溢出的问题。所以把这块的逻辑加上之后,就没我们看到的这么简单了。不过没关系,我们只要清楚 av_rescale_q 是做什么的,怎么用就可以了。

下面我再给出两个算计公式:

  • 时间戳转秒
time_in_seconds = av_q2d(AV_TIME_BASE_Q) * timestamp
  • 秒转时间戳
timestamp = AV_TIME_BASE * time_in_seconds

音频的timebase是如何确定的?

与视频类似, 只是音频换做采样率这个概念,采样率代表麦克风一秒有多少个采样产生,这个频率是极为精确的.所以我的一般做法是设置为 1/采样率; 时间戳每次递增输入的采样数;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,488评论 6 531
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,034评论 3 414
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,327评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,554评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,337评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,883评论 1 321
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,975评论 3 439
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,114评论 0 286
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,625评论 1 332
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,555评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,737评论 1 369
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,244评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,973评论 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,362评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,615评论 1 280
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,343评论 3 390
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,699评论 2 370

推荐阅读更多精彩内容

  • 最近在学习FFmpeg的过程中发现,其他的知识点还比较清楚,就是对于FFmpeg中的时间基概念模糊,前面做Demo...
    MzDavid阅读 1,845评论 0 2
  • 教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基...
    90后的思维阅读 4,729评论 0 3
  • 今日体验:今天上午不忙出去给客户送证件,真的是事儿挺多的,到了前台还要查信息乱七八糟的,但是还是有必要的为了顾客的...
    房傲东阅读 121评论 0 0
  • 很早以前,我狂热的很想开家咖啡馆,我想好了店名:嘿,你也在这儿。舒服温馨的店里,放着悠扬而又轻缓的音乐,你正在喝着...
    醉翁之意_966e阅读 215评论 0 0