FFMPEG知识

一:ffmpeg的模型

1:转码模型

转码基本流程:flv格式数据-->h264/aac数据-->yuv/pcm数据-->h264/aac数据-->mp4格式数据。

a:我们把flv格式数据或者mp4格式数据这一层叫做mux/demux层或者复用层有些人习惯于叫做封装层,这里叫做mux/demux层下面同理。

b:我们把h264/aac数据这一层叫做编解码层或者codec/decode,这里叫做codec/decode层下面同理。

c:我们把yuv/pcm数据这一层叫做原始数据层或者Raw data 层,这里叫做Raw data层下面同理。

2:摄像头采集模型

摄像头采集基本流程:yuv/pcm数据-->h264/aac数据-->flv格式数据。

3:播放器模型

播放器基本流程:flv格式数据-->h264/aac数据-->yuv/pcm数据。

从上面的三个最常用模型不难看出也可以说总结出ffmpeg基本把数据或者说结构分为了 “mux/demux层”也就是ffmpeg中的AVStream 

“codec/decode层” 也就是ffmpeg中的AVCodec 

“Raw data 层”这个也在AVStream 中存放着(如果是自己填写的例如ios或者android获取当前毫秒时间的可以单独放置到一个timebse的结构体中),这个。各位看官对这个分层有了大致的了解之后我们再说分层对timebase的影响。

二:ffmpeg中的timebase是什么

FFMPEG的很多结构中有AVRational time_base;这样的一个成员,它是AVRational结构的

typedef struct AVRational{

int num; ///< numerator

int den; ///< denominator

} AVRational;

AVRational这个结构标识一个分数,num为分数,den为分母。


1:简单来讲ffmpeg的timebase是为了解决当时间戳是小数的时候转化为整数和为了更好的做分层结构而设置的一种机制。

2:ffmpeg的timebse我们可以理解为单位,比如米,毫秒,秒,千克这些都是单位,但这个timebse有时候不是我们日常中能见到的单位,举个例子ffmpeg本身是以秒为基准的,1秒= 1000毫秒,那如果timebse是1:1很好理解是秒的单位,如果timebase是1:1000也很好理解是毫秒单位,但如果timebase是1:25呢,我们的常用单位就解释不了了,这要是很多人的误区。

3.有了时间戳之后,最终进行展示时还要需要将 PTS时间戳转成以秒为单位的时间;那这里需要向大家介绍一下 ffmpeg的时间基。

tbr: 是我们通常所说的帧率。time base of rate

tbn: 视频流的时间基。 time base of stream

tbc: 视频解码的时间基。time base of codec

那我们如何理解时间基呢?其实非常简单,就是时间刻度。

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

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

再举个例子,(1,25),时间刻度就是1/25

(1,90000),时间刻度就是1/90000

那么,在刻度为1/25的体系下的time=5,转换成在刻度为1/90000体系下的时间time为(5*1/25)/(1/90000) = 3600*5=18000

如果由某个解码器产生固定帧率的码流

AVCodecContext中的AVRational根据帧率来设定,如25帧,那么num = 1,den=25

AVStream中的time_base一般根据其采样频率设定,如(1,90000)

将不同时间基的值转成按秒为单位的值计算如下:

static inline double av_q2d(AVRational a){

    return a.num / (double) a.den;

}

timestamp(秒) = pts * av_q2d(time_base)

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

av_rescale_q(a,b,c) ==a * b / c。

av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd);  rnd是取整的方式

既然公式这么简单,我们自己写就OK了,为什么ffmpeg还要单独提供一个函数呢?其实这个看似简单的方法,还要考虑数值溢出的问题。所以把这块的逻辑加上之后,就没我们看到的这么简单了。

ffmpeg内部时间基:

#define AV_TIME_BASE 1000000

#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE}

将不同时间基的值转成按秒为单位的值计算如下:

time_in_seconds = av_q2d(AV_TIME_BASE_Q) * timestamp

将不同时间基的值转成按秒为单位的值计算如下:

timestamp = AV_TIME_BASE * time_in_seconds


三:ffmpeg常见概念

帧率:帧率(Frame rate)也叫帧频率,帧率是视频文件中每一秒的帧数,肉眼想看到连续移动图像至少需要15帧。

码率:比特率(Bit rate)(也叫码率,数据率)是一个确定整体视频/音频质量的参数,每秒单位处理的字节数,码率和视频质量成正比,在视频文件中中比特率用bps来表达。

AV_NOPTS_VALUE:

Undefined timestamp value.

FFmpeg里有两种时间戳:DTS(Decoding TimeStamp)和PTS(Presentation TimeStamp,前者是解码的时间,后者是显示的时间。要仔细理解这两个概念,需要先了解FFmpeg中的packet和frame的概念;FFmpeg中用AVPacket结构体来描述解码前或编码后的压缩包,用AVFrame结构体来描述解码后或编码前的信号帧。 对于视频来说,AVFrame就是视频的一帧图像。这帧图像什么时候显示给用户,就取决于它的PTS。DTS是AVPacket里的一个成员,表示这个压缩包应该什么时候被解码。 如果视频里各帧的编码是按输入顺序(也就是显示顺序)依次进行的,那么解码和显示时间应该是一致的。可事实上,在大多数编解码标准(如H.264或HEVC)中,编码顺序和输入顺序并不一致。 于是才会需要PTS和DTS这两种不同的时间戳。

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

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

下面给出一个GOP为15的例子,其解码的参照frame及其解码的顺序都在里面:


GOP

如上图:I frame 的解码不依赖于任何的其它的帧.而p frame的解码则依赖于其前面的I frame或者P frame.B frame的解码则依赖于其前的最近的一个I frame或者P frame 及其后的最近的一个P frame.

常用结构体:

AVFilterLink:A link between two filters

包含内容:

AVFilterContext *src -----source filter 

AVFilterContext *dst------ dest filter 

AVStream:

index:0-video,1-audio

一个视频文件的PTS不一定从0开始,因此第一个PTS就是基准值,此时的播放时间就是当前帧的PTS减去第一帧的PTS。

PTS不是具体的毫秒,而是一个数值,真实的时间由timebase计算而来。

 progress =av_rescale_q(enc_pkt.dts, media_muxer_->get_stream(video_stream_index_)->time_base, AV_TIME_BASE_Q);

  int percent = (int)(progress *100/duration_); //可以计算进度

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

推荐阅读更多精彩内容