From 6e98aba4d23d00cab236d993d895f57ea76ea0e5 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 22 Mar 2013 09:56:29 -0700 Subject: 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 --- .../libstagefright/wifi-display/MediaReceiver.cpp | 7 +- media/libstagefright/wifi-display/MediaSender.cpp | 11 +- media/libstagefright/wifi-display/rtp/RTPBase.h | 1 + .../wifi-display/rtp/RTPReceiver.cpp | 143 ++++++++++++++------- .../libstagefright/wifi-display/rtp/RTPReceiver.h | 11 +- .../libstagefright/wifi-display/rtp/RTPSender.cpp | 55 +++++--- media/libstagefright/wifi-display/rtp/RTPSender.h | 6 +- media/libstagefright/wifi-display/rtptest.cpp | 7 +- 8 files changed, 167 insertions(+), 74 deletions(-) diff --git a/media/libstagefright/wifi-display/MediaReceiver.cpp b/media/libstagefright/wifi-display/MediaReceiver.cpp index 10a2dff..e2e791d 100644 --- a/media/libstagefright/wifi-display/MediaReceiver.cpp +++ b/media/libstagefright/wifi-display/MediaReceiver.cpp @@ -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()); diff --git a/media/libstagefright/wifi-display/MediaSender.cpp b/media/libstagefright/wifi-display/MediaSender.cpp index d13a92e..6fc50f7 100644 --- a/media/libstagefright/wifi-display/MediaSender.cpp +++ b/media/libstagefright/wifi-display/MediaSender.cpp @@ -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) { diff --git a/media/libstagefright/wifi-display/rtp/RTPBase.h b/media/libstagefright/wifi-display/rtp/RTPBase.h index 6507a6f..e3fa845 100644 --- a/media/libstagefright/wifi-display/rtp/RTPBase.h +++ b/media/libstagefright/wifi-display/rtp/RTPBase.h @@ -29,6 +29,7 @@ struct RTPBase { enum TransportMode { TRANSPORT_UNDEFINED, + TRANSPORT_NONE, TRANSPORT_UDP, TRANSPORT_TCP, TRANSPORT_TCP_INTERLEAVED, diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp b/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp index 8711b08..c55e0be 100644 --- a/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp +++ b/media/libstagefright/wifi-display/rtp/RTPReceiver.cpp @@ -407,13 +407,22 @@ RTPReceiver::RTPReceiver( const sp ¬ify) : 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 rtpNotify = new AMessage(kWhatRTPNotify, id()); sp 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,15 +490,22 @@ 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); } - err = mNetSession->createUDPSession( - 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,35 +523,46 @@ 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; + + if (mRTPMode == TRANSPORT_UDP) { + CHECK(!mRTPConnected); + + err = mNetSession->connectUDPSession( + mRTPSessionID, remoteHost, remoteRTPPort); + + if (err != OK) { + notifyInitDone(err); + return err; + } - status_t err = mNetSession->connectUDPSession( - mRTPSessionID, remoteHost, remoteRTPPort); + ALOGI("connectUDPSession RTP successful."); - if (err != OK) { - notifyInitDone(err); - return err; + mRTPConnected = true; } - ALOGI("connectUDPSession RTP successful."); + if (mRTCPMode == TRANSPORT_UDP) { + CHECK(!mRTCPConnected); - if (remoteRTCPPort >= 0) { 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; } - notifyInitDone(OK); + if (mRTPConnected + && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) { + notifyInitDone(OK); + } return OK; } @@ -615,15 +650,18 @@ void RTPReceiver::onNetNotify(bool isRTP, const sp &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,22 +683,39 @@ void RTPReceiver::onNetNotify(bool isRTP, const sp &msg) { case ANetworkSession::kWhatClientConnected: { - CHECK_EQ(mMode, TRANSPORT_TCP); - CHECK(isRTP); - int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); - if (mRTPClientSessionID != 0) { - // We only allow a single client connection. - mNetSession->destroySession(sessionID); - sessionID = 0; - break; - } + if (isRTP) { + CHECK_EQ(mRTPMode, TRANSPORT_TCP); - mRTPClientSessionID = sessionID; + if (mRTPClientSessionID != 0) { + // We only allow a single client connection. + mNetSession->destroySession(sessionID); + sessionID = 0; + break; + } + + 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; + } - notifyInitDone(OK); + mRTCPClientSessionID = sessionID; + mRTCPConnected = true; + } + + if (mRTPConnected + && (mRTCPConnected || mRTCPMode == TRANSPORT_NONE)) { + notifyInitDone(OK); + } break; } } diff --git a/media/libstagefright/wifi-display/rtp/RTPReceiver.h b/media/libstagefright/wifi-display/rtp/RTPReceiver.h index ec4671d..abbe6a8 100644 --- a/media/libstagefright/wifi-display/rtp/RTPReceiver.h +++ b/media/libstagefright/wifi-display/rtp/RTPReceiver.h @@ -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 mNetSession; sp 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 mPacketTypes; KeyedVector > mSources; diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp index c8e265c..c686e01 100644 --- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp +++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp @@ -38,7 +38,8 @@ RTPSender::RTPSender( const sp ¬ify) : mNetSession(netSession), mNotify(notify), - mMode(TRANSPORT_UNDEFINED), + mRTPMode(TRANSPORT_UNDEFINED), + mRTCPMode(TRANSPORT_UNDEFINED), mRTPSessionID(0), mRTCPSessionID(0), mRTPConnected(false), @@ -74,18 +75,24 @@ int32_t RTPBase::PickRandomRTPPort() { } status_t RTPSender::initAsync( - TransportMode mode, const char *remoteHost, int32_t remoteRTPPort, + TransportMode rtpMode, int32_t remoteRTCPPort, + TransportMode rtcpMode, int32_t *outLocalRTPPort) { - if (mMode != TRANSPORT_UNDEFINED || mode == TRANSPORT_UNDEFINED) { + 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); - if (mode == TRANSPORT_TCP && remoteRTCPPort >= 0) { + if (rtcpMode == TRANSPORT_NONE && remoteRTCPPort >= 0 + || rtcpMode != TRANSPORT_NONE && remoteRTCPPort < 0) { return INVALID_OPERATION; } @@ -105,7 +112,7 @@ status_t RTPSender::initAsync( localRTPPort = PickRandomRTPPort(); status_t err; - if (mode == TRANSPORT_UDP) { + if (rtpMode == TRANSPORT_UDP) { err = mNetSession->createUDPSession( localRTPPort, remoteHost, @@ -113,7 +120,7 @@ status_t RTPSender::initAsync( rtpNotify, &mRTPSessionID); } else { - CHECK_EQ(mode, TRANSPORT_TCP); + CHECK_EQ(rtpMode, TRANSPORT_TCP); err = mNetSession->createTCPDatagramSession( localRTPPort, remoteHost, @@ -130,7 +137,7 @@ status_t RTPSender::initAsync( break; } - if (mode == TRANSPORT_UDP) { + if (rtcpMode == TRANSPORT_UDP) { err = mNetSession->createUDPSession( localRTPPort + 1, remoteHost, @@ -138,7 +145,7 @@ status_t RTPSender::initAsync( rtcpNotify, &mRTCPSessionID); } else { - CHECK_EQ(mode, TRANSPORT_TCP); + CHECK_EQ(rtcpMode, TRANSPORT_TCP); err = mNetSession->createTCPDatagramSession( localRTPPort + 1, remoteHost, @@ -155,15 +162,20 @@ status_t RTPSender::initAsync( mRTPSessionID = 0; } - if (mode == TRANSPORT_UDP) { + if (rtpMode == TRANSPORT_UDP) { mRTPConnected = true; + } + + if (rtcpMode == TRANSPORT_UDP) { mRTCPConnected = true; } - mMode = mode; + mRTPMode = rtpMode; + mRTCPMode = rtcpMode; *outLocalRTPPort = localRTPPort; - if (mMode == TRANSPORT_UDP) { + if (mRTPMode == TRANSPORT_UDP + && (mRTCPMode == TRANSPORT_UDP || mRTCPMode == TRANSPORT_NONE)) { notifyInitDone(OK); } @@ -496,12 +508,12 @@ void RTPSender::onNetNotify(bool isRTP, const sp &msg) { mRTCPSessionID = 0; } - if (mMode == TRANSPORT_TCP) { - if (!mRTPConnected - || (mRTCPSessionID > 0 && !mRTCPConnected)) { - notifyInitDone(err); - break; - } + if (!mRTPConnected + || (mRTPMode != TRANSPORT_NONE && !mRTCPConnected)) { + // We haven't completed initialization, attach the error + // to the notification instead. + notifyInitDone(err); + break; } notifyError(err); @@ -523,20 +535,21 @@ void RTPSender::onNetNotify(bool isRTP, const sp &msg) { case ANetworkSession::kWhatConnected: { - CHECK_EQ(mMode, TRANSPORT_TCP); - int32_t sessionID; CHECK(msg->findInt32("sessionID", &sessionID)); if (isRTP) { + CHECK_EQ(mRTPMode, TRANSPORT_TCP); CHECK_EQ(sessionID, mRTPSessionID); mRTPConnected = true; } else { + CHECK_EQ(mRTCPMode, TRANSPORT_TCP); CHECK_EQ(sessionID, mRTCPSessionID); mRTCPConnected = true; } - if (mRTPConnected && (mRTCPSessionID == 0 || mRTCPConnected)) { + if (mRTPConnected + && (mRTCPMode == TRANSPORT_NONE || mRTCPConnected)) { notifyInitDone(OK); } break; diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.h b/media/libstagefright/wifi-display/rtp/RTPSender.h index 90b1796..8409b8d 100644 --- a/media/libstagefright/wifi-display/rtp/RTPSender.h +++ b/media/libstagefright/wifi-display/rtp/RTPSender.h @@ -43,10 +43,11 @@ struct RTPSender : public RTPBase, public AHandler { const sp ¬ify); status_t initAsync( - TransportMode mode, const char *remoteHost, int32_t remoteRTPPort, + TransportMode rtpMode, int32_t remoteRTCPPort, + TransportMode rtcpMode, int32_t *outLocalRTPPort); status_t queueBuffer( @@ -72,7 +73,8 @@ private: sp mNetSession; sp mNotify; - TransportMode mMode; + TransportMode mRTPMode; + TransportMode mRTCPMode; int32_t mRTPSessionID; int32_t mRTCPSessionID; bool mRTPConnected; diff --git a/media/libstagefright/wifi-display/rtptest.cpp b/media/libstagefright/wifi-display/rtptest.cpp index 607d9d2..eade832 100644 --- a/media/libstagefright/wifi-display/rtptest.cpp +++ b/media/libstagefright/wifi-display/rtptest.cpp @@ -106,7 +106,9 @@ void TestHandler::onMessageReceived(const sp &msg) { int32_t receiverRTPPort; CHECK_EQ((status_t)OK, mReceiver->initAsync( - RTPReceiver::TRANSPORT_UDP, &receiverRTPPort)); + RTPReceiver::TRANSPORT_UDP, // rtpMode + RTPReceiver::TRANSPORT_UDP, // rtcpMode + &receiverRTPPort)); printf("picked receiverRTPPort %d\n", receiverRTPPort); @@ -155,10 +157,11 @@ void TestHandler::onMessageReceived(const sp &msg) { int32_t senderRTPPort; CHECK_EQ((status_t)OK, mSender->initAsync( - RTPSender::TRANSPORT_UDP, host.c_str(), receiverRTPPort, + RTPSender::TRANSPORT_UDP, // rtpMode receiverRTPPort + 1, + RTPSender::TRANSPORT_UDP, // rtcpMode &senderRTPPort)); printf("picked senderRTPPort %d\n", senderRTPPort); -- cgit v1.1