低延时高RTSP兼容的EasyPlayer-RTSP-win解决H.264一帧多个nal单元录像花屏问题方案
2021-05-19 08:27
标签:writer 标准 信道 情况 iter 来讲 信息 比较 bsp EasyPlayer-RTSP-win解决H264一帧多个nal单元录像花屏问题 我们来讲解一下关于H264编码格式中的一帧多nal(Network Abstract Layer, 即网络抽象层),关于H264和NAL,这里引用一段话来科普一下: 【转】 在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。因此我们平时的每帧数据就是一个NAL单元(SPS与PPS除外)。在实际的H264数据帧中,往往帧前面带有00 00 00 01 或 00 00 01分隔符,一般来说编码器编出的首帧数据为PPS与SPS,接着为I帧…… 一般情况下,一个H264帧直接以00 00 00 01开头作为一个NAL作为网络传输单元,而在有些H264的编码器则编码出来的H264帧包含了多个NAL,这个时候每个分片的NAL(注意是分片的)则是是以00 00 01开头作为网络传输单元,经过分片的NAL数据量更小,从而更加方便进行网络;但是,我们在接收到带有多个NAL的H264帧的时候进行写MP4则不能简单是只通过将头部的00 00 00 01标志转换从AVC的长度标识,而需要将所有的00 00 00 01和00 00 01都需要转换成该NAL单元的长度,否则就会出现视频解码只能播放头部一小部分,其他部分全部花屏的情况,如下图所示: 说了这么多,大家是否明白了呢,如果不明白的(文字描述比较虚),我们直接看EasyPlayer代码实现: 其中find_nal_unit()函数是从H264帧中分析出以00 00 00 01和00 00 01开头的NAL单元,然后直接填充成该NAL单元的长度,注意字节顺序为大端顺序: 将NAL长度拷贝到AVC的缓冲区内,紧接着数据部分拷贝: 低延时高RTSP兼容的EasyPlayer-RTSP-win解决H.264一帧多个nal单元录像花屏问题方案 标签:writer 标准 信道 情况 iter 来讲 信息 比较 bsp 原文地址:https://www.cnblogs.com/TSINGSEE/p/11714029.html
int EasyMP4Writer::WriteMp4File(unsigned char* pdata, int datasize, bool keyframe, long nTimestamp, int nWidth, int nHeight)
{
if (nTimestamp==0||(pdata==NULL)||datasize=0; nI--)
{
if (m_ppps[nI] == 0x00)
{
nZeroCount++;
}
else
{
break;
}
}
m_ppslen = m_ppslen-nZeroCount;
WriteH264SPSandPPS(m_psps,m_spslen,m_ppps,m_ppslen,nWidth,nHeight);
m_bwritevideoinfo = true;
}
if (m_bwritevideoinfo==false||nRealDataSize
//写入头4个字节==nal内容的长度(H264数据的长度)unsigned char byte0 = pRealData[nRealDataSize+3];
unsigned char byte1 = pRealData[nRealDataSize+2];
pRealData[nRealDataSize+3] = pRealData[nRealDataSize+0];
pRealData[nRealDataSize+2] = pRealData[nRealDataSize+1];
pRealData[nRealDataSize+1] = byte1;
pRealData[nRealDataSize+0] = byte0;
memcpy(pRealData+nRealDataSize, pout, outlen);
最后,组装成完成的avc帧之后写入MP4,播放的时候就不会有花屏、马赛克的情况出现了。
上一篇:PHP下载压缩包文件
文章标题:低延时高RTSP兼容的EasyPlayer-RTSP-win解决H.264一帧多个nal单元录像花屏问题方案
文章链接:http://soscw.com/index.php/essay/87569.html