Video streaming 如何在H265/HEVC的RTP数据(通过UDP)中解除碎片帧的打包?
我正在尝试对原始RTP H265流进行解包并重建它,以便解码器可以读取它。 通过识别NAL和FU细节,我已经能够从RTP缓冲区中提取单个和碎片单元。但是,我找不到关于处理要放在碎片单元缓冲区前面的NAL的确切细节 以下是我的工作:Video streaming 如何在H265/HEVC的RTP数据(通过UDP)中解除碎片帧的打包?,video-streaming,rtp,hevc,video-codecs,h.265,Video Streaming,Rtp,Hevc,Video Codecs,H.265,我正在尝试对原始RTP H265流进行解包并重建它,以便解码器可以读取它。 通过识别NAL和FU细节,我已经能够从RTP缓冲区中提取单个和碎片单元。但是,我找不到关于处理要放在碎片单元缓冲区前面的NAL的确切细节 以下是我的工作: 当有效负载头类型为49时,我知道它是一个碎片单元 然后我查找第三个字节,其尾部的6个字节为FU type/NAL类型,前两位告诉您它是帧的开始还是结束片段。 以下是重建NAL的代码: if(类型==49){ 无符号字符fu_头=(无符号字符)*(rtpPayloadP
if(类型==49){
无符号字符fu_头=(无符号字符)*(rtpPayloadPos+2);
无符号字符fu_head_se=(fu_header&0xC0)>>6;
nal_type=fu_头&0x3F;
开关(前端){
案例0x02://nal开始
{
payloadType=RTP\u有效载荷\u FU\u启动\u H265\u NAL;
*h265DataPos=rtpPlayloadPos-3;
*(*h265DataPos)=0x00;
*((*h265DataPos)+1)=0x00;
*((*h265DataPos)+2)=0x00;
*((*h265DataPos)+3)=0x01;
*((*h265DataPos)+4)=(fu_headerRFC规范中包含了这方面的所有细节
要遵循的简单步骤:
删除12字节的RTP头和3字节的FU头
合并所有FU分组,直到找到/接收到来自视频编码帧的结束分组
组合的所有包(如果多个包形成一个帧)形成视频帧,可以将其馈送到解码器
感谢您的输入。我已经过了那个阶段。我已经将所有FU数据包合并并写入H265文件。但是当我在ffplay上查看此文件时,它会说:“cu_qp_delta-57超出了有效范围”。这看起来像是对PPS参数中QP范围的引用。但是,如果我使用ffplay直接从流中保存文件,并将我的文件与使用ffplay录制的文件进行比较,它们的VPS、SP和PPS看起来是相同的。但是由于某些原因,我的视频无法使用相同的ffplay正确播放。这使我认为我没有处理FU Info正确。确保编码器输出和解码器输入转储相同。您可以将它们转储到文件并进行二进制比较-验证是否相同。我修复了问题。问题是,在碎片单元的中间和最后一个切片中,我应该删除前三个字节,然后追加它们。但是,我删除了前两个字节太奇怪了,因为ffplay一直在抱怨cu_qp_delta让我偏离了轨道。谢谢@mail2subhajit的帮助
if(type == 49){
unsigned char fu_header = (unsigned char) *(rtpPayloadPos+2);
unsigned char fu_head_se = (fu_header & 0xC0) >> 6;
nal_type = fu_header & 0x3F;
switch(fu_head_se){
case 0x02: //nal start
{
payloadType = RTP_PAYLOAD_FU_START_H265_NAL;
*h265DataPos = rtpPlayloadPos-3;
*(*h265DataPos) = 0x00;
*((*h265DataPos)+1) = 0x00;
*((*h265DataPos)+2) = 0x00;
*((*h265DataPos)+3) = 0x01;
*((*h265DataPos)+4) = (fu_header << 1);
*((*h265DataPos)+5) = 0x01;
h265Len = len - headLen + 3;
}
break;
case 0x00: //nal middle
{
*h265DataPos = rtpPlayloadPos+2;
h265Len = len - headLen - 2;
payloadType = RTP_PAYLOAD_FU_MIDDLE_H265_NAL;
}
break;
case 0x01: //nal end
{
*h265DataPos = rtpPlayloadPos+2;
h265Len = len - headLen - 2;
payloadType = RTP_PAYLOAD_FU_END_H265_NAL;
}
break;
default:
printf("Unknown fu head\n");
return -1;
}