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

Cip*_*ipi 25 rtp rtsp

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

它有特定的签名/标题吗?

Cip*_*ipi 32

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

如何检测I帧:

  • 删除RTP标头
  • 检查h264有效负载中第一个字节的值
  • 如果值为124(0x7C),则为I帧

我无法弄清楚MPEG4-ES流......有什么建议吗?

编辑:H264 IDR

适用于我的h264流(fmtp:96 packetization-mode=1; profile-level-id=420029;).您只需传递表示通过RTP接收的h264片段的字节数组.如果要传递整个RTP,只需更正该RTPHeaderBytes值即可跳过RTP标头.我总是得到I-Frame,因为它是唯一可以分段的帧,请参见此处.我在我的服务器中使用这段(简化的)代码,它就像一个魅力!!!! 如果I帧(IDR)没有分段,则为fragment_type5,因此该代码将返回true分段且未分段的IDR.

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;
   }
Run Code Online (Sandbox Code Playgroud)

这是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] 
Run Code Online (Sandbox Code Playgroud)

编辑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. 接下来是更多信息,我不打算在这里描述(参见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)
    
    Run Code Online (Sandbox Code Playgroud)

因此,要找到I-Frame,请找到以四个字节开头000001B6并具有下一个字节的高两位的数据包00.这将在MPEG4流中找到具有简单视频对象类型的帧(对于高级简单而言不确定).

对于任何其他问题,您可以查看提供的文档(ISO IEC 14496-2),您需要了解有关MPEG4的所有信息.:)

  • 这不正确(甚至没有关闭).它可能恰好适用于您正在查看的流.在IETF查看RFC 3984(很快将被3984bis替换).请注意,您可以拥有碎片NAL(具有片段标头,具有多个NAL的STAP数据包(以及iframe可以在数据包的第二个NAL中启动)等等.您真的想要扫描数据包流中的所有NAL以便NAL引入注意,实际的i帧/ si帧之前可能有一组序列和图片参数集,这些参数集是*important*,应该被认为是IDR的一部分(但不是标记) (6认同)

che*_*che 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(那些看起来像关键帧)
  • 别的东西(可能不是关键帧)

我担心你需要解析流来确定: - /


小智 6

实际上,你对h264流是正确的,如果NAL值(第一个字节)是0x7C意味着I帧被分段.没有其它帧(P和B)可以被分割,因此,如果有packetization-mode=1SDP,那么它意味着该I帧被分段,且因此,如果你读0x7C为第一个字节,那么它是I帧.在这里阅读更多内容:http://www.rfc-editor.org/rfc/rfc3984.txt.