[vlc-commits] chromecast: add a stream out proxy
Thomas Guillem
git at videolan.org
Thu Jan 25 18:33:29 CET 2018
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Jan 25 18:01:31 2018 +0100| [5fb95aaf5ea1887e670ee0faf33d71065035f938] | committer: Thomas Guillem
chromecast: add a stream out proxy
This new submodule wait for all tracks to be added into the last stream out
(the http one) before running a chromecast session.
This fixes chromecast timeout errors when the session was started during the
middle of a playback and when the http sout was still empty (because no video
IFrames were available for example).
This also fixes the "You can try increasing sout-mux-caching value" error (when
the timeout came from VLC and not the CC).
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5fb95aaf5ea1887e670ee0faf33d71065035f938
---
modules/stream_out/chromecast/cast.cpp | 101 ++++++++++++++++++++++++++++++---
1 file changed, 93 insertions(+), 8 deletions(-)
diff --git a/modules/stream_out/chromecast/cast.cpp b/modules/stream_out/chromecast/cast.cpp
index a017d98b92..182e0ee600 100644
--- a/modules/stream_out/chromecast/cast.cpp
+++ b/modules/stream_out/chromecast/cast.cpp
@@ -71,6 +71,7 @@ struct sout_stream_sys_t
std::string sout;
const std::string default_muxer;
const std::string default_mime;
+ std::string mime;
intf_sys_t * const p_intf;
const bool b_supports_video;
@@ -79,8 +80,10 @@ struct sout_stream_sys_t
sout_stream_id_sys_t *GetSubId( sout_stream_t*, sout_stream_id_sys_t* );
bool es_changed;
+ bool cc_has_input;
std::vector<sout_stream_id_sys_t*> streams;
std::vector<sout_stream_id_sys_t*> out_streams;
+ unsigned int out_streams_added;
unsigned int transcode_attempt_idx;
States previous_state;
@@ -100,6 +103,7 @@ static const char DEFAULT_MUXER[] = "avformat{mux=matroska,options={live=1}}";
*****************************************************************************/
static int Open(vlc_object_t *);
static void Close(vlc_object_t *);
+static int ProxyOpen(vlc_object_t *);
static const char *const ppsz_sout_options[] = {
"ip", "port", "http-port", "mux", "mime", "video", NULL
@@ -182,6 +186,11 @@ vlc_module_begin ()
CONVERSION_QUALITY_TEXT, CONVERSION_QUALITY_LONGTEXT, false );
change_integer_list(conversion_quality_list, conversion_quality_list_text)
+ add_submodule()
+ /* sout proxy that start the cc input when all streams are loaded */
+ add_shortcut("chromecast-proxy")
+ set_capability("sout stream", 0)
+ set_callbacks(ProxyOpen, NULL)
vlc_module_end ()
@@ -191,6 +200,72 @@ struct sout_stream_id_sys_t
sout_stream_id_sys_t *p_sub_id;
};
+static sout_stream_id_sys_t *ProxyAdd(sout_stream_t *p_stream, const es_format_t *p_fmt)
+{
+ sout_stream_sys_t *p_sys = p_stream->p_sys;
+ sout_stream_id_sys_t *id = sout_StreamIdAdd(p_stream->p_next, p_fmt);
+ if (id)
+ p_sys->out_streams_added++;
+ return id;
+}
+
+static void ProxyDel(sout_stream_t *p_stream, sout_stream_id_sys_t *id)
+{
+ sout_stream_sys_t *p_sys = p_stream->p_sys;
+ p_sys->out_streams_added--;
+ return sout_StreamIdDel(p_stream->p_next, id);
+}
+
+static int ProxySend(sout_stream_t *p_stream, sout_stream_id_sys_t *id,
+ block_t *p_buffer)
+{
+ sout_stream_sys_t *p_sys = p_stream->p_sys;
+ if (p_sys->cc_has_input || p_sys->out_streams_added >= p_sys->out_streams.size())
+ {
+ int ret = sout_StreamIdSend(p_stream->p_next, id, p_buffer);
+ if (ret == VLC_SUCCESS && !p_sys->cc_has_input)
+ {
+ /* Start the chromecast only when all streams are added into the
+ * last sout (the http one) */
+ p_sys->p_intf->setHasInput(p_sys->mime);
+ p_sys->cc_has_input = true;
+ }
+ return ret;
+ }
+ else
+ {
+ block_Release(p_buffer);
+ return VLC_SUCCESS;
+ }
+}
+
+static void ProxyFlush(sout_stream_t *p_stream, sout_stream_id_sys_t *id)
+{
+ return sout_StreamFlush(p_stream->p_next, id);
+}
+
+static int ProxyControl(sout_stream_t *p_stream, int i_query, va_list args)
+{
+ if (!p_stream->p_next->pf_control)
+ return VLC_EGENERIC;
+ return p_stream->p_next->pf_control(p_stream->p_next, i_query, args);
+}
+
+static int ProxyOpen(vlc_object_t *p_this)
+{
+ sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>(p_this);
+ p_stream->p_sys = (sout_stream_sys_t *) var_InheritAddress(p_this, SOUT_CFG_PREFIX "sys");
+ if (p_stream->p_sys == NULL || p_stream->p_next == NULL)
+ return VLC_EGENERIC;
+
+ p_stream->pf_add = ProxyAdd;
+ p_stream->pf_del = ProxyDel;
+ p_stream->pf_send = ProxySend;
+ p_stream->pf_flush = ProxyFlush;
+ p_stream->pf_control = ProxyControl;
+ return VLC_SUCCESS;
+}
+
/*****************************************************************************
* Sout callbacks
*****************************************************************************/
@@ -322,6 +397,9 @@ bool sout_stream_sys_t::startSoutChain( sout_stream_t *p_stream )
}
msg_Dbg( p_stream, "Creating chain %s", sout.c_str() );
+ cc_has_input = false;
+ out_streams_added = 0;
+
p_out = sout_StreamChainNew( p_stream->p_sout, sout.c_str(), NULL, NULL);
if (p_out == NULL) {
msg_Dbg(p_stream, "could not create sout chain:%s", sout.c_str());
@@ -508,7 +586,6 @@ bool sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )
}
ssout << "}:";
}
- std::string mime;
if ( !p_original_video && default_muxer == DEFAULT_MUXER )
mime = "audio/x-matroska";
else if ( i_codec_audio == VLC_CODEC_VORBIS &&
@@ -518,18 +595,14 @@ bool sout_stream_sys_t::UpdateOutput( sout_stream_t *p_stream )
else
mime = default_mime;
- ssout << "http{dst=:" << i_port << "/stream"
+ ssout << "chromecast-proxy:"
+ << "http{dst=:" << i_port << "/stream"
<< ",mux=" << default_muxer
<< ",access=http{mime=" << mime << "}}";
sout = ssout.str();
- if ( startSoutChain( p_stream ) )
- {
- /* tell the chromecast to load the content */
- p_intf->setHasInput( mime );
- }
- else
+ if ( !startSoutChain( p_stream ) )
{
p_intf->requestPlayerStop();
@@ -598,7 +671,11 @@ static int Send(sout_stream_t *p_stream, sout_stream_id_sys_t *id,
int ret = sout_StreamIdSend(p_sys->p_out, next_id, p_buffer);
if (ret != VLC_SUCCESS)
+ {
+ bool was_es_changed = p_sys->es_changed;
Del(p_stream, id);
+ p_sys->es_changed = was_es_changed;
+ }
return ret;
}
@@ -712,6 +789,13 @@ static int Open(vlc_object_t *p_this)
if (unlikely(p_sys == NULL))
goto error;
+ /* prevent sout-mux-caching since chromecast-proxy is already doing it */
+ var_Create( p_stream->p_sout, "sout-mux-caching", VLC_VAR_INTEGER );
+ var_SetInteger( p_stream->p_sout, "sout-mux-caching", 0 );
+
+ var_Create( p_stream->p_sout, SOUT_CFG_PREFIX "sys", VLC_VAR_ADDRESS );
+ var_SetAddress( p_stream->p_sout, SOUT_CFG_PREFIX "sys", p_sys );
+
// Set the sout callbacks.
p_stream->pf_add = Add;
p_stream->pf_del = Del;
@@ -743,6 +827,7 @@ static void Close(vlc_object_t *p_this)
{
sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>(p_this);
+ var_Destroy( p_stream->p_sout, SOUT_CFG_PREFIX "sys" );
delete p_stream->p_sys;
}
More information about the vlc-commits
mailing list