Changeset 144bd771d6ccb981b245942cae439f942f54fe31

Show
Ignore:
Timestamp:
03/10/04 18:10:40 (4 years ago)
Author:
Gildas Bazin <gbazin@videolan.org>
git-committer:
Gildas Bazin <gbazin@videolan.org> 1078938640 +0000
git-parent:

[f50eee0d06b197f99fc9f3bec869fbbe2f4e3ebf]

git-author:
Gildas Bazin <gbazin@videolan.org> 1078938640 +0000
Message:

* modules/access/file.c:

+ implemented a --file-cat config option that accepts a coma separated list of file names.

This option allows opening splitted files as a single (concatenated) input.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • modules/access/file.c

    r4598fd2 r144bd77  
    33 ***************************************************************************** 
    44 * Copyright (C) 2001, 2002 VideoLAN 
    5  * $Id: file.c,v 1.23 2004/03/01 12:50:39 gbazin Exp
     5 * $Id
    66 * 
    77 * Authors: Christophe Massiot <massiot@via.ecp.fr> 
     
    5454/* stat() support for large files on win32 */ 
    5555#if defined( WIN32 ) && !defined( UNDER_CE ) 
    56 #define stat(a,b) _stati64(a,b) 
     56#define stat _stati64 
    5757#define fstat(a,b) _fstati64(a,b) 
     58#endif 
     59 
     60#ifdef UNDER_CE 
     61#   define close(a) CloseHandle((HANDLE)a) 
    5862#endif 
    5963 
     
    6670static void    Seek   ( input_thread_t *, off_t ); 
    6771static ssize_t Read   ( input_thread_t *, byte_t *, size_t ); 
     72 
     73static int     _OpenFile( input_thread_t *, char * ); 
    6874 
    6975/***************************************************************************** 
     
    7480    "Allows you to modify the default caching value for file streams. This " \ 
    7581    "value should be set in miliseconds units." ) 
     82#define CAT_TEXT N_("Concatenate with additional files") 
     83#define CAT_LONGTEXT N_( \ 
     84    "Allows you to play splitted files as they were part of a unique file. " \ 
     85    "Specify a coma (',') separated list of files." ) 
    7686 
    7787vlc_module_begin(); 
    7888    set_description( _("Standard filesystem file input") ); 
    7989    add_integer( "file-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); 
     90    add_string( "file-cat", NULL, NULL, CAT_TEXT, CAT_LONGTEXT, VLC_TRUE ); 
    8091    set_capability( "access", 50 ); 
    8192    add_shortcut( "file" ); 
     
    89100 *                  fields 
    90101 *****************************************************************************/ 
     102typedef struct file_entry_s 
     103{ 
     104    char     *psz_name; 
     105    int64_t  i_size; 
     106 
     107} file_entry_t; 
     108 
    91109typedef struct _input_socket_s 
    92110{ 
     
    95113    unsigned int        i_nb_reads; 
    96114    vlc_bool_t          b_kfir; 
     115 
     116    /* Files list */ 
     117    file_entry_t **p_files; 
     118    int          i_files; 
     119 
     120    /* Current file */ 
     121    int  i_index; 
     122 
    97123} _input_socket_t; 
    98124 
     
    106132#ifdef HAVE_SYS_STAT_H 
    107133    int                 i_stat; 
    108 #if defined( WIN32 ) && !defined( UNDER_CE ) 
    109     struct _stati64     stat_info; 
    110 #else 
    111134    struct stat         stat_info; 
    112 #endif 
    113135#endif 
    114136    _input_socket_t *   p_access_data; 
    115137    vlc_bool_t          b_stdin, b_kfir = 0; 
    116138    vlc_value_t         val; 
     139 
     140    file_entry_t *      p_file; 
    117141 
    118142    p_input->i_mtu = 0; 
     
    218242    else 
    219243    { 
    220 #ifdef UNDER_CE 
    221         wchar_t psz_filename[MAX_PATH]; 
    222         MultiByteToWideChar( CP_ACP, 0, psz_name, -1, psz_filename, MAX_PATH ); 
    223  
    224         p_access_data->_socket.i_handle = (int)CreateFile( psz_filename, 
    225             GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,  
    226             FILE_ATTRIBUTE_NORMAL, NULL ); 
    227  
    228         if( (HANDLE)p_access_data->_socket.i_handle == INVALID_HANDLE_VALUE ) 
    229         { 
    230             msg_Err( p_input, "cannot open file %s", psz_name ); 
     244        if( _OpenFile( p_input, psz_name ) != VLC_SUCCESS ) 
     245        { 
    231246            free( p_access_data ); 
    232247            return VLC_EGENERIC; 
    233248        } 
    234         p_input->stream.p_selected_area->i_size = 
    235                 GetFileSize( (HANDLE)p_access_data->_socket.i_handle, NULL ); 
    236 #else 
    237         p_access_data->_socket.i_handle = open( psz_name, 
    238                                                 O_NONBLOCK /*| O_LARGEFILE*/ ); 
    239         if( p_access_data->_socket.i_handle == -1 ) 
    240         { 
    241 #   ifdef HAVE_ERRNO_H 
    242             msg_Err( p_input, "cannot open file %s (%s)", psz_name, 
    243                               strerror(errno) ); 
    244 #   else 
    245             msg_Err( p_input, "cannot open file %s", psz_name ); 
    246 #   endif 
    247             free( p_access_data ); 
    248             return VLC_EGENERIC; 
    249         } 
    250 #endif 
    251249    } 
    252250 
     
    264262    p_input->i_pts_delay = val.i_int * 1000; 
    265263 
     264    /* 
     265     * Get the additional list of files 
     266     */ 
     267    p_access_data->p_files = NULL; 
     268    p_access_data->i_files = p_access_data->i_index = 0; 
     269    p_file = (file_entry_t *)malloc( sizeof(file_entry_t) ); 
     270    p_file->i_size = p_input->stream.p_selected_area->i_size; 
     271    p_file->psz_name = strdup( psz_name ); 
     272    TAB_APPEND( p_access_data->i_files, p_access_data->p_files, p_file ); 
     273 
     274    var_Create( p_input, "file-cat", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); 
     275    var_Get( p_input, "file-cat", &val ); 
     276 
     277    if( val.psz_string && *val.psz_string ) 
     278    { 
     279        char *psz_parser = psz_name = val.psz_string; 
     280        int64_t i_size; 
     281 
     282        while( psz_name && *psz_name ) 
     283        { 
     284            psz_parser = strchr( psz_name, ',' ); 
     285            if( psz_parser ) *psz_parser = 0; 
     286 
     287            psz_name = strdup( psz_name ); 
     288            if( psz_name ) 
     289            { 
     290                msg_Dbg( p_input, "adding file `%s'", psz_name ); 
     291 
     292#ifdef HAVE_SYS_STAT_H 
     293                if( !stat( psz_name, &stat_info ) ) 
     294                { 
     295                    p_input->stream.p_selected_area->i_size += 
     296                        stat_info.st_size; 
     297                    i_size = stat_info.st_size; 
     298                } 
     299                else 
     300                { 
     301                    msg_Dbg( p_input, "cannot stat() file `%s'", psz_name ); 
     302                    i_size = 0; 
     303                } 
     304#endif 
     305 
     306                p_file = (file_entry_t *)malloc( sizeof(file_entry_t) ); 
     307                p_file->i_size = i_size; 
     308                p_file->psz_name = psz_name; 
     309 
     310                TAB_APPEND( p_access_data->i_files, p_access_data->p_files, 
     311                            p_file ); 
     312            } 
     313 
     314            psz_name = psz_parser; 
     315            if( psz_name ) psz_name++; 
     316        } 
     317    } 
     318 
     319    if( val.psz_string ) free( val.psz_string ); 
     320 
    266321    return VLC_SUCCESS; 
    267322} 
     
    272327static void Close( vlc_object_t * p_this ) 
    273328{ 
    274     input_thread_t * p_input = (input_thread_t *)p_this; 
    275     input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data; 
     329    input_thread_t *p_input = (input_thread_t *)p_this; 
     330    _input_socket_t *p_access_data = (_input_socket_t *)p_input->p_access_data; 
     331    int i; 
    276332 
    277333    msg_Info( p_input, "closing `%s/%s://%s'",  
    278334              p_input->psz_access, p_input->psz_demux, p_input->psz_name ); 
    279335  
    280 #ifdef UNDER_CE 
    281     CloseHandle( (HANDLE)p_access_data->i_handle ); 
    282 #else 
    283     close( p_access_data->i_handle ); 
    284 #endif 
     336    close( p_access_data->_socket.i_handle ); 
     337 
     338    for( i = 0; i < p_access_data->i_files; i++ ) 
     339    { 
     340        free( p_access_data->p_files[i]->psz_name ); 
     341        free( p_access_data->p_files[i] ); 
     342    } 
     343    if( p_access_data->p_files ) free( p_access_data->p_files ); 
    285344 
    286345    free( p_access_data ); 
     
    292351static ssize_t Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) 
    293352{ 
    294     _input_socket_t * p_access_data = (_input_socket_t *)p_input->p_access_data; 
     353    _input_socket_t *p_access_data = (_input_socket_t *)p_input->p_access_data; 
    295354    ssize_t i_ret; 
    296355  
     
    381440            && (p_access_data->i_nb_reads % INPUT_FSTAT_NB_READS) == 0 ) 
    382441    { 
    383 #if defined( WIN32 ) && !defined( UNDER_CE ) 
    384         struct _stati64 stat_info; 
    385 #else 
    386442        struct stat stat_info; 
    387 #endif 
     443        int i_file = p_access_data->i_index; 
     444 
    388445        if ( fstat( p_access_data->_socket.i_handle, &stat_info ) == -1 ) 
    389446        { 
     
    395452#   endif 
    396453        } 
    397         else if ( p_input->stream.p_selected_area->i_size != stat_info.st_size ) 
    398         { 
    399             p_input->stream.p_selected_area->i_size = stat_info.st_size; 
     454        else if ( p_access_data->p_files[i_file]->i_size != stat_info.st_size ) 
     455        { 
     456            p_input->stream.p_selected_area->i_size += 
     457                (stat_info.st_size - p_access_data->p_files[i_file]->i_size); 
    400458            p_input->stream.b_changed = 1; 
    401459        } 
    402460    } 
    403461#endif 
     462 
     463    /* If we reached an EOF then switch to the next file in the list */ 
     464    if ( i_ret == 0 && ++p_access_data->i_index < p_access_data->i_files ) 
     465    { 
     466        int i_handle = p_access_data->_socket.i_handle; 
     467        char *psz_name = 
     468            p_access_data->p_files[p_access_data->i_index]->psz_name; 
     469 
     470        msg_Dbg( p_input, "opening file `%s'", psz_name ); 
     471 
     472        if ( _OpenFile( p_input, psz_name ) != VLC_SUCCESS ) return i_ret; 
     473 
     474        close( i_handle ); 
     475 
     476        /* We have to read some data */ 
     477        return Read( p_input, p_buffer, i_len ); 
     478    } 
    404479 
    405480    return i_ret; 
     
    412487{ 
    413488#define S p_input->stream 
    414     input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data; 
     489    _input_socket_t *p_access_data = (_input_socket_t *)p_input->p_access_data; 
     490    int64_t i_size = 0; 
     491 
     492    /* Check which file we need to access */ 
     493    if ( p_access_data->i_files > 1 ) 
     494    { 
     495        int i, i_handle = p_access_data->_socket.i_handle; 
     496        char * psz_name; 
     497 
     498        for ( i = 0; i < p_access_data->i_files - 1; i++ ) 
     499        { 
     500            if( i_pos < p_access_data->p_files[i+1]->i_size + i_size ) break; 
     501            i_size += p_access_data->p_files[i+1]->i_size; 
     502        } 
     503 
     504        psz_name = p_access_data->p_files[i]->psz_name; 
     505        p_access_data->i_index = i; 
     506 
     507        msg_Dbg( p_input, "opening file `%s'", psz_name ); 
     508        if ( _OpenFile( p_input, psz_name ) == VLC_SUCCESS ) 
     509        { 
     510            /* Close old file */ 
     511            close( i_handle ); 
     512        } 
     513        else 
     514        { 
     515            p_access_data->_socket.i_handle = i_handle; 
     516        } 
     517    } 
    415518 
    416519#if defined( WIN32 ) && !defined( UNDER_CE ) 
    417     _lseeki64( p_access_data->i_handle, i_pos, SEEK_SET ); 
     520    _lseeki64( p_access_data->_socket.i_handle, i_pos - i_size, SEEK_SET ); 
    418521#else 
    419     lseek( p_access_data->i_handle, i_pos, SEEK_SET ); 
     522    lseek( p_access_data->_socket.i_handle, i_pos - i_size, SEEK_SET ); 
    420523#endif 
    421524 
     
    436539} 
    437540 
     541/***************************************************************************** 
     542 * OpenFile: Opens a specific file 
     543 *****************************************************************************/ 
     544static int _OpenFile( input_thread_t * p_input, char * psz_name ) 
     545{ 
     546    input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data; 
     547 
     548#ifdef UNDER_CE 
     549    wchar_t psz_filename[MAX_PATH]; 
     550    MultiByteToWideChar( CP_ACP, 0, psz_name, -1, psz_filename, MAX_PATH ); 
     551 
     552    p_access_data->i_handle = 
     553       (int)CreateFile( psz_filename, GENERIC_READ, FILE_SHARE_READ, 
     554                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 
     555 
     556    if ( (HANDLE)p_access_data->i_handle == INVALID_HANDLE_VALUE ) 
     557    { 
     558        msg_Err( p_input, "cannot open file %s", psz_name ); 
     559        return VLC_EGENERIC; 
     560    } 
     561    p_input->stream.p_selected_area->i_size = 
     562        GetFileSize( (HANDLE)p_access_data->i_handle, NULL ); 
     563#else 
     564 
     565    p_access_data->i_handle = open( psz_name, O_NONBLOCK /*| O_LARGEFILE*/ ); 
     566    if ( p_access_data->i_handle == -1 ) 
     567    { 
     568#   ifdef HAVE_ERRNO_H 
     569        msg_Err( p_input, "cannot open file %s (%s)", psz_name, 
     570                 strerror(errno) ); 
     571#   else 
     572        msg_Err( p_input, "cannot open file %s", psz_name ); 
     573#   endif 
     574        return VLC_EGENERIC; 
     575    } 
     576#endif 
     577 
     578    return VLC_SUCCESS; 
     579}