Beispiel #1
0
/**
 *  Register a new session with the announce handler, using a pregenerated SDP
 *
 * \param p_sout a sout instance structure
 * \param psz_sdp the SDP to register
 * \param psz_uri session URI (needed for SAP address auto detection
 * \param p_method an announce method descriptor
 * \return the new session descriptor structure
 */
session_descriptor_t *sout_AnnounceRegisterSDP( sout_instance_t *p_sout,
                          const char *psz_sdp, const char *psz_uri,
                          announce_method_t *p_method )
{
    session_descriptor_t *p_session;
    announce_handler_t *p_announce = (announce_handler_t*)
                                     vlc_object_find( p_sout,
                                              VLC_OBJECT_ANNOUNCE,
                                              FIND_ANYWHERE );
    if( !p_announce )
    {
        msg_Dbg( p_sout, "no announce handler found, creating one" );
        p_announce = announce_HandlerCreate( p_sout );
        if( !p_announce )
        {
            msg_Err( p_sout, "Creation failed" );
            return NULL;
        }
        vlc_object_yield( p_announce );
    }

    if( p_method->i_type != METHOD_TYPE_SAP )
    {
        msg_Warn( p_sout, "forcing SAP announcement");
    }

    p_session = sout_AnnounceSessionCreate();
    p_session->psz_sdp = strdup( psz_sdp );
    p_session->psz_uri = strdup( psz_uri );
    announce_Register( p_announce, p_session, p_method );

    vlc_object_release( p_announce );
    return p_session;
}
Beispiel #2
0
/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    sout_stream_t       *p_stream = (sout_stream_t*)p_this;
    sout_instance_t     *p_sout = p_stream->p_sout;
    slp_session_t       *p_slp = NULL;

    char *psz_mux;
    char *psz_access;
    char *psz_url;

    vlc_value_t val;

    sout_access_out_t   *p_access;
    sout_mux_t          *p_mux;

    char                *psz_mux_byext = NULL;

    sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options,
                   p_stream->p_cfg );

    var_Get( p_stream, SOUT_CFG_PREFIX "access", &val );
    psz_access = *val.psz_string ? val.psz_string : NULL;
    if( val.psz_string && !*val.psz_string ) free( val.psz_string );

    var_Get( p_stream, SOUT_CFG_PREFIX "mux", &val );
    psz_mux = *val.psz_string ? val.psz_string : NULL;
    if( val.psz_string && !*val.psz_string ) free( val.psz_string );

    var_Get( p_stream, SOUT_CFG_PREFIX "url", &val );
    psz_url = *val.psz_string ? val.psz_string : NULL;
    if( val.psz_string && !*val.psz_string ) free( val.psz_string );

    p_stream->p_sys = malloc( sizeof( sout_stream_sys_t) );
    p_stream->p_sys->p_session = NULL;

    msg_Dbg( p_this, "creating `%s/%s://%s'", psz_access, psz_mux, psz_url );

    /* ext -> muxer name */
    if( psz_url && strrchr( psz_url, '.' ) )
    {
        /* by extention */
        static struct { char *ext; char *mux; } exttomux[] =
        {
            { "avi", "avi" },
            { "ogg", "ogg" },
            { "ogm", "ogg" },
            { "mp4", "mp4" },
            { "mov", "mov" },
            { "moov","mov" },
            { "asf", "asf" },
            { "wma", "asf" },
            { "wmv", "asf" },
            { "trp", "ts" },
            { "ts",  "ts" },
            { "mpg", "ps" },
            { "mpeg","ps" },
            { "ps",  "ps" },
            { "mpeg1","mpeg1" },
            { NULL,  NULL }
        };
        char *psz_ext = strrchr( psz_url, '.' ) + 1;
        int  i;

        msg_Dbg( p_this, "extention is %s", psz_ext );
        for( i = 0; exttomux[i].ext != NULL; i++ )
        {
            if( !strcasecmp( psz_ext, exttomux[i].ext ) )
            {
                psz_mux_byext = exttomux[i].mux;
                break;
            }
        }
        msg_Dbg( p_this, "extention -> mux=%s", psz_mux_byext );
    }

    /* We fix access/mux to valid couple */

    if( !psz_access && !psz_mux )
    {
        if( psz_mux_byext )
        {
            msg_Warn( p_stream,
                      "no access _and_ no muxer, extention gives file/%s",
                      psz_mux_byext );
            psz_access = strdup("file");
            psz_mux    = strdup(psz_mux_byext);
        }
        else
        {
            msg_Err( p_stream, "no access _and_ no muxer (fatal error)" );
            return VLC_EGENERIC;
        }
    }

    if( psz_access && !psz_mux )
    {
        /* access given, no mux */
        if( !strncmp( psz_access, "mmsh", 4 ) )
        {
            psz_mux = strdup("asfh");
        }
        else if( !strncmp( psz_access, "udp", 3 ) )
        {
            psz_mux = strdup("ts");
        }
        else if( psz_mux_byext )
        {
            psz_mux = strdup(psz_mux_byext);
        }
        else
        {
            msg_Err( p_stream, "no mux specified or found by extention" );
            return VLC_EGENERIC;
        }
    }
    else if( psz_mux && !psz_access )
    {
        /* mux given, no access */
        if( !strncmp( psz_mux, "asfh", 4 ) )
        {
            psz_access = strdup("mmsh");
        }
        else
        {
            /* default file */
            psz_access = strdup("file");
        }
    }

    /* fix or warm of incompatible couple */
    if( psz_mux && psz_access )
    {
        if( !strncmp( psz_access, "mmsh", 4 ) &&
            strncmp( psz_mux, "asfh", 4 ) )
        {
            char *p = strchr( psz_mux,'{' );

            msg_Warn( p_stream, "fixing to mmsh/asfh" );
            if( p )
            {
                /* -> a little memleak but ... */
                psz_mux = malloc( strlen( "asfh" ) + strlen( p ) + 1);
                sprintf( psz_mux, "asfh%s", p );
            }
            else
            {
                psz_mux = strdup("asfh");
            }
        }
        else if( ( !strncmp( psz_access, "rtp", 3 ) ||
                   !strncmp( psz_access, "udp", 3 ) ) &&
                 strncmp( psz_mux, "ts", 2 ) )
        {
            msg_Err( p_stream, "for now udp and rtp are only valid with TS" );
        }
        else if( strncmp( psz_access, "file", 4 ) &&
                 ( !strncmp( psz_mux, "mov", 3 ) ||
                   !strncmp( psz_mux, "mp4", 3 ) ) )
        {
            msg_Err( p_stream, "mov and mp4 work only with file output" );
        }
    }

    msg_Dbg( p_this, "using `%s/%s://%s'", psz_access, psz_mux, psz_url );

    /* *** find and open appropriate access module *** */
    p_access = sout_AccessOutNew( p_sout, psz_access, psz_url );
    if( p_access == NULL )
    {
        msg_Err( p_stream, "no suitable sout access module for `%s/%s://%s'",
                 psz_access, psz_mux, psz_url );
        if( psz_access ) free( psz_access );
        if( psz_mux ) free( psz_mux );
        return VLC_EGENERIC;
    }
    msg_Dbg( p_stream, "access opened" );

    /* *** find and open appropriate mux module *** */
    p_mux = sout_MuxNew( p_sout, psz_mux, p_access );
    if( p_mux == NULL )
    {
        msg_Err( p_stream, "no suitable sout mux module for `%s/%s://%s'",
                 psz_access, psz_mux, psz_url );

        sout_AccessOutDelete( p_access );
        if( psz_access ) free( psz_access );
        if( psz_mux ) free( psz_mux );
        return VLC_EGENERIC;
    }
    msg_Dbg( p_stream, "mux opened" );

    /*  *** Create the SAP Session structure *** */
    var_Get( p_stream, SOUT_CFG_PREFIX "sap", &val );
    if( val.b_bool &&
        ( strstr( psz_access, "udp" ) || strstr( psz_access , "rtp" ) ) )
    {
        session_descriptor_t *p_session = sout_AnnounceSessionCreate();
        announce_method_t *p_method =
            sout_AnnounceMethodCreate( METHOD_TYPE_SAP );
        vlc_url_t url;

        var_Get( p_stream, SOUT_CFG_PREFIX "name", &val );
        if( *val.psz_string )
        {
            p_session->psz_name = strdup( val.psz_string );
        }
        else
        {
            p_session->psz_name = strdup( psz_url );
        }
        free( val.psz_string );

        var_Get( p_stream, SOUT_CFG_PREFIX "group", &val );
        if( *val.psz_string )
        {
            p_session->psz_group = strdup( val.psz_string );
        }
        free( val.psz_string );

        var_Get( p_stream, SOUT_CFG_PREFIX "sap-ipv6", &val );
        p_method->i_ip_version = val.b_bool ? 6 : 4;

        /* Now, parse the URL to extract host and port */
        vlc_UrlParse( &url, psz_url , 0);

        if( url.psz_host )
        {
            if( url.i_port == 0 ) url.i_port = DEFAULT_PORT;

            p_session->psz_uri = url.psz_host;
            p_session->i_port = url.i_port;
            p_session->psz_sdp = NULL;

            p_session->i_ttl = config_GetInt( p_sout, "ttl" );
            p_session->i_payload = 33;

            msg_Info( p_this, "SAP Enabled");

            sout_AnnounceRegister( p_sout, p_session, p_method );

            /* FIXME: Free p_method */

            p_stream->p_sys->p_session = p_session;
        }
        vlc_UrlClean( &url );

        if( p_method->psz_address) free( p_method->psz_address );
        free( p_method );
    }

    /* *** Register with slp *** */
#ifdef HAVE_SLP_H
    var_Get( p_stream, SOUT_CFG_PREFIX "slp", &val );
    if( val.b_bool &&
        ( strstr( psz_access, "udp" ) || strstr( psz_access ,  "rtp" ) ) )
    {
        int i_ret;

        msg_Info( p_this, "SLP Enabled");
        var_Get( p_stream, SOUT_CFG_PREFIX "name", &val );
        if( *val.psz_string )
        {
            i_ret = sout_SLPReg( p_sout, psz_url, val.psz_string );
        }
        else
        {
            i_ret = sout_SLPReg( p_sout, psz_url, psz_url );
        }

        if( i_ret )
        {
           msg_Warn( p_sout, "SLP Registering failed");
        }
        else
        {
            p_slp = malloc(sizeof(slp_session_t));
            p_slp->psz_url = strdup( psz_url );
            p_slp->psz_name =
                strdup( *val.psz_string ? val.psz_string : psz_url );
        }
        free( val.psz_string );
    }
#endif

    p_stream->pf_add    = Add;
    p_stream->pf_del    = Del;
    p_stream->pf_send   = Send;

    p_stream->p_sys->p_mux = p_mux;
    p_stream->p_sys->p_slp = p_slp;

    if( psz_access ) free( psz_access );
    if( psz_mux ) free( psz_mux );
    if( psz_url ) free( psz_url );


    return VLC_SUCCESS;
}