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

Thomas Guillem thomas at gllm.fr
Tue Oct 20 20:27:06 CEST 2015


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