下面貼出安卓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();
}