2009-12-24 66 views

回答

30

好吧,我想出了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,因爲它是唯一可以被分割的幀,請參閱here。我在我的服務器中使用這個(簡化的)代碼段,它就像一個魅力!如果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

我忘了更新這...感謝名單給車和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位(值爲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幀找到以四個字節0​​且下一個字節00的高兩位的數據包。這將發現我在一個簡單的視頻對象類型MPEG4流幀(不確定高級簡單)。

對於任何其他問題,您可以檢查提供的文檔(ISO IEC 14496-2),有關於MPEG4的所有你想知道的。:)

+4

這不是正確的(甚至還沒有接近)。它可能適用於您正在查看的流。 在IETF檢查RFC 3984(很快將被3984bis替換)。請注意,您可以分割NAL(包含片段標頭,帶有多個NAL的STAP數據包(並且iframe可以在數據包的第二個NAL中啓動)等等) 您確實想要掃描數據包流中的所有NAL介紹IDR的NAL。請注意,實際的i-frame/si-frame可能有一組序列和圖片參數集,它們是*重要的*,應被視爲IDR的一部分(但不是標記) – jesup 2010-01-14 20:22:57

+0

對我來說,然後... = | – Cipi 2010-01-20 11:46:34

+0

@jesup參數集通常不是帶外發送的嗎?另外 - 嗨!想象你在這裏...... – 2011-09-07 16:56:53

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

實際上,如果NAL值(第一個字節)是0x7C,那麼表示I-幀是分段的,這對於h264流是正確的。沒有其他幀(P和B)可以被分段,所以如果SDP中有packetization-mode=1,那麼這意味着I幀被分段,因此如果您將0x7C作爲第一個字節讀取,則它是I幀。在這裏閱讀更多:http://www.rfc-editor.org/rfc/rfc3984.txt

0

0x000001b6:vop_start_code(關鍵幀,如果下一兩個比特是零) 這是正確的方式對MPEG-4

1

這爲我工作:
- 找出「有效載荷類型」,例如:負載類型:DynamicRTP-Type-96(96)
- 告訴wireshark哪個流是H264:File-> preferences-> protocols-> H264。輸入96作爲有效載荷類型。
- 上的slice_type篩選: 「h264.slice_type當量7」

1

對於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。

例子:

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