我有损坏的 mpeg4 文件,需要帧重新整理(示例位于 https://drive.google.com/file/d/1GD7YiVS2z8h0r6UdsPPIXFgnh9RukoeR/view?usp=drive_link ) 我使用 ffmpeg 的 shuffleframes 过滤器取得了一些成功,但它需要视频重新编码,我想避免这种情况。
我分析了这些 mpeg4 文件,发现它们没有 CTTS 框,因此我尝试添加一个具有所需偏移量的文件,但无济于事:VLC 3.0.20 仍然以错误的顺序播放帧:-(。
为了确认 CTTS 是否按我的想法工作,我使用 ffmpeg 制作了以下具有 100 个编号帧 @2fps 的测试视频: https://drive.google.com/file/d/1vp3uKZYgoOFqlMk7GLKOC-_vxzJCMwGQ/view?usp=sharing 我对其进行了分析,并确认它包含一个定义帧偏移量 (*) 的 CTTS 框,并且 VLC 可以正常播放。好。
现在奇怪的是:如果我编辑该测试 MPEG-4 并删除 CTTS 框(生成以下文件:https://drive.google.com/file/d/1JMEcyBoz5r0uVDt08ZOumDVngT1PYWm8/view?usp=sharing ),VLC 仍然按正确的顺序播放视频!
所以我的问题是:VLC 如何进行?我猜它使用了一些其他(冗余)信息? 并且,当该信息和 CTTS 都存在且不一致时,哪个优先?
或者,简而言之,如何以一致的方式修复帧顺序?
谢谢,
文森特
(*) 从测试文件开始 CTTS 解码:
Entry{count=1, offset=16384}, 2f => frame encoded at pos. 0 => presented at pos. 0+2=2
Entry{count=1, offset=32768}, 4f => frame encoded at pos. 1 => presented at pos. 1+4=5
Entry{count=2, offset=8192}, 1f => frame encoded at pos. 2 => presented at pos. 2+1=3
1f => frame encoded at pos. 3 => presented at pos. 3+1=4
Entry{count=1, offset=40960}, 5f => frame encoded at pos. 4 => presented at pos. 4+5=9
Entry{count=1, offset=16384}, 2f => frame encoded at pos. 5 => presented at pos. 5+2=7
Entry{count=1, offset=0}, 0f => frame encoded at pos. 6 => presented at pos. 6+0=6
Entry{count=1, offset=8192}, 1f => frame encoded at pos. 7 => presented at pos. 7+1=8
Entry{count=1, offset=32768}, 4f => frame encoded at pos. 8 => presented at pos. 8+4=12
Entry{count=2, offset=8192}, 1f => frame encoded at pos. 9 => presented at pos. 9+1=10
1f => frame encoded at pos. 10 => presented at pos. 10+1=11
Entry{count=1, offset=32768}, 4f => frame encoded at pos. 11 => presented at pos. 11+4=15
Entry{count=2, offset=8192}, 1f => frame encoded at pos. 12 => presented at pos. 12+1=13
1f => frame encoded at pos. 13 => presented at pos. 13+1=14
Entry{count=1, offset=32768}, 4f => frame encoded at pos. 14 => presented at pos. 14+4=18
Entry{count=2, offset=8192}, 1f => frame encoded at pos. 15 => presented at pos. 15+1=16
1f => frame encoded at pos. 16 => presented at pos. 16+1=17
Entry{count=1, offset=24576}, 3f => frame encoded at pos. 17 => presented at pos. 17+3=20
Entry{count=1, offset=8192}, 1f => frame encoded at pos. 18 => presented at pos. 18+1=19
显示(和解码)顺序存储在 H.264 和 H.265 流中。
图片顺序计数 (POC) 确定解码帧的显示(输出)顺序。 POC 源自片头。 POC 成为 MP4 里面的
ctts
盒子。
我会尝试将视频流复制到 H.265 基本流中 - 将视频流从容器中剥离出来。 然后将视频流重新包装到 MPEG-4 容器中。
ffmpeg -i av.mp4 -codec:v copy -an v.h264
ffmpeg -i v.h264 -codec:v copy -an v.mp4