簡體   English   中英

如何知道H.264流中代表圖片的NAL單元數

[英]How to know the number of NAL unit in H.264 stream which represent a picture

我正在使用通過avcodec解碼的RTSP上具有H.264流的相機。 對於大多數相機,接收到的每個數據包(NAL單元)代表一個完整的幀(I幀或幀),當我對其進行解碼時,每次都會獲得一個幀。 但是對於另一台攝像機,一幀被分成許多大小不變的NAL單元,當我解碼每個數據包時,我沒有每個數據包的幀。

我看到NAL單元中有一個開始和結束標志。 除PPS或SPS之外,永遠不會設置結束標志。 不過,我可以檢測到開始代碼,並在新幀開始時告訴每個幀結束。

我想在將單個NAL單元中緩沖每個NAL單元,然后再將其發送到解碼器(這是為了記錄功能並最小化幀索引)。

此處為示例(NAL [1]字節內的start_flags為128)

NALU: 10 bytes: SPS, NAL[1]={0,64,0,2} // Start Frame 1
NALU: 5 bytes: PPS, NAL[1]={128,64,0,14}
NALU: 551 bytes: I-Frame, NAL[1]={128,0,0,8}
NALU: 531 bytes: I-Frame, NAL[1]={0,0,0,9}
NALU: 532 bytes: I-Frame, NAL[1]={0,0,0,4}
NALU: 517 bytes: I-Frame, NAL[1]={0,0,0,7}
NALU: 533 bytes: I-Frame, NAL[1]={0,0,0,3}
NALU: 621 bytes: I-Frame, NAL[1]={0,0,0,3}
NALU: 586 bytes: I-Frame, NAL[1]={0,0,0,1}
NALU: 520 bytes: I-Frame, NAL[1]={0,0,0,1}
NALU: 507 bytes: I-Frame, NAL[1]={0,0,0,1}
NALU: 508 bytes: I-Frame, NAL[1]={0,0,0,1}
NALU: 531 bytes: I-Frame, NAL[1]={0,0,0,0}
NALU: 558 bytes: I-Frame, NAL[1]={0,0,0,0}
NALU: 49 bytes: I-Frame, NAL[1]={0,0,0,0} // Start Frame 2 + END Frame 1
NALU: 253 bytes: Frame, NAL[1]={128,0,0,26} // Start Frame 3 + END Frame 2
// Frame 2 start so we can record/decode Frame 1
NALU: 510 bytes: Frame, NAL[1]={128,0,0,26}
// Frame 3 start so we can record/decode Frame 2
NALU: 506 bytes: Frame, NAL[1]={0,0,0,1}
NALU: 267 bytes: Frame, NAL[1]={0,0,0,0} // Start Frame 4 + END Frame 3
NALU: 535 bytes: Frame, NAL[1]={128,0,0,26}
// Frame 4 start so we can record/decode Frame 3
NALU: 527 bytes: Frame, NAL[1]={0,0,0,4}
NALU: 509 bytes: Frame, NAL[1]={0,0,0,3}
NALU: 508 bytes: Frame, NAL[1]={0,0,0,1}
NALU: 519 bytes: Frame, NAL[1]={0,0,0,0}
NALU: 327 bytes: Frame, NAL[1]={0,0,0,0} // END Frame 4
...

但是,似乎我遇到了一些流的麻煩。 對於每個NAL單元代表一個幀的流,如果我僅在下一次啟動時才解碼幀,則RTSP流似乎會丟失一些I幀。 我認為這是由於可能由於解碼時間而引起的同步問題,因為在直接接收到我解碼幀時不會發生問題。

這里是我直接解碼時的細節(一切正常):

NALU: 24 bytes: SPS, NAL[1]={0,64,0,13} // Start Frame 1
NALU: 4 bytes: PPS, NAL[1]={128,64,32,14}
NALU: 176124 bytes: Frame, NAL[1]={128,0,0,8}
// Decode Frame 1 OK
NALU: 24 bytes: SPS, NAL[1]={0,64,0,13}  // Start Frame 2
NALU: 4 bytes: PPS, NAL[1]={128,64,32,14}
NALU: 175605 bytes: I-Frame, NAL[1]={128,0,0,8}
// Decode Frame 2 OK
NALU: 38777 bytes: Frame, NAL[1]={128,0,0,26} // Start Frame 3
// Decode Frame 3 OK
NALU: 32188 bytes: Frame, NAL[1]={128,0,0,26} // Start Frame 4
// Decode Frame 4 OK
NALU: 24 bytes: SPS, NAL[1]={0,64,0,13} // Start Frame 5
NALU: 4 bytes: PPS, NAL[1]={128,64,32,14}
NALU: 175975 bytes: I-Frame, NAL[1]={128,0,0,8}
// Decode Frame 5 OK
NALU: 41681 bytes: Frame, NAL[1]={128,0,0,26} // Start Frame 6
// Decode Frame 6 OK

這是我在每幀開始后解碼時的詳細信息(某些幀未解碼):

NALU: 24 bytes: NAL[0]={0,3,7}, NAL[1]={0,64,0,13} // Start frame 1
NALU: 4 bytes: NAL[0]={0,3,8}, NAL[1]={128,64,32,14}
NALU: 177827 bytes: NAL[0]={0,3,1}, NAL[1]={128,0,0,8}
NALU: 24 bytes: NAL[0]={0,3,7}, NAL[1]={0,64,0,13} // Start frame 2 + End frame 1
// Decode Frame 1 OK
NALU: 4 bytes: NAL[0]={0,3,8}, NAL[1]={128,64,32,14}
NALU: 43304 bytes: NAL[0]={0,3,1}, NAL[1]={128,0,0,26}
NALU: 39115 bytes: NAL[0]={0,3,1}, NAL[1]={128,0,0,26} // Start frame 3 + End frame 2
// Decode Frame 2 OK
NALU: 24 bytes: NAL[0]={0,3,7}, NAL[1]={0,64,0,13} // Start frame 4 + End frame 3
// Decode Frame 3 OK
NALU: 4 bytes: NAL[0]={0,3,8}, NAL[1]={128,64,32,14} 
NALU: 49200 bytes: NAL[0]={0,3,1}, NAL[1]={128,0,0,26}
NALU: 41002 bytes: NAL[0]={0,3,1}, NAL[1]={128,0,0,26}  // Start frame 5 + End frame 4
// Decode Frame 4 failed
 NALU: 39581 bytes: NAL[0]={0,3,1}, NAL[1]={128,0,0,26}
// Decode Frame 5 failed

就像RTSP流(I-Frame)丟棄了某些幀一樣

所以我的問題是:

  • 您認為RTPS丟了一些幀嗎?
  • H.264解碼器是否期望某個延遲內到達的幀能夠正確解碼,同時遵守一些時間碼或類似的東西?
  • 我如何檢測NAL單元是圖片的最后一個,而不是等待下一個的開始。

謝謝您的幫助

首先,沒有“結束標志”。 僅附件B的起始代碼和其他格式的NALU大小(我相信RTP使用附件B)。 在H.264中,您所說的幀稱為訪問單元。 對於每個訪問單元,非視頻編碼層(非VCL)NALUS可選地位於VCL nalus之前。 因此,要確定是否擁有所有的VCL Nalu,必須分析每個NALU,以確定哪些宏塊被編碼到切片中。 通過使用從SPS解析的數據,您可以確定每幀可能有多少宏塊。 然后,一旦收到所有宏塊,就可以解碼該幀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM