FFmpeg总结

一、概述

本文会讲到的内容:
1、FFmpeg结构
2、FFmpeg解码
3、FFmpeg的时间timebase
4、FFmpeg编码
5、FFmpeg封装mp4

二、FFmpeg结构

image.png

AVFormatContext:文件信息上下文,其中就包含了流信息结构AVStream

AVStream:流信息,其中就包含具体的音视频格式信息AVCodecContext

AVCodecContext:具体的音视频格式信息。要解码音视频,需要从这里拿到相关信息,比如AVCodecID

AVPacket:未解码的音视频内容。比如视频的每一帧数据,就体现在一个packet中

AVFrame:解码后的音视频内容。

通过FFmpeg解析mp4的过程来理解:

image.png

思考
1、如何得到音频的编码格式?
AVFormatContext->AVStream->AVCodecContext->AVCodecID

2、如何得到这个mp4的总时间?
AVFormatContext->duration

3、如何得到视频的分辨率?
AVCodecContext->width、height

三、FFmpeg解码

1、解码H264(Annex-B)

Annex-B:H264其中一种表示格式。一般运用在网络传输中。

一般是以0x00000001或者0x000001开头,视频帧分为I、P、B帧。
I帧还会带上sps,pps信息,有这两个信息才可以正常解码。
0000000167+(SPS的内容)+0000000168+(PPS的内容)+0000000165+(IDR主帧的内容):
标志位计算公式:code&0x1F,通过公式计算,得到:
SPS:0x07
PPS:0x08
IDR:0x05
0x67 & 0x1F = 0x07,所以0x67是sps的标志位。

哪天你看到0000000127,标志位为0x27,0x27&0x1F = 0x07,所以它也是sps的标志。
image.gif

解码的部分代码:

image.png

思考
这里的解码器AVCodecContext不需要配置参数就可以解码成功,为什么?
1、可以得到具体的NAL
2、可以得到解码需要的信息
因为前面提到的sps,pps已经携带了解码的一些信息,比如分辨率,格式等等。FFmpeg会自动解析,然后进行解码。
p2p流通过Annex-B这种格式传H264。好处是每一个主帧都是独立的,就算前面的主帧携带的sps、pps有错,导致解码失败。后面的主帧也不受影响,还是可以解码成功。这样的容错性就更好。

2、解码H264(AVCC)

AVCC:H264其中一种表示格式。一般运用在mp4封装格式中。
与Annex-B区别有两点:一个是参数集(SPS, PPS)组织格式,一个是分隔。
Annex-B:使用start code分隔NAL(start code为三字节或四字节,0x000001或0x00000001,一般是四字节);SPS和PPS按流的方式写在头部。

AVCC:使用NALU长度(固定字节,通常为4字节)分隔NAL,在头部包含extradata(或sequence header)的结构体。
image.png

组成:

extradata+NAL长度+NAL+NAL长度+NAL。。。
NAL长度所占字节、SPS与PPS等包含在extradata中

extradata格式:

image.jpeg

举个例子:


image.png
image.png

思考
FFmpeg如何解码AVCC格式的H264?
解码的两大条件:
1、可以得到具体的NAL
2、可以得到解码需要的信息
前面提到了。必现要有extradata。才可以得到拆分出具体的NAL,并且extradata也包含了sps,pps等的解码需要的信息。

解码AVCC的H264:

image.png

3、如何得到extradata

a、从mp4文件中解析得到
AVFormatContext->AVStream->AVCodecContext->extradata

b、自己构造
(1)、直接构造extradata


image.png

(2)、先创建Annex-B格式的extradata,再通过ffmpeg自带函数转成AVCC的extradata
-先构造Annex-B方式的extradata:


image.png

-extradata(Annex-B) ----> extradata(AVCC)


image.png

四、timebase

timebase:视频处理中的一种时间单位
基本的时间单位:时、分、秒、毫秒

视频中最小单位为帧,帧都是毫秒级别
帧率为15,那么每帧时间为:1000/15=66.6666毫秒

1、不用浮点型
2、精度更高

只能扩大倍速了,比如扩大100倍,那么每一帧就是6666,这时候就得定义一种新的单位,可以转换为我们认知的时间:秒。

最终的数值都可以转化为秒。

比如,100毫秒,就是0.1秒
100*(1/1000) = 0.1秒

这里的timebase = 1/1000,表示 1秒=1000 毫秒。所以timebase包含了与秒的对应关系。

思考
1、刚才的6666,它的timebase是多少呢?
6666*timebase = 0.066秒
timebase = 1/100000

image.png

2、上面的pkt_pts_time是怎么得出来的?
timebase = 1/15360
pts = 1024
pts_time = 1024 * (1/15360) = 0.066667

五、FFmpeg编码

YUV 编码为 H264

编码代码:
image.png

解码代码:
image.png

是否这样就可以编码成功了呢?像解码一样,不需要参数?

引出的编码相关的问题:
1、每一帧压缩百分比多少,即编码大小未知
2、每一帧的分辨率未知
3、每一帧的原图片格式未知。YUV420? YUV422
所以这些东西都需要配置。

AVCodecContext的编码参数配置:

image.png

思考
1、如果编码的分辨率不按图片的分辨率设置会怎样?
设置多少,编码多少。如果图片分辨率1600X1200,我设置成800X600。结果如下:

image.png

2、如何控制编码后帧的大小?
a、通过修改码流参数,bit_rate
有时候你会发现,码流改小了很多,但编码后的大小变化不大

b、设置正确的timebase值

只有设置了正确的timebase,在改变bit_rate后,编码后的大小才能正确改变。
可以根据AVFrame中的timebase,具体你可以看它的pts值,推断大概的timebase。
比如:
你以帧率为15来算,那么每一帧的时间为1/15秒
1、比如第二帧 pts为1,那么1xtimebase = 1/15,所以timebase为(AVRational){1, 15}
2、比如第二帧pts为1024,同理1024xtimebase = 1/15,所以timebase为1/15除以1024,所以为(AVRational){1, 15360}

六、FFmpeg封装mp4

image.png

重点1:AVCodecContext的配置
需要配置正确的AVCodecContext->extradata
1、Annex-B的H264,配置对应的extradata(解码时候有提到)
2、AVCC的H264,配置对应的extradata

重点2:配置正确的timebase
如果合成的mp4播放速度不对,很大概率都是timebase设置错误了。
控制倍速播放等等,也通过修改timebase值,达到修改了每一帧的展示时间。

思考
timebase由1/15 改成 1/30,会怎样?

原本某帧的pts=30,30(1/15) = 2,就是这帧在第2秒才展示
30
(1/30) = 1,这帧变为第1秒展示,所以播放速度快了一倍

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

推荐阅读更多精彩内容

  • 结合前面的知识,这次把FFmpeg的解封装、解码、编码和封装整合到一块。代码仓库:https://github.c...
    Johnny_Wu阅读 2,138评论 4 5
  • 一、整体播放策略 (1)iOS自带的播放控件- AVPlayer、AVQueuePlayer只能通过路径播放,可以...
    Johnny_Wu阅读 826评论 0 2
  • FFmpeg 介绍 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LG...
    Y了个J阅读 11,344评论 0 28
  • 视频相关的问与答: 一、YUV的内存存储格式YUV格式有很多种,比如YUV420,YUV422,YUV444等。比...
    Johnny_Wu阅读 345评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,570评论 28 53