3

我有 1000 多个包含错误级别信息的视频,因此无法在某些设备上播放。它们是 H.264 基线,在 mp4 容器中带有 aac 音频。我想纠正它们,但避免重新编码。我是否正确地假设这是可能的并且会更快?如何识别流中的 level_idc 位?所有流都将它们放在同一位置吗?我希望这只会出现在流中的一个地方,这个假设是否正确?更新:我遇到了一个声称可以执行此操作的 Windows 可执行链接。我希望能够在 unix 上执行此命令行,因此我可以编写脚本。

更多更新:根据以下 Roman 的回答。我挖掘了 MP4 语法,发现 Profile 和 Level 信息是avcCatom under stsd. 我可以看到该级别设置为1E,我将其更正为1F。之前:61 76 63 43 01 42 C0 1E FF E1 00 19 67 42 C0 1E D9 之后:61 76 63 43 01 42 C0 1F FF E1 00 19 67 42 C0 1E D9MediaInfo 更改为:

Video
ID                                       : 1
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : Baseline@L3.0
Format settings, CABAC                   : No
Format settings, ReFrames                : 3 frames
Muxing mode                              : Container profile=Baseline@3.1
Codec ID                                 : avc1
Codec ID/Info                            : Advanced Video Coding
Duration                                 : 1mn 4s
Bit rate                                 : 3 000 Kbps
Width                                    : 1 280 pixels
Height                                   : 720 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Constant
Frame rate                               : 30.000 fps
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 0.109
Stream size                              : 22.7 MiB (92%)
Writing library                          : x264 core 120 r2151 a3f4407
Encoding settings                        : cabac=0 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=12 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=abr / mbtree=1 / bitrate=3000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00 

它引入了一个带有级别的 Muxing 模式参数,3.1但可惜这个流也没有在设备上播放。如何在Format Profile不重新编码的情况下更正这可能吗?

4

2 回答 2

1

请注意,级别存在于格式描述符上,也可能在有效负载本身上重复。如果您不关心描述符本身和有效负载/编码的实际完整性(我想提高级别很好,但降低它可能不好),可以在不重新编码视频的情况下更改级别。

不仅如此,通过找到包含视频轨道描述符的框并在此处修补级别,您可以通过两种方式做到这一点 - 您不需要 FFmpeg,您宁愿直接访问字节,而 MP4 格式可能足够简单来做到这一点从纯代码。

或者,您需要在途中重新多路复用轨道更改格式。解复用器和多路复用器不会检查此级别值是否可接受,因此将其作为与 FFmpeg 重新多路复用的一部分进行修补是可行的。extradata任何在不重新编码的情况下写入 MP4 的示例 FFmpeg 代码都是一个好的开始(您的任务将是在打开之前更新字段指向的字节数组AVFormatContext)。

于 2013-03-20T09:59:25.153 回答
1

我找到了一个解决方案,感谢@Roman 帮助我解决了这个问题。在比特流中的 avcC atom 之后找到 Profile 和 Level mp4,在我的情况下42 C0 1E,这是 Baseline@L3.0,我希望级别是3.1。为此,42 C0 1E在流中查找所有出现的 并替换1E1F. 我发现了大约 8-10 次这样的事件。现在你有了 Baseline@L3.1。这可以使用来验证mediainfo。我认为这是必要的,因为 h.264 被编码为一堆数据包,并且每个数据包都有带有配置文件和级别信息的 SPS 标头。

于 2013-03-22T11:28:29.940 回答