从海康7816的ps流里获取数据h264数据.docx
- 文档编号:1249716
- 上传时间:2022-10-19
- 格式:DOCX
- 页数:8
- 大小:18.44KB
从海康7816的ps流里获取数据h264数据.docx
《从海康7816的ps流里获取数据h264数据.docx》由会员分享,可在线阅读,更多相关《从海康7816的ps流里获取数据h264数据.docx(8页珍藏版)》请在冰豆网上搜索。
从海康7816的ps流里获取数据h264数据
从海康7816的ps流里获取数据h264数据
海康7816使用ps流来封装h.264数据,这里使用的解码器无法识别ps流,因此需要将h264数据从ps流里提取出来
对于ps流的规定可以参考13818-1文档
这里从7816里获取到一些数据取样
000001BA447326B83401000003FEFFFF00000001000001BC005AE0FF0024400E484B00010DAFC5D3E007FFFFFFFF4112484B00
000000000000000000000000000000002C1BE00010420E0000A02102C00240121FFF001C2191C0000C430A0000FE007D0303E803FFBDBD0000BFBF000000000000000001E000
1A8C800A211CC9AE0DFFFFFFFFFC000000016742001E95A82C0499000001E0000E8C0003
FFFFFC0000000168CE3C80000001E013FA8C0002FFFD。
。
。
如上是一个i帧的数据的开始部分,如下是一个非i帧的数据的开始部分
000001BA447327993401000003FEFFFF00000003000001E007128C800A211CC9E64DFFFFFFFFF8。
。
。
可见都是以000001BA开头,这是ps的包头(ProgramStreampackheader),其中000001是pack_start_code,是一个数据包的开始标识,接下来的1byte(BA)是流标识(stream_id),在文档13818-1的Table2-33和2.5.3.4节有ProgramStreampackheader的描述。
这里把上面i帧的的(ProgramStreampackheader列出来
000001BA447326B83401000003FEFFFF00000001
根据文档描述包头最少有14个字节,第14个字节的最后3bit说明了包头14字节后填充数据的长度,这里是pack_stuffing_length=FE&0x07=6,有6byte的填充数据,既是FF
FF00000001,海康7816使用这部分填充数据来说明每帧的序号,01说明是第1帧数据。
要注意的是包头可能还有系统标题头,id为bb,他也是包头的一部分,并且,他的长度并未算在pack_stufing_length里,比如:
000001BB000C80CCF504E17FE0E0E8C0C020
这里起始码后的000C说明了其后数据的长度,这里是12个字节
接在ProgramStreampackheader后的是以000001BC开始的一个包,000001是pack_start_code,BC是stream_id流标识,说明跟在ProgramStreampackheader后的是ProgramStreammap。
文档13818-1的Table2-35和2.5.4.2节有ProgramStreampackheader的描述。
跟在000001BC后的两位是说明了ProgramStreammap,他也是pes包的一种,包的长度program_stream_map_length,这里是005A,说明跟在其后的数据长度为90,跳过这其后的90byte数据是以000001E0开始的包,E表示是GB/TXXXX.2或GB/TAAAA.2视频流编号xxxx规格的pes包了,0表示流id为0,h264数据就在这个包里。
从ProgramStreammap里我们还能得知pes里的流是何种流(stream_type和elementary_stream_id表明),以及帧率()等
1110XXXX(0xex)表示视频数据,111XXXXX表示audio数据,其后的帧有关信息共5字节,2字节PES包长度是001A,表示此PES数据包的长度是0x001a即26字节;2字节标准位信息是8C80,5字节中的最后一字节表示附加数据长度是0A,跟在附加数据长度后的就是视频数据负载了。
pes包可以有多个,这里的i帧就把数据放到了多个pes包里,这里的非i帧就只有一个pes包
有了以上信息就已经可以从7816里剥离出h246数据了,更详细的说明请参考文档。
截取一段pes包头进行分析
000001E0001A8C800A211CC9AE0DFFFFFFFFFC
001A:
2字节表示长度,表示再这两个字节之后的数据长度(如果有附加数据包括了其后的附加数据,和负载数据,我们希望得到的是负载数据,因此要略过附加数据部分)
8C(10001100):
首先是固定值10,。
接下来的两位为(PES加扰控制字段)PES_scrambling_control,这里是00,表示没有加扰(加密)。
剩下的01,10,11由用户自定义。
接下来第4位为PES优先级字段(PES_priority),当为1时为高优先级,0为低优先级。
这里为1。
接下来第3位为(数据对齐指示符字段)PESdata_alignment_indicator,
接下来第2位为版权位,
接下来第1位为版权位,
80(10000000):
首先是PTS,DTS标志字段,这里是10,表示有PTS,没有DTS。
接下来第6位是ESCR标志字段,这里为0,表示没有该段
接下来第5位是ES速率标志字段,,这里为0,表示没有该段
接下来第4位是DSM特技方式标志字段,,这里为0,表示没有该段
接下来第3位是附加版权信息标志字段,,这里为0,表示没有该段
接下来第2位是PESCRC标志字段,,这里为0,表示没有该段
接下来第1位是PES扩展标志字段,,这里为0,表示没有该段
0A(10):
1个字节,指出包含在PES分组标题中的可选字段和任何填充字节所占用的总字节数(既是前面提到的附加数据)。
该字段之前的字节指出了有无可选字段(这里只有PTS)。
因为这里PTS,DTS标志字段是10,那就有5个字节的PTS段,就是这里的211CC9AE0D
最后的五个字节的FFFFFFFFFC是海康自己的一个自减计数值#pragmapack
(1)
unionlittel_endian_size
{
unsignedshortintlength;
unsignedcharbyte[2];
};
structpack_start_code
{
unsignedcharstart_code[3];
unsignedcharstream_id[1];
};
structprogram_stream_pack_header
{
pack_start_codePackStart;//4
unsignedcharBuf[9];
unsignedcharstuffinglen;
};
structprogram_stream_map
{
pack_start_codePackStart;
littel_endian_sizePackLength;//wemastdoexchange
//program_stream_info_length
//info
//elementary_stream_map_length
//elem
};
structprogram_stream_e
{
pack_start_codePackStart;
littel_endian_sizePackLength;//wemastdoexchange
charPackInfo1[2];
unsignedcharstuffing_length;
};
#pragmapack()
intinlineProgramStreamPackHeader(char*Pack,intlength,char**NextPack,int*leftlength)
{
//printf("[%s]%x%x%x%x\n",__FUNCTION__,Pack[0],Pack[1],Pack[2],Pack[3]);
//通过000001ba头的第14个字节的最后3位来确定头部填充了多少字节
program_stream_pack_header*PsHead=(program_stream_pack_header*)Pack;
unsignedcharpack_stuffing_length=PsHead->stuffinglen&'\x07';
*leftlength=length-sizeof(program_stream_pack_header)-pack_stuffing_length;//减去头和填充的字节
*NextPack=Pack+sizeof(program_stream_pack_header)+pack_stuffing_length;
if(*leftlength<4)return0;
//printf("[%s]2%x%x%x%x\n",__FUNCTION__,(*NextPack)[0],(*NextPack)[1],(*NextPack)[2],(*NextPack)[3]);
return*leftlength;
}
inlineintProgramStreamMap(char*Pack,intlength,char**NextPack,int*leftlength,char**PayloadData,int*PayloadDataLen)
{
//printf("[%s]%x%x%x%x\n",__FUNCTION__,Pack[0],Pack[1],Pack[2],Pack[3]);
program_stream_map*PSMPack=(program_stream_map*)Pack;
//nopayload
*PayloadData=0;
*PayloadDataLen=0;
if(length<sizeof(program_stream_map))return0;
littel_endian_sizepsm_length;
psm_length.byte[0]=PSMPack->PackLength.byte[1
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 7816 ps 获取 数据 h264