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

Commit dca73b8f authored by Andreas Huber's avatar Andreas Huber
Browse files

In "special" mode we now establish a UDP RTCP channel in addition to the

TCP RTP channel and provide feedback on the latency of arriving packets from
the sink back to the source. This information is then used to throttle
video bitrate.

Change-Id: Ic589a3cb65e4893a3ff67de947da6063d32a1c6e
parent d3d9263c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -565,7 +565,7 @@ status_t ANetworkSession::Session::writeMore() {
        mSawSendFailure = true;
    }

#if 1
#if 0
    int numBytesQueued;
    int res = ioctl(mSocket, SIOCOUTQ, &numBytesQueued);
    if (res == 0 && numBytesQueued > 50 * 1024) {
@@ -576,7 +576,7 @@ status_t ANetworkSession::Session::writeMore() {
        int64_t nowUs = ALooper::GetNowUs();

        if (mLastStallReportUs < 0ll
                || nowUs > mLastStallReportUs + 500000ll) {
                || nowUs > mLastStallReportUs + 100000ll) {
            sp<AMessage> msg = mNotify->dup();
            msg->setInt32("sessionID", mSessionID);
            msg->setInt32("reason", kWhatNetworkStall);
+22 −10
Original line number Diff line number Diff line
@@ -85,10 +85,11 @@ ssize_t MediaSender::addTrack(const sp<AMessage> &format, uint32_t flags) {

status_t MediaSender::initAsync(
        ssize_t trackIndex,
        RTPSender::TransportMode transportMode,
        const char *remoteHost,
        int32_t remoteRTPPort,
        RTPSender::TransportMode rtpMode,
        int32_t remoteRTCPPort,
        RTPSender::TransportMode rtcpMode,
        int32_t *localRTPPort) {
    if (trackIndex < 0) {
        if (mMode != MODE_UNDEFINED) {
@@ -126,12 +127,9 @@ status_t MediaSender::initAsync(
            err = mTSSender->initAsync(
                    remoteHost,
                    remoteRTPPort,
                    transportMode,  // rtpMode
                    rtpMode,
                    remoteRTCPPort,
                    (transportMode == RTPSender::TRANSPORT_UDP
                        && remoteRTCPPort >= 0)
                        ? transportMode
                        : RTPSender::TRANSPORT_NONE,  // rtcpMode
                    rtcpMode,
                    localRTPPort);

            if (err != OK) {
@@ -180,11 +178,9 @@ status_t MediaSender::initAsync(
    status_t err = info->mSender->initAsync(
            remoteHost,
            remoteRTPPort,
            transportMode,  // rtpMode
            rtpMode,
            remoteRTCPPort,
            (transportMode == RTPSender::TRANSPORT_UDP && remoteRTCPPort >= 0)
                ? transportMode
                : RTPSender::TRANSPORT_NONE,  // rtcpMode
            rtcpMode,
            localRTPPort);

    if (err != OK) {
@@ -345,6 +341,22 @@ void MediaSender::onSenderNotify(const sp<AMessage> &msg) {
            break;
        }

        case kWhatInformSender:
        {
            int64_t avgLatencyUs;
            CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));

            int64_t maxLatencyUs;
            CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));

            sp<AMessage> notify = mNotify->dup();
            notify->setInt32("what", kWhatInformSender);
            notify->setInt64("avgLatencyUs", avgLatencyUs);
            notify->setInt64("maxLatencyUs", maxLatencyUs);
            notify->post();
            break;
        }

        default:
            TRESPASS();
    }
+3 −1
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ struct MediaSender : public AHandler {
        kWhatInitDone,
        kWhatError,
        kWhatNetworkStall,
        kWhatInformSender,
    };

    MediaSender(
@@ -59,10 +60,11 @@ struct MediaSender : public AHandler {
    // If trackIndex == -1, initialize for transport stream muxing.
    status_t initAsync(
            ssize_t trackIndex,
            RTPSender::TransportMode transportMode,
            const char *remoteHost,
            int32_t remoteRTPPort,
            RTPSender::TransportMode rtpMode,
            int32_t remoteRTCPPort,
            RTPSender::TransportMode rtcpMode,
            int32_t *localRTPPort);

    status_t queueAccessUnit(
+18 −2
Original line number Diff line number Diff line
@@ -91,8 +91,8 @@ status_t RTPSender::initAsync(
    CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
    CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);

    if (rtcpMode == TRANSPORT_NONE && remoteRTCPPort >= 0
            || rtcpMode != TRANSPORT_NONE && remoteRTCPPort < 0) {
    if ((rtcpMode == TRANSPORT_NONE && remoteRTCPPort >= 0)
            || (rtcpMode != TRANSPORT_NONE && remoteRTCPPort < 0)) {
        return INVALID_OPERATION;
    }

@@ -616,6 +616,7 @@ status_t RTPSender::onRTCPData(const sp<ABuffer> &buffer) {
                break;

            case 204:  // APP
                parseAPP(data, headerLength);
                break;

            case 205:  // TSFB (transport layer specific feedback)
@@ -721,6 +722,21 @@ status_t RTPSender::parseTSFB(const uint8_t *data, size_t size) {
    return OK;
}

status_t RTPSender::parseAPP(const uint8_t *data, size_t size) {
    if (!memcmp("late", &data[8], 4)) {
        int64_t avgLatencyUs = (int64_t)U64_AT(&data[12]);
        int64_t maxLatencyUs = (int64_t)U64_AT(&data[20]);

        sp<AMessage> notify = mNotify->dup();
        notify->setInt32("what", kWhatInformSender);
        notify->setInt64("avgLatencyUs", avgLatencyUs);
        notify->setInt64("maxLatencyUs", maxLatencyUs);
        notify->post();
    }

    return OK;
}

void RTPSender::notifyInitDone(status_t err) {
    sp<AMessage> notify = mNotify->dup();
    notify->setInt32("what", kWhatInitDone);
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ struct RTPSender : public RTPBase, public AHandler {
        kWhatInitDone,
        kWhatError,
        kWhatNetworkStall,
        kWhatInformSender,
    };
    RTPSender(
            const sp<ANetworkSession> &netSession,
@@ -105,6 +106,7 @@ private:
    status_t onRTCPData(const sp<ABuffer> &data);
    status_t parseReceiverReport(const uint8_t *data, size_t size);
    status_t parseTSFB(const uint8_t *data, size_t size);
    status_t parseAPP(const uint8_t *data, size_t size);

    void notifyInitDone(status_t err);
    void notifyError(status_t err);
Loading