我正在制作h264流分析器,并且在写入和读取与MPEG-TS打包的相同帧时发现了奇怪的ffmpeg行为。
我已经在HEX中转储了帧编码和解码帧数据并发现了这些差异:
在帧的开头添加了NAL分隔符:
+ 00
+ 00
+ 00
+ 01
+ 09
+ f0
对我来说看起来绝对合法。
但这里有些奇怪的事情:
如果当前数据包不是最后一个,则添加一些后缀(即在最后写入的帧中没有此后缀)。并且此后缀被添加到当前读取帧(即,这不是下一帧的前缀)。
+ e0
+ 00
+ 00
+ 00
+ 01
+ ce
+ 8c
+ 4d
+ 9d
+ 10
+ 8e
+ 25
+ e9
+ fe
(完全从添加e0
字节开始)
我想了解这可能意味着什么。如果00000001
是NAL标题,则后跟ce
字节,禁止零位等于1,绝对不会。
我使用ffmpeg github repo的fork最后与89092fafdde894c6ba4d4f8e3cd1cce0d68bfc22
commit合并。
ffmpeg使用--disable-everything --enable-encoder=libopenh264 --enable-muxer=mpegts --enable-demuxer=mpegts --enable-protocol=file --enable-parser=h264 --enable-decoder=libopenh264 --enable-shared --disable-static --disable-programs --disable-doc --enable-libopenh264
选项
答案 0 :(得分:2)
所以我找到了问题。
pInputFormatContext->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
在avformat_open_input
我在发布时发现AVPacket在执行时utils.c:1661
被破坏了
av_packet_merge_side_data(pkt);
更重要的是,我发现之前看到的其他数据的后续序列:
#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
在av_packet_merge_side_data
AVPacket中Side的数据类型为AV_PKT_DATA_MPEGTS_STREAM_ID (78)
,仅在解复用器和复用器中使用,但不在编解码器中使用。
我感到很困惑,因为我已经阅读了av_read_frame
的注释用于从文件中读取帧数据:
Return the next frame of a stream.
This function returns what is stored in the file, and does not validate
that what is there are valid frames for the decoder. It will split what is
stored in the file into frames and return one for each call. It will not
omit invalid data between valid frames so as to give the decoder the maximum
information possible for decoding.
我完全不知道为什么流标志在我使用过的两台PC上有所不同,但是禁用将边数据合并到数据包的数据中就可以了。
所以我认为这是ffmpeg的文档问题,它已经向我保证“我将被返回存储在文件中的内容”而不提及可以添加一些额外的数据。