[vlc-commits] chromecast: load input asynchronously
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
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