[vlc-devel] [PATCH 04/12] chromecast: only create the sub-sout when we know the ES in use

Steve Lhomme robux4 at videolabs.io
Tue Apr 26 11:01:30 CEST 2016


This patch is replaced and merged into https://patches.videolan.org/patch/13091/

On Mon, Apr 25, 2016 at 5:46 PM, Steve Lhomme <robux4 at videolabs.io> wrote:
> we then decide whether we want to remux or transcode
> use the Matroska as it allows better streaming and more codec than the
> Chromecast supports (VP8 / Vorbis)
> ---
>  modules/stream_out/chromecast/cast.cpp | 168 +++++++++++++++++++++++++++++++--
>  1 file changed, 160 insertions(+), 8 deletions(-)
>
> diff --git a/modules/stream_out/chromecast/cast.cpp b/modules/stream_out/chromecast/cast.cpp
> index 1581695..6886799 100644
> --- a/modules/stream_out/chromecast/cast.cpp
> +++ b/modules/stream_out/chromecast/cast.cpp
> @@ -38,10 +38,14 @@
>
>  struct sout_stream_sys_t
>  {
> -    sout_stream_sys_t(intf_sys_t *intf, sout_stream_t *sout, bool has_video)
> -        : p_out(sout)
> +    sout_stream_sys_t(intf_sys_t * const intf, bool has_video, int port,
> +                      const char *psz_default_muxer, const char *psz_default_mime)
> +        : p_out(NULL)
> +        , default_muxer(psz_default_muxer)
> +        , default_mime(psz_default_mime)
>          , p_intf(intf)
>          , b_has_video(has_video)
> +        , i_port(port)
>          , last_added_ts( VLC_TS_INVALID )
>      {
>          assert(p_intf != NULL);
> @@ -56,9 +60,17 @@ struct sout_stream_sys_t
>          vlc_mutex_destroy( &es_lock );
>      }
>
> -    sout_stream_t * const p_out;
> +    bool canDecodeVideo( const es_format_t *p_es ) const;
> +    bool canDecodeAudio( const es_format_t *p_es ) const;
> +
> +    sout_stream_t     *p_out;
> +    std::string        sout;
> +    const std::string  default_muxer;
> +    const std::string  default_mime;
> +
>      intf_sys_t * const p_intf;
>      const bool b_has_video;
> +    const int i_port;
>
>      sout_stream_id_sys_t *GetSubId( sout_stream_t*, sout_stream_id_sys_t* );
>
> @@ -74,6 +86,11 @@ private:
>  #define SOUT_CFG_PREFIX "sout-chromecast-"
>  const static mtime_t MAX_WAIT_BETWEEN_ADD = (CLOCK_FREQ / 3);
>
> +static const vlc_fourcc_t DEFAULT_TRANSCODE_AUDIO = VLC_CODEC_MP3;
> +static const vlc_fourcc_t DEFAULT_TRANSCODE_VIDEO = VLC_CODEC_H264;
> +static const char DEFAULT_MUXER[] = "avformat{mux=matroska}";
> +
> +
>  /*****************************************************************************
>   * Local prototypes
>   *****************************************************************************/
> @@ -110,8 +127,8 @@ vlc_module_begin ()
>
>      add_integer(SOUT_CFG_PREFIX "http-port", HTTP_PORT, HTTP_PORT_TEXT, HTTP_PORT_LONGTEXT, false)
>      add_bool(SOUT_CFG_PREFIX "video", true, HAS_VIDEO_TEXT, HAS_VIDEO_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)
> +    add_string(SOUT_CFG_PREFIX "mux", DEFAULT_MUXER, MUX_TEXT, MUX_LONGTEXT, false)
> +    add_string(SOUT_CFG_PREFIX "mime", "video/x-matroska", MIME_TEXT, MIME_LONGTEXT, false)
>
>  vlc_module_end ()
>
> @@ -168,6 +185,36 @@ static void Del(sout_stream_t *p_stream, sout_stream_id_sys_t *id)
>              break;
>          }
>      }
> +
> +    if ( p_sys->streams.empty() )
> +    {
> +        sout_StreamChainDelete( p_sys->p_out, p_sys->p_out );
> +        p_sys->p_out = NULL;
> +        p_sys->sout = "";
> +    }
> +}
> +
> +
> +bool sout_stream_sys_t::canDecodeVideo( const es_format_t *p_es ) const
> +{
> +    if (p_es->i_codec == VLC_CODEC_H264 || p_es->i_codec == VLC_CODEC_VP8)
> +        return true;
> +    return false;
> +}
> +
> +bool sout_stream_sys_t::canDecodeAudio( const es_format_t *p_es ) const
> +{
> +    if (p_es->i_codec == VLC_CODEC_VORBIS ||
> +        p_es->i_codec == VLC_CODEC_MP4A ||
> +        p_es->i_codec == VLC_FOURCC('h', 'a', 'a', 'c') ||
> +        p_es->i_codec == VLC_FOURCC('l', 'a', 'a', 'c') ||
> +        p_es->i_codec == VLC_FOURCC('s', 'a', 'a', 'c') ||
> +        p_es->i_codec == VLC_CODEC_MPGA ||
> +        p_es->i_codec == VLC_CODEC_MP3 ||
> +        p_es->i_codec == VLC_CODEC_A52 ||
> +        p_es->i_codec == VLC_CODEC_EAC3)
> +        return true;
> +    return false;
>  }
>
>  int sout_stream_sys_t::WaitEsReady( sout_stream_t *p_stream )
> @@ -184,6 +231,107 @@ int sout_stream_sys_t::WaitEsReady( sout_stream_t *p_stream )
>              vlc_cleanup_pop();
>          }
>          last_added_ts = VLC_TS_INVALID;
> +
> +        bool canRemux = true;
> +        vlc_fourcc_t i_codec_video = 0, i_codec_audio = 0;
> +
> +        for (std::vector<sout_stream_id_sys_t*>::iterator it = streams.begin(); it != streams.end(); ++it)
> +        {
> +            const es_format_t *p_es = &(*it)->fmt;
> +            if (p_es->i_cat == AUDIO_ES)
> +            {
> +                if (!canDecodeAudio( p_es ))
> +                {
> +                    msg_Dbg( p_stream, "can't remux audio track %d codec %4.4s", p_es->i_id, (const char*)&p_es->i_codec );
> +                    canRemux = false;
> +                }
> +                else if (i_codec_audio == 0)
> +                    i_codec_audio = p_es->i_codec;
> +            }
> +            else if (b_has_video && p_es->i_cat == VIDEO_ES)
> +            {
> +                if (!canDecodeVideo( p_es ))
> +                {
> +                    msg_Dbg( p_stream, "can't remux video track %d codec %4.4s", p_es->i_id, (const char*)&p_es->i_codec );
> +                    canRemux = false;
> +                }
> +                else if (i_codec_video == 0)
> +                    i_codec_video = p_es->i_codec;
> +            }
> +        }
> +
> +        std::stringstream ssout;
> +        if ( !canRemux )
> +        {
> +            if ( i_codec_audio == 0 )
> +                i_codec_audio = DEFAULT_TRANSCODE_AUDIO;
> +            /* avcodec AAC encoder is experimental */
> +            if ( i_codec_audio == VLC_CODEC_MP4A ||
> +                 i_codec_audio == VLC_FOURCC('h', 'a', 'a', 'c') ||
> +                 i_codec_audio == VLC_FOURCC('l', 'a', 'a', 'c') ||
> +                 i_codec_audio == VLC_FOURCC('s', 'a', 'a', 'c'))
> +                i_codec_audio = DEFAULT_TRANSCODE_AUDIO;
> +
> +            if ( i_codec_video == 0 )
> +                i_codec_video = DEFAULT_TRANSCODE_VIDEO;
> +
> +            /* TODO: provide audio samplerate and channels */
> +            ssout << "transcode{acodec=";
> +            char s_fourcc[5];
> +            vlc_fourcc_to_char( i_codec_audio, s_fourcc );
> +            s_fourcc[4] = '\0';
> +            ssout << s_fourcc;
> +            if ( b_has_video )
> +            {
> +                /* TODO: provide maxwidth,maxheight */
> +                ssout << ",vcodec=";
> +                vlc_fourcc_to_char( i_codec_video, s_fourcc );
> +                s_fourcc[4] = '\0';
> +                ssout << s_fourcc;
> +            }
> +            ssout << "}:";
> +        }
> +        std::string mime;
> +        if ( !b_has_video && default_muxer == DEFAULT_MUXER )
> +            mime = "audio/x-matroska";
> +        else if ( i_codec_audio == VLC_CODEC_VORBIS &&
> +                  i_codec_video == VLC_CODEC_VP8 &&
> +                  default_muxer == DEFAULT_MUXER )
> +            mime = "video/webm";
> +        else
> +            mime = default_mime;
> +
> +        ssout << "http{dst=:" << i_port << "/stream"
> +              << ",mux=" << default_muxer
> +              << ",access=http{mime=" << mime << "}}";
> +
> +        if ( sout != ssout.str() )
> +        {
> +            if ( unlikely( p_out != NULL ) )
> +            {
> +                sout_StreamChainDelete( p_out, p_out );
> +                sout = "";
> +            }
> +
> +            p_out = sout_StreamChainNew( p_stream->p_sout, ssout.str().c_str(), NULL, NULL);
> +            if (p_out == NULL) {
> +                msg_Dbg(p_stream, "could not create sout chain:%s", ssout.str().c_str());
> +                return VLC_EGENERIC;
> +            }
> +            sout = ssout.str();
> +        }
> +
> +        /* check the streams we can actually add */
> +        for (std::vector<sout_stream_id_sys_t*>::iterator it = streams.begin(); it != streams.end(); ++it)
> +        {
> +            sout_stream_id_sys_t *p_sys_id = *it;
> +            p_sys_id->p_sub_id = sout_StreamIdAdd( p_out, &p_sys_id->fmt );
> +            if ( p_sys_id->p_sub_id == NULL )
> +            {
> +                msg_Err( p_stream, "can't handle a stream" );
> +                streams.erase( it, it );
> +            }
> +        }
>      }
>
>      return VLC_SUCCESS;
> @@ -255,9 +403,11 @@ static int Open(vlc_object_t *p_this)
>      char *psz_var_mime = NULL;
>      sout_stream_t *p_sout = NULL;
>      bool b_has_video = true;
> +    int i_local_server_port;
>      std::stringstream ss;
>
>      config_ChainParse(p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg);
> +    i_local_server_port = var_InheritInteger(p_stream, SOUT_CFG_PREFIX "http-port");
>
>      psz_mux = var_GetNonEmptyString(p_stream, SOUT_CFG_PREFIX "mux");
>      if (psz_mux == NULL)
> @@ -268,7 +418,8 @@ static int Open(vlc_object_t *p_this)
>      if (psz_var_mime == NULL)
>          goto error;
>
> -    ss << "http{dst=:" << var_InheritInteger(p_stream, SOUT_CFG_PREFIX "http-port") << "/stream"
> +    /* check if we can open the proper sout */
> +    ss << "http{dst=:" << i_local_server_port << "/stream"
>         << ",mux=" << psz_mux
>         << ",access=http{mime=" << psz_var_mime << "}}";
>
> @@ -280,9 +431,11 @@ static int Open(vlc_object_t *p_this)
>
>      b_has_video = var_GetBool(p_stream, SOUT_CFG_PREFIX "video");
>
> -    p_sys = new(std::nothrow) sout_stream_sys_t(p_intf, p_sout, b_has_video);
> +    p_sys = new(std::nothrow) sout_stream_sys_t( p_intf, b_has_video, i_local_server_port,
> +                                                 psz_mux, psz_var_mime );
>      if (unlikely(p_sys == NULL))
>          goto error;
> +    sout_StreamChainDelete( p_sout, p_sout );
>
>      // Set the sout callbacks.
>      p_stream->pf_add     = Add;
> @@ -297,7 +450,6 @@ static int Open(vlc_object_t *p_this)
>      return VLC_SUCCESS;
>
>  error:
> -    sout_StreamChainDelete(p_sout, p_sout);
>      free(psz_mux);
>      free(psz_var_mime);
>      delete p_sys;
> --
> 2.7.0
>


More information about the vlc-devel mailing list