Beispiel #1
0
    void initTimes()
    {
        if( demux_Control( p_demux->p_next, DEMUX_GET_TIME, &m_start_time ) != VLC_SUCCESS )
            m_start_time = -1;

        if( demux_Control( p_demux->p_next, DEMUX_GET_POSITION, &m_start_pos ) != VLC_SUCCESS )
            m_start_pos = -1.0f;

        m_last_time = m_start_time;
        m_last_pos = m_start_pos;
    }
Beispiel #2
0
static void* DStreamThread( void *obj )
{
    stream_t *s = (stream_t *)obj;
    stream_sys_t *p_sys = s->p_sys;
    demux_t *p_demux;

    /* Create the demuxer */
    p_demux = demux_New( s, s->p_input, "", p_sys->psz_name, "", s, p_sys->out,
                         false );
    if( p_demux == NULL )
        return NULL;

    /* stream_Demux cannot apply DVB filters.
     * Get all programs and let the E/S output sort them out. */
    demux_Control( p_demux, DEMUX_SET_GROUP, -1, NULL );

    /* Main loop */
    mtime_t next_update = 0;
    while( atomic_load( &p_sys->active ) )
    {
        if( p_demux->info.i_update || mdate() >= next_update )
        {
            double newpos;
            int64_t newlen, newtime;

            if( demux_Control( p_demux, DEMUX_GET_POSITION, &newpos ) )
                newpos = 0.;
            if( demux_Control( p_demux, DEMUX_GET_LENGTH, &newlen ) )
                newlen = 0;
            if( demux_Control( p_demux, DEMUX_GET_TIME, &newtime ) )
                newtime = 0;

            vlc_mutex_lock( &p_sys->lock );
            p_sys->stats.position = newpos;
            p_sys->stats.length = newlen;
            p_sys->stats.time = newtime;
            vlc_mutex_unlock( &p_sys->lock );

            p_demux->info.i_update = 0;
            next_update = mdate() + (CLOCK_FREQ / 4);
        }

        if( demux_Demux( p_demux ) <= 0 )
            break;
    }

    /* Explicit kludge: the stream is destroyed by the owner of the
     * streamDemux, not here. */
    p_demux->s = NULL;
    demux_Delete( p_demux );

    return NULL;
}
Beispiel #3
0
    void seekBack( vlc_tick_t time, double pos )
    {
        es_out_Control( p_demux->p_next->out, ES_OUT_RESET_PCR );

        if( m_can_seek )
        {
            int ret = VLC_EGENERIC;
            if( time >= 0 )
                ret = demux_Control( p_demux->p_next, DEMUX_SET_TIME, time, false );

            if( ret != VLC_SUCCESS && pos >= 0 )
                demux_Control( p_demux->p_next, DEMUX_SET_POSITION, pos, false );
        }
    }
Beispiel #4
0
Datei: var.c Projekt: IAPark/vlc
/*****************************************************************************
 * input_ControlVarStop:
 *****************************************************************************/
void input_ControlVarStop( input_thread_t *p_input )
{
    demux_t* p_demux  = input_priv(p_input)->master->p_demux;
    int i_cur_title;

    if( !input_priv(p_input)->b_preparsing )
        InputDelCallbacks( p_input, p_input_callbacks );

    if( input_priv(p_input)->i_title > 1 )
        InputDelCallbacks( p_input, p_input_title_navigation_callbacks );

    for( int i = 0; i < input_priv(p_input)->i_title; i++ )
    {
        char name[sizeof("title ") + 3 * sizeof (int)];

        sprintf( name, "title %2u", i );
        var_DelCallback( p_input, name, NavigationCallback, (void *)(intptr_t)i );
    }

    if( !demux_Control( p_demux, DEMUX_GET_TITLE, &i_cur_title ) )
    {
        const input_title_t* t = input_priv(p_input)->title[ i_cur_title ];

        if( t->i_seekpoint > 1 )
            InputDelCallbacks( p_input, p_input_seekpoint_navigation_callbacks );
    }
}
Beispiel #5
0
static void *vlc_demux_chained_Thread(void *data)
{
    vlc_demux_chained_t *dc = data;
    demux_t *demux = demux_New(VLC_OBJECT(dc->reader), dc->name, dc->reader,
                               dc->out);
    if (demux == NULL)
    {
        vlc_stream_Delete(dc->reader);
        return NULL;
    }

    /* Stream FIFO cannot apply DVB filters.
     * Get all programs and let the E/S output sort them out. */
    demux_Control(demux, DEMUX_SET_GROUP_ALL);

    /* Main loop */
    vlc_tick_t next_update = 0;

    do
        if (demux_TestAndClearFlags(demux, UINT_MAX) || vlc_tick_now() >= next_update)
        {
            double newpos;
            vlc_tick_t newlen;
            vlc_tick_t newtime;

            if (demux_Control(demux, DEMUX_GET_POSITION, &newpos))
                newpos = 0.;
            if (demux_Control(demux, DEMUX_GET_LENGTH, &newlen))
                newlen = 0;
            if (demux_Control(demux, DEMUX_GET_TIME, &newtime))
                newtime = 0;

            vlc_mutex_lock(&dc->lock);
            dc->stats.position = newpos;
            dc->stats.length = newlen;
            dc->stats.time = newtime;
            vlc_mutex_unlock(&dc->lock);

            next_update = vlc_tick_now() + VLC_TICK_FROM_MS(250);
        }
    while (demux_Demux(demux) > 0);

    demux_Delete(demux);
    return NULL;
}
Beispiel #6
0
    int Control( demux_t *p_demux_filter, int i_query, va_list args )
    {
        if( !m_enabled && i_query != DEMUX_FILTER_ENABLE )
            return demux_vaControl( p_demux_filter->p_next, i_query, args );

        switch (i_query)
        {
        case DEMUX_GET_POSITION:
        {
            double pos = getPosition();
            if( pos >= 0 )
            {
                *va_arg( args, double * ) = pos;
                return VLC_SUCCESS;
            }
            return VLC_EGENERIC;
        }
        case DEMUX_GET_TIME:
        {
            vlc_tick_t time = getTime();
            if( time >= 0 )
            {
                *va_arg(args, vlc_tick_t *) = time;
                return VLC_SUCCESS;
            }
            return VLC_EGENERIC;
        }
        case DEMUX_GET_LENGTH:
        {
            int ret;
            va_list ap;

            va_copy( ap, args );
            ret = demux_vaControl( p_demux_filter->p_next, i_query, args );
            if( ret == VLC_SUCCESS )
                m_length = *va_arg( ap, vlc_tick_t * );
            va_end( ap );
            return ret;
        }

        case DEMUX_CAN_SEEK:
        {
            int ret;
            va_list ap;

            va_copy( ap, args );
            ret = demux_vaControl( p_demux_filter->p_next, i_query, args );
            if( ret == VLC_SUCCESS )
                m_can_seek = *va_arg( ap, bool* );
            va_end( ap );
            return ret;
        }

        case DEMUX_SET_POSITION:
        {
            double pos = va_arg( args, double );
            /* Force unprecise seek */
            int ret = demux_Control( p_demux->p_next, DEMUX_SET_POSITION, pos, false );
            if( ret != VLC_SUCCESS )
                return ret;

            resetTimes();
            resetDemuxEof();
            return VLC_SUCCESS;
        }
        case DEMUX_SET_TIME:
        {
            vlc_tick_t time = va_arg( args, vlc_tick_t );
            /* Force unprecise seek */
            int ret = demux_Control( p_demux->p_next, DEMUX_SET_TIME, time, false );
            if( ret != VLC_SUCCESS )
                return ret;

            resetTimes();
            resetDemuxEof();
            return VLC_SUCCESS;
        }
        case DEMUX_SET_PAUSE_STATE:
        {
            va_list ap;

            va_copy( ap, args );
            int paused = va_arg( ap, int );
            va_end( ap );

            setPauseState( paused != 0 );
            break;
        }
        case DEMUX_SET_ES:
            /* Seek back to the last known pos when changing tracks. This will
             * flush sout streams, make sout del/add called right away and
             * clear CC buffers. */
            seekBack(m_last_time, m_last_pos);
            resetTimes();
            resetDemuxEof();
            break;
        case DEMUX_FILTER_ENABLE:
            p_renderer = static_cast<chromecast_common *>(
                        var_InheritAddress( p_demux, CC_SHARED_VAR_NAME ) );
            assert(p_renderer != NULL);
            m_enabled = true;
            init();
            return VLC_SUCCESS;

        case DEMUX_FILTER_DISABLE:

            deinit();

            /* Seek back to last known position. Indeed we don't want to resume
             * from the input position that can be more than 1 minutes forward
             * (depending on the CC buffering policy). */
            seekBack(m_last_time, m_last_pos);

            m_enabled = false;
            p_renderer = NULL;

            return VLC_SUCCESS;
        }

        return demux_vaControl( p_demux_filter->p_next, i_query, args );
    }
Beispiel #7
0
Datei: ps.c Projekt: mstorsjo/vlc
/*****************************************************************************
 * Control:
 *****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    double f, *pf;
    int64_t i64;
    int i_ret;

    switch( i_query )
    {
        case DEMUX_CAN_SEEK:
            *va_arg( args, bool * ) = p_sys->b_seekable;
            return VLC_SUCCESS;

        case DEMUX_GET_TITLE:
            *va_arg( args, int * ) = p_sys->current_title;
            return VLC_SUCCESS;

        case DEMUX_GET_SEEKPOINT:
            *va_arg( args, int * ) = p_sys->current_seekpoint;
            return VLC_SUCCESS;

        case DEMUX_GET_POSITION:
            pf = va_arg( args, double * );
            i64 = stream_Size( p_demux->s ) - p_sys->i_start_byte;
            if( i64 > 0 )
            {
                double current = vlc_stream_Tell( p_demux->s ) - p_sys->i_start_byte;
                *pf = current / (double)i64;
            }
            else
            {
                *pf = 0.0;
            }
            return VLC_SUCCESS;

        case DEMUX_SET_POSITION:
            f = va_arg( args, double );
            i64 = stream_Size( p_demux->s ) - p_sys->i_start_byte;
            p_sys->i_current_pts = VLC_TICK_INVALID;
            p_sys->i_scr = VLC_TICK_INVALID;

            if( p_sys->format == CDXA_PS )
            {
                i64 = (int64_t)(i64  * f); /* Align to sector payload */
                i64 = p_sys->i_start_byte + i64 - (i64 % CDXA_SECTOR_SIZE) + CDXA_SECTOR_HEADER_SIZE;
            }
            else
            {
                i64 = p_sys->i_start_byte + (int64_t)(i64 * f);
            }

            i_ret = vlc_stream_Seek( p_demux->s, i64 );
            if( i_ret == VLC_SUCCESS )
            {
                NotifyDiscontinuity( p_sys->tk, p_demux->out );
                return i_ret;
            }
            break;

        case DEMUX_GET_TIME:
            if( p_sys->i_time_track_index >= 0 && p_sys->i_current_pts != VLC_TICK_INVALID )
            {
                *va_arg( args, vlc_tick_t * ) = p_sys->i_current_pts - p_sys->tk[p_sys->i_time_track_index].i_first_pts;
                return VLC_SUCCESS;
            }
            if( p_sys->i_first_scr != VLC_TICK_INVALID && p_sys->i_scr != VLC_TICK_INVALID )
            {
                vlc_tick_t i_time = p_sys->i_scr - p_sys->i_first_scr;
                /* H.222 2.5.2.2 */
                if( p_sys->i_mux_rate > 0 && p_sys->b_have_pack )
                {
                    uint64_t i_offset = vlc_stream_Tell( p_demux->s ) - p_sys->i_lastpack_byte;
                    i_time += vlc_tick_from_samples(i_offset, p_sys->i_mux_rate * 50);
                }
                *va_arg( args, vlc_tick_t * ) = i_time;
                return VLC_SUCCESS;
            }
            *va_arg( args, vlc_tick_t * ) = 0;
            break;

        case DEMUX_GET_LENGTH:
            if( p_sys->i_length > VLC_TICK_0 )
            {
                *va_arg( args, vlc_tick_t * ) = p_sys->i_length;
                return VLC_SUCCESS;
            }
            else if( p_sys->i_mux_rate > 0 )
            {
                *va_arg( args, vlc_tick_t * ) = vlc_tick_from_samples( stream_Size( p_demux->s ) - p_sys->i_start_byte / 50,
                    p_sys->i_mux_rate );
                return VLC_SUCCESS;
            }
            *va_arg( args, vlc_tick_t * ) = 0;
            break;

        case DEMUX_SET_TIME:
        {
            if( p_sys->i_time_track_index >= 0 && p_sys->i_current_pts != VLC_TICK_INVALID &&
                p_sys->i_length > VLC_TICK_0)
            {
                vlc_tick_t i_time = va_arg( args, vlc_tick_t );
                i_time -= p_sys->tk[p_sys->i_time_track_index].i_first_pts;
                return demux_Control( p_demux, DEMUX_SET_POSITION, (double) i_time / p_sys->i_length );
            }
            break;
        }

        case DEMUX_GET_TITLE_INFO:
        {
            struct input_title_t ***v = va_arg( args, struct input_title_t*** );
            int *c = va_arg( args, int * );

            *va_arg( args, int* ) = 0; /* Title offset */
            *va_arg( args, int* ) = 0; /* Chapter offset */
            return vlc_stream_Control( p_demux->s, STREAM_GET_TITLE_INFO, v,
                                       c );
        }

        case DEMUX_SET_TITLE:
            return vlc_stream_vaControl( p_demux->s, STREAM_SET_TITLE, args );

        case DEMUX_SET_SEEKPOINT:
            return vlc_stream_vaControl( p_demux->s, STREAM_SET_SEEKPOINT,
                                         args );

        case DEMUX_TEST_AND_CLEAR_FLAGS:
        {
            unsigned *restrict flags = va_arg(args, unsigned *);
            *flags &= p_sys->updates;
            p_sys->updates &= ~*flags;
            return VLC_SUCCESS;
        }

        case DEMUX_GET_META:
            return vlc_stream_vaControl( p_demux->s, STREAM_GET_META, args );

        case DEMUX_GET_FPS:
            break;

        case DEMUX_CAN_PAUSE:
        case DEMUX_SET_PAUSE_STATE:
        case DEMUX_CAN_CONTROL_PACE:
        case DEMUX_GET_PTS_DELAY:
            return demux_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );

        default:
            break;

    }
    return VLC_EGENERIC;
}