Android源码分析:VoIP

概述

Android的voip功能支持位于目录frameworks/base/voip中。它包括支持rtp功能的package

RTP支持

RTP支持包位于目录frameworks/base/voip/java/android/net/rtp下,主要包含四个Java类:代表着基于RTP协议的流RtpStream、基于RTP协议的语音流AudioStream、描述了语音Codec信息的AudioCodec和语音会话组的AudioGroup、。

 

RTP流:RtpStream

它是基于RTP(Real-time Transport Protocol)协议的数据流。Java层的API类是android.net.rtp.RtpStream,代表着一个通过RTP协议发送和接收网络多媒体数据包的流。一个流主要包括本机网络地址和端口号、远程主机网络地址和端口号、socket号和流模式。

RtpStream支持三种流模式,可由setMode函数设定:

MODE_NORMAL:正常模式,接收和发送数据包

MODE_SEND_ONLY: 只发送数据包

MODE_RECEIVE_ONLY:只接收数据包

本地主机IP地址(InetAddress,支持IPv4和IPv6)由调用构造函数时传入。在构造函数中,会调用native层实现的create函数获取一个本地主机端口号(依据RFC 3550);同时,native层的create函数还会得到一个socket连接号,socket号会在native层中更新到该Java类实例中。

远程主机地址和端口号由函数associate指定:

public void associate(InetAddress address, int port)

获取socket号的过程如下:

android.net.rtp.RtpStream的一个私有成员整型变量mNative存放的是socket号:

private int mNative;

它由JNI层在调用socket函数后得到一个socket号后存入里面。具体如下:在JNI层(frameworks/base/voip/jni/rtp/RtpStream.cpp)中标识它的变量是:

jfieldID gNative;

在函数registerRtpStream中获取具体的值:

(gNative = env->GetFieldID(clazz, “mNative”, “I”)) == NULL ||

在JNI层的create函数中,会调用socket函数得到一个socket号:

int socket = ::socket(ss.ss_family, SOCK_DGRAM, 0);

这个socket号会被指定给Java层的mNative变量:

env->SetIntField(thiz, gNative, socket);

端口号port则由create函数直接返回。create函数已经支持IPv6。

 

语音流:AudioStream

android.net.rtp.AudioStream继承自RtpStream,代表着一个建立在RTP协议之上的与对方通话的语音流。语音流需要使用一个语音Codec来描述其对应的编解码信息。在建立通话之前,语音流需加入(join)到会话组android.net.rtp.AudioGroup中。因此,它包含了:所在的语音组、语音Codec以及DTMF(Dual-Tone Multi-Frequency)类型(RFC 2833)等信息。

 

语音Codec:AudioCodec

一个android.net.rtp.AudioStream需要有一个android.net.rtp.AudioCodec为其编解码。Java层的AudioCodec只是描述了Codec信息的类,主要包含了三样信息:

 

public final int type; //The RTP payload type of the encoding.

public final String rtpmap; //The encoding parameters to be used in the corresponding SDP attribute.

public final String fmtp; //The format parameters to be used in the corresponding SDP attribute.

可以使用AudioCodec.getCodec轻松得到一个Codec:

public static AudioCodec getCodec(int type, String rtpmap, String fmtp)

为方便使用,在AudioCodec中Android定义了常用的几个Codec:PCMU、PCMA、GSM、GSM_EFR和AMR。

 

语音组:AudioGroup

android.net.rtp.AudioGroup代表的是一个会话,可能只是两人通话,也可能是多于两人的电话会议。可以同时有多组会话,因为麦克和扬声器只能是排他性使用,故只能有一组会话为活动的,其它必须是HOLD状态。

语音组通过一个映射表来维护加入它里面的语音流:

private final Map<AudioStream, Integer> mStreams;

 

一个AudioStream加入到AudioGroup的流程如下:

首先是AudioStream调用join加入到某个AudioGroup中:

public void join(AudioGroup group)

然后调用AudioGroup.add,接着调用:

private native void

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AndroidVoIP客户端App源代码,用以实现经典的语音及视频通话功能,开发环境的配置下载下来SipDroid源代码后,不能直接导入到eclipse中,否则是无法使用和编译的。   首先需要通过command line参照工程目录下的BUILT.txt文件对工程进行update。   如:android update project -p . -t 2(这里 -p指的是 --path -t指的是 --target)   由于是开源软件,需要版本控制的服务器,可以安装Subclipse(可以参见官网)   这样就可以将工程import到eclipse中了。   整理一些Android视频通话技术开发的资料:   SipDroid是一款开源的SIP/Voip客户端软件,针对Android手机开发平台。它是通过SIP provider来提供电话通信服务的,在它的最新的版本1.5.5beta中也提供了视频通话的服务。   它运行在标准的SIP协议之上,由于Android内核本身没有提供SIP协议栈,所以SipDroid软件中通过JNI直接实现了SIP协议栈。它能够在如下一些网络中提供VoiP服务:WLAN、3G、EDGE网络。甚至能够和Skype、Google Talk, MSN, Yahoo, AIM, and ICQ等用户进行通话。但前提必须到一些SIP provider注册账号(有免费的,也有收费的),SipDroid强烈建议使用PBXes这个sip provider来得到服务。   对于SipDroid实现视频通话的原理,目前的理解是:发送方是将是将视频数据传输到视频流媒体服务器,然后再传输给接收方的。具体细节目前不是很清楚,因为涉及到许多通信协议。   本项目共250 个目标文件,还有jni文件下c 文件需要编译。 感兴趣的同学必须得好好研究研究。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值