检测RTP流中的MPEG4 / H264 I帧(IDR)

时间:2009-12-24 08:42:34

标签: rtp rtsp

我需要在RTP数据包中检测MPEG4 I-Frame。我知道如何删除RTP标头并获取其中的MPEG4帧,但我无法弄清楚如何识别I帧。

是否有特定的签名/标题?

6 个答案:

答案 0 :(得分:31)

好的,所以我想出了h264流。

如何检测I-Frame:

  • 删除RTP标题
  • 检查h264有效负载中第一个字节的值
  • 如果值为124(0x7C),则为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):

  1. VOP(视频对象平面 - 帧)以代码000001B6(十六进制)开头。所有MPEG4帧(I,P,B)
  2. 都是一样的
  3. 接下来是更多信息,我不打算在此描述(参见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)
    
  4. 因此,要找到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:

  1. 删除RTP标题。
  2. 如果块NAL类型(在第一个字节中)是SPS(7)或PPS(8)将帧标记为IFrame(许多相机不使用SPS和PPS(包括轴))。
  3. 如果块NAL类型是#28 FU A(分段单元A),检查FU Header(下一个字节)是否为NAL类型IDR(5)(IDR(瞬时解码刷新)图片)是IFrame。
  4. 示例:

    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
    ...