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

📄 live555.cpp

📁 uclinux 下的vlc播放器源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                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 ) ) )                {                    msg_Err( p_demux, "SETUP of'%s/%s' failed %s", sub->mediumName(),                             sub->codecName(), p_sys->env->getResultMsg() );                }                else i_active_sessions++;            } else i_active_sessions++; /* we don't really know, let's just hope it's there */            if( !p_sys->b_multicast )            {                /* Check, because we need diff. rollover behaviour for multicast */                p_sys->b_multicast = IsMulticastAddress( sub->connectionEndpointAddress() );            }        }    }    delete iter;    if( i_active_sessions <= 0 ) i_return = VLC_EGENERIC;    return i_return;}/***************************************************************************** * Play: starts the actual playback of the stream *****************************************************************************/static int Play( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    if( p_sys->rtsp )    {        /* The PLAY */        if( !p_sys->rtsp->playMediaSession( *p_sys->ms ) )        {            msg_Err( p_demux, "RTSP PLAY failed %s", p_sys->env->getResultMsg() );            return VLC_EGENERIC;        }        /* Retrieve the timeout value and set up a timeout prevention thread */#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1138089600        p_sys->i_timeout = p_sys->rtsp->sessionTimeoutParameter();#endif        if( p_sys->i_timeout > 0 && !p_sys->p_timeout )        {            msg_Dbg( p_demux, "We have a timeout of %d seconds",  p_sys->i_timeout );            p_sys->p_timeout = (timeout_thread_t *)vlc_object_create( p_demux, sizeof(timeout_thread_t) );            p_sys->p_timeout->p_sys = p_demux->p_sys; /* lol, object recursion :D */            if( vlc_thread_create( p_sys->p_timeout, "liveMedia-timeout", TimeoutPrevention,                                   VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )            {                msg_Err( p_demux, "cannot spawn liveMedia timeout thread" );                vlc_object_destroy( p_sys->p_timeout );            }            msg_Dbg( p_demux, "spawned timeout thread" );            vlc_object_attach( p_sys->p_timeout, p_demux );        }    }    return VLC_SUCCESS;}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t    *p_sys = p_demux->p_sys;    TaskToken      task;    vlc_bool_t      b_send_pcr = VLC_TRUE;    int64_t         i_pcr = 0;    int             i;    /* Check if we need to send the server a Keep-A-Live signal */    if( p_sys->b_timeout_call && p_sys->rtsp && p_sys->ms )    {#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1138089600        char *psz_bye = NULL;        p_sys->rtsp->getMediaSessionParameter( *p_sys->ms, NULL, psz_bye );#endif        p_sys->b_timeout_call = VLC_FALSE;    }    for( i = 0; i < p_sys->i_track; i++ )    {        live_track_t *tk = p_sys->track[i];        if( tk->b_asf || tk->b_muxed )            b_send_pcr = VLC_FALSE;        if( i_pcr == 0 )        {            i_pcr = tk->i_pts;        }        else if( tk->i_pts != 0 && i_pcr > tk->i_pts )        {            i_pcr = tk->i_pts ;        }    }    if( i_pcr != p_sys->i_pcr && i_pcr > 0 )    {        p_sys->i_pcr = i_pcr;        if( b_send_pcr )            es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_pcr );        if( p_sys->i_pcr_start <= 0 || p_sys->i_pcr_start > i_pcr ||            ( p_sys->i_length > 0 && i_pcr - p_sys->i_pcr_start > p_sys->i_length ) )        {            p_sys->i_pcr_start = i_pcr;        }    }#if 0    /* Disabled because it's simply not reliable enough */    /* When a On Demand QT stream ends, the last frame keeps going with the same PCR/PTS value */    /* This tests for that, so we can later decide to end this session */    if( i_pcr > 0 && p_sys->i_pcr == p_sys->i_pcr_previous )    {        if( p_sys->i_pcr_repeats == 0 )            p_sys->i_pcr_repeatdate = mdate();        p_sys->i_pcr_repeats++;    }    else    {        p_sys->i_pcr_previous = p_sys->i_pcr;        p_sys->i_pcr_repeatdate = 0;        p_sys->i_pcr_repeats = 0;    }    if( p_sys->i_pcr_repeats > 5 && mdate() > p_sys->i_pcr_repeatdate + 1000000 )    {        /* We need at least 5 repeats over at least a second of time before we EOF */        msg_Dbg( p_demux, "suspect EOF due to end of VoD session" );        return 0;    }#endif    /* First warn we want to read data */    p_sys->event = 0;    for( i = 0; i < p_sys->i_track; i++ )    {        live_track_t *tk = p_sys->track[i];        if( tk->waiting == 0 )        {            tk->waiting = 1;            tk->readSource->getNextFrame( tk->p_buffer, tk->i_buffer,                                          StreamRead, tk, StreamClose, tk );        }    }    /* Create a task that will be called if we wait more than 300ms */    task = p_sys->scheduler->scheduleDelayedTask( 300000, TaskInterrupt, p_demux );    /* Do the read */    p_sys->scheduler->doEventLoop( &p_sys->event );    /* remove the task */    p_sys->scheduler->unscheduleDelayedTask( task );    /* Check for gap in pts value */    for( i = 0; i < p_sys->i_track; i++ )    {        live_track_t *tk = p_sys->track[i];        if( !tk->b_muxed && !tk->b_rtcp_sync &&            tk->rtpSource && tk->rtpSource->hasBeenSynchronizedUsingRTCP() )        {            msg_Dbg( p_demux, "tk->rtpSource->hasBeenSynchronizedUsingRTCP()" );            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );            tk->b_rtcp_sync = VLC_TRUE;            /* reset PCR and PCR start, mmh won't work well for multi-stream I fear */            tk->i_pts = 0;            p_sys->i_pcr_start = 0;            p_sys->i_pcr = 0;            i_pcr = 0;        }    }    if( p_sys->b_multicast && p_sys->b_no_data && p_sys->i_no_data_ti > 120 )    {        /* FIXME Make this configurable        msg_Err( p_demux, "no multicast data received in 36s, aborting" );        return 0;        */    }    else if( !p_sys->b_multicast && p_sys->b_no_data && p_sys->i_no_data_ti > 34 )    {        vlc_bool_t b_rtsp_tcp = var_GetBool( p_demux, "rtsp-tcp" );        if( !b_rtsp_tcp && p_sys->rtsp && p_sys->ms )        {            msg_Warn( p_demux, "no data received in 10s. Switching to TCP" );            if( RollOverTcp( p_demux ) )            {                msg_Err( p_demux, "TCP rollover failed, aborting" );                return 0;            }        }        else if( p_sys->i_no_data_ti > 34 )        {            msg_Err( p_demux, "no data received in 10s, aborting" );            return 0;        }    }    else if( !p_sys->b_multicast && p_sys->b_no_data && p_sys->i_no_data_ti > 34 )    {        /* EOF ? */        msg_Warn( p_demux, "no data received in 10s, eof ?" );        return 0;    }    return p_demux->b_error ? 0 : 1;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys = p_demux->p_sys;    int64_t *pi64;    double  *pf, f;    vlc_bool_t *pb, b_bool;    switch( i_query )    {        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = p_sys->i_pcr - p_sys->i_pcr_start + p_sys->i_start;            return VLC_SUCCESS;        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = p_sys->i_length;            return VLC_SUCCESS;        case DEMUX_GET_POSITION:            pf = (double*)va_arg( args, double* );            if( p_sys->i_length > 0 )            {                *pf = (double)( p_sys->i_pcr - p_sys->i_pcr_start +                                p_sys->i_start ) / (double)(p_sys->i_length);            }            else            {                *pf = 0.0;            }            return VLC_SUCCESS;        case DEMUX_SET_POSITION:            float time;            f = (double)va_arg( args, double );            if( p_sys->rtsp && p_sys->i_length > 0 )            {                time = f * (double)p_sys->i_length / 1000000.0;   /* in second */                if( !p_sys->rtsp->playMediaSession( *p_sys->ms, time ) )                {                    msg_Err( p_demux, "PLAY failed %s",                        p_sys->env->getResultMsg() );                    return VLC_EGENERIC;                }                p_sys->i_start = (int64_t)(f * (double)p_sys->i_length);                p_sys->i_pcr_start = 0;                p_sys->i_pcr       = 0;                return VLC_SUCCESS;            }            return VLC_SUCCESS;        /* Special for access_demux */        case DEMUX_CAN_PAUSE:            pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );            if( p_sys->rtsp && p_sys->i_length )                /* Not always true, but will be handled in SET_PAUSE_STATE */                *pb = VLC_TRUE;            else                *pb = VLC_FALSE;            return VLC_SUCCESS;        case DEMUX_CAN_CONTROL_PACE:            pb = (vlc_bool_t*)va_arg( args, vlc_bool_t * );#if 0       /* Disable for now until we have a clock synchro algo             * which works with something else than MPEG over UDP */            *pb = VLC_FALSE;#else            *pb = VLC_TRUE;#endif            return VLC_SUCCESS;        case DEMUX_SET_PAUSE_STATE:            double d_npt;            d_npt = ( (double)( p_sys->i_pcr - p_sys->i_pcr_start +                                p_sys->i_start ) ) / 1000000.00;            b_bool = (vlc_bool_t)va_arg( args, vlc_bool_t );            if( p_sys->rtsp == NULL )                return VLC_EGENERIC;            if( ( b_bool && !p_sys->rtsp->pauseMediaSession( *p_sys->ms ) ) ||                    ( !b_bool && !p_sys->rtsp->playMediaSession( *p_sys->ms,                      d_npt > 0 ? d_npt : -1 ) ) )            {                    msg_Err( p_demux, "PLAY or PAUSE failed %s", p_sys->env->getResultMsg() );                    return VLC_EGENERIC;            }#if 0            /* reset PCR and PCR start, mmh won't work well for multi-stream I fear */            for( i = 0; i < p_sys->i_track; i++ )            {                p_sys->track[i]->i_pts = 0;            }            p_sys->i_pcr_start = 0; /* FIXME Wrong */            p_sys->i_pcr = 0;#endif            return VLC_SUCCESS;        case DEMUX_GET_TITLE_INFO:        case DEMUX_SET_TITLE:        case DEMUX_SET_SEEKPOINT:            return VLC_EGENERIC;        case DEMUX_GET_PTS_DELAY:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = (int64_t)var_GetInteger( p_demux, "rtsp-caching" ) * 1000;            return VLC_SUCCESS;        default:            return VLC_EGENERIC;    }}/***************************************************************************** * RollOverTcp: reopen the rtsp into TCP mode * XXX: ugly, a lot of code are duplicated from Open() *****************************************************************************/static int RollOverTcp( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    MediaSubsessionIterator *iter = 0;    MediaSubsession *sub;    int i_tk;    int i_return;    var_SetBool( p_demux, "rtsp-tcp", VLC_TRUE );    /* We close the old RTSP session */    p_sys->rtsp->teardownMediaSession( *p_sys->ms );    Medium::close( p_sys->ms );    RTSPClient::close( p_sys->rtsp );    p_sys->ms = NULL;    p_sys->rtsp = NULL;    /* Reopen rtsp client */    if( ( i_return = Connect( p_demux ) ) != VLC_SUCCESS )    {        msg_Err( p_demux, "Failed to connect with rtsp://%s", p_sys->psz_path );        goto error;    }    if( p_sys->p_sdp == NULL )    {        msg_Err( p_demux, "Failed to retrieve the RTSP Session Description" );        goto error;    }    /* 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() );        goto error;    }    if( ( i_return = SessionsSetup( p_demux ) ) != VLC_SUCCESS )    {        msg_Err( p_demux, "Nothing to play for rtsp://%s", p_sys->psz_path );        goto error;    }    /* Retrieve the duration if possible */    p_sys->i_length = (int64_t)( p_sys->ms->playEndTime() * 1000000.0 );    if( p_sys->i_length < 0 )        p_sys->i_length = -1;    if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )        goto error;    /* Update all tracks */    iter = new MediaSubsessionIterator( *p_sys->ms );    i_tk = 0;    while( ( sub = iter->next() ) != NULL )    {        live_track_t *tk;        if( sub->readSource() == NULL )            continue;        if( i_tk >= p_sys->i_track )

⌨️ 快捷键说明

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