下面贴出安卓N版本AAVCAssembler::submitAccessUnit原文
void AAVCAssembler::submitAccessUnit() {
CHECK(!mNALUnits.empty());
//要被处理的mNALUnits里所有的NAL单元是同属同一帧数据的
ALOGV("Access unit complete (%zu nal units)", mNALUnits.size());
//下面需要将这些所有的同属同一帧数据的NAL单元组合成一帧完整的数据
//计算容纳所有的NAL单元所需要的字节数
size_t totalSize = 0;
for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
it != mNALUnits.end(); ++it) {
//计算规则就是每个NAL单元的大小加上一个额外的4个字节,该4个字节用来填充分隔符"\x00\x00\x00\x01"
totalSize += 4 + (*it)->size();
}
//创建一个新的buffer用来容纳所有的NAL单元
sp<ABuffer> accessUnit = new ABuffer(totalSize);
size_t offset = 0;
for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
it != mNALUnits.end(); ++it) {
//在将该NAL单元复制到accessUnit所指向的buffer之前,先填充4个字节的分隔符"\x00\x00\x00\x01"
memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
offset += 4;
//填充完分隔符,将该NAL单元复制accessUnit所指向的buffer
sp<ABuffer> nal = *it;
memcpy(accessUnit->data() + offset, nal->data(), nal->size());
offset += nal->size();
}
//向该buffer填充时间戳等信息
CopyTimes(accessUnit, *mNALUnits.begin());
#if 0
printf(mAccessUnitDamaged ? "X" : ".");
fflush(stdout);
#endif
if (mAccessUnitDamaged) {
//如果mAccessUnitDamaged的值为true,则将"damaged"字段添加到accessUnit->meta()中
accessUnit->meta()->setInt32("damaged", true);
}
//将mNALUnits里所有的buffer清楚,然后将mAccessUnitDamaged设置为false
mNALUnits.clear();
mAccessUnitDamaged = false;
//在通知消息msg设置字段"access-unit"添加新建的buffer的引用accessUnit,并将该消息发送出去进行异步处理
sp<AMessage> msg = mNotifyMsg->dup();
msg->setBuffer("access-unit", accessUnit);
msg->post();
}