Browse Source

cache_block: remove module

And use cache_read instead, cf. previous commit.
Furthermore, there is only one access module: vcd, that could use
cache_block since slow block based accesses will use prefetch.

Fixes #28484
pull/162/head
Thomas Guillem 3 years ago
committed by Steve Lhomme
parent
commit
d55aa4e741
  1. 3
      modules/stream_filter/Makefile.am
  2. 330
      modules/stream_filter/cache_block.c
  3. 5
      modules/stream_filter/meson.build
  4. 1
      po/POTFILES.in

3
modules/stream_filter/Makefile.am

@ -5,9 +5,6 @@ stream_filter_LTLIBRARIES =
libcache_read_plugin_la_SOURCES = stream_filter/cache_read.c
stream_filter_LTLIBRARIES += libcache_read_plugin.la
libcache_block_plugin_la_SOURCES = stream_filter/cache_block.c
stream_filter_LTLIBRARIES += libcache_block_plugin.la
libdecomp_plugin_la_SOURCES = stream_filter/decomp.c
if !HAVE_WIN32
if !HAVE_TVOS

330
modules/stream_filter/cache_block.c

@ -1,330 +0,0 @@
/*****************************************************************************
* cache_block.c
*****************************************************************************
* Copyright (C) 1999-2004 VLC authors and VideoLAN
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_stream.h>
#include <vlc_interrupt.h>
#include <vlc_block_helper.h>
/* TODO:
* - tune the 2 methods (block/stream)
* - compute cost for seek
* - improve stream mode seeking with closest segments
* - ...
*/
/*
* One linked list of data read
*/
/* How many tracks we have, currently only used for stream mode */
#ifdef OPTIMIZE_MEMORY
/* Max size of our cache 128KiB per stream */
# define STREAM_CACHE_SIZE (1024*128)
#else
/* Max size of our cache 48MiB per stream */
# define STREAM_CACHE_SIZE (4*12*1024*1024)
#endif
/* How many data we try to prebuffer
* XXX it should be small to avoid useless latency but big enough for
* efficient demux probing */
#define STREAM_CACHE_PREBUFFER_SIZE (128)
/* Method: Simple, for pf_block.
* We get blocks and put them in the linked list.
* We release blocks once the total size is bigger than STREAM_CACHE_SIZE
*/
typedef struct
{
block_bytestream_t cache; /* bytestream chain for storing cache */
struct
{
/* Stats for calculating speed */
uint64_t read_bytes;
vlc_tick_t read_time;
} stat;
} stream_sys_t;
static int AStreamRefillBlock(stream_t *s)
{
stream_sys_t *sys = s->p_sys;
size_t cache_size = sys->cache.i_total;
/* Release data */
if (cache_size >= STREAM_CACHE_SIZE)
{
block_BytestreamFlush( &sys->cache );
cache_size = sys->cache.i_total;
}
if (cache_size >= STREAM_CACHE_SIZE &&
sys->cache.p_chain != *sys->cache.pp_last)
{
/* Enough data, don't read more */
return VLC_SUCCESS;
}
/* Now read a new block */
const vlc_tick_t start = vlc_tick_now();
block_t *b;
for (;;)
{
if (vlc_killed())
return VLC_EGENERIC;
/* Fetch a block */
if ((b = vlc_stream_ReadBlock(s->s)))
break;
if (vlc_stream_Eof(s->s))
return VLC_EGENERIC;
}
sys->stat.read_time += vlc_tick_now() - start;
size_t added_bytes;
block_ChainProperties( b, NULL, &added_bytes, NULL );
sys->stat.read_bytes += added_bytes;
block_BytestreamPush( &sys->cache, b );
return VLC_SUCCESS;
}
static void AStreamPrebufferBlock(stream_t *s)
{
stream_sys_t *sys = s->p_sys;
vlc_tick_t start = vlc_tick_now();
bool first = true;
msg_Dbg(s, "starting pre-buffering");
for (;;)
{
const vlc_tick_t now = vlc_tick_now();
size_t cache_size = block_BytestreamRemaining( &sys->cache );
if (vlc_killed() || cache_size > STREAM_CACHE_PREBUFFER_SIZE)
{
int64_t byterate;
/* Update stat */
sys->stat.read_bytes = cache_size;
sys->stat.read_time = now - start;
byterate = (CLOCK_FREQ * sys->stat.read_bytes ) /
(sys->stat.read_time -1);
msg_Dbg(s, "prebuffering done %zu bytes "
"in %"PRIu64"s - %"PRIu64"u KiB/s", cache_size,
SEC_FROM_VLC_TICK(sys->stat.read_time), byterate / 1024 );
break;
}
/* Fetch a block */
block_t *b = vlc_stream_ReadBlock(s->s);
if (b == NULL)
{
if (vlc_stream_Eof(s->s))
break;
continue;
}
block_BytestreamPush( &sys->cache, b);
if (first)
{
msg_Dbg(s, "received first data after %"PRId64" ms",
MS_FROM_VLC_TICK(vlc_tick_now() - start));
first = false;
}
}
}
/****************************************************************************
* AStreamControlReset:
****************************************************************************/
static void AStreamControlReset(stream_t *s)
{
stream_sys_t *sys = s->p_sys;
block_BytestreamEmpty( &sys->cache );
/* Do the prebuffering */
AStreamPrebufferBlock(s);
}
static int AStreamSeekBlock(stream_t *s, uint64_t i_pos)
{
stream_sys_t *sys = s->p_sys;
if( block_SkipBytes( &sys->cache, i_pos) == VLC_SUCCESS )
return VLC_SUCCESS;
/* Not enough bytes, empty and seek */
/* Do the access seek */
if (vlc_stream_Seek(s->s, i_pos)) return VLC_EGENERIC;
block_BytestreamEmpty( &sys->cache );
/* Refill a block */
if (AStreamRefillBlock(s))
return VLC_EGENERIC;
return VLC_SUCCESS;
}
static ssize_t AStreamReadBlock(stream_t *s, void *buf, size_t len)
{
stream_sys_t *sys = s->p_sys;
ssize_t i_current = block_BytestreamRemaining( &sys->cache );
size_t i_copy = VLC_CLIP((size_t)i_current, 0, len);
/**
* we should not signal end-of-file if we have not exhausted
* the cache. i_copy == 0 just means that the cache currently does
* not contain data at the offset that we want, not EOF.
**/
if( i_copy == 0 )
{
/* Return EOF if we are unable to refill cache, most likely
* really EOF */
if( AStreamRefillBlock(s) == VLC_EGENERIC )
return 0;
}
/* Copy data */
if( block_GetBytes( &sys->cache, buf, i_copy ) )
return -1;
/* If we ended up on refill, try to read refilled cache */
if( i_copy == 0 && sys->cache.p_chain )
return AStreamReadBlock( s, buf, len );
return i_copy;
}
/****************************************************************************
* AStreamControl:
****************************************************************************/
static int AStreamControl(stream_t *s, int i_query, va_list args)
{
switch(i_query)
{
case STREAM_CAN_SEEK:
case STREAM_CAN_FASTSEEK:
case STREAM_CAN_PAUSE:
case STREAM_CAN_CONTROL_PACE:
case STREAM_GET_MTIME:
case STREAM_GET_SIZE:
case STREAM_GET_PTS_DELAY:
case STREAM_GET_TITLE_INFO:
case STREAM_GET_TITLE:
case STREAM_GET_SEEKPOINT:
case STREAM_GET_META:
case STREAM_GET_CONTENT_TYPE:
case STREAM_GET_SIGNAL:
case STREAM_GET_TAGS:
case STREAM_SET_PAUSE_STATE:
case STREAM_SET_PRIVATE_ID_STATE:
case STREAM_SET_PRIVATE_ID_CA:
case STREAM_GET_PRIVATE_ID_STATE:
return vlc_stream_vaControl(s->s, i_query, args);
case STREAM_SET_TITLE:
case STREAM_SET_SEEKPOINT:
{
int ret = vlc_stream_vaControl(s->s, i_query, args);
if (ret == VLC_SUCCESS)
AStreamControlReset(s);
return ret;
}
case STREAM_SET_RECORD_STATE:
default:
msg_Err(s, "invalid vlc_stream_vaControl query=0x%x", i_query);
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
static int Open(vlc_object_t *obj)
{
stream_t *s = (stream_t *)obj;
if (s->s->pf_block == NULL)
return VLC_EGENERIC;
stream_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
msg_Dbg(s, "Using block method for AStream*");
/* Init all fields of sys->block */
block_BytestreamInit( &sys->cache );
s->p_sys = sys;
/* Do the prebuffering */
AStreamPrebufferBlock(s);
if (block_BytestreamRemaining( &sys->cache ) <= 0)
{
msg_Err(s, "cannot pre fill buffer");
free(sys);
return VLC_EGENERIC;
}
s->pf_read = AStreamReadBlock;
s->pf_seek = AStreamSeekBlock;
s->pf_control = AStreamControl;
return VLC_SUCCESS;
}
/****************************************************************************
* AStreamDestroy:
****************************************************************************/
static void Close(vlc_object_t *obj)
{
stream_t *s = (stream_t *)obj;
stream_sys_t *sys = s->p_sys;
block_BytestreamEmpty( &sys->cache );
free(sys);
}
vlc_module_begin()
set_subcategory(SUBCAT_INPUT_STREAM_FILTER)
set_capability("stream_filter", 0)
add_shortcut("cache")
set_description(N_("Block stream cache"))
set_callbacks(Open, Close)
vlc_module_end()

5
modules/stream_filter/meson.build

@ -3,11 +3,6 @@ vlc_modules += {
'sources' : files('cache_read.c')
}
vlc_modules += {
'name' : 'cache_block',
'sources' : files('cache_block.c')
}
if host_system != 'windows' and not have_tvos
vlc_modules += {
'name' : 'decomp',

1
po/POTFILES.in

@ -1239,7 +1239,6 @@ modules/spu/subsdelay.c
modules/stream_extractor/archive.c
modules/stream_filter/adf.c
modules/stream_filter/aribcam.c
modules/stream_filter/cache_block.c
modules/stream_filter/cache_read.c
modules/stream_filter/decomp.c
modules/stream_filter/hds/hds.c

Loading…
Cancel
Save