1.荷載結構
RTP定義了三種荷載H264碼流的結構,採用的結構格式在RTP荷載的H264碼流的第一個字節的後5個bit位,也就是data[0]的後5個bit位。可以通過:
unsigned nalType = data[0] & 0x1f;即data[0] & 0001 1111
計算得到。
1.單個NAL單元包 ,nalType >= 1 && nalType <= 23。即荷載的H264碼流中只有一個NAL單元。
2.聚合包:
1.單時間聚合包類型A(STAP-A),nalType == 24。
2.單時間聚合包類型B (STAP-B),nalType == 25。
3.多時間聚合包類型16位位移(MTAP16),nalType == 26。
4.多時間聚合包類型24位位移(MTAP24),nalType ==27。
即荷載的H264碼流中有多個NAL單元。
3.分片單元,FU-A,FU-B,用NAL單元類型 28,29標識。即用於分片單個NAL單元到多個RTP包。
下面貼出安卓N版本對於RTP荷載的H264碼流不同荷載結構的處理:
ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
const sp<ARTPSource> &source) {
List<sp<ABuffer> > *queue = source->queue();
if (queue->empty()) {
return NOT_ENOUGH_DATA;
}
if (mNextExpectedSeqNoValid) {
List<sp<ABuffer> >::iterator it = queue->begin();
while (it != queue->end()) {
if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
break;
}
it = queue->erase(it);
}
if (queue->empty()) {
return NOT_ENOUGH_DATA;
}
}
sp<ABuffer> buffer = *queue->begin();
if (!mNextExpectedSeqNoValid) {
mNextExpectedSeqNoValid = true;
mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
} else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
ALOGV("Not the sequence number I expected");
return WRONG_SEQUENCE_NUMBER;
}
const uint8_t *data = buffer->data();
size_t size = buffer->size();
if (size < 1 || (data[0] & 0x80)) {
// Corrupt.
ALOGV("Ignoring corrupt buffer.");
queue->erase(queue->begin());
++mNextExpectedSeqNo;
return MALFORMED_PACKET;
}
unsigned nalType = data[0] & 0x1f;//計算得到RTP荷載的H264碼流的荷載結構
if (nalType >= 1 && nalType <= 23) {
//對單個NAL單元包結構的處理
addSingleNALUnit(buffer);
queue->erase(queue->begin());
++mNextExpectedSeqNo;
return OK;
} else if (nalType == 28) {
//對分片單元FU-A的處理
// FU-A
return addFragmentedNALUnit(queue);
} else if (nalType == 24) {
//對單時間聚合包類型A(STAP-A)的處理
// STAP-A
bool success = addSingleTimeAggregationPacket(buffer);
queue->erase(queue->begin());
++mNextExpectedSeqNo;
return success ? OK : MALFORMED_PACKET;
} else if (nalType == 0) {
ALOGV("Ignoring undefined nal type.");
queue->erase(queue->begin());
++mNextExpectedSeqNo;
return OK;
} else {
ALOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
queue->erase(queue->begin());
++mNextExpectedSeqNo;
return MALFORMED_PACKET;
}
}
代碼中的中文註釋我自己添加輔助大家理解的。可以看出安卓N版本並沒有支持所有NAL Type。