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

📄 stream.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
        return VLC_EGENERIC;    }    /* Date the current track */    p_sys->stream.tk[p_sys->stream.i_tk].i_date = mdate();    /* Try to reuse already read data */    for( i = 0; i < STREAM_CACHE_TRACK; i++ )    {        stream_track_t *tk = &p_sys->stream.tk[i];        if( i_pos >= tk->i_start && i_pos <= tk->i_end )        {#ifdef STREAM_DEBUG            msg_Dbg( s, "AStreamSeekStream: reusing %d start=%"PRId64                     " end=%"PRId64, i, tk->i_start, tk->i_end );#endif            /* Seek at the end of the buffer */            if( ASeek( s, tk->i_end ) ) return VLC_EGENERIC;            /* That's it */            p_sys->i_pos = i_pos;            p_sys->stream.i_tk = i;            p_sys->stream.i_offset = i_pos - tk->i_start;            if( p_sys->stream.i_used < 1024 )                p_sys->stream.i_used = 1024;            if( AStreamRefillStream( s ) && i_pos == tk->i_end )                return VLC_EGENERIC;            return VLC_SUCCESS;        }    }    access_Control( p_access, ACCESS_CAN_SEEK, &b_afastseek );    /* FIXME compute seek cost (instead of static 'stupid' value) */    i_maxth = __MIN( p_sys->stream.i_read_size, STREAM_READ_ATONCE / 2 );    if( !b_afastseek )        i_maxth *= 3;    /* FIXME TODO */#if 0    /* Search closest segment TODO */    for( i = 0; i < STREAM_CACHE_TRACK; i++ )    {        stream_track_t *tk = &p_sys->stream.tk[i];        if( i_pos + i_maxth >= tk->i_start )        {            msg_Dbg( s, "good segment before current pos, TODO" );        }        if( i_pos - i_maxth <= tk->i_end )        {            msg_Dbg( s, "good segment after current pos, TODO" );        }    }#endif    /* Nothing good, seek and choose oldest segment */    if( ASeek( s, i_pos ) ) return VLC_EGENERIC;    p_sys->i_pos = i_pos;    i_new = 0;    for( i = 1; i < STREAM_CACHE_TRACK; i++ )    {        if( p_sys->stream.tk[i].i_date < p_sys->stream.tk[i_new].i_date )            i_new = i;    }    /* Reset the segment */    p_sys->stream.i_tk     = i_new;    p_sys->stream.i_offset =  0;    p_sys->stream.tk[i_new].i_start = i_pos;    p_sys->stream.tk[i_new].i_end   = i_pos;    /* Read data */    if( p_sys->stream.i_used < STREAM_READ_ATONCE / 2 )        p_sys->stream.i_used = STREAM_READ_ATONCE / 2;    if( AStreamRefillStream( s ) )        return VLC_EGENERIC;    return VLC_SUCCESS;}static int AStreamRefillStream( stream_t *s ){    stream_sys_t *p_sys = s->p_sys;    stream_track_t *tk = &p_sys->stream.tk[p_sys->stream.i_tk];    /* We read but won't increase i_start after initial start + offset */    int i_toread =        __MIN( p_sys->stream.i_used, STREAM_CACHE_TRACK_SIZE -               (tk->i_end - tk->i_start - p_sys->stream.i_offset) );    bool b_read = false;    int64_t i_start, i_stop;    if( i_toread <= 0 ) return VLC_EGENERIC; /* EOF */#ifdef STREAM_DEBUG    msg_Dbg( s, "AStreamRefillStream: used=%d toread=%d",                 p_sys->stream.i_used, i_toread );#endif    i_start = mdate();    while( i_toread > 0 )    {        int i_off = tk->i_end % STREAM_CACHE_TRACK_SIZE;        int i_read;        if( s->b_die )            return VLC_EGENERIC;        i_read = __MIN( i_toread, STREAM_CACHE_TRACK_SIZE - i_off );        i_read = AReadStream( s, &tk->p_buffer[i_off], i_read );        /* msg_Dbg( s, "AStreamRefillStream: read=%d", i_read ); */        if( i_read <  0 )        {            msleep( STREAM_DATA_WAIT );            continue;        }        else if( i_read == 0 )        {            if( !b_read ) return VLC_EGENERIC;            return VLC_SUCCESS;        }        b_read = true;        /* Update end */        tk->i_end += i_read;        /* Windows of STREAM_CACHE_TRACK_SIZE */        if( tk->i_end - tk->i_start > STREAM_CACHE_TRACK_SIZE )        {            int i_invalid = tk->i_end - tk->i_start - STREAM_CACHE_TRACK_SIZE;            tk->i_start += i_invalid;            p_sys->stream.i_offset -= i_invalid;        }        i_toread -= i_read;        p_sys->stream.i_used -= i_read;        p_sys->stat.i_bytes += i_read;        p_sys->stat.i_read_count++;    }    i_stop = mdate();    p_sys->stat.i_read_time += i_stop - i_start;    return VLC_SUCCESS;}static void AStreamPrebufferStream( stream_t *s ){    stream_sys_t *p_sys = s->p_sys;    access_t     *p_access = p_sys->p_access;    int64_t i_first = 0;    int64_t i_start;    int64_t i_prebuffer = p_sys->b_quick ? STREAM_CACHE_TRACK_SIZE /100 :        ( (p_access->info.i_title > 1 || p_access->info.i_seekpoint > 1) ?          STREAM_CACHE_PREBUFFER_SIZE : STREAM_CACHE_TRACK_SIZE / 3 );    msg_Dbg( s, "pre-buffering..." );    i_start = mdate();    for( ;; )    {        stream_track_t *tk = &p_sys->stream.tk[p_sys->stream.i_tk];        int64_t i_date = mdate();        int i_read;        if( s->b_die || tk->i_end >= i_prebuffer ||            (i_first > 0 && i_first + STREAM_CACHE_PREBUFFER_LENGTH < i_date) )        {            int64_t i_byterate;            /* Update stat */            p_sys->stat.i_bytes = tk->i_end - tk->i_start;            p_sys->stat.i_read_time = i_date - i_start;            i_byterate = ( INT64_C(1000000) * p_sys->stat.i_bytes ) /                         (p_sys->stat.i_read_time+1);            msg_Dbg( s, "pre-buffering done %"PRId64" bytes in %"PRId64"s - "                     "%"PRId64" kbytes/s",                     p_sys->stat.i_bytes,                     p_sys->stat.i_read_time / INT64_C(1000000),                     i_byterate / 1024 );            break;        }        /* */        i_read = STREAM_CACHE_TRACK_SIZE - tk->i_end;        i_read = __MIN( p_sys->stream.i_read_size, i_read );        i_read = AReadStream( s, &tk->p_buffer[tk->i_end], i_read );        if( i_read <  0 )        {            msleep( STREAM_DATA_WAIT );            continue;        }        else if( i_read == 0 )        {            /* EOF */            break;        }        if( i_first == 0 )        {            i_first = mdate();            msg_Dbg( s, "received first data for our buffer");        }        tk->i_end += i_read;        p_sys->stat.i_read_count++;    }}/**************************************************************************** * Method 3: ****************************************************************************/static int AStreamReadImmediate( stream_t *s, void *p_read, unsigned int i_read ){    stream_sys_t *p_sys = s->p_sys;#ifdef STREAM_DEBUG    msg_Dbg( s, "AStreamReadImmediate p_read=%p i_read=%d",             p_read, i_read );#endif    /* First, check if we already have some data in the buffer,     * that we could copy directly */    int i_copy = __MIN( stream_buffered_size( s ), i_read );    if( i_copy )    {#ifdef STREAM_DEBUG        msg_Dbg( s, "AStreamReadImmediate: copy %d from %p", i_copy, stream_buffer( s ) );#endif        assert( i_copy <= STREAM_CACHE_SIZE );        if( p_read )        {            memcpy( p_read, stream_buffer( s ), i_copy );            p_read = (uint8_t *)p_read + i_copy;        }    }    /* Now that we've read our buffer we don't need its i_copy bytes */    stream_buffer_empty( s, i_copy );    /* Now check if we have still to really read some data */    int i_to_read = i_read - i_copy;    if( i_to_read )    {        if( p_read )            i_to_read = AReadStream( s, p_read, i_to_read );        else        {            void * dummy = malloc(i_to_read);            i_to_read = AReadStream( s, dummy, i_to_read );            free(dummy);        }    }    p_sys->i_pos += i_to_read;    return i_to_read + i_copy;}static int AStreamPeekImmediate( stream_t *s, const uint8_t **pp_peek, unsigned int i_read ){#ifdef STREAM_DEBUG    msg_Dbg( s, "AStreamPeekImmediate: %d  size=%"PRId64,             i_read, size_buffered_size( s ) );#endif    /* Avoid problem, but that shouldn't happen */    if( i_read > STREAM_CACHE_SIZE / 2 )        i_read = STREAM_CACHE_SIZE / 2;    int i_to_read = i_read - stream_buffered_size( s );    if( i_to_read > 0 )    {#ifdef STREAM_DEBUG        msg_Dbg( s, "AStreamPeekImmediate: Reading %d",             i_to_read );#endif        i_to_read = AReadStream( s, stream_buffer( s ) + stream_buffered_size( s ),                                 i_to_read );        if( i_to_read > 0 )            stream_buffer_fill( s, i_to_read );    }    *pp_peek = stream_buffer( s );    return __MIN(stream_buffered_size( s ), i_read);}static int AStreamSeekImmediate( stream_t *s, int64_t i_pos ){    stream_sys_t *p_sys = s->p_sys;    access_t     *p_access = p_sys->p_access;    bool   b_aseek;#ifdef STREAM_DEBUG    msg_Dbg( s, "AStreamSeekImmediate to %"PRId64" pos=%"PRId64             i_pos, p_sys->i_pos );#endif    access_Control( p_access, ACCESS_CAN_SEEK, &b_aseek );    if( !b_aseek )    {        /* We can't do nothing */        msg_Dbg( s, "AStreamSeekImmediate: can't seek" );        return VLC_EGENERIC;    }    /* Just reset our buffer */    stream_buffer_empty( s, stream_buffered_size( s ) );    if( ASeek( s, i_pos ) ) return VLC_EGENERIC;    return VLC_SUCCESS;}/**************************************************************************** * stream_ReadLine: ****************************************************************************//** * Read from the stream untill first newline. * \param s Stream handle to read from * \return A pointer to the allocated output string. You need to free this when you are done. */#define STREAM_PROBE_LINE 2048#define STREAM_LINE_MAX (2048*100)char * stream_ReadLine( stream_t *s ){    char *p_line = NULL;    int i_line = 0, i_read = 0;    while( i_read < STREAM_LINE_MAX )    {        char *psz_eol;        const uint8_t *p_data;        int i_data;        int64_t i_pos;        /* Probe new data */        i_data = stream_Peek( s, &p_data, STREAM_PROBE_LINE );        if( i_data <= 0 ) break; /* No more data */        /* BOM detection */        i_pos = stream_Tell( s );        if( i_pos == 0 && i_data > 4 )        {            int i_bom_size = 0;            char *psz_encoding = NULL;            if( p_data[0] == 0xEF && p_data[1] == 0xBB && p_data[2] == 0xBF )            {                psz_encoding = strdup( "UTF-8" );                i_bom_size = 3;            }            else if( p_data[0] == 0x00 && p_data[1] == 0x00 )            {                if( p_data[2] == 0xFE && p_data[3] == 0xFF )                {                    psz_encoding = strdup( "UTF-32BE" );                    s->i_char_width = 4;                    i_bom_size = 4;                }            }            else if( p_data[0] == 0xFF && p_data[1] == 0xFE )            {                if( p_data[2] == 0x00 && p_data[3] == 0x00 )                {                    psz_encoding = strdup( "UTF-32LE" );                    s->i_char_width = 4;                    s->b_little_endian = true;                    i_bom_size = 4;                }                else                {                    psz_encoding = strdup( "UTF-16LE" );                    s->b_little_endian = true;                    s->i_char_width = 2;                    i_bom_size = 2;                }            }            else if( p_data[0] == 0xFE && p_data[1] == 0xFF )            {                psz_encoding = strdup( "UTF-16BE" );                s->i_char_width = 2;                i_bom_size = 2;            }            /* Seek past the BOM */            if( i_bom_size )            {                stream_Seek( s, i_bom_size );                p_data += i_bom_size;                i_data -= i_bom_size;            }            /* Open the converter if we need it */            if( psz_encoding != NULL )            {                input_thread_t *p_input;                msg_Dbg( s, "%s BOM detected", psz_encoding );                p_input = (input_thread_t *)vlc_object_find( s, VLC_OBJECT_INPUT, FIND_PARENT );                if( s->i_char_width > 1 )                {                    s->conv = vlc_iconv_open( "UTF-8", psz_encoding );                    if( s->conv == (vlc_iconv_t)-1 )                    {                        msg_Err( s, "iconv_open failed" );                    }                }                if( p_input != NULL)                {                    var_Create( p_input, "subsdec-encoding", VLC_VAR_STRING | VLC_VAR_DOINHERIT );

⌨️ 快捷键说明

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