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

Commit 6e98aba4 authored by Andreas Huber's avatar Andreas Huber
Browse files

Separate the mode of the RTP and RTCP channels.

I now can use a TCP reliable data channel with a UDP back channel.

Change-Id: Ieb0f0970e3a6da4cff250e9547e181c0c961b9fb
parent a97d15e2
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -73,7 +73,12 @@ ssize_t MediaReceiver::addTrack(
    info.mReceiver->registerPacketType(
            97, RTPReceiver::PACKETIZATION_H264);

    status_t err = info.mReceiver->initAsync(transportMode, localRTPPort);
    status_t err = info.mReceiver->initAsync(
            transportMode,  // rtpMode
            transportMode == RTPReceiver::TRANSPORT_UDP
                ? transportMode
                : RTPReceiver::TRANSPORT_NONE,  // rtcpMode
            localRTPPort);

    if (err != OK) {
        looper()->unregisterHandler(info.mReceiver->id());
+9 −2
Original line number Diff line number Diff line
@@ -124,10 +124,14 @@ status_t MediaSender::initAsync(
            looper()->registerHandler(mTSSender);

            err = mTSSender->initAsync(
                    transportMode,
                    remoteHost,
                    remoteRTPPort,
                    transportMode,  // rtpMode
                    remoteRTCPPort,
                    (transportMode == RTPSender::TRANSPORT_UDP
                        && remoteRTCPPort >= 0)
                        ? transportMode
                        : RTPSender::TRANSPORT_NONE,  // rtcpMode
                    localRTPPort);

            if (err != OK) {
@@ -174,10 +178,13 @@ status_t MediaSender::initAsync(
    looper()->registerHandler(info->mSender);

    status_t err = info->mSender->initAsync(
            transportMode,
            remoteHost,
            remoteRTPPort,
            transportMode,  // rtpMode
            remoteRTCPPort,
            (transportMode == RTPSender::TRANSPORT_UDP && remoteRTCPPort >= 0)
                ? transportMode
                : RTPSender::TRANSPORT_NONE,  // rtcpMode
            localRTPPort);

    if (err != OK) {
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ struct RTPBase {

    enum TransportMode {
        TRANSPORT_UNDEFINED,
        TRANSPORT_NONE,
        TRANSPORT_UDP,
        TRANSPORT_TCP,
        TRANSPORT_TCP_INTERLEAVED,
+99 −44
Original line number Diff line number Diff line
@@ -407,13 +407,22 @@ RTPReceiver::RTPReceiver(
        const sp<AMessage> &notify)
    : mNetSession(netSession),
      mNotify(notify),
      mMode(TRANSPORT_UNDEFINED),
      mRTPMode(TRANSPORT_UNDEFINED),
      mRTCPMode(TRANSPORT_UNDEFINED),
      mRTPSessionID(0),
      mRTCPSessionID(0),
      mRTPClientSessionID(0) {
      mRTPConnected(false),
      mRTCPConnected(false),
      mRTPClientSessionID(0),
      mRTCPClientSessionID(0) {
}

RTPReceiver::~RTPReceiver() {
    if (mRTCPClientSessionID != 0) {
        mNetSession->destroySession(mRTCPClientSessionID);
        mRTCPClientSessionID = 0;
    }

    if (mRTPClientSessionID != 0) {
        mNetSession->destroySession(mRTPClientSessionID);
        mRTPClientSessionID = 0;
@@ -430,17 +439,24 @@ RTPReceiver::~RTPReceiver() {
    }
}

status_t RTPReceiver::initAsync(TransportMode mode, int32_t *outLocalRTPPort) {
    if (mMode != TRANSPORT_UNDEFINED || mode == TRANSPORT_UNDEFINED) {
status_t RTPReceiver::initAsync(
        TransportMode rtpMode,
        TransportMode rtcpMode,
        int32_t *outLocalRTPPort) {
    if (mRTPMode != TRANSPORT_UNDEFINED
            || rtpMode == TRANSPORT_UNDEFINED
            || rtpMode == TRANSPORT_NONE
            || rtcpMode == TRANSPORT_UNDEFINED) {
        return INVALID_OPERATION;
    }

    CHECK_NE(mMode, TRANSPORT_TCP_INTERLEAVED);
    CHECK_NE(rtpMode, TRANSPORT_TCP_INTERLEAVED);
    CHECK_NE(rtcpMode, TRANSPORT_TCP_INTERLEAVED);

    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());

    sp<AMessage> rtcpNotify;
    if (mode == TRANSPORT_UDP) {
    if (rtcpMode != TRANSPORT_NONE) {
        rtcpNotify = new AMessage(kWhatRTCPNotify, id());
    }

@@ -456,13 +472,13 @@ status_t RTPReceiver::initAsync(TransportMode mode, int32_t *outLocalRTPPort) {
        localRTPPort = PickRandomRTPPort();

        status_t err;
        if (mode == TRANSPORT_UDP) {
        if (rtpMode == TRANSPORT_UDP) {
            err = mNetSession->createUDPSession(
                    localRTPPort,
                    rtpNotify,
                    &mRTPSessionID);
        } else {
            CHECK_EQ(mode, TRANSPORT_TCP);
            CHECK_EQ(rtpMode, TRANSPORT_TCP);
            err = mNetSession->createTCPDatagramSession(
                    ifaceAddr,
                    localRTPPort,
@@ -474,14 +490,21 @@ status_t RTPReceiver::initAsync(TransportMode mode, int32_t *outLocalRTPPort) {
            continue;
        }

        if (mode == TRANSPORT_TCP) {
        if (rtcpMode == TRANSPORT_NONE) {
            break;
        }

        } else if (rtcpMode == TRANSPORT_UDP) {
            err = mNetSession->createUDPSession(
                    localRTPPort + 1,
                    rtcpNotify,
                    &mRTCPSessionID);
        } else {
            CHECK_EQ(rtpMode, TRANSPORT_TCP);
            err = mNetSession->createTCPDatagramSession(
                    ifaceAddr,
                    localRTPPort + 1,
                    rtcpNotify,
                    &mRTCPSessionID);
        }

        if (err == OK) {
            break;
@@ -491,7 +514,8 @@ status_t RTPReceiver::initAsync(TransportMode mode, int32_t *outLocalRTPPort) {
        mRTPSessionID = 0;
    }

    mMode = mode;
    mRTPMode = rtpMode;
    mRTCPMode = rtcpMode;
    *outLocalRTPPort = localRTPPort;

    return OK;
@@ -499,11 +523,12 @@ status_t RTPReceiver::initAsync(TransportMode mode, int32_t *outLocalRTPPort) {

status_t RTPReceiver::connect(
        const char *remoteHost, int32_t remoteRTPPort, int32_t remoteRTCPPort) {
    if (mMode == TRANSPORT_TCP) {
        return OK;
    }
    status_t err;

    status_t err = mNetSession->connectUDPSession(
    if (mRTPMode == TRANSPORT_UDP) {
        CHECK(!mRTPConnected);

        err = mNetSession->connectUDPSession(
                mRTPSessionID, remoteHost, remoteRTPPort);

        if (err != OK) {
@@ -513,21 +538,31 @@ status_t RTPReceiver::connect(

        ALOGI("connectUDPSession RTP successful.");

    if (remoteRTCPPort >= 0) {
        mRTPConnected = true;
    }

    if (mRTCPMode == TRANSPORT_UDP) {
        CHECK(!mRTCPConnected);

        err = mNetSession->connectUDPSession(
                mRTCPSessionID, remoteHost, remoteRTCPPort);

        if (err != OK) {
        ALOGI("connect failed w/ err %d", err);

            notifyInitDone(err);
            return err;
        }

        scheduleSendRR();

        ALOGI("connectUDPSession RTCP successful.");

        mRTCPConnected = true;
    }

    if (mRTPConnected
            && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
        notifyInitDone(OK);
    }

    return OK;
}
@@ -615,15 +650,18 @@ void RTPReceiver::onNetNotify(bool isRTP, const sp<AMessage> &msg) {

            if (sessionID == mRTPSessionID) {
                mRTPSessionID = 0;

                if (mMode == TRANSPORT_TCP && mRTPClientSessionID == 0) {
                    notifyInitDone(err);
                    break;
                }
            } else if (sessionID == mRTCPSessionID) {
                mRTCPSessionID = 0;
            } else if (sessionID == mRTPClientSessionID) {
                mRTPClientSessionID = 0;
            } else if (sessionID == mRTCPClientSessionID) {
                mRTCPClientSessionID = 0;
            }

            if (!mRTPConnected
                    || (mRTCPMode != TRANSPORT_NONE && !mRTCPConnected)) {
                notifyInitDone(err);
                break;
            }

            notifyError(err);
@@ -645,12 +683,12 @@ void RTPReceiver::onNetNotify(bool isRTP, const sp<AMessage> &msg) {

        case ANetworkSession::kWhatClientConnected:
        {
            CHECK_EQ(mMode, TRANSPORT_TCP);
            CHECK(isRTP);

            int32_t sessionID;
            CHECK(msg->findInt32("sessionID", &sessionID));

            if (isRTP) {
                CHECK_EQ(mRTPMode, TRANSPORT_TCP);

                if (mRTPClientSessionID != 0) {
                    // We only allow a single client connection.
                    mNetSession->destroySession(sessionID);
@@ -659,8 +697,25 @@ void RTPReceiver::onNetNotify(bool isRTP, const sp<AMessage> &msg) {
                }

                mRTPClientSessionID = sessionID;
                mRTPConnected = true;
            } else {
                CHECK_EQ(mRTCPMode, TRANSPORT_TCP);

                if (mRTCPClientSessionID != 0) {
                    // We only allow a single client connection.
                    mNetSession->destroySession(sessionID);
                    sessionID = 0;
                    break;
                }

                mRTCPClientSessionID = sessionID;
                mRTCPConnected = true;
            }

            if (mRTPConnected
                    && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) {
                notifyInitDone(OK);
            }
            break;
        }
    }
+9 −2
Original line number Diff line number Diff line
@@ -46,7 +46,10 @@ struct RTPReceiver : public RTPBase, public AHandler {
    status_t registerPacketType(
            uint8_t packetType, PacketizationMode mode);

    status_t initAsync(TransportMode mode, int32_t *outLocalRTPPort);
    status_t initAsync(
            TransportMode rtpMode,
            TransportMode rtcpMode,
            int32_t *outLocalRTPPort);

    status_t connect(
            const char *remoteHost,
@@ -79,11 +82,15 @@ private:

    sp<ANetworkSession> mNetSession;
    sp<AMessage> mNotify;
    TransportMode mMode;
    TransportMode mRTPMode;
    TransportMode mRTCPMode;
    int32_t mRTPSessionID;
    int32_t mRTCPSessionID;
    bool mRTPConnected;
    bool mRTCPConnected;

    int32_t mRTPClientSessionID;  // in TRANSPORT_TCP mode.
    int32_t mRTCPClientSessionID;  // in TRANSPORT_TCP mode.

    KeyedVector<uint8_t, PacketizationMode> mPacketTypes;
    KeyedVector<uint32_t, sp<Source> > mSources;
Loading