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

📄 live555.cpp

📁 VLC Player Source Code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                          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->sub->rtpSource() && tk->sub->rtpSource()->hasBeenSynchronizedUsingRTCP() )        {            msg_Dbg( p_demux, "tk->rtpSource->hasBeenSynchronizedUsingRTCP()" );            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );            tk->b_rtcp_sync = true;            /* reset PCR */            tk->i_pts = 0;            tk->i_npt = 0;            p_sys->i_pcr = 0;            p_sys->i_npt = 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 ) )    {        bool b_rtsp_tcp = var_GetBool( p_demux, "rtsp-tcp" ) ||                                var_GetBool( p_demux, "rtsp-http" );        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;            }            return 1;        }        msg_Err( p_demux, "no data received in 10s, aborting" );        return 0;    }    else if( !p_sys->b_multicast && 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, i64;    double  *pf, f;    bool *pb, *pb2, b_bool;    int *pi_int;    switch( i_query )    {        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_npt > 0 )            {                *pi64 = p_sys->i_npt;                return VLC_SUCCESS;            }            return VLC_EGENERIC;        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_npt_length > 0 )            {                *pi64 = p_sys->i_npt_length;                return VLC_SUCCESS;            }            return VLC_EGENERIC;        case DEMUX_GET_POSITION:            pf = (double*)va_arg( args, double* );            if( p_sys->i_npt_length > 0 && p_sys->i_npt > 0)            {                *pf = ( (double)p_sys->i_npt / (double)p_sys->i_npt_length );                return VLC_SUCCESS;            }            return VLC_EGENERIC;        case DEMUX_SET_POSITION:        case DEMUX_SET_TIME:            if( p_sys->rtsp && p_sys->i_npt_length > 0 )            {                int i;                float time;                if( i_query == DEMUX_SET_TIME && p_sys->i_npt )                {                    i64 = (int64_t)va_arg( args, int64_t );                    time = (float)((double)i64 / (double)1000000.0); /* in second */                }                else if( i_query == DEMUX_SET_TIME )                    return VLC_EGENERIC;                else                {                    f = (double)va_arg( args, double );                    time = f * (double)p_sys->i_npt_length / (double)1000000.0;   /* in second */                }                if( !p_sys->rtsp->playMediaSession( *p_sys->ms, time, -1, 1 ) )                {                    msg_Err( p_demux, "PLAY failed %s",                        p_sys->env->getResultMsg() );                    return VLC_EGENERIC;                }                es_out_Control( p_demux->out, ES_OUT_RESET_PCR );                p_sys->i_pcr = 0;                /* Retrieve RTP-Info values */                for( i = 0; i < p_sys->i_track; i++ )                {                    p_sys->track[i]->b_rtcp_sync = false;                    p_sys->track[i]->i_pts = 0;                }                /* Retrieve the starttime if possible */                p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 );                if( p_sys->i_npt_start < 0 )                    p_sys->i_npt_start = -1;                else p_sys->i_npt = p_sys->i_npt_start;                /* Retrieve the duration if possible */                p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 );                if( p_sys->i_npt_length < 0 )                    p_sys->i_npt_length = -1;                msg_Dbg( p_demux, "seek start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length );                return VLC_SUCCESS;            }            return VLC_EGENERIC;        /* Special for access_demux */        case DEMUX_CAN_PAUSE:        case DEMUX_CAN_SEEK:            pb = (bool*)va_arg( args, bool * );            if( p_sys->rtsp && p_sys->i_npt_length )                /* Not always true, but will be handled in SET_PAUSE_STATE */                *pb = true;            else                *pb = false;            return VLC_SUCCESS;        case DEMUX_CAN_CONTROL_PACE:            pb = (bool*)va_arg( args, bool * );#if 1       /* Disable for now until we have a clock synchro algo             * which works with something else than MPEG over UDP */            *pb = false;#else            *pb = true;#endif            return VLC_SUCCESS;#if 0        case DEMUX_CAN_CONTROL_RATE:            pb = (bool*)va_arg( args, bool * );            pb2 = (bool*)va_arg( args, bool * );            *pb = p_sys->rtsp != NULL && p_sys->i_npt_length > 0 && !var_GetBool( p_demux, "rtsp-kasenna" );            *pb2 = false;            return VLC_SUCCESS;        case DEMUX_SET_RATE:        {            double f_scale;            if( !p_sys->rtsp || p_sys->i_npt_length <= 0 || var_GetBool( p_demux, "rtsp-kasenna" ) )                return VLC_EGENERIC;            /* TODO we might want to ensure that the new rate is different from             * old rate after playMediaSession...             * I have no idea how the server map the requested rate to the             * ones it supports.             * ex:             *  current is x2 we request x1.5 if the server return x2 we will             *  never succeed to return to x1.             *  In this case we should retry with a lower rate until we have             *  one (even x1).             */            pi_int = (int*)va_arg( args, int * );            f_scale = (double)INPUT_RATE_DEFAULT / (*p_int);            /* Passing -1 for the start and end time will mean liveMedia won't            * create a Range: section for the RTSP message. The server should            * pick up from the current position */            if( !p_sys->rtsp->playMediaSession( *p_sys->ms, -1, -1, f_scale ) )            {                msg_Err( p_demux, "PLAY with Scale %0.2f failed %s", f_scale,                        p_sys->env->getResultMsg() );                return VLC_EGENERIC;            }            /* ReSync the stream */            p_sys->i_npt_start = 0;            p_sys->i_pcr = 0;            p_sys->i_npt = 0;            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );            *pi_int = (int)( INPUT_RATE_DEFAULT / p_sys->ms->scale() + 0.5 );            return VLC_SUCCESS;        }#endif        case DEMUX_SET_PAUSE_STATE:        {            int i;            b_bool = (bool)va_arg( args, int );            if( p_sys->rtsp == NULL )                return VLC_EGENERIC;            /* FIXME */            if( ( b_bool && !p_sys->rtsp->pauseMediaSession( *p_sys->ms ) ) ||                    ( !b_bool && !p_sys->rtsp->playMediaSession( *p_sys->ms,                       -1 ) ) )            {                    msg_Err( p_demux, "PLAY or PAUSE failed %s", p_sys->env->getResultMsg() );                    return VLC_EGENERIC;            }            /* When we Pause, we'll need the TimeoutPrevention thread to             * handle sending the "Keep Alive" message to the server.              * Unfortunately Live555 isn't thread safe and so can't              * do this normally while the main Demux thread is handling             * a live stream. We end up with the Timeout thread blocking             * waiting for a response from the server. So when we PAUSE             * we set a flag that the TimeoutPrevention function will check             * and if it's set, it will trigger the GET_PARAMETER message */            if( b_bool && p_sys->p_timeout != NULL )                p_sys->p_timeout->b_handle_keep_alive = true;            else if( !b_bool && p_sys->p_timeout != NULL )                 p_sys->p_timeout->b_handle_keep_alive = false;            for( i = 0; !b_bool && i < p_sys->i_track; i++ )            {                live_track_t *tk = p_sys->track[i];                tk->b_rtcp_sync = false;                tk->i_pts = 0;                p_sys->i_pcr = 0;                es_out_Control( p_demux->out, ES_OUT_RESET_PCR );            }            /* Retrieve the starttime if possible */            p_sys->i_npt_start = (int64_t)( p_sys->ms->playStartTime() * (double)1000000.0 );            if( p_sys->i_npt_start < 0 )                p_sys->i_npt_start = -1;            else p_sys->i_npt = p_sys->i_npt_start;            /* Retrieve the duration if possible */            p_sys->i_npt_length = (int64_t)( p_sys->ms->playEndTime() * (double)1000000.0 );            if( p_sys->i_npt_length < 0 )                p_sys->i_npt_length = -1;            msg_Dbg( p_demux, "pause start: %lld stop:%lld", p_sys->i_npt_start, p_sys->i_npt_length );            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() * This should REALLY be fixed *****************************************************************************/static int RollOverTcp( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    int i, i_return;    var_SetBool( p_demux, "rtsp-tcp", true );    /* We close the old RTSP session */    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 );        if( tk->p_es ) es_out_Del( p_demux->out, tk->p_es );        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 );    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;    p_sys->track = NULL;    p_sys->i_track = 0;    /* 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;    }    if( ( i_return = SessionsSetup( p_demux ) ) != VLC_SUCCESS )    {        msg_Err( p_demux, "Nothing to play for rtsp://%s", p_sys->psz_path );        goto error;    }    if( ( i_return = Play( p_demux ) ) != VLC_SUCCESS )        goto error;    return VLC_SUCCESS;error:    return VLC_EGENERIC;}/***************************************************************************** * *****************************************************************************/static void StreamRead( void *p_private, unsigned int i_size,                        unsigned int i_truncated_bytes, struct timeval pts,                        unsigned int duration ){    live_track_t   *tk = (live_track_t*)p_private;    demux_t        *p_demux = tk->p_demux;    demux_sys_t    *p_sys = p_demux->p_sys;    block_t        *p_block;

⌨️ 快捷键说明

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