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。

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