aac音频数据的rtp封包过程(android)

【记录备忘】

对一段aac进行rtp封包,过程比较简单:

  1. 需要将aac的ADTS去掉;
  2. 添加12字节的rtp报头;
  3. 添加2字节的AU_HEADER_LENGTH;
  4. 添加2字节的AU_HEADER;
  5. 从第17字节开始就是payload(去掉ADTS的aac数据)数据了

下面附上代码

private UdpSocket udpSocket = null;
private byte[] sendbuf=new byte[1500];
private int seq_num = 0;//rtp包的序列号
private int timestamp_increse=(int)(96);//时间戳间隔
private static int ts_current=0;
private int bytes=0;
//data是已经去掉ADTS的数据,len是data的长度
public void sendRTPData(byte[] data, int len)throws IOException {
        memset(sendbuf, 0, 1500);
        sendbuf[1] = (byte) (sendbuf[1] | 96); // 负载类型号96,其值为:01100000
        sendbuf[0] = (byte) (sendbuf[0] | 0x80); // 版本号,此版本固定为2
        sendbuf[1] = (byte) (sendbuf[1] & 254); //标志位,由具体协议规定其值,其值为:01100000
        sendbuf[11] = 10;//随机指定10,并在本RTP回话中全局唯一,java默认采用网络字节序号 不用转换(同源标识符的最后一个字节)
        sendbuf[1] = (byte) (sendbuf[1] | 0x80); // 设置rtp M位为1,其值为:11100000,分包的最后一片,M位(第一位)为0,后7位是十进制的96,表示负载类型
        System.arraycopy(intToByte(seq_num++), 0, sendbuf, 2, 2);//send[2]和send[3]为序列号,共两位
        {
            // java默认的网络字节序是大端字节序(无论在什么平台上),因为windows为小字节序,所以必须倒序
            /**参考:
             * http://blog.csdn.net/u011068702/article/details/51857557
             * http://cpjsjxy.iteye.com/blog/1591261
             */
            byte temp = 0;
            temp = sendbuf[3];
            sendbuf[3] = sendbuf[2];
            sendbuf[2] = temp;
        }
        //AU_HEADER
        sendbuf[12] = 0x0;
        sendbuf[13] = 0x10;
        //AU_HEADER_LENGTH
        sendbuf[14] = (byte)((len & 0xff) >> 5);
        sendbuf[15] = (byte)((len & 0xff) << 3);
        // 同理将sendbuf[17]赋给nalu_payload
        System.arraycopy(data, 0, sendbuf, 16,  len);
        ts_current = ts_current + timestamp_increse;
        System.arraycopy(intToByte(ts_current), 0, sendbuf, 4, 4);//序列号接下来是时间戳,4个字节,存储后也需要倒序
        {
            byte temp = 0;
            temp = sendbuf[4];
            sendbuf[4] = sendbuf[7];
            sendbuf[7] = temp;
            temp = sendbuf[5];
            sendbuf[5] = sendbuf[6];
            sendbuf[6] = temp;
        }
        bytes = len + 16;//获sendbuf的长度
        udpSocket.datagramSend(sendbuf, bytes);//将封装好的rtp包发送出去
    }
    //返回的是4个字节的数组。
    public byte[] intToByte(int number) {
        int temp = number;
        byte[] b = new byte[4];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Integer(temp & 0xff).byteValue();
            temp = temp >> 8;
        }
        return b;
    }

aac封包不需要做FU-A分包了,直接一个包发送(h264则需要考虑分包处理)。

你可能感兴趣的:(aac音频数据的rtp封包过程(android))