summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2013-02-05 17:55:48 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-02-05 17:55:48 +0000
commit7846311d9a7d1f52432f5b66d084d587666ab27a (patch)
tree5129a41b2dc4118d13439409440529e562e0047f /media/libstagefright/wifi-display
parentb15a3e8292d3c98d06d136a07b6e8e66f33dd5c7 (diff)
parent7bc2ffca12828d72aaeeace0891183dc547877c0 (diff)
downloadframeworks_av-7846311d9a7d1f52432f5b66d084d587666ab27a.zip
frameworks_av-7846311d9a7d1f52432f5b66d084d587666ab27a.tar.gz
frameworks_av-7846311d9a7d1f52432f5b66d084d587666ab27a.tar.bz2
Merge "Revive the code to support TCP interleaved transport"
Diffstat (limited to 'media/libstagefright/wifi-display')
-rw-r--r--media/libstagefright/wifi-display/ANetworkSession.cpp1
-rw-r--r--media/libstagefright/wifi-display/sink/RTPSink.cpp53
-rw-r--r--media/libstagefright/wifi-display/sink/RTPSink.h10
-rw-r--r--media/libstagefright/wifi-display/source/PlaybackSession.cpp12
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp40
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h1
6 files changed, 88 insertions, 29 deletions
diff --git a/media/libstagefright/wifi-display/ANetworkSession.cpp b/media/libstagefright/wifi-display/ANetworkSession.cpp
index 62a6e7f..06f71f4 100644
--- a/media/libstagefright/wifi-display/ANetworkSession.cpp
+++ b/media/libstagefright/wifi-display/ANetworkSession.cpp
@@ -1091,7 +1091,6 @@ void ANetworkSession::threadLoop() {
clientSocket);
sp<Session> clientSession =
- // using socket sd as sessionID
new Session(
mNextSessionID++,
Session::CONNECTED,
diff --git a/media/libstagefright/wifi-display/sink/RTPSink.cpp b/media/libstagefright/wifi-display/sink/RTPSink.cpp
index 7f4b66f..be54595 100644
--- a/media/libstagefright/wifi-display/sink/RTPSink.cpp
+++ b/media/libstagefright/wifi-display/sink/RTPSink.cpp
@@ -253,6 +253,8 @@ RTPSink::RTPSink(
mRTPPort(0),
mRTPSessionID(0),
mRTCPSessionID(0),
+ mRTPClientSessionID(0),
+ mRTCPClientSessionID(0),
mFirstArrivalTimeUs(-1ll),
mNumPacketsReceived(0ll),
mRegression(1000),
@@ -260,6 +262,14 @@ RTPSink::RTPSink(
}
RTPSink::~RTPSink() {
+ if (mRTCPClientSessionID != 0) {
+ mNetSession->destroySession(mRTCPClientSessionID);
+ }
+
+ if (mRTPClientSessionID != 0) {
+ mNetSession->destroySession(mRTPClientSessionID);
+ }
+
if (mRTCPSessionID != 0) {
mNetSession->destroySession(mRTCPSessionID);
}
@@ -269,8 +279,8 @@ RTPSink::~RTPSink() {
}
}
-status_t RTPSink::init(bool useTCPInterleaving) {
- if (useTCPInterleaving) {
+status_t RTPSink::init(bool usingTCPTransport, bool usingTCPInterleaving) {
+ if (usingTCPInterleaving) {
return OK;
}
@@ -280,8 +290,16 @@ status_t RTPSink::init(bool useTCPInterleaving) {
sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
for (clientRtp = 15550;; clientRtp += 2) {
int32_t rtpSession;
- status_t err = mNetSession->createUDPSession(
- clientRtp, rtpNotify, &rtpSession);
+ status_t err;
+ struct in_addr ifaceAddr;
+ if (usingTCPTransport) {
+ ifaceAddr.s_addr = INADDR_ANY;
+ err = mNetSession->createTCPDatagramSession(
+ ifaceAddr, clientRtp, rtpNotify, &rtpSession);
+ } else {
+ err = mNetSession->createUDPSession(
+ clientRtp, rtpNotify, &rtpSession);
+ }
if (err != OK) {
ALOGI("failed to create RTP socket on port %d", clientRtp);
@@ -289,8 +307,13 @@ status_t RTPSink::init(bool useTCPInterleaving) {
}
int32_t rtcpSession;
- err = mNetSession->createUDPSession(
- clientRtp + 1, rtcpNotify, &rtcpSession);
+ if (usingTCPTransport) {
+ err = mNetSession->createTCPDatagramSession(
+ ifaceAddr, clientRtp + 1, rtcpNotify, &rtcpSession);
+ } else {
+ err = mNetSession->createUDPSession(
+ clientRtp + 1, rtcpNotify, &rtcpSession);
+ }
if (err == OK) {
mRTPPort = clientRtp;
@@ -367,6 +390,24 @@ void RTPSink::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case ANetworkSession::kWhatClientConnected:
+ {
+ int32_t sessionID;
+ CHECK(msg->findInt32("sessionID", &sessionID));
+ ALOGI("TCP session %d now connected", sessionID);
+
+ int32_t serverPort;
+ CHECK(msg->findInt32("server-port", &serverPort));
+
+ if (serverPort == mRTPPort) {
+ mRTPClientSessionID = sessionID;
+ } else {
+ CHECK_EQ(serverPort, mRTPPort + 1);
+ mRTCPClientSessionID = sessionID;
+ }
+ break;
+ }
+
default:
TRESPASS();
}
diff --git a/media/libstagefright/wifi-display/sink/RTPSink.h b/media/libstagefright/wifi-display/sink/RTPSink.h
index 6e40185..f9cbce9 100644
--- a/media/libstagefright/wifi-display/sink/RTPSink.h
+++ b/media/libstagefright/wifi-display/sink/RTPSink.h
@@ -48,7 +48,7 @@ struct RTPSink : public AHandler {
// If TCP interleaving is used, no UDP sockets are created, instead
// incoming RTP/RTCP packets (arriving on the RTSP control connection)
// are manually injected by WifiDisplaySink.
- status_t init(bool useTCPInterleaving);
+ status_t init(bool usingTCPTransport, bool usingTCPInterleaving);
status_t connect(
const char *host, int32_t remoteRtpPort, int32_t remoteRtcpPort);
@@ -79,8 +79,12 @@ private:
KeyedVector<uint32_t, sp<Source> > mSources;
int32_t mRTPPort;
- int32_t mRTPSessionID;
- int32_t mRTCPSessionID;
+
+ int32_t mRTPSessionID; // in TCP unicast mode these are just server
+ int32_t mRTCPSessionID; // sockets. No data is transferred through them.
+
+ int32_t mRTPClientSessionID; // in TCP unicast mode
+ int32_t mRTCPClientSessionID;
int64_t mFirstArrivalTimeUs;
int64_t mNumPacketsReceived;
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index e542908..ede4e60 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -542,6 +542,18 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
onFinishPlay2();
} else if (what == Sender::kWhatSessionDead) {
notifySessionDead();
+ } else if (what == Sender::kWhatBinaryData) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatBinaryData);
+
+ int32_t channel;
+ CHECK(msg->findInt32("channel", &channel));
+ notify->setInt32("channel", channel);
+
+ sp<ABuffer> data;
+ CHECK(msg->findBuffer("data", &data));
+ notify->setBuffer("data", data);
+ notify->post();
} else {
TRESPASS();
}
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 981d5f9..825ebc6 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -597,15 +597,6 @@ status_t WifiDisplaySource::sendM3(int32_t sessionID) {
status_t WifiDisplaySource::sendM4(int32_t sessionID) {
CHECK_EQ(sessionID, mClientSessionID);
- AString transportString = "UDP";
-
- char val[PROPERTY_VALUE_MAX];
- if (property_get("media.wfd.enable-tcp", val, NULL)
- && (!strcasecmp("true", val) || !strcmp("1", val))) {
- ALOGI("Using TCP transport.");
- transportString = "TCP";
- }
-
AString body;
if (mSinkSupportsVideo) {
@@ -630,11 +621,11 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) {
body.append(
StringPrintf(
- "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n"
- "wfd_client_rtp_ports: RTP/AVP/%s;unicast %d 0 mode=play\r\n",
- mClientInfo.mLocalIP.c_str(),
- transportString.c_str(),
- mChosenRTPPort));
+ "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n",
+ mClientInfo.mLocalIP.c_str()));
+
+ body.append(mWfdClientRtpPorts);
+ body.append("\r\n");
AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
AppendCommonResponse(&request, mNextCSeq);
@@ -797,18 +788,29 @@ status_t WifiDisplaySource::onReceiveM3Response(
return ERROR_MALFORMED;
}
- unsigned port0, port1;
+ unsigned port0 = 0, port1 = 0;
if (sscanf(value.c_str(),
"RTP/AVP/UDP;unicast %u %u mode=play",
&port0,
- &port1) != 2
- || port0 == 0 || port0 > 65535 || port1 != 0) {
- ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
+ &port1) == 2
+ || sscanf(value.c_str(),
+ "RTP/AVP/TCP;unicast %u %u mode=play",
+ &port0,
+ &port1) == 2) {
+ if (port0 == 0 || port0 > 65535 || port1 != 0) {
+ ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
+ value.c_str());
+
+ return ERROR_MALFORMED;
+ }
+ } else if (strcmp(value.c_str(), "RTP/AVP/TCP;interleaved mode=play")) {
+ ALOGE("Unsupported value for wfd_client_rtp_ports (%s)",
value.c_str());
- return ERROR_MALFORMED;
+ return ERROR_UNSUPPORTED;
}
+ mWfdClientRtpPorts = value;
mChosenRTPPort = port0;
if (!params->findParameter("wfd_video_formats", &value)) {
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index fec2c6d..724462c 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -119,6 +119,7 @@ private:
uint32_t mStopReplyID;
+ AString mWfdClientRtpPorts;
int32_t mChosenRTPPort; // extracted from "wfd_client_rtp_ports"
bool mSinkSupportsVideo;