https://blog.csdn.net/zahngjialiang/article/details/69788885
java实现RTP的h264分包发送
下面是RTP实现FU-A分包方式的代码,其中每个包的大小是1400字节。注释比较全面,看代码就行:
private void sendData(byte[] r, int h264len)throws IOException {
memset(sendbuf, 0, 1500);
sendbuf[1] = (byte) (sendbuf[1] | 96);
sendbuf[0] = (byte) (sendbuf[0] | 0x80);
sendbuf[1] = (byte) (sendbuf[1] & 254);
sendbuf[11] = 10;
if (h264len <= packageSize) {
sendbuf[1] = (byte) (sendbuf[1] | 0x80);
System.arraycopy(intToByte(seq_num++), 0, sendbuf, 2, 2);
{
byte temp = 0;
temp = sendbuf[3];
sendbuf[3] = sendbuf[2];
sendbuf[2] = temp;
}
sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x80)) << 7);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) ((r[0] & 0x60) >> 5)) << 5);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x1f)));
System.arraycopy(r, 1, sendbuf, 13, h264len - 1);
ts_current = ts_current + timestamp_increse;
System.arraycopy(intToByte(ts_current), 0, sendbuf, 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 = h264len + 12;
client.send(new DatagramPacket(sendbuf, bytes, addr, port));
} else if (h264len > packageSize) {
int k = 0, l = 0;
k = h264len / packageSize;
l = h264len % packageSize;
int t = 0;
ts_current = ts_current + timestamp_increse;
System.arraycopy(intToByte(ts_current), 0, sendbuf, 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;
}
while (t <= k) {
System.arraycopy(intToByte(seq_num++), 0, sendbuf, 2, 2);
{
byte temp = 0;
temp = sendbuf[3];
sendbuf[3] = sendbuf[2];
sendbuf[2] = temp;
}
if (t == 0) {
sendbuf[1] = (byte) (sendbuf[1] & 0x7F);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x80)) << 7);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) ((r[0] & 0x60) >> 5)) << 5);
sendbuf[12] = (byte) (sendbuf[12] | (byte) (28));
sendbuf[13] = (byte) (sendbuf[13] & 0xBF);
sendbuf[13] = (byte) (sendbuf[13] & 0xDF);
sendbuf[13] = (byte) (sendbuf[13] | 0x80);
sendbuf[13] = (byte) (sendbuf[13] | ((byte) (r[0] & 0x1f)));
System.arraycopy(r, 1, sendbuf, 14, packageSize);
client.send(new DatagramPacket(sendbuf, packageSize+14, addr, port));
t++;
} else if (t == k) {
sendbuf[1] = (byte) (sendbuf[1] | 0x80);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x80)) << 7);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) ((r[0] & 0x60) >> 5)) << 5);
sendbuf[12] = (byte) (sendbuf[12] | (byte) (28));
sendbuf[13] = (byte) (sendbuf[13] & 0xDF);
sendbuf[13] = (byte) (sendbuf[13] & 0x7F);
sendbuf[13] = (byte) (sendbuf[13] | 0x40);
sendbuf[13] = (byte) (sendbuf[13] | ((byte) (r[0] & 0x1f)));
if (0 != l) {
System.arraycopy(r, t * packageSize + 1, sendbuf, 14, l - 1);
bytes = l - 1 + 14;
client.send(new DatagramPacket(sendbuf, bytes, addr, port));
}
t++;
} else if (t < k && 0 != t) {
sendbuf[1] = (byte) (sendbuf[1] & 0x7F);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x80)) << 7);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) ((r[0] & 0x60) >> 5)) << 5);
sendbuf[12] = (byte) (sendbuf[12] | (byte) (28));
sendbuf[13] = (byte) (sendbuf[13] & 0xDF);
sendbuf[13] = (byte) (sendbuf[13] & 0x7F);
sendbuf[13] = (byte) (sendbuf[13] & 0xBF);
sendbuf[13] = (byte) (sendbuf[13] | ((byte) (r[0] & 0x1f)));
System.arraycopy(r, t * packageSize + 1, sendbuf, 14, packageSize);
client.send(new DatagramPacket(sendbuf, packageSize+14, addr, port));
t++;
}
}
}
}
其他的参数和代码:
private byte[] sendbuf=new byte[1500];
private int packageSize=1400;
private int seq_num = 0;
private timestamp_increse=(int)(90000.0/framerate);
private int ts_current=0;
private int bytes=0;
public void memset(byte[] buf, int value, int size) {
for (int i = 0; i < size; i++) {
buf[i] = (byte) value;
}
}
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;
}