淘先锋技术网

首页 1 2 3 4 5 6 7

GB28181音视频这块基本都需要PS,PS的打包和解析非常重要,GB28181文档只给出了打包纯视频或音视频一起打包的的说明,没有给出单独打包纯音频的说明,在实际场景中,特别是语音广播,语音对讲, PS打包纯音频很常见. 有些pts的clock frequency 也不是90000,我遇到过8000的,1000的都有.

GB28181给出的PS打包方式如下:

包头

系统头

PSM

PESV

PESA

但GB28181标准没给出纯音频的PS打包方式,由于没有说明,实现方式多种多样,下面给出一种比较容易解析的实现方式:

包头

系统头

PSM

PESA

包头(pack header),系统头( system header ), PSM, PES详细描述请参考ISO/IEC 13818-1 .

在PS流中,包头,系统头,PSM, PES包前三个字节都是0x00, 0x00, 0x01。pack header(包头)的start code是0x00, 0x00, 0x01, 0xBA; system header (系统头)的start code是0x00, 0x00, 0x01, 0xBA;PSM(Program Stream map )的start code是0x00, 0x00, 0x01, 0xBC; PES packet的start code是0x00, 0x00, 0x01, 八位的流ID(GB28181中规定视频的流ID是0xE0, 音频的流ID是0xC0)。

另外用PS打包纯音频,SDP描述中"m"字段的"media"项:audio.

rtp payload type 还是96.

rtp时钟频率标准是90hHz, 实际环境中也有其他值,比如1kHz.

下面是一个rtp over udp PS传输纯音频SDP例子:

v=0
s=Play
c=IN IP4 192.168.0.173
t=0 0
m=audio 27360 RTP/AVP 96
a=rtpmap:96 PS/90000
a=sendonly

我的代码对外提供的PS解析接口如下:

    // Copyright (C) [email protected]
   
    /**
     *设置 RTP Receiver Payload 相关信息
     *
     * @param rtp_receiver_handle, CreateRTPReceiver
     *
     * @param payload_type, 请参考 RFC 3551
     *
     * @param encoding_name, 编码名, 请参考 RFC 3551, 如果payload_type不是动态的, 传null就好
     *
     * @param media_type, 媒体类型, 请参考 RFC 3551, 1 是视频, 2是音频
     *
     * @param clock_rate, 请参考 RFC 3551
     *
     * @return {0} if successful
     */
    public native int SetRTPReceiverPayloadType(long rtp_receiver_handle, int payload_type, String encoding_name, int media_type, int clock_rate);

    /**
     *设置RTP Receiver PS的pts和dts clock frequency
     *
     * @param rtp_receiver_handle, CreateRTPReceiver
     *
     * @param ps_clock_frequency, 默认是90000, 用于一些PS流不是用90000打包的时间戳
     *
     * @return {0} if successful
     */
    public native int SetRTPReceiverPSClockFrequency(long rtp_receiver_handle, int payload_type, int ps_clock_frequency);

    /**
     *清除RTP Receiver PS解析器配置的PSM, PSM具体清参考PS协议
     *
     * @param rtp_receiver_handle, CreateRTPReceiver
     *
     * @return {0} if successful
     */
    public native int ClearRTPReceiverPSMap(long rtp_receiver_handle, int payload_type);

    
    /**
     *设置RTP Receiver PS解析器的PSM, 有些PS流解析时需要设置, PSM具体清参考PS协议
     *
     * @param rtp_receiver_handle, CreateRTPReceiver
     *
     * @param stream_type, 流类型
     *
     * @param elementary_stream_id, 流id
     *
     * @return {0} if successful
     */
    public native int SetRTPReceiverPSMap(long rtp_receiver_handle, int payload_type, int stream_type, int elementary_stream_id);

实际中遇到PS打包纯音频,如果只是求打包成PS,不会太麻烦的按基本规则来就好,解析会比较麻烦了,各种形式都有,解析代码实现上成本高些。