您的位置 首页 > 娱乐休闲

【megui导入avs出现的框什么都没有】视频压缩:IBP帧分类和断点续压的机制与实现

1,IBP帧

在压缩视频的过程中,在一段时间内对相似的帧记录第一章,接下来的几章只记录第一章和其他部分是自然的想法。

由此引申出两种帧:

I帧(Independent Frame),独立编码的帧。I帧相当于记录一张jpg;一般常见于一个场景开头。后续的帧就需要依赖I帧,P帧(Predictive Frame),需要依赖其他帧来编码的类型。P帧需要参照在它之前的I帧或者其他的P帧,因为它只记录差别,所以对于那种前后差别很小甚至没有的帧,使用P帧编码能极大地减少体积。

MPEG2之后,引入了第三种帧:

B帧(Bi-directional Frame),双向预测帧。B帧跟P帧类似,都是需要参照别的帧,区别在于B帧可以(但不必要)参照它后面的帧,B帧的记录和预测方式也做了调整,使得B帧的预测方式更灵活,对付高度静态规律的场景可以更有效的降低体积一种典型的排列方式:

IPBBPBPIPPB视频开头一定是一个I帧。

2、IDR帧与GOP区间

I帧中,有一类特殊的I帧,叫做IDR帧。IDR帧的性质是,比如第1000帧是IDR帧,那么这一帧相当于一个分水岭,从1001帧开始,所有的帧都不能再参照1000帧之前的帧。在closed GOP规定下(x264设置中可以指定,并且vcb-s一直指定),0~999帧也不允许参照这个IDR帧以及之后的帧。这个性质在播放的时候额外有用:如果我直接从第1000帧开始播放,我可以毫无问题的播放下去,因为我不需要参照1000帧之前的内容完成解码。我从开头播放,直到999帧的时候,我都不需要参照1000帧及它后面的东西;1000帧之后的数据都损坏了,0~999帧也能正常播放。

视频开头的I帧一定是IDR帧。

在我们拖动进度条的时候,为啥有时候会卡顿,或者拖不准呢?其实是播放器干了这些事:

1. 计算你拖动进度条的时间,找出它应该是哪一帧,假设为N

2. 通过搜索视频索引信息,找出N帧前面最近的一个IDR帧,假设为M(M<=N)。很显然,M和N同属于一个GOP区间,

这个区间开头的帧是M

3. 如果你的播放器设置了快速索引,视频将直接从M帧开始播放,因为M帧是IDR,它不需要参照任何帧,所以立刻

可以开始播放。这是为啥你会发现开始的地方总是在之前一点。

4. 否则,如果你的播放器设置了精确索引,解码器会从M帧一直开始解码,解码到N帧,然后显示N帧的画面,并继续播放。

当N-M比较大的时候,播放器可能需要先解码几百甚至上千帧,才能继续播放。如果视频允许很长的GOP区间,这个视频在播放的时候,拖动进度条就特容易卡顿。

在x264中,如果设置了--min-keyint 1,那么所有I帧都是IDR帧(vcb-s也一直在用)。而GOP区间最大的范围是通过--keyint指定的。这些在后续x264参数教程中再讨论。

两个IDR帧之间的区间,从一个IDR帧开始,到下一个IDR前的帧结束,叫做IDR区间,又叫做GOP区间。GOP区间可以看做是独立的一段视频:它里面的所有帧,都不需要参照任何区间之外的东西,只要一个GOP区间是齐全的,区间里面所有的帧都能被解码。我们平时看的视频就是多段GOP区间连接起来的。

3、断点续压的抢救原理

如果在编码的时候,不幸断电,崩溃,或者必须掐掉(注意掐掉必须是通过任务管理器,掐掉x264_64.exe,不能点abort,否则半成品的mkv会被megui删除),半成品的mkv文件是什么样子呢?

[完成的GOP区间1] [完成的GOP区间2]……[完成的GOP区间N] [正在做的GOP区间N+1, 断在某一帧1~N 这些GOP区间,已经完成了,完全可以提取出来作为第一段。然后从N+1开头的IDR帧继续编码到结束,作为第二段,最后将两个视频拼接起来。

如何知道当前断的IDR区间,具体开始帧的位置呢?这个就要通过x264的编码记录来判断了。在编码之前,我们需要对x264的参数添加两句:

--log-file "xxx.log" --log-file-level debug

这个命令是让x264详细的将编码的过程记录到xxx.log中(文件名你可以自己指定,这是个文本文件,所以也可以是xxx.txt等。默认在megui目录下;如果已经存在,就是接着上个文件的末尾写)

4、断点续压的操作

1、找到xxx.log,用附带的notepad2打开(注意普通记事本不能识别换行符,所以直接打开会看不到换行。

如果你有notepad++这种编辑器那么也可以用)往最后翻,光标停在最后一行:

重要的信息有两个,第一个是帧数frame=xxxx. 这个帧数是从0算起的。

第二个是Slice: I/B/P,表明这一帧是哪种类型。注意了如果是I帧那么一定是IDR帧。

从下往上,找到第一个I帧,这个可以用edit-find(Ctrl+F),关键字: Slice:I。在光标停在最后一行的时候,

find previous可以让你马上找到最末一个I帧:

http://www.z4a.net/images/2017/03/25/3.png

它是40583帧(从0开始数起)。这意味着所有完成的部分是0~40582帧,40583~结束还需要再编码

2、用mkvtoolnix抢救有效部分。打开mkvtoolnix\mmg.exe,拖入半成品mkv:

然后标签打到全局(globle)下,切割模式,选择 根据帧/场编号切割为分段。然后下面填入范围。 注意了mmg的帧数编号是从1开始。(我们一般习惯从0开始,x264的记录也好,avs的编号也好,都是0开始,唯独mmg是从1开始,这是个需要注意的地方)因为从1开始,所以有效部分的0-40582就变成了1-40583:

随后,开始混流。输出的mkv就是前面抢救完成的部分。

3、继续编码剩余的部分。

40583~结束还需要再编码,那么我们就在avs里面做一个trim:

注意这个trim永远是新开一行加在末尾。如果末尾有"""),那么加在倒数第二行(有这个标志是avs的多线程优化机制)。添加这个trim,意味着重复之前的载入片源和必要处理,但是输出的时候,只输出40583到结尾。

用这个新的avs配合以前的参数继续编码。注意如果你还没有从之前的半成品中,抢救有效部分,新的编码要小心,

千万不要覆盖掉之前的半成品

4、前一段和后一段做完后,就可以使用mmg.exe合并了(见下图):

mmg中,"添加"是指添加一条新的轨道,但是"追加合并",则是在某个轨道后面继续接东西。

所以合并视频可以用追加合并来完成。追加合并两条视频后,继续添加音轨等就需要再用添加按钮,而不是追加合并。

封装完毕后常规的检查下,特别是中断的部分衔接,没有问题就OK了。

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

相关推荐