gpt4 book ai didi

c++ - 如何知道代表一张图片的H.264流中NAL单元的数量

转载 作者:行者123 更新时间:2023-11-28 06:25:45 25 4
gpt4 key购买 nike

我正在使用带有 H.264 流的摄像机,通过 RTSP 解码,并使用 avcodec 进行解码。对于大多数相机,接收到的每个数据包(NAL 单元)代表一个完整的帧(I 帧或帧),当我对其进行解码时,我每次都会获得一个帧。但是对于另一个相机,一个帧被分成许多大小不变的 NAL 单元,当我解码每个数据包时,我没有得到每个数据包的帧。

我看到 NAL 单元中有开始和结束标志。除了 PPS 或 SPS 之外,永远不会设置结束标志。不过,我可以检测开始代码,并在新帧开始时告诉每个帧结束。

我想在单个帧内缓冲每个 NAL 单元,然后将其发送到解码器(这是为了记录功能和最小化帧索引)。

这里有一个例子(start_flags在NAL[1]字节中是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 帧)丢弃

所以我的问题是:

  • 您认为 RTPS 会掉帧吗?
  • H.264 解码器是否期望在延迟内到达的帧被正确解码,遵​​守一些时间码或类似的东西?
  • 如何检测 NAL 单元是图片的最后一个,而不是等待下一个的开始。

谢谢你的帮助

最佳答案

首先,没有“结束标志”。只有附件 B 的起始代码和其他格式的 NALU 大小(我相信 RTP 使用附件 B)。在 H.264 中,您所说的帧称为访问单元。对于每个非视频编码层(非 VCL)访问单元,NALUS 可选地位于 VCL nalus 之前。所以要确定你是否拥有所有的 VCL Nalus,你必须解析每个 NALU 以确定哪些宏 block 被编码到切片中。通过使用从 SPS 收到的解析数据,您可以确定每帧有多少个宏 block 。然后,一旦您收到所有宏 block ,就可以对帧进行解码。

关于c++ - 如何知道代表一张图片的H.264流中NAL单元的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28559529/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com