OSDN Git Service

Only run the wifi display RTSP server on demand, and only on the wifi direct
authorAndreas Huber <andih@google.com>
Thu, 30 Aug 2012 21:51:40 +0000 (14:51 -0700)
committerAndreas Huber <andih@google.com>
Thu, 30 Aug 2012 21:51:40 +0000 (14:51 -0700)
interface.

Change-Id: I7d3c44cb79cd40e73499f2d7ccf35c69b628e6d7

12 files changed:
include/media/IMediaPlayerService.h
media/libmedia/IMediaPlayerService.cpp
media/libmediaplayerservice/MediaPlayerService.cpp
media/libmediaplayerservice/MediaPlayerService.h
media/libmediaplayerservice/RemoteDisplay.cpp
media/libmediaplayerservice/RemoteDisplay.h
media/libstagefright/wifi-display/ANetworkSession.cpp
media/libstagefright/wifi-display/ANetworkSession.h
media/libstagefright/wifi-display/source/PlaybackSession.cpp
media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
media/libstagefright/wifi-display/source/WifiDisplaySource.h
media/libstagefright/wifi-display/wfd.cpp

index dbcdf92..172975c 100644 (file)
@@ -50,7 +50,11 @@ public:
     virtual sp<IOMX>            getOMX() = 0;
     virtual sp<ICrypto>         makeCrypto() = 0;
 
-    virtual status_t enableRemoteDisplay(bool enable) = 0;
+    // If iface == NULL, disable remote display, otherwise
+    // iface should be of the form "x.x.x.x:y", i.e. ip address
+    // of the local interface to bind to and the port number
+    // to listen on.
+    virtual status_t enableRemoteDisplay(const char *iface) = 0;
 
     // codecs and audio devices usage tracking for the battery app
     enum BatteryDataBits {
index 41969b1..d3e2e19 100644 (file)
@@ -121,10 +121,17 @@ public:
         return interface_cast<ICrypto>(reply.readStrongBinder());
     }
 
-    virtual status_t enableRemoteDisplay(bool enable) {
+    virtual status_t enableRemoteDisplay(const char *iface) {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
-        data.writeInt32(enable);
+
+        if (iface != NULL) {
+            data.writeInt32(1);
+            data.writeCString(iface);
+        } else {
+            data.writeInt32(0);
+        }
+
         remote()->transact(ENABLE_REMOTE_DISPLAY, data, &reply);
         return reply.readInt32();
     }
@@ -217,8 +224,11 @@ status_t BnMediaPlayerService::onTransact(
         } break;
         case ENABLE_REMOTE_DISPLAY: {
             CHECK_INTERFACE(IMediaPlayerService, data, reply);
-            bool enable = data.readInt32();
-            reply->writeInt32(enableRemoteDisplay(enable));
+            const char *iface = NULL;
+            if (data.readInt32()) {
+                iface = data.readCString();
+            }
+            reply->writeInt32(enableRemoteDisplay(iface));
             return NO_ERROR;
         } break;
         case ADD_BATTERY_DATA: {
index 5fe446f..166bae9 100644 (file)
@@ -279,13 +279,17 @@ sp<ICrypto> MediaPlayerService::makeCrypto() {
     return new Crypto;
 }
 
-status_t MediaPlayerService::enableRemoteDisplay(bool enable) {
+status_t MediaPlayerService::enableRemoteDisplay(const char *iface) {
     Mutex::Autolock autoLock(mLock);
 
-    if (enable && mRemoteDisplay == NULL) {
+    if (iface != NULL) {
+        if (mRemoteDisplay != NULL) {
+            return INVALID_OPERATION;
+        }
+
         mRemoteDisplay = new RemoteDisplay;
 
-        status_t err = mRemoteDisplay->start();
+        status_t err = mRemoteDisplay->start(iface);
 
         if (err != OK) {
             mRemoteDisplay.clear();
@@ -293,7 +297,9 @@ status_t MediaPlayerService::enableRemoteDisplay(bool enable) {
         }
 
         return OK;
-    } else if (!enable && mRemoteDisplay != NULL) {
+    }
+
+    if (mRemoteDisplay != NULL) {
         mRemoteDisplay->stop();
         mRemoteDisplay.clear();
     }
index 8fbc5d5..2577c58 100644 (file)
@@ -248,7 +248,7 @@ public:
     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat);
     virtual sp<IOMX>            getOMX();
     virtual sp<ICrypto>         makeCrypto();
-    virtual status_t            enableRemoteDisplay(bool enable);
+    virtual status_t            enableRemoteDisplay(const char *iface);
 
     virtual status_t            dump(int fd, const Vector<String16>& args);
 
index 855824a..49f7278 100644 (file)
@@ -32,13 +32,11 @@ RemoteDisplay::RemoteDisplay()
 RemoteDisplay::~RemoteDisplay() {
 }
 
-status_t RemoteDisplay::start() {
+status_t RemoteDisplay::start(const char *iface) {
     mNetSession->start();
     mLooper->start();
 
-    // XXX replace with 8554 for bcom dongle (it doesn't respect the
-    // default port or the one advertised in the wfd IE).
-    mSource->start(WifiDisplaySource::kWifiDisplayDefaultPort);
+    mSource->start(iface);
 
     return OK;
 }
index 6b37afb..3607d06 100644 (file)
@@ -31,7 +31,7 @@ struct WifiDisplaySource;
 struct RemoteDisplay : public RefBase {
     RemoteDisplay();
 
-    status_t start();
+    status_t start(const char *iface);
     status_t stop();
 
 protected:
index ee0600c..4ddd778 100644 (file)
@@ -537,6 +537,7 @@ status_t ANetworkSession::createRTSPClient(
         int32_t *sessionID) {
     return createClientOrServer(
             kModeCreateRTSPClient,
+            NULL /* addr */,
             0 /* port */,
             host,
             port,
@@ -545,9 +546,11 @@ status_t ANetworkSession::createRTSPClient(
 }
 
 status_t ANetworkSession::createRTSPServer(
-        unsigned port, const sp<AMessage> &notify, int32_t *sessionID) {
+        const struct in_addr &addr, unsigned port,
+        const sp<AMessage> &notify, int32_t *sessionID) {
     return createClientOrServer(
             kModeCreateRTSPServer,
+            &addr,
             port,
             NULL /* remoteHost */,
             0 /* remotePort */,
@@ -568,6 +571,7 @@ status_t ANetworkSession::createUDPSession(
         int32_t *sessionID) {
     return createClientOrServer(
             kModeCreateUDPSession,
+            NULL /* addr */,
             localPort,
             remoteHost,
             remotePort,
@@ -608,6 +612,7 @@ status_t ANetworkSession::MakeSocketNonBlocking(int s) {
 
 status_t ANetworkSession::createClientOrServer(
         Mode mode,
+        const struct in_addr *localAddr,
         unsigned port,
         const char *remoteHost,
         unsigned remotePort,
@@ -677,8 +682,11 @@ status_t ANetworkSession::createClientOrServer(
 
         addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
         addr.sin_port = htons(remotePort);
+    } else if (localAddr != NULL) {
+        addr.sin_addr = *localAddr;
+        addr.sin_port = htons(port);
     } else {
-        addr.sin_addr.s_addr = INADDR_ANY;
+        addr.sin_addr.s_addr = htonl(INADDR_ANY);
         addr.sin_port = htons(port);
     }
 
index d4cd14f..8d961ee 100644 (file)
@@ -23,6 +23,8 @@
 #include <utils/RefBase.h>
 #include <utils/Thread.h>
 
+#include <netinet/in.h>
+
 namespace android {
 
 struct AMessage;
@@ -40,7 +42,8 @@ struct ANetworkSession : public RefBase {
             int32_t *sessionID);
 
     status_t createRTSPServer(
-            unsigned port, const sp<AMessage> &notify, int32_t *sessionID);
+            const struct in_addr &addr, unsigned port,
+            const sp<AMessage> &notify, int32_t *sessionID);
 
     status_t createUDPSession(
             unsigned localPort, const sp<AMessage> &notify, int32_t *sessionID);
@@ -92,6 +95,7 @@ private:
     };
     status_t createClientOrServer(
             Mode mode,
+            const struct in_addr *addr,
             unsigned port,
             const char *remoteHost,
             unsigned remotePort,
index c99a11e..f9223d6 100644 (file)
@@ -625,7 +625,7 @@ status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
     ssize_t index = mSerializer->addSource(source);
 #else
     ssize_t index = mSerializer->addSource(
-            new RepeaterSource(source, 55.0 /* rateHz */));
+            new RepeaterSource(source, 30.0 /* rateHz */));
 #endif
 
     CHECK_GE(index, 0);
index 3f75bc3..35d4414 100644 (file)
@@ -27,6 +27,9 @@
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
 
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
 namespace android {
 
 WifiDisplaySource::WifiDisplaySource(const sp<ANetworkSession> &netSession)
@@ -39,9 +42,9 @@ WifiDisplaySource::WifiDisplaySource(const sp<ANetworkSession> &netSession)
 WifiDisplaySource::~WifiDisplaySource() {
 }
 
-status_t WifiDisplaySource::start(int32_t port) {
+status_t WifiDisplaySource::start(const char *iface) {
     sp<AMessage> msg = new AMessage(kWhatStart, id());
-    msg->setInt32("port", port);
+    msg->setString("iface", iface);
 
     sp<AMessage> response;
     status_t err = msg->postAndAwaitResponse(&response);
@@ -81,13 +84,44 @@ void WifiDisplaySource::onMessageReceived(const sp<AMessage> &msg) {
             uint32_t replyID;
             CHECK(msg->senderAwaitsResponse(&replyID));
 
-            int32_t port;
-            CHECK(msg->findInt32("port", &port));
+            AString iface;
+            CHECK(msg->findString("iface", &iface));
+
+            status_t err = OK;
+
+            ssize_t colonPos = iface.find(":");
+
+            unsigned long port;
+
+            if (colonPos >= 0) {
+                const char *s = iface.c_str() + colonPos + 1;
+
+                char *end;
+                port = strtoul(s, &end, 10);
+
+                if (end == s || *end != '\0' || port > 65535) {
+                    err = -EINVAL;
+                } else {
+                    iface.erase(colonPos, iface.size() - colonPos);
+                }
+            } else {
+                port = kWifiDisplayDefaultPort;
+            }
+
+            struct in_addr addr;
 
-            sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());
+            if (err == OK) {
+                if (inet_aton(iface.c_str(), &addr) != 0) {
+                    sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());
 
-            status_t err = mNetSession->createRTSPServer(
-                    port, notify, &mSessionID);
+                    err = mNetSession->createRTSPServer(
+                            addr, port, notify, &mSessionID);
+
+                    ALOGI("createRTSPServer returned err %d", err);
+                } else {
+                    err = -EINVAL;
+                }
+            }
 
             sp<AMessage> response = new AMessage;
             response->setInt32("err", err);
index 95c3560..cd9939b 100644 (file)
@@ -33,7 +33,7 @@ struct WifiDisplaySource : public AHandler {
 
     WifiDisplaySource(const sp<ANetworkSession> &netSession);
 
-    status_t start(int32_t port);
+    status_t start(const char *iface);
     status_t stop();
 
 protected:
index 32cdf3f..5e7d9fd 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace android {
 
-static void enableDisableRemoteDisplay(bool enable) {
+static void enableDisableRemoteDisplay(const char *iface) {
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> binder = sm->getService(String16("media.player"));
 
@@ -41,7 +41,7 @@ static void enableDisableRemoteDisplay(bool enable) {
 
     CHECK(service.get() != NULL);
 
-    service->enableRemoteDisplay(enable);
+    service->enableRemoteDisplay(iface);
 }
 
 }  // namespace android
@@ -53,7 +53,7 @@ static void usage(const char *me) {
             "           %s -c host[:port]\tconnect to wifi source\n"
             "           -u uri        \tconnect to an rtsp uri\n"
 #endif
-            "           -e            \tenable remote display\n"
+            "           -e ip[:port]       \tenable remote display\n"
             "           -d            \tdisable remote display\n",
             me);
 }
@@ -70,7 +70,7 @@ int main(int argc, char **argv) {
     AString uri;
 
     int res;
-    while ((res = getopt(argc, argv, "hc:l:u:ed")) >= 0) {
+    while ((res = getopt(argc, argv, "hc:l:u:e:d")) >= 0) {
         switch (res) {
 #if SUPPORT_SINK
             case 'c':
@@ -103,9 +103,15 @@ int main(int argc, char **argv) {
 #endif
 
             case 'e':
+            {
+                enableDisableRemoteDisplay(optarg);
+                exit(0);
+                break;
+            }
+
             case 'd':
             {
-                enableDisableRemoteDisplay(res == 'e');
+                enableDisableRemoteDisplay(NULL);
                 exit(0);
                 break;
             }