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

Commit 6552d60d authored by Byeongjo Park's avatar Byeongjo Park Committed by Lajos Molnar
Browse files

VT: SFR: H264: CVO implementation for Tx side.



CVO(Coordination of Video Orientation) implemented for H264.

Support Coordination of Video Orientation (CVO) feature that carried in RTP Header extension.
it updates a device degrees(orientation) on RTP extension when device is rotated.
(6.2.3 of 3GPP Release 12 TS 26.114)

- rtp-param-ext-cvo-degrees: updates how much degress should be rotated.
- rtp-param-ext-cvo-extmap: updates what extmap CVO mapped in SDP negoration.

Merged-in: I49ab063d549b033aef06eadf39fd189384a5f724
Change-Id: I49ab063d549b033aef06eadf39fd189384a5f724
Signed-off-by: default avatarByeongjo Park <bjo.park@samsung.com>
Signed-off-by: default avatarKim Sungyeon <sy85.kim@samsung.com>
parent ebf1e771
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -117,6 +117,8 @@ StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName)
      mAudioSource((audio_source_t)AUDIO_SOURCE_CNT), // initialize with invalid value
      mPrivacySensitive(PRIVACY_SENSITIVE_DEFAULT),
      mVideoSource(VIDEO_SOURCE_LIST_END),
      mRTPCVOExtMap(-1),
      mRTPCVODegrees(0),
      mStarted(false),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mDeviceCallbackEnabled(false),
@@ -832,6 +834,26 @@ status_t StagefrightRecorder::setParamPayloadType(int32_t payloadType) {
    return OK;
}

status_t StagefrightRecorder::setRTPCVOExtMap(int32_t extmap) {
    ALOGV("setRtpCvoExtMap: %d", extmap);

    mRTPCVOExtMap = extmap;
    return OK;
}

status_t StagefrightRecorder::setRTPCVODegrees(int32_t cvoDegrees) {
    Mutex::Autolock autolock(mLock);
    ALOGV("setRtpCvoDegrees: %d", cvoDegrees);

    mRTPCVODegrees = cvoDegrees;

    if (mStarted && mOutputFormat == OUTPUT_FORMAT_RTP_AVP) {
        mWriter->updateCVODegrees(mRTPCVODegrees);
    }

    return OK;
}

status_t StagefrightRecorder::setParameter(
        const String8 &key, const String8 &value) {
    ALOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -966,6 +988,16 @@ status_t StagefrightRecorder::setParameter(
        if (safe_strtoi32(value.string(), &payloadType)) {
            return setParamPayloadType(payloadType);
        }
    } else if (key == "rtp-param-ext-cvo-extmap") {
        int32_t extmap;
        if (safe_strtoi32(value.string(), &extmap)) {
            return setRTPCVOExtMap(extmap);
        }
    } else if (key == "rtp-param-ext-cvo-degrees") {
        int32_t degrees;
        if (safe_strtoi32(value.string(), &degrees)) {
            return setRTPCVODegrees(degrees);
        }
    } else {
        ALOGE("setParameter: failed to find key %s", key.string());
    }
@@ -1134,6 +1166,10 @@ status_t StagefrightRecorder::start() {
            meta->setInt64(kKeyTime, startTimeUs);
            meta->setInt32(kKeySelfID, mSelfID);
            meta->setInt32(kKeyPayloadType, mPayloadType);
            if (mRTPCVOExtMap > 0) {
                meta->setInt32(kKeyRtpExtMap, mRTPCVOExtMap);
                meta->setInt32(kKeyRtpCvoDegrees, mRTPCVODegrees);
            }
            status = mWriter->start(meta.get());
            break;
        }
+4 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ private:
    int32_t mRemotePort;
    int32_t mSelfID;
    int32_t mPayloadType;
    int32_t mRTPCVOExtMap;
    int32_t mRTPCVODegrees;

    int64_t mDurationRecordedUs;
    int64_t mStartedRecordingUs;
@@ -231,6 +233,8 @@ private:
    status_t setParamRtpRemotePort(int32_t remotePort);
    status_t setParamSelfID(int32_t selfID);
    status_t setParamPayloadType(int32_t payloadType);
    status_t setRTPCVOExtMap(int32_t extmap);
    status_t setRTPCVODegrees(int32_t cvoDegrees);
    void clipVideoBitRate();
    void clipVideoFrameRate();
    void clipVideoFrameWidth();
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ struct MediaWriter : public RefBase {
    virtual void setStartTimeOffsetMs(int /*ms*/) {}
    virtual int32_t getStartTimeOffsetMs() const { return 0; }
    virtual status_t setNextFd(int /*fd*/) { return INVALID_OPERATION; }

    virtual void updateCVODegrees(int32_t /*cvoDegrees*/) {}
protected:
    virtual ~MediaWriter() {}
    int64_t mMaxFileSizeLimitBytes;
+2 −0
Original line number Diff line number Diff line
@@ -251,6 +251,8 @@ enum {
    kKeyPps              = 'sPps', // int32_t, indicates that a buffer is pps.
    kKeySelfID           = 'sfid', // int32_t, source ID to identify itself on RTP protocol.
    kKeyPayloadType      = 'pTyp', // int32_t, SDP negotiated payload type.
    kKeyRtpExtMap        = 'extm', // int32_t, rtp extension ID for cvo on RTP protocol.
    kKeyRtpCvoDegrees    = 'cvod', // int32_t, rtp cvo degrees as per 3GPP 26.114.
};

enum {
+75 −11
Original line number Diff line number Diff line
@@ -198,6 +198,8 @@ status_t ARTPWriter::start(MetaData * params) {
    mLastRTPTime = 0;
    mLastNTPTime = 0;
    mNumSRsSent = 0;
    mRTPCVOExtMap = -1;
    mRTPCVODegrees = 0;

    const char *mime;
    CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));
@@ -206,13 +208,18 @@ status_t ARTPWriter::start(MetaData * params) {
    if(params->findInt32(kKeySelfID, &selfID))
        mSourceID = selfID;

    if (mPayloadType == 0)
        mPayloadType = PT;

    int32_t payloadType = 0;
    if(params->findInt32(kKeyPayloadType, &payloadType))
        mPayloadType = payloadType;

    int32_t rtpExtMap = 0;
    if(params->findInt32(kKeyRtpExtMap, &rtpExtMap))
        mRTPCVOExtMap = rtpExtMap;

    int32_t rtpCVODegrees = 0;
    if(params->findInt32(kKeyRtpCvoDegrees, &rtpCVODegrees))
        mRTPCVODegrees = rtpCVODegrees;

    mMode = INVALID;
    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
        mMode = H264;
@@ -898,6 +905,8 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
        // The data fits into a single packet
        uint8_t *data = buffer->data();
        data[0] = 0x80;
        if (mRTPCVOExtMap > 0)
            data[0] |= 0x10;
        if (isSpsPps)
            data[1] = mPayloadType;  // Marker bit should not be set in case of sps/pps
        else
@@ -913,16 +922,51 @@ void ARTPWriter::sendAVCData(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

@@ -942,6 +986,8 @@ void ARTPWriter::sendAVCData(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;
@@ -954,24 +1000,37 @@ void ARTPWriter::sendAVCData(MediaBufferBase *mediaBuf) {
            data[10] = (mSourceID >> 8) & 0xff;
            data[11] = mSourceID & 0xff;

            data[12] = 28 | (nalType & 0xe0);
            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;
            }

            data[12 + rtpExtIndex] = 28 | (nalType & 0xe0);

            CHECK(!firstPacket || !lastPacket);

            data[13] =
            data[13 + rtpExtIndex] =
                (firstPacket ? 0x80 : 0x00)
                | (lastPacket ? 0x40 : 0x00)
                | (nalType & 0x1f);

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

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

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

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

            firstPacket = false;
            offset += size;
@@ -1044,6 +1103,11 @@ void ARTPWriter::sendH263Data(MediaBufferBase *mediaBuf) {
    mLastNTPTime = GetNowNTP();
}

void ARTPWriter::updateCVODegrees(int32_t cvoDegrees) {
    Mutex::Autolock autoLock(mLock);
    mRTPCVODegrees = cvoDegrees;
}

static size_t getFrameSize(bool isWide, unsigned FT) {
    static const size_t kFrameSizeNB[8] = {
        95, 103, 118, 134, 148, 159, 204, 244
Loading