[vlc-commits] chromecast: load input asynchronously

2018-02-06 Thread Thomas Guillem
vlc/vlc-3.0 | branch: master | Thomas Guillem  | Tue Feb  6 
09:04:27 2018 +0100| [56ba38bfb702e44b5f5edbc8bd6fa8869d608fcc] | committer: 
Jean-Baptiste Kempf

chromecast: load input asynchronously

setHasInput() is now non-blocking. It was called from the sout chain and could
deadlock (no interrupt context) in case of connectivity issue.

(cherry picked from commit 341dc6dd25a13d8ffcb6cba7b454e17b9d5d7e8b)
Signed-off-by: Jean-Baptiste Kempf 

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

 modules/stream_out/chromecast/chromecast.h|  3 +
 modules/stream_out/chromecast/chromecast_ctrl.cpp | 84 ++-
 2 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/modules/stream_out/chromecast/chromecast.h 
b/modules/stream_out/chromecast/chromecast.h
index 61389d681f..781bc1d29d 100644
--- a/modules/stream_out/chromecast/chromecast.h
+++ b/modules/stream_out/chromecast/chromecast.h
@@ -182,6 +182,8 @@ private:
 
 void setPauseState(bool paused);
 bool isStatePlaying() const;
+bool isStateReady() const;
+void tryLoad();
 
 void setMeta( vlc_meta_t *p_meta );
 
@@ -236,6 +238,7 @@ private:
 std::queue m_msgQueue;
 States m_state;
 bool m_request_stop;
+bool m_request_load;
 bool m_eof;
 
 vlc_meta_t *m_meta;
diff --git a/modules/stream_out/chromecast/chromecast_ctrl.cpp 
b/modules/stream_out/chromecast/chromecast_ctrl.cpp
index b1f14c7051..8130991f38 100644
--- a/modules/stream_out/chromecast/chromecast_ctrl.cpp
+++ b/modules/stream_out/chromecast/chromecast_ctrl.cpp
@@ -93,6 +93,7 @@ intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, 
std::string device
  , m_communication( p_this, device_addr.c_str(), device_port )
  , m_state( Authenticating )
  , m_request_stop( false )
+ , m_request_load( false )
  , m_eof( false )
  , m_meta( NULL )
  , m_ctl_thread_interrupt(p_interrupt)
@@ -265,6 +266,38 @@ void intf_sys_t::prepareHttpArtwork()
 vlc_meta_Set( m_meta, vlc_meta_ArtworkURL, ss.str().c_str() );
 }
 
+void intf_sys_t::tryLoad()
+{
+if( !m_request_load )
+return;
+
+if ( !isStateReady() )
+{
+if ( m_state == Dead )
+{
+msg_Warn( m_module, "no Chromecast hook possible");
+m_request_load = false;
+}
+else if( m_state == Connected )
+{
+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;
+m_communication.msgReceiverLaunchApp();
+}
+return;
+}
+
+m_request_load = false;
+
+// We should now be in the ready state, and therefor have a valid 
transportId
+assert( m_appTransportId.empty() == false );
+// Reset the mediaSessionID to allow the new session to become the current 
one.
+// we cannot start a new load when the last one is still processing
+m_communication.msgPlayerLoad( m_appTransportId, m_streaming_port, m_mime, 
m_meta );
+m_state = Loading;
+}
+
 void intf_sys_t::setHasInput( const std::string mime_type )
 {
 vlc_mutex_locker locker(&m_lock);
@@ -278,23 +311,14 @@ void intf_sys_t::setHasInput( const std::string mime_type 
)
 std::queue empty;
 std::swap(m_msgQueue, empty);
 
-waitAppStarted();
-if ( m_state == Dead )
-{
-msg_Warn( m_module, "no Chromecast hook possible");
-return;
-}
-
 prepareHttpArtwork();
 
-// We should now be in the ready state, and therefor have a valid 
transportId
-assert( m_appTransportId.empty() == false );
-// Reset the mediaSessionID to allow the new session to become the current 
one.
-m_mediaSessionId = 0;
-// we cannot start a new load when the last one is still processing
-m_communication.msgPlayerLoad( m_appTransportId, m_streaming_port, 
mime_type, m_meta );
-setState( Loading );
 m_eof = false;
+m_mediaSessionId = 0;
+m_request_load = true;
+
+tryLoad();
+vlc_cond_signal( &m_stateChangedCond );
 }
 
 bool intf_sys_t::isStatePlaying() const
@@ -312,6 +336,22 @@ bool intf_sys_t::isStatePlaying() const
 }
 }
 
+bool intf_sys_t::isStateReady() const
+{
+switch( m_state )
+{
+case Connected:
+case Launching:
+case Authenticating:
+case Connecting:
+case Stopping:
+case Dead:
+return false;
+default:
+return true;
+}
+}
+
 /**
  * @brief Process a message received from the Chromecast
  * @param msg the CastMessage to process
@@ -498,8 +538,8 @@ void intf_sys_t::processReceiverMessage( const 
castchannel::CastMessage& msg )
 {
 msg_Dbg( m_module, "Media receiver application was already 
running" );
 m_appTransportId = (const char*)(*p_app)["transportId"];
-setState( Ready );
 

[vlc-commits] chromecast: load input asynchronously

2018-02-06 Thread Thomas Guillem
vlc | branch: master | Thomas Guillem  | Tue Feb  6 09:04:27 
2018 +0100| [341dc6dd25a13d8ffcb6cba7b454e17b9d5d7e8b] | committer: Thomas 
Guillem

chromecast: load input asynchronously

setHasInput() is now non-blocking. It was called from the sout chain and could
deadlock (no interrupt context) in case of connectivity issue.

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

 modules/stream_out/chromecast/chromecast.h|  3 +
 modules/stream_out/chromecast/chromecast_ctrl.cpp | 84 ++-
 2 files changed, 71 insertions(+), 16 deletions(-)

diff --git a/modules/stream_out/chromecast/chromecast.h 
b/modules/stream_out/chromecast/chromecast.h
index 61389d681f..781bc1d29d 100644
--- a/modules/stream_out/chromecast/chromecast.h
+++ b/modules/stream_out/chromecast/chromecast.h
@@ -182,6 +182,8 @@ private:
 
 void setPauseState(bool paused);
 bool isStatePlaying() const;
+bool isStateReady() const;
+void tryLoad();
 
 void setMeta( vlc_meta_t *p_meta );
 
@@ -236,6 +238,7 @@ private:
 std::queue m_msgQueue;
 States m_state;
 bool m_request_stop;
+bool m_request_load;
 bool m_eof;
 
 vlc_meta_t *m_meta;
diff --git a/modules/stream_out/chromecast/chromecast_ctrl.cpp 
b/modules/stream_out/chromecast/chromecast_ctrl.cpp
index b1f14c7051..8130991f38 100644
--- a/modules/stream_out/chromecast/chromecast_ctrl.cpp
+++ b/modules/stream_out/chromecast/chromecast_ctrl.cpp
@@ -93,6 +93,7 @@ intf_sys_t::intf_sys_t(vlc_object_t * const p_this, int port, 
std::string device
  , m_communication( p_this, device_addr.c_str(), device_port )
  , m_state( Authenticating )
  , m_request_stop( false )
+ , m_request_load( false )
  , m_eof( false )
  , m_meta( NULL )
  , m_ctl_thread_interrupt(p_interrupt)
@@ -265,6 +266,38 @@ void intf_sys_t::prepareHttpArtwork()
 vlc_meta_Set( m_meta, vlc_meta_ArtworkURL, ss.str().c_str() );
 }
 
+void intf_sys_t::tryLoad()
+{
+if( !m_request_load )
+return;
+
+if ( !isStateReady() )
+{
+if ( m_state == Dead )
+{
+msg_Warn( m_module, "no Chromecast hook possible");
+m_request_load = false;
+}
+else if( m_state == Connected )
+{
+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;
+m_communication.msgReceiverLaunchApp();
+}
+return;
+}
+
+m_request_load = false;
+
+// We should now be in the ready state, and therefor have a valid 
transportId
+assert( m_appTransportId.empty() == false );
+// Reset the mediaSessionID to allow the new session to become the current 
one.
+// we cannot start a new load when the last one is still processing
+m_communication.msgPlayerLoad( m_appTransportId, m_streaming_port, m_mime, 
m_meta );
+m_state = Loading;
+}
+
 void intf_sys_t::setHasInput( const std::string mime_type )
 {
 vlc_mutex_locker locker(&m_lock);
@@ -278,23 +311,14 @@ void intf_sys_t::setHasInput( const std::string mime_type 
)
 std::queue empty;
 std::swap(m_msgQueue, empty);
 
-waitAppStarted();
-if ( m_state == Dead )
-{
-msg_Warn( m_module, "no Chromecast hook possible");
-return;
-}
-
 prepareHttpArtwork();
 
-// We should now be in the ready state, and therefor have a valid 
transportId
-assert( m_appTransportId.empty() == false );
-// Reset the mediaSessionID to allow the new session to become the current 
one.
-m_mediaSessionId = 0;
-// we cannot start a new load when the last one is still processing
-m_communication.msgPlayerLoad( m_appTransportId, m_streaming_port, 
mime_type, m_meta );
-setState( Loading );
 m_eof = false;
+m_mediaSessionId = 0;
+m_request_load = true;
+
+tryLoad();
+vlc_cond_signal( &m_stateChangedCond );
 }
 
 bool intf_sys_t::isStatePlaying() const
@@ -312,6 +336,22 @@ bool intf_sys_t::isStatePlaying() const
 }
 }
 
+bool intf_sys_t::isStateReady() const
+{
+switch( m_state )
+{
+case Connected:
+case Launching:
+case Authenticating:
+case Connecting:
+case Stopping:
+case Dead:
+return false;
+default:
+return true;
+}
+}
+
 /**
  * @brief Process a message received from the Chromecast
  * @param msg the CastMessage to process
@@ -498,8 +538,8 @@ void intf_sys_t::processReceiverMessage( const 
castchannel::CastMessage& msg )
 {
 msg_Dbg( m_module, "Media receiver application was already 
running" );
 m_appTransportId = (const char*)(*p_app)["transportId"];
-setState( Ready );
 m_communication.msgConnect( m_appTransportId );
+setState( Ready );
 }
 else