这次来讲类AACLATMPacketizer。
这个类先说下干什么的,手机的音频数据写入到后面的某个socket文件后,
需要由一个AACLATMPacketizer打包器将数据打包成RTP和RTCP发送给对方,
AACLATMPacketizer就是起这个作用的。我们来看看具体的执行过程。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
先看涉及到的类:
abstract public class AbstractPacketizer {
public class AACLATMPacketizer extends AbstractPacketizer implements Runnable
涉及到2个类,一个接口。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~各个击破
super();表明要先初始化AbstractPacketizer 。
~~~~~~~~~~~~~~~进入AbstractPacketizer初始化函数
int ssrc = new Random().nextInt();、、产生一个随机数,
假设为://383053901
~~~~~~~~~~~接下来
ts = new Random().nextInt();
假设为:// 1238348531
~~~~~~~~~~~接下来
socket = new RtpSocket();
这里就是我们发送RTP报文的 socket,先看看怎么初始化的。
public class RtpSocket implements Runnable {
这个表明RtpSocket类是没有父类的,这是我最高兴看到的地方。
public RtpSocket() throws IOException
{
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
mCacheSize = 400;
//设置为400
//自定义检查点: 1 2 3
mBufferCount = 300; // TODO: reajust that when the FIFO is full
//set to be 300
//自定义检查点: 1 2 3
mBufferIn = 0;
// set to be 0
//自定义检查点: 1 2 3
mBufferOut = 0;
// set to be 0
//自定义检查点: 1 2 3
mBuffers = new byte[mBufferCount][];
//产生一个二维数组
//自定义检查点: 1 2 3
mPackets = new DatagramPacket[mBufferCount];
//设置一个300数组
//自定义检查点: 1 2 3
mTimestamps = new long[mBufferCount];
//设置一个300成员的long数组
//自定义检查点: 1 2 3
mBufferRequested = new Semaphore(mBufferCount);
//设置一个最多容许300个访问的信号量
//通过acquire()和release()获取和释放访问许可。
//自定义检查点: 1 2 3
mBufferCommitted = new Semaphore(0);
//设置一个最多容许0个访问的信号量
//通过acquire()和release()获取和释放访问许可。
//自定义检查点: 1 2 3
for (int i=0; i<mBufferCount; i++)
{
//设置300个对象
mBuffers[i] = new byte[MTU];
//对0-299号成员分配缓冲区
//自定义检查点: 1 2 3
mPackets[i] = new DatagramPacket(mBuffers[i], 1);
//给每个成员赋值
//自定义检查点: 1 2 3
/* Version(2) Padding(0) */
/* ^ ^ Extension(0) */
/* | | ^ */
/* | -------- | */
/* | |--------------------- */
/* | || -----------------------> Source Identifier(0) */
/* | || | */
mBuffers[i][0] = (byte) Integer.parseInt("10000000",2);
//赋值
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
/* Payload Type */
mBuffers[i][1] = (byte) 96;
//设置负载类型为96
////自定义检查点: 1 2 3
/* Byte 2,3 -> Sequence Number */
/* Byte 4,5,6,7 -> Timestamp */
/* Byte 8,9,10,11 -> Sync Source Identifier */
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
}
//自定义检查点: 1 2 3
mSocket = new MulticastSocket();
//设置一个多播句柄
//自定义检查点: 1 2 3
mTime = mOldTime = SystemClock.elapsedRealtime();
//计算系统启动逝去的时间
MainActivity.singleInstane.dispatch("mTime="+mTime+",mOldTime="+mOldTime+"\r\n");
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
//自定义检查点: 1 2 3
}
接下来执行report = new SenderReport();
这个一看就知道是发送者报告,用RTCP协议发送。
public class SenderReport 表明它也没有父类,看来今天运气很好!
~~~~~~~~~~~~~
public SenderReport() throws IOException
//自定义检查点: 1 2 3
{
//自定义检查点: 1 2 3
/* Version(2) Padding(0) */
/* ^ ^ PT = 0 */
/* | | ^ */
/* | -------- | */
/* | |--------------------- */
/* | || */
/* | || */
buffer[0] = (byte) Integer.parseInt("10000000",2);
//以二进制的形式10000000写进入
//自定义检查点: 1 2 3
/* Packet Type PT */
buffer[1] = (byte) 200;
//根据RTCP协议,发送者报告的代码就是200
//自定义检查点: 1 2 3
/* Byte 2,3 -> Length */
setLong(28/4-1, 2, 4);
//对buffer[2],buffer[3]进入赋值
//自定义检查点: 1 2 3
/* Byte 4,5,6,7 -> SSRC */
/* Byte 8,9,10,11 -> NTP timestamp hb */
/* Byte 12,13,14,15 -> NTP timestamp lb */
/* Byte 16,17,18,19 -> RTP timestamp */
/* Byte 20,21,22,23 -> packet count */
/* Byte 24,25,26,27 -> octet count */
//自定义检查点: 1 2 3
usock = new MulticastSocket();
//初始化
upack = new DatagramPacket(buffer, 1);
//赋值
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
继续执行代码,就可以将AbstractPacketizer全部初始化完毕,如下所示:
public AbstractPacketizer() throws IOException
{
int ssrc = new Random().nextInt();
//1770841009
ts = new Random().nextInt();
// 1238348531
socket = new RtpSocket();
report = new SenderReport();
socket.setSSRC(ssrc);
//保存SSRC,及为每个缓冲区写入SSRC,反正SSRC不会改变
report.setSSRC(ssrc);
//从上面可以看到,同一个媒体流涉及到的RTCP和RTP两个通道的报文的SSRC是一样的
}