[vlc-commits] chromecast: retry connection after a Dead state

Thomas Guillem git at videolan.org
Thu Mar 29 10:23:11 CEST 2018


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Mar 29 10:15:24 2018 +0200| [400fa1a9906bb8d53875c6475eed69a60cdb19f2] | committer: Thomas Guillem

chromecast: retry connection after a Dead state

Retry only when playing a new input in order to avoid retry busy loops.

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

 modules/stream_out/chromecast/chromecast.h        |   4 +-
 modules/stream_out/chromecast/chromecast_ctrl.cpp | 102 ++++++++++++++++------
 2 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/modules/stream_out/chromecast/chromecast.h b/modules/stream_out/chromecast/chromecast.h
index 50c678f188..19b0c9dea1 100644
--- a/modules/stream_out/chromecast/chromecast.h
+++ b/modules/stream_out/chromecast/chromecast.h
@@ -185,6 +185,7 @@ struct intf_sys_t
     int httpd_file_fill( uint8_t *psz_request, uint8_t **pp_data, int *pi_data );
     void interrupt_wake_up();
 private:
+    void reinit();
     bool handleMessages();
 
     bool processMessage(const castchannel::CastMessage &msg);
@@ -237,7 +238,9 @@ 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;
 
     std::string m_appTransportId;
     unsigned m_last_request_id;
@@ -248,7 +251,6 @@ private:
     vlc_cond_t   m_pace_cond;
     vlc_thread_t m_chromecastThread;
 
-
     on_input_event_itf    m_on_input_event;
     void                 *m_on_input_event_data;
 
diff --git a/modules/stream_out/chromecast/chromecast_ctrl.cpp b/modules/stream_out/chromecast/chromecast_ctrl.cpp
index c293261594..184e516e39 100644
--- a/modules/stream_out/chromecast/chromecast_ctrl.cpp
+++ b/modules/stream_out/chromecast/chromecast_ctrl.cpp
@@ -91,6 +91,8 @@ intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, std::string device
                        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 )
  , m_mediaSessionId( 0 )
  , m_on_input_event( NULL )
@@ -116,7 +118,8 @@ intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, std::string device
  , m_pause_delay( VLC_TS_INVALID )
  , m_pingRetriesLeft( PING_WAIT_RETRIES )
 {
-    m_communication = new ChromecastCommunication( p_this, device_addr.c_str(), device_port );
+    m_communication = new ChromecastCommunication( p_this, m_device_addr.c_str(),
+                                                   m_device_port );
 
     m_ctl_thread_interrupt = vlc_interrupt_create();
     if( unlikely(m_ctl_thread_interrupt == NULL) )
@@ -159,36 +162,40 @@ intf_sys_t::~intf_sys_t()
     var_Destroy( m_module->obj.parent->obj.parent, CC_SHARED_VAR_NAME );
 
     vlc_mutex_lock(&m_lock);
-    switch ( m_state )
+    if( m_communication )
     {
-    case Ready:
-    case Loading:
-    case Buffering:
-    case Playing:
-    case Paused:
-    case Stopping:
-    case Stopped:
-        // Generate the close messages.
-        m_communication->msgReceiverClose( m_appTransportId );
-        /* fallthrough */
-    case Connecting:
-    case Connected:
-    case Launching:
-        m_communication->msgReceiverClose(DEFAULT_CHOMECAST_RECEIVER);
-        /* fallthrough */
-    default:
-        break;
-    }
-    vlc_mutex_unlock(&m_lock);
+        switch ( m_state )
+        {
+        case Ready:
+        case Loading:
+        case Buffering:
+        case Playing:
+        case Paused:
+        case Stopping:
+        case Stopped:
+            // Generate the close messages.
+            m_communication->msgReceiverClose( m_appTransportId );
+            /* fallthrough */
+        case Connecting:
+        case Connected:
+        case Launching:
+            m_communication->msgReceiverClose(DEFAULT_CHOMECAST_RECEIVER);
+            /* fallthrough */
+        default:
+            break;
+        }
 
-    vlc_interrupt_kill( m_ctl_thread_interrupt );
+        vlc_mutex_unlock(&m_lock);
+        vlc_interrupt_kill( m_ctl_thread_interrupt );
+        vlc_join(m_chromecastThread, NULL);
 
-    vlc_join(m_chromecastThread, NULL);
+        delete m_communication;
+    }
+    else
+        vlc_mutex_unlock(&m_lock);
 
     vlc_interrupt_destroy( m_ctl_thread_interrupt );
 
-    delete m_communication;
-
     if (m_meta != NULL)
         vlc_meta_Delete(m_meta);
 
@@ -202,6 +209,38 @@ intf_sys_t::~intf_sys_t()
     vlc_mutex_destroy(&m_lock);
 }
 
+void intf_sys_t::reinit()
+{
+    assert( m_state == Dead );
+
+    if( m_communication )
+    {
+        vlc_join( m_chromecastThread, NULL );
+        delete m_communication;
+        m_communication = NULL;
+    }
+
+    try
+    {
+        m_communication = new ChromecastCommunication( m_module,
+                                                       m_device_addr.c_str(),
+                                                       m_device_port );
+    } catch (const std::runtime_error& err )
+    {
+        msg_Warn( m_module, "failed to re-init ChromecastCommunication (%s)", err.what() );
+        m_communication = NULL;
+        return;
+    }
+
+    m_state = Authenticating;
+    if( vlc_clone( &m_chromecastThread, ChromecastThread, this, VLC_THREAD_PRIORITY_LOW) )
+    {
+        m_state = Dead;
+        delete m_communication;
+        m_communication = NULL;
+    }
+}
+
 int intf_sys_t::httpd_file_fill( uint8_t *psz_request, uint8_t **pp_data, int *pi_data )
 {
     (void) psz_request;
@@ -316,6 +355,7 @@ void intf_sys_t::tryLoad()
         }
         else if( m_state == Connected )
         {
+            assert( m_communication );
             msg_Dbg( m_module, "Starting the media receiver application" );
             // Don't use setState as we don't want to signal the condition in this case.
             m_state = Launching;
@@ -348,6 +388,9 @@ void intf_sys_t::setHasInput( const std::string mime_type )
     vlc_mutex_locker locker(&m_lock);
     msg_Dbg( m_module, "Loading content" );
 
+    if( m_state == Dead )
+        reinit();
+
     this->m_mime = mime_type;
 
     /* new input: clear message queue */
@@ -1036,12 +1079,18 @@ void intf_sys_t::setDemuxEnabled(bool enabled,
     vlc_mutex_locker locker(&m_lock);
     m_on_paused_changed = on_paused_changed;
     m_on_paused_changed_data = on_paused_changed_data;
+
+    if( enabled )
+    {
+        if( m_state == Dead && !vlc_killed() )
+            reinit();
+    }
 }
 
 void intf_sys_t::setPauseState(bool paused, mtime_t delay)
 {
     vlc_mutex_locker locker( &m_lock );
-    if ( m_mediaSessionId == 0 || paused == m_paused )
+    if ( m_mediaSessionId == 0 || paused == m_paused || !m_communication )
         return;
 
     m_paused = paused;
@@ -1088,6 +1137,7 @@ mtime_t intf_sys_t::getPlaybackTimestamp()
             /* fallthrough */
         case Playing:
         {
+            assert( m_communication );
             mtime_t now = mdate();
             if( m_state == Playing && m_last_request_id == 0
              && now - m_cc_time_last_request_date > INT64_C(4000000) )



More information about the vlc-commits mailing list