Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/test/src/input/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 10 kB image not shown  

Quelle  stream.c   Sprache: C

 

/*****************************************************************************
 * 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_strings.h>
#include <vlc_hash.h>
#include <vlc_stream.h>
#include <vlc_fs.h>

#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#ifndef TEST_NET
#define RAND_FILE_SIZE (1024 * 1024)
#else
#define HTTP_URL "http://streams.videolan.org/streams/ogm/MJPEG.ogm"
#define HTTP_MD5 "4eaf9e8837759b670694398a33f02bc0"
#endif

struct reader
{
    const char *psz_name;
    union {
        FILE *f;
        stream_t *s;
    } u;
    void *p_data;

    void        (*pf_close)( struct reader * );
    uint64_t    (*pf_getsize)( 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 );
};

#ifndef TEST_NET
static uint64_t
libc_getsize( struct reader *p_reader )
{
    struct stat st;
    int i_fd = fileno( p_reader->u.f );

    assert( i_fd >= 0 );
    assert( fstat( i_fd, &st ) != -1 );

    return st.st_size;
}

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 void
libc_close( struct reader *p_reader )
{
    fclose( p_reader->u.f );
    free( p_reader->p_data );
    free( p_reader );
}

static struct reader *
libc_open( const char *psz_file )
{
    struct reader *p_reader = calloc( 1, sizeof(struct reader) );
    assert( p_reader );

    p_reader->u.f = fopen( psz_file, "r" );
    if( !p_reader->u.f )
    {
        free( p_reader );
        return NULL;
    }
    p_reader->pf_close = libc_close;
    p_reader->pf_getsize = libc_getsize;
    p_reader->pf_read = libc_read;
    p_reader->pf_peek = libc_peek;
    p_reader->pf_tell = libc_tell;
    p_reader->pf_seek = libc_seek;
    p_reader->psz_name = "libc";
    assert( p_reader->psz_name );
    return p_reader;
}
#endif

static uint64_t
stream_getsize( struct reader *p_reader )
{
    uint64_t i_size;

    assert( vlc_stream_GetSize( p_reader->u.s, &i_size ) == 0 );
    return i_size;
}

static ssize_t
stream_read( struct reader *p_reader, void *p_buf, size_t i_len )
{
    return vlc_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 vlc_stream_Peek( p_reader->u.s, pp_buf, i_len );
}

static uint64_t
stream_tell( struct reader *p_reader )
{
    return vlc_stream_Tell( p_reader->u.s );
}

static int
stream_seek( struct reader *p_reader, uint64_t i_offset )
{
    return vlc_stream_Seek( p_reader->u.s, i_offset );
}

static void
stream_close( struct reader *p_reader )
{
    vlc_stream_Delete( p_reader->u.s );
    libvlc_release( p_reader->p_data );
    free( p_reader );
}

static struct reader *
stream_open( const char *psz_url )
{
    libvlc_instance_t *p_vlc;
    struct reader *p_reader;
    const char * argv[] = {
        "-v",
        "--ignore-config",
        "-I",
        "dummy",
        "--no-media-library",
        "--vout=dummy",
        "--aout=dummy",
    };

    p_reader = calloc( 1, sizeof(struct reader) );
    assert( p_reader );

    p_vlc = libvlc_new( ARRAY_SIZE(argv), argv );
    assert( p_vlc != NULL );

    p_reader->u.s = vlc_stream_NewURL( p_vlc->p_libvlc_int, psz_url );
    if( !p_reader->u.s )
    {
        libvlc_release( p_vlc );
        free( p_reader );
        return NULL;
    }
    p_reader->pf_close = stream_close;
    p_reader->pf_getsize = stream_getsize;
    p_reader->pf_read = stream_read;
    p_reader->pf_peek = stream_peek;
    p_reader->pf_tell = stream_tell;
    p_reader->pf_seek = stream_seek;
    p_reader->p_data = p_vlc;
    p_reader->psz_name = "stream";
    return p_reader;
}

static ssize_t
read_at( struct reader **pp_readers, unsigned int i_readers,
         void *p_buf, uint64_t i_offset,
         size_t i_read, uint64_t i_size )
{
    void *p_cmp_buf = NULL;
    ssize_t i_cmp_ret = 0, i_ret = 0;

    for( unsigned i = 0; i < i_readers; ++i )
    {
        uint64_t i_last_pos;
        const uint8_t *p_peek = NULL;
        struct reader *p_reader = pp_readers[i];

        test_log( "%s: %s %zu @ %"PRIu64" (size: %" PRIu64 ")\n", p_reader->psz_name,
                  p_buf ? "read" : "peek", i_read, i_offset, i_size );
        assert( p_reader->pf_seek( p_reader, i_offset ) != -1 );

        i_last_pos = p_reader->pf_tell( p_reader );
        assert( i_last_pos == i_offset );

        if( p_buf )
        {
            i_ret = p_reader->pf_read( p_reader, p_buf, i_read );
            assert( i_ret >= 0 );
            assert( p_reader->pf_tell( p_reader ) == i_ret + i_last_pos );
        }
        else
        {
            i_ret = p_reader->pf_peek( p_reader, &p_peek, i_read );
            assert( i_ret >= 0 );
            assert( p_reader->pf_tell( p_reader ) == i_last_pos );
            if( i_ret > 0 )
                assert( p_peek );
        }

        if( i_offset < i_size )
            assert( (size_t) i_ret == __MIN( i_read, i_size - i_last_pos ) );

        if( i_readers > 1 )
        {
            if( i == 0 )
            {
                if( i_ret > 0 )
                {
                    p_cmp_buf = malloc( i_ret );
                    assert( p_cmp_buf );
                    memcpy( p_cmp_buf, p_buf ? p_buf : p_peek, i_ret );
                }
                i_cmp_ret = i_ret;
            }
            else
            {
                assert( i_cmp_ret == i_ret );
                if( i_ret > 0 )
                    assert( memcmp( p_cmp_buf, p_buf ? p_buf : p_peek, i_ret ) == 0 );
            }
        }
    }
    free( p_cmp_buf );
    return i_ret;
}

static void
test( struct reader **pp_readers, unsigned int i_readers, const char *psz_md5 )
{
#define READ_AT( i_offset, i_read ) \
    read_at( pp_readers, i_readers, p_buf, i_offset, i_read, i_size )
#define PEEK_AT( i_offset, i_read ) \
    read_at( pp_readers, i_readers, NULL, i_offset, i_read, i_size )
    uint8_t p_buf[4096];
    ssize_t i_ret = 0;
    uint64_t i_offset = 0;
    uint64_t i_size;
    char psz_read_md5[VLC_HASH_MD5_DIGEST_HEX_SIZE];
    vlc_hash_md5_t md5;

    /* Compare size between each readers */
    i_size = pp_readers[0]->pf_getsize( pp_readers[0] );
    assert( i_size > 0 );

    test_log( "stream size: %"PRIu64"\n", i_size );
    for( unsigned int i = 1; i < i_readers; ++i )
        assert( pp_readers[i]->pf_getsize( pp_readers[i] ) == i_size );

    /* Read the whole file and compare between each readers */
    if( psz_md5 != NULL )
        vlc_hash_md5_Init( &md5 );
    while( ( i_ret = READ_AT( i_offset, 4096 ) ) > 0 )
    {
        i_offset += i_ret;
        if( psz_md5 != NULL )
            vlc_hash_md5_Update( &md5, p_buf, i_ret );
    }
    if( psz_md5 != NULL )
    {
        vlc_hash_FinishHex( &md5, psz_read_md5 );
        assert( strcmp( psz_read_md5, psz_md5 ) == 0 );
    }

    /* Test cache skip */
    i_offset = 9 * i_size / 10;
    while( i_offset < i_size && ( i_ret = READ_AT( i_offset, 4096 ) ) > 0 )
        i_offset += i_ret + 1;

    /* Test seek and peek */
    READ_AT( 0, 42 );
    READ_AT( i_size - 5, 43 );
    READ_AT( 1, 45 );
    READ_AT( 2, 45 );
    READ_AT( i_size / 2, 45 );
    READ_AT( 2, 45 );
    READ_AT( 1, 45 );

    PEEK_AT( 0, 46 );
    PEEK_AT( i_size - 23, 46 );
    PEEK_AT( i_size / 2, 46 );
    PEEK_AT( 0, 46 );
}

#ifndef TEST_NET
static void
fill_rand( int i_fd, size_t i_size )
{
    unsigned int seed = 12345;

    while( i_size > 0 )
    {
        uint8_t p_buf[4096];
        size_t i_tocopy = __MIN( i_size, sizeof (p_buf) );

        for (size_t i = 0; i < i_tocopy; i++)
            p_buf[i] = rand_r(&seed);

        ssize_t i_ret = write( i_fd, p_buf, i_tocopy );
        if( i_ret < (ssize_t)i_tocopy ) {
            if( i_ret >= 0 )
                errno = ENOSPC;
            perror("write error");
            abort();
        }
        i_size -= i_ret;
    }
}
#endif

int
main( void )
{
    struct reader *pp_readers[3];

    test_init();

#ifndef TEST_NET
    char psz_tmp_path[] = "/tmp/libvlc_XXXXXX";
    char *psz_url;
    int i_tmp_fd;

    test_log( "Generating random file...\n" );
    i_tmp_fd = vlc_mkstemp( psz_tmp_path );
    fill_rand( i_tmp_fd, RAND_FILE_SIZE );
    test_log( "Testing random file with libc, and stream...\n" );
    assert( i_tmp_fd != -1 );
    assert( asprintf( &psz_url, "file://%s", psz_tmp_path ) != -1 );

    assert( ( pp_readers[0] = libc_open( psz_tmp_path ) ) );
    assert( ( pp_readers[1] = stream_open( psz_url ) ) );

    test( pp_readers, 2, NULL );
    for( unsigned int i = 0; i < 2; ++i )
        pp_readers[i]->pf_close( pp_readers[i] );
    free( psz_url );

    close( i_tmp_fd );
#else

    test_log( "Testing http url with stream...\n" );
    alarm( 0 );
    if( !( pp_readers[0] = stream_open( HTTP_URL ) ) )
    {
        test_log( "WARNING: can't test http url" );
        return 0;
    }

    test( pp_readers, 1, HTTP_MD5 );
    for( unsigned int i = 0; i < 1; ++i )
        pp_readers[i]->pf_close( pp_readers[i] );

#endif

    return 0;
}

Messung
CHZG
839710093

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.