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。