[vlc-devel] [RFC PATCH 2/3] test: add input/stream

Thomas Guillem thomas at gllm.fr
Tue Oct 20 20:33:53 CEST 2015


This test should also test a network url with prefetch, cache_read and
without cache.

On Tue, Oct 20, 2015, at 20:27, Thomas Guillem wrote:
> This test compare IO output/returns between libc FILE functions and
> stream
> functions, with and without a stream-filter cache.
> ---
>  test/Makefile.am        |   3 +
>  test/src/input/stream.c | 306
>  ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 309 insertions(+)
>  create mode 100644 test/src/input/stream.c
> 
> diff --git a/test/Makefile.am b/test/Makefile.am
> index ae1f492..c83bea9 100644
> --- a/test/Makefile.am
> +++ b/test/Makefile.am
> @@ -21,6 +21,7 @@ check_PROGRAMS = \
>  	test_src_config_chain \
>  	test_src_misc_variables \
>  	test_src_crypto_update \
> +       test_src_input_stream \
>          $(NULL)
>  
>  check_SCRIPTS = \
> @@ -79,6 +80,8 @@ test_src_config_chain_SOURCES = src/config/chain.c
>  test_src_config_chain_LDADD = $(LIBVLCCORE)
>  test_src_crypto_update_SOURCES = src/crypto/update.c
>  test_src_crypto_update_LDADD = $(LIBVLCCORE) $(GCRYPT_LIBS)
> +test_src_input_stream_SOURCES = src/input/stream.c
> +test_src_input_stream_LDADD = $(LIBVLCCORE) $(LIBVLC)
>  
>  checkall:
>  	$(MAKE) check_PROGRAMS="$(check_PROGRAMS) $(EXTRA_PROGRAMS)" check
> diff --git a/test/src/input/stream.c b/test/src/input/stream.c
> new file mode 100644
> index 0000000..5193e90
> --- /dev/null
> +++ b/test/src/input/stream.c
> @@ -0,0 +1,306 @@
> +/*****************************************************************************
> + * stream.c test streams and stream filters
> +
> *****************************************************************************
> + * Copyright (C) 2015 VLC authors and VideoLAN
> + *
> + * 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.
> +
> *****************************************************************************/
> +
> +#include "../../libvlc/test.h"
> +#include "../lib/libvlc_internal.h"
> +
> +#include <vlc_md5.h>
> +#include <vlc_stream.h>
> +
> +#include <limits.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +
> +struct reader
> +{
> +    union {
> +        FILE *f;
> +        stream_t *s;
> +    } u;
> +    void *p_data;
> +};
> +
> +struct callbacks
> +{
> +    struct reader * (*pf_open)( const char *, const char *, const char *
> );
> +    void            (*pf_close)( struct reader * );
> +    ssize_t         (*pf_read)( struct reader *, void *, size_t );
> +    ssize_t         (*pf_peek)( struct reader *, const uint8_t **,
> size_t );
> +    uint64_t        (*pf_tell)( struct reader * );
> +    int             (*pf_seek)( struct reader *, uint64_t );
> +};
> +
> +static struct reader *
> +libc_open( const char *psz_file, const char *psz_url, const char
> *psz_cachename )
> +{
> +    (void) psz_url; (void) psz_cachename;
> +    struct reader *p_reader = calloc( 1, sizeof(struct reader) );
> +    assert( p_reader );
> +
> +    p_reader->u.f = fopen( psz_file, "r" );
> +    assert( p_reader->u.f );
> +    return p_reader;
> +}
> +
> +static void
> +libc_close( struct reader *p_reader )
> +{
> +    fclose( p_reader->u.f );
> +    free( p_reader->p_data );
> +    free( p_reader );
> +    p_reader->p_data = NULL;
> +}
> +
> +static ssize_t
> +libc_read( struct reader *p_reader, void *p_buf, size_t i_len )
> +{
> +    return fread( p_buf, 1, i_len , p_reader->u.f );
> +}
> +
> +static ssize_t
> +libc_peek( struct reader *p_reader, const uint8_t **pp_buf, size_t i_len
> )
> +{
> +    ssize_t i_ret;
> +    long i_last_pos;
> +
> +    free( p_reader->p_data );
> +    p_reader->p_data = malloc( i_len );
> +    assert( p_reader->p_data );
> +
> +    i_last_pos = ftell( p_reader->u.f );
> +
> +    i_ret = fread( p_reader->p_data, 1, i_len, p_reader->u.f );
> +    *pp_buf = p_reader->p_data;
> +
> +    assert( fseek( p_reader->u.f, i_last_pos, SEEK_SET ) == 0 );
> +    return i_ret;
> +}
> +
> +static uint64_t
> +libc_tell( struct reader *p_reader )
> +{
> +    long i_ret = ftell( p_reader->u.f );
> +    assert( i_ret >= 0 );
> +    return i_ret;
> +}
> +
> +static int
> +libc_seek( struct reader *p_reader, uint64_t i_offset )
> +{
> +    return fseek( p_reader->u.f, (long) i_offset, SEEK_SET );
> +}
> +
> +static struct reader *
> +stream_open( const char *psz_file, const char *psz_url,
> +             const char *psz_cachename )
> +{
> +    (void) psz_file;
> +    libvlc_instance_t *p_vlc;
> +    struct reader *p_reader;
> +    const char * args[] = {
> +        "-v",
> +        "--ignore-config",
> +        "-I",
> +        "dummy",
> +        "--no-media-library",
> +        "--vout=dummy",
> +        "--aout=dummy",
> +        "--stream-cache", psz_cachename,
> +    };
> +
> +    p_reader = calloc( 1, sizeof(struct reader) );
> +    assert( p_reader );
> +
> +    p_vlc = libvlc_new( sizeof(args) / sizeof(args[0]), args );
> +    assert( p_vlc != NULL );
> +
> +    p_reader->u.s = stream_UrlNew( p_vlc->p_libvlc_int, psz_url );
> +    assert( p_reader->u.s );
> +    p_reader->p_data = p_vlc;
> +    return p_reader;
> +}
> +
> +static void
> +stream_close( struct reader *p_reader )
> +{
> +    stream_Delete( p_reader->u.s );
> +    libvlc_release( p_reader->p_data );
> +    free( p_reader );
> +}
> +
> +static ssize_t
> +stream_read( struct reader *p_reader, void *p_buf, size_t i_len )
> +{
> +    return stream_Read( p_reader->u.s, p_buf, i_len );
> +}
> +
> +static ssize_t
> +stream_peek( struct reader *p_reader, const uint8_t **pp_buf, size_t
> i_len )
> +{
> +    return stream_Peek( p_reader->u.s, pp_buf, i_len );
> +}
> +
> +static uint64_t
> +stream_tell( struct reader *p_reader )
> +{
> +    return stream_Tell( p_reader->u.s );
> +}
> +
> +static int
> +stream_seek( struct reader *p_reader, uint64_t i_offset )
> +{
> +    return stream_Seek( p_reader->u.s, i_offset );
> +}
> +
> +static void
> +read_at( struct callbacks *p_cbs, struct reader *p_reader, struct md5_s
> *p_md5,
> +         void *p_buf, uint64_t i_offset,
> +         size_t i_read, size_t i_size )
> +{
> +    ssize_t i_ret;
> +    uint64_t i_last_pos;
> +
> +    log( "%s %zu @ %lu\n", p_buf ? "read" : "peek", i_read, i_offset );
> +
> +    i_last_pos = p_cbs->pf_tell( p_reader );
> +
> +    assert( p_cbs->pf_seek( p_reader, i_offset ) != -1 );
> +    i_last_pos = p_cbs->pf_tell( p_reader );
> +
> +    if( p_buf )
> +        i_ret = p_cbs->pf_read( p_reader, p_buf, i_read );
> +    else
> +    {
> +        const uint8_t *p_peek;
> +
> +        i_ret = p_cbs->pf_peek( p_reader, &p_peek, i_read );
> +
> +        /* peek at end should return 0 */
> +        if( i_offset >= i_size )
> +            assert( i_ret == 0 );
> +
> +        p_buf = (void *) p_peek;
> +        i_ret = 0;
> +    }
> +    assert( i_ret >= 0 );
> +
> +    assert( p_cbs->pf_tell( p_reader ) == i_ret + i_last_pos );
> +    AddMD5( p_md5, p_buf, i_ret );
> +}
> +
> +static char *
> +test( const char *psz_file, const char *psz_url,
> +      const char *psz_cachename, struct callbacks *p_cbs, off_t i_size )
> +{
> +#define READ_AT( i_offset, i_read ) \
> +    read_at( p_cbs, p_reader, &md5, p_buf, i_offset, i_read, i_size )
> +#define PEEK_AT( i_offset, i_read ) \
> +    read_at( p_cbs, p_reader, &md5, NULL, i_offset, i_read, i_size )
> +
> +    char *psz_md5;
> +    struct md5_s md5;
> +    void *p_buf;
> +    struct reader *p_reader = p_cbs->pf_open( psz_file, psz_url,
> psz_cachename );
> +
> +    p_buf = malloc( 4096 );
> +    assert( p_buf );
> +
> +    InitMD5( &md5 );
> +
> +    READ_AT( 0, 42 );
> +    READ_AT( 0, 42 );
> +    READ_AT( i_size - 5, 43 );
> +    READ_AT( i_size, 43 );
> +    READ_AT( i_size * 2, 43 );
> +
> +    READ_AT( 99999999LL, 44 );
> +
> +    READ_AT( 1, 45 );
> +    READ_AT( 2, 45 );
> +    READ_AT( 3, 45 );
> +    READ_AT( 2, 45 );
> +    READ_AT( 1, 45 );
> +
> +    PEEK_AT( 0, 46 );
> +    PEEK_AT( i_size - 23, 46 );
> +    PEEK_AT( i_size, 46 );
> +    PEEK_AT( i_size * 2, 46 );
> +    PEEK_AT( 0, 46 );
> +
> +    EndMD5( &md5 );
> +    p_cbs->pf_close( p_reader );
> +
> +    psz_md5 = psz_md5_hash( &md5 );
> +    assert( psz_md5 );
> +    return psz_md5;
> +}
> +
> +int
> +main( void )
> +{
> +    char psz_file[PATH_MAX];
> +    char *psz_url;
> +    struct stat st;
> +    char *psz_libc_md5 = NULL;
> +    char *psz_stream_md5 = NULL;
> +    struct callbacks cbs;
> +
> +    assert( realpath( SRCDIR"/samples/image.jpg", psz_file ) == psz_file
> );
> +    assert( asprintf( &psz_url, "file://%s", psz_file ) != -1 );
> +
> +    test_init();
> +
> +    log( "get stat: %s\n", psz_file );
> +    assert( stat( psz_file, &st ) != -1 );
> +
> +    cbs.pf_open = libc_open;
> +    cbs.pf_close = libc_close;
> +    cbs.pf_read = libc_read;
> +    cbs.pf_peek = libc_peek;
> +    cbs.pf_tell = libc_tell;
> +    cbs.pf_seek = libc_seek;
> +
> +    log( "test with libc\n" );
> +    psz_libc_md5 = test( psz_file, psz_url, NULL, &cbs, st.st_size );
> +
> +    cbs.pf_open = stream_open;
> +    cbs.pf_close = stream_close;
> +    cbs.pf_read = stream_read;
> +    cbs.pf_peek = stream_peek;
> +    cbs.pf_tell = stream_tell;
> +    cbs.pf_seek = stream_seek;
> +
> +    log( "test with file stream\n" );
> +    psz_stream_md5 = test( psz_file, psz_url, "none", &cbs, st.st_size
> );
> +    assert( strcmp( psz_libc_md5, psz_stream_md5 ) == 0 );
> +    free( psz_stream_md5 );
> +
> +    log( "test with file stream and with 'cache_read' stream_filter\n"
> );
> +    psz_stream_md5 = test( psz_file, psz_url, "cache_read", &cbs,
> st.st_size );
> +    assert( strcmp( psz_libc_md5, psz_stream_md5 ) == 0 );
> +    free( psz_stream_md5 );
> +
> +    free( psz_libc_md5 );
> +    free( psz_url );
> +
> +    return 0;
> +}
> +
> -- 
> 2.1.4
> 


More information about the vlc-devel mailing list