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

Commit 8784f4cb authored by Byeongjo Park's avatar Byeongjo Park Committed by Kim Sungyeon
Browse files

VT: Supports cvo mode for H265 stream.



[Problem] video rotated wrongly if H.265 stream.
[Cause] CVO is not implemented yet for H.265 stream.
[Solution] Implements CVO for H.265

* Some expressions used in this H.265 sendHEVCData()
  copied on the same function part of H.264 for consistency.

Bug: 192326376

Signed-off-by: default avatarByeongjo Park <bjo.park@samsung.com>
Change-Id: I5f6331e40bb5102b823ec0f8fce07bd448baad4f
Signed-off-by: default avatarKim Sungyeon <sy85.kim@samsung.com>
parent 6e47c8dd
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);