这里,终于要开始发送RTP和RTCP报文了,很爽,这也意味着,即将进入核心过程了,
这也是我研究SpyDroid源码的根本目的,我对Android平台的音频录制本身没有兴趣,
我需要掌握源码的核心,我认为核心就是接下来的发送过程,这才是最重要的。
至于Android平台,下次可能是winphone平台,也可能是iphone平台,所以平台不是核心。
而协议是基本上不发生改变的。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~下面开始研究run函数,研究完了本系列也就结束了。
int length = 0;
//设置一个长度指示器
long oldtime = SystemClock.elapsedRealtime(), now = oldtime;
//定义2个时间
//刚开始,自然oldtime和now是一样的,后面会更新。
MainActivity.singleInstane.dispatch("oldtime="+oldtime+" now="+now+"\r\n");
//自定义检查点 : 1 2 3
~~~~~~~~~~~~~~~~~~~~~~~接下来执行:
socket.requestBuffer();
这个需要好好研究一下:函数代码如下:
public byte[] requestBuffer() throws InterruptedException
{
mBufferRequested.acquire();
mBuffers[mBufferIn][1] &= 0x7F;
return mBuffers[mBufferIn];
}
~~~~~~~~~
mBufferRequested.acquire();
//获取一个信号量
mBuffers[mBufferIn][1] &= 0x7F;
//将缓冲区[1]--->0x0;
return mBuffers[mBufferIn];
//返回缓冲区的引用
~~~~~~~~~~~~~~~~~~~~~~~~接下来执行
length = is.read(buffer, rtphl+4, MAXPACKETSIZE-(rtphl+4));
// read(buffer,16,1400-16);
//开始读取数据,length指定了数据的长度
//自定义检查点: 1 2 3
bufferInfo = ((MediaCodecInputStream)is).getLastBufferInfo();
//Log.d(TAG,"length: "+length+" ts: "+bufferInfo.presentationTimeUs);
ts = bufferInfo.presentationTimeUs*1000;
//获取一个时间戳
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~然后执行
socket.markNextPacket();
目的是:mBuffers[mBufferIn][1] |= 0x80;设置为0x10000000.
~~~~~~~~~~~
setLong(mBuffers[mBufferIn], (timestamp/100L)*(mClock/1000L)/10000L, 4, 8);
在第 [4-7]字节,写入时间戳。(timestamp/100L)*(8000/1000L)/10000L
~~~~~~~~~~~~~~~~~~~~~~~~~
buffer[rtphl] = 0;
//buffer[12]=0;
~~~~~~~~~~~~~~~~~
buffer[rtphl+1] = 0x10;
//buffer[13] = 0x10;
//自定义检查点: 1 2 3
// AU-size
buffer[rtphl+2] = (byte) (length>>5);
buffer[rtphl+3] = (byte) (length<<3);
//写入长度
//自定义检查点: 1 2 3
// AU-Index
buffer[rtphl+3] &= 0xF8;
buffer[rtphl+3] |= 0x00;
~~~~~~~~~~~~~~~~~~~~~~~~~
那么到目前为止,buffer的状态如下所示:
private byte[][] mBuffers;
//new byte[300][];
//每个成员是new byte[1500];
// byte[0]=Integer.parseInt("10000000",2);
// byte[1] = (byte) 96 &= 0x7F--->96 | 0x80
// byte[4-7]写入时间戳
// byte[8,9,10,11]=ssrc
// byte[12]=0
// //buffer[13] = 0x10;
// buffer[14] = (byte) (length>>5);
// buffer[15] = (byte) (length<<3);
// buffer[15] &= 0xF8;
// buffer[15] |= 0x00;
// byte[16---x]=数据
解释:版本2,填充位,扩展位为0,CSRC计数为0.
~~~~~~~~~~~~~~~~~
我本来纳闷buffer[12-15]为什么会有数据,看下面就明白了。
然后执行send(rtphl+length+4);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
socket.commitBuffer(length);
调用
private void updateSequence()
{
setLong(mBuffers[mBufferIn], ++mSeq, 2, 4);
}
这是写入sequence.
~~~~~~~~~
/** Sends the RTP packet over the network. */
public void commitBuffer(int length) throws IOException
{
//自定义检查点: 1 2 3
//length=数据长度+16
updateSequence();
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
mPackets[mBufferIn].setLength(length);
//自定义检查点: 1 2 3
mOctetCount += length;
//自定义检查点: 1 2 3
mTime = SystemClock.elapsedRealtime();
if (mTime - mOldTime > 1500)
{
mBitRate = mOctetCount*8000/(mTime-mOldTime);
mOctetCount = 0;
mOldTime = mTime;
}
//自定义检查点: 1 2 3
mBufferCommitted.release();
//释放信号量
//自定义检查点: 1 2 3
if (++mBufferIn>=mBufferCount) mBufferIn = 0;
//计算下一个缓冲区的位置
if (mThread == null)
{
mThread = new Thread(this);
mThread.start();
}
//启动一个线程来发送报文
}
~~~~~~~~~~~~~~~~~
report.update(length);比较简单,就不说了。
if (intervalBetweenReports>0)
{
if (now-oldtime>=intervalBetweenReports)
{
oldtime = now;
report.send(System.nanoTime(),ts*samplingRate/1000000000L);
}
}
表示如果超过5秒,就发送一个RTCP 发送者报告。