27

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

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

4

6 回答 6

35

好的,所以我想出了 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_type为 5,因此此代码将返回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;
   }

这是 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

我忘了更新这个……感谢 Che 和ISO IEC 14496-2文件,我设法解决了这个问题!Che 很老套,但他的回答并不那么精确......所以简而言之,这里是如何找到 I、P 和 B 帧(I-VOP、P-VOP、B-VOP):

  1. VOP(视频对象平面——帧)以代码000001B6(十六进制)开头。所有 MPEG4 帧 (I,P,B) 都是相同的
  2. 接下来是更多信息,我不打算在这里描述(参见 IEC 文档),但我们只(如 che 所说)需要来自下一个字节的高 2 位(具有 value 的字节之后的下两个位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 帧,请查找以四个字节开头000001B6并具有下一个字节的高两位的数据包00。这将在 MPEG4 流中找到具有简单视频对象类型的 I 帧(不确定高级简单)。

对于任何其他问题,您可以查看提供的文档(ISO IEC 14496-2),关于 MPEG4 您想了解的都有。:)

于 2009-12-28T11:03:45.387 回答
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(那些看起来也像关键帧)
  • 别的东西(可能不是关键帧)

恐怕您需要解析流以确保:-/

于 2010-01-03T18:13:14.553 回答
6

实际上,您对 h264 流是正确的,如果 NAL 值(第一个字节)是0x7C它意味着 I-Frame 是分段的。没有其他帧(P 和 B)可以被分片,所以如果有packetization-mode=1SDP则表示 I-Frame 是分片的,因此如果您0x7C作为第一个字节读取,则它是 I-Frame。在此处阅读更多信息:http ://www.rfc-editor.org/rfc/rfc3984.txt 。

于 2010-05-15T19:47:37.990 回答
1

这对我有用:
- 找出“有效负载类型”,例如:有效负载类型:DynamicRTP-Type-96 (96)
- 告诉wireshark哪个流是H264:文件->首选项->协议->H264。输入 96 作为有效负载类型。
- 过滤 slice_type:"h264.slice_type eq 7"

于 2013-11-05T10:00:23.500 回答
1

对于 H264:

  1. 删除 RTP 标头。
  2. 如果块 NAL 类型(在第一个字节中)是 SPS (7) 或 PPS (8),则将帧标记为 IFrame(许多相机不使用 SPS 和 PPS(包括轴))。
  3. 如果chunk NAL type是#28 FU A (fragmentation unit A),检查FU Header (next byte)是否是NAL type IDR(5)(IDR(Instantaneous Decoding Refresh) Picture)是一个IFrame。

例子:

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
...
于 2016-10-23T00:12:47.953 回答
0

0x000001b6:vop_start_code(关键帧,如果接下来的两位为零)这是 MPEG-4 的正确方法

于 2012-01-13T04:20:37.340 回答