检测 RTP 流中的 MPEG4/H264 I 帧 (IDR)
我需要检测 RTP 数据包中的 MPEG4 I 帧。我知道如何删除 RTP 标头并获取其中的 MPEG4 帧,但我不知道如何识别 I 帧。
它有特定的签名/标头吗?
I need to detect MPEG4 I-Frame in RTP packet. I know how to remove RTP header and get the MPEG4 frame in it, but I can't figure out how to identify the I-Frame.
Does it have a specific signature/header?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
好的,我想出了 h264 流的方法。
如何检测 I 帧:
我无法弄清楚 MPEG4-ES 流...有什么建议?
编辑:H264 IDR
这适用于我的 h264 流 (
fmtp:96 packetization-mode=1; profile-level-id=420029;
) 。您只需传递表示通过 RTP 接收到的 h264 片段的字节数组。如果您想传递整个 RTP,只需更正RTPHeaderBytes
值即可跳过 RTP 标头。我总是得到 I 帧,因为它是唯一可以分段的帧,请参见 此处。我在我的服务器中使用这段(简化的)代码,它的工作就像一个魅力!如果 I 帧 (IDR) 未分段,则fragment_type
将为 5,因此此代码将为分段和非分段 IDR 返回true
。以下是 NAL 单元类型表:
编辑 2:MPEG4 I-VOP
我忘记更新此...感谢 Che 和 ISO IEC 14496-2 文档,我设法解决了这个问题! Che 很仪式,但他的回答并不那么精确...所以这里是如何找到 I、P 和 B 帧(I-VOP、P-VOP、B-VOP),简而言之:
000001B6
(十六进制)开头。对于所有 MPEG4 帧(I、P、B)都是相同的接下来有更多信息,我不会在这里描述(请参阅 IEC 文档),但我们只(如 che 所说)需要更高的来自后续字节的 2 位(值为
B6
的字节之后的接下来两位)。这 2 位告诉您 VOP_CODING_TYPE,请参阅表格:因此,要查找 I 帧,请查找以四个字节
000001B6
开头并具有下一个字节的高两位00
的数据包。代码>.这将在 MPEG4 流中找到具有简单视频对象类型的 I 帧(不确定高级简单)。对于任何其他问题,您可以查看提供的文档(ISO IEC 14496 -2),这里有您想了解的有关 MPEG4 的所有信息。 :)
Ok so I figured it out for h264 stream.
How to detect I-Frame:
I cant figure it out for the MPEG4-ES stream... any suggestions?
EDIT: H264 IDR
This works for my h264 stream (
fmtp:96 packetization-mode=1; profile-level-id=420029;
). You just pass byte array that represents the h264 fragment received through RTP. If you want to pass whole RTP, just correct theRTPHeaderBytes
value to skip RTP header. I always get the I-Frame, because it is the only frame that can be fragmented, see here. I use this (simplified) piece of code in my server, and it works like a charm!!!! If the I-Frame (IDR) is not fragmented, thefragment_type
would be 5, so this code would returntrue
for the fragmented and not fragmented IDRs.Here's the table of NAL unit types:
EDIT 2: MPEG4 I-VOP
I forgot to update this... Thanx to Che and ISO IEC 14496-2 document, I managed to work this out! Che was rite, but not so precise in his answer... so here is how to find I, P and B frames (I-VOP, P-VOP, B-VOP) in short:
000001B6
(hex). It is the same for all MPEG4 frames (I,P,B)Next follows many more info, that I am not going to describe here (see the IEC doc), but we only (as che said) need the higher 2 bits from the following byte (next two bits after the byte with the value
B6
). Those 2 bits tell you the VOP_CODING_TYPE, see the table:So, to find I-Frame find the packet starting with four bytes
000001B6
and having the higher two bits of the next byte00
. This will find I frame in MPEG4 stream with a simple video object type (not sure for advanced simple).For any other problems, you can check the document provided (ISO IEC 14496-2), there is all you want to know about MPEG4. :)
据我所知,RTP负载中的MPEG4-ES流片段通常以MPEG4起始码开头,可以是以下之一:
0x000001b0
:visual_object_sequence_start_code(可能是关键帧)0x000001b6
: vop_start_code(关键帧,如果接下来的两位为零)0x000001b3
:group_of_vop_start_code,包含三个字节,然后希望 vop_start_code 可能属于也可能不属于关键帧(见上文)0x00000120< /code>:video_object_layer_start_code(可能是关键帧)
0x00000100
-0x0000011f
:video_object_start_code(那些看起来也像关键帧)我担心你需要解析流以确保:-/
As far as I know, MPEG4-ES stream fragments in RTP payload usually start with MPEG4 startcode, which can be one of these:
0x000001b0
: visual_object_sequence_start_code (probably keyframe)0x000001b6
: vop_start_code (keyframe, if the next two bits are zero)0x000001b3
: group_of_vop_start_code, which contains three bytes and then hopefully a vop_start_code that may or may not belong to a keyframe (see above)0x00000120
: video_object_layer_start_code (probably keyframe)0x00000100
-0x0000011f
: video_object_start_code (those look like keyframes as well)I'm afraid that you'll need to parse the stream to be sure :-/
实际上,对于 h264 流,您是正确的,如果 NAL 值(第一个字节)是 0x7C,则意味着 I 帧已分段。没有其他帧(P 和 B)可以分片,因此如果
SDP
中存在packetization-mode=1
,则表示 I 帧已分片,并且因此,如果您将0x7C
读取为第一个字节,则它是 I 帧。在这里阅读更多内容: http://www.rfc-editor.org/rfc/rfc3984.txt 。Actually, you was correct for h264 stream, if the NAL value (first byte) is
0x7C
it means that the I-Frame is fragmented. No other frames (P and B) can be fragmented, so if there ispacketization-mode=1
inSDP
, then it means that the I-Frames are fragmented, and therefore if you read0x7C
as first byte, then it is I-Frame. Read more here: http://www.rfc-editor.org/rfc/rfc3984.txt.这对我有用:
- 找出“有效负载类型”,例如:有效负载类型:DynamicRTP-Type-96 (96)
- 告诉wireshark哪个流是H264:文件->首选项->协议->H264。输入 96 作为负载类型。
- 对 slice_type 进行过滤:“h264.slice_type eq 7”
This worked for me:
- Figure out the "payload type", for example: Payload type: DynamicRTP-Type-96 (96)
- Tell wireshark which stream is H264: File->preferences->protocols->H264. Enter 96 as payload type.
- Filter on slice_type:"h264.slice_type eq 7"
对于 H264:
示例:
For H264:
Examples:
0x000001b6:vop_start_code(关键帧,如果接下来的两位为零)
这是 MPEG-4 的正确方法
0x000001b6: vop_start_code (keyframe, if the next two bits are zero)
this is correct way for MPEG-4