From 5a68fc340e5b61ec29d8283433ddb003d6871abc Mon Sep 17 00:00:00 2001 From: Li Sun Date: Fri, 3 Jul 2015 15:13:43 +0800 Subject: RTSP: add RTSP extensions for IPV6 support Change access modifiers and add overridables in rtsp stack. Make ARTSPConnection/ARTPConnection extensible for IPV6 support. Provide default implementations in AVMediaServiceExensions and AVMediaServiceFactory. Change-Id: Iaa67070d1832d56e0569dabfd8327c1998f04493 --- media/libavextensions/Android.mk | 2 ++ .../mediaplayerservice/AVMediaServiceExtensions.h | 16 ++++++++++++++++ .../mediaplayerservice/AVMediaServiceFactory.cpp | 11 +++++++++++ .../mediaplayerservice/AVMediaServiceUtils.cpp | 20 ++++++++++++++++++++ media/libstagefright/rtsp/ARTPConnection.cpp | 10 ++++++++-- media/libstagefright/rtsp/ARTPConnection.h | 7 ++++--- media/libstagefright/rtsp/ARTSPConnection.cpp | 13 ++++++++++++- media/libstagefright/rtsp/ARTSPConnection.h | 7 ++++++- media/libstagefright/rtsp/Android.mk | 1 + media/libstagefright/rtsp/MyHandler.h | 20 +++++++++++++------- 10 files changed, 93 insertions(+), 14 deletions(-) diff --git a/media/libavextensions/Android.mk b/media/libavextensions/Android.mk index 391edcb..511f13f 100644 --- a/media/libavextensions/Android.mk +++ b/media/libavextensions/Android.mk @@ -67,6 +67,8 @@ LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/include/media/ \ $(TOP)/frameworks/av/media/libmediaplayerservice \ $(TOP)/frameworks/av/media/libavextensions \ + $(TOP)/frameworks/av/media/libstagefright/include \ + $(TOP)/frameworks/av/media/libstagefright/rtsp \ $(TOP)/frameworks/native/include/media/hardware \ $(TOP)/frameworks/native/include/media/openmax \ $(TOP)/external/flac/include \ diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h b/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h index 327e0a0..5c31fad 100644 --- a/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h +++ b/media/libavextensions/mediaplayerservice/AVMediaServiceExtensions.h @@ -31,11 +31,16 @@ #include +#include #include namespace android { struct StagefrightRecorder; +struct ARTSPConnection; +struct ARTPConnection; +struct AString; +struct MyHandler; /* * Factory to create objects of base-classes in libmediaplayerservice @@ -43,6 +48,10 @@ struct StagefrightRecorder; struct AVMediaServiceFactory { virtual StagefrightRecorder *createStagefrightRecorder(const String16 &); + // RTSP extensions + virtual sp createARTSPConnection(bool uidValid, uid_t uid); + virtual sp createARTPConnection(); + // ----- NO TRESSPASSING BEYOND THIS LINE ------ DECLARE_LOADABLE_SINGLETON(AVMediaServiceFactory); }; @@ -52,6 +61,13 @@ struct AVMediaServiceFactory { */ struct AVMediaServiceUtils { + // RTSP IPV6 utils + virtual bool pokeAHole(sp handler, int rtpSocket, int rtcpSocket, + const AString &transport, const AString &sessionHost); + virtual void makePortPair(int *rtpSocket, int *rtcpSocket, unsigned *rtpPort, + bool isIPV6); + virtual const char* parseURL(AString *host); + // ----- NO TRESSPASSING BEYOND THIS LINE ------ DECLARE_LOADABLE_SINGLETON(AVMediaServiceUtils); }; diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp b/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp index eb0ebb7..10b66f5 100644 --- a/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp +++ b/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp @@ -32,6 +32,8 @@ #include #include +#include "ARTPConnection.h" +#include "ARTSPConnection.h" #include "MediaRecorderClient.h" #include "MediaPlayerService.h" @@ -46,6 +48,15 @@ StagefrightRecorder *AVMediaServiceFactory::createStagefrightRecorder( return new StagefrightRecorder(opPackageName); } +sp AVMediaServiceFactory::createARTSPConnection( + bool uidValid, uid_t uid) { + return new ARTSPConnection(uidValid, uid); +} + +sp AVMediaServiceFactory::createARTPConnection() { + return new ARTPConnection(); +} + // ----- NO TRESSPASSING BEYOND THIS LINE ------ AVMediaServiceFactory::AVMediaServiceFactory() { } diff --git a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp index a3da1df..705ce8a 100644 --- a/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp +++ b/media/libavextensions/mediaplayerservice/AVMediaServiceUtils.cpp @@ -31,11 +31,31 @@ #include #include +#include "ARTPConnection.h" +#include "MyHandler.h" + #include "common/ExtensionsLoader.hpp" #include "mediaplayerservice/AVMediaServiceExtensions.h" namespace android { +bool AVMediaServiceUtils::pokeAHole(sp handler, int rtpSocket, int rtcpSocket, + const AString &transport, const AString &/*sessionHost*/) { + if (handler == NULL) { + ALOGW("MyHandler is NULL"); + return false; + } + return handler->pokeAHole(rtpSocket, rtcpSocket, transport); +} + +void AVMediaServiceUtils::makePortPair(int *rtpSocket, int *rtcpSocket, unsigned *rtpPort, + bool /*isIPV6*/) { + return ARTPConnection::MakePortPair(rtpSocket, rtcpSocket, rtpPort); +} + +const char* AVMediaServiceUtils::parseURL(AString *host) { + return strchr(host->c_str(), ':'); +} // ----- NO TRESSPASSING BEYOND THIS LINE ------ AVMediaServiceUtils::AVMediaServiceUtils() { diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp index a86ab74..e021b29 100644 --- a/media/libstagefright/rtsp/ARTPConnection.cpp +++ b/media/libstagefright/rtsp/ARTPConnection.cpp @@ -81,7 +81,8 @@ void ARTPConnection::addStream( const sp &sessionDesc, size_t index, const sp ¬ify, - bool injected) { + bool injected, + bool isIPV6) { sp msg = new AMessage(kWhatAddStream, this); msg->setInt32("rtp-socket", rtpSocket); msg->setInt32("rtcp-socket", rtcpSocket); @@ -89,6 +90,7 @@ void ARTPConnection::addStream( msg->setSize("index", index); msg->setMessage("notify", notify); msg->setInt32("injected", injected); + msg->setInt32("isIPV6", isIPV6); msg->post(); } @@ -145,6 +147,10 @@ void ARTPConnection::MakePortPair( TRESPASS(); } +size_t ARTPConnection::sockAddrSize() { + return sizeof(struct sockaddr_in); +} + void ARTPConnection::onMessageReceived(const sp &msg) { switch (msg->what()) { case kWhatAddStream: @@ -345,7 +351,7 @@ void ARTPConnection::onPollStreams() { n = sendto( s->mRTCPSocket, buffer->data(), buffer->size(), 0, (const struct sockaddr *)&s->mRemoteRTCPAddr, - sizeof(s->mRemoteRTCPAddr)); + sockAddrSize()); } while (n < 0 && errno == EINTR); if (n <= 0) { diff --git a/media/libstagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/ARTPConnection.h index edbcc35..057007b 100644 --- a/media/libstagefright/rtsp/ARTPConnection.h +++ b/media/libstagefright/rtsp/ARTPConnection.h @@ -38,7 +38,8 @@ struct ARTPConnection : public AHandler { int rtpSocket, int rtcpSocket, const sp &sessionDesc, size_t index, const sp ¬ify, - bool injected); + bool injected, + bool isIPV6 = false); void removeStream(int rtpSocket, int rtcpSocket); @@ -53,8 +54,8 @@ struct ARTPConnection : public AHandler { protected: virtual ~ARTPConnection(); virtual void onMessageReceived(const sp &msg); + virtual size_t sockAddrSize(); -private: enum { kWhatAddStream, kWhatRemoveStream, @@ -72,7 +73,7 @@ private: bool mPollEventPending; int64_t mLastReceiverReportTimeUs; - void onAddStream(const sp &msg); + virtual void onAddStream(const sp &msg); void onRemoveStream(const sp &msg); void onPollStreams(); void onInjectPacket(const sp &msg); diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp index 855ffdc..b2c1fd1 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.cpp +++ b/media/libstagefright/rtsp/ARTSPConnection.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -170,7 +171,7 @@ bool ARTSPConnection::ParseURL( } } - const char *colonPos = strchr(host->c_str(), ':'); + const char *colonPos = AVMediaServiceUtils::get()->parseURL(host); if (colonPos != NULL) { unsigned long x; @@ -252,6 +253,11 @@ void ARTSPConnection::onConnect(const sp &msg) { ALOGV("user = '%s', pass = '%s'", mUser.c_str(), mPass.c_str()); } + performConnect(reply, host, port); +} + +void ARTSPConnection::performConnect(const sp &reply, + AString host, unsigned port) { struct hostent *ent = gethostbyname(host.c_str()); if (ent == NULL) { ALOGE("Unknown host %s", host.c_str()); @@ -381,7 +387,12 @@ void ARTSPConnection::onCompleteConnection(const sp &msg) { socklen_t optionLen = sizeof(err); CHECK_EQ(getsockopt(mSocket, SOL_SOCKET, SO_ERROR, &err, &optionLen), 0); CHECK_EQ(optionLen, (socklen_t)sizeof(err)); + performCompleteConnection(msg, err); +} +void ARTSPConnection::performCompleteConnection(const sp &msg, int err) { + sp reply; + CHECK(msg->findMessage("reply", &reply)); if (err != 0) { ALOGE("err = %d (%s)", err, strerror(err)); diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h index 1fe9c99..c4ebe1d 100644 --- a/media/libstagefright/rtsp/ARTSPConnection.h +++ b/media/libstagefright/rtsp/ARTSPConnection.h @@ -42,6 +42,8 @@ struct ARTSPConnection : public AHandler { void observeBinaryData(const sp &reply); + virtual bool isIPV6() { return false; } + static bool ParseURL( const char *url, AString *host, unsigned *port, AString *path, AString *user, AString *pass); @@ -49,8 +51,11 @@ struct ARTSPConnection : public AHandler { protected: virtual ~ARTSPConnection(); virtual void onMessageReceived(const sp &msg); + virtual void performConnect(const sp &reply, + AString host, unsigned port); + virtual void performCompleteConnection(const sp &msg, + int err); -private: enum State { DISCONNECTED, CONNECTING, diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk index c5e8c35..28c6fb6 100644 --- a/media/libstagefright/rtsp/Android.mk +++ b/media/libstagefright/rtsp/Android.mk @@ -23,6 +23,7 @@ LOCAL_SHARED_LIBRARIES += libcrypto LOCAL_C_INCLUDES:= \ $(TOP)/frameworks/av/media/libstagefright \ + $(TOP)/frameworks/av/media/libavextensions \ $(TOP)/frameworks/native/include/media/openmax LOCAL_MODULE:= libstagefright_rtsp diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index 0d0baf3..2981685 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -115,8 +116,6 @@ struct MyHandler : public AHandler { mUIDValid(uidValid), mUID(uid), mNetLooper(new ALooper), - mConn(new ARTSPConnection(mUIDValid, mUID)), - mRTPConn(new ARTPConnection), mOriginalSessionURL(url), mSessionURL(url), mSetupTracksSuccessful(false), @@ -140,6 +139,9 @@ struct MyHandler : public AHandler { mPausing(false), mPauseGeneration(0), mPlayResponseParsed(false) { + mConn = AVMediaServiceFactory::get()->createARTSPConnection( + mUIDValid, uid); + mRTPConn = AVMediaServiceFactory::get()->createARTPConnection(); mNetLooper->setName("rtsp net"); mNetLooper->start(false /* runOnCallingThread */, false /* canCallJava */, @@ -722,16 +724,19 @@ struct MyHandler : public AHandler { // We are going to continue even if we were // unable to poke a hole into the firewall... - pokeAHole( + AVMediaServiceUtils::get()->pokeAHole( + this, track->mRTPSocket, track->mRTCPSocket, - transport); + transport, + mSessionHost); } mRTPConn->addStream( track->mRTPSocket, track->mRTCPSocket, mSessionDesc, index, - notify, track->mUsingInterleavedTCP); + notify, track->mUsingInterleavedTCP, + mConn->isIPV6()); mSetupTracksSuccessful = true; } else { @@ -1648,8 +1653,9 @@ private: request.append(interleaveIndex + 1); } else { unsigned rtpPort; - ARTPConnection::MakePortPair( - &info->mRTPSocket, &info->mRTCPSocket, &rtpPort); + AVMediaServiceUtils::get()->makePortPair( + &info->mRTPSocket, &info->mRTCPSocket, &rtpPort, + mConn->isIPV6()); if (mUIDValid) { HTTPBase::RegisterSocketUserTag(info->mRTPSocket, mUID, -- cgit v1.1