==>
void ARTPConnection::postPollEvent() {
//mPollEventPending的值在构造函数中被初始化为false
if (mPollEventPending) {
return;
}
//新建消息msg,消息名为kWhatPollStreams,消息处理者为this,即ARTPConnection
sp<AMessage> msg = new AMessage(kWhatPollStreams, this);
msg->post();
//将mPollEventPending的值设置为true,表示当前处于pengding状态
//在当前状态为完成的时候不允许再次发送名为kWhatPollStreams的消息
mPollEventPending = true;
}
==>
void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatAddStream:
{
onAddStream(msg);
break;
}
case kWhatRemoveStream:
{
onRemoveStream(msg);
break;
}
case kWhatPollStreams:
{
//对消息名为kWhatPollStreams的处理
//调用onPollStreams函数进行处理
onPollStreams();
break;
}
case kWhatInjectPacket:
{
onInjectPacket(msg);
break;
}
default:
{
TRESPASS();
break;
}
}
}
void ARTPConnection::onPollStreams() {
//将mPollEventPending的值设置为false
//允许再产生一个这样的状态
mPollEventPending = false;
if (mStreams.empty()) {
//如果mStreams容器为空,说明不存在任何流,不进行处理,直接返回
return;
}
//创建一个timeval类型的表述时间的结构体
//并设置好tv_usec域的值,tv_sec的值设置为零
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = kSelectTimeoutUs;
//创建一个套接字描述符集合rs
//并将套接字描述符集合rs清空
fd_set rs;
FD_ZERO(&rs);
int maxSocket = -1;
for (List<StreamInfo>::iterator it = mStreams.begin();
it != mStreams.end(); ++it) {
if ((*it).mIsInjected) {
continue;
}
//将该流的
FD_SET(it->mRTPSocket, &rs);
FD_SET(it->mRTCPSocket, &rs);
if (it->mRTPSocket > maxSocket) {
maxSocket = it->mRTPSocket;
}
if (it->mRTCPSocket > maxSocket) {
maxSocket = it->mRTCPSocket;
}
}
if (maxSocket == -1) {
return;
}
int res = select(maxSocket + 1, &rs, NULL, NULL, &tv);
if (res > 0) {
List<StreamInfo>::iterator it = mStreams.begin();
while (it != mStreams.end()) {
if ((*it).mIsInjected) {
++it;
continue;
}
status_t err = OK;
if (FD_ISSET(it->mRTPSocket, &rs)) {
err = receive(&*it, true);
}
if (err == OK && FD_ISSET(it->mRTCPSocket, &rs)) {
err = receive(&*it, false);
}
if (err == -ECONNRESET) {
// socket failure, this stream is dead, Jim.
ALOGW("failed to receive RTP/RTCP datagram.");
it = mStreams.erase(it);
continue;
}
++it;
}
}
int64_t nowUs = ALooper::GetNowUs();
if (mLastReceiverReportTimeUs <= 0
|| mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
List<StreamInfo>::iterator it = mStreams.begin();
while (it != mStreams.end()) {
StreamInfo *s = &*it;
if (s->mIsInjected) {
++it;
continue;
}
if (s->mNumRTCPPacketsReceived == 0) {
// We have never received any RTCP packets on this stream,
// we don't even know where to send a report.
++it;
continue;
}
buffer->setRange(0, 0);
for (size_t i = 0; i < s->mSources.size(); ++i) {
sp<ARTPSource> source = s->mSources.valueAt(i);
source->addReceiverReport(buffer);
if (mFlags & kRegularlyRequestFIR) {
source->addFIR(buffer);
}
}
if (buffer->size() > 0) {
ALOGV("Sending RR...");
ssize_t n;
do {
n = sendto(
s->mRTCPSocket, buffer->data(), buffer->size(), 0,
(const struct sockaddr *)&s->mRemoteRTCPAddr,
sockAddrSize());
} while (n < 0 && errno == EINTR);
if (n <= 0) {
ALOGW("failed to send RTCP receiver report (%s).",
n == 0 ? "connection gone" : strerror(errno));
it = mStreams.erase(it);
continue;
}
CHECK_EQ(n, (ssize_t)buffer->size());
mLastReceiverReportTimeUs = nowUs;
}
++it;
}
}
if (!mStreams.empty()) {
postPollEvent();
}
}
03-09
282

05-02
05-02
05-02
05-02
05-02