安防视频监控系统视频上云解决方案EasyCVR语音转发功能音频数据打包发送流程介绍

时间:2022-07-25
本文章向大家介绍安防视频监控系统视频上云解决方案EasyCVR语音转发功能音频数据打包发送流程介绍,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

目前TSINGSEE青犀视频的视频上云服务平台EasyCVR已经可集成海康EHome私有协议,并且在前文中我也跟大家讲过EHome协议的配置和调用流程,有兴趣的可以阅读一下:配置及协议介绍Ehome协议调用流程介绍

EasyCVR语音转发功能音频数据打包发送流程

1、数据整体结构见下图

2、ps 文件头

int gb28181_make_ps_header(char *pData, unsigned long long s64Scr)
{
    unsigned long long lScrExt = (s64Scr) % 100;
    s64Scr = s64Scr / 100;
    bits_buffer_t      bitsBuffer;
    bitsBuffer.i_size = PS_HDR_LEN;
    bitsBuffer.i_data = 0;
    bitsBuffer.i_mask = 0x80;
    bitsBuffer.p_data =    (unsigned char *)(pData);
    memset(bitsBuffer.p_data, 0, PS_HDR_LEN);
    bits_write(&bitsBuffer, 32, 0x000001BA);            /*start codes 起始码*/
    bits_write(&bitsBuffer, 2,     1);                        /*marker bits '01b'*/
    bits_write(&bitsBuffer, 3,     (s64Scr>>30)&0x07);     /*System clock [32..30]*/
    bits_write(&bitsBuffer, 1,     1);                               /*marker bit*/
    bits_write(&bitsBuffer, 15, (s64Scr>>15)&0x7FFF);   /*System clock [29..15]*/
    bits_write(&bitsBuffer, 1,     1);                            /*marker bit*/
    bits_write(&bitsBuffer, 15, s64Scr & 0x7fff);        /*System clock [14..0]*/
    bits_write(&bitsBuffer, 1,     1);                        /*marker bit*/
    bits_write(&bitsBuffer, 9,     0);                     /*SCR extension*/
    bits_write(&bitsBuffer, 1,     1);                        /*marker bit*/
    bits_write(&bitsBuffer, 22, (255)&0x3fffff);        /*bit rate(n units of 50 bytes per second.)*/
    bits_write(&bitsBuffer, 2,     3);                        /*marker bits '11'*/
    bits_write(&bitsBuffer, 5,     0x1f);                    /*reserved(reserved for future use)*/
    bits_write(&bitsBuffer, 3,     0);                        /*stuffing length*/
    return 0;
}

包起始码字段 pack_start_code 值为’0000 0000 0000 0000 0000 0001 1011 1010’ (0x000001BA)的位串,用来标志一个包的开始

系统时钟参考字段 system_clock_reference_base 和 system_clock_reference_extenstion

标记位字段 marker_bit 1位字段,固定值 ‘1’

节目复合速率字段 program_mux_rate 一个22位整数,规定P-STD在包含该字段的包期间接收节目流的速率,其值以50字节/秒为单位,不允许取0值

包填充长度字段 pack_stuffing_length 3位整数,规定该字段后填充字节的个数

填充字节字段 stuffing_byte 8位字段,取值恒为’1111 1111’

3、ps系统信息

system_header_start_code 系统标题起始码字段32 位字段,取值’0000 0000 0000 0000 0000 0001 1011 1011’ (0x000001BB)的位串,指出系统标题的开始

header_length 标题长度字段16位字段。指出该字段后的系统标题的字节长度。在本规范将来的扩充中可能扩展该字段

marker_bit 占位1bit, 固定值为 1

rate_bound 速率界限字段22位字段,取值不小于编码在节目流的任何包中的program_mux_rate字段的最大值。该字段可被解码器用于估计是否有能力对整个流解码

marker_bit 占位1bit, 固定值为 1

audio_bound 音频界限字段6位字段,取值是在从0到32的闭区间中的整数,且不小于节目流中解码过程同时活动的GB/T XXXX.3和GB/T AAAA.3音频流的最大数目

fixed_flag 固定标志字段1位标志位。置’1’时表示比特率恒定的操作;置’0’时,表示操作的比特率可变

CSPS_flag CSPS标志字段1位字段。置’1’时,节目流符合标准

system_audio_lock_flag 系统音频锁定标志字段1位字段。表示在系统目标解码器的音频采样率和system_clock_frequency之间存在规定的比率

system_video_lock_flag 系统视频锁定标志字段1位字段。表示在系统目标解码器的视频帧速率和system_clock_frequency之间存在规定的比率

marker_bit 占位1bit, 固定值为 1

vedio_bound 视频界限字段5位字段,取值是在从0到16的闭区间中的整数且不小于节目流中解码过程同时活动的GB/T XXXX.2和GB/T AAAA.2流的最大数目

packet_rate_restriction_flag 分组速率限制标志字段1位标志位。若CSPS标识为’1’,则该字段表示2.7.9中规定的哪个限制适用于分组速率。若CSPS标识为’0’,则该字段的含义未定义。

reserved_bits 保留位字段,7位字段。固定值应为’111 1111’定

stream_id 流标识字段8位字段。指示其后的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段所涉及的流的编码和基本流号码。若取值’1011 1000’,则其后的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段指节目流中所有的音频流;若取值’1011 1001’,则其后的P-STD_buffer_bound_scale和P-STD_buffer_size_bound字段指节目流中所有的视频流

P-STD_buffer_bound_scale P-STD缓冲区界限比例字段1位字段。表示用于解释后续P-STD_buffer_size_bound字段的比例系数。若前面的stream_id表示一个音频流,则该字段值为’0’。若表示一个视频流,则该字段值为’1’。对于所有其它的流类型,该字段值可以为’0’也可以为’1’

P-STD_buffer_size_bound P-STD缓冲区大小界限字段13位无符号整数,取值不小于节目流中流n的所有分组的P-STD缓冲区大小BSn的最大值。若P-STD_buffer_bound_scale的值为’0’,则该字段以128字节为单位来度量缓冲区大小的边界

4、psm 信息

packet_start_code_prefix 分组起始码前缀字段24位码。它和跟随其后的map_stream_id共同组成一个分组起始码以标志分组的开始。该字段是值为’0000 0000 0000 0000 0000 0001’ (0x000001)的位串

map_stream_id 映射流标识字段8位字段,值为0xBC

program_stream_map_length 节目流映射长度字段16位字段。指示紧跟在该字段后的program_stream_map中的字节数

current_next_indicator 当前下一个指示符字段1位字段。置’1’时表示传送的节目流映射当前是可用的。置’0’时表示传送的节目流映射还不可用,但它将是下一个生效的表

reserved 保留字段 2位

program_stream_map_version 节目流映射版本字段5位字段,表示整个节目流映射的版本号。一旦节目流映射的定义发生变化,该字段将递增1,并对32取模。在current_next_indicator为’1’时,该字段应该是当前适用的节目流映射的版本号;在current_next_indicator为’0’时,该字段应该是下一个适用的节目流映射的版本号

reserved 保留字段 7位

marker_bit 标志位 , 1位字段,取值为’1’

program_stream_info_length 节目流信息长度字段16位字段,指出紧跟在该字段后的描述符的总长度

elementary_stream_map_length 基本流映射长度字段16位字段,指出在该节目流映射中的所有基本流信息的字节长度。它只包括stream_type、elementary_stream_id和elementary_stream_info_length字段

stream_type 流类型字段 MPEG-4 视频流: 0x10; H.264 视频流: 0x1B; SVAC 视频流: 0x80; G.711 音频流: 0x90; G.722.1 音频流: 0x92; G.723.1 音频流: 0x93; G.729 音频流: 0x99; SVAC音频流: 0x9B。

elementary_stream_id 基本流标识字段8位字段,指出该基本流所在PES分组的PES分组标题中stream_id字段的值。(这个字段的定义,其中0x(C0DF)指音频,0x(E0EF)为视频)

elementary_stream_info_length 基本流信息长度字段16位字段,指出紧跟在该字段后的描述符的字节长度。(即这个类型的流描述长度。这个后面的字段后面的指定长度不在elementary_stream_map_length指定的范围类。)

CRC_32 CRC 32字段

32位字段,它包含CRC值以在处理完整个节目流映射后在附录A中定义的解码器寄存器产生0输出值

5、pes数据

int gb28181_make_pes_header(char *pData, int stream_id, int payload_len, unsigned long long pts, unsigned long long dts)
{
 
    bits_buffer_t      bitsBuffer;
    bitsBuffer.i_size = PES_HDR_LEN;
    bitsBuffer.i_data = 0;
    bitsBuffer.i_mask = 0x80;
    bitsBuffer.p_data =    (unsigned char *)(pData);
    memset(bitsBuffer.p_data, 0, PES_HDR_LEN);
    /*system header*/
    bits_write( &bitsBuffer, 24,0x000001);    /*start code*/
    bits_write( &bitsBuffer, 8, (stream_id));    /*streamID*/
    bits_write( &bitsBuffer, 16,(payload_len)+13);    /*packet_len pes剩余头部以及后面的es长度之和,比如SPS长度+13*/
    bits_write( &bitsBuffer, 2, 2 );        /*'10'*/
    bits_write( &bitsBuffer, 2, 0 );        /*scrambling_control*/
    bits_write( &bitsBuffer, 1, 1 );        /*priority*/
    bits_write( &bitsBuffer, 1, 1 );        /*data_alignment_indicator*/
    bits_write( &bitsBuffer, 1, 0 );        /*copyright*/
    bits_write( &bitsBuffer, 1, 0 );        /*original_or_copy*/
    bits_write( &bitsBuffer, 1, 1 );        /*PTS_flag 是否有PTS*/
    bits_write( &bitsBuffer, 1, 1 );        /*DTS_flag 是否有DTS信息*/
    bits_write( &bitsBuffer, 1, 0 );        /*ESCR_flag*/
    bits_write( &bitsBuffer, 1, 0 );        /*ES_rate_flag*/
    bits_write( &bitsBuffer, 1, 0 );        /*DSM_trick_mode_flag*/
    bits_write( &bitsBuffer, 1, 0 );        /*additional_copy_info_flag*/
    bits_write( &bitsBuffer, 1, 0 );        /*PES_CRC_flag*/
    bits_write( &bitsBuffer, 1, 0 );        /*PES_extension_flag*/
    bits_write( &bitsBuffer, 8, 10);        /*header_data_length*/
 
    /*PTS,DTS*/
    bits_write( &bitsBuffer, 4, 3 );                    /*'0011'*/
    bits_write( &bitsBuffer, 3, ((pts)>>30)&0x07 );     /*PTS[32..30]*/
    bits_write( &bitsBuffer, 1, 1 );
    bits_write( &bitsBuffer, 15,((pts)>>15)&0x7FFF);    /*PTS[29..15]*/
    bits_write( &bitsBuffer, 1, 1 );
    bits_write( &bitsBuffer, 15,(pts)&0x7FFF);          /*PTS[14..0]*/
    bits_write( &bitsBuffer, 1, 1 );
    bits_write( &bitsBuffer, 4, 1 );                    /*'0001'*/
    bits_write( &bitsBuffer, 3, ((dts)>>30)&0x07 );     /*DTS[32..30]*/
    bits_write( &bitsBuffer, 1, 1 );
    bits_write( &bitsBuffer, 15,((dts)>>15)&0x7FFF);    /*DTS[29..15]*/
    bits_write( &bitsBuffer, 1, 1 );
    bits_write( &bitsBuffer, 15,(dts)&0x7FFF);          /*DTS[14..0]*/
    bits_write( &bitsBuffer, 1, 1 );
    return 0;
}