前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解 FFmpeg 中的 pts,dts,time_base

理解 FFmpeg 中的 pts,dts,time_base

作者头像
字节流动
发布2024-02-28 13:47:03
1880
发布2024-02-28 13:47:03
举报
文章被收录于专栏:字节流动字节流动
首先介绍下概念:

PTS:Presentation Time Stamp。PTS主要用于度量解码后的视频帧什么时候被显示出来。

DTS:Decode Time Stamp。DTS主要是标识读入内存中的bit流在什么时候开始送入解码器中进行解码。

也就是pts反映帧什么时候开始显示,dts反映数据流什么时候开始解码。

怎么理解这里的“什么时候”呢?如果有某一帧,假设它是第10秒开始显示。那么它的pts是多少呢。是10?还是10s?还是两者都不是。

为了回答这个问题,先引入FFmpeg中时间基的概念,也就是time_base。它也是用来度量时间的。

如果把1秒分为25等份,你可以理解就是一把尺,那么每一格表示的就是1/25秒。此时的time_base={1,25}。

如果你是把1秒分成90000份,每一个刻度就是1/90000秒,此时的time_base={1,90000}。

所谓时间基表示的就是每个刻度是多少秒

pts的值就是占多少个时间刻度(占多少个格子)。它的单位不是秒,而是时间刻度。只有pts加上time_base两者同时在一起,才能表达出时间是多少。

好比我只告诉你,某物体的长度占某一把尺上的20个刻度。但是我不告诉你,这把尺总共是多少厘米的,你就没办法计算每个刻度是多少厘米,你也就无法知道物体的长度。

pts=20个刻度 time_base={1,10} 每一个刻度是1/10厘米 所以物体的长度=pts * time_base=20 *1/10 厘米

在ffmpeg中,av_q2d(time_base)=每个刻度是多少秒。

此时你应该不难理解 pts*av_q2d(time_base)才是帧的显示时间戳。

下面理解时间基的转换,为什么要有时间基转换。

首先,不同的封装格式,timebase是不一样的。另外,整个转码过程,不同的数据状态对应的时间基也不一致。

拿mpegts封装格式25fps来说(只说视频,音频大致一样,但也略有不同)。

非压缩时候的数据(即YUV或者其它),在ffmpeg中对应的结构体为AVFrame,它的时间基为AVCodecContext 的time_base ,AVRational{1,25}。

压缩后的数据(对应的结构体为AVPacket)对应的时间基为AVStream的time_base,AVRational{1,90000}。

因为数据状态不同,时间基不一样,所以我们必须转换,在1/25时间刻度下占10格,在1/90000下是占多少格。这就是pts的转换。

根据pts来计算一桢在整个视频中的时间位置: timestamp(秒) = pts * av_q2d(st->time_base)

duration和pts单位一样,duration表示当前帧的持续时间占多少格。或者理解是两帧的间隔时间是占多少格,一定要理解单位。

pts:格子数 av_q2d(st->time_base): 秒/格

计算视频长度: time(秒) = st->duration * av_q2d(st->time_base)

ffmpeg内部的时间与标准的时间转换方法: ffmpeg内部的时间戳 = AV_TIME_BASE * time(秒) AV_TIME_BASE_Q=1/AV_TIME_BASE

av_rescale_q(int64_t a, AVRational bq, AVRational cq)函数

这个函数的作用是计算a*bq / cq来把时间戳从一个时间基调整到另外一个时间基。

在进行时间基转换的时候,应该首先这个函数,因为它可以避免溢出的情况发生。

函数表示在bq下的占a个格子,在cq下是多少。

关于音频pts的计算:

音频sample_rate:samples per second,即采样率,表示每秒采集多少采样点。 比如44100HZ,就是一秒采集44100个sample。

即每个sample的时间是1/44100秒。

一个音频帧的 AVFrame 有 nb_samples 个 sample,所以一个AVFrame耗时是nb_samples乘以(1/44100)秒。

即标准时间下duration_s=nb_samples乘以(1/44100)秒。

转换成 AVStream 时间基下 duration=duration_s / av_q2d(st->time_base)。

基于st->time_base 的 num 值一般等于采样率, 所以 duration=nb_samples。

pts=n* duration=n *nb_samples。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-02-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 字节流动 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 首先介绍下概念:
  • 所谓时间基表示的就是每个刻度是多少秒
  • 下面理解时间基的转换,为什么要有时间基转换。
  • 关于音频pts的计算:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档