音频


//添加音频头 大小可调
private byte[] audioBufferSend = new byte[32 + 1 + 12];
		addAudioTitle(audioBufferSend);



/***
	 * RTP 头
	 * @param audioBufferSend
	 */
	private void addAudioTitle(byte[] audioBufferSend) {
		CalculateUtil.memset(audioBufferSend, 0, audioBufferSend.length);// 情况sendbuf,此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值

		audioBufferSend[0] = (byte) 0x80;
		audioBufferSend[1] = (byte)(audioBufferSend[1] | AUDIO_RTP_FH);//(byte) 0x68;  // 104 16进制68
		
//		Log.i(TAG, "@@@@@@@@@@@@@@@@@audioSeq_num:   " + audioSeq_num);
		System.arraycopy(CalculateUtil.intToByte(audioSeq_num++), 0, audioBufferSend, 2, 2);
		{
			byte temp = 0;
			temp = audioBufferSend[3];
			audioBufferSend[3] = audioBufferSend[2];
			audioBufferSend[2] = temp;
		}
		
		audioTs_current = audioTs_current + audioTimestamp_increse;
		// rtp_hdr.timestamp = ts_current;// htonl(ts_current)
		// java默认网络字节序
		System.arraycopy(CalculateUtil.intToByte(audioTs_current), 0, audioBufferSend, 4, 4);
		{
			byte temp = 0;
			temp = audioBufferSend[4];
			audioBufferSend[4] = audioBufferSend[7];
			audioBufferSend[7] = temp;

			temp = audioBufferSend[5];
			audioBufferSend[5] = audioBufferSend[6];
			audioBufferSend[6] = temp;
		}
		
		audioBufferSend[8] = (byte) 0x68;
		audioBufferSend[9] = (byte) 0x87;
		audioBufferSend[10] = (byte) 0x58;
		audioBufferSend[11] = (byte) 0xde;
		audioBufferSend[12] = (byte) 0xf0;
	}




// 时间戳增量
	private float audioFramerate = 500;
	private int audioTimestamp_increse = (int) (80000.0 / audioFramerate); // +0.5);
	private int audioTs_current = 0;
	private int AUDIO_RTP_FH = 0;
	private int audioSeq_num = 0;
	/***
	 * RTP 头
	 * @param audioBufferSend
	 */
	private void addAudioTitle(byte[] audioBufferSend) {
//		CalculateUtil.memset(audioBufferSend, 0, audioBufferSend.length);// 情况sendbuf,此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值

		audioBufferSend[0] = (byte) 0x80;
		audioBufferSend[1] = (byte)(audioBufferSend[1] | AUDIO_RTP_FH);//PCMU;  // 104 
		
//		Log.i(TAG, "@@@@@@@@@@@@@@@@@audioSeq_num:   " + audioSeq_num);
		System.arraycopy(CalculateUtil.intToByte(audioSeq_num++), 0, audioBufferSend, 2, 2);
		{
			byte temp = 0;
			temp = audioBufferSend[3];
			audioBufferSend[3] = audioBufferSend[2];
			audioBufferSend[2] = temp;
		}
		
		audioTs_current = audioTs_current + audioTimestamp_increse;
		// rtp_hdr.timestamp = ts_current;// htonl(ts_current)
		// java默认网络字节序
		System.arraycopy(CalculateUtil.intToByte(audioTs_current), 0, audioBufferSend, 4, 4);
		{
			byte temp = 0;
			temp = audioBufferSend[4];
			audioBufferSend[4] = audioBufferSend[7];
			audioBufferSend[7] = temp;

			temp = audioBufferSend[5];
			audioBufferSend[5] = audioBufferSend[6];
			audioBufferSend[6] = temp;
		}
		
		audioBufferSend[8] = (byte) ((new Random()).nextInt() % 256);
		audioBufferSend[9] = (byte) ((new Random()).nextInt() % 256);
		audioBufferSend[10] = (byte) ((new Random()).nextInt() % 256);
		audioBufferSend[11] = (byte) ((new Random()).nextInt() % 256);
	}
}




/**
	 * 视频流   分包
	 * @param bForIn
	 * @throws Exception
	 */
	protected void sendByteForIn(byte[] bForIn) throws Exception {
		videoBais = new ByteArrayInputStream(bForIn);

		while (!(0 == videoBais.available())) {

//			Log.i(TAG, "GetAnnexbNALU start:" + (System.currentTimeMillis() - start));
			GetAnnexbNALU(n, bForIn); // 每执行一次, 文件指针指向本次找到的NALU的末尾,
//			Log.i(TAG, "GetAnnexbNALU end:" + (System.currentTimeMillis() - start));
			// 下一位置即为下个NALU的起始码0x000001
			CalculateUtil.dump(n);// 输出NALU的长度和NALU
			// 从文件中 获取一个nalu大小
			// 判断其大小 分包发送
			CalculateUtil.memset(videoSendbuf, 0, 1500);// 情况sendbuf,此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值
//			Log.i(TAG, "memset :" + (System.currentTimeMillis() - start));
			
			videoSendbuf[1] = (byte) (videoSendbuf[1] | RTP_FH); // 负载类型号96
			// System.out.println("-----!"+sendbuf[1]);
			videoSendbuf[0] = (byte) (videoSendbuf[0] | 0x80); // 版本号,此版本固定为2
			videoSendbuf[1] = (byte) (videoSendbuf[1] & 254); // 标志位,由具体协议规定其值
			videoSendbuf[11] = 10; // 随即指定10,并在本RTP回话中全局唯一,java默认采用网络字节序号 不用转换
			
//			Log.i(TAG, "@@@@@@@@@@@@@@@@@seq_num:   " + videoSeq_num);
//			Log.i(TAG, "n.len start :" + (System.currentTimeMillis() - start));
			if (n.len <= 1400) {
				videoSendbuf[1] = (byte) (videoSendbuf[1] | 0x80); // 设置rtp M位为1
				// sendbug[2], sendbuf[3]赋值seq_num ++ 每发送一次rtp包增1
				// sendbuf[3] = (byte) seq_num ++
//				Log.i(TAG, "arraycopy start :" + (System.currentTimeMillis() - start));
				System.arraycopy(CalculateUtil.intToByte(videoSeq_num++), 0, videoSendbuf, 2, 2);
//				Log.i(TAG, "System.arraycopy start end :" + (System.currentTimeMillis() - start));
				{
					// 倒序
					byte temp = 0;
					temp = videoSendbuf[3];
					videoSendbuf[3] = videoSendbuf[2];
					videoSendbuf[2] = temp;
				}

				// 设置NALU HEADER, 并将这个HEADER填入sendbuf[12]
				videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) n.forbidden_bit) << 7);
				videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) (n.nal_reference_idc >> 5)) << 5);
				videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) n.nal_unit_type));
//				Log.i(TAG, "arraycopy start :" + (System.currentTimeMillis() - start));
				// 同理将sendbuf[13]赋给nalu_payload
				System.arraycopy(n.buf, 1, videoSendbuf, 13, n.len - 1);// 去掉nalu头的nalu剩余类容写入sendbuf[13]开始的字符串
//				Log.i(TAG, "System.arraycopy start end :" + (System.currentTimeMillis() - start));
				videoTs_current = videoTs_current + videoTimestamp_increse;
				// rtp_hdr.timestamp = ts_current;// htonl(ts_current)
				// java默认网络字节序
//				Log.i(TAG, "arraycopy start :" + (System.currentTimeMillis() - start));
				System.arraycopy(CalculateUtil.intToByte(videoTs_current), 0, videoSendbuf, 4, 4);
//				Log.i(TAG, "arraycopy end :" + (System.currentTimeMillis() - start));
				{
					// 倒序
					byte temp = 0;
					temp = videoSendbuf[4];
					videoSendbuf[4] = videoSendbuf[7];
					videoSendbuf[7] = temp;

					temp = videoSendbuf[5];
					videoSendbuf[5] = videoSendbuf[6];
					videoSendbuf[6] = temp;
				}
				bytes = n.len + 12; // 获sendbuf的长度,为nalu的长度(包含nalu头但取出起始前缀,加上rtp_header固定长度12个字节)
//				Log.i(TAG, "l1400:" + (System.currentTimeMillis() - start) + ", 包长:" + bytes);
				sendVideoPacket(videoSendbuf, bytes, 12, (int)(System.currentTimeMillis() - start));// 发送rtp包
//				Log.i(TAG, "发送时间: " + (System.currentTimeMillis() - start)+"线程标示"+Thread.currentThread().getId());
			} 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包
				videoTs_current = videoTs_current + videoTimestamp_increse;
				// rtp_hdr->timestamp=htonl(ts_current);
				System.arraycopy(CalculateUtil.intToByte(videoTs_current), 0, videoSendbuf, 4, 4);
				{
					// 倒序
					byte temp = 0;
					temp = videoSendbuf[4];
					videoSendbuf[4] = videoSendbuf[7];
					videoSendbuf[7] = temp;

					temp = videoSendbuf[5];
					videoSendbuf[5] = videoSendbuf[6];
					videoSendbuf[6] = temp;

				}
				while (t <= k) {
					// rtp_hdr->seq_no = htons(seq_num ++);//序列号, 每发送一个rtp包增加1
					// sendbuf[3] = (byte) seq_num ++;
					System.arraycopy(CalculateUtil.intToByte(videoSeq_num++), 0, videoSendbuf, 2, 2);
					{
						// 倒序
						byte temp = 0;
						temp = videoSendbuf[3];
						videoSendbuf[3] = videoSendbuf[2];
						videoSendbuf[2] = temp;
					}
					if (0 == t) {
						// 设置rtp M位
						videoSendbuf[1] = (byte) (videoSendbuf[1] & 0x7F); // M=0
						// 设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
						videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) n.forbidden_bit) << 7);
						videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) (n.nal_reference_idc >> 5)) << 5);
						videoSendbuf[12] = (byte) (videoSendbuf[12] | (byte) (28));

						// 设置FU HEADER,并将这个HEADER填入snedbuf[13]
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0xBF);// E=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0xDF);// R=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] | 0x80);// S=1
						videoSendbuf[13] = (byte) (videoSendbuf[13] | ((byte) n.nal_unit_type));

						// 同理将sendbuf[14]赋给nalu_playload
						System.arraycopy(n.buf, 1, videoSendbuf, 14, 1400);
						bytes = 1400 + 14;
//						Log.i(TAG, "0 == t包:" + (System.currentTimeMillis() - start) + ", 包长:" + bytes);
						sendVideoPacket(videoSendbuf, bytes, 12, (int)(System.currentTimeMillis() - start));
//						Log.i(TAG, "0 == t发送时间: " + (System.currentTimeMillis() - start));
						t++;
					}
					// 发送一个需要分片的NALU的非第一个分片,清零FU HEADER
					// 的S位,如果该分片是该NALU的最后一个分片,置FU HEADER的E位
					else if (k == t) // 发送的是最后一个分片,注意最后一个分片的长度可能超过1400字节(当l>1386时)
					{
						// 设置rtp M位,当前床书的是最后一个分片时该位置1
						videoSendbuf[1] = (byte) (videoSendbuf[1] | 0x80);
						// 设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
						videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) n.forbidden_bit) << 7);
						videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) (n.nal_reference_idc >> 5)) << 5);
						videoSendbuf[12] = (byte) (videoSendbuf[12] | (byte) (28));

						// 设置FU HEADER,并将这个HEADER填入sendbuf[13]
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0xDF); // R=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0x7F); // S=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] | 0x40); // E=1
						videoSendbuf[13] = (byte) (videoSendbuf[13] | ((byte) n.nal_unit_type));

						// 将nalu的最后神域的l-1(去掉了一个字节的nalu头)字节类容写入sendbuf[14]开始的字符串
						System.arraycopy(n.buf, t * 1400 + 1, videoSendbuf, 14,
								l - 1);
						bytes = l - 1 + 14;
//						Log.i(TAG, "k == t包:" + (System.currentTimeMillis() - start) + ", 包长:" + bytes);
						sendVideoPacket(videoSendbuf, bytes, 11, (int)(System.currentTimeMillis() - start));// 发送rtp包
//						Log.i(TAG, "k == t发送时间: " + (System.currentTimeMillis() - start));
						t++;
					} else if (t < k && 0 != t) {
						// 设置rtp M位
						videoSendbuf[1] = (byte) (videoSendbuf[1] & 0x7F); // M=0

						// 设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
						videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) n.forbidden_bit) << 7);
						videoSendbuf[12] = (byte) (videoSendbuf[12] | ((byte) (n.nal_reference_idc >> 5)) << 5);
						videoSendbuf[12] = (byte) (videoSendbuf[12] | (byte) (28));

						// 设置FU HEADER,并将这个HEADER填入sendbuf[13]
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0xDF); // R=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0x7F); // S=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] & 0xBF); // E=0
						videoSendbuf[13] = (byte) (videoSendbuf[13] | ((byte) n.nal_unit_type));

						System.arraycopy(n.buf, t * 1400 + 1, videoSendbuf, 14, 1400);// 去掉起始前缀的nalu剩余内容写入sendbuf[14]开始的字符串。
						bytes = 1400 + 14; // 获得sendbuf的长度,为nalu的长度(除去原NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
//						Log.i(TAG, "t < k包:" + (System.currentTimeMillis() - start) + ", 包长:" + bytes);
						sendVideoPacket(videoSendbuf, bytes, 11, (int)(System.currentTimeMillis() - start));// 发送rtp包
//						Log.i(TAG, "t < k发送时间: " + (System.currentTimeMillis() - start));
						t++;
					}
				}
			}
		}
	}