RTP荷载H264码流

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章