下面贴出安卓N版本MyHandler.h对消息”accu”的处理原文
//收到'accu'消息,说明AAVCAssembler成功将多个NAL单元组合成了一帧完整的数据,并将存放该帧数据的buffer的引用添加到该buffer里了。
case 'accu':
{
if (mSeekPending) {
ALOGV("Stale access unit.");
break;
}
int32_t timeUpdate;
if (msg->findInt32("time-update", &timeUpdate) && timeUpdate) {
//如果在消息msg里设置了"time-update"字段信息,并且得到的timeUpdate值非零,则需要进行处理
//从消息msg里设置的"track-index"字段信息得到trackIndex的值
//从消息msg里设置的"rtp-time"字段信息得到rtpTime的值
//从消息msg里设置的"ntp-time"字段信息得到ntpTime的值
//调用onTimeUpdate(trackIndex, rtpTime, ntpTime)进行处理
//break跳出该case处理分支
size_t trackIndex;
CHECK(msg->findSize("track-index", &trackIndex));
uint32_t rtpTime;
uint64_t ntpTime;
CHECK(msg->findInt32("rtp-time", (int32_t *)&rtpTime));
CHECK(msg->findInt64("ntp-time", (int64_t *)&ntpTime));
onTimeUpdate(trackIndex, rtpTime, ntpTime);
break;
}
int32_t first;
if (msg->findInt32("first-rtcp", &first)) {
//如果消息msg里设置了"first-rtcp"字段信息则将mReceivedFirstRTCPPacket的值设置为true
//break跳出该case语句处理分支
mReceivedFirstRTCPPacket = true;
break;
}
if (msg->findInt32("first-rtp", &first)) {
//如果消息msg里设置了"first-rtp"字段信息,则将mReceivedFirstRTPPacket的值设置为true
//break跳出该case语句处理分支
mReceivedFirstRTPPacket = true;
break;
}
//代码执行到这里说明收到的是正常的一帧数据
//将mNumAccessUnitsReceived自增1计数已经收到的帧的数量
//调用postAccessUnitTimeoutCheck进行超时检查
++mNumAccessUnitsReceived;
postAccessUnitTimeoutCheck();
//从消息msg的字段信息"track-index"得到trackIndex的值
size_t trackIndex;
CHECK(msg->findSize("track-index", &trackIndex));
if (trackIndex >= mTracks.size()) {
//mTracks.size()表示的是支持的最大轨道数目,trackIndex不同超过这个值
//trackIndex在0~mTracks.size()-1内
ALOGV("late packets ignored.");
break;
}
//由trackIndex得到对应轨道的TrackInfo信息结构体的指针
TrackInfo *track = &mTracks.editItemAt(trackIndex);
int32_t eos;
if (msg->findInt32("eos", &eos)) {
//如果消息msg设置了"eos"字段信息,说明该帧位位结尾帧
//当收到的帧是结尾帧的时候进行相应处理
//这里具体的处理就先不介绍了先放一边,抓住主要矛盾先
ALOGI("received BYE on track index %zu", trackIndex);
char value[PROPERTY_VALUE_MAX] = {0};
if (property_get("rtcp.bye.notify", value, "false")
&& !strcasecmp(value, "true")) {
sp<AMessage> msg = mNotify->dup();
msg->setInt32("what", kWhatByeReceived);
msg->post();
}
if (!mAllTracksHaveTime && dataReceivedOnAllChannels()) {
ALOGI("No time established => fake existing data");
track->mEOSReceived = true;
mTryFakeRTCP = true;
mReceivedFirstRTCPPacket = true;
fakeTimestamps();
} else {
postQueueEOS(trackIndex, ERROR_END_OF_STREAM);
}
return;
}
if (mSeekPending) {
ALOGV("we're seeking, dropping stale packet.");
break;
}
/从消息msg里的"access-unit"字段信息得到存放数据帧buffer的引用
//调用onAccessUnitComplete(trackIndex, accessUnit)对该buffer进行处理
sp<ABuffer> accessUnit;
CHECK(msg->findBuffer("access-unit", &accessUnit));
onAccessUnitComplete(trackIndex, accessUnit);
break;
}
小结:MyHandler对消息”accu”的处理是:收到正常的数据帧的做法从消息msg里的”access-unit”字段信息得到存放数据帧buffer的引用,然后调用onAccessUnitComplete(trackIndex, accessUnit)进行处理