⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vcd.c

📁 VLC媒体播放程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    for ( i_index = 0 ; i_index < i_blocks ; i_index++ )    {        if ( ioctl_ReadSectors( VLC_OBJECT(p_input), p_vcd->vcddev,             p_vcd->i_sector, p_buffer + i_index * VCD_DATA_SIZE, 1,             VCD_TYPE ) < 0 )        {            msg_Err( p_input, "could not read sector %d", p_vcd->i_sector );            return -1;        }        p_vcd->i_sector ++;        if ( p_vcd->i_sector == p_vcd->p_sectors[p_vcd->i_track + 1] )        {            input_area_t *p_area;            if ( p_vcd->i_track >= p_vcd->i_nb_tracks - 1 )                return 0; /* EOF */            vlc_mutex_lock( &p_input->stream.stream_lock );            p_area = p_input->stream.pp_areas[                    p_input->stream.p_selected_area->i_id + 1 ];            msg_Dbg( p_input, "new title" );            p_area->i_part = 1;            VCDSetArea( p_input, p_area );            vlc_mutex_unlock( &p_input->stream.stream_lock );        }        /* Update chapter */        else if( p_vcd->b_valid_ep &&                /* FIXME kludge so that read does not update chapter                 * when a manual chapter change was requested and not                 * yet accomplished */                !p_input->stream.p_new_area )        {            int i_entry;            vlc_mutex_lock( &p_input->stream.stream_lock );            i_entry = p_input->stream.p_selected_area->i_plugin_data                /* 1st entry point of the track (area)*/                        + p_input->stream.p_selected_area->i_part - 1;            if( i_entry + 1 < p_vcd->i_entries_nb &&                    p_vcd->i_sector >= p_vcd->p_entries[i_entry + 1] )            {                vlc_value_t val;                msg_Dbg( p_input, "new chapter" );                p_input->stream.p_selected_area->i_part ++;                /* Update the navigation variables without triggering                 * a callback */                val.i_int = p_input->stream.p_selected_area->i_part;                var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL );            }            vlc_mutex_unlock( &p_input->stream.stream_lock );        }        i_read += VCD_DATA_SIZE;    }    if ( i_len % VCD_DATA_SIZE ) /* this should not happen */    {        if ( ioctl_ReadSectors( VLC_OBJECT(p_input), p_vcd->vcddev,             p_vcd->i_sector, p_last_sector, 1, VCD_TYPE ) < 0 )        {            msg_Err( p_input, "could not read sector %d", p_vcd->i_sector );            return -1;        }        p_input->p_vlc->pf_memcpy( p_buffer + i_blocks * VCD_DATA_SIZE,                                   p_last_sector, i_len % VCD_DATA_SIZE );        i_read += i_len % VCD_DATA_SIZE;    }    return i_read;}/***************************************************************************** * VCDSetProgram: Does nothing since a VCD is mono_program *****************************************************************************/static int VCDSetProgram( input_thread_t * p_input,                          pgrm_descriptor_t * p_program){    return 0;}/***************************************************************************** * VCDSetArea: initialize input data for title x, chapter y. * It should be called for each user navigation request. ****************************************************************************/static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area ){    thread_vcd_data_t *     p_vcd;    vlc_value_t val;    p_vcd = (thread_vcd_data_t*)p_input->p_access_data;    /* we can't use the interface slider until initilization is complete */    p_input->stream.b_seekable = 0;    if( p_area != p_input->stream.p_selected_area )    {        unsigned int i;        /* Reset the Chapter position of the current title */        p_input->stream.p_selected_area->i_part = 1;        p_input->stream.p_selected_area->i_tell = 0;        /* Change the default area */        p_input->stream.p_selected_area = p_area;        /* Change the current track */        /* The first track is not a valid one  */        p_vcd->i_track = p_area->i_id;        p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track];        /* Update the navigation variables without triggering a callback */        val.i_int = p_area->i_id;        var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );        var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );        for( i = 1; i <= p_area->i_part_nb; i++ )        {            val.i_int = i;            var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val, NULL );        }    }    if( p_vcd->b_valid_ep )    {        int i_entry = p_area->i_plugin_data /* 1st entry point of                                               the track (area)*/                            + p_area->i_part - 1;        p_vcd->i_sector = p_vcd->p_entries[i_entry];    }    else        p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track];    p_input->stream.p_selected_area->i_tell =        (off_t)p_vcd->i_sector * (off_t)VCD_DATA_SIZE         - p_input->stream.p_selected_area->i_start;    /* warn interface that something has changed */    p_input->stream.b_seekable = 1;    p_input->stream.b_changed = 1;    /* Update the navigation variables without triggering a callback */    val.i_int = p_area->i_part;    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL );    return 0;}/**************************************************************************** * VCDSeek ****************************************************************************/static void VCDSeek( input_thread_t * p_input, off_t i_off ){    thread_vcd_data_t * p_vcd;    unsigned int i_index;    p_vcd = (thread_vcd_data_t *) p_input->p_access_data;    p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track]                       + i_off / (off_t)VCD_DATA_SIZE;    vlc_mutex_lock( &p_input->stream.stream_lock );#define p_area p_input->stream.p_selected_area    /* Find chapter */    if( p_vcd->b_valid_ep )    {        for( i_index = 2 ; i_index <= p_area->i_part_nb; i_index ++ )        {            if( p_vcd->i_sector < p_vcd->p_entries[p_area->i_plugin_data                + i_index - 1] )            {                vlc_value_t val;                p_area->i_part = i_index - 1;                /* Update the navigation variables without triggering                 * a callback */                val.i_int = p_area->i_part;                var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL );                break;            }        }    }#undef p_area    p_input->stream.p_selected_area->i_tell =        (off_t)p_vcd->i_sector * (off_t)VCD_DATA_SIZE         - p_input->stream.p_selected_area->i_start;    vlc_mutex_unlock( &p_input->stream.stream_lock );}/***************************************************************************** * VCDEntryPoints: Reads the information about the entry points on the disc. *****************************************************************************/static int VCDEntryPoints( input_thread_t * p_input ){    thread_vcd_data_t *               p_vcd;    byte_t *                          p_sector;    entries_sect_t                    entries;    uint16_t                          i_nb;    int                               i, i_entry_index = 0;    int                               i_previous_track = -1;    p_vcd = (thread_vcd_data_t *) p_input->p_access_data;    p_sector = malloc( VCD_DATA_SIZE * sizeof( byte_t ) );    if( p_sector == NULL )    {        msg_Err( p_input, "not enough memory for entry points treatment" );        return -1;    }    if( ioctl_ReadSectors( VLC_OBJECT(p_input), p_vcd->vcddev,        VCD_ENTRIES_SECTOR, p_sector, 1, VCD_TYPE ) < 0 )    {        msg_Err( p_input, "could not read entry points sector" );        free( p_sector );        return( -1 );    }    memcpy( &entries, p_sector, CD_SECTOR_SIZE );    free( p_sector );    if( (i_nb = U16_AT( &entries.i_entries_nb )) > 500 )    {        msg_Err( p_input, "invalid entry points number" );        return( -1 );    }    p_vcd->p_entries = malloc( sizeof( int ) * i_nb );    if( p_vcd->p_entries == NULL )    {        msg_Err( p_input, "not enough memory for entry points treatment" );        return -1;    }    if( strncmp( entries.psz_id, "ENTRYVCD", sizeof( entries.psz_id ) )     && strncmp( entries.psz_id, "ENTRYSVD", sizeof( entries.psz_id ) ))    {        msg_Err( p_input, "unrecognized entry points format" );        free( p_vcd->p_entries );        return -1;    }    p_vcd->i_entries_nb = 0;#define i_track BCD_TO_BIN(entries.entry[i].i_track)    /* Reset the i_part_nb for each track */    for( i = 0 ; i < i_nb ; i++ )    {        if( i_track <= p_input->stream.i_area_nb )        {            p_input->stream.pp_areas[i_track-1]->i_part_nb = 0;        }    }    for( i = 0 ; i < i_nb ; i++ )    {        if( i_track <= p_input->stream.i_area_nb )        {            p_vcd->p_entries[i_entry_index] =                (MSF_TO_LBA2( BCD_TO_BIN( entries.entry[i].msf.minute ),                              BCD_TO_BIN( entries.entry[i].msf.second ),                              BCD_TO_BIN( entries.entry[i].msf.frame  ) ));            p_input->stream.pp_areas[i_track-1]->i_part_nb ++;            /* if this entry belongs to a new track */            if( i_track != i_previous_track )            {                /* i_plugin_data is used to store the first entry of the area*/                p_input->stream.pp_areas[i_track-1]->i_plugin_data =                                                            i_entry_index;                i_previous_track = i_track;            }            msg_Dbg( p_input, "entry point %i begins at LBA: %i",                     i_entry_index, p_vcd->p_entries[i_entry_index] );            i_entry_index ++;            p_vcd->i_entries_nb ++;        }        else            msg_Warn( p_input, "wrong track number found in entry points" );    }#undef i_track    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -