예제 #1
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;
}
예제 #2
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;
}
예제 #3
0
    int Demux()
    {
        if ( !m_enabled )
            return demux_Demux( p_demux->p_next );

        /* The CC sout is not pacing, so we pace here */
        int pace = p_renderer->pf_pace( p_renderer->p_opaque );
        switch (pace)
        {
            case CC_PACE_ERR:
                return VLC_DEMUXER_EGENERIC;
            case CC_PACE_ERR_RETRY:
            {
                /* Seek back to started position */
                seekBack(m_start_time, m_start_pos);

                resetDemuxEof();
                p_renderer->pf_send_input_event( p_renderer->p_opaque,
                                                 CC_INPUT_EVENT_RETRY,
                                                 cc_input_arg{false} );
                break;
            }
            case CC_PACE_OK_WAIT:
                /* Yeld: return to let the input thread doing controls  */
                return VLC_DEMUXER_SUCCESS;
            case CC_PACE_OK:
            case CC_PACE_OK_ENDED:
                break;
            default:
                vlc_assert_unreachable();
        }

        int ret = VLC_DEMUXER_SUCCESS;
        if( !m_demux_eof )
        {
            ret = demux_Demux( p_demux->p_next );
            if( ret != VLC_DEMUXER_EGENERIC
             && ( m_start_time < 0 || m_start_pos < 0.0f ) )
                initTimes();
            if( ret == VLC_DEMUXER_EOF )
                m_demux_eof = true;
        }

        if( m_demux_eof )
        {
            /* Signal EOF to the sout when the es_out is empty (so when the
             * DecoderThread fifo are empty) */
            bool b_empty;
            es_out_Control( p_demux->p_next->out, ES_OUT_GET_EMPTY, &b_empty );
            if( b_empty )
                p_renderer->pf_send_input_event( p_renderer->p_opaque,
                                                 CC_INPUT_EVENT_EOF,
                                                 cc_input_arg{ true } );

            /* Don't return EOF until the chromecast is not EOF. This allows
             * this demux filter to have more controls over the sout. Indeed,
             * we still can seek or change tracks when the input is EOF and we
             * should continue to handle CC errors. */
            ret = pace == CC_PACE_OK ? VLC_DEMUXER_SUCCESS : VLC_DEMUXER_EOF;
        }

        return ret;
    }