import java.io.*;
import java.net.*;
public class MyTest
{
// 主函数
public static void main(String arg[]) throws IOException
{
//String fileName = "F:/test22.264";
String fileName = "F:/camera.h264";
InitSocket();
//ReadFromFile.readFileByBytes(fileName);
file = new File(fileName);
in = new FileInputStream(file);
int seq_num = 0;
int bytes=0;
// 时间戳增量
float framerate = 25;
int timestamp_increse=0,ts_current=0;
timestamp_increse=(int)(90000.0 / framerate); //+0.5);
// rtp包缓冲
byte[] sendbuf = new byte[1500];
while(!(0 == in.available())) {
NALU_t n = new NALU_t();
GetAnnexbNALU(n); // 每执行一次, 文件指针指向本次找到的NALU的末尾, 下一位置即为下个NALU的起始码0x000001
dump(n);//输出NALU的长度和NALU
// 从文件中 获取一个nalu大小
// 判断其大小 分包发送
memset(sendbuf,0,1500);//情况sendbuf,此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值
sendbuf[1] = (byte)(sendbuf[1]|96); // 负载类型号96
//System.out.println("-----!"+sendbuf[1]);
sendbuf[0] = (byte)(sendbuf[0]|0x80); // 版本号,此版本固定为2
sendbuf[1] = (byte)(sendbuf[1]&254); //标志位,由具体协议规定其值
sendbuf[11] = 10; //随即指定10,并在本RTP回话中全局唯一,java默认采用网络字节序号 不用转换
if(n.len <= 1400)
{
sendbuf[1] = (byte)(sendbuf[1]|0x80); // 设置rtp M位为1
//sendbug[2], sendbuf[3]赋值seq_num ++ 每发送一次rtp包增1
//sendbuf[3] = (byte) seq_num ++
System.arraycopy(intToByte(seq_num++), 0, sendbuf, 2, 2);
{
// 倒序
byte temp = 0;
temp = sendbuf[3];
sendbuf[3] = sendbuf[2];
sendbuf[2] = temp;
}
// 设置NALU HEADER, 并将这个HEADER填入sendbuf[12]
sendbuf[12] = (byte)(sendbuf[12]|((byte)n.forbidden_bit)<<7);
sendbuf[12] = (byte)(sendbuf[12]|((byte)(n.nal_reference_idc>>5))<<5);
sendbuf[12] = (byte)(sendbuf[12]|((byte)n.nal_unit_type));
// 同理将sendbuf[13]赋给nalu_payload
System.arraycopy(n.buf, 1, sendbuf, 13, n.len-1);//去掉nalu头的nalu剩余类容写入sendbuf[13]开始的字符串
ts_current = ts_current+timestamp_increse;
//rtp_hdr.timestamp = ts_current;// htonl(ts_current) java默认网络字节序
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 = n.len + 12 ; //获sendbuf的长度,为nalu的长度(包含nalu头但取出起始前缀,加上rtp_header固定长度12个字节)
Send(sendbuf, bytes);//发送rtp包
}
else if(n.len > 1400)
{
// 得到该nalu需要用多少长度为1400字节的rtp包来发送
int k = 0, l = 0;
k = n.len/1400; //需要k个1400字节的rtp包
l = n.len%1400; //最后一个rtp包需要装载的字节数
int t = 0; // 用于指示当前发送的第几个分片RTP包
ts_current = ts_current + timestamp_increse;
//rtp_hdr->timestamp=htonl(ts_current);
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)
{
//rtp_hdr->seq_no = htons(seq_num ++);//序列号, 每发送一个rtp包增加1
//sendbuf[3] = (byte) seq_num ++;
System.arraycopy(intToByte(seq_num++), 0, sendbuf, 2, 2);
{
// 倒序
byte temp = 0;
temp = sendbuf[3];
sendbuf[3] = sendbuf[2];
sendbuf[2] = temp;
}
if(0 == t)
{
// 设置rtp M位
sendbuf[1] = (byte)(sendbuf[1]&0x7F); // M=0
// 设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
sendbuf[12] = (byte)(sendbuf[12]|((byte)n.forbidden_bit)<<7);
sendbuf[12] = (byte)(sendbuf[12]|((byte)(n.nal_reference_idc>>5))<<5);
sendbuf[12] = (byte)(sendbuf[12]|(byte)(28));
// 设置FU HEADER,并将这个HEADER填入snedbuf[13]
sendbuf[13] = (byte)(sendbuf[13]&0xBF);//E=0
sendbuf[13] = (byte)(sendbuf[13]&0xDF);//R=0
sendbuf[13] = (byte)(sendbuf[13]|0x80);//S=1
sendbuf[13] = (byte)(sendbuf[13]|((byte)n.nal_unit_type));
// 同理将sendbuf[14]赋给nalu_playload
System.arraycopy(n.buf, 1, sendbuf, 14, 1400);
bytes = 1400 + 14;
Send(sendbuf, bytes);
t++;
}
// 发送一个需要分片的NALU的非第一个分片,清零FU HEADER 的S位,如果该分片是该NALU的最后一个分片,置FU HEADER的E位
else if(k == t) //发送的是最后一个分片,注意最后一个分片的长度可能超过1400字节(当l>1386时)
{
// 设置rtp M位,当前床书的是最后一个分片时该位置1
sendbuf[1] = (byte)(sendbuf[1]|0x80);
// 设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
sendbuf[12] = (byte)(sendbuf[12]|((byte)n.forbidden_bit)<<7);
sendbuf[12] = (byte)(sendbuf[12]|((byte)(n.nal_reference_idc>>5))<<5);
sendbuf[12] = (byte)(sendbuf[12]|(byte)(28));
//设置FU HEADER,并将这个HEADER填入sendbuf[13]
sendbuf[13] = (byte) (sendbuf[13]&0xDF); //R=0
sendbuf[13] = (byte) (sendbuf[13]&0x7F); //S=0
sendbuf[13] = (byte) (sendbuf[13]|0x40); //E=1
sendbuf[13] = (byte) (sendbuf[13]|((byte)n.nal_unit_type));
// 将nalu的最后神域的l-1(去掉了一个字节的nalu头)字节类容写入sendbuf[14]开始的字符串
System.arraycopy(n.buf, t*1400+1, sendbuf, 14, l-1);
bytes = l-1+14;
Send(sendbuf, bytes);
t++;
}
else if(t < k && 0 !=t)
{
//设置rtp M位
sendbuf[1] = (byte)(sendbuf[1]&0x7F); // M=0
// 设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
sendbuf[12] = (byte)(sendbuf[12]|((byte)n.forbidden_bit)<<7);
sendbuf[12] = (byte)(sendbuf[12]|((byte)(n.nal_reference_idc>>5))<<5);
sendbuf[12] = (byte)(sendbuf[12]|(byte)(28));
//设置FU HEADER,并将这个HEADER填入sendbuf[13]
sendbuf[13] = (byte) (sendbuf[13]&0xDF); //R=0
sendbuf[13] = (byte) (sendbuf[13]&0x7F); //S=0
sendbuf[13] = (byte) (sendbuf[13]&0xBF); //E=0
sendbuf[13] = (byte) (sendbuf[13]|((byte)n.nal_unit_type));
System.arraycopy(n.buf, t*1400+1, sendbuf, 14, 1400);//去掉起始前缀的nalu剩余内容写入sendbuf[14]开始的字符串。
bytes=1400+14; //获得sendbuf的长度,为nalu的长度(除去原NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
Send(sendbuf, bytes);//发送rtp包
t++;
}
}
}
}
//free nalu
}
public static FileInputStream in = null;
/**
* 注释:int到字节数组的转换!
*
* @param number
* @return
*/
public static byte[] intToByte(int number) {