[vlc-commits] chromecast: load input asynchronously
Thomas Guillem
git at videolan.org
Tue Feb 6 12:51:42 CET 2018
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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<QueueableMessages> 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<QueueableMessages> 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
{
@@ -511,9 +551,9 @@ void intf_sys_t::processReceiverMessage( const castchannel::CastMessage& msg )
if ( p_app != NULL )
{
msg_Dbg( m_module, "Media receiver application has been started." );
- setState( Ready );
m_appTransportId = (const char*)(*p_app)["transportId"];
m_communication.msgConnect( m_appTransportId );
+ setState( Ready );
}
break;
case Loading:
@@ -813,6 +853,8 @@ void intf_sys_t::requestPlayerStop()
{
vlc_mutex_locker locker(&m_lock);
+ m_request_load = false;
+
if( m_httpd_file )
{
httpd_FileDelete( m_httpd_file );
@@ -958,6 +1000,16 @@ void intf_sys_t::setState( States state )
msg_Dbg( m_module, "Switching from state %s to %s", StateToStr( m_state ), StateToStr( state ) );
#endif
m_state = state;
+
+ switch( m_state )
+ {
+ case Connected:
+ case Ready:
+ tryLoad();
+ break;
+ default:
+ break;
+ }
vlc_cond_signal( &m_stateChangedCond );
}
}
More information about the vlc-commits
mailing list