tinkle
帖子: 82
注册时间: 2011-08-03 13:14

想学习关于各种编码视频的切割原理

为什么有的视频不能精确切割,为什么有的切出来无法播放,为什么有的切出来视频音频不同步了?想学习一下原理性的知识。不知道网上有没有相关介绍的文章,各位前辈能不能分享下自己的心得呢。谢谢 {:cat_11}
头像
upyzl
帖子: 446
注册时间: 2010-12-25 18:44
来自: 湘/京
联系: 网站

Re: 想学习关于各种编码视频的切割原理

关于精确切割,可以这样理解:
假设某视频第N帧是IDR,第(N+1)帧是P帧,且参考第N帧。如果想不重编码无损切割成0~N和N+1~N+k两部分,由于第(N+1)帧实际并没有储存我们所看到的完整信息,一般切割软件为了保证切割后的视频也是正确的就无法精确切割,不然就花屏等现象了。


关于切割后视频音频不同步,这个我印象里ffmpeg会这样。
原因是ffmpeg分别按视频、音频切割,视频受如上所说的限制精确度大减,而音频能很好地切割(但也不是绝对精确,至少有损音频编码会受除了音频采样率的其他因素所影响,不过这方面我就不清楚了……但不管怎样都能比有大量P/B帧的视频更为精确)。
不过当时我用的ffmpeg比较老,不知道现在是什么情况了。
另外切割软件应该不少,不过我现在常用的主要是mkvtoolnix,故不清楚其他的是什么情况……
tinkle
帖子: 82
注册时间: 2011-08-03 13:14

Re: 想学习关于各种编码视频的切割原理

我记得有个软件非重编码切割时有说明,会在切割点的前面找距离最近的IDR帧切,这个地方我有个不懂的就是切割时能不能按照I帧来切而不是IDR?一个视频是否可以从一个i帧开始正常解码播放?后面的p帧、b帧理论上应该只参考了他们前后帧的信息所以说就与那个i帧之前的帧无关了吧,那么只要在切割的时候将这个i帧重定义为IDR帧不就可以了?
但事实是往往按照软件自己说的按idr切切出来的视频往往也有问题,比如说x264编码的avi(在这里我又想问一句为什么这些人总喜欢用avi而不用mp4、mkv,有什么好处么?),但是x264的mp4切割就很方便,并没遇到过无法播放等问题,说明切割还是跟容器有关的,个中原因就不明白了。
头像
06_taro
核心会员
核心会员
帖子: 998
注册时间: 2010-09-22 18:32
来自: United Kingdom
联系: 网站

Re: 想学习关于各种编码视频的切割原理

广义的I帧表示解码时不需要参考其他帧的非参考帧,但是不代表对GOP进行分割。只有IDR是对GOP分割的。
举个例子,把非IDR的I帧记为i,IDR记为I的话:
IBPiBPIBP....
这里出现的i帧后的B帧与P帧在解码时有可能参考i之前的I帧P帧甚至是B帧(开b-pyramid时),而第二个I帧后的B帧P帧则肯定不会参考该I帧之前的任何帧。分割时,i帧由于起不到分割GOP作用,i之后的帧解码可能还会参考之前的,所以不能在这里进行分割;而I帧分割的GOP,可以安全地分割。
つまんねー事聞くなよ!

I, personally, for me, believe (obviously sometimes) that my OS choice is right. That's me. I'm not telling you that you should believe it. Learn the facts, and the origins behind the facts, and make up your own damn mind. That's why you have one. (source)

Follow me: @06_taro

304——
为纪念伟大的宇宙史上最强压制304先生,联合国教科文组织决定,将每年的第304天,即平年的10月31日或者闰年的10月30日,定为世界304日。
tinkle
帖子: 82
注册时间: 2011-08-03 13:14

Re: 想学习关于各种编码视频的切割原理

06_taro 写了:广义的I帧表示解码时不需要参考其他帧的非参考帧,但是不代表对GOP进行分割。只有IDR是对GOP分割的。
举个例子,把非IDR的I帧记为i,IDR记为I的话:
IBPiBPIBP....
这里出现的i帧后的B帧与P帧在解码时有可能参考i之前的I帧P帧甚至是B帧(开b-pyramid时),而第二个I帧后的B帧P帧则肯定不会参考该I帧之前的任何帧。分割时,i帧由于起不到分割GOP作用,i之后的帧解码可能还会参考之前的,所以不能在这里进行分割;而I帧分割的GOP,可以安全地分割。
那您觉得有些视频切出来不对是不是由于没有按照IDR帧分割而是按照i帧分割了,也就是说没能识别出正确的IDR帧?如果是按照IDR切割的,那么为什么会出现无法播放的情况?

回到 “封装容器 / Container muxer and demuxer”