SpyDroid源码分析系列18:SpyDroid上传AAC音频原理8

这里,终于要开始发送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 发送者报告。

你可能感兴趣的:(android,RTP,rtcp,SpyDroid)