[vlc-devel] [RFC PATCH 2/3] test: add input/stream
Rémi Denis-Courmont
remi at remlab.net
Tue Oct 20 21:47:27 CEST 2015
On Tuesday 20 October 2015 20:27:06 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>
Isn´t it easier to compare the file content directly here?
> +#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;
> +}
> +
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list