如何知道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单元发送到解码器之前,在单个帧内对其进行缓冲(这是为了记录功能并最小化帧索引)。
这里是一个例子(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,以确定哪些宏块被编码到切片中。通过使用您从SPS接收到的解析数据,您可以确定每帧有多少宏块。然后,一旦你收到了所有的宏块,你就可以解码帧。
- 什么时候调用组成单元对象的析构函数
- 不同翻译单元中不可重载的非内联函数定义
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 将QIcon添加到QTableView单元格
- 用于交叉编译和CMake的预处理器宏的单元测试
- 当用户在qtablewidget中输入单元格时,如何获得信号?C++
- 字节真的是最小可寻址单元吗
- C++ 用于单元测试的模板模板
- 为什么未命名的结构内联变量在每个翻译单元中没有相同的地址?
- 提升 1.64 单元测试编译失败
- boost::包含提升单元的元组的哈希值
- 单元测试欧拉到四元数实现失败
- 查找矩阵中单元格的相邻元素
- 运行 C++ 单元测试时LNK2005链接错误
- 禁用自动捕获 Googletest 单元测试中的C++异常
- 我想知道如何使用C编程来识别HEVC流中的NAL单元
- 如何知道H.264流中表示图片的NAL单元的数量
- x264/avcodec:从 NAL 单元推断帧序列号