⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 live555.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }    if( p_sys->b_real ) goto error;    if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )        goto error;    if( p_sys->p_out_asf && ParseASF( p_demux ) )    {        msg_Err( p_demux, "cannot find a usable asf header" );        /* TODO Clean tracks */        goto error;    }    if( p_sys->i_track <= 0 )        goto error;    return VLC_SUCCESS;error:    for( i = 0; i < p_sys->i_track; i++ )    {        live_track_t *tk = p_sys->track[i];        if( tk->b_muxed ) stream_DemuxDelete( tk->p_out_muxed );        es_format_Clean( &tk->fmt );        free( tk->p_buffer );        free( tk );    }    if( p_sys->i_track ) free( p_sys->track );    if( p_sys->p_out_asf ) stream_DemuxDelete( p_sys->p_out_asf );    if( p_sys->rtsp && p_sys->ms ) p_sys->rtsp->teardownMediaSession( *p_sys->ms );    if( p_sys->ms ) Medium::close( p_sys->ms );    if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );    if( p_sys->env ) p_sys->env->reclaim();    if( p_sys->p_timeout )    {        vlc_object_kill( p_sys->p_timeout );        vlc_thread_join( p_sys->p_timeout );        vlc_object_detach( p_sys->p_timeout );        vlc_object_release( p_sys->p_timeout );    }    delete p_sys->scheduler;    free( p_sys->p_sdp );    free( p_sys->psz_path );    vlc_UrlClean( &p_sys->url );    free( p_sys );    return i_error;}/***************************************************************************** * DemuxClose: *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys = p_demux->p_sys;    int i;    for( i = 0; i < p_sys->i_track; i++ )    {        live_track_t *tk = p_sys->track[i];        if( tk->b_muxed ) stream_DemuxDelete( tk->p_out_muxed );        es_format_Clean( &tk->fmt );        free( tk->p_buffer );        free( tk );    }    if( p_sys->i_track ) free( p_sys->track );    if( p_sys->p_out_asf ) stream_DemuxDelete( p_sys->p_out_asf );    if( p_sys->rtsp && p_sys->ms ) p_sys->rtsp->teardownMediaSession( *p_sys->ms );    if( p_sys->ms ) Medium::close( p_sys->ms );    if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );    if( p_sys->env ) p_sys->env->reclaim();    if( p_sys->p_timeout )    {        vlc_object_kill( p_sys->p_timeout );        vlc_thread_join( p_sys->p_timeout );        vlc_object_detach( p_sys->p_timeout );        vlc_object_release( p_sys->p_timeout );    }    delete p_sys->scheduler;    free( p_sys->p_sdp );    free( p_sys->psz_path );    vlc_UrlClean( &p_sys->url );    free( p_sys );}/***************************************************************************** * Connect: connects to the RTSP server to setup the session DESCRIBE *****************************************************************************/static int Connect( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    Authenticator authenticator;    bool b_firstpass  = true;    char *psz_user    = NULL;    char *psz_pwd     = NULL;    char *psz_url     = NULL;    char *psz_options = NULL;    char *p_sdp       = NULL;    int  i_http_port  = 0;    int  i_ret        = VLC_SUCCESS;    int i_lefttries;    if( p_sys->url.i_port == 0 ) p_sys->url.i_port = 554;    if( p_sys->url.psz_username || p_sys->url.psz_password )    {        int err;        err = asprintf( &psz_url, "rtsp://%s:%d%s", p_sys->url.psz_host,                        p_sys->url.i_port, p_sys->url.psz_path );        if( err == -1 ) return VLC_ENOMEM;        psz_user = strdup( p_sys->url.psz_username );        psz_pwd  = strdup( p_sys->url.psz_password );    }    else    {        int err;        err = asprintf( &psz_url, "rtsp://%s", p_sys->psz_path );        if( err == -1 ) return VLC_ENOMEM;        psz_user = var_CreateGetString( p_demux, "rtsp-user" );        psz_pwd  = var_CreateGetString( p_demux, "rtsp-pwd" );    }    i_lefttries = 3;createnew:    i_lefttries--;    if( !vlc_object_alive (p_demux) || p_demux->b_error )    {        free( psz_user );        free( psz_pwd );        free( psz_url );        return VLC_EGENERIC;    }    if( var_CreateGetBool( p_demux, "rtsp-http" ) )        i_http_port = var_CreateGetInteger( p_demux, "rtsp-http-port" );    if( ( p_sys->rtsp = RTSPClient::createNew( *p_sys->env,          var_CreateGetInteger( p_demux, "verbose" ) > 1,          "VLC media player", i_http_port ) ) == NULL )    {        msg_Err( p_demux, "RTSPClient::createNew failed (%s)",                 p_sys->env->getResultMsg() );        free( psz_user );        free( psz_pwd );        free( psz_url );        return VLC_EGENERIC;    }    /* Kasenna enables KeepAlive by analysing the User-Agent string.      * Appending _KA to the string should be enough to enable this feature,      * however, there is a bug where the _KA doesn't get parsed from the      * default User-Agent as created by VLC/Live555 code. This is probably due      * to spaces in the string or the string being too long. Here we override     * the default string with a more compact version.     */    if( var_CreateGetBool( p_demux, "rtsp-kasenna" ))    {        p_sys->rtsp->setUserAgentString( "VLC_MEDIA_PLAYER_KA" );    }describe:    authenticator.setUsernameAndPassword( (const char*)psz_user,                                          (const char*)psz_pwd );    psz_options = p_sys->rtsp->sendOptionsCmd( psz_url, psz_user, psz_pwd,                                               &authenticator );    if( psz_options )        p_sys->b_get_param = strstr( psz_options, "GET_PARAMETER" ) ? true : false ;    delete [] psz_options;    p_sdp = p_sys->rtsp->describeURL( psz_url, &authenticator,                         var_GetBool( p_demux, "rtsp-kasenna" ) );    if( p_sdp == NULL )    {        /* failure occurred */        int i_code = 0;        const char *psz_error = p_sys->env->getResultMsg();        if( var_GetBool( p_demux, "rtsp-http" ) )            sscanf( psz_error, "%*s %*s HTTP GET %*s HTTP/%*u.%*u %3u %*s",                    &i_code );        else        {            const char *psz_tmp = strstr( psz_error, "RTSP" );            if( psz_tmp )                sscanf( psz_tmp, "RTSP/%*s%3u", &i_code );            else                i_code = 0;        }        msg_Dbg( p_demux, "DESCRIBE failed with %d: %s", i_code, psz_error );        if( b_firstpass )        {   /* describeURL always returns an "RTSP/1.0 401 Unauthorized" the             * first time. This is a workaround to avoid asking for a             * user/passwd the first time the code passess here. */            i_code = 0;            b_firstpass = false;        }        if( i_code == 401 )        {            int i_result;            msg_Dbg( p_demux, "authentication failed" );            free( psz_user );            free( psz_pwd );            psz_user = psz_pwd = NULL;            i_result = intf_UserLoginPassword( p_demux, _("RTSP authentication"),                           _("Please enter a valid login name and a password."),                                                   &psz_user, &psz_pwd );            if( i_result == DIALOG_OK_YES )            {                msg_Dbg( p_demux, "retrying with user=%s, pwd=%s",                         psz_user, psz_pwd );                goto describe;            }        }        else if( (i_code != 0) && !var_GetBool( p_demux, "rtsp-http" ) )        {            /* Perhaps a firewall is being annoying. Try HTTP tunneling mode */            vlc_value_t val;            val.b_bool = true;            msg_Dbg( p_demux, "we will now try HTTP tunneling mode" );            var_Set( p_demux, "rtsp-http", val );            if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );            p_sys->rtsp = NULL;            goto createnew;        }        else        {            msg_Dbg( p_demux, "connection timeout, retrying" );            if( p_sys->rtsp ) RTSPClient::close( p_sys->rtsp );            p_sys->rtsp = NULL;            if( i_lefttries > 0 )                goto createnew;        }        i_ret = VLC_EGENERIC;    }    /* malloc-ated copy */    free( psz_url );    free( psz_user );    free( psz_pwd );    free( p_sys->p_sdp );    p_sys->p_sdp = NULL;    if( p_sdp ) p_sys->p_sdp = strdup( (char*)p_sdp );    delete[] p_sdp;    return i_ret;}/***************************************************************************** * SessionsSetup: prepares the subsessions and does the SETUP *****************************************************************************/static int SessionsSetup( demux_t *p_demux ){    demux_sys_t             *p_sys  = p_demux->p_sys;    MediaSubsessionIterator *iter   = NULL;    MediaSubsession         *sub    = NULL;    bool           b_rtsp_tcp = false;    int            i_client_port;    int            i_return = VLC_SUCCESS;    unsigned int   i_buffer = 0;    unsigned const thresh = 200000; /* RTP reorder threshold .2 second (default .1) */    b_rtsp_tcp    = var_CreateGetBool( p_demux, "rtsp-tcp" ) ||                    var_GetBool( p_demux, "rtsp-http" );    i_client_port = var_CreateGetInteger( p_demux, "rtp-client-port" );    /* Create the session from the SDP */    if( !( p_sys->ms = MediaSession::createNew( *p_sys->env, p_sys->p_sdp ) ) )    {        msg_Err( p_demux, "Could not create the RTSP Session: %s",            p_sys->env->getResultMsg() );        return VLC_EGENERIC;    }    /* Initialise each media subsession */    iter = new MediaSubsessionIterator( *p_sys->ms );    while( ( sub = iter->next() ) != NULL )    {        Boolean bInit;        live_track_t *tk;        if( !vlc_object_alive (p_demux) || p_demux->b_error )        {            delete iter;            return VLC_EGENERIC;        }        /* Value taken from mplayer */        if( !strcmp( sub->mediumName(), "audio" ) )            i_buffer = 100000;        else if( !strcmp( sub->mediumName(), "video" ) )            i_buffer = 2000000;        else continue;        if( i_client_port != -1 )        {            sub->setClientPortNum( i_client_port );            i_client_port += 2;        }        if( strcasestr( sub->codecName(), "REAL" ) )        {            msg_Info( p_demux, "real codec detected, using real-RTSP instead" );            p_sys->b_real = true; /* This is a problem, we'll handle it later */            continue;        }        if( !strcmp( sub->codecName(), "X-ASF-PF" ) )            bInit = sub->initiate( 4 ); /* Constant ? */        else            bInit = sub->initiate();        if( !bInit )        {            msg_Warn( p_demux, "RTP subsession '%s/%s' failed (%s)",                      sub->mediumName(), sub->codecName(),                      p_sys->env->getResultMsg() );        }        else        {            if( sub->rtpSource() != NULL )            {                int fd = sub->rtpSource()->RTPgs()->socketNum();                /* Increase the buffer size */                if( i_buffer > 0 )                    increaseReceiveBufferTo( *p_sys->env, fd, i_buffer );                /* Increase the RTP reorder timebuffer just a bit */                sub->rtpSource()->setPacketReorderingThresholdTime(thresh);            }            msg_Dbg( p_demux, "RTP subsession '%s/%s'", sub->mediumName(),                     sub->codecName() );            /* Issue the SETUP */            if( p_sys->rtsp )            {                if( !p_sys->rtsp->setupMediaSubsession( *sub, False,                                           b_rtsp_tcp ? True : False,                                           ( p_sys->b_force_mcast && !b_rtsp_tcp ) ? True : False ) )                {                    /* if we get an unsupported transport error, toggle TCP use and try again */                    if( !strstr(p_sys->env->getResultMsg(), "461 Unsupported Transport")                     || !p_sys->rtsp->setupMediaSubsession( *sub, False,                                           b_rtsp_tcp ? False : True,                                           False ) )                    {                        msg_Err( p_demux, "SETUP of'%s/%s' failed %s", sub->mediumName(),                                 sub->codecName(), p_sys->env->getResultMsg() );                        continue;                    }                }            }            /* Check if we will receive data from this subsession for this track */            if( sub->readSource() == NULL ) continue;            if( !p_sys->b_multicast )            {                /* Check, because we need diff. rollover behaviour for multicast */                p_sys->b_multicast = IsMulticastAddress( sub->connectionEndpointAddress() );            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -