[vlc-devel] [PATCH 1/2] chromecast: move the Chromecast communication in a control interface module
Steve Lhomme
robux4 at videolabs.io
Fri Jan 15 17:18:01 CET 2016
---
modules/MODULES_LIST | 1 +
modules/stream_out/Makefile.am | 13 +-
modules/stream_out/chromecast/cast.cpp | 202 ++++-----------------
modules/stream_out/chromecast/chromecast.h | 9 +-
modules/stream_out/chromecast/chromecast_ctrl.cpp | 208 +++++++++++++++++++++-
5 files changed, 251 insertions(+), 182 deletions(-)
diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST
index 146fba5..442fc8a 100644
--- a/modules/MODULES_LIST
+++ b/modules/MODULES_LIST
@@ -85,6 +85,7 @@ $Id$
* console_logger: Logger outputting in the terminal
* croppadd: Crop/Padd image filter
* crystalhd: crystalhd decoder
+ * ctrl_chromecast: Module to handle communication with Chromecast and redirect input playback
* cvdsub: CVD subtitles decoder
* cvpx_i420: filter to copy from OS X accelerated surfaces to CPU in YUV
* d3d11_surface: Convert D3D11 GPU textures to YUV planes
diff --git a/modules/stream_out/Makefile.am b/modules/stream_out/Makefile.am
index 269354a..7e5d2b3 100644
--- a/modules/stream_out/Makefile.am
+++ b/modules/stream_out/Makefile.am
@@ -80,18 +80,23 @@ SUFFIXES += .proto .pb.cc
%.pb.h %.pb.cc: %.proto
$(PROTOC) --cpp_out=. -I$(srcdir) $<
-libstream_out_chromecast_plugin_la_SOURCES = \
+libctrl_chromecast_plugin_la_SOURCES = \
stream_out/chromecast/cast_channel.proto stream_out/chromecast/chromecast.h \
- stream_out/chromecast/cast.cpp stream_out/chromecast/chromecast_ctrl.cpp \
+ stream_out/chromecast/chromecast_ctrl.cpp \
misc/webservices/json.h misc/webservices/json.c
-nodist_libstream_out_chromecast_plugin_la_SOURCES = stream_out/chromecast/cast_channel.pb.cc
+nodist_libctrl_chromecast_plugin_la_SOURCES = stream_out/chromecast/cast_channel.pb.cc
+libctrl_chromecast_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -Istream_out/chromecast $(CHROMECAST_CFLAGS)
+libctrl_chromecast_plugin_la_LIBADD = $(CHROMECAST_LIBS) $(SOCKET_LIBS)
+CLEANFILES += $(nodist_libctrl_chromecast_plugin_la_SOURCES)
+
+libstream_out_chromecast_plugin_la_SOURCES = stream_out/chromecast/cast.cpp stream_out/chromecast/chromecast.h
libstream_out_chromecast_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -Istream_out/chromecast $(CHROMECAST_CFLAGS)
libstream_out_chromecast_plugin_la_LIBADD = $(CHROMECAST_LIBS) $(SOCKET_LIBS)
-CLEANFILES += $(nodist_libstream_out_chromecast_plugin_la_SOURCES)
if ENABLE_SOUT
if BUILD_CHROMECAST
BUILT_SOURCES += stream_out/chromecast/cast_channel.pb.h
sout_LTLIBRARIES += libstream_out_chromecast_plugin.la
+control_LTLIBRARIES += libctrl_chromecast_plugin.la
endif
endif
diff --git a/modules/stream_out/chromecast/cast.cpp b/modules/stream_out/chromecast/cast.cpp
index 052b685..c97511a 100644
--- a/modules/stream_out/chromecast/cast.cpp
+++ b/modules/stream_out/chromecast/cast.cpp
@@ -1,10 +1,11 @@
/*****************************************************************************
- * cast.cpp: Chromecast module for vlc
+ * cast.cpp: Chromecast sout module for vlc
*****************************************************************************
- * Copyright © 2014 VideoLAN
+ * Copyright © 2014-2015 VideoLAN
*
* Authors: Adrien Maglo <magsoft at videolan.org>
* Jean-Baptiste Kempf <jb at videolan.org>
+ * Steve Lhomme <robux4 at videolabs.io>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
@@ -31,17 +32,14 @@
#include "chromecast.h"
-#include <errno.h>
-
#include <vlc_sout.h>
-#include <vlc_threads.h>
#include <cassert>
struct sout_stream_sys_t
{
- sout_stream_sys_t(intf_sys_t *intf)
- : p_out(NULL)
+ sout_stream_sys_t(intf_sys_t *intf, sout_stream_t *sout)
+ : p_out(sout)
, p_intf(intf)
{
assert(p_intf != NULL);
@@ -49,17 +47,15 @@ struct sout_stream_sys_t
~sout_stream_sys_t()
{
- delete p_intf;
+ sout_StreamChainDelete(p_out, p_out);
}
vlc_thread_t chromecastThread;
- sout_stream_t *p_out;
+ sout_stream_t * const p_out;
intf_sys_t * const p_intf;
};
-#define HTTP_PORT 8010
-
#define SOUT_CFG_PREFIX "sout-chromecast-"
/*****************************************************************************
@@ -69,18 +65,14 @@ static int Open(vlc_object_t *);
static void Close(vlc_object_t *);
static void Clean(sout_stream_t *p_stream);
-static void *chromecastThread(void *data);
-
static const char *const ppsz_sout_options[] = {
- "ip", "http-port", "mux", "mime", NULL
+ "http-port", "mux", "mime", NULL
};
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-#define IP_TEXT N_("Chromecast IP address")
-#define IP_LONGTEXT N_("This sets the IP adress of the Chromecast receiver.")
#define HTTP_PORT_TEXT N_("HTTP port")
#define HTTP_PORT_LONGTEXT N_("This sets the HTTP port of the server " \
"used to stream the media to the Chromecast.")
@@ -99,7 +91,6 @@ vlc_module_begin ()
set_subcategory(SUBCAT_SOUT_STREAM)
set_callbacks(Open, Close)
- add_string(SOUT_CFG_PREFIX "ip", "", IP_TEXT, IP_LONGTEXT, false)
add_integer(SOUT_CFG_PREFIX "http-port", HTTP_PORT, HTTP_PORT_TEXT, HTTP_PORT_LONGTEXT, false)
add_string(SOUT_CFG_PREFIX "mux", "mp4stream", MUX_TEXT, MUX_LONGTEXT, false)
add_string(SOUT_CFG_PREFIX "mime", "video/mp4", MIME_TEXT, MIME_LONGTEXT, false)
@@ -155,105 +146,32 @@ static int Open(vlc_object_t *p_this)
{
sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>(p_this);
sout_stream_sys_t *p_sys;
- intf_sys_t *p_intf = new(std::nothrow) intf_sys_t(p_stream);
- if (p_intf == NULL)
- return VLC_ENOMEM;
- p_sys = new(std::nothrow) sout_stream_sys_t(p_intf);
- if (p_sys == NULL)
- {
- delete p_intf;
- return VLC_ENOMEM;
- }
- p_stream->p_sys = p_sys;
+ intf_sys_t *p_intf = NULL;
+ char *psz_mux = NULL;
+ sout_stream_t *p_sout = NULL;
+ std::stringstream ss;
config_ChainParse(p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg);
- char *psz_ipChromecast = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "ip");
- if (psz_ipChromecast == NULL)
- {
- msg_Err(p_stream, "No Chromecast receiver IP provided");
- Clean(p_stream);
- return VLC_EGENERIC;
- }
-
- p_intf->i_sock_fd = p_intf->connectChromecast(psz_ipChromecast);
- free(psz_ipChromecast);
- if (p_intf->i_sock_fd < 0)
- {
- msg_Err(p_stream, "Could not connect the Chromecast");
- Clean(p_stream);
- return VLC_EGENERIC;
- }
- p_intf->setConnectionStatus(CHROMECAST_TLS_CONNECTED);
-
- char psz_localIP[NI_MAXNUMERICHOST];
- if (net_GetSockAddress(p_intf->i_sock_fd, psz_localIP, NULL))
- {
- msg_Err(p_this, "Cannot get local IP address");
- Clean(p_stream);
- return VLC_EGENERIC;
- }
- p_intf->serverIP = psz_localIP;
-
- char *psz_mux = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "mux");
- if (psz_mux == NULL)
- {
- Clean(p_stream);
- return VLC_EGENERIC;
- }
- char *psz_chain = NULL;
- int i_bytes = asprintf(&psz_chain, "http{dst=:%u/stream,mux=%s}",
- (unsigned)var_InheritInteger(p_stream, SOUT_CFG_PREFIX"http-port"),
- psz_mux);
- free(psz_mux);
- if (i_bytes < 0)
- {
- Clean(p_stream);
- return VLC_EGENERIC;
- }
-
- p_sys->p_out = sout_StreamChainNew(p_stream->p_sout, psz_chain, NULL, NULL);
- free(psz_chain);
- if (p_sys->p_out == NULL)
+ psz_mux = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "mux");
+ if (psz_mux == NULL || !psz_mux[0])
{
- Clean(p_stream);
- return VLC_EGENERIC;
+ goto error;
}
- // Start the Chromecast event thread.
- if (vlc_clone(&p_sys->chromecastThread, chromecastThread, p_stream,
- VLC_THREAD_PRIORITY_LOW))
- {
- msg_Err(p_stream, "Could not start the Chromecast talking thread");
- Clean(p_stream);
- return VLC_EGENERIC;
- }
+ ss << "http{dst=:" << var_InheritInteger(p_stream, SOUT_CFG_PREFIX "http-port") << "/stream"
+ << ",mux=" << psz_mux
+ << ",access=http}";
- /* Ugly part:
- * We want to be sure that the Chromecast receives the first data packet sent by
- * the HTTP server. */
-
- // Lock the sout thread until we have sent the media loading command to the Chromecast.
- int i_ret = 0;
- const mtime_t deadline = mdate() + 6 * CLOCK_FREQ;
- vlc_mutex_lock(&p_intf->lock);
- while (p_intf->getConnectionStatus() != CHROMECAST_MEDIA_LOAD_SENT)
- {
- i_ret = vlc_cond_timedwait(&p_intf->loadCommandCond, &p_intf->lock, deadline);
- if (i_ret == ETIMEDOUT)
- {
- msg_Err(p_stream, "Timeout reached before sending the media loading command");
- vlc_mutex_unlock(&p_intf->lock);
- vlc_cancel(p_sys->chromecastThread);
- Clean(p_stream);
- return VLC_EGENERIC;
- }
+ p_sout = sout_StreamChainNew( p_stream->p_sout, ss.str().c_str(), NULL, NULL);
+ if (p_sout == NULL) {
+ msg_Dbg(p_stream, "could not create sout chain:%s", ss.str().c_str());
+ goto error;
}
- vlc_mutex_unlock(&p_intf->lock);
- /* Even uglier: sleep more to let to the Chromecast initiate the connection
- * to the http server. */
- msleep(2 * CLOCK_FREQ);
+ p_sys = new(std::nothrow) sout_stream_sys_t(p_intf, p_sout);
+ if (unlikely(p_sys == NULL))
+ goto error;
// Set the sout callbacks.
p_stream->pf_add = Add;
@@ -262,9 +180,17 @@ static int Open(vlc_object_t *p_this)
p_stream->pf_flush = Flush;
p_stream->pf_control = Control;
+ p_stream->p_sys = p_sys;
+ free(psz_mux);
+
return VLC_SUCCESS;
-}
+error:
+ sout_StreamChainDelete(p_sout, p_sout);
+ free(psz_mux);
+ Clean(p_stream);
+ return VLC_EGENERIC;
+}
/*****************************************************************************
* Close: destroy interface
@@ -272,24 +198,6 @@ static int Open(vlc_object_t *p_this)
static void Close(vlc_object_t *p_this)
{
sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>(p_this);
- sout_stream_sys_t *p_sys = p_stream->p_sys;
-
- vlc_cancel(p_sys->chromecastThread);
- vlc_join(p_sys->chromecastThread, NULL);
-
- switch (p_sys->p_intf->getConnectionStatus())
- {
- case CHROMECAST_MEDIA_LOAD_SENT:
- case CHROMECAST_APP_STARTED:
- // Generate the close messages.
- p_sys->p_intf->msgReceiverClose(p_sys->p_intf->appTransportId);
- // ft
- case CHROMECAST_AUTHENTICATED:
- p_sys->p_intf->msgReceiverClose(DEFAULT_CHOMECAST_RECEIVER);
- // ft
- default:
- break;
- }
Clean(p_stream);
}
@@ -300,46 +208,6 @@ static void Close(vlc_object_t *p_this)
*/
static void Clean(sout_stream_t *p_stream)
{
- sout_stream_sys_t *p_sys = p_stream->p_sys;
-
- if (p_sys->p_out)
- {
- sout_StreamChainDelete(p_sys->p_out, p_sys->p_out);
- }
-
- p_sys->p_intf->disconnectChromecast();
-
- delete p_sys;
+ delete p_stream->p_sys;
}
-
-
-
-/*****************************************************************************
- * Chromecast thread
- *****************************************************************************/
-static void* chromecastThread(void* p_data)
-{
- int canc = vlc_savecancel();
- // Not cancellation-safe part.
- sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>(p_data);
- sout_stream_sys_t* p_sys = p_stream->p_sys;
-
- p_sys->p_intf->msgAuth();
- vlc_restorecancel(canc);
-
- while (1)
- {
- p_sys->p_intf->handleMessages();
-
- vlc_mutex_lock(&p_sys->p_intf->lock);
- if ( p_sys->p_intf->getConnectionStatus() == CHROMECAST_CONNECTION_DEAD )
- {
- vlc_mutex_unlock(&p_sys->p_intf->lock);
- break;
- }
- vlc_mutex_unlock(&p_sys->p_intf->lock);
- }
-
- return NULL;
-}
diff --git a/modules/stream_out/chromecast/chromecast.h b/modules/stream_out/chromecast/chromecast.h
index f39c7d2..759f011 100644
--- a/modules/stream_out/chromecast/chromecast.h
+++ b/modules/stream_out/chromecast/chromecast.h
@@ -30,10 +30,13 @@
#define VLC_CHROMECAST_H
#include <vlc_common.h>
+#include <vlc_interface.h>
#include <vlc_plugin.h>
#include <vlc_sout.h>
#include <vlc_tls.h>
+#include <sstream>
+
#include "cast_channel.pb.h"
#define PACKET_HEADER_LEN 4
@@ -43,6 +46,7 @@ static const std::string DEFAULT_CHOMECAST_RECEIVER = "receiver-0";
/* see https://developers.google.com/cast/docs/reference/messages */
static const std::string NAMESPACE_MEDIA = "urn:x-cast:com.google.cast.media";
+#define HTTP_PORT 8010
// Status
enum connection_status
@@ -57,10 +61,10 @@ enum connection_status
struct intf_sys_t
{
- intf_sys_t(sout_stream_t * const p_stream);
+ intf_sys_t(intf_thread_t * const intf);
~intf_sys_t();
- sout_stream_t * const p_stream;
+ intf_thread_t * const p_stream;
std::string serverIP;
std::string appTransportId;
@@ -70,6 +74,7 @@ struct intf_sys_t
vlc_mutex_t lock;
vlc_cond_t loadCommandCond;
+ vlc_thread_t chromecastThread;
void msgAuth();
void msgReceiverClose(std::string destinationId);
diff --git a/modules/stream_out/chromecast/chromecast_ctrl.cpp b/modules/stream_out/chromecast/chromecast_ctrl.cpp
index 96bb0fe..0439b73 100644
--- a/modules/stream_out/chromecast/chromecast_ctrl.cpp
+++ b/modules/stream_out/chromecast/chromecast_ctrl.cpp
@@ -32,9 +32,11 @@
#include "chromecast.h"
-#include <vlc_sout.h>
+#include <vlc_playlist.h>
+#include <vlc_threads.h>
-#include <sstream>
+#include <cassert>
+#include <cerrno>
#ifdef HAVE_POLL
# include <poll.h>
#endif
@@ -46,7 +48,7 @@
// Media player Chromecast app id
#define APP_ID "CC1AD845" // Default media player aka DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
-#define CHROMECAST_CONTROL_PORT 8009
+static const int CHROMECAST_CONTROL_PORT = 8009;
/* deadline regarding pings sent from receiver */
#define PING_WAIT_TIME 6000
@@ -55,13 +57,176 @@
#define PONG_WAIT_TIME 500
#define PONG_WAIT_RETRIES 2
-#define SOUT_CFG_PREFIX "sout-chromecast-"
+#define CONTROL_CFG_PREFIX "chromecast-"
static const std::string NAMESPACE_DEVICEAUTH = "urn:x-cast:com.google.cast.tp.deviceauth";
static const std::string NAMESPACE_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
static const std::string NAMESPACE_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
static const std::string NAMESPACE_RECEIVER = "urn:x-cast:com.google.cast.receiver";
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Open(vlc_object_t *);
+static void Close(vlc_object_t *);
+static void Clean(intf_thread_t *);
+
+static void *ChromecastThread(void *data);
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+
+#define IP_TEXT N_("Chromecast IP address")
+#define IP_LONGTEXT N_("This sets the IP adress of the Chromecast receiver.")
+#define HTTP_PORT_TEXT N_("HTTP port")
+#define HTTP_PORT_LONGTEXT N_("This sets the HTTP port of the server " \
+ "used to stream the media to the Chromecast.")
+#define MUXER_TEXT N_("Muxer")
+#define MUXER_LONGTEXT N_("This sets the muxer used to stream to the Chromecast.")
+#define MIME_TEXT N_("MIME content type")
+#define MIME_LONGTEXT N_("This sets the media MIME content type sent to the Chromecast.")
+
+vlc_module_begin ()
+ set_shortname( N_("Chromecast") )
+ set_category( CAT_INTERFACE )
+ set_subcategory( SUBCAT_INTERFACE_CONTROL )
+ set_description( N_("Chromecast interface") )
+ set_capability( "interface", 0 )
+ add_shortcut("chromecast")
+ add_string(CONTROL_CFG_PREFIX "addr", "", IP_TEXT, IP_LONGTEXT, false)
+ add_integer(CONTROL_CFG_PREFIX "http-port", HTTP_PORT, HTTP_PORT_TEXT, HTTP_PORT_LONGTEXT, false)
+ add_string(CONTROL_CFG_PREFIX "mime", "video/x-matroska", MIME_TEXT, MIME_LONGTEXT, false)
+ add_string(CONTROL_CFG_PREFIX "mux", "avformat{mux=matroska}", MUXER_TEXT, MUXER_LONGTEXT, false)
+ set_callbacks( Open, Close )
+
+vlc_module_end ()
+
+/*****************************************************************************
+ * Open: connect to the Chromecast and initialize the sout
+ *****************************************************************************/
+int Open(vlc_object_t *p_this)
+{
+ intf_thread_t *p_intf = reinterpret_cast<intf_thread_t*>(p_this);
+ intf_sys_t *p_sys = new(std::nothrow) intf_sys_t(p_intf);
+ if (unlikely(p_sys == NULL))
+ return VLC_ENOMEM;
+
+ char *psz_ipChromecast = var_InheritString(p_intf, CONTROL_CFG_PREFIX "addr");
+ if (psz_ipChromecast == NULL)
+ {
+ msg_Err(p_intf, "No Chromecast receiver IP provided");
+ Clean(p_intf);
+ return VLC_EGENERIC;
+ }
+
+ p_sys->i_sock_fd = p_sys->connectChromecast(psz_ipChromecast);
+ free(psz_ipChromecast);
+ if (p_sys->i_sock_fd < 0)
+ {
+ msg_Err(p_intf, "Could not connect the Chromecast");
+ Clean(p_intf);
+ return VLC_EGENERIC;
+ }
+ p_sys->setConnectionStatus(CHROMECAST_TLS_CONNECTED);
+
+ char psz_localIP[NI_MAXNUMERICHOST];
+ if (net_GetSockAddress(p_sys->i_sock_fd, psz_localIP, NULL))
+ {
+ msg_Err(p_this, "Cannot get local IP address");
+ Clean(p_intf);
+ return VLC_EGENERIC;
+ }
+ p_sys->serverIP = psz_localIP;
+
+ char *psz_mux = var_InheritString(p_intf, CONTROL_CFG_PREFIX "mux");
+ if (psz_mux == NULL)
+ {
+ Clean(p_intf);
+ return VLC_EGENERIC;
+ }
+
+ // Start the Chromecast event thread.
+ if (vlc_clone(&p_sys->chromecastThread, ChromecastThread, p_intf,
+ VLC_THREAD_PRIORITY_LOW))
+ {
+ msg_Err(p_intf, "Could not start the Chromecast talking thread");
+ Clean(p_intf);
+ return VLC_EGENERIC;
+ }
+
+ /* Ugly part:
+ * We want to be sure that the Chromecast receives the first data packet sent by
+ * the HTTP server. */
+
+ // Lock the sout thread until we have sent the media loading command to the Chromecast.
+ int i_ret = 0;
+ const mtime_t deadline = mdate() + 6 * CLOCK_FREQ;
+ vlc_mutex_lock(&p_sys->lock);
+ while (p_sys->getConnectionStatus() != CHROMECAST_MEDIA_LOAD_SENT)
+ {
+ i_ret = vlc_cond_timedwait(&p_sys->loadCommandCond, &p_sys->lock, deadline);
+ if (i_ret == ETIMEDOUT)
+ {
+ msg_Err(p_intf, "Timeout reached before sending the media loading command");
+ vlc_mutex_unlock(&p_sys->lock);
+ vlc_cancel(p_sys->chromecastThread);
+ Clean(p_intf);
+ return VLC_EGENERIC;
+ }
+ }
+ vlc_mutex_unlock(&p_sys->lock);
+
+ /* Even uglier: sleep more to let to the Chromecast initiate the connection
+ * to the http server. */
+ msleep(2 * CLOCK_FREQ);
+
+ p_intf->p_sys = p_sys;
+
+ return VLC_SUCCESS;
+}
+
+
+/*****************************************************************************
+ * Close: destroy interface
+ *****************************************************************************/
+void Close(vlc_object_t *p_this)
+{
+ intf_thread_t *p_intf = reinterpret_cast<intf_thread_t*>(p_this);
+ intf_sys_t *p_sys = p_intf->p_sys;
+
+ vlc_cancel(p_sys->chromecastThread);
+ vlc_join(p_sys->chromecastThread, NULL);
+
+ switch (p_sys->getConnectionStatus())
+ {
+ case CHROMECAST_MEDIA_LOAD_SENT:
+ case CHROMECAST_APP_STARTED:
+ // Generate the close messages.
+ p_sys->msgReceiverClose(p_sys->appTransportId);
+ // ft
+ case CHROMECAST_AUTHENTICATED:
+ p_sys->msgReceiverClose(DEFAULT_CHOMECAST_RECEIVER);
+ // ft
+ default:
+ break;
+ }
+
+ Clean(p_intf);
+}
+
+/**
+ * @brief Clean and release the variables in a sout_stream_sys_t structure
+ */
+void Clean(intf_thread_t *p_stream)
+{
+ intf_sys_t *p_sys = p_stream->p_sys;
+
+ p_sys->disconnectChromecast();
+
+ delete p_sys;
+}
+
/**
* @brief Build a CastMessage to send to the Chromecast
* @param namespace_ the message namespace
@@ -91,7 +256,7 @@ void intf_sys_t::buildMessage(const std::string & namespace_,
sendMessage(msg);
}
-intf_sys_t::intf_sys_t(sout_stream_t * const p_this)
+intf_sys_t::intf_sys_t(intf_thread_t * const p_this)
: p_stream(p_this)
, p_tls(NULL)
, conn_status(CHROMECAST_DISCONNECTED)
@@ -163,7 +328,7 @@ void intf_sys_t::disconnectChromecast()
* @return the number of bytes received of -1 on error
*/
// Use here only C linkage and POD types as this function is a cancelation point.
-extern "C" int recvPacket(sout_stream_t *p_stream, bool &b_msgReceived,
+extern "C" int recvPacket(vlc_object_t *p_stream, bool &b_msgReceived,
uint32_t &i_payloadSize, int i_sock_fd, vlc_tls_t *p_tls,
unsigned *pi_received, uint8_t *p_data, bool *pb_pingTimeout,
int *pi_wait_delay, int *pi_wait_retries)
@@ -509,14 +674,14 @@ void intf_sys_t::msgReceiverLaunchApp()
void intf_sys_t::msgPlayerLoad()
{
- char *psz_mime = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "mime");
+ char *psz_mime = var_InheritString(p_stream, CONTROL_CFG_PREFIX "mime");
if (psz_mime == NULL)
return;
std::stringstream ss;
ss << "{\"type\":\"LOAD\","
<< "\"media\":{\"contentId\":\"http://" << serverIP << ":"
- << var_InheritInteger(p_stream, SOUT_CFG_PREFIX"http-port")
+ << var_InheritInteger(p_stream, CONTROL_CFG_PREFIX"http-port")
<< "/stream\","
<< "\"streamType\":\"LIVE\","
<< "\"contentType\":\"" << std::string(psz_mime) << "\"},"
@@ -555,6 +720,31 @@ int intf_sys_t::sendMessage(const castchannel::CastMessage &msg)
return VLC_EGENERIC;
}
+/*****************************************************************************
+ * Chromecast thread
+ *****************************************************************************/
+static void* ChromecastThread(void* p_data)
+{
+ int canc = vlc_savecancel();
+ // Not cancellation-safe part.
+ intf_thread_t *p_stream = reinterpret_cast<intf_thread_t*>(p_data);
+ intf_sys_t *p_sys = p_stream->p_sys;
+
+ p_sys->msgAuth();
+ vlc_restorecancel(canc);
+
+ while (1)
+ {
+ p_sys->handleMessages();
+
+ vlc_mutex_locker locker(&p_sys->lock);
+ if ( p_sys->getConnectionStatus() == CHROMECAST_CONNECTION_DEAD )
+ break;
+ }
+
+ return NULL;
+}
+
void intf_sys_t::handleMessages()
{
unsigned i_received = 0;
@@ -566,7 +756,7 @@ void intf_sys_t::handleMessages()
bool b_msgReceived = false;
uint32_t i_payloadSize = 0;
- int i_ret = recvPacket(p_stream, b_msgReceived, i_payloadSize, i_sock_fd,
+ int i_ret = recvPacket(VLC_OBJECT(p_stream), b_msgReceived, i_payloadSize, i_sock_fd,
p_tls, &i_received, p_packet, &b_pingTimeout,
&i_waitdelay, &i_retries);
--
2.6.0.windows.1
More information about the vlc-devel
mailing list