Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c748eea6 authored by Byeongjo Park's avatar Byeongjo Park Committed by Automerger Merge Worker
Browse files

VT: Supports cvo mode for H265 stream. am: 050b31fb

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/15200996

Change-Id: I44f25e9299179d63e84c450c74ec434da70aace1
parents dd180388 050b31fb
Loading
Loading
Loading
Loading
+99 −25
Original line number Diff line number Diff line
@@ -995,12 +995,14 @@ void ARTPWriter::sendHEVCData(MediaBufferBase *mediaBuf) {
    }

    sp<ABuffer> buffer = new ABuffer(kMaxPacketSize);

    if (mediaBuf->range_length() + TCPIP_HEADER_SIZE + RTP_HEADER_SIZE + RTP_HEADER_EXT_SIZE
            + RTP_PAYLOAD_ROOM_SIZE <= buffer->capacity()) {
        // The data fits into a single packet
        uint8_t *data = buffer->data();
        data[0] = 0x80;
        if (mRTPCVOExtMap > 0) {
            data[0] |= 0x10;
        }
        if (isNonVCL) {
            data[1] = mPayloadType;  // Marker bit should not be set in case of Non-VCL
        } else {
@@ -1017,16 +1019,51 @@ void ARTPWriter::sendHEVCData(MediaBufferBase *mediaBuf) {
        data[10] = (mSourceID >> 8) & 0xff;
        data[11] = mSourceID & 0xff;

        memcpy(&data[12],
        int rtpExtIndex = 0;
        if (mRTPCVOExtMap > 0) {
            /*
                0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |       0xBE    |    0xDE       |           length=3            |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |  ID   | L=0   |     data      |  ID   |  L=1  |   data...
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     ...data   |    0 (pad)    |    0 (pad)    |  ID   | L=3   |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |                          data                                 |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


              In the one-byte header form of extensions, the 16-bit value required
              by the RTP specification for a header extension, labeled in the RTP
              specification as "defined by profile", takes the fixed bit pattern
              0xBEDE (the first version of this specification was written on the
              feast day of the Venerable Bede).
            */
            data[12] = 0xBE;
            data[13] = 0xDE;
            // put a length of RTP Extension.
            data[14] = 0x00;
            data[15] = 0x01;
            // put extmap of RTP assigned for CVO.
            data[16] = (mRTPCVOExtMap << 4) | 0x0;
            // put image degrees as per CVO specification.
            data[17] = mRTPCVODegrees;
            data[18] = 0x0;
            data[19] = 0x0;
            rtpExtIndex = 8;
        }

        memcpy(&data[12 + rtpExtIndex],
               mediaData, mediaBuf->range_length());

        buffer->setRange(0, mediaBuf->range_length() + 12);
        buffer->setRange(0, mediaBuf->range_length() + (12 + rtpExtIndex));

        send(buffer, false /* isRTCP */);

        ++mSeqNo;
        ++mNumRTPSent;
        mNumRTPOctetsSent += buffer->size() - 12;
        mNumRTPOctetsSent += buffer->size() - (12 + rtpExtIndex);
    } else {
        // FU-A

@@ -1047,6 +1084,9 @@ void ARTPWriter::sendHEVCData(MediaBufferBase *mediaBuf) {

            uint8_t *data = buffer->data();
            data[0] = 0x80;
            if (lastPacket && mRTPCVOExtMap > 0) {
                data[0] |= 0x10;
            }
            data[1] = (lastPacket ? (1 << 7) : 0x00) | mPayloadType;  // M-bit
            data[2] = (mSeqNo >> 8) & 0xff;
            data[3] = mSeqNo & 0xff;
@@ -1059,6 +1099,19 @@ void ARTPWriter::sendHEVCData(MediaBufferBase *mediaBuf) {
            data[10] = (mSourceID >> 8) & 0xff;
            data[11] = mSourceID & 0xff;

            int rtpExtIndex = 0;
            if (lastPacket && mRTPCVOExtMap > 0) {
                data[12] = 0xBE;
                data[13] = 0xDE;
                data[14] = 0x00;
                data[15] = 0x01;
                data[16] = (mRTPCVOExtMap << 4) | 0x0;
                data[17] = mRTPCVODegrees;
                data[18] = 0x0;
                data[19] = 0x0;
                rtpExtIndex = 8;
            }

            /*  H265 payload header is 16 bit
                 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -1067,37 +1120,37 @@ void ARTPWriter::sendHEVCData(MediaBufferBase *mediaBuf) {
            */
            ALOGV("H265 payload header 0x%x %x", mediaData[0], mediaData[1]);
            // excludes Type from 1st byte of H265 payload header.
            data[12] = mediaData[0] & 0x81;
            data[12 + rtpExtIndex] = mediaData[0] & 0x81;
            // fills Type as FU (49 == 0x31)
            data[12] = data[12] | (0x31 << 1);
            data[13] = mediaData[1];
            data[12 + rtpExtIndex] = data[12 + rtpExtIndex] | (0x31 << 1);
            data[13 + rtpExtIndex] = mediaData[1];

            ALOGV("H265 FU header 0x%x %x", data[12], data[13]);
            ALOGV("H265 FU header 0x%x %x", data[12 + rtpExtIndex], data[13 + rtpExtIndex]);

            CHECK(!firstPacket || !lastPacket);
            /*
                FU INDICATOR HDR
                 0 1 2 3 4 5 6 7
                +-+-+-+-+-+-+-+
                +-+-+-+-+-+-+-+-+
                |S|E|   Type    |
                +-+-+-+-+-+-+-+
                +-+-+-+-+-+-+-+-+
            */

            data[14] =
            data[14 + rtpExtIndex] =
                (firstPacket ? 0x80 : 0x00)
                | (lastPacket ? 0x40 : 0x00)
                | (nalType & H265_NALU_MASK);
            ALOGV("H265 FU indicator 0x%x", data[14]);

            memcpy(&data[15], &mediaData[offset], size);
            memcpy(&data[15 + rtpExtIndex], &mediaData[offset], size);

            buffer->setRange(0, 15 + size);
            buffer->setRange(0, 15 + rtpExtIndex + size);

            send(buffer, false /* isRTCP */);

            ++mSeqNo;
            ++mNumRTPSent;
            mNumRTPOctetsSent += buffer->size() - 12;
            mNumRTPOctetsSent += buffer->size() - (12 + rtpExtIndex);

            firstPacket = false;
            offset += size;
@@ -1106,7 +1159,6 @@ void ARTPWriter::sendHEVCData(MediaBufferBase *mediaBuf) {

    mLastRTPTime = rtpTime;
    mLastNTPTime = GetNowNTP();

}

void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
@@ -1138,12 +1190,14 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
        // The data fits into a single packet
        uint8_t *data = buffer->data();
        data[0] = 0x80;
        if (mRTPCVOExtMap > 0)
        if (mRTPCVOExtMap > 0) {
            data[0] |= 0x10;
        if (isSpsPps)
        }
        if (isSpsPps) {
            data[1] = mPayloadType;  // Marker bit should not be set in case of sps/pps
        else
        } else {
            data[1] = (1 << 7) | mPayloadType;
        }
        data[2] = (mSeqNo >> 8) & 0xff;
        data[3] = mSeqNo & 0xff;
        data[4] = rtpTime >> 24;
@@ -1203,7 +1257,8 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
    } else {
        // FU-A

        unsigned nalType = mediaData[0];
        unsigned nalType = mediaData[0] & H264_NALU_MASK;
        ALOGV("H264 nalType 0x%x, data[0]=0x%x", nalType, mediaData[0]);
        size_t offset = 1;

        bool firstPacket = true;
@@ -1219,8 +1274,9 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {

            uint8_t *data = buffer->data();
            data[0] = 0x80;
            if (lastPacket && mRTPCVOExtMap > 0)
            if (lastPacket && mRTPCVOExtMap > 0) {
                data[0] |= 0x10;
            }
            data[1] = (lastPacket ? (1 << 7) : 0x00) | mPayloadType;  // M-bit
            data[2] = (mSeqNo >> 8) & 0xff;
            data[3] = mSeqNo & 0xff;
@@ -1246,14 +1302,32 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
                rtpExtIndex = 8;
            }

            data[12 + rtpExtIndex] = 28 | (nalType & 0xe0);
            /*  H264 payload header is 8 bit
                 0 1 2 3 4 5 6 7
                +-+-+-+-+-+-+-+-+
                |F|NRI|  Type   |
                +-+-+-+-+-+-+-+-+
            */
            ALOGV("H264 payload header 0x%x", mediaData[0]);
            // excludes Type from 1st byte of H264 payload header.
            data[12 + rtpExtIndex] = mediaData[0] & 0xe0;
            // fills Type as FU (28 == 0x1C)
            data[12 + rtpExtIndex] = data[12 + rtpExtIndex] | 0x1C;

            CHECK(!firstPacket || !lastPacket);
            /*
                FU header
                 0 1 2 3 4 5 6 7
                +-+-+-+-+-+-+-+-+
                |S|E|R|  Type   |
                +-+-+-+-+-+-+-+-+
            */

            data[13 + rtpExtIndex] =
                (firstPacket ? 0x80 : 0x00)
                | (lastPacket ? 0x40 : 0x00)
                | (nalType & 0x1f);
                | (nalType & H264_NALU_MASK);
            ALOGV("H264 FU header 0x%x", data[13]);

            memcpy(&data[14 + rtpExtIndex], &mediaData[offset], size);