[vlc-devel] [PATCH 4/4] dlna: add PrepareForConnection action

Shaleen Jain shaleen at jain.sh
Wed Jan 9 16:10:40 CET 2019


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.
---
 modules/stream_out/dlna/dlna.cpp | 89 ++++++++++++++++++++++++++++++--
 modules/stream_out/dlna/dlna.hpp |  9 ++++
 2 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/modules/stream_out/dlna/dlna.cpp b/modules/stream_out/dlna/dlna.cpp
index f9f7a61c29..54a09dc03b 100644
--- a/modules/stream_out/dlna/dlna.cpp
+++ b/modules/stream_out/dlna/dlna.cpp
@@ -471,6 +471,8 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )
     if ( !startSoutChain( p_stream, new_streams, ssout.str() ) )
         return VLC_EGENERIC;
 
+    renderer->PrepareForConnection(dlna_write_protocol_info(*stream_protocol));
+
     msg_Dbg(p_stream, "AVTransportURI: %s", uri);
     renderer->Stop();
     renderer->SetAVTransportURI(uri, *stream_protocol);
@@ -565,7 +567,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},
     };
 
@@ -581,7 +583,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);
@@ -667,6 +669,86 @@ std::vector<protocol_info_t> MediaRenderer::GetProtocolInfo()
     return supported_protocols;
 }
 
+int MediaRenderer::PrepareForConnection(std::string protocol_str)
+{
+    std::list<std::pair<const char*, const char*>> arg_list;
+    arg_list.push_back(std::make_pair("PeerConnectionID", "-1"));
+    arg_list.push_back(std::make_pair("PeerConnectionManager", ""));
+    arg_list.push_back(std::make_pair("Direction", "Input"));
+    arg_list.push_back(std::make_pair("RemoteProtocolInfo", protocol_str.c_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));
+    if (IXML_NodeList *node_list =
+            ixmlDocument_getElementsByTagName(response , "ConnectionID"))
+    {
+        if (IXML_Node* node = ixmlNodeList_item(node_list, 0))
+        {
+            IXML_Node* p_text_node = ixmlNode_getFirstChild(node);
+            if (p_text_node)
+            {
+                ConnectionID.assign(ixmlNode_getNodeValue(p_text_node));
+            }
+        }
+        ixmlNodeList_free(node_list);
+    }
+
+    if (IXML_NodeList *node_list =
+            ixmlDocument_getElementsByTagName(response , "AVTransportID"))
+    {
+        if (IXML_Node* node = ixmlNodeList_item(node_list, 0))
+        {
+            IXML_Node* p_text_node = ixmlNode_getFirstChild(node);
+            if (p_text_node)
+            {
+                AVTransportID.assign(ixmlNode_getNodeValue(p_text_node));
+            }
+        }
+        ixmlNodeList_free(node_list);
+    }
+
+    if (IXML_NodeList *node_list =
+            ixmlDocument_getElementsByTagName(response , "RcsID"))
+    {
+        if (IXML_Node* node = ixmlNodeList_item(node_list, 0))
+        {
+            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[] =
@@ -696,7 +778,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},
     };
@@ -865,6 +947,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..d2b2cb8f8d 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(std::string protocol_str);
+    int ConnectionComplete();
     int SetAVTransportURI(const char* uri, const protocol_info_t& proto);
 };
 
-- 
2.20.1


More information about the vlc-devel mailing list