Example #1
0
File: ps.c Project: mstorsjo/vlc
static bool FindLength( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    int64_t i_current_pos = -1, i_size = 0, i_end = 0;

    if( !var_CreateGetBool( p_demux, "ps-trust-timestamps" ) )
        return true;

    if( p_sys->i_length == VLC_TICK_INVALID ) /* First time */
    {
        p_sys->i_length = VLC_TICK_0;
        /* Check beginning */
        int i = 0;
        i_current_pos = vlc_stream_Tell( p_demux->s );
        while( i < 40 && Probe( p_demux, false ) > 0 ) i++;

        /* Check end */
        i_size = stream_Size( p_demux->s );
        i_end = VLC_CLIP( i_size, 0, 200000 );
        if( vlc_stream_Seek( p_demux->s, i_size - i_end ) == VLC_SUCCESS )
        {
            i = 0;
            while( i < 400 && Probe( p_demux, true ) > 0 ) i++;
            if( i_current_pos >= 0 &&
                vlc_stream_Seek( p_demux->s, i_current_pos ) != VLC_SUCCESS )
                    return false;
        }
        else return false;
    }

    /* Find the longest track */
    for( int i = 0; i < PS_TK_COUNT; i++ )
    {
        ps_track_t *tk = &p_sys->tk[i];
        if( tk->i_first_pts != VLC_TICK_INVALID &&
            tk->i_last_pts > tk->i_first_pts )
        {
            vlc_tick_t i_length = tk->i_last_pts - tk->i_first_pts;
            if( i_length > p_sys->i_length )
            {
                p_sys->i_length = i_length;
                p_sys->i_time_track_index = i;
                msg_Dbg( p_demux, "we found a length of: %"PRId64 "s", SEC_FROM_VLC_TICK(p_sys->i_length) );
            }
        }
    }
    return true;
}
Example #2
0
File: access.c Project: etix/vlc
static ssize_t SeekCallback(struct archive *p_archive, void *p_object, ssize_t i_offset, int i_whence)
{
    VLC_UNUSED(p_archive);
    callback_data_t *p_data = (callback_data_t *) p_object;
    access_sys_t *p_sys = p_data->p_access->p_sys;

    ssize_t i_pos;

    switch(i_whence)
    {
    case SEEK_CUR:
        i_pos = vlc_stream_Tell(p_sys->p_stream);
        break;
    case SEEK_SET:
        i_pos = 0;
        break;
    case SEEK_END:
        i_pos = stream_Size(p_sys->p_stream) - 1;
        break;
    default:
        return -1;
    }

    if (i_pos < 0)
        return -1;

    vlc_stream_Seek(p_sys->p_stream, i_pos + i_offset); /* We don't care about return val */
    return vlc_stream_Tell(p_sys->p_stream);
}
Example #3
0
static int Seek(access_t *access, uint64_t position)
{
    access_sys_t *sys = access->p_sys;
    const rar_file_t *file = sys->file;

    if (position > file->real_size)
        position = file->real_size;
    sys->position = position;

    /* Search the chunk */
    const rar_file_chunk_t *old_chunk = sys->chunk;
    for (int i = 0; i < file->chunk_count; i++) {
        sys->chunk = file->chunk[i];
        if (position < sys->chunk->cummulated_size + sys->chunk->size)
            break;
    }

    const uint64_t offset = sys->chunk->offset +
                            (position - sys->chunk->cummulated_size);

    if (strcmp(old_chunk->mrl, sys->chunk->mrl)) {
        if (sys->s)
            vlc_stream_Delete(sys->s);
        sys->s = vlc_stream_NewMRL(access, sys->chunk->mrl);
    }
    return sys->s ? vlc_stream_Seek(sys->s, offset) : VLC_EGENERIC;
}
Example #4
0
static int Seek( stream_t *s, uint64_t offset )
{
    stream_sys_t *p_sys = s->p_sys;

    assert( p_sys->b_seek );
    return vlc_stream_Seek( s->p_source, offset );
}
Example #5
0
static int Seek( stream_t *p_stream, uint64_t i_pos )
{
    int i_ret = vlc_stream_Seek( p_stream->s, i_pos );
    if ( i_ret == VLC_SUCCESS )
        RemainFlush( p_stream->p_sys );
    return i_ret;
}
Example #6
0
File: access.c Project: etix/vlc
static ssize_t SkipCallback(struct archive *p_archive, void *p_object, ssize_t i_request)
{
    VLC_UNUSED(p_archive);
    callback_data_t *p_data = (callback_data_t *) p_object;
    access_sys_t *p_sys = p_data->p_access->p_sys;
    ssize_t i_skipped = 0;

    /* be smart as small seeks converts to reads */
    if (p_sys->b_source_canseek)
    {
        int64_t i_pos = vlc_stream_Tell(p_sys->p_stream);
        if (i_pos >=0)
            vlc_stream_Seek(p_sys->p_stream, i_pos + i_request);
        i_skipped = vlc_stream_Tell(p_sys->p_stream) - i_pos;
    }
    else while(i_request)
    {
        int i_skip = __MIN(INT32_MAX, i_request);
        int i_read = vlc_stream_Read(p_sys->p_stream, NULL, i_skip);
        if (i_read > 0)
            i_skipped += i_read;
        else
            break;
        i_request -= i_read;
    }

    return i_skipped;
}
Example #7
0
File: cdg.c Project: 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;
    uint64_t i_old_offset = vlc_stream_Tell( p_demux->s );
    int i_ret = demux_vaControlHelper( p_demux->s, 0, -1,
                                       8*CDG_FRAME_SIZE*CDG_FRAME_RATE, CDG_FRAME_SIZE,
                                       i_query, args );
    if( !i_ret && ( i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME ) )
    {
        date_Set( &p_sys->pts, PosToDate( p_demux ) );
        if ( i_old_offset > vlc_stream_Tell( p_demux->s ) )
            i_ret = vlc_stream_Seek( p_demux->s, 0 );
        else
            i_ret = vlc_stream_Seek( p_demux->s, i_old_offset );
    }

    return i_ret;
}
Example #8
0
/** **************************************************************************
 * \brief seek in the stream
 * \param opaque should be the stream
 * \param stream stream created by ZipIO_Open
 * \param offset positive offset to seek
 * \param origin current position in stream
 * \return ¿ VLC_SUCCESS or an error code ?
 *****************************************************************************/
static long ZCALLBACK ZipIO_Seek ( void *opaque, void *stream,
                                   unsigned long offset, int origin )
{
    (void) stream;
    stream_t *s = (stream_t*) opaque;
    long l_ret;

    uint64_t pos = offset + origin;
    l_ret = (long) vlc_stream_Seek( s->p_source, pos );
    return l_ret;
}
Example #9
0
File: m3u.c Project: etix/vlc
/*****************************************************************************
 * Import_M3U: main import function
 *****************************************************************************/
int Import_M3U( vlc_object_t *p_this )
{
    demux_t *p_demux = (demux_t *)p_this;
    const uint8_t *p_peek;
    char *(*pf_dup) (const char *) = GuessEncoding;
    int offset = 0;

    CHECK_FILE();
    if( vlc_stream_Peek( p_demux->s, &p_peek, 3 ) == 3
     && !memcmp( p_peek, "\xef\xbb\xbf", 3) )
    {
        pf_dup = CheckUnicode; /* UTF-8 Byte Order Mark */
        offset = 3;
    }

    if( demux_IsPathExtension( p_demux, ".m3u8" )
     || demux_IsForced( p_demux, "m3u8" )
     || CheckContentType( p_demux->s, "application/vnd.apple.mpegurl" ) )
        pf_dup = CheckUnicode; /* UTF-8 file type */
    else
    if( demux_IsPathExtension( p_demux, ".m3u" )
     || demux_IsPathExtension( p_demux, ".vlc" )
     || demux_IsForced( p_demux, "m3u" )
     || ContainsURL( p_demux )
     || CheckContentType( p_demux->s, "audio/x-mpegurl") )
        ; /* Guess encoding */
    else
    {
        if( vlc_stream_Peek( p_demux->s, &p_peek, 8 + offset ) < (8 + offset) )
            return VLC_EGENERIC;

        p_peek += offset;

        if( !strncasecmp( (const char *)p_peek, "RTSPtext", 8 ) ) /* QuickTime */
            pf_dup = CheckUnicode; /* UTF-8 */
        else
        if( !memcmp( p_peek, "#EXTM3U", 7 ) )
            ; /* Guess encoding */
        else
            return VLC_EGENERIC;
    }

    vlc_stream_Seek( p_demux->s, offset );

    STANDARD_DEMUX_INIT_MSG( "found valid M3U playlist" );
    p_demux->p_sys->psz_prefix = FindPrefix( p_demux );
    p_demux->p_sys->pf_dup = pf_dup;

    return VLC_SUCCESS;
}
Example #10
0
File: demux.c Project: mstorsjo/vlc
static int64_t IOSeek( void *opaque, int64_t offset, int whence )
{
    demux_t *p_demux = opaque;
    int64_t i_absolute;
    int64_t i_size = stream_Size( p_demux->s );

#ifdef AVFORMAT_DEBUG
    msg_Warn( p_demux, "IOSeek offset: %"PRId64", whence: %i", offset, whence );
#endif

    switch( whence )
    {
#ifdef AVSEEK_SIZE
        case AVSEEK_SIZE:
            return i_size;
#endif
        case SEEK_SET:
            i_absolute = (int64_t)offset;
            break;
        case SEEK_CUR:
            i_absolute = vlc_stream_Tell( p_demux->s ) + (int64_t)offset;
            break;
        case SEEK_END:
            i_absolute = i_size + (int64_t)offset;
            break;
        default:
            return -1;

    }

    if( i_absolute < 0 )
    {
        msg_Dbg( p_demux, "Trying to seek before the beginning" );
        return -1;
    }

    if( i_size > 0 && i_absolute >= i_size )
    {
        msg_Dbg( p_demux, "Trying to seek too far : EOF?" );
        return -1;
    }

    if( vlc_stream_Seek( p_demux->s, i_absolute ) )
    {
        msg_Warn( p_demux, "we were not allowed to seek, or EOF " );
        return -1;
    }

    return vlc_stream_Tell( p_demux->s );
}
Example #11
0
/* Allow to append indexes after starting playback */
int AVI_ChunkFetchIndexes( stream_t *s, avi_chunk_t *p_riff )
{
    avi_chunk_t *p_movi = AVI_ChunkFind( p_riff, AVIFOURCC_movi, 0 );
    if ( !p_movi )
        return VLC_EGENERIC;

    avi_chunk_t *p_chk;
    uint64_t i_indexpos = 8 + p_movi->common.i_chunk_pos + p_movi->common.i_chunk_size;
    bool b_seekable = false;
    int i_ret = VLC_SUCCESS;

    vlc_stream_Control( s, STREAM_CAN_SEEK, &b_seekable );
    if ( !b_seekable || vlc_stream_Seek( s, i_indexpos ) )
        return VLC_EGENERIC;

    for( ; ; )
    {
        p_chk = xmalloc( sizeof( avi_chunk_t ) );
        memset( p_chk, 0, sizeof( avi_chunk_t ) );
        if (unlikely( !p_riff->common.p_first ))
            p_riff->common.p_first = p_chk;
        else
            p_riff->common.p_last->common.p_next = p_chk;
        p_riff->common.p_last = p_chk;

        i_ret = AVI_ChunkRead( s, p_chk, p_riff );
        if( i_ret )
            break;

        if( p_chk->common.p_father->common.i_chunk_size > 0 &&
           ( vlc_stream_Tell( s ) >
              (off_t)p_chk->common.p_father->common.i_chunk_pos +
               (off_t)__EVEN( p_chk->common.p_father->common.i_chunk_size ) ) )
        {
            break;
        }

        /* If we can't seek then stop when we 've found any index */
        if( p_chk->common.i_chunk_fourcc == AVIFOURCC_indx ||
            p_chk->common.i_chunk_fourcc == AVIFOURCC_idx1 )
        {
            break;
        }

    }

    return i_ret;
}
Example #12
0
static int archive_extractor_reset( stream_extractor_t* p_extractor )
{
    private_sys_t* p_sys = p_extractor->p_sys;

    if( vlc_stream_Seek( p_extractor->source, 0 )
        || archive_clean( p_sys )
        || archive_init( p_sys, p_extractor->source )
        || archive_seek_subentry( p_sys, p_extractor->identifier ) )
    {
        p_sys->b_dead = true;
        return VLC_EGENERIC;
    }

    p_sys->i_offset = 0;
    p_sys->b_eof = false;
    p_sys->b_dead = false;
    return VLC_SUCCESS;
}
Example #13
0
static int libarchive_exit_cb( libarchive_t* p_arc, void* p_obj )
{
    VLC_UNUSED( p_arc );

    libarchive_callback_t* p_cb = (libarchive_callback_t*)p_obj;

    if( p_cb->p_sys->source == p_cb->p_source )
    {  /* DO NOT CLOSE OUR MOTHER STREAM */
        if( !p_cb->p_sys->b_dead && vlc_stream_Seek( p_cb->p_source, 0 ) )
            return ARCHIVE_FATAL;
    }
    else if( p_cb->p_source )
    {
        vlc_stream_Delete( p_cb->p_source );
        p_cb->p_source = NULL;
    }

    return ARCHIVE_OK;
}
Example #14
0
static int AVI_NextChunk( stream_t *s, avi_chunk_t *p_chk )
{
    avi_chunk_t chk;

    if( !p_chk )
    {
        if( AVI_ChunkReadCommon( s, &chk ) )
        {
            return VLC_EGENERIC;
        }
        p_chk = &chk;
    }

    if( p_chk->common.p_father )
    {
        if( p_chk->common.p_father->common.i_chunk_pos +
                __EVEN( p_chk->common.p_father->common.i_chunk_size ) + 8 <
            p_chk->common.i_chunk_pos +
                __EVEN( p_chk->common.i_chunk_size ) + 8 )
        {
            return VLC_EGENERIC;
        }
    }

    bool b_seekable = false;
    uint64_t i_offset = p_chk->common.i_chunk_pos +
                        __EVEN( p_chk->common.i_chunk_size ) + 8;
    if ( !vlc_stream_Control(s, STREAM_CAN_SEEK, &b_seekable) && b_seekable )
    {
        return vlc_stream_Seek( s, i_offset );
    }
    else
    {
        ssize_t i_read = i_offset - vlc_stream_Tell( s );
        return (i_read >=0 && vlc_stream_Read( s, NULL, i_read ) == i_read) ?
                    VLC_SUCCESS : VLC_EGENERIC;
    }
}
Example #15
0
File: stl.c Project: BossKing/vlc
static int Control(demux_t *demux, int query, va_list args)
{
    demux_sys_t *sys = demux->p_sys;
    switch(query) {
    case DEMUX_CAN_SEEK:
        return vlc_stream_vaControl(demux->s, query, args);
    case DEMUX_GET_LENGTH: {
        int64_t *l = va_arg(args, int64_t *);
        *l = sys->count > 0 ? sys->index[sys->count-1].stop : 0;
        return VLC_SUCCESS;
    }
    case DEMUX_GET_TIME: {
        int64_t *t = va_arg(args, int64_t *);
        *t = sys->current < sys->count ? sys->index[sys->count-1].start : 0;
        return VLC_SUCCESS;
    }
    case DEMUX_SET_NEXT_DEMUX_TIME: {
        sys->next_date = va_arg(args, int64_t);
        return VLC_SUCCESS;
    }
    case DEMUX_SET_TIME: {
        int64_t t = va_arg(args, int64_t);
        sys->current = 0;
        while (sys->current < sys->count) {
            if (sys->index[sys->current].stop > t) {
                vlc_stream_Seek(demux->s, 1024 + 128LL * sys->index[sys->current].index);
                break;
            }
            sys->current++;
        }
        return VLC_SUCCESS;
    }
    case DEMUX_SET_POSITION:
    case DEMUX_GET_POSITION:
    default:
        return VLC_EGENERIC;
    }
}
Example #16
0
static la_int64_t libarchive_skip_cb( libarchive_t* p_arc, void* p_obj,
  off_t i_request )
{
    VLC_UNUSED( p_arc );

    libarchive_callback_t* p_cb = (libarchive_callback_t*)p_obj;

    stream_t*  p_source = p_cb->p_source;
    private_sys_t* p_sys = p_cb->p_sys;

    /* TODO: fix b_seekable_source on libarchive_callback_t */

    if( p_sys->b_seekable_source )
    {
        if( vlc_stream_Seek( p_source, vlc_stream_Tell( p_source ) + i_request ) )
            return ARCHIVE_FATAL;

        return i_request;
    }

    ssize_t i_read = vlc_stream_Read( p_source, NULL, i_request );
    return  i_read >= 0 ? i_read : ARCHIVE_FATAL;
}
Example #17
0
static la_int64_t libarchive_seek_cb( libarchive_t* p_arc, void* p_obj,
  la_int64_t offset, int whence )
{
    VLC_UNUSED( p_arc );

    libarchive_callback_t* p_cb = (libarchive_callback_t*)p_obj;
    stream_t* p_source = p_cb->p_source;

    ssize_t whence_pos;

    switch( whence )
    {
        case SEEK_SET: whence_pos = 0;                           break;
        case SEEK_CUR: whence_pos = vlc_stream_Tell( p_source ); break;
        case SEEK_END: whence_pos = stream_Size( p_source ); break;
              default: vlc_assert_unreachable();

    }

    if( whence_pos < 0 || vlc_stream_Seek( p_source, whence_pos + offset ) )
        return ARCHIVE_FATAL;

    return vlc_stream_Tell( p_source );
}
Example #18
0
int RarAccessOpen(vlc_object_t *object)
{
    access_t *access = (access_t*)object;

    const char *name = strchr(access->psz_location, '|');
    if (name == NULL)
        return VLC_EGENERIC;

    char *base = strndup(access->psz_location, name - access->psz_location);
    if (unlikely(base == NULL))
        return VLC_ENOMEM;

    name++;
    vlc_uri_decode(base);

    stream_t *s = vlc_stream_NewMRL(access, base);
    if (!s || RarProbe(s))
        goto error;

    struct
    {
        int filescount;
        rar_file_t **files;
        unsigned int i_nbvols;
    } newscheme = { 0, NULL, 0 }, oldscheme = { 0, NULL, 0 }, *p_scheme;

    if (RarParse(s, &newscheme.filescount, &newscheme.files, &newscheme.i_nbvols, false)
            || newscheme.filescount < 1 || newscheme.i_nbvols < 2 )
    {
        /* We might want to lookup old naming scheme, could be a part1.rar,part1.r00 */
        vlc_stream_Seek(s, 0);
        RarParse(s, &oldscheme.filescount, &oldscheme.files, &oldscheme.i_nbvols, true);
    }

    if (oldscheme.filescount >= newscheme.filescount && oldscheme.i_nbvols > newscheme.i_nbvols)
    {
        for (int i = 0; i < newscheme.filescount; i++)
            RarFileDelete(newscheme.files[i]);
        free(newscheme.files);
        p_scheme = &oldscheme;
        msg_Dbg(s, "using rar old naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols);
    }
    else if (newscheme.filescount)
    {
        for (int i = 0; i < oldscheme.filescount; i++)
            RarFileDelete(oldscheme.files[i]);
        free(oldscheme.files);
        p_scheme = &newscheme;
        msg_Dbg(s, "using rar new naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols);
    }
    else
    {
        msg_Info(s, "Invalid or unsupported RAR archive");
        for (int i = 0; i < oldscheme.filescount; i++)
            RarFileDelete(oldscheme.files[i]);
        free(oldscheme.files);
        for (int i = 0; i < newscheme.filescount; i++)
            RarFileDelete(newscheme.files[i]);
        free(newscheme.files);
        goto error;
    }

    rar_file_t *file = NULL;
    for (int i = 0; i < p_scheme->filescount; i++) {
        if (!file && !strcmp(p_scheme->files[i]->name, name))
            file = p_scheme->files[i];
        else
            RarFileDelete(p_scheme->files[i]);
    }
    free(p_scheme->files);
    if (!file)
        goto error;

    access_sys_t *sys = access->p_sys = malloc(sizeof(*sys));
    sys->s    = s;
    sys->file = file;

    access->pf_read    = Read;
    access->pf_block   = NULL;
    access->pf_control = Control;
    access->pf_seek    = Seek;

    rar_file_chunk_t dummy = {
        .mrl = base,
    };
    sys->chunk = &dummy;
    Seek(access, 0);

    free(base);
    return VLC_SUCCESS;

error:
    if (s)
        vlc_stream_Delete(s);
    free(base);
    return VLC_EGENERIC;
}
Example #19
0
File: ps.c Project: 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;
}
Example #20
0
static int ControlSetTime( demux_t *p_demux, int64_t i_time )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    bool b_seekable;
    int i;

    /* */
    vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_seekable );
    if( !b_seekable )
        return VLC_EGENERIC;

    const mtime_t i_length = ControlGetLength( p_demux );
    if( i_length <= 0 )
        return VLC_EGENERIC;

    const uint64_t i_stream_size = stream_Size( p_demux->s );
    if( i_stream_size <= p_sys->i_data_pos )
        return VLC_EGENERIC;

    const double i_bytemicrorate = (double) i_length / (i_stream_size - p_sys->i_data_pos);
    if( i_bytemicrorate == 0 )
        return VLC_EGENERIC;

    uint64_t i_lower = p_sys->i_data_pos;
    uint64_t i_upper = i_stream_size;
    uint64_t i_start_pos;

    assert( p_sys->i_seekpoint > 0 );   /* ReadMeta ensure at least (0,0) */
    if( p_sys->i_seekpoint > 1 )
    {
        /* lookup base offset */
        for( i = p_sys->i_seekpoint-1; i >= 0; i-- )
        {
            if( p_sys->seekpoint[i]->i_time_offset <= i_time )
                break;
        }

        i_lower = p_sys->seekpoint[0]->i_byte_offset + p_sys->i_data_pos;
        if( i+1 < p_sys->i_seekpoint )
            i_upper = p_sys->seekpoint[i+1]->i_byte_offset + p_sys->i_data_pos;

        i_start_pos = i_lower;
    }
    else
    {
        i_start_pos = i_time / i_bytemicrorate;
    }

    if( VLC_SUCCESS != vlc_stream_Seek( p_demux->s, i_start_pos ) )
        return VLC_EGENERIC;

    int i_ret = RefineSeek( p_demux, i_time, i_bytemicrorate, i_lower, i_upper );
    if( i_ret == VLC_SUCCESS )
    {
        p_sys->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
        Reset( p_sys );
        es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_time );
    }

    return i_ret;
}
Example #21
0
static int RefineSeek( demux_t *p_demux, mtime_t i_time, double i_bytemicrorate,
                       uint64_t i_lowpos, uint64_t i_highpos )
{
    demux_sys_t *p_sys = p_demux->p_sys;
    bool b_found = false;
    block_t *p_block_out;
    block_t *p_block_in;

    unsigned i_frame_size = FLAC_MIN_FRAME_SIZE;

    bool b_canfastseek = false;
    (int) vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b_canfastseek );

    uint64_t i_start_pos = vlc_stream_Tell( p_demux->s );

    while( !b_found )
    {
        FlushPacketizer( p_sys->p_packetizer );

        p_block_out = NULL;
        p_block_in = NULL;

        while( !p_block_out )
        {
            if( !p_block_in )
            {
                if( !(p_block_in = vlc_stream_Block( p_demux->s, i_frame_size )) )
                    break;
            }

            p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in );
        }

        if( !p_block_out )
        {
            if( p_block_in )
                block_Release( p_block_in );
            break;
        }

        if( p_block_out->i_buffer > i_frame_size )
            i_frame_size = p_block_out->i_buffer;

        /* If we are further than wanted block */
        if( p_block_out->i_dts >= i_time )
        {
            mtime_t i_diff = p_block_out->i_dts - i_time;
            /* Not in acceptable approximation range */
            if( i_diff > CLOCK_FREQ / 10 && i_diff / i_bytemicrorate > i_frame_size )
            {
                i_highpos = i_start_pos;
                i_start_pos -= ( i_diff / i_bytemicrorate );
                i_start_pos = __MAX(i_start_pos, i_lowpos + i_frame_size);
            }
            else b_found = true;
        }
        else if( p_block_out->i_dts < i_time )
        {
            mtime_t i_diff = i_time - p_block_out->i_dts;
            /* Not in acceptable NEXT_TIME demux range */
            if( i_diff >= ((b_canfastseek) ? FLAC_MAX_PREROLL : FLAC_MAX_SLOW_PREROLL) &&
                i_diff / i_bytemicrorate > i_frame_size )
            {
                i_lowpos = i_start_pos;
                i_start_pos += ( i_diff / i_bytemicrorate );
                i_start_pos = __MIN(i_start_pos, i_highpos - i_frame_size);
            }
            else b_found = true;
        }

        if( p_block_out )
            block_Release( p_block_out );
        if( p_block_in )
            block_Release( p_block_in );

        if( !b_found )
        {
            if( i_highpos < i_lowpos || i_highpos - i_lowpos < i_frame_size )
                break;

            if( VLC_SUCCESS != vlc_stream_Seek( p_demux->s, i_start_pos ) )
                break;
        }
    }

    return b_found ? VLC_SUCCESS : VLC_EGENERIC;
}
Example #22
0
static int Seek( stream_t *s, uint64_t offset )
{
    return vlc_stream_Seek( s->p_source, offset );
}
Example #23
0
File: stl.c Project: BossKing/vlc
static int Open(vlc_object_t *object)
{
    demux_t *demux = (demux_t*)object;

    const uint8_t *peek;
    if (vlc_stream_Peek(demux->s, &peek, 11) != 11)
        return VLC_EGENERIC;

    bool is_stl_25 = !memcmp(&peek[3], "STL25.01", 8);
    bool is_stl_30 = !memcmp(&peek[3], "STL30.01", 8);
    if (!is_stl_25 && !is_stl_30)
        return VLC_EGENERIC;
    const double fps = is_stl_25 ? 25 : 30;

    uint8_t header[1024];
    if (vlc_stream_Read(demux->s, header, sizeof(header)) != sizeof(header)) {
        msg_Err(demux, "Incomplete EBU STL header");
        return VLC_EGENERIC;
    }
    const int cct = ParseInteger(&header[12], 2);
    const mtime_t program_start = ParseTextTimeCode(&header[256], fps);
    const int tti_count = ParseInteger(&header[238], 5);
    msg_Dbg(demux, "Detected EBU STL : CCT=%d TTI=%d start=%8.8s %"PRId64, cct, tti_count, &header[256], program_start);

    demux_sys_t *sys = xmalloc(sizeof(*sys));
    sys->next_date = 0;
    sys->current   = 0;
    sys->count     = 0;
    sys->index     = xcalloc(tti_count, sizeof(*sys->index));


    bool comment = false;
    stl_entry_t *s = &sys->index[0];
    s->count = 0;

    for (int i = 0; i < tti_count; i++) {
        uint8_t tti[16];
        if (vlc_stream_Read(demux->s, tti, 16) != 16 ||
            vlc_stream_Read(demux->s, NULL, 112) != 112) {
            msg_Warn(demux, "Incomplete EBU STL file");
            break;
        }
        const int ebn = tti[3];
        if (ebn >= 0xf0 && ebn <= 0xfd)
            continue;
        if (ebn == 0xfe)
            continue;

        if (s->count <= 0) {
            comment  = tti[15] != 0;
            s->start = ParseTimeCode(&tti[5], fps) - program_start;
            s->stop  = ParseTimeCode(&tti[9], fps) - program_start;
            s->index = i;
        }
        s->count++;
        if (ebn == 0xff && !comment)
            s = &sys->index[++sys->count];
        if (ebn == 0xff && sys->count < tti_count)
            s->count = 0;
    }
    if (sys->count > 0)
        vlc_stream_Seek(demux->s, 1024 + 128LL * sys->index[0].index);

    es_format_t fmt;
    es_format_Init(&fmt, SPU_ES, VLC_CODEC_EBU_STL);
    fmt.i_extra = sizeof(header);
    fmt.p_extra = header;

    sys->es = es_out_Add(demux->out, &fmt);

    fmt.i_extra = 0;
    fmt.p_extra = NULL;
    es_format_Clean(&fmt);

    demux->p_sys      = sys;
    demux->pf_demux   = Demux;
    demux->pf_control = Control;
    return VLC_SUCCESS;
}