Changeset 2401b66298e2d714223c9d5f32aa23376a0afc4c

Show
Ignore:
Timestamp:
06/11/02 16:41:29 (6 years ago)
Author:
Johan Bilien <jobi@videolan.org>
git-committer:
Johan Bilien <jobi@videolan.org> 1036597289 +0000
git-parent:

[93160b29203c6adc490121f5b9f7282386e243da]

git-author:
Johan Bilien <jobi@videolan.org> 1036597289 +0000
Message:
  • modules/access/vcd/vcd.*: added entry points support (sort of
    chapters).
  • modules/gui/gtk/gtk_callbacks.c: added some locks to the
    navigation functions
Files:

Legend:

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

    r09cbae7 r2401b66  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000 VideoLAN 
    5  * $Id: vcd.c,v 1.9 2002/10/26 15:24:19 gbazin Exp $ 
     5 * $Id: vcd.c,v 1.10 2002/11/06 15:41:29 jobi Exp $ 
    66 * 
    77 * Author: Johan Bilien <jobi@via.ecp.fr> 
     
    1111 * the Free Software Foundation; either version 2 of the License, or 
    1212 * (at your option) any later version. 
    13  *  
     13 * 
    1414 * This program is distributed in the hope that it will be useful, 
    1515 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     
    5151{ 
    5252    vcddev_t    *vcddev;                            /* vcd device descriptor */ 
    53     int         nb_tracks;                          /* Nb of tracks (titles) */ 
     53    int         i_nb_tracks;                        /* Nb of tracks (titles) */ 
    5454    int         i_track;                                    /* Current track */ 
    5555    int         i_sector;                                  /* Current Sector */ 
    5656    int *       p_sectors;                                  /* Track sectors */ 
     57    int         i_entries_nb;                      /* Number of entry points */ 
     58    int *       p_entries;                                   /* Entry points */ 
     59    vlc_bool_t  b_valid_ep;                       /* Valid entry points flag */ 
    5760    vlc_bool_t  b_end_of_track;           /* If the end of track was reached */ 
    5861 
     
    6871static int  VCDSetArea      ( input_thread_t *, input_area_t * ); 
    6972static int  VCDSetProgram   ( input_thread_t *, pgrm_descriptor_t * ); 
     73static int  VCDEntryPoints  ( input_thread_t * ); 
    7074 
    7175/***************************************************************************** 
     
    112116    /* parse the options passed in command line : */ 
    113117    psz_orig = psz_parser = psz_source = strdup( p_input->psz_name ); 
    114      
     118 
    115119    if( !psz_orig ) 
    116120    { 
    117121        return( -1 ); 
    118122    } 
    119   
     123 
    120124    while( *psz_parser && *psz_parser != '@' ) 
    121125    { 
     
    159163        return -1; 
    160164    } 
    161      
     165 
    162166    p_input->p_access_data = (void *)p_vcd; 
    163      
     167 
    164168    p_input->i_mtu = VCD_DATA_ONCE; 
    165     
     169 
    166170    vlc_mutex_lock( &p_input->stream.stream_lock ); 
    167171 
     
    183187 
    184188    /* We read the Table Of Content information */ 
    185     p_vcd->nb_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input), 
     189    p_vcd->i_nb_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input), 
    186190                                           p_vcd->vcddev, &p_vcd->p_sectors ); 
    187191    free( psz_source ); 
    188     if( p_vcd->nb_tracks < 0 ) 
     192    if( p_vcd->i_nb_tracks < 0 ) 
    189193        msg_Err( p_input, "unable to count tracks" ); 
    190     else if( p_vcd->nb_tracks <= 1 ) 
     194    else if( p_vcd->i_nb_tracks <= 1 ) 
    191195        msg_Err( p_input, "no movie tracks found" ); 
    192     if( p_vcd->nb_tracks <= 1) 
    193     { 
    194         //input_BuffersEnd( p_input, p_input->p_method_data ); /* ??? */ 
     196    if( p_vcd->i_nb_tracks <= 1) 
     197    { 
    195198        ioctl_Close( p_this, p_vcd->vcddev ); 
    196199        free( p_vcd ); 
     
    198201    } 
    199202 
     203    /* Allocate the entry points table */ 
     204    p_vcd->p_entries = malloc( p_vcd->i_nb_tracks * sizeof( int ) ); 
     205 
     206    if( p_vcd->p_entries == NULL ) 
     207    { 
     208        msg_Err( p_input, "not enough memory" ); 
     209        ioctl_Close( p_this, p_vcd->vcddev ); 
     210        free( p_vcd ); 
     211    } 
     212 
    200213    /* Set stream and area data */ 
    201214    vlc_mutex_lock( &p_input->stream.stream_lock ); 
     
    207220    p_input->stream.i_method = INPUT_METHOD_VCD; 
    208221 
     222    p_input->stream.i_area_nb = 1; 
     223 
    209224#define area p_input->stream.pp_areas 
    210     for( i = 1 ; i <= p_vcd->nb_tracks - 1 ; i++ ) 
     225    for( i = 1 ; i <= p_vcd->i_nb_tracks - 1 ; i++ ) 
    211226    { 
    212227        input_AddArea( p_input ); 
     
    224239        area[i]->i_part = 1; 
    225240 
    226         area[i]->i_plugin_data = p_vcd->p_sectors[i]; 
     241        /* i_plugin_data is used to store which entry point is the first 
     242         * of the track (area) */ 
     243        area[i]->i_plugin_data = 0; 
    227244    } 
    228245#undef area 
    229246 
    230247    p_area = p_input->stream.pp_areas[i_title]; 
     248 
     249    p_vcd->b_valid_ep = 1; 
     250    if( VCDEntryPoints( p_input ) < 0 ) 
     251    { 
     252        msg_Warn( p_input, "could read entry points, will not use them" ); 
     253        p_vcd->b_valid_ep = 0; 
     254    } 
    231255 
    232256    VCDSetArea( p_input, p_area ); 
     
    257281 * bytes. 
    258282 *****************************************************************************/ 
    259 static int VCDRead( input_thread_t * p_input, byte_t * p_buffer,  
     283static int VCDRead( input_thread_t * p_input, byte_t * p_buffer, 
    260284                     size_t i_len ) 
    261285{ 
     
    274298    i_blocks = i_len / VCD_DATA_SIZE; 
    275299 
    276     for ( i_index = 0 ; i_index < i_blocks ; i_index++ )  
     300    for ( i_index = 0 ; i_index < i_blocks ; i_index++ ) 
    277301    { 
    278302        if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev, 
     
    287311        { 
    288312            input_area_t *p_area; 
    289              
    290             if ( p_vcd->i_track >= p_vcd->nb_tracks - 1 ) 
     313 
     314            if ( p_vcd->i_track >= p_vcd->i_nb_tracks - 1 ) 
    291315                return 0; /* EOF */ 
    292              
     316 
     317            vlc_mutex_lock( &p_input->stream.stream_lock ); 
    293318            p_area = p_input->stream.pp_areas[ 
    294319                    p_input->stream.p_selected_area->i_id + 1 ]; 
    295              
     320 
    296321            msg_Dbg( p_input, "new title" ); 
    297              
     322 
    298323            p_area->i_part = 1; 
    299324            VCDSetArea( p_input, p_area ); 
    300      
    301         } 
     325            vlc_mutex_unlock( &p_input->stream.stream_lock ); 
     326        } 
     327 
     328        /* Update chapter */ 
     329        else if( p_vcd->b_valid_ep && 
     330                /* FIXME kludge so that read does not update chapter 
     331                 * when a manual chapter change was requested and not 
     332                 * yet accomplished */ 
     333                !p_input->stream.p_new_area ) 
     334        { 
     335            int i_entry; 
     336 
     337            vlc_mutex_lock( &p_input->stream.stream_lock ); 
     338            i_entry = p_input->stream.p_selected_area->i_plugin_data 
     339                /* 1st entry point of the track (area)*/ 
     340                        + p_input->stream.p_selected_area->i_part - 1; 
     341            if( i_entry + 1 < p_vcd->i_entries_nb && 
     342                    p_vcd->i_sector >= p_vcd->p_entries[i_entry + 1] ) 
     343            { 
     344                msg_Dbg( p_input, "new chapter" ); 
     345                p_input->stream.p_selected_area->i_part ++; 
     346            } 
     347            vlc_mutex_unlock( &p_input->stream.stream_lock ); 
     348        } 
     349 
    302350        i_read += VCD_DATA_SIZE; 
    303351    } 
    304      
     352 
    305353    if ( i_len % VCD_DATA_SIZE ) /* this should not happen */ 
    306     {  
     354    { 
    307355        if ( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev, 
    308356                               p_vcd->i_sector, p_last_sector ) < 0 ) 
     
    311359            return -1; 
    312360        } 
    313          
     361 
    314362        p_input->p_vlc->pf_memcpy( p_buffer + i_blocks * VCD_DATA_SIZE, 
    315363                                   p_last_sector, i_len % VCD_DATA_SIZE ); 
     
    359407    } 
    360408 
     409    if( p_vcd->b_valid_ep ) 
     410    { 
     411        int i_entry = p_area->i_plugin_data /* 1st entry point of 
     412                                               the track (area)*/ 
     413                            + p_area->i_part - 1; 
     414        p_vcd->i_sector = p_vcd->p_entries[i_entry]; 
     415    } 
     416    else 
     417        p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track]; 
     418 
     419    p_input->stream.p_selected_area->i_tell = 
     420        (off_t)p_vcd->i_sector * (off_t)VCD_DATA_SIZE 
     421         - p_input->stream.p_selected_area->i_start; 
     422 
    361423    /* warn interface that something has changed */ 
    362424    p_input->stream.b_seekable = 1; 
     
    373435{ 
    374436    thread_vcd_data_t *               p_vcd; 
     437    int                               i_index; 
    375438 
    376439    p_vcd = (thread_vcd_data_t *) p_input->p_access_data; 
     
    379442                       + i_off / (off_t)VCD_DATA_SIZE; 
    380443 
    381     p_input->stream.p_selected_area->i_tell =  
     444    vlc_mutex_lock( &p_input->stream.stream_lock ); 
     445#define p_area p_input->stream.p_selected_area 
     446    /* Find chapter */ 
     447    if( p_vcd->b_valid_ep ) 
     448    { 
     449        for( i_index = 0 ; i_index < p_area->i_part_nb - 1 ; i_index ++ ) 
     450        { 
     451            if( p_vcd->i_sector < p_vcd->p_entries[p_area->i_plugin_data 
     452                + i_index + 1] ) 
     453            { 
     454                p_area->i_part = i_index; 
     455                break; 
     456            } 
     457        } 
     458    } 
     459#undef p_area 
     460 
     461    p_input->stream.p_selected_area->i_tell = 
    382462        (off_t)p_vcd->i_sector * (off_t)VCD_DATA_SIZE 
    383463         - p_input->stream.p_selected_area->i_start; 
    384 
     464    vlc_mutex_unlock( &p_input->stream.stream_lock ); 
     465
     466 
     467/***************************************************************************** 
     468 * VCDEntryPoints: Reads the information about the entry points on the disc. 
     469 *****************************************************************************/ 
     470static int VCDEntryPoints( input_thread_t * p_input ) 
     471
     472    thread_vcd_data_t *               p_vcd; 
     473    byte_t *                          p_sector; 
     474    entries_sect_t                    entries; 
     475    uint16_t                          i_nb; 
     476    int                               i, i_entry_index = 0; 
     477    int                               i_previous_track = -1; 
     478 
     479    p_vcd = (thread_vcd_data_t *) p_input->p_access_data; 
     480 
     481    p_sector = malloc( VCD_DATA_SIZE * sizeof( byte_t ) ); 
     482    if( p_sector == NULL ) 
     483    { 
     484        msg_Err( p_input, "not enough memory for entry points treatment" ); 
     485        return -1; 
     486    } 
     487 
     488    if( ioctl_ReadSector( VLC_OBJECT(p_input), p_vcd->vcddev, 
     489                                VCD_ENTRIES_SECTOR, p_sector ) < 0 ) 
     490    { 
     491        msg_Err( p_input, "could not read entry points sector" ); 
     492        free( p_sector ); 
     493        return( -1 ); 
     494    } 
     495 
     496    memcpy( &entries, p_sector, CD_SECTOR_SIZE ); 
     497    free( p_sector ); 
     498 
     499    if( (i_nb = U16_AT( &entries.i_entries_nb )) > 500 ) 
     500    { 
     501        msg_Err( p_input, "invalid entry points number" ); 
     502        return( -1 ); 
     503    } 
     504 
     505    p_vcd->p_entries = malloc( sizeof( int ) * i_nb ); 
     506    if( p_vcd->p_entries == NULL ) 
     507    { 
     508        msg_Err( p_input, "not enough memory for entry points treatment" ); 
     509        return -1; 
     510    } 
     511 
     512    if( strncmp( entries.psz_id, "ENTRYVCD", sizeof( entries.psz_id ) ) 
     513     && strncmp( entries.psz_id, "ENTRYSVD", sizeof( entries.psz_id ) )) 
     514    { 
     515        msg_Err( p_input, "unrecognized entry points format" ); 
     516        free( p_vcd->p_entries ); 
     517        return -1; 
     518    } 
     519 
     520    p_vcd->i_entries_nb = 0; 
     521 
     522#define i_track entries.entry[i].i_track 
     523    for( i = 0 ; i < i_nb ; i++ ) 
     524    { 
     525        if( i_track <= p_input->stream.i_area_nb ) 
     526        { 
     527            p_vcd->p_entries[i_entry_index] = 
     528                (MSF_TO_LBA2( BCD_TO_BIN( entries.entry[i].msf.minute ), 
     529                              BCD_TO_BIN( entries.entry[i].msf.second ), 
     530                              BCD_TO_BIN( entries.entry[i].msf.frame  ) )); 
     531            p_input->stream.pp_areas[i_track-1]->i_part_nb ++; 
     532            /* if this entry belongs to a new track */ 
     533            if( i_track != i_previous_track ) 
     534            { 
     535                /* i_plugin_data is used to store the first entry of the area*/ 
     536                p_input->stream.pp_areas[i_track-1]->i_plugin_data = 
     537                                                            i_entry_index; 
     538                i_previous_track = i_track; 
     539            } 
     540            i_entry_index ++; 
     541            p_vcd->i_entries_nb ++; 
     542        } 
     543        else 
     544            msg_Warn( p_input, "wrong track number found in entry points" ); 
     545    } 
     546#undef i_track 
     547    return 0; 
     548
  • modules/access/vcd/vcd.h

    r235dfe2 r2401b66  
    33 ***************************************************************************** 
    44 * Copyright (C) 1999-2001 VideoLAN 
    5  * $Id: vcd.h,v 1.2 2002/10/15 19:56:59 gbazin Exp $ 
     5 * $Id: vcd.h,v 1.3 2002/11/06 15:41:29 jobi Exp $ 
    66 * 
    77 * Author: Johan Bilien <jobi@via.ecp.fr> 
     
    3030/* size of a CD sector */ 
    3131#define CD_SECTOR_SIZE 2048 
     32/* sector containing the entry points */ 
     33#define VCD_ENTRIES_SECTOR 151 
     34 
     35/***************************************************************************** 
     36 * Misc. Macros 
     37 *****************************************************************************/ 
     38/* LBA = msf.frame + 75 * ( msf.second + 60 * msf.minute ) */ 
     39#define MSF_TO_LBA(min, sec, frame) ((int)frame + 75 * (sec + 60 * min)) 
     40/* LBA = msf.frame + 75 * ( msf.second - 2 + 60 * msf.minute ) */ 
     41#define MSF_TO_LBA2(min, sec, frame) ((int)frame + 75 * (sec -2 + 60 * min)) 
     42/* Converts BCD to Binary data */ 
     43#define BCD_TO_BIN(i) \ 
     44    ((uint8_t)(0xf & (uint8_t)i)+((uint8_t)10*((uint8_t)i >> 4))) 
    3245 
    3346#ifndef VCDDEV_T 
    3447typedef struct vcddev_s vcddev_t; 
    3548#endif 
     49 
     50/***************************************************************************** 
     51 * structure to store minute/second/frame locations 
     52 *****************************************************************************/ 
     53typedef struct msf_s 
     54{ 
     55    uint8_t minute; 
     56    uint8_t second; 
     57    uint8_t frame; 
     58} msf_t; 
     59 
     60 
     61/***************************************************************************** 
     62 * entries_sect structure: the sector containing entry points 
     63 *****************************************************************************/ 
     64typedef struct entries_sect_s 
     65{ 
     66    uint8_t psz_id[8];                              /* "ENTRYVCD" */ 
     67    uint8_t i_version;                              /* 0x02 VCD2.0 
     68                                                       0x01 SVCD  */ 
     69    uint8_t i_sys_prof_tag;                         /* 0x01 if VCD1.1 
     70                                                       0x00 else */ 
     71    uint16_t i_entries_nb;                          /* entries number <= 500 */ 
     72 
     73    struct 
     74    { 
     75        uint8_t i_track;                            /* track number */ 
     76        msf_t   msf;                                /* msf location 
     77                                                       (in BCD format) */ 
     78    } entry[500]; 
     79    uint8_t zeros[36];                              /* should be 0x00 */ 
     80} entries_sect_t; 
    3681 
    3782/***************************************************************************** 
     
    4287int       ioctl_GetTracksMap ( vlc_object_t *, const vcddev_t *, int ** ); 
    4388int       ioctl_ReadSector   ( vlc_object_t *, const vcddev_t *, 
    44                   int, byte_t * ); 
     89                               int, byte_t * ); 
  • modules/gui/gtk/gtk_callbacks.c

    r2799d36 r2401b66  
    33 ***************************************************************************** 
    44 * Copyright (C) 2000, 2001 VideoLAN 
    5  * $Id: gtk_callbacks.c,v 1.3 2002/09/30 11:05:39 sam Exp $ 
     5 * $Id: gtk_callbacks.c,v 1.4 2002/11/06 15:41:29 jobi Exp $ 
    66 * 
    77 * Authors: Samuel Hocevar <sam@zoy.org> 
     
    218218    p_intf = GtkGetIntf( button ); 
    219219 
     220    vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    220221    i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1; 
    221222 
     
    223224    { 
    224225        p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id]; 
     226        vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    225227        input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 
    226228 
     
    230232        vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    231233        GtkSetupMenus( p_intf ); 
    232         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    233     } 
     234    } 
     235    vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    234236} 
    235237 
     
    242244 
    243245    p_intf = GtkGetIntf( button ); 
     246    vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    244247    i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1; 
    245248 
     
    247250    { 
    248251        p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];    
     252        vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    249253        input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 
    250254 
     
    254258        vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    255259        GtkSetupMenus( p_intf ); 
    256         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    257     } 
     260    } 
     261    vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    258262} 
    259263 
     
    265269 
    266270    p_intf = GtkGetIntf( button ); 
     271    vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    267272    p_area = p_intf->p_sys->p_input->stream.p_selected_area; 
    268273 
     
    270275    { 
    271276        p_area->i_part--; 
     277        vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    272278        input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 
     279        vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
     280  
     281        input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); 
     282 
     283        p_intf->p_sys->b_chapter_update = 1; 
     284        GtkSetupMenus( p_intf ); 
     285    } 
     286    vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
     287} 
     288 
     289 
     290void GtkChapterNext( GtkButton * button, gpointer user_data ) 
     291{ 
     292    intf_thread_t * p_intf; 
     293    input_area_t *  p_area; 
     294 
     295    p_intf = GtkGetIntf( button ); 
     296    vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
     297    p_area = p_intf->p_sys->p_input->stream.p_selected_area; 
     298 
     299    if( p_area->i_part < p_area->i_part_nb ) 
     300    { 
     301        p_area->i_part++; 
     302        vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
     303        input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 
     304        vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    273305 
    274306        input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); 
     
    277309        vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    278310        GtkSetupMenus( p_intf ); 
    279         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    280     } 
    281 
    282  
    283  
    284 void GtkChapterNext( GtkButton * button, gpointer user_data ) 
    285 
    286     intf_thread_t * p_intf; 
    287     input_area_t *  p_area; 
    288  
    289     p_intf = GtkGetIntf( button ); 
    290     p_area = p_intf->p_sys->p_input->stream.p_selected_area; 
    291  
    292     if( p_area->i_part < p_area->i_part_nb ) 
    293     { 
    294         p_area->i_part++; 
    295         input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area ); 
    296  
    297         input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); 
    298  
    299         p_intf->p_sys->b_chapter_update = 1; 
    300         vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    301         GtkSetupMenus( p_intf ); 
    302         vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    303     } 
     311    } 
     312    vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock ); 
    304313} 
    305314