我需要在RTP数据包中检测MPEG4 I-Frame。我知道如何删除RTP标头并获取其中的MPEG4帧,但我无法弄清楚如何识别I帧。
是否有特定的签名/标题?
答案 0 :(得分:31)
好的,所以我想出了h264流。
如何检测I-Frame:
我无法弄清楚MPEG4-ES流......有什么建议吗?
编辑:H264 IDR
我的h264流(fmtp:96 packetization-mode=1; profile-level-id=420029;
)有效。您只需传递表示通过RTP接收的h264片段的字节数组。如果要传递整个RTP,只需更正RTPHeaderBytes
值即可跳过RTP标头。我总是得到I帧,因为它是唯一可以分段的帧,请参阅here。我在我的服务器中使用这段(简化的)代码,它就像一个魅力!!!!如果I帧(IDR)没有分段,则fragment_type
将为5,因此对于分段且未分段的IDR,此代码将返回true
。
public static bool isH264iFrame(byte[] paket)
{
int RTPHeaderBytes = 0;
int fragment_type = paket[RTPHeaderBytes + 0] & 0x1F;
int nal_type = paket[RTPHeaderBytes + 1] & 0x1F;
int start_bit = paket[RTPHeaderBytes + 1] & 0x80;
if (((fragment_type == 28 || fragment_type == 29) && nal_type == 5 && start_bit == 128) || fragment_type == 5)
{
return true;
}
return false;
}
以下是NAL单位类型表:
Type Name
0 [unspecified]
1 Coded slice
2 Data Partition A
3 Data Partition B
4 Data Partition C
5 IDR (Instantaneous Decoding Refresh) Picture
6 SEI (Supplemental Enhancement Information)
7 SPS (Sequence Parameter Set)
8 PPS (Picture Parameter Set)
9 Access Unit Delimiter
10 EoS (End of Sequence)
11 EoS (End of Stream)
12 Filter Data
13-23 [extended]
24-31 [unspecified]
编辑2:MPEG4 I-VOP
我忘了更新这个... Thanx to Che和ISO IEC 14496-2文件,我设法解决了这个问题! Che是仪式,但在答案中并不那么精确......所以这里是如何找到I,P和B帧(简称I-VOP,P-VOP,B-VOP):
000001B6
(十六进制)开头。所有MPEG4帧(I,P,B)接下来是更多信息,我不打算在此描述(参见IEC文档),但我们只(如上所述)需要后续字节中的高2位(后两位)值为B6
的字节。这2位告诉你VOP_CODING_TYPE,见表:
VOP_CODING_TYPE (binary) Coding method
00 intra-coded (I)
01 predictive-coded (P)
10 bidirectionally-predictive-coded (B)
11 sprite (S)
因此,要找到I-Frame,请找到以四个字节000001B6
开头并且具有下一个字节00
的高两位的数据包。这将在MPEG4流中找到I帧,具有简单的视频对象类型(不确定是否为高级简单)。
对于任何其他问题,您可以查看提供的文档(ISO IEC 14496-2),您可以了解有关MPEG4的所有信息。 :)
答案 1 :(得分:7)
据我所知,RTP有效载荷中的MPEG4-ES流片段通常以MPEG4起始码开头,可以是其中之一:
0x000001b0
:visual_object_sequence_start_code(可能是关键帧)0x000001b6
:vop_start_code(关键帧,如果接下来的两位为零)0x000001b3
:group_of_vop_start_code,包含三个字节,然后希望一个vop_start_code可能属于或不属于一个关键帧(见上文)0x00000120
:video_object_layer_start_code(可能是关键帧)0x00000100
- 0x0000011f
:video_object_start_code(它们看起来像关键帧)我担心您需要解析流以确定: - /
答案 2 :(得分:6)
实际上,你对h264流是正确的,如果NAL值(第一个字节)是0x7C
,则意味着I帧被分段。没有其他帧(P和B)可以被分段,因此如果packetization-mode=1
中有SDP
,那么这意味着I帧被分段,因此如果您将0x7C
读为第一个字节,然后它是I帧。在此处阅读更多内容:http://www.rfc-editor.org/rfc/rfc3984.txt。
答案 3 :(得分:1)
这对我有用:
- 找出“有效载荷类型”,例如:有效载荷类型:DynamicRTP-Type-96(96)
- 告诉wireshark哪个流是H264:文件 - >首选项 - >协议 - > H264。输入96作为有效载荷类型
- 过滤slice_type:“h264.slice_type eq 7”
答案 4 :(得分:0)
0x000001b6:vop_start_code(关键帧,如果接下来的两位为零) 这是MPEG-4的正确方法
答案 5 :(得分:0)
对于H264:
示例:
nal_ref_idc: 3, nal type: 7 (0x07) descripcion: 7 (SPS)<br>
00000000 24 00 00 2B 80 60 22 ED 96 57 3E 68 57 F3 22 B5 $..+.`"í.W>hWó"µ<br>
00000010 67 64 00 1E AD 84 01 0C 20 08 61 00 43 08 02 18 gd..... .a.C...
00000020 40 10 C2 00 84 2B 50 5A 09 34 DC 04 04 04 08 @.Â..+PZ.4Ü....<br>
nal_ref_idc: 3, nal type: 8 (0x08) descripcion: 8 (PPS)<br>
00000000 24 00 00 10 80 60 22 EE 96 57 3E 68 57 F3 22 B5 $....`"î.W>hWó"µ
00000010 68 EE 3C B0 hî<°
FU_A (fragmentation unit A)
nal_ref_idc: 3, nal type: 5 (0x05) descripcion: 5 (IDR (Instantaneous Decoding Refresh) Picture)
00000000 24 00 05 96 80 60 22 F1 96 57 3E 68 57 F3 22 B5 $....`"ñ.W>hWó"µ
00000010 7C 05 A0 AA 2F 81 92 AB CA FE 9E 34 D8 06 AD 74 |. ª/..«Êþ.4Ø.t
...