From 27fdfcfd6872d4868a8bef6f01ef4341fe033096 Mon Sep 17 00:00:00 2001 From: Rocky Bernstein Date: Sun, 19 Dec 2004 13:58:38 +0000 Subject: [PATCH] First attempt to libcdio VCD working under new regime. It is still mostly disabled or broken. --- modules/access/vcdx/Modules.am | 4 +- modules/access/vcdx/access.c | 1632 ++++++++++++------------------- modules/access/vcdx/cdrom.c | 10 +- modules/access/vcdx/cdrom.h | 2 +- modules/access/vcdx/demux.c | 14 +- modules/access/vcdx/info.c | 405 ++++++++ modules/access/vcdx/info.h | 39 + modules/access/vcdx/intf.h | 4 +- modules/access/vcdx/vcd.c | 23 +- modules/access/vcdx/vcd.h | 14 +- modules/access/vcdx/vcdplayer.c | 120 +-- modules/access/vcdx/vcdplayer.h | 73 +- 12 files changed, 1231 insertions(+), 1109 deletions(-) create mode 100644 modules/access/vcdx/info.c create mode 100644 modules/access/vcdx/info.h diff --git a/modules/access/vcdx/Modules.am b/modules/access/vcdx/Modules.am index 58af28076f..02bbe8ddc6 100644 --- a/modules/access/vcdx/Modules.am +++ b/modules/access/vcdx/Modules.am @@ -2,11 +2,11 @@ SOURCES_vcdx = \ access.c \ cdrom.c \ cdrom.h \ - demux.c \ - intf.c \ intf.h \ vcd.c \ vcd.h \ vcdplayer.h \ vcdplayer.c \ + info.c \ + info.h \ $(NULL) diff --git a/modules/access/vcdx/access.c b/modules/access/vcdx/access.c index 0664238502..9e03318955 100644 --- a/modules/access/vcdx/access.c +++ b/modules/access/vcdx/access.c @@ -7,7 +7,8 @@ * $Id$ * * Authors: Rocky Bernstein - * Johan Bilien + * Some code is based on the non-libcdio VCD plugin (as there really + * isn't real documentation yet.) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,13 +30,14 @@ *****************************************************************************/ #include -#include #include +#include -#include "../../demux/mpeg/system.h" #include "vcd.h" #include "vcdplayer.h" #include "intf.h" +#include "info.h" +#include "vlc_keys.h" #include #include @@ -48,34 +50,37 @@ /* how many blocks VCDRead will read in each loop */ #define VCD_BLOCKS_ONCE 20 -#define VCD_DATA_ONCE (VCD_BLOCKS_ONCE * M2F2_SECTOR_SIZE) - -#define VCD_MRL_PREFIX "vcdx://" /***************************************************************************** * Local prototypes *****************************************************************************/ /* First those which are accessed from outside (via pointers). */ -static int VCDRead ( input_thread_t *, byte_t *, size_t ); -static int VCDSetProgram ( input_thread_t *, pgrm_descriptor_t * ); +static block_t *VCDReadBlock ( access_t * ); + +static int VCDControl ( access_t *p_access, int i_query, + va_list args ); /* Now those which are strictly internal */ -static void VCDSetOrigin ( input_thread_t *, lsn_t origin_lsn, - lsn_t cur_lsn, lsn_t end_lsn, - int cur_entry, track_t track ); -static int VCDEntryPoints ( input_thread_t * ); -static int VCDLIDs ( input_thread_t * ); -static int VCDSegments ( input_thread_t * ); -static void VCDTracks ( input_thread_t * ); +static void VCDSetOrigin ( access_t *p_access, + lsn_t origin_lsn, + lsn_t i_lsn, lsn_t end_lsn, + track_t track, + const vcdinfo_itemid_t * p_itemid ); +static int VCDEntryPoints ( access_t * ); +static int VCDLIDs ( access_t * ); +#ifdef FIXED +static int VCDSegments ( access_t * ); +#endif +static int VCDTitles ( access_t * ); static int VCDReadSector ( vlc_object_t *p_this, - const vcdinfo_obj_t *p_vcd, lsn_t cur_lsn, + const vcdinfo_obj_t *p_vcd, lsn_t i_lsn, byte_t * p_buffer ); -static char *VCDParse ( input_thread_t *, +static char *VCDParse ( access_t *, /*out*/ vcdinfo_itemid_t * p_itemid , /*out*/ vlc_bool_t *play_single_item ); -static void VCDUpdateVar( input_thread_t *p_input, int i_entry, int i_action, +static void VCDUpdateVar( access_t *p_access, int i_entry, int i_action, const char *p_varname, char *p_label, const char *p_debug_label ); @@ -88,28 +93,28 @@ static vcdinfo_obj_t *vcd_Open ( vlc_object_t *p_this, const char *psz_dev ); /* FIXME: This variable is a hack. Would be nice to eliminate the global-ness. */ -static input_thread_t *p_vcd_input = NULL; +static access_t *p_vcd_access = NULL; /* process messages that originate from libcdio. */ static void cdio_log_handler (cdio_log_level_t level, const char message[]) { - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data; + const access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; switch (level) { case CDIO_LOG_DEBUG: case CDIO_LOG_INFO: if (p_vcd->i_debug & INPUT_DBG_CDIO) - msg_Dbg( p_vcd_input, message); + msg_Dbg( p_vcd_access, message); break; case CDIO_LOG_WARN: - msg_Warn( p_vcd_input, message); + msg_Warn( p_vcd_access, message); break; case CDIO_LOG_ERROR: case CDIO_LOG_ASSERT: - msg_Err( p_vcd_input, message); + msg_Err( p_vcd_access, message); break; default: - msg_Warn( p_vcd_input, message, + msg_Warn( p_vcd_access, message, _("The above message had unknown log level"), level); } @@ -120,22 +125,22 @@ cdio_log_handler (cdio_log_level_t level, const char message[]) static void vcd_log_handler (vcd_log_level_t level, const char message[]) { - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data; + access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; switch (level) { case VCD_LOG_DEBUG: case VCD_LOG_INFO: if (p_vcd->i_debug & INPUT_DBG_VCDINFO) - msg_Dbg( p_vcd_input, message); + msg_Dbg( p_vcd_access, message); break; case VCD_LOG_WARN: - msg_Warn( p_vcd_input, message); + msg_Warn( p_vcd_access, message); break; case VCD_LOG_ERROR: case VCD_LOG_ASSERT: - msg_Err( p_vcd_input, message); + msg_Err( p_vcd_access, message); break; default: - msg_Warn( p_vcd_input, "%s\n%s %d", message, + msg_Warn( p_vcd_access, "%s\n%s %d", message, _("The above message had unknown vcdimager log level"), level); } @@ -143,16 +148,15 @@ vcd_log_handler (vcd_log_level_t level, const char message[]) } /***************************************************************************** - * VCDRead: reads i_len bytes from the VCD into p_buffer. - ***************************************************************************** - * Returns -1 in case of error, 0 in case of EOF, otherwise the number of - * bytes. + VCDRead: reads VCD_BLOCKS_ONCE from the VCD and returns that. + NULL is returned if something went wrong. *****************************************************************************/ -static int -VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) +static block_t * +VCDReadBlock( access_t * p_access ) { - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; - int i_blocks; + access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; + block_t *p_block; + int i_blocks = VCD_BLOCKS_ONCE; int i_index; int i_read; byte_t p_last_sector[ M2F2_SECTOR_SIZE ]; @@ -160,40 +164,47 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) i_read = 0; dbg_print( (INPUT_DBG_CALL), "lsn: %lu", - (long unsigned int) p_vcd->cur_lsn ); + (long unsigned int) p_vcd->i_lsn ); /* Compute the number of blocks we have to read */ - i_blocks = i_len / M2F2_SECTOR_SIZE; + i_blocks = VCD_BLOCKS_ONCE ; + + /* Allocate a block for the reading */ + if( !( p_block = block_New( p_access, i_blocks * M2F2_SECTOR_SIZE ) ) ) + { + msg_Err( p_access, "cannot get a new block of size: %i", + i_blocks * M2F2_SECTOR_SIZE ); + block_Release( p_block ); + return NULL; + } for ( i_index = 0 ; i_index < i_blocks ; i_index++ ) { - if ( p_vcd->cur_lsn == p_vcd->end_lsn ) { + if ( p_vcd->i_lsn == p_vcd->end_lsn ) { vcdplayer_read_status_t read_status; /* We've run off of the end of this entry. Do we continue or stop? */ dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "end reached, cur: %lu", - (long unsigned int) p_vcd->cur_lsn ); + (long unsigned int) p_vcd->i_lsn ); read_status = vcdplayer_pbc_is_on( p_vcd ) - ? vcdplayer_pbc_nav( p_input ) - : vcdplayer_non_pbc_nav( p_input ); + ? vcdplayer_pbc_nav( p_access ) + : vcdplayer_non_pbc_nav( p_access ); switch (read_status) { case READ_END: /* End reached. Return NULL to indicated this. */ case READ_ERROR: /* Some sort of error. */ - return i_read; + return NULL; case READ_STILL_FRAME: { /* Reached the end of a still frame. */ - - byte_t * p_buf = p_buffer; - pgrm_descriptor_t * p_pgrm = p_input->stream.p_selected_program;; + byte_t * p_buf = (byte_t *) p_block->p_buffer; p_buf += (i_index*M2F2_SECTOR_SIZE); memset(p_buf, 0, M2F2_SECTOR_SIZE); @@ -201,24 +212,10 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) *p_buf = 0x01; dbg_print(INPUT_DBG_STILL, "Handled still event"); -#if 1 - p_vcd->p_intf->p_sys->b_still = 1; - var_SetInteger( p_input, "state", PAUSE_S ); -#endif - - vlc_mutex_lock( &p_input->stream.stream_lock ); - - p_pgrm = p_input->stream.p_selected_program; - p_pgrm->i_synchro_state = SYNCHRO_REINIT; - - vlc_mutex_unlock( &p_input->stream.stream_lock ); - - input_ClockManageControl( p_input, p_pgrm, 0 ); + p_vcd->p_intf->p_sys->b_still = VLC_TRUE; + var_SetInteger( p_access, "state", PAUSE_S ); - p_vcd->p_intf->p_sys->b_still = 1; - var_SetInteger( p_input, "state", PAUSE_S ); - - return i_read + M2F2_SECTOR_SIZE; + return p_block; } default: case READ_BLOCK: @@ -226,206 +223,115 @@ VCDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_len ) } } - if ( VCDReadSector( VLC_OBJECT(p_input), p_vcd->vcd, - p_vcd->cur_lsn, - p_buffer + (i_index*M2F2_SECTOR_SIZE) ) < 0 ) + if ( VCDReadSector( VLC_OBJECT(p_access), p_vcd->vcd, + p_vcd->i_lsn, + (byte_t *) p_block->p_buffer + (i_index*M2F2_SECTOR_SIZE) ) < 0 ) { LOG_ERR ("could not read sector %lu", - (long unsigned int) p_vcd->cur_lsn ); - return -1; + (long unsigned int) p_vcd->i_lsn ); + return NULL; } - p_vcd->cur_lsn ++; - - /* Update chapter */ - 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 ) - { - unsigned int i_entry = p_input->stream.p_selected_area->i_part; - - vlc_mutex_lock( &p_input->stream.stream_lock ); + p_vcd->i_lsn ++; - if( i_entry < p_vcd->num_entries && - p_vcd->cur_lsn >= p_vcd->p_entries[i_entry+1] ) - { - dbg_print( INPUT_DBG_PBC, - "new entry, i_entry %d, sector %lu, es %u", - i_entry, (long unsigned int) p_vcd->cur_lsn, - p_vcd->p_entries[i_entry] ); - p_vcd->play_item.num = - ++ p_input->stream.p_selected_area->i_part; - p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; - VCDUpdateVar( p_input, p_vcd->play_item.num, VLC_VAR_SETVALUE, - "chapter", _("Entry"), "Setting entry" ); - } - vlc_mutex_unlock( &p_input->stream.stream_lock ); - } - - i_read += M2F2_SECTOR_SIZE; } - if ( i_len % M2F2_SECTOR_SIZE ) /* this should not happen */ + if ( i_index != i_blocks ) /* this should not happen */ { - if ( VCDReadSector( VLC_OBJECT(p_input), p_vcd->vcd, - p_vcd->cur_lsn, p_last_sector ) < 0 ) + if ( VCDReadSector( VLC_OBJECT(p_access), p_vcd->vcd, + p_vcd->i_lsn, p_last_sector ) < 0 ) { LOG_ERR ("could not read sector %lu", - (long unsigned int) p_vcd->cur_lsn ); - return -1; + (long unsigned int) p_vcd->i_lsn ); } - - p_input->p_vlc->pf_memcpy( p_buffer + i_blocks * M2F2_SECTOR_SIZE, - p_last_sector, i_len % M2F2_SECTOR_SIZE ); - i_read += i_len % M2F2_SECTOR_SIZE; + + return NULL; } - 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) -{ - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; - dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "VCDSetProgram" ); - return 0; -} - - -/***************************************************************************** - * VCDSetArea: initialize internal data structures and input stream data - so set subsequent reading and seeking to reflect that we are - at track x, entry or segment y. - This is called for each user navigation request, e.g. the GUI - Chapter/Title selections or in initial MRL parsing. - ****************************************************************************/ -int -VCDSetArea( input_thread_t * p_input, input_area_t * p_area ) -{ - thread_vcd_data_t *p_vcd = (thread_vcd_data_t*)p_input->p_access_data; - unsigned int i_entry = p_area->i_part; - track_t i_track = p_area->i_id; - int old_seekable = p_input->stream.b_seekable; - unsigned int i_nb = p_area->i_plugin_data + p_area->i_part_nb; - - dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), - "track: %d, entry %d, seekable %d, area %lx, select area %lx ", - i_track, i_entry, old_seekable, - (long unsigned int) p_area, - (long unsigned int) p_input->stream.p_selected_area ); - - /* 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 ) + /* Update seekpoints */ + for( i_read = 0; i_read < i_blocks; i_read++ ) { - unsigned int i; - - /* If is the result of a track change, make the entry valid. */ - if (i_entry < p_area->i_plugin_data || i_entry >= i_nb) - i_entry = p_area->i_plugin_data; - - /* Change the default area */ - p_input->stream.p_selected_area = p_area; + input_title_t *t = p_vcd->p_title[p_access->info.i_title]; - /* Update the navigation variables without triggering a callback */ - - VCDUpdateVar( p_input, i_track, VLC_VAR_SETVALUE, "title", - _("Track"), "Setting track"); - - var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL ); - for( i = p_area->i_plugin_data; i < i_nb; i++ ) + if( t->i_seekpoint > 0 && + p_access->info.i_seekpoint + 1 < t->i_seekpoint && + p_access->info.i_pos + i_read * M2F2_SECTOR_SIZE >= + t->seekpoint[p_access->info.i_seekpoint+1]->i_byte_offset ) { - VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE, - "chapter", - p_vcd->play_item.type == VCDINFO_ITEM_TYPE_SEGMENT ? - _("Segment"): _("Entry"), - "Adding entry choice"); + msg_Dbg( p_access, "seekpoint change" ); + p_access->info.i_update |= INPUT_UPDATE_SEEKPOINT; + p_access->info.i_seekpoint++; } - - if (p_vcd->b_svd) { - unsigned int audio_type = - vcdinfo_get_track_audio_type(p_vcd->vcd, i_track); - unsigned int i_channels = - vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type); - - var_Change( p_input, "audio_channels", VLC_VAR_CLEARCHOICES, NULL, - NULL ); - - for( i = 0; i < i_channels; i++ ) - { - VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE, - "audio_channels", NULL, "Adding audio choice"); - } - } - } - if (i_track == 0) - VCDSetOrigin( p_input, p_vcd->p_segments[i_entry], - p_vcd->p_segments[i_entry], p_vcd->p_segments[i_entry+1], - i_entry, 0 ); - else - VCDSetOrigin( p_input, p_vcd->p_sectors[i_track], - vcdinfo_get_entry_lsn(p_vcd->vcd, i_entry), - p_vcd->p_sectors[i_track+1], - i_entry, i_track ); + /* Update a few values */ + p_vcd->i_lsn += i_blocks; + p_access->info.i_pos += p_block->i_buffer; - p_input->stream.b_seekable = old_seekable; - /* warn interface that something has changed */ - p_input->stream.b_changed = 1; - - return VLC_SUCCESS; + return p_block; } /**************************************************************************** * VCDSeek ****************************************************************************/ -void -VCDSeek( input_thread_t * p_input, off_t i_off ) +int +VCDSeek( access_t * p_access, int64_t i_pos ) { - thread_vcd_data_t * p_vcd; - unsigned int i_entry=0; /* invalid entry */ - - p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - - p_vcd->cur_lsn = p_vcd->origin_lsn + (i_off / (off_t)M2F2_SECTOR_SIZE); - - vlc_mutex_lock( &p_input->stream.stream_lock ); -#define p_area p_input->stream.p_selected_area - /* Find entry */ - if( p_vcd->b_valid_ep ) + if (!p_access || !p_access->p_sys) return VLC_EGENERIC; + { - for( i_entry = 0 ; i_entry < p_vcd->num_entries ; i_entry ++ ) - { - if( p_vcd->cur_lsn < p_vcd->p_entries[i_entry] ) - { - VCDUpdateVar( p_input, i_entry, VLC_VAR_SETVALUE, - "chapter", _("Entry"), "Setting entry" ); - break; - } - } - p_vcd->play_item.num = p_area->i_part = i_entry; - p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; - } -#undef p_area - - p_input->stream.p_selected_area->i_tell = i_off; - - dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK), - "orig %lu, cur: %lu, offset: %lld, start: %lld, entry %d", - (long unsigned int) p_vcd->origin_lsn, - (long unsigned int) p_vcd->cur_lsn, i_off, - p_input->stream.p_selected_area->i_start, i_entry ); + access_vcd_data_t *p_vcd = + (access_vcd_data_t *)p_vcd_access->p_sys; + const input_title_t *t = p_vcd->p_title[p_access->info.i_title]; + int i_seekpoint; + unsigned int i_entry=VCDINFO_INVALID_ENTRY; + + /* Next sector to read */ + p_access->info.i_pos = i_pos; + p_vcd->i_lsn = (i_pos / (int64_t)M2F2_SECTOR_SIZE) + + p_vcd->origin_lsn; + + /* Find entry */ + if( p_vcd->b_valid_ep ) + { + for( i_entry = 0 ; i_entry < p_vcd->i_entries ; i_entry ++ ) + { + if( p_vcd->i_lsn < p_vcd->p_entries[i_entry] ) + { + VCDUpdateVar( p_access, i_entry, VLC_VAR_SETVALUE, + "chapter", _("Entry"), "Setting entry" ); + break; + } + } + p_vcd->play_item.num = i_entry; + p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; + } + + /* Find seekpoint */ + for( i_seekpoint = 0; i_seekpoint < t->i_seekpoint; i_seekpoint++ ) + { + if( i_seekpoint + 1 >= t->i_seekpoint ) break; + if( i_pos < t->seekpoint[i_seekpoint + 1]->i_byte_offset ) break; + } + + /* Update current seekpoint */ + if( i_seekpoint != p_access->info.i_seekpoint ) + { + msg_Dbg( p_access, "seekpoint change" ); + p_access->info.i_update |= INPUT_UPDATE_SEEKPOINT; + p_access->info.i_seekpoint = i_seekpoint; + } - vlc_mutex_unlock( &p_input->stream.stream_lock ); + dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_SEEK), + "orig %lu, cur: %lu, offset: %lld, entry %d", + (long unsigned int) p_vcd->origin_lsn, + (long unsigned int) p_vcd->i_lsn, i_pos, + i_entry ); + + } + return VLC_SUCCESS; + } /***************************************************************************** @@ -436,147 +342,149 @@ VCDSeek( input_thread_t * p_input, off_t i_off ) for differences in numbering. *****************************************************************************/ int -VCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid ) +VCDPlay( access_t *p_access, vcdinfo_itemid_t itemid ) { - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; - input_area_t * p_area; - vlc_bool_t b_was_still; - - dbg_print(INPUT_DBG_CALL, "itemid.num: %d, itemid.type: %d\n", - itemid.num, itemid.type); - - if (!p_input->p_access_data) return VLC_EGENERIC; + if (!p_access || !p_access->p_sys) return VLC_EGENERIC; - b_was_still = p_vcd->in_still; - -#define area p_input->stream.pp_areas - - switch (itemid.type) { - case VCDINFO_ITEM_TYPE_TRACK: - - /* Valid tracks go from 1...num_tracks-1, because track 0 is unplayable. - */ - - if (itemid.num == 0 || itemid.num >= p_vcd->num_tracks) { - LOG_ERR ("Invalid track number %d", itemid.num ); - return VLC_EGENERIC; - } - p_vcd->in_still = VLC_FALSE; - p_area = area[itemid.num]; - p_area->i_part = p_area->i_plugin_data; - p_input->stream.b_seekable = 1; - break; - case VCDINFO_ITEM_TYPE_SEGMENT: - /* Valid segments go from 0...num_segments-1. */ - if (itemid.num >= p_vcd->num_segments) { - LOG_ERR ( "Invalid segment number: %d", itemid.num ); - return VLC_EGENERIC; - } else { - vcdinfo_video_segment_type_t segtype = - vcdinfo_get_video_type(p_vcd->vcd, itemid.num); - - dbg_print(INPUT_DBG_PBC, "%s (%d), seg_num: %d", - vcdinfo_video_type2str(p_vcd->vcd, itemid.num), - (int) segtype, itemid.num); - - p_area = area[0]; - p_area->i_part = itemid.num; - - switch (segtype) - { - case VCDINFO_FILES_VIDEO_NTSC_STILL: - case VCDINFO_FILES_VIDEO_NTSC_STILL2: - case VCDINFO_FILES_VIDEO_PAL_STILL: - case VCDINFO_FILES_VIDEO_PAL_STILL2: - p_input->stream.b_seekable = 0; - p_vcd->in_still = VLC_TRUE; - break; - default: - p_input->stream.b_seekable = 1; - p_vcd->in_still = VLC_FALSE; - } - } - break; - - case VCDINFO_ITEM_TYPE_LID: - /* LIDs go from 1..num_lids. */ - if (itemid.num == 0 || itemid.num > p_vcd->num_lids) { - LOG_ERR ( "Invalid LID number: %d", itemid.num ); - return VLC_EGENERIC; - } else { - p_vcd->cur_lid = itemid.num; - vcdinfo_lid_get_pxd(p_vcd->vcd, &(p_vcd->pxd), itemid.num); - - switch (p_vcd->pxd.descriptor_type) { - - case PSD_TYPE_SELECTION_LIST: - case PSD_TYPE_EXT_SELECTION_LIST: { - vcdinfo_itemid_t trans_itemid; - uint16_t trans_itemid_num; - - if (p_vcd->pxd.psd == NULL) return VLC_EGENERIC; - trans_itemid_num = vcdinf_psd_get_itemid(p_vcd->pxd.psd); - vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); - p_vcd->loop_count = 1; - p_vcd->loop_item = trans_itemid; - return VCDPlay( p_input, trans_itemid ); - break; - } - - case PSD_TYPE_PLAY_LIST: { - if (p_vcd->pxd.pld == NULL) return VLC_EGENERIC; - p_vcd->pdi = -1; - return vcdplayer_inc_play_item(p_input) - ? VLC_SUCCESS : VLC_EGENERIC; - break; - } + { + + access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; +#if 0 + const vlc_bool_t b_was_still = p_vcd->in_still; +#endif + + dbg_print(INPUT_DBG_CALL, "itemid.num: %d, itemid.type: %d\n", + itemid.num, itemid.type); - case PSD_TYPE_END_LIST: - case PSD_TYPE_COMMAND_LIST: + switch (itemid.type) { + case VCDINFO_ITEM_TYPE_TRACK: + + { + track_t i_track = itemid.num; + unsigned int i_entry = + vcdinfo_track_get_entry( p_vcd->vcd, i_track); + + /* Valid tracks go from 1...i_tracks-1, because track 0 is + unplayable. */ + + if (i_track == 0 || i_track >= p_vcd->i_tracks) { + LOG_ERR ("Invalid track number %d", i_track ); + return VLC_EGENERIC; + } + p_vcd->in_still = VLC_FALSE; + VCDSetOrigin( p_access, p_vcd->p_sectors[i_track], + vcdinfo_get_entry_lsn(p_vcd->vcd, i_entry), + p_vcd->p_sectors[i_track+1], + i_track, &itemid ); + break; + } + + case VCDINFO_ITEM_TYPE_SEGMENT: + { + int i_seg = itemid.num; + + /* Valid segments go from 0...i_segments-1. */ + if (itemid.num >= p_vcd->i_segments) { + LOG_ERR ( "Invalid segment number: %d", i_seg ); + return VLC_EGENERIC; + } else { + vcdinfo_video_segment_type_t segtype = + vcdinfo_get_video_type(p_vcd->vcd, i_seg); + + dbg_print(INPUT_DBG_PBC, "%s (%d), seg_num: %d", + vcdinfo_video_type2str(p_vcd->vcd, i_seg), + (int) segtype, itemid.num); + + switch (segtype) + { + case VCDINFO_FILES_VIDEO_NTSC_STILL: + case VCDINFO_FILES_VIDEO_NTSC_STILL2: + case VCDINFO_FILES_VIDEO_PAL_STILL: + case VCDINFO_FILES_VIDEO_PAL_STILL2: + p_vcd->in_still = VLC_TRUE; + break; + default: + p_vcd->in_still = VLC_FALSE; + } + VCDSetOrigin( p_access, p_vcd->p_segments[i_seg], + p_vcd->p_segments[i_seg], + p_vcd->p_segments[i_seg+1], + 0, &itemid ); + } - default: - ; - } - } - return VLC_EGENERIC; - case VCDINFO_ITEM_TYPE_ENTRY: - /* Entries go from 0..num_entries-1. */ - if (itemid.num >= p_vcd->num_entries) { - LOG_ERR ("Invalid entry number: %d", itemid.num ); - return VLC_EGENERIC; - } else { - track_t cur_track = vcdinfo_get_track(p_vcd->vcd, itemid.num); - p_vcd->in_still = VLC_FALSE; - p_area = area[cur_track]; - p_area->i_part = itemid.num; - p_input->stream.b_seekable = 1; + } + break; + + case VCDINFO_ITEM_TYPE_LID: + /* LIDs go from 1..i_lids. */ + if (itemid.num == 0 || itemid.num > p_vcd->i_lids) { + LOG_ERR ( "Invalid LID number: %d", itemid.num ); + return VLC_EGENERIC; + } else { + p_vcd->i_lid = itemid.num; + vcdinfo_lid_get_pxd(p_vcd->vcd, &(p_vcd->pxd), itemid.num); + + switch (p_vcd->pxd.descriptor_type) { + + case PSD_TYPE_SELECTION_LIST: + case PSD_TYPE_EXT_SELECTION_LIST: { + vcdinfo_itemid_t trans_itemid; + uint16_t trans_itemid_num; + + if (p_vcd->pxd.psd == NULL) return VLC_EGENERIC; + trans_itemid_num = vcdinf_psd_get_itemid(p_vcd->pxd.psd); + vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); + p_vcd->loop_count = 1; + p_vcd->loop_item = trans_itemid; + return VCDPlay( p_access, trans_itemid ); + break; + } + + case PSD_TYPE_PLAY_LIST: { + if (p_vcd->pxd.pld == NULL) return VLC_EGENERIC; + p_vcd->pdi = -1; + return vcdplayer_inc_play_item(p_access) + ? VLC_SUCCESS : VLC_EGENERIC; + break; + } + + case PSD_TYPE_END_LIST: + case PSD_TYPE_COMMAND_LIST: + + default: + ; + } + } + return VLC_EGENERIC; + case VCDINFO_ITEM_TYPE_ENTRY: + { + int i_entry = itemid.num; + + /* Entries go from 0..i_entries-1. */ + if (itemid.num >= p_vcd->i_entries) { + LOG_ERR ("Invalid entry number: %d", i_entry ); + return VLC_EGENERIC; + } else { + track_t i_track = vcdinfo_get_track(p_vcd->vcd, i_entry); + p_vcd->in_still = VLC_FALSE; + VCDSetOrigin( p_access, p_vcd->p_sectors[i_track], + vcdinfo_get_entry_lsn(p_vcd->vcd, i_entry), + p_vcd->p_sectors[i_track+1], + i_track, &itemid ); + } + break; + } + + default: + LOG_ERR ("unknown entry type" ); + return VLC_EGENERIC; } - break; - default: - LOG_ERR ("unknown entry type" ); - return VLC_EGENERIC; - } - - VCDSetArea( p_input, p_area ); - -#undef area -#if 1 - if ( p_vcd->in_still != b_was_still ) { - if (p_input->stream.pp_selected_es) { - var_SetInteger( p_input, "state", PLAYING_S ); - } + p_vcd->play_item = itemid; + } -#endif - - p_vcd->play_item = itemid; - - dbg_print( (INPUT_DBG_CALL), - "i_start %lld, i_size: %lld, i_tell: %lld, lsn %lu", - p_area->i_start, p_area->i_size, - p_area->i_tell, - (long unsigned int) p_vcd->cur_lsn ); - + + return VLC_SUCCESS; } @@ -586,78 +494,81 @@ VCDPlay( input_thread_t *p_input, vcdinfo_itemid_t itemid ) Before calling this track information should have been read in. *****************************************************************************/ static int -VCDEntryPoints( input_thread_t * p_input ) +VCDEntryPoints( access_t * p_access ) { - thread_vcd_data_t * p_vcd; - unsigned int i_nb; - unsigned int i, i_entry_index = 0; - unsigned int i_previous_track = CDIO_INVALID_TRACK; - - p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - - i_nb = vcdinfo_get_num_entries(p_vcd->vcd); - if (0 == i_nb) - return -1; - - p_vcd->p_entries = malloc( sizeof( lba_t ) * i_nb ); - - if( p_vcd->p_entries == NULL ) - { - LOG_ERR ("not enough memory for entry points treatment" ); - return -1; + if (!p_access || !p_access->p_sys) return VLC_EGENERIC; + + { + access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + const unsigned int i_entries = vcdinfo_get_num_entries(p_vcd->vcd); + const track_t i_last_track + = cdio_get_num_tracks(vcdinfo_get_cd_image(p_vcd->vcd)) + + cdio_get_first_track_num(vcdinfo_get_cd_image(p_vcd->vcd)); + unsigned int i; + + if (0 == i_entries) { + LOG_ERR ("no entires found -- something is wrong" ); + return VLC_EGENERIC; } - - p_vcd->num_entries = 0; - - for( i = 0 ; i < i_nb ; i++ ) + + p_vcd->p_entries = malloc( sizeof( lsn_t ) * i_entries ); + + if( p_vcd->p_entries == NULL ) + { + LOG_ERR ("not enough memory for entry points treatment" ); + return VLC_EGENERIC; + } + + p_vcd->i_entries = i_entries; + + for( i = 0 ; i < i_entries ; i++ ) { - track_t i_track = vcdinfo_get_track(p_vcd->vcd, i); - if( i_track <= p_input->stream.i_area_nb ) - { - p_vcd->p_entries[i] = - vcdinfo_get_entry_lsn(p_vcd->vcd, i); - p_input->stream.pp_areas[i_track]->i_part_nb ++; + const track_t i_track = vcdinfo_get_track(p_vcd->vcd, i); + if( i_track <= i_last_track ) { + seekpoint_t *s = vlc_seekpoint_New(); + char psz_entry[100]; + + snprintf(psz_entry, sizeof(psz_entry), "%s%02d", _("Entry "), i ); - /* 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]->i_plugin_data = - i_entry_index; - i_previous_track = i_track; - p_input->stream.pp_areas[i_track]->i_part_nb = 1; - } - i_entry_index ++; - p_vcd->num_entries ++; - } - else - msg_Warn( p_input, "wrong track number found in entry points" ); + p_vcd->p_entries[i] = vcdinfo_get_entry_lsn(p_vcd->vcd, i); + + s->psz_name = strdup(psz_entry); + s->i_byte_offset = (p_vcd->p_entries[i] - p_vcd->p_sectors[i_track]) + * M2F2_SECTOR_SIZE; + + TAB_APPEND( p_vcd->p_title[i_track-1]->i_seekpoint, + p_vcd->p_title[i_track-1]->seekpoint, s ); + } else + msg_Warn( p_access, "wrong track number found in entry points" ); } p_vcd->b_valid_ep = VLC_TRUE; return 0; + } } +/*????? FIXME!!! */ +#ifdef FIXED /***************************************************************************** * VCDSegments: Reads the information about the segments the disc. *****************************************************************************/ static int -VCDSegments( input_thread_t * p_input ) +VCDSegments( access_t * p_access ) { - thread_vcd_data_t * p_vcd; + access_vcd_data_t * p_vcd; unsigned int i; - unsigned int num_segments; + unsigned int i_segments; - p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - num_segments = p_vcd->num_segments = vcdinfo_get_num_segments(p_vcd->vcd); + p_vcd = (access_vcd_data_t *) p_access->p_sys; + i_segments = p_vcd->num_segments = vcdinfo_get_num_segments(p_vcd->vcd); -#define area p_input->stream.pp_areas +#define area p_access->stream.pp_areas /* area 0 is reserved for segments. Set Absolute start offset and size */ area[0]->i_plugin_data = 0; - input_DelArea( p_input, area[0] ); - input_AddArea( p_input, 0, 0 ); + input_DelArea( p_access, area[0] ); + input_AddArea( p_access, 0, 0 ); area[0]->i_start = (off_t)p_vcd->p_sectors[0] * (off_t)M2F2_SECTOR_SIZE; @@ -677,12 +588,12 @@ VCDSegments( input_thread_t * p_input ) "area[0] id: %d, i_start: %lld, i_size: %lld", area[0]->i_id, area[0]->i_start, area[0]->i_size ); - if (num_segments == 0) return 0; + if (i_segments == 0) return 0; /* We have one additional segment allocated so we can get the size by subtracting seg[i+1] - seg[i]. */ - p_vcd->p_segments = malloc( sizeof( lba_t ) * (num_segments+1) ); + p_vcd->p_segments = malloc( sizeof( lsn_t ) * (i_segments+1) ); if( p_vcd->p_segments == NULL ) { LOG_ERR ("not enough memory for segment treatment" ); @@ -690,82 +601,85 @@ VCDSegments( input_thread_t * p_input ) } /* Update the navigation variables without triggering a callback */ - VCDUpdateVar( p_input, 0, VLC_VAR_SETVALUE, "title", _("Track"), + VCDUpdateVar( p_access, 0, VLC_VAR_SETVALUE, "title", _("Track"), "Setting track" ); - var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL ); + var_Change( p_access, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL ); - for( i = 0 ; i < num_segments ; i++ ) + for( i = 0 ; i < i_segments ; i++ ) { p_vcd->p_segments[i] = vcdinfo_get_seg_lsn(p_vcd->vcd, i); area[0]->i_part_nb ++; - VCDUpdateVar( p_input, i , VLC_VAR_ADDCHOICE, + VCDUpdateVar( p_access, i , VLC_VAR_ADDCHOICE, "chapter", _("Segment"), "Adding segment choice"); } #undef area - p_vcd->p_segments[num_segments] = p_vcd->p_segments[num_segments-1]+ - vcdinfo_get_seg_sector_count(p_vcd->vcd, num_segments-1); + p_vcd->p_segments[i_segments] = p_vcd->p_segments[i_segments-1]+ + vcdinfo_get_seg_sector_count(p_vcd->vcd, i_segments-1); return 0; } +#endif /***************************************************************************** - VCDTracks: initializes area information. - Before calling this track information should have been read in. + Build title table which will be returned via ACCESS_GET_TITLE_INFO. + + We start area addressing for tracks at 1 since the default area 0 + is reserved for segments. *****************************************************************************/ -static void -VCDTracks( input_thread_t * p_input ) +static int +VCDTitles( access_t * p_access ) { - thread_vcd_data_t * p_vcd; - unsigned int i; - - p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - -#define area p_input->stream.pp_areas - - /* We start area addressing for tracks at 1 since the default area 0 - is reserved for segments */ + /* We'll assume a VCD has its first MPEG track + cdio_get_first_track_num()+1 could be used if one wanted to be + very careful about this. Note: cdio_get_first_track() will give the + ISO-9660 track before the MPEG tracks. + */ + const unsigned int i_first_mpeg_track=2; + + if (!p_access || !p_access->p_sys) return VLC_EGENERIC; - for( i = 1 ; i < p_vcd->num_tracks ; i++ ) { - /* Tracks are Program Chains */ - input_AddArea( p_input, i, i ); - - /* Absolute start byte offset and byte size */ - area[i]->i_start = (off_t) p_vcd->p_sectors[i] - * (off_t)M2F2_SECTOR_SIZE; - area[i]->i_size = (off_t)(p_vcd->p_sectors[i+1] - p_vcd->p_sectors[i]) - * (off_t)M2F2_SECTOR_SIZE; + access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + track_t i; - /* Current entry being played in track */ - area[i]->i_part = 0; - - /* i_plugin_data is used to store which entry point is the first - * of the track (area) */ - area[i]->i_plugin_data = 0; - - dbg_print( INPUT_DBG_MRL, - "area[%d] id: %d, i_start: %lld, i_size: %lld", - i, area[i]->i_id, area[i]->i_start, area[i]->i_size ); + p_vcd->i_titles = 0; + for( i = 2 ; i <= p_vcd->i_tracks ; i++ ) + { + input_title_t *t = p_vcd->p_title[i - i_first_mpeg_track] + = vlc_input_title_New(); + char psz_track[100]; + uint32_t i_secsize = + cdio_get_track_sec_count( vcdinfo_get_cd_image(p_vcd->vcd), i ); + + snprintf(psz_track, sizeof(psz_track), "%s%02d", _("Track "), + i-1 ); + + t->i_size = (i_secsize) * (int64_t) M2F2_SECTOR_SIZE; + t->psz_name = strdup(psz_track); + + dbg_print( INPUT_DBG_MRL, "track[%d] i_size: %lld", + i, t->i_size ); + + p_vcd->i_titles++; + } + + return VLC_SUCCESS; } - -#undef area - - return ; } /***************************************************************************** VCDLIDs: Reads the LIST IDs from the LOT. *****************************************************************************/ static int -VCDLIDs( input_thread_t * p_input ) +VCDLIDs( access_t * p_access ) { - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data; + access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; - p_vcd->num_lids = vcdinfo_get_num_LIDs(p_vcd->vcd); - p_vcd->cur_lid = VCDINFO_INVALID_ENTRY; + p_vcd->i_lids = vcdinfo_get_num_LIDs(p_vcd->vcd); + p_vcd->i_lid = VCDINFO_INVALID_ENTRY; if (vcdinfo_read_psd (p_vcd->vcd)) { @@ -784,7 +698,7 @@ VCDLIDs( input_thread_t * p_input ) } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_MRL), - "num LIDs=%d", p_vcd->num_lids); + "num LIDs=%d", p_vcd->i_lids); return 0; } @@ -793,15 +707,15 @@ VCDLIDs( input_thread_t * p_input ) * VCDParse: parse command line *****************************************************************************/ static char * -VCDParse( input_thread_t * p_input, /*out*/ vcdinfo_itemid_t * p_itemid, +VCDParse( access_t * p_access, /*out*/ vcdinfo_itemid_t * p_itemid, /*out*/ vlc_bool_t *play_single_item ) { - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_access->p_sys; char * psz_parser; char * psz_source; char * psz_next; - if( config_GetInt( p_input, MODULE_STRING "-PBC" ) ) { + if( config_GetInt( p_access, MODULE_STRING "-PBC" ) ) { p_itemid->type = VCDINFO_ITEM_TYPE_LID; p_itemid->num = 1; *play_single_item = VLC_FALSE; @@ -815,15 +729,15 @@ VCDParse( input_thread_t * p_input, /*out*/ vcdinfo_itemid_t * p_itemid, #ifdef WIN32 /* On Win32 we want the VCD access plugin to be explicitly requested, * we end up with lots of problems otherwise */ - if( !p_input->psz_access || !*p_input->psz_access ) return NULL; + if( !p_access->psz_access || !*p_access->psz_access ) return NULL; #endif - if( !p_input->psz_name ) + if( !p_access->psz_path ) { return NULL; } - psz_parser = psz_source = strdup( p_input->psz_name ); + psz_parser = psz_source = strdup( p_access->psz_path ); /* Parse input string : * [device][@[type][title]] */ @@ -881,9 +795,9 @@ VCDParse( input_thread_t * p_input, /*out*/ vcdinfo_itemid_t * p_itemid, if( !*psz_source ) { /* No source specified, so figure it out. */ - if( !p_input->psz_access ) return NULL; + if( !p_access->psz_access ) return NULL; - psz_source = config_GetPsz( p_input, "vcd" ); + psz_source = config_GetPsz( p_access, "vcd" ); if( !psz_source || 0==strlen(psz_source) ) { /* Scan for a CD-ROM drive with a VCD in it. */ @@ -913,30 +827,33 @@ VCDParse( input_thread_t * p_input, /*out*/ vcdinfo_itemid_t * p_itemid, Set's start origin subsequent seeks/reads */ static void -VCDSetOrigin( input_thread_t *p_input, lsn_t origin_lsn, - lsn_t cur_lsn, lsn_t end_lsn, int cur_entry, track_t cur_track ) +VCDSetOrigin( access_t *p_access, lsn_t origin_lsn, + lsn_t i_lsn, lsn_t end_lsn, track_t i_track, + const vcdinfo_itemid_t *p_itemid ) { - thread_vcd_data_t * p_vcd = (thread_vcd_data_t *) p_input->p_access_data; + access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; p_vcd->origin_lsn = origin_lsn; - p_vcd->cur_lsn = cur_lsn; + p_vcd->i_lsn = i_lsn; p_vcd->end_lsn = end_lsn; - p_vcd->cur_track = cur_track; - p_vcd->play_item.num = cur_entry; - p_vcd->play_item.type = VCDINFO_ITEM_TYPE_ENTRY; + p_vcd->i_track = i_track; + p_vcd->play_item.num = p_itemid->num; + p_vcd->play_item.type = p_itemid->type; + + p_access->info.i_title = i_track-1; + p_access->info.i_seekpoint = p_itemid->num; + p_access->info.i_size = p_vcd->p_title[i_track]->i_size; + p_access->info.i_pos = ( i_lsn - origin_lsn ) * M2F2_SECTOR_SIZE; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_LSN), - "origin: %lu, cur_lsn: %lu, end_lsn: %lu, entry: %d, track: %d", + "origin: %lu, cur_lsn: %lu, end_lsn: %lu, track: %d", (long unsigned int) origin_lsn, - (long unsigned int) cur_lsn, - (long unsigned int) end_lsn, cur_entry, cur_track ); + (long unsigned int) i_lsn, + (long unsigned int) end_lsn, i_track ); - p_input->stream.p_selected_area->i_tell = - (off_t) (p_vcd->cur_lsn - p_vcd->origin_lsn) * (off_t)M2F2_SECTOR_SIZE; - - VCDUpdateVar( p_input, cur_entry, VLC_VAR_SETVALUE, + VCDUpdateVar( p_access, p_itemid->num, VLC_VAR_SETVALUE, "chapter", - p_vcd->play_item.type == VCDINFO_ITEM_TYPE_ENTRY ? + p_itemid->type == VCDINFO_ITEM_TYPE_ENTRY ? _("Entry") : _("Segment"), "Setting entry/segment"); } @@ -968,21 +885,21 @@ vcd_Open( vlc_object_t *p_this, const char *psz_dev ) ****************************************************************************/ static int VCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd, - lsn_t cur_lsn, byte_t * p_buffer ) + lsn_t i_lsn, byte_t * p_buffer ) { typedef struct { - uint8_t subheader [8]; + uint8_t subheader [CDIO_CD_SUBHEADER_SIZE]; uint8_t data [M2F2_SECTOR_SIZE]; uint8_t spare [4]; } vcdsector_t; vcdsector_t vcd_sector; if( cdio_read_mode2_sector( vcdinfo_get_cd_image( p_vcd ), - &vcd_sector, cur_lsn, VLC_TRUE ) + &vcd_sector, i_lsn, VLC_TRUE ) != 0) { msg_Warn( p_this, "Could not read LSN %lu", - (long unsigned int) cur_lsn ); + (long unsigned int) i_lsn ); return -1; } @@ -995,399 +912,24 @@ VCDReadSector( vlc_object_t *p_this, const vcdinfo_obj_t *p_vcd, Update the "varname" variable to i_num without triggering a callback. ****************************************************************************/ static void -VCDUpdateVar( input_thread_t *p_input, int i_num, int i_action, +VCDUpdateVar( access_t *p_access, int i_num, int i_action, const char *p_varname, char *p_label, const char *p_debug_label) { vlc_value_t val; val.i_int = i_num; - if (NULL != p_vcd_input) { - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data; + if (p_access) { + const access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; dbg_print( INPUT_DBG_PBC, "%s %d", p_debug_label, i_num ); } if (p_label) { vlc_value_t text; text.psz_string = p_label; - var_Change( p_input, p_varname, VLC_VAR_SETTEXT, &text, NULL ); - } - var_Change( p_input, p_varname, i_action, &val, NULL ); -} - - -static inline void -MetaInfoAddStr(input_thread_t *p_input, char *p_cat, - char *title, const char *str) -{ - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - if ( str ) { - dbg_print( INPUT_DBG_META, "field: %s: %s\n", title, str); - input_Control( p_input, INPUT_ADD_INFO, p_cat, title, "%s", str); - } -} - - -static inline void -MetaInfoAddNum(input_thread_t *p_input, char *p_cat, char *title, int num) -{ - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - dbg_print( INPUT_DBG_META, "field %s: %d\n", title, num); - input_Control( p_input, INPUT_ADD_INFO, p_cat, title, "%d", num ); -} - -#define addstr(title, str) \ - MetaInfoAddStr( p_input, p_cat, title, str ); - -#define addnum(title, num) \ - MetaInfoAddNum( p_input, p_cat, title, num ); - -static void InformationCreate( input_thread_t *p_input ) -{ - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *) p_input->p_access_data; - unsigned int i_nb = vcdinfo_get_num_entries(p_vcd->vcd); - unsigned int last_entry = 0; - char *p_cat; - track_t i_track; - - p_cat = _("General"); - - addstr( _("VCD Format"), vcdinfo_get_format_version_str(p_vcd->vcd) ); - addstr( _("Album"), vcdinfo_get_album_id(p_vcd->vcd)); - addstr( _("Application"), vcdinfo_get_application_id(p_vcd->vcd) ); - addstr( _("Preparer"), vcdinfo_get_preparer_id(p_vcd->vcd) ); - addnum( _("Vol #"), vcdinfo_get_volume_num(p_vcd->vcd) ); - addnum( _("Vol max #"), vcdinfo_get_volume_count(p_vcd->vcd) ); - addstr( _("Volume Set"), vcdinfo_get_volumeset_id(p_vcd->vcd) ); - addstr( _("Volume"), vcdinfo_get_volume_id(p_vcd->vcd) ); - addstr( _("Publisher"), vcdinfo_get_publisher_id(p_vcd->vcd) ); - addstr( _("System Id"), vcdinfo_get_system_id(p_vcd->vcd) ); - addnum( "LIDs", vcdinfo_get_num_LIDs(p_vcd->vcd) ); - addnum( _("Entries"), vcdinfo_get_num_entries(p_vcd->vcd) ); - addnum( _("Segments"), vcdinfo_get_num_segments(p_vcd->vcd) ); - addnum( _("Tracks"), vcdinfo_get_num_tracks(p_vcd->vcd) ); - - /* Spit out track information. Could also include MSF info. - */ - -#define TITLE_MAX 30 - for( i_track = 1 ; i_track < p_vcd->num_tracks ; i_track++ ) { - char psz_track[TITLE_MAX]; - unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcd->vcd, - i_track); - snprintf(psz_track, TITLE_MAX, "%s%02d", _("Track "), i_track); - p_cat = psz_track; - - if (p_vcd->b_svd) { - addnum(_("Audio Channels"), - vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type) ); - } - - addnum(_("First Entry Point"), last_entry ); - for ( ; last_entry < i_nb - && vcdinfo_get_track(p_vcd->vcd, last_entry) == i_track; - last_entry++ ) ; - addnum(_("Last Entry Point"), last_entry-1 ); - } -} - -#define add_format_str_info(val) \ - { \ - const char *str = val; \ - unsigned int len; \ - if (val != NULL) { \ - len=strlen(str); \ - if (len != 0) { \ - strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \ - tp += len; \ - } \ - saw_control_prefix = VLC_FALSE; \ - } \ - } - -#define add_format_num_info( val, fmt ) \ - { \ - char num_str[10]; \ - unsigned int len; \ - sprintf(num_str, fmt, val); \ - len = strlen(num_str); \ - if( len != 0 ) \ - { \ - strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \ - tp += len; \ - } \ - saw_control_prefix = VLC_FALSE; \ - } - -/*! - Take a format string and expand escape sequences, that is sequences that - begin with %, with information from the current VCD. - The expanded string is returned. Here is a list of escape sequences: - - %A : The album information - %C : The VCD volume count - the number of CD's in the collection. - %c : The VCD volume num - the number of the CD in the collection. - %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD - %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT... - %L : The playlist ID prefixed with " LID" if it exists - %M : MRL - %N : The current number of the %I - a decimal number - %P : The publisher ID - %p : The preparer ID - %S : If we are in a segment (menu), the kind of segment - %T : The track number - %V : The volume set ID - %v : The volume ID - A number between 1 and the volume count. - %% : a % -*/ -static char * -VCDFormatStr(const input_thread_t *p_input, thread_vcd_data_t *p_vcd, - const char format_str[], const char *mrl, - const vcdinfo_itemid_t *itemid) -{ -#define TEMP_STR_SIZE 256 -#define TEMP_STR_LEN (TEMP_STR_SIZE-1) - static char temp_str[TEMP_STR_SIZE]; - size_t i; - char * tp = temp_str; - vlc_bool_t saw_control_prefix = VLC_FALSE; - size_t format_len = strlen(format_str); - - memset(temp_str, 0, TEMP_STR_SIZE); - - for (i=0; ivcd), - MAX_ALBUM_LEN)); - break; - - case 'c': - add_format_num_info(vcdinfo_get_volume_num(p_vcd->vcd), "%d"); - break; - - case 'C': - add_format_num_info(vcdinfo_get_volume_count(p_vcd->vcd), "%d"); - break; - - case 'F': - add_format_str_info(vcdinfo_get_format_version_str(p_vcd->vcd)); - break; - - case 'I': - { - switch (itemid->type) { - case VCDINFO_ITEM_TYPE_TRACK: - strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(_("Track")); - break; - case VCDINFO_ITEM_TYPE_ENTRY: - strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(_("Entry")); - break; - case VCDINFO_ITEM_TYPE_SEGMENT: - strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(_("Segment")); - break; - case VCDINFO_ITEM_TYPE_LID: - strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(_("List ID")); - break; - case VCDINFO_ITEM_TYPE_SPAREID2: - strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(_("Navigation")); - break; - default: - /* What to do? */ - ; - } - saw_control_prefix = VLC_FALSE; - } - break; - - case 'L': - if (vcdplayer_pbc_is_on(p_vcd)) { - char num_str[40]; - sprintf(num_str, "%s %d", _("List ID"), p_vcd->cur_lid); - strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(num_str); - } - saw_control_prefix = VLC_FALSE; - break; - - case 'M': - add_format_str_info(mrl); - break; - - case 'N': - add_format_num_info(itemid->num, "%d"); - break; - - case 'p': - add_format_str_info(vcdinfo_get_preparer_id(p_vcd->vcd)); - break; - - case 'P': - add_format_str_info(vcdinfo_get_publisher_id(p_vcd->vcd)); - break; - - case 'S': - if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) { - char seg_type_str[10]; - - sprintf(seg_type_str, " %s", - vcdinfo_video_type2str(p_vcd->vcd, itemid->num)); - strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str)); - tp += strlen(seg_type_str); - } - saw_control_prefix = VLC_FALSE; - break; - - case 'T': - add_format_num_info(p_vcd->cur_track, "%d"); - break; - - case 'V': - add_format_str_info(vcdinfo_get_volumeset_id(p_vcd->vcd)); - break; - - case 'v': - add_format_str_info(vcdinfo_get_volume_id(p_vcd->vcd)); - break; - - default: - *tp++ = '%'; - *tp++ = format_str[i]; - saw_control_prefix = VLC_FALSE; - } - } - return strdup(temp_str); -} - -static void -VCDCreatePlayListItem(const input_thread_t *p_input, - thread_vcd_data_t *p_vcd, - playlist_t *p_playlist, - const vcdinfo_itemid_t *itemid, - char *psz_mrl, int psz_mrl_max, - const char *psz_source, int playlist_operation, - int i_pos) -{ - char *p_author; - char *p_title; - char c_type; - - switch(itemid->type) { - case VCDINFO_ITEM_TYPE_TRACK: - c_type='T'; - break; - case VCDINFO_ITEM_TYPE_SEGMENT: - c_type='S'; - break; - case VCDINFO_ITEM_TYPE_LID: - c_type='P'; - break; - case VCDINFO_ITEM_TYPE_ENTRY: - c_type='E'; - break; - default: - c_type='?'; - break; + var_Change( p_access, p_varname, VLC_VAR_SETTEXT, &text, NULL ); } - - snprintf(psz_mrl, psz_mrl_max, "%s%s@%c%u", VCD_MRL_PREFIX, psz_source, - c_type, itemid->num); - - p_title = - VCDFormatStr( p_input, p_vcd, - config_GetPsz( p_input, MODULE_STRING "-title-format" ), - psz_mrl, itemid ); - - playlist_Add( p_playlist, psz_mrl, p_title, playlist_operation, i_pos ); - - p_author = - VCDFormatStr( p_input, p_vcd, - config_GetPsz( p_input, MODULE_STRING "-author-format" ), - psz_mrl, itemid ); - - if( i_pos == PLAYLIST_END ) i_pos = p_playlist->i_size - 1; - playlist_AddInfo(p_playlist, i_pos, _("General"), _("Author"), "%s", - p_author); + var_Change( p_access, p_varname, i_action, &val, NULL ); } -static int -VCDFixupPlayList( input_thread_t *p_input, thread_vcd_data_t *p_vcd, - const char *psz_source, vcdinfo_itemid_t *itemid, - vlc_bool_t play_single_item ) -{ - unsigned int i; - playlist_t * p_playlist; - char * psz_mrl; - unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + strlen(psz_source) + - strlen("@T") + strlen("100") + 1; - - psz_mrl = malloc( psz_mrl_max ); - - if( psz_mrl == NULL ) - { - msg_Warn( p_input, "out of memory" ); - return -1; - } - - p_playlist = (playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); - if( !p_playlist ) - { - msg_Warn( p_input, "can't find playlist" ); - free(psz_mrl); - return -1; - } - - if ( play_single_item ) - { - /* May fill out more information when the playlist user interface becomes - more mature. - */ - VCDCreatePlayListItem(p_input, p_vcd, p_playlist, itemid, - psz_mrl, psz_mrl_max, psz_source, PLAYLIST_REPLACE, - p_playlist->i_index); - - } - else - { - vcdinfo_itemid_t list_itemid; - list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY; - - playlist_LockDelete( p_playlist, p_playlist->i_index); - - for( i = 0 ; i < p_vcd->num_entries ; i++ ) - { - list_itemid.num=i; - VCDCreatePlayListItem(p_input, p_vcd, p_playlist, &list_itemid, - psz_mrl, psz_mrl_max, psz_source, - PLAYLIST_APPEND, PLAYLIST_END); - } - - playlist_Command( p_playlist, PLAYLIST_GOTO, 0 ); - - } - - vlc_object_release( p_playlist ); - free(psz_mrl); - return 0; -} /***************************************************************************** * Public routines. @@ -1396,14 +938,14 @@ int E_(DebugCallback) ( vlc_object_t *p_this, const char *psz_name, vlc_value_t oldval, vlc_value_t val, void *p_data ) { - thread_vcd_data_t *p_vcd; + access_vcd_data_t *p_vcd; - if (NULL == p_vcd_input) return VLC_EGENERIC; + if (NULL == p_vcd_access) return VLC_EGENERIC; - p_vcd = (thread_vcd_data_t *)p_vcd_input->p_access_data; + p_vcd = (access_vcd_data_t *)p_vcd_access->p_sys; if (p_vcd->i_debug & (INPUT_DBG_CALL|INPUT_DBG_EXT)) { - msg_Dbg( p_vcd_input, "Old debug (x%0x) %d, new debug (x%0x) %d", + msg_Dbg( p_vcd_access, "Old debug (x%0x) %d, new debug (x%0x) %d", p_vcd->i_debug, p_vcd->i_debug, val.i_int, val.i_int); } p_vcd->i_debug = val.i_int; @@ -1411,35 +953,8 @@ E_(DebugCallback) ( vlc_object_t *p_this, const char *psz_name, } -/* - The front-ends change spu-es - which sort of represents a symbolic - name. Internally we use spu-channel which runs from 0..3. - - So we add a callback to intercept changes to spu-es and change them - to updates to spu-channel. Ugly. - -*/ - -static int -VCDSPUCallback( vlc_object_t *p_this, const char *psz_variable, - vlc_value_t old_val, vlc_value_t new_val, void *param) -{ - - input_thread_t *p_input = (input_thread_t *)p_this; - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data; - vlc_value_t val; - - dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EVENT), "old_val: %x, new_val %x", - old_val.i_int, new_val.i_int); - - val.i_int = new_val.i_int; - var_Set( p_this, "spu-channel", val ); - - return VLC_SUCCESS; -} - /***************************************************************************** - Open: open VCD. + VCDOpen: open VCD. read in meta-information about VCD: the number of tracks, segments, entries, size and starting information. Then set up state variables so that we read/seek starting at the location specified. @@ -1448,21 +963,28 @@ VCDSPUCallback( vlc_object_t *p_this, const char *psz_variable, and VLC_EGENERIC for some other error. *****************************************************************************/ int -E_(Open) ( vlc_object_t *p_this ) +E_(VCDOpen) ( vlc_object_t *p_this ) { - input_thread_t * p_input = (input_thread_t *)p_this; - thread_vcd_data_t * p_vcd; + access_t * p_access = (access_t *)p_this; + access_vcd_data_t * p_vcd; char * psz_source; vcdinfo_itemid_t itemid; vlc_bool_t b_play_ok; vlc_bool_t play_single_item = VLC_FALSE; - p_input->pf_read = VCDRead; - p_input->pf_seek = VCDSeek; - p_input->pf_set_area = VCDSetArea; - p_input->pf_set_program = VCDSetProgram; + p_access->pf_read = NULL; + p_access->pf_block = VCDReadBlock; + p_access->pf_control = VCDControl; + p_access->pf_seek = VCDSeek; + + p_access->info.i_update = 0; + p_access->info.i_size = 0; + p_access->info.i_pos = 0; + p_access->info.b_eof = VLC_FALSE; + p_access->info.i_title = 0; + p_access->info.i_seekpoint = 0; - p_vcd = malloc( sizeof(thread_vcd_data_t) ); + p_vcd = malloc( sizeof(access_vcd_data_t) ); if( p_vcd == NULL ) { @@ -1470,17 +992,21 @@ E_(Open) ( vlc_object_t *p_this ) return VLC_ENOMEM; } - p_input->p_access_data = (void *)p_vcd; + p_access->p_sys = (access_sys_t *) p_vcd; + p_vcd->i_debug = config_GetInt( p_this, MODULE_STRING "-debug" ); p_vcd->in_still = VLC_FALSE; p_vcd->play_item.type = VCDINFO_ITEM_TYPE_NOTFOUND; + p_vcd->p_input = vlc_object_find( p_access, VLC_OBJECT_INPUT, + FIND_PARENT ); + p_vcd->p_meta = vlc_meta_New(); /* Set where to log errors messages from libcdio. */ - p_vcd_input = (input_thread_t *)p_this; + p_vcd_access = p_access; cdio_log_set_handler ( cdio_log_handler ); vcd_log_set_handler ( vcd_log_handler ); - psz_source = VCDParse( p_input, &itemid, &play_single_item ); + psz_source = VCDParse( p_access, &itemid, &play_single_item ); if ( NULL == psz_source ) { @@ -1489,109 +1015,86 @@ E_(Open) ( vlc_object_t *p_this ) } dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "source: %s: mrl: %s", - psz_source, p_input->psz_name ); + psz_source, p_access->psz_path ); p_vcd->p_segments = NULL; p_vcd->p_entries = NULL; /* set up input */ - p_input->i_mtu = VCD_DATA_ONCE; - - vlc_mutex_lock( &p_input->stream.stream_lock ); - - /* If we are here we can control the pace... */ - p_input->stream.b_pace_control = 1; - - p_input->stream.b_seekable = 1; - p_input->stream.p_selected_area->i_size = 0; - p_input->stream.p_selected_area->i_tell = 0; - - vlc_mutex_unlock( &p_input->stream.stream_lock ); if( !(p_vcd->vcd = vcd_Open( p_this, psz_source )) ) { - msg_Warn( p_input, "could not open %s", psz_source ); + msg_Warn( p_access, "could not open %s", psz_source ); goto err_exit; } p_vcd->b_svd= (vlc_bool_t) vcdinfo_get_tracksSVD(p_vcd->vcd);; /* Get track information. */ - p_vcd->num_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_input), - vcdinfo_get_cd_image(p_vcd->vcd), - &p_vcd->p_sectors ); - if( p_vcd->num_tracks < 0 ) - LOG_ERR ("unable to count tracks" ); - else if( p_vcd->num_tracks <= 1 ) - LOG_ERR ("no movie tracks found" ); - if( p_vcd->num_tracks <= 1) - { + p_vcd->i_tracks = ioctl_GetTracksMap( VLC_OBJECT(p_access), + vcdinfo_get_cd_image(p_vcd->vcd), + &p_vcd->p_sectors ); + if( p_vcd->i_tracks <= 1 ) { vcdinfo_close( p_vcd->vcd ); + LOG_ERR ("no movie tracks found" ); goto err_exit; } - - /* Set stream and area data */ - vlc_mutex_lock( &p_input->stream.stream_lock ); - - /* Initialize ES structures */ - input_InitStream( p_input, sizeof( stream_ps_data_t ) ); - - /* disc input method */ - p_input->stream.i_method = INPUT_METHOD_VCD; - - p_input->stream.i_area_nb = 1; - - + +#ifdef FIXED /* Initialize segment information. */ - VCDSegments( p_input ); + VCDSegments( p_access ); +#endif - /* Initialize track area information. */ - VCDTracks( p_input ); + /* Build Navigation Title table. */ + VCDTitles( p_access ); - if( VCDEntryPoints( p_input ) < 0 ) + /* Map entry points into Chapters */ + if( VCDEntryPoints( p_access ) < 0 ) { - msg_Warn( p_input, "could not read entry points, will not use them" ); + msg_Warn( p_access, "could not read entry points, will not use them" ); p_vcd->b_valid_ep = VLC_FALSE; } - if( VCDLIDs( p_input ) < 0 ) + if( VCDLIDs( p_access ) < 0 ) { - msg_Warn( p_input, "could not read entry LIDs" ); + msg_Warn( p_access, "could not read entry LIDs" ); } - b_play_ok = (VLC_SUCCESS == VCDPlay( p_input, itemid )); - - vlc_mutex_unlock( &p_input->stream.stream_lock ); +#if FIXED + b_play_ok = (VLC_SUCCESS == VCDPlay( p_access, itemid )); if ( ! b_play_ok ) { vcdinfo_close( p_vcd->vcd ); goto err_exit; } - - if( !p_input->psz_demux || !*p_input->psz_demux ) - { -#if FIXED - p_input->psz_demux = "vcdx"; -#else - p_input->psz_demux = "ps"; +#else + /* We assume playing CD track 2 (1st MPEG data) for now */ + + p_vcd->origin_lsn = p_vcd->i_lsn = p_vcd->p_sectors[1]; + p_access->info.i_title = 0; + p_access->info.i_seekpoint = 0; + p_access->info.i_size = p_vcd->p_title[0]->i_size; + p_access->info.i_pos = 0; + #endif - } - p_vcd->p_intf = intf_Create( p_input, "vcdx" ); + p_access->psz_demux = strdup( "ps" ); + +#if FIXED + p_vcd->p_intf = intf_Create( p_access, "vcdx" ); p_vcd->p_intf->b_block = VLC_FALSE; intf_RunThread( p_vcd->p_intf ); +#endif - InformationCreate( p_input ); - +#if FIXED if (play_single_item) - VCDFixupPlayList( p_input, p_vcd, psz_source, &itemid, + VCDFixupPlayList( p_access, p_vcd, psz_source, &itemid, play_single_item ); +#endif + free( psz_source ); - var_AddCallback( p_this, "spu-es", VCDSPUCallback, NULL ); - - return VLC_SUCCESS; err_exit: free( psz_source ); @@ -1600,17 +1103,16 @@ E_(Open) ( vlc_object_t *p_this ) } /***************************************************************************** - * Close: closes VCD releasing allocated memory. + * VCDClose: closes VCD releasing allocated memory. *****************************************************************************/ void -E_(Close) ( vlc_object_t *p_this ) +E_(VCDClose) ( vlc_object_t *p_this ) { - input_thread_t * p_input = (input_thread_t *)p_this; - thread_vcd_data_t *p_vcd = (thread_vcd_data_t *)p_input->p_access_data; + access_t *p_access = (access_t *)p_this; + access_vcd_data_t *p_vcd = (access_vcd_data_t *)p_access->p_sys; dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT), "VCDClose" ); - var_DelCallback( p_this, "spu-es", VCDSPUCallback, NULL ); vcdinfo_close( p_vcd->vcd ); free( p_vcd->p_entries ); @@ -1627,6 +1129,164 @@ E_(Close) ( vlc_object_t *p_this ) } free( p_vcd ); - p_input->p_access_data = NULL; - p_vcd_input = NULL; + p_access->p_sys = NULL; + p_vcd_access = NULL; +} + +/***************************************************************************** + * Control: The front-end or vlc engine calls here to ether get + * information such as meta information or plugin capabilities or to + * issue miscellaneous "set" requests. + *****************************************************************************/ +static int VCDControl( access_t *p_access, int i_query, va_list args ) +{ + access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; + int *pi_int; + int i; + + dbg_print( (INPUT_DBG_CALL|INPUT_DBG_EXT|INPUT_DBG_EVENT), + "query %d", i_query ); + + switch( i_query ) + { + /* Pass back a copy of meta information that was gathered when we + during the Open/Initialize call. + */ + case ACCESS_GET_META: + { + vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** ); + + dbg_print( INPUT_DBG_EVENT, "get meta info" ); + + if ( p_vcd->p_meta ) { + *pp_meta = vlc_meta_Duplicate( p_vcd->p_meta ); + dbg_print( INPUT_DBG_META, "%s", "Meta copied" ); + } else + msg_Warn( p_access, "tried to copy NULL meta info" ); + + return VLC_SUCCESS; + } + return VLC_EGENERIC; + + case ACCESS_CAN_SEEK: + case ACCESS_CAN_FASTSEEK: + case ACCESS_CAN_PAUSE: + case ACCESS_CAN_CONTROL_PACE: + { + vlc_bool_t *pb_bool = (vlc_bool_t*)va_arg( args, vlc_bool_t* ); + + dbg_print( INPUT_DBG_EVENT, + "seek/fastseek/pause/can_control_pace" ); + *pb_bool = VLC_TRUE; + return VLC_SUCCESS; + break; + } + + /* */ + case ACCESS_GET_MTU: + pi_int = (int*)va_arg( args, int * ); + *pi_int = (VCD_BLOCKS_ONCE * M2F2_SECTOR_SIZE); + dbg_print( INPUT_DBG_EVENT, "GET MTU: %d", *pi_int ); + break; + + case ACCESS_GET_PTS_DELAY: + { + int64_t *pi_64 = (int64_t*)va_arg( args, int64_t * ); + *pi_64 = var_GetInteger( p_access, MODULE_STRING "-caching" ) + * MILLISECONDS_PER_SEC; + dbg_print( INPUT_DBG_EVENT, "GET PTS DELAY" ); + return VLC_SUCCESS; + break; + } + + /* */ + case ACCESS_SET_PAUSE_STATE: + dbg_print( INPUT_DBG_EVENT, "SET PAUSE STATE" ); + return VLC_SUCCESS; + break; + + case ACCESS_GET_TITLE_INFO: + { + input_title_t ***ppp_title; + unsigned int i; + + ppp_title = (input_title_t***)va_arg( args, input_title_t*** ); + pi_int = (int*)va_arg( args, int* ); + + dbg_print( INPUT_DBG_EVENT, "GET TITLE: i_titles %d", + p_vcd->i_titles ); + + VCDMetaInfo( p_access ); + + /* Duplicate title info */ + if( p_vcd->i_titles == 0 ) + { + *pi_int = 0; ppp_title = NULL; + return VLC_SUCCESS; + } + *pi_int = p_vcd->i_titles; + *ppp_title = malloc(sizeof( input_title_t **) * p_vcd->i_titles ); + + if (!*ppp_title) return VLC_ENOMEM; + + for( i = 0; i < p_vcd->i_titles; i++ ) + { + if ( p_vcd->p_title[i] ) + (*ppp_title)[i] = + vlc_input_title_Duplicate( p_vcd->p_title[i] ); + } + + + return VLC_SUCCESS; + } + break; + + case ACCESS_SET_TITLE: + i = (int)va_arg( args, int ); + + dbg_print( INPUT_DBG_EVENT, "set title %d" , i); + if( i != p_access->info.i_title ) + { + /* Update info */ + p_access->info.i_update |= + INPUT_UPDATE_TITLE|INPUT_UPDATE_SIZE; + p_access->info.i_title = i; + p_access->info.i_size = p_vcd->p_title[i]->i_size; + p_access->info.i_pos = 0; + + /* Next sector to read */ + p_vcd->i_lsn = p_vcd->p_sectors[i]; + } + break; + + case ACCESS_SET_SEEKPOINT: + { + input_title_t *t = p_vcd->p_title[p_access->info.i_title]; + i = (int)va_arg( args, int ); + if( t->i_seekpoint > 0 ) + { + p_access->info.i_update |= INPUT_UPDATE_SEEKPOINT; + p_access->info.i_seekpoint = i; + + p_vcd->i_lsn = p_vcd->p_sectors[1+p_access->info.i_title] + + t->seekpoint[i]->i_byte_offset / M2F2_SECTOR_SIZE; + + p_access->info.i_pos = + (int64_t)(p_vcd->i_lsn - + p_vcd->p_sectors[1+p_access->info.i_title]) + * M2F2_SECTOR_SIZE; + } + return VLC_SUCCESS; + } + + case ACCESS_SET_PRIVATE_ID_STATE: + dbg_print( INPUT_DBG_EVENT, "set seekpoint/set private id" ); + return VLC_EGENERIC; + + default: + msg_Warn( p_access, "unimplemented query in control" ); + return VLC_EGENERIC; + + } + return VLC_SUCCESS; } diff --git a/modules/access/vcdx/cdrom.c b/modules/access/vcdx/cdrom.c index dba99e60a3..bf17b7b6ec 100644 --- a/modules/access/vcdx/cdrom.c +++ b/modules/access/vcdx/cdrom.c @@ -95,13 +95,15 @@ void ioctl_Close( cddev_t *p_cddev ) * This makes finding the end of the last track uniform * how it is done for other tracks. *****************************************************************************/ -track_t ioctl_GetTracksMap( vlc_object_t *p_this, const CdIo *cdio, +track_t ioctl_GetTracksMap( vlc_object_t *p_this, const CdIo *p_cdio, lsn_t **pp_sectors ) { - track_t i_tracks = cdio_get_num_tracks(cdio); - track_t first_track = cdio_get_first_track_num(cdio); + track_t i_tracks = cdio_get_num_tracks(p_cdio); + track_t first_track = cdio_get_first_track_num(p_cdio); track_t i; + if (CDIO_INVALID_TRACK == i_tracks) + return 0; *pp_sectors = malloc( (i_tracks + 1) * sizeof(lsn_t) ); if( *pp_sectors == NULL ) @@ -116,7 +118,7 @@ track_t ioctl_GetTracksMap( vlc_object_t *p_this, const CdIo *cdio, */ for( i = 0 ; i <= i_tracks ; i++ ) { - (*pp_sectors)[ i ] = cdio_get_track_lsn(cdio, first_track+i); + (*pp_sectors)[ i ] = cdio_get_track_lsn(p_cdio, first_track+i); } return i_tracks; diff --git a/modules/access/vcdx/cdrom.h b/modules/access/vcdx/cdrom.h index 1d28982207..fe9cafa324 100644 --- a/modules/access/vcdx/cdrom.h +++ b/modules/access/vcdx/cdrom.h @@ -2,7 +2,7 @@ * cdrom.h: cdrom tools header ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: cdrom.h,v 1.2 2003/11/26 03:34:22 rocky Exp $ + * $Id$ * * Authors: Johan Bilien * Gildas Bazin diff --git a/modules/access/vcdx/demux.c b/modules/access/vcdx/demux.c index cf6dc5bf79..aa0ca319b7 100644 --- a/modules/access/vcdx/demux.c +++ b/modules/access/vcdx/demux.c @@ -32,8 +32,6 @@ #include #include -#include "../../demux/mpeg/system.h" - #ifdef HAVE_UNISTD_H # include #endif @@ -72,15 +70,15 @@ struct demux_sys_t }; /***************************************************************************** - * InitVCD: initializes structures + * VCDInit: initializes structures *****************************************************************************/ -int E_(InitVCD) ( vlc_object_t *p_this ) +int E_(VCDInit) ( vlc_object_t *p_this ) { input_thread_t *p_input = (input_thread_t *)p_this; - vcd_data_t * p_vcd = (vcd_data_t *)p_input->p_access_data; + vcd_data_t * p_vcd = (vcd_data_t *)p_input->p_sys; demux_sys_t * p_demux; - printf("++++ InitVCD CALLED\n"); + printf("++++ VCDInit CALLED\n"); if( p_input->stream.i_method != INPUT_METHOD_VCD ) @@ -115,9 +113,9 @@ int E_(InitVCD) ( vlc_object_t *p_this ) } /***************************************************************************** - * EndVCD: frees unused data + * VCDEnd: frees unused data *****************************************************************************/ -void E_(EndVCD) ( vlc_object_t *p_this ) +void E_(VCDEnd) ( vlc_object_t *p_this ) { input_thread_t *p_input = (input_thread_t *)p_this; vcd_data_t * p_vcd = p_input->p_demux_data->p_vcd; diff --git a/modules/access/vcdx/info.c b/modules/access/vcdx/info.c new file mode 100644 index 0000000000..c6dbfbe274 --- /dev/null +++ b/modules/access/vcdx/info.c @@ -0,0 +1,405 @@ +/***************************************************************************** + * info.c : CD digital audio input information routines + ***************************************************************************** + * Copyright (C) 2004 VideoLAN + * $Id: info.c 8845 2004-09-29 09:00:41Z rocky $ + * + * Authors: Rocky Bernstein + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +#include +#include + +#include "vcd.h" +#include +#include "vcdplayer.h" +#include "vlc_keys.h" + +#include +#include +#include +#include +#include +#include + +static inline void +MetaInfoAddStr(access_t *p_access, char *p_cat, + char *title, const char *str) +{ + access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + if ( str ) { + dbg_print( INPUT_DBG_META, "field: %s: %s", title, str); + input_Control( p_vcd->p_input, INPUT_ADD_INFO, p_cat, title, "%s", str); + } +} + + +static inline void +MetaInfoAddNum(access_t *p_access, char *psz_cat, char *title, int num) +{ + access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + dbg_print( INPUT_DBG_META, "field %s: %d", title, num); + input_Control( p_vcd->p_input, INPUT_ADD_INFO, psz_cat, title, "%d", num ); +} + +#define addstr(title, str) \ + MetaInfoAddStr( p_access, psz_cat, title, str ); + +#define addnum(title, num) \ + MetaInfoAddNum( p_access, psz_cat, title, num ); + +void +VCDMetaInfo( access_t *p_access ) +{ + access_vcd_data_t *p_vcd = (access_vcd_data_t *) p_access->p_sys; + unsigned int i_entries = vcdinfo_get_num_entries(p_vcd->vcd); + unsigned int last_entry = 0; + char *psz_cat; + track_t i_track; + + psz_cat = _("General"); + + addstr( _("VCD Format"), vcdinfo_get_format_version_str(p_vcd->vcd) ); + addstr( _("Album"), vcdinfo_get_album_id(p_vcd->vcd)); + addstr( _("Application"), vcdinfo_get_application_id(p_vcd->vcd) ); + addstr( _("Preparer"), vcdinfo_get_preparer_id(p_vcd->vcd) ); + addnum( _("Vol #"), vcdinfo_get_volume_num(p_vcd->vcd) ); + addnum( _("Vol max #"), vcdinfo_get_volume_count(p_vcd->vcd) ); + addstr( _("Volume Set"), vcdinfo_get_volumeset_id(p_vcd->vcd) ); + addstr( _("Volume"), vcdinfo_get_volume_id(p_vcd->vcd) ); + addstr( _("Publisher"), vcdinfo_get_publisher_id(p_vcd->vcd) ); + addstr( _("System Id"), vcdinfo_get_system_id(p_vcd->vcd) ); + addnum( "LIDs", vcdinfo_get_num_LIDs(p_vcd->vcd) ); + addnum( _("Entries"), vcdinfo_get_num_entries(p_vcd->vcd) ); + addnum( _("Segments"), vcdinfo_get_num_segments(p_vcd->vcd) ); + addnum( _("Tracks"), vcdinfo_get_num_tracks(p_vcd->vcd) ); + + /* Spit out track information. Could also include MSF info. + Also build title table. + */ + +#define TITLE_MAX 30 + for( i_track = 1 ; i_track < p_vcd->i_tracks ; i_track++ ) { + unsigned int audio_type = vcdinfo_get_track_audio_type(p_vcd->vcd, + i_track); + uint32_t i_secsize = + p_vcd->p_sectors[i_track+1] - p_vcd->p_sectors[i_track]; + if (p_vcd->b_svd) { + addnum(_("Audio Channels"), + vcdinfo_audio_type_num_channels(p_vcd->vcd, audio_type) ); + } + + addnum(_("First Entry Point"), last_entry ); + for ( ; last_entry < i_entries + && vcdinfo_get_track(p_vcd->vcd, last_entry) == i_track; + last_entry++ ) ; + addnum(_("Last Entry Point"), last_entry-1 ); + addnum(_("Track size (in sectors)"), i_secsize ); + } +} + +#define add_format_str_info(val) \ + { \ + const char *str = val; \ + unsigned int len; \ + if (val != NULL) { \ + len=strlen(str); \ + if (len != 0) { \ + strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \ + tp += len; \ + } \ + saw_control_prefix = VLC_FALSE; \ + } \ + } + +#define add_format_num_info( val, fmt ) \ + { \ + char num_str[10]; \ + unsigned int len; \ + sprintf(num_str, fmt, val); \ + len = strlen(num_str); \ + if( len != 0 ) \ + { \ + strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \ + tp += len; \ + } \ + saw_control_prefix = VLC_FALSE; \ + } + +/*! + Take a format string and expand escape sequences, that is sequences that + begin with %, with information from the current VCD. + The expanded string is returned. Here is a list of escape sequences: + + %A : The album information + %C : The VCD volume count - the number of CD's in the collection. + %c : The VCD volume num - the number of the CD in the collection. + %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD + %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT... + %L : The playlist ID prefixed with " LID" if it exists + %M : MRL + %N : The current number of the %I - a decimal number + %P : The publisher ID + %p : The preparer ID + %S : If we are in a segment (menu), the kind of segment + %T : The track number + %V : The volume set ID + %v : The volume ID + A number between 1 and the volume count. + %% : a % +*/ +char * +VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd, + const char format_str[], const char *mrl, + const vcdinfo_itemid_t *itemid) +{ +#define TEMP_STR_SIZE 256 +#define TEMP_STR_LEN (TEMP_STR_SIZE-1) + static char temp_str[TEMP_STR_SIZE]; + size_t i; + char * tp = temp_str; + vlc_bool_t saw_control_prefix = VLC_FALSE; + size_t format_len = strlen(format_str); + + memset(temp_str, 0, TEMP_STR_SIZE); + + for (i=0; ivcd), + MAX_ALBUM_LEN)); + break; + + case 'c': + add_format_num_info(vcdinfo_get_volume_num(p_vcd->vcd), "%d"); + break; + + case 'C': + add_format_num_info(vcdinfo_get_volume_count(p_vcd->vcd), "%d"); + break; + + case 'F': + add_format_str_info(vcdinfo_get_format_version_str(p_vcd->vcd)); + break; + + case 'I': + { + switch (itemid->type) { + case VCDINFO_ITEM_TYPE_TRACK: + strncat(tp, _("Track"), TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(_("Track")); + break; + case VCDINFO_ITEM_TYPE_ENTRY: + strncat(tp, _("Entry"), TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(_("Entry")); + break; + case VCDINFO_ITEM_TYPE_SEGMENT: + strncat(tp, _("Segment"), TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(_("Segment")); + break; + case VCDINFO_ITEM_TYPE_LID: + strncat(tp, _("List ID"), TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(_("List ID")); + break; + case VCDINFO_ITEM_TYPE_SPAREID2: + strncat(tp, _("Navigation"), TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(_("Navigation")); + break; + default: + /* What to do? */ + ; + } + saw_control_prefix = VLC_FALSE; + } + break; + + case 'L': + if (vcdplayer_pbc_is_on(p_vcd)) { + char num_str[40]; + sprintf(num_str, "%s %d", _("List ID"), p_vcd->i_lid); + strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(num_str); + } + saw_control_prefix = VLC_FALSE; + break; + + case 'M': + add_format_str_info(mrl); + break; + + case 'N': + add_format_num_info(itemid->num, "%d"); + break; + + case 'p': + add_format_str_info(vcdinfo_get_preparer_id(p_vcd->vcd)); + break; + + case 'P': + add_format_str_info(vcdinfo_get_publisher_id(p_vcd->vcd)); + break; + + case 'S': + if ( VCDINFO_ITEM_TYPE_SEGMENT==itemid->type ) { + char seg_type_str[10]; + + sprintf(seg_type_str, " %s", + vcdinfo_video_type2str(p_vcd->vcd, itemid->num)); + strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str)); + tp += strlen(seg_type_str); + } + saw_control_prefix = VLC_FALSE; + break; + + case 'T': + add_format_num_info(p_vcd->i_track, "%d"); + break; + + case 'V': + add_format_str_info(vcdinfo_get_volumeset_id(p_vcd->vcd)); + break; + + case 'v': + add_format_str_info(vcdinfo_get_volume_id(p_vcd->vcd)); + break; + + default: + *tp++ = '%'; + *tp++ = format_str[i]; + saw_control_prefix = VLC_FALSE; + } + } + return strdup(temp_str); +} + +static void +VCDCreatePlayListItem(const access_t *p_access, + access_vcd_data_t *p_vcd, + playlist_t *p_playlist, + const vcdinfo_itemid_t *itemid, + char *psz_mrl, int psz_mrl_max, + const char *psz_source, int playlist_operation, + int i_pos) +{ + char *p_author; + char *p_title; + char c_type; + + switch(itemid->type) { + case VCDINFO_ITEM_TYPE_TRACK: + c_type='T'; + break; + case VCDINFO_ITEM_TYPE_SEGMENT: + c_type='S'; + break; + case VCDINFO_ITEM_TYPE_LID: + c_type='P'; + break; + case VCDINFO_ITEM_TYPE_ENTRY: + c_type='E'; + break; + default: + c_type='?'; + break; + } + + snprintf(psz_mrl, psz_mrl_max, "%s%s@%c%u", VCD_MRL_PREFIX, psz_source, + c_type, itemid->num); + + p_title = + VCDFormatStr( p_access, p_vcd, + config_GetPsz( p_access, MODULE_STRING "-title-format" ), + psz_mrl, itemid ); + + playlist_Add( p_playlist, psz_mrl, p_title, playlist_operation, i_pos ); + + p_author = + VCDFormatStr( p_access, p_vcd, + config_GetPsz( p_access, MODULE_STRING "-author-format" ), + psz_mrl, itemid ); + + if( i_pos == PLAYLIST_END ) i_pos = p_playlist->i_size - 1; + playlist_AddInfo(p_playlist, i_pos, _("General"), _("Author"), "%s", + p_author); +} + +int +VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd, + const char *psz_source, vcdinfo_itemid_t *itemid, + vlc_bool_t b_single_item ) +{ + unsigned int i; + playlist_t * p_playlist; + char * psz_mrl; + unsigned int psz_mrl_max = strlen(VCD_MRL_PREFIX) + strlen(psz_source) + + strlen("@T") + strlen("100") + 1; + + psz_mrl = malloc( psz_mrl_max ); + + if( psz_mrl == NULL ) + { + msg_Warn( p_access, "out of memory" ); + return -1; + } + + p_playlist = (playlist_t *) vlc_object_find( p_access, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + if( !p_playlist ) + { + msg_Warn( p_access, "can't find playlist" ); + free(psz_mrl); + return -1; + } + + { + vcdinfo_itemid_t list_itemid; + list_itemid.type=VCDINFO_ITEM_TYPE_ENTRY; + + playlist_LockDelete( p_playlist, p_playlist->i_index); + + for( i = 0 ; i < p_vcd->i_entries ; i++ ) + { + list_itemid.num=i; + VCDCreatePlayListItem(p_access, p_vcd, p_playlist, &list_itemid, + psz_mrl, psz_mrl_max, psz_source, + PLAYLIST_APPEND, PLAYLIST_END); + } + +#if LOOKED_OVER + playlist_Command( p_playlist, PLAYLIST_GOTO, 0 ); +#endif + + } + + vlc_object_release( p_playlist ); + free(psz_mrl); + return 0; +} + diff --git a/modules/access/vcdx/info.h b/modules/access/vcdx/info.h new file mode 100644 index 0000000000..17ebc0351a --- /dev/null +++ b/modules/access/vcdx/info.h @@ -0,0 +1,39 @@ +/***************************************************************************** + * info.h : VCD information routine headers + ***************************************************************************** + * Copyright (C) 2004 VideoLAN + * $Id: info.h 8606 2004-08-31 18:32:54Z rocky $ + * + * Authors: Rocky Bernstein + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/* + Fills out playlist information. + */ +int VCDFixupPlayList( access_t *p_access, access_vcd_data_t *p_vcd, + const char *psz_source, vcdinfo_itemid_t *itemid, + vlc_bool_t b_single_track ); + +/* + Sets VCD meta information and navigation/playlist entries. + */ +void VCDMetaInfo( access_t *p_access ); + +char * +VCDFormatStr(const access_t *p_access, access_vcd_data_t *p_vcd, + const char format_str[], const char *mrl, + const vcdinfo_itemid_t *itemid); diff --git a/modules/access/vcdx/intf.h b/modules/access/vcdx/intf.h index 90c04b0479..52475802eb 100644 --- a/modules/access/vcdx/intf.h +++ b/modules/access/vcdx/intf.h @@ -2,7 +2,7 @@ * intf.h: send info to intf. ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: intf.h,v 1.4 2003/12/22 14:32:55 sam Exp $ + * $Id$ * * Author: Stéphane Borel * @@ -27,7 +27,7 @@ struct intf_sys_t { input_thread_t * p_input; - thread_vcd_data_t * p_vcd; + access_vcd_data_t * p_vcd; vlc_bool_t b_still; /* True if we are in a still frame */ vlc_bool_t b_inf_still; /* True if still wait time is infinite */ diff --git a/modules/access/vcdx/vcd.c b/modules/access/vcdx/vcd.c index 52db0a87fe..6cd87fa4d0 100644 --- a/modules/access/vcdx/vcd.c +++ b/modules/access/vcdx/vcd.c @@ -1,7 +1,7 @@ /***************************************************************************** * vcd.c : VCD input module for vlc ***************************************************************************** - * Copyright (C) 2000,2003 VideoLAN + * Copyright (C) 2000, 2003, 2004 VideoLAN * $Id$ * * Authors: Rocky Bernstein @@ -34,12 +34,12 @@ /***************************************************************************** * Exported prototypes *****************************************************************************/ -int E_(Open) ( vlc_object_t * ); -void E_(Close) ( vlc_object_t * ); +int E_(VCDOpen) ( vlc_object_t * ); +void E_(VCDClose) ( vlc_object_t * ); int E_(OpenIntf) ( vlc_object_t * ); void E_(CloseIntf) ( vlc_object_t * ); -int E_(InitVCD) ( vlc_object_t * ); -void E_(EndVCD) ( vlc_object_t * ); +int E_(VCDInit) ( vlc_object_t * ); +void E_(VCDEnd) ( vlc_object_t * ); int E_(DebugCallback) ( vlc_object_t *p_this, const char *psz_name, vlc_value_t oldval, vlc_value_t val, @@ -90,12 +90,9 @@ int E_(DebugCallback) ( vlc_object_t *p_this, const char *psz_name, vlc_module_begin(); add_usage_hint( N_("vcdx://[device-or-file][@{P,S,T}num]") ); set_description( _("Video CD (VCD 1.0, 1.1, 2.0, SVCD, HQVCD) input") ); - set_capability( "access", 85 /* slightly higher than vcd */ ); - set_callbacks( E_(Open), E_(Close) ); - add_shortcut( "vcd" ); + set_capability( "access2", 55 /* slightly lower than vcd */ ); + set_callbacks( E_(VCDOpen), E_(VCDClose) ); add_shortcut( "vcdx" ); - set_category( CAT_INPUT ); - set_subcategory( SUBCAT_INPUT_ACCESS ); /* Configuration options */ add_integer ( MODULE_STRING "-debug", 0, E_(DebugCallback), @@ -123,11 +120,11 @@ vlc_module_begin(); #ifdef FIXED add_submodule(); set_capability( "demux", 0 ); - set_callbacks( E_(InitVCD), E_(EndVCD) ); -#endif - + set_callbacks( E_(VCDInit), E_(VCDEnd) ); add_submodule(); set_capability( "interface", 0 ); set_callbacks( E_(OpenIntf), E_(CloseIntf) ); +#endif + vlc_module_end(); diff --git a/modules/access/vcdx/vcd.h b/modules/access/vcdx/vcd.h index 416a1b7066..b6dcb48a41 100644 --- a/modules/access/vcdx/vcd.h +++ b/modules/access/vcdx/vcd.h @@ -1,8 +1,8 @@ /***************************************************************************** * vcd.h : VCD input module header for vlc - * using libcdio, libvcd and libvcdinfo + * using libcdio, libvcd and libvcdinfo ***************************************************************************** - * Copyright (C) 2003 VideoLAN + * Copyright (C) 2003, 2004 VideoLAN * $Id$ * * Authors: Rocky Bernstein @@ -24,6 +24,8 @@ #include +#define VCD_MRL_PREFIX "vcdx://" + /***************************************************************************** * vcd_data_t: structure for communication between access and intf. *****************************************************************************/ @@ -40,7 +42,7 @@ typedef struct #endif int i_still_time; - vlc_bool_t b_end_of_cell; + vlc_bool_t b_end_of_cell; #if FINISHED vcdplay_event_t event; @@ -50,6 +52,6 @@ typedef struct } vcd_data_t; -int VCDSetArea ( input_thread_t *, input_area_t * ); -void VCDSeek ( input_thread_t *, off_t ); -int VCDPlay ( input_thread_t *, vcdinfo_itemid_t ); +int VCDSetArea ( access_t * ); +int VCDSeek ( access_t *, off_t ); +int VCDPlay ( access_t *, vcdinfo_itemid_t ); diff --git a/modules/access/vcdx/vcdplayer.c b/modules/access/vcdx/vcdplayer.c index 247501e4ae..02fb87cea4 100644 --- a/modules/access/vcdx/vcdplayer.c +++ b/modules/access/vcdx/vcdplayer.c @@ -2,7 +2,7 @@ * vcdplayer.c : VCD input module for vlc * using libcdio, libvcd and libvcdinfo ***************************************************************************** - * Copyright (C) 2003 Rocky Bernstein + * Copyright (C) 2003, 2004 Rocky Bernstein * $Id$ * * This program is free software; you can redistribute it and/or modify @@ -50,15 +50,17 @@ /*! Return VLC_TRUE if playback control (PBC) is on */ -vlc_bool_t vcdplayer_pbc_is_on( const thread_vcd_data_t *p_vcd ) +vlc_bool_t +vcdplayer_pbc_is_on( const access_vcd_data_t *p_vcd ) { - return VCDINFO_INVALID_ENTRY != p_vcd->cur_lid; + return VCDINFO_INVALID_ENTRY != p_vcd->i_lid; } -static void vcdplayer_update_entry( input_thread_t * p_input, uint16_t ofs, +static void +vcdplayer_update_entry( access_t * p_access, uint16_t ofs, uint16_t *entry, const char *label) { - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; if ( ofs == VCDINFO_INVALID_OFFSET ) { *entry = VCDINFO_INVALID_ENTRY; @@ -79,17 +81,18 @@ static void vcdplayer_update_entry( input_thread_t * p_input, uint16_t ofs, return VLC_TRUE if the caller should return. */ -vcdplayer_read_status_t vcdplayer_non_pbc_nav ( input_thread_t * p_input ) +vcdplayer_read_status_t +vcdplayer_non_pbc_nav ( access_t * p_access ) { - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; /* Not in playback control. Do we advance automatically or stop? */ switch (p_vcd->play_item.type) { case VCDINFO_ITEM_TYPE_TRACK: case VCDINFO_ITEM_TYPE_ENTRY: { - dbg_print( INPUT_DBG_LSN, "new track %d, lsn %d", p_vcd->cur_track, - p_vcd->p_sectors[p_vcd->cur_track+1] ); + dbg_print( INPUT_DBG_LSN, "new track %d, lsn %d", p_vcd->i_track, + p_vcd->p_sectors[p_vcd->i_track+1] ); return READ_END; break; } @@ -97,7 +100,6 @@ vcdplayer_read_status_t vcdplayer_non_pbc_nav ( input_thread_t * p_input ) dbg_print( (INPUT_DBG_STILL|INPUT_DBG_LSN), "SPAREID2" ); /* FIXME */ - p_input->stream.b_seekable = 0; if (p_vcd->in_still) { return READ_STILL_FRAME ; @@ -112,7 +114,6 @@ vcdplayer_read_status_t vcdplayer_non_pbc_nav ( input_thread_t * p_input ) case VCDINFO_ITEM_TYPE_SEGMENT: /* Hack: Just go back and do still again */ /* FIXME */ - p_input->stream.b_seekable = 0; if (p_vcd->in_still) { dbg_print( (INPUT_DBG_STILL|INPUT_DBG_LSN), @@ -126,9 +127,9 @@ vcdplayer_read_status_t vcdplayer_non_pbc_nav ( input_thread_t * p_input ) /* Handles PBC navigation when reaching the end of a play item. */ vcdplayer_read_status_t -vcdplayer_pbc_nav ( input_thread_t * p_input ) +vcdplayer_pbc_nav ( access_t * p_access ) { - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; /* We are in playback control. */ vcdinfo_itemid_t itemid; @@ -137,12 +138,12 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) sequence (or track). */ if ( (VCDINFO_ITEM_TYPE_ENTRY == p_vcd->play_item.type) && - (p_vcd->cur_lsn < p_vcd->end_lsn) ) { + (p_vcd->i_lsn < p_vcd->end_lsn) ) { /* Set up to just continue to the next entry */ p_vcd->play_item.num++; dbg_print( (INPUT_DBG_LSN|INPUT_DBG_PBC), "continuing into next entry: %u", p_vcd->play_item.num); - VCDPlay( p_input, p_vcd->play_item ); + VCDPlay( p_access, p_vcd->play_item ); /* p_vcd->update_title(); */ return READ_BLOCK; } @@ -156,20 +157,22 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) dbg_print(INPUT_DBG_PBC, "playlist wait_time: %d", wait_time); - if (vcdplayer_inc_play_item(p_input)) + if (vcdplayer_inc_play_item(p_access)) return READ_BLOCK; /* Handle any wait time given. */ +#if FIXED if (p_vcd->in_still) { vcdIntfStillTime( p_vcd->p_intf, wait_time ); return READ_STILL_FRAME; } +#endif - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_pld_get_next_offset(p_vcd->pxd.pld), &itemid.num, "next" ); itemid.type = VCDINFO_ITEM_TYPE_LID; - VCDPlay( p_input, itemid ); + VCDPlay( p_access, itemid ); break; } case PSD_TYPE_SELECTION_LIST: /* Selection List (+Ext. for SVCD) */ @@ -185,16 +188,18 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) wait_time, p_vcd->loop_count, max_loop); /* Handle any wait time given */ +#if FIXED if (p_vcd->in_still) { vcdIntfStillTime( p_vcd->p_intf, wait_time ); return READ_STILL_FRAME; } +#endif /* Handle any looping given. */ if ( max_loop == 0 || p_vcd->loop_count < max_loop ) { p_vcd->loop_count++; if (p_vcd->loop_count == 0x7f) p_vcd->loop_count = 0; - VCDSeek( p_input, 0 ); + VCDSeek( p_access, 0 ); /* if (p_vcd->in_still) p_vcd->force_redisplay();*/ return READ_BLOCK; } @@ -207,7 +212,7 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) itemid.num = offset_timeout_LID->lid; itemid.type = VCDINFO_ITEM_TYPE_LID; dbg_print(INPUT_DBG_PBC, "timeout to: %d", itemid.num); - VCDPlay( p_input, itemid ); + VCDPlay( p_access, itemid ); return READ_BLOCK; } else { int num_selections = vcdinf_get_num_selections(p_vcd->pxd.psd); @@ -217,13 +222,13 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) int rand_selection=bsn + (int) ((num_selections+0.0)*rand()/(RAND_MAX+1.0)); lid_t rand_lid=vcdinfo_selection_get_lid (p_vcd->vcd, - p_vcd->cur_lid, + p_vcd->i_lid, rand_selection); itemid.num = rand_lid; itemid.type = VCDINFO_ITEM_TYPE_LID; dbg_print(INPUT_DBG_PBC, "random selection %d, lid: %d", rand_selection - bsn, rand_lid); - VCDPlay( p_input, itemid ); + VCDPlay( p_access, itemid ); return READ_BLOCK; } else if (p_vcd->in_still) { /* Hack: Just go back and do still again */ @@ -257,9 +262,10 @@ vcdplayer_pbc_nav ( input_thread_t * p_input ) confused with a user's list of favorite things to play or the "next" field of a LID which moves us to a different LID. */ -vlc_bool_t vcdplayer_inc_play_item( input_thread_t *p_input ) +vlc_bool_t +vcdplayer_inc_play_item( access_t *p_access ) { - thread_vcd_data_t * p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t * p_vcd= (access_vcd_data_t *)p_access->p_sys; int noi; @@ -287,7 +293,7 @@ vlc_bool_t vcdplayer_inc_play_item( input_thread_t *p_input ) vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); dbg_print(INPUT_DBG_PBC, " play-item[%d]: %s", p_vcd->pdi, vcdinfo_pin2str (trans_itemid_num)); - return VLC_SUCCESS == VCDPlay( p_input, trans_itemid ); + return VLC_SUCCESS == VCDPlay( p_access, trans_itemid ); } } @@ -296,9 +302,10 @@ vlc_bool_t vcdplayer_inc_play_item( input_thread_t *p_input ) Return VLC_FALSE if there was some problem. */ -vlc_bool_t vcdplayer_play_default( input_thread_t * p_input ) +vlc_bool_t +vcdplayer_play_default( access_t * p_access ) { - thread_vcd_data_t *p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; vcdinfo_itemid_t itemid; @@ -317,27 +324,27 @@ vlc_bool_t vcdplayer_play_default( input_thread_t * p_input ) if (vcdplayer_pbc_is_on(p_vcd)) { #if defined(LIBVCD_VERSION) - lid_t lid=vcdinfo_get_multi_default_lid(p_vcd->vcd, p_vcd->cur_lid, - p_vcd->cur_lsn); + lid_t lid=vcdinfo_get_multi_default_lid(p_vcd->vcd, p_vcd->i_lid, + p_vcd->i_lsn); if (VCDINFO_INVALID_LID != lid) { itemid.num = lid; itemid.type = VCDINFO_ITEM_TYPE_LID; dbg_print(INPUT_DBG_PBC, "DEFAULT to %d\n", itemid.num); } else { - dbg_print(INPUT_DBG_PBC, "no DEFAULT for LID %d\n", p_vcd->cur_lid); + dbg_print(INPUT_DBG_PBC, "no DEFAULT for LID %d\n", p_vcd->i_lid); } #else - vcdinfo_lid_get_pxd(p_vcd->vcd, &(p_vcd->pxd), p_vcd->cur_lid); + vcdinfo_lid_get_pxd(p_vcd->vcd, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (p_vcd->pxd.psd == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinfo_get_default_offset(p_vcd->vcd, - p_vcd->cur_lid), + p_vcd->i_lid), &itemid.num, "default"); break; @@ -360,7 +367,7 @@ vlc_bool_t vcdplayer_play_default( input_thread_t * p_input ) } /** ??? p_vcd->update_title(); ***/ - return VLC_SUCCESS == VCDPlay( p_input, itemid ); + return VLC_SUCCESS == VCDPlay( p_access, itemid ); } @@ -369,9 +376,10 @@ vlc_bool_t vcdplayer_play_default( input_thread_t * p_input ) Return VLC_FALSE if there was some problem. */ -vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ) +vlc_bool_t +vcdplayer_play_next( access_t * p_access ) { - thread_vcd_data_t *p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; vcdinfo_obj_t *obj; vcdinfo_itemid_t itemid; @@ -387,13 +395,13 @@ vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ) if (vcdplayer_pbc_is_on(p_vcd)) { - vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->cur_lid); + vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (p_vcd->pxd.psd == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_psd_get_next_offset(p_vcd->pxd.psd), &itemid.num, "next"); itemid.type = VCDINFO_ITEM_TYPE_LID; @@ -401,7 +409,7 @@ vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ) case PSD_TYPE_PLAY_LIST: if (p_vcd->pxd.pld == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_pld_get_next_offset(p_vcd->pxd.pld), &itemid.num, "next"); itemid.type = VCDINFO_ITEM_TYPE_LID; @@ -425,13 +433,13 @@ vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ) switch (p_vcd->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: - max_entry = p_vcd->num_entries; + max_entry = p_vcd->i_entries; break; case VCDINFO_ITEM_TYPE_SEGMENT: - max_entry = p_vcd->num_segments; + max_entry = p_vcd->i_segments; break; case VCDINFO_ITEM_TYPE_TRACK: - max_entry = p_vcd->num_tracks; + max_entry = p_vcd->i_tracks; break; default: ; /* Handle exceptional cases below */ } @@ -457,7 +465,7 @@ vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ) } /** ??? p_vcd->update_title(); ***/ - return VLC_SUCCESS == VCDPlay( p_input, itemid ); + return VLC_SUCCESS == VCDPlay( p_access, itemid ); } @@ -466,9 +474,10 @@ vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ) Return VLC_FALSE if there was some problem. */ -vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ) +vlc_bool_t +vcdplayer_play_prev( access_t * p_access ) { - thread_vcd_data_t *p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; vcdinfo_obj_t *obj = p_vcd->vcd; vcdinfo_itemid_t itemid; @@ -480,13 +489,13 @@ vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ) if (vcdplayer_pbc_is_on(p_vcd)) { - vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->cur_lid); + vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (p_vcd->pxd.psd == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_psd_get_prev_offset(p_vcd->pxd.psd), &itemid.num, "prev"); itemid.type = VCDINFO_ITEM_TYPE_LID; @@ -494,7 +503,7 @@ vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ) case PSD_TYPE_PLAY_LIST: if (p_vcd->pxd.pld == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_pld_get_prev_offset(p_vcd->pxd.pld), &itemid.num, "prev"); itemid.type = VCDINFO_ITEM_TYPE_LID; @@ -522,7 +531,7 @@ vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ) } /** ??? p_vcd->update_title(); ***/ - return VLC_SUCCESS == VCDPlay( p_input, itemid ); + return VLC_SUCCESS == VCDPlay( p_access, itemid ); } @@ -531,9 +540,10 @@ vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ) Return VLC_FALSE if there was some problem. */ -vlc_bool_t vcdplayer_play_return( input_thread_t * p_input ) +vlc_bool_t +vcdplayer_play_return( access_t * p_access ) { - thread_vcd_data_t *p_vcd= (thread_vcd_data_t *)p_input->p_access_data; + access_vcd_data_t *p_vcd= (access_vcd_data_t *)p_access->p_sys; vcdinfo_obj_t *obj = p_vcd->vcd; vcdinfo_itemid_t itemid; @@ -545,13 +555,13 @@ vlc_bool_t vcdplayer_play_return( input_thread_t * p_input ) if (vcdplayer_pbc_is_on(p_vcd)) { - vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->cur_lid); + vcdinfo_lid_get_pxd(obj, &(p_vcd->pxd), p_vcd->i_lid); switch (p_vcd->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (p_vcd->pxd.psd == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_psd_get_return_offset(p_vcd->pxd.psd), &itemid.num, "return"); itemid.type = VCDINFO_ITEM_TYPE_LID; @@ -559,7 +569,7 @@ vlc_bool_t vcdplayer_play_return( input_thread_t * p_input ) case PSD_TYPE_PLAY_LIST: if (p_vcd->pxd.pld == NULL) return VLC_FALSE; - vcdplayer_update_entry( p_input, + vcdplayer_update_entry( p_access, vcdinf_pld_get_return_offset(p_vcd->pxd.pld), &itemid.num, "return"); itemid.type = VCDINFO_ITEM_TYPE_LID; @@ -580,6 +590,6 @@ vlc_bool_t vcdplayer_play_return( input_thread_t * p_input ) } /** ??? p_vcd->update_title(); ***/ - return VLC_SUCCESS == VCDPlay( p_input, itemid ); + return VLC_SUCCESS == VCDPlay( p_access, itemid ); } diff --git a/modules/access/vcdx/vcdplayer.h b/modules/access/vcdx/vcdplayer.h index 1addfacc03..ed1b5a8fb4 100644 --- a/modules/access/vcdx/vcdplayer.h +++ b/modules/access/vcdx/vcdplayer.h @@ -25,6 +25,7 @@ #define _VCDPLAYER_H_ #include +#include "vlc_meta.h" #define INPUT_DBG_META 1 /* Meta information */ #define INPUT_DBG_EVENT 2 /* input (keyboard/mouse) events */ @@ -43,13 +44,13 @@ #if INPUT_DEBUG #define dbg_print(mask, s, args...) \ if (p_vcd && p_vcd->i_debug & mask) \ - msg_Dbg(p_input, "%s: "s, __func__ , ##args) + msg_Dbg(p_access, "%s: "s, __func__ , ##args) #else #define dbg_print(mask, s, args...) #endif -#define LOG_ERR(args...) msg_Err( p_input, args ) -#define LOG_WARN(args...) msg_Warn( p_input, args ) +#define LOG_ERR(args...) msg_Err( p_access, args ) +#define LOG_WARN(args...) msg_Warn( p_access, args ) /* vcdplayer_read return status */ typedef enum { @@ -60,29 +61,25 @@ typedef enum { } vcdplayer_read_status_t; /***************************************************************************** - * thread_vcd_data_t: VCD information + * access_vcd_data_t: VCD information *****************************************************************************/ typedef struct thread_vcd_data_s { vcdinfo_obj_t *vcd; /* CD device descriptor */ - vlc_bool_t in_still; /* true if in still */ - vlc_bool_t b_svd; /* true if we have SVD info */ - unsigned int num_tracks; /* Nb of tracks (titles) */ - unsigned int num_segments; /* Nb of segments */ - unsigned int num_entries; /* Nb of entries */ - unsigned int num_lids; /* Nb of List IDs */ + vlc_bool_t in_still; /* true if in still */ + vlc_bool_t b_svd; /* true if we have SVD info */ + track_t i_tracks; /* # of tracks */ + unsigned int i_segments; /* # of segments */ + unsigned int i_entries; /* # of entries */ + unsigned int i_lids; /* # of List IDs */ + unsigned int i_titles; /* # of navigatable titles. */ vcdinfo_itemid_t play_item; /* play-item, VCDPLAYER_BAD_ENTRY if none */ - int cur_lid; /* LID that play item is in. Implies + int i_lid; /* LID that play item is in. Implies PBC is on. VCDPLAYER_BAD_ENTRY if not none or not in PBC */ -#if (defined LIBVCD_VERSION_NUM) && (LIBVCD_VERSION_NUM >= 21) PsdListDescriptor_t pxd; /* If PBC is on, the relevant PSD/PLD */ -#else - PsdListDescriptor pxd; /* If PBC is on, the relevant - PSD/PLD */ -#endif int pdi; /* current pld index of pxd. -1 if no index*/ vcdinfo_itemid_t loop_item; /* Where do we loop back to? @@ -91,25 +88,37 @@ typedef struct thread_vcd_data_s int loop_count; /* # of times play-item has been played. Meaningful only in a selection list. */ - track_t cur_track; /* Current track number */ - lsn_t cur_lsn; /* Current logical sector number */ + track_t i_track; /* Current track number */ + lsn_t i_lsn; /* Current logical sector number */ lsn_t end_lsn; /* LSN of end of current entry/segment/track. */ lsn_t origin_lsn; /* LSN of start of seek/slider */ - lsn_t * p_sectors; /* Track sectors */ + lsn_t * p_sectors; /* Track sectors. This is 0 origin + so the first VCD track will be + at 0 and this is the ISO9660 + filesystem. The first Mode2 form2 + MPEG track is probably track 2 or + p_sectors[1]. + */ lsn_t * p_entries; /* Entry points */ lsn_t * p_segments; /* Segments */ vlc_bool_t b_valid_ep; /* Valid entry points flag */ vlc_bool_t b_end_of_track; /* If the end of track was reached */ int i_debug; /* Debugging mask */ + /* Information about CD */ + vlc_meta_t *p_meta; + + input_title_t *p_title[CDIO_CD_MAX_TRACKS]; + /* Probably gets moved into another structure...*/ - intf_thread_t * p_intf; - int i_audio_nb; - int i_still_time; - vlc_bool_t b_end_of_cell; + intf_thread_t *p_intf; + int i_audio_nb; + int i_still_time; + vlc_bool_t b_end_of_cell; + input_thread_t *p_input; -} thread_vcd_data_t; +} access_vcd_data_t; /*! Get the next play-item in the list given in the LIDs. Note play-item @@ -117,33 +126,33 @@ typedef struct thread_vcd_data_s confused with a user's list of favorite things to play or the "next" field of a LID which moves us to a different LID. */ -vlc_bool_t vcdplayer_inc_play_item( input_thread_t *p_input ); +vlc_bool_t vcdplayer_inc_play_item( access_t *p_access ); /*! Return true if playback control (PBC) is on */ -vlc_bool_t vcdplayer_pbc_is_on(const thread_vcd_data_t *p_this); +vlc_bool_t vcdplayer_pbc_is_on(const access_vcd_data_t *p_this); /*! Play item assocated with the "default" selection. Return false if there was some problem. */ -vlc_bool_t vcdplayer_play_default( input_thread_t * p_input ); +vlc_bool_t vcdplayer_play_default( access_t * p_access ); /*! Play item assocated with the "next" selection. Return false if there was some problem. */ -vlc_bool_t vcdplayer_play_next( input_thread_t * p_input ); +vlc_bool_t vcdplayer_play_next( access_t * p_access ); /*! Play item assocated with the "prev" selection. Return false if there was some problem. */ -vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ); +vlc_bool_t vcdplayer_play_prev( access_t * p_access ); /*! Play item assocated with the "return" selection. @@ -151,10 +160,10 @@ vlc_bool_t vcdplayer_play_prev( input_thread_t * p_input ); Return false if there was some problem. */ vlc_bool_t -vcdplayer_play_return( input_thread_t * p_input ); +vcdplayer_play_return( access_t * p_access ); -vcdplayer_read_status_t vcdplayer_pbc_nav ( input_thread_t * p_input ); -vcdplayer_read_status_t vcdplayer_non_pbc_nav ( input_thread_t * p_input ); +vcdplayer_read_status_t vcdplayer_pbc_nav ( access_t * p_access ); +vcdplayer_read_status_t vcdplayer_non_pbc_nav ( access_t * p_access ); #endif /* _VCDPLAYER_H_ */ /* -- 2.39.2