[vlc-commits] dlna: add PrepareForConnection action

Shaleen Jain git at videolan.org
Thu Jan 10 17:14:10 CET 2019


vlc | branch: master | Shaleen Jain <shaleen at jain.sh> | Fri Sep 28 16:15:02 2018 +0530| [b671d3b3270790fd11aa3bc76cfe42f75ca25c52] | committer: Thomas Guillem

dlna: add PrepareForConnection action

This adds support for casting to Media Renderers that
implement the optional CM::PrepareForConnection action
and require Control Points to call this action before
being able to play any content.

Signed-off-by: Thomas Guillem <thomas at gllm.fr>
Signed-off-by: Hugo Beauzée-Luyssen <hugo at beauzee.fr>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b671d3b3270790fd11aa3bc76cfe42f75ca25c52
---

 modules/stream_out/dlna/dlna.cpp | 97 ++++++++++++++++++++++++++++++++++++++--
 modules/stream_out/dlna/dlna.hpp |  9 ++++
 2 files changed, 103 insertions(+), 3 deletions(-)

diff --git a/modules/stream_out/dlna/dlna.cpp b/modules/stream_out/dlna/dlna.cpp
index 0965782d06..8716911b0c 100644
--- a/modules/stream_out/dlna/dlna.cpp
+++ b/modules/stream_out/dlna/dlna.cpp
@@ -475,6 +475,8 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )
         return VLC_EGENERIC;
     }
 
+    renderer->PrepareForConnection(dlna_write_protocol_info(*stream_protocol).c_str());
+
     msg_Dbg(p_stream, "AVTransportURI: %s", uri);
     renderer->Stop();
     renderer->SetAVTransportURI(uri, *stream_protocol);
@@ -569,7 +571,7 @@ IXML_Document *MediaRenderer::SendAction(const char* action_name,const char *ser
 int MediaRenderer::Play(const char *speed)
 {
     std::list<std::pair<const char*, const char*>> arg_list = {
-        {"InstanceID", "0"},
+        {"InstanceID", AVTransportID.c_str()},
         {"Speed", speed},
     };
 
@@ -585,7 +587,7 @@ int MediaRenderer::Play(const char *speed)
 int MediaRenderer::Stop()
 {
     std::list<std::pair<const char*, const char*>> arg_list = {
-        {"InstanceID", "0"},
+        {"InstanceID", AVTransportID.c_str()},
     };
 
     IXML_Document *p_response = SendAction("Stop", AV_TRANSPORT_SERVICE_TYPE, arg_list);
@@ -674,6 +676,94 @@ std::vector<protocol_info_t> MediaRenderer::GetProtocolInfo()
     return supported_protocols;
 }
 
+int MediaRenderer::PrepareForConnection(const char* protocol_str)
+{
+    std::list<std::pair<const char*, const char*>> arg_list = {
+        { "PeerConnectionID", "-1" },
+        { "PeerConnectionManager", "" },
+        { "Direction", "Input" },
+        { "RemoteProtocolInfo", protocol_str },
+    };
+
+    IXML_Document *response = SendAction("PrepareForConnection",
+                                    CONNECTION_MANAGER_SERVICE_TYPE, arg_list);
+    if(!response)
+    {
+        return VLC_EGENERIC;
+    }
+
+    msg_Dbg(parent, "PrepareForConnection response: %s",
+                                    ixmlPrintDocument(response));
+
+    IXML_NodeList *node_list =
+            ixmlDocument_getElementsByTagName(response , "ConnectionID");
+    if (node_list)
+    {
+        IXML_Node* node = ixmlNodeList_item(node_list, 0);
+        if (node)
+        {
+            IXML_Node* p_text_node = ixmlNode_getFirstChild(node);
+            if (p_text_node)
+            {
+                ConnectionID.assign(ixmlNode_getNodeValue(p_text_node));
+            }
+        }
+        ixmlNodeList_free(node_list);
+    }
+
+    node_list =
+            ixmlDocument_getElementsByTagName(response , "AVTransportID");
+    if (node_list)
+    {
+        IXML_Node* node = ixmlNodeList_item(node_list, 0);
+        if (node)
+        {
+            IXML_Node* p_text_node = ixmlNode_getFirstChild(node);
+            if (p_text_node)
+            {
+                AVTransportID.assign(ixmlNode_getNodeValue(p_text_node));
+            }
+        }
+        ixmlNodeList_free(node_list);
+    }
+
+    node_list =
+            ixmlDocument_getElementsByTagName(response , "RcsID");
+    if (node_list)
+    {
+        IXML_Node* node = ixmlNodeList_item(node_list, 0);
+        if (node)
+        {
+            IXML_Node* p_text_node = ixmlNode_getFirstChild(node);
+            if (p_text_node)
+            {
+                RcsID.assign(ixmlNode_getNodeValue(p_text_node));
+            }
+        }
+        ixmlNodeList_free(node_list);
+    }
+
+    ixmlDocument_free(response);
+    return VLC_SUCCESS;
+}
+
+int MediaRenderer::ConnectionComplete()
+{
+    std::list<std::pair<const char*, const char*>> arg_list = {
+        {"ConnectionID", ConnectionID.c_str()},
+    };
+
+    IXML_Document *p_response = SendAction("ConnectionComplete",
+                                    CONNECTION_MANAGER_SERVICE_TYPE, arg_list);
+    if(!p_response)
+    {
+        return VLC_EGENERIC;
+    }
+
+    ixmlDocument_free(p_response);
+    return VLC_SUCCESS;
+}
+
 int MediaRenderer::SetAVTransportURI(const char* uri, const protocol_info_t& proto)
 {
     static const char didl[] =
@@ -703,7 +793,7 @@ int MediaRenderer::SetAVTransportURI(const char* uri, const protocol_info_t& pro
 
     msg_Dbg(parent, "didl: %s", meta_data);
     std::list<std::pair<const char*, const char*>> arg_list = {
-        {"InstanceID", "0"},
+        {"InstanceID", AVTransportID.c_str()},
         {"CurrentURI", uri},
         {"CurrentURIMetaData", meta_data},
     };
@@ -873,6 +963,7 @@ void CloseSout( vlc_object_t *p_this)
     sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>( p_this );
     sout_stream_sys_t *p_sys = static_cast<sout_stream_sys_t *>( p_stream->p_sys );
 
+    p_sys->renderer->ConnectionComplete();
     p_sys->p_upnp->release();
     delete p_sys;
 }
diff --git a/modules/stream_out/dlna/dlna.hpp b/modules/stream_out/dlna/dlna.hpp
index d4a18ebd52..128ee1c423 100644
--- a/modules/stream_out/dlna/dlna.hpp
+++ b/modules/stream_out/dlna/dlna.hpp
@@ -77,6 +77,9 @@ public:
         , base_url(base_url)
         , device_url(device_url)
         , handle(upnp->handle())
+        , ConnectionID("0")
+        , AVTransportID("0")
+        , RcsID("0")
     {
     }
 
@@ -85,6 +88,10 @@ public:
     std::string         device_url;
     UpnpClient_Handle   handle;
 
+    std::string         ConnectionID;
+    std::string         AVTransportID;
+    std::string         RcsID;
+
     char *getServiceURL(const char* type, const char* service);
     IXML_Document *SendAction(const char* action_name, const char *service_type,
                     std::list<std::pair<const char*, const char*>> arguments);
@@ -92,6 +99,8 @@ public:
     int Play(const char *speed);
     int Stop();
     std::vector<protocol_info_t> GetProtocolInfo();
+    int PrepareForConnection(const char* protocol_str);
+    int ConnectionComplete();
     int SetAVTransportURI(const char* uri, const protocol_info_t& proto);
 };
 



More information about the vlc-commits mailing list