[vlc-commits] sout: chromecast: prevent conflict between multiple chromecasts

Filip Roséen git at videolan.org
Tue Jul 24 16:08:26 CEST 2018


vlc/vlc-3.0 | branch: master | Filip Roséen <filip at atch.se> | Mon Jul 23 19:57:02 2018 +0200| [eb9decc16ee690d4dc0129803a3a392865bb2b6e] | committer: Jean-Baptiste Kempf

sout: chromecast: prevent conflict between multiple chromecasts

In order for us to support streaming to more than one chromecast using
the same instance of libvlc (as through VLM), and with the same
options for the httpd, we will need to have a unique identifier for
each output.

These changes generates a random path upon initialization of the
relevant object, while also incorporating the current tick. There is
an extremely slim chance that two chromecast souts would try to create
the http bindings at the exact same time, but vlc_tick_now + a random
identifier is a "better safe than sorry" implementation.

In order to really dive down in the "better safe than sorry"-category,
we try three times before giving up.

fixes: #20380
fixes: #20890
Signed-off-by: Thomas Guillem <thomas at gllm.fr>
(cherry picked from commit 710a2ef49669806e208d6845a494a01ed90b18db)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

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

 modules/stream_out/chromecast/chromecast.h        | 12 +++++--
 modules/stream_out/chromecast/chromecast_ctrl.cpp | 40 +++++++++++++++++++----
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/modules/stream_out/chromecast/chromecast.h b/modules/stream_out/chromecast/chromecast.h
index dc64840d9f..a9ecee9c33 100644
--- a/modules/stream_out/chromecast/chromecast.h
+++ b/modules/stream_out/chromecast/chromecast.h
@@ -244,7 +244,6 @@ private:
 
 private:
     vlc_object_t  * const m_module;
-    const int      m_streaming_port;
     const int      m_device_port;
     std::string    m_mime;
     std::string    m_device_addr;
@@ -281,7 +280,16 @@ private:
 
     vlc_interrupt_t *m_ctl_thread_interrupt;
 
-    httpd_host_t     *m_httpd_host;
+    struct httpd_info_t {
+        httpd_info_t( httpd_host_t* host, int port );
+        ~httpd_info_t();
+
+        httpd_host_t *m_host;
+        int           m_port;
+        httpd_url_t  *m_url;
+        std::string   m_root;
+    } const m_httpd;
+
     httpd_file_t     *m_httpd_file;
     std::string       m_art_http_ip;
     char             *m_art_url;
diff --git a/modules/stream_out/chromecast/chromecast_ctrl.cpp b/modules/stream_out/chromecast/chromecast_ctrl.cpp
index 09374b5dbd..864ae2c53d 100644
--- a/modules/stream_out/chromecast/chromecast_ctrl.cpp
+++ b/modules/stream_out/chromecast/chromecast_ctrl.cpp
@@ -38,6 +38,7 @@
 #include <iomanip>
 
 #include <vlc_stream.h>
+#include <vlc_rand.h>
 
 #include "../../misc/webservices/json.h"
 
@@ -90,7 +91,6 @@ static const char* StateToStr( States s )
 intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, std::string device_addr,
                        int device_port, httpd_host_t *httpd_host)
  : m_module(p_this)
- , m_streaming_port(port)
  , m_device_port(device_port)
  , m_device_addr(device_addr)
  , m_last_request_id( 0 )
@@ -109,7 +109,7 @@ intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, std::string device
  , m_cc_eof( false )
  , m_pace( false )
  , m_meta( NULL )
- , m_httpd_host(httpd_host)
+ , m_httpd( httpd_host, port )
  , m_httpd_file(NULL)
  , m_art_url(NULL)
  , m_art_idx(0)
@@ -327,7 +327,7 @@ void intf_sys_t::prepareHttpArtwork()
 
         if( m_httpd_file )
             httpd_FileDelete( m_httpd_file );
-        m_httpd_file = httpd_FileNew( m_httpd_host, ss_art_idx.str().c_str(),
+        m_httpd_file = httpd_FileNew( m_httpd.m_host, ss_art_idx.str().c_str(),
                                       "application/octet-stream", NULL, NULL,
                                       httpd_file_fill_cb, (httpd_file_sys_t *) this );
 
@@ -584,6 +584,34 @@ void intf_sys_t::queueMessage( QueueableMessages msg )
     vlc_interrupt_raise( m_ctl_thread_interrupt );
 }
 
+intf_sys_t::httpd_info_t::httpd_info_t( httpd_host_t* host, int port )
+    : m_host( host )
+    , m_port( port )
+{
+    for( int i = 0; i < 3; ++i )
+    {
+        std::ostringstream ss;
+        ss << "/chromecast"
+           << "/" << mdate()
+           << "/" << static_cast<uint64_t>( vlc_mrand48() );
+
+        m_root = ss.str();
+        m_url = httpd_UrlNew( m_host, m_root.c_str(), NULL, NULL );
+        if( m_url )
+            break;
+    }
+
+    if( m_url == NULL )
+        throw std::runtime_error( "unable to bind to http path" );
+}
+
+intf_sys_t::httpd_info_t::~httpd_info_t()
+
+{
+    if( m_url )
+        httpd_UrlDelete( m_url );
+}
+
 /*****************************************************************************
  * Chromecast thread
  *****************************************************************************/
@@ -1116,17 +1144,17 @@ mtime_t intf_sys_t::getPauseDelay()
 
 unsigned int intf_sys_t::getHttpStreamPort() const
 {
-    return m_streaming_port;
+    return m_httpd.m_port;
 }
 
 std::string intf_sys_t::getHttpStreamPath() const
 {
-    return "/stream";
+    return m_httpd.m_root + "/stream";
 }
 
 std::string intf_sys_t::getHttpArtRoot() const
 {
-    return "/art";
+    return m_httpd.m_root + "/art";
 }
 
 bool intf_sys_t::isFinishedPlaying()



More information about the vlc-commits mailing list