2,541
社区成员
发帖
与我相关
我的任务
分享
private void SendR(byte[] r,int h264len)throws IOException {
//showMessage("in send rtp");
codecTotal += h264len;
Log.d(TAG,"SendR:"+h264len);
memset(sendbuf, 0, 1500);
sendbuf[1] = (byte) (sendbuf[1] | 96); // 负载类型号96
sendbuf[0] = (byte) (sendbuf[0] | 0x80); // 版本号,此版本固定为2
sendbuf[1] = (byte) (sendbuf[1] & 254); //标志位,由具体协议规定其值
sendbuf[11] = 10;//随即指定10,并在本RTP回话中全局唯一,java默认采用网络字节序号 不用转换
if (h264len <= packageSize) {
sendbuf[1] = (byte) (sendbuf[1] | 0x80); // 设置rtp M位为1
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) (r[0] & 0x80)) << 7);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) ((r[0] & 0x60) >> 5)) << 5);
sendbuf[12] = (byte) (sendbuf[12] | ((byte) (r[0] & 0x1f)));
// 同理将sendbuf[13]赋给nalu_payload
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;//获sendbuf的长度,为nalu的长度(包含nalu头但取出起始前缀,加上rtp_header固定长度12个字节)
client.send(new DatagramPacket(sendbuf, bytes, addr, port/*9200*/));
//send(sendbuf,bytes);
} 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);//E=0
sendbuf[13] = (byte) (sendbuf[13] & 0xDF);//R=0
sendbuf[13] = (byte) (sendbuf[13] | 0x80);//S=1
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/*9200*/));
//send(sendbuf,1414);
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); //R=0
sendbuf[13] = (byte) (sendbuf[13] & 0x7F); //S=0
sendbuf[13] = (byte) (sendbuf[13] | 0x40); //E=1
sendbuf[13] = (byte) (sendbuf[13] | ((byte) (r[0] & 0x1f)));
if (0 != l) {
System.arraycopy(r, t * packageSize + 1, sendbuf, 14, l - 1);//l-1
bytes = l - 1 + 14; //bytes=l-1+14;
client.send(new DatagramPacket(sendbuf, bytes, addr, port/*9200*/));
//send(sendbuf,bytes);
}//pl
t++;
} else if (t < k && 0 != t) {
sendbuf[1] = (byte) (sendbuf[1] & 0x7F); //M=0
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); //R=0
sendbuf[13] = (byte) (sendbuf[13] & 0x7F); //S=0
sendbuf[13] = (byte) (sendbuf[13] & 0xBF); //E=0
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/*9200*/));
//send(sendbuf,1414);
t++;
}
}
}
}
try {
while (outputBufferIndex >= 0) {
//Log.i("AvcEncoder", "Get H264 Buffer Success! flag = "+bufferInfo.flags+",pts = "+bufferInfo.presentationTimeUs+"");
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
int type = outputBuffer.get(4) & 0x07;
if (type == 7 || type == 8) {//SPS和PPS
mPpsSps = outData;
int sps_length = outData.length - 8 -4;
SPS=new byte[sps_length];
System.arraycopy(outData,4,SPS,0,sps_length);
PPS=new byte[4];
System.arraycopy(outData,8+sps_length,PPS,0,4);
Log.e("liang", "SPS是"+Util.bytesToHexString(SPS) );
Log.e("liang", "PPS是"+Util.bytesToHexString(PPS) );
//Sendspspps();
}else if(type==5){//关键帧
byte[] iframeData = new byte[mPpsSps.length + outData.length];
System.arraycopy(mPpsSps, 0, iframeData, 0, mPpsSps.length);
System.arraycopy(outData, 0, iframeData, mPpsSps.length, outData.length);
outData = iframeData;
Log.e("liang", "关键帧是"+Util.bytesToHexString(outData) );
byte[] newData = new byte[outData.length-4];
System.arraycopy(outData, 4, newData, 0, outData.length-4);
SendR(newData, outData.length - 4);
outputStream.write(outData, 0, outData.length);
}else {//B帧
Log.e("liang", "普通帧是"+Util.bytesToHexString(outData) );
byte[] newData = new byte[outData.length-4];
System.arraycopy(outData, 4, newData, 0, outData.length-4);
SendR(newData, outData.length - 4);
outputStream.write(outData, 0, outData.length);
}
mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
}
} catch (Throwable t) {
t.printStackTrace();
}