From: Stéphane Borel Date: Fri, 8 Mar 2002 22:58:12 +0000 (+0000) Subject: Rewrite most functions in DVD plugin. Some old bugs might have been X-Git-Tag: 0.3.0~127 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=83b13fcb303923ca9b37ba3f2f19a8159a8e1415;p=vlc Rewrite most functions in DVD plugin. Some old bugs might have been solved in the operation. The plugin some be more readable now, and should produce fewaer segfaults (I hope so :p) --- diff --git a/plugins/dvd/dvd.h b/plugins/dvd/dvd.h index 3cb03a49a9..67b4ceccf2 100644 --- a/plugins/dvd/dvd.h +++ b/plugins/dvd/dvd.h @@ -2,7 +2,7 @@ * dvd.h: thread structure of the DVD plugin ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: dvd.h,v 1.1 2002/03/06 01:20:56 stef Exp $ + * $Id: dvd.h,v 1.2 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -45,19 +45,19 @@ typedef struct thread_dvd_data_s int i_chapter_nb; int i_chapter; + boolean_t b_new_chapter; int i_angle_nb; int i_angle; - int i_angle_cell; /* cell index in the current angle */ - int i_cell; /* cell index in adress map */ - int i_prg_cell; /* cell index in program map */ + int i_map_cell; /* cell index in adress map */ + int i_prg_cell; /* cell index in program map */ + int i_angle_cell; /* cell index in the current angle */ - int i_sector; - int i_end_sector; /* last sector of current cell */ + int i_vts_start; /* offset to beginning of vts */ + int i_vts_lb; /* sector in vts */ + int i_end_lb; /* last sector of current cell */ - int i_title_start; - int i_start; int i_size; /* Structure that contains all information of the DVD */ diff --git a/plugins/dvd/dvd_access.c b/plugins/dvd/dvd_access.c index ff51e4b894..2014d134a5 100644 --- a/plugins/dvd/dvd_access.c +++ b/plugins/dvd/dvd_access.c @@ -8,7 +8,7 @@ * -dvd_udf to find files ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_access.c,v 1.2 2002/03/06 12:26:35 stef Exp $ + * $Id: dvd_access.c,v 1.3 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -104,6 +104,10 @@ void _M( access_getfunctions)( function_list_t * p_function_list ) * Data access functions */ +#define DVDLB p_dvd->i_vts_start + p_dvd->i_vts_lb +#define DVDTell LB2OFF( p_dvd->i_vts_start + p_dvd->i_vts_lb ) \ + - p_input->stream.p_selected_area->i_start + /***************************************************************************** * DVDOpen: open dvd *****************************************************************************/ @@ -221,15 +225,16 @@ static int DVDOpen( struct input_thread_s *p_input ) p_area = p_input->stream.pp_areas[p_dvd->i_title]; - p_dvd->i_chapter = p_dvd->i_chapter < p_area->i_part_nb ? + p_dvd->i_chapter = p_dvd->i_chapter <= p_area->i_part_nb ? p_dvd->i_chapter : 1; p_area->i_part = p_dvd->i_chapter; + p_dvd->b_new_chapter = 0; p_dvd->i_audio_nb = 0; p_dvd->i_spu_nb = 0; /* set title, chapter, audio and subpic */ - if( DVDSetArea( p_input, p_area ) ) + if( DVDSetArea( p_input, p_area ) < 0 ) { vlc_mutex_unlock( &p_input->stream.stream_lock ); return -1; @@ -271,14 +276,15 @@ static int DVDSetProgram( input_thread_t * p_input, thread_dvd_data_t * p_dvd; int i_angle; - p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); i_angle = p_program->i_number; /* DVD is actually mono-program: we only need the current angle * number, so copy the data between programs */ - memcpy( p_program, p_input->stream.p_selected_program, + memcpy( p_program, + p_input->stream.p_selected_program, sizeof(pgrm_descriptor_t) ); - p_program->i_number = i_angle; + p_program->i_number = i_angle; p_input->stream.p_selected_program = p_program; #define title \ @@ -287,17 +293,19 @@ static int DVDSetProgram( input_thread_t * p_input, { if( ( p_program->i_number - p_dvd->i_angle ) < 0 ) { - p_dvd->i_cell = 0; + /* we have to go backwards */ + p_dvd->i_map_cell = 0; } p_dvd->i_prg_cell += ( p_program->i_number - p_dvd->i_angle ); - p_dvd->i_angle = p_program->i_number; - - DVDFindSector( p_dvd ); - p_dvd->i_cell += p_dvd->i_angle_cell; + p_dvd->i_map_cell = CellPrg2Map( p_dvd ); + p_dvd->i_map_cell += p_dvd->i_angle_cell; + p_dvd->i_vts_lb = CellStartSector( p_dvd ); + p_dvd->i_end_lb = CellEndSector( p_dvd ); + p_dvd->i_angle = p_program->i_number; } else { - p_dvd->i_angle = p_program->i_number; + p_dvd->i_angle = p_program->i_number; } #undef title intf_WarnMsg( 3, "dvd info: angle %d selected", p_dvd->i_angle ); @@ -313,11 +321,59 @@ static int DVDSetProgram( input_thread_t * p_input, * Take care that i_title starts from 0 (vmg) and i_chapter start from 1. * Note that you have to take the lock before entering here. *****************************************************************************/ +#define vmg p_dvd->p_ifo->vmg +#define vts p_dvd->p_ifo->vts + +static void DVDFlushStream( input_thread_t * p_input ) +{ + if( p_input->stream.pp_programs != NULL ) + { + /* We don't use input_EndStream here since + * we keep area structures */ + while( p_input->stream.i_es_number ) + { + input_DelES( p_input, p_input->stream.pp_es[0] ); + } + + while( p_input->stream.i_pgrm_number ) + { + input_DelProgram( p_input, p_input->stream.pp_programs[0] ); + } + + if( p_input->stream.pp_selected_es ) + { + free( p_input->stream.pp_selected_es ); + p_input->stream.pp_selected_es = NULL; + } + p_input->stream.i_selected_es_number = 0; + } + + return; +} + +static int DVDReadAngle( input_thread_t * p_input ) +{ + thread_dvd_data_t * p_dvd; + int i_angle_nb; + int i; + + p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + i_angle_nb = vmg.title_inf.p_attr[p_dvd->i_title-1].i_angle_nb; + + input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) ); + p_input->stream.p_selected_program = p_input->stream.pp_programs[0]; + + for( i = 1 ; i < i_angle_nb ; i++ ) + { + input_AddProgram( p_input, i+1, 0 ); + } + + return i_angle_nb; +} + static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) { thread_dvd_data_t * p_dvd; - int i_vts_title; - int i; p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); @@ -326,156 +382,97 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) if( p_area != p_input->stream.p_selected_area ) { + int i_vts_title; + u32 i_start; + u32 i_size; + /* Reset the Chapter position of the old title */ - p_input->stream.p_selected_area->i_part = 0; - p_input->stream.p_selected_area = p_area; + p_input->stream.p_selected_area->i_part = 1; + p_input->stream.p_selected_area = p_area; /* * We have to load all title information */ - /* Change the default area */ - - /* title number: it is not vts nb!, - * it is what appears in the interface list */ - p_dvd->i_title = p_area->i_id; - p_dvd->p_ifo->i_title = p_dvd->i_title; - /* set number of chapters of current title */ + /* title number as it appears in the interface list */ + p_dvd->i_title = p_area->i_id; p_dvd->i_chapter_nb = p_area->i_part_nb; - /* ifo vts */ - if( IfoTitleSet( p_dvd->p_ifo ) < 0 ) + if( IfoTitleSet( p_dvd->p_ifo, p_dvd->i_title ) < 0 ) { intf_ErrMsg( "dvd error: fatal error in vts ifo" ); free( p_dvd ); - p_input->b_error = 1; return -1; } -#define vmg p_dvd->p_ifo->vmg -#define vts p_dvd->p_ifo->vts /* title position inside the selected vts */ - i_vts_title = vmg.title_inf.p_attr[p_dvd->i_title-1].i_title_num; + i_vts_title = vmg.title_inf.p_attr[p_dvd->i_title-1].i_title_num; p_dvd->i_title_id = vts.title_inf.p_title_start[i_vts_title-1].i_title_id; intf_WarnMsg( 3, "dvd: title %d vts_title %d pgc %d", p_dvd->i_title, i_vts_title, p_dvd->i_title_id ); - - /* - * Set selected title start and size - */ - /* title set offset XXX: convert to block values */ - p_dvd->i_title_start = + p_dvd->i_vts_start = vts.i_pos + vts.manager_inf.i_title_vob_start_sector; - /* last video cell */ - p_dvd->i_cell = 0; + /* last cell */ + intf_WarnMsg( 4, "prg_cell nb %d", vts.title_unit.p_title[p_dvd->i_title_id-1].title.i_cell_nb ); p_dvd->i_prg_cell = -1 + vts.title_unit.p_title[p_dvd->i_title_id-1].title.i_cell_nb; + p_dvd->i_map_cell = 0; + p_dvd->i_map_cell = CellPrg2Map( p_dvd ); + i_size = CellEndSector( p_dvd ); - if( DVDFindCell( p_dvd ) < 0 ) - { - intf_ErrMsg( "dvd error: can't find title end" ); - p_input->b_error = 1; - return -1; - } - - /* temporary hack to fix size in some dvds */ - if( p_dvd->i_cell >= vts.cell_inf.i_cell_nb ) - { - p_dvd->i_cell = vts.cell_inf.i_cell_nb - 1; - } - - p_dvd->i_sector = 0; - p_dvd->i_size = vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector; + /* first cell */ + p_dvd->i_prg_cell = 0; + p_dvd->i_map_cell = 0; + p_dvd->i_map_cell = CellPrg2Map ( p_dvd ); + p_dvd->i_vts_lb = CellStartSector( p_dvd ); + p_dvd->i_end_lb = CellEndSector ( p_dvd ); - if( DVDChapterSelect( p_dvd, 1 ) < 0 ) - { - intf_ErrMsg( "dvd error: can't find first chapter" ); - p_input->b_error = 1; - return -1; - } - /* Force libdvdcss to check its title key. * It is only useful for title cracking method. Methods using the * decrypted disc key are fast enough to check the key at each seek */ - - if( dvdcss_seek( p_dvd->dvdhandle, p_dvd->i_start, - DVDCSS_SEEK_KEY ) < 0 ) + if( ( i_start = dvdcss_seek( p_dvd->dvdhandle, DVDLB, + DVDCSS_SEEK_KEY ) ) < 0 ) { intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); return -1; } - p_dvd->i_size -= p_dvd->i_sector + 1; - - IfoPrintTitle( p_dvd ); + i_size -= p_dvd->i_vts_lb + 1; /* Area definition */ - p_input->stream.p_selected_area->i_start = LB2OFF( p_dvd->i_start ); - p_input->stream.p_selected_area->i_size = LB2OFF( p_dvd->i_size ); + p_input->stream.p_selected_area->i_start = LB2OFF( i_start ); + p_input->stream.p_selected_area->i_size = LB2OFF( i_size ); - /* - * Destroy obsolete ES by reinitializing programs - * and find all ES in title with ifo data - */ - if( p_input->stream.pp_programs != NULL ) - { - /* We don't use input_EndStream here since - * we keep area structures */ - while( p_input->stream.i_es_number ) - { - input_DelES( p_input, p_input->stream.pp_es[0] ); - } - - while( p_input->stream.i_pgrm_number ) - { - input_DelProgram( p_input, p_input->stream.pp_programs[0] ); - } - - if( p_input->stream.pp_selected_es ) - { - free( p_input->stream.pp_selected_es ); - p_input->stream.pp_selected_es = NULL; - } - p_input->stream.i_selected_es_number = 0; - } + /* Destroy obsolete ES by reinitializing programs */ + DVDFlushStream( p_input ); - /* - * Angle management: angles are handled through programs - */ - p_dvd->i_angle_nb = vmg.title_inf.p_attr[p_dvd->i_title-1].i_angle_nb; + /* Angle management: angles are handled through programs */ + p_dvd->i_angle_nb = DVDReadAngle( p_input ); if( ( p_dvd->i_angle <= 0 ) || p_dvd->i_angle > p_dvd->i_angle_nb ) { p_dvd->i_angle = 1; } - - input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) ); - p_input->stream.p_selected_program = p_input->stream.pp_programs[0]; - - for( i = 1 ; i < p_dvd->i_angle_nb ; i++ ) - { - input_AddProgram( p_input, i+1, 0 ); - } - + DVDSetProgram( p_input, p_input->stream.pp_programs[p_dvd->i_angle-1] ); - + + intf_WarnMsg( 3, "dvd info: title start: %d size: %d", + i_start, i_size ); + IfoPrintTitle( p_dvd ); /* No PSM to read in DVD mode, we already have all information */ p_input->stream.p_selected_program->b_is_ok = 1; + /* Find all ES in title with ifo data */ DVDReadVideo( p_input ); - DVDReadAudio( p_input ); - - DVDReadSPU( p_input ); + DVDReadSPU ( p_input ); - /* FIXME: hack to check that the demuxer is ready, and set - * the decoders */ if( p_input->p_demux_module ) { DVDLaunchDecoders( p_input ); @@ -486,49 +483,24 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area ) { p_area = p_input->stream.p_selected_area; } -#undef vts -#undef vmg - - /* - * Chapter selection - */ - if( p_area->i_part != p_dvd->i_chapter ) - { - if( ( p_area->i_part > 0 ) && - ( p_area->i_part <= p_area->i_part_nb )) - { - if( DVDChapterSelect( p_dvd, p_area->i_part ) < 0 ) - { - intf_ErrMsg( "dvd error: can't set chapter in area" ); - p_input->b_error = 1; - return -1; - } - - p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; - p_input->stream.p_selected_area->i_tell = - LB2OFF( p_dvd->i_start ) - p_area->i_start; + /* Chapter selection */ + p_dvd->i_chapter = DVDSetChapter( p_dvd, p_area->i_part ); - intf_WarnMsg( 4, "dvd info: chapter %d start at: %lld", - p_area->i_part, p_area->i_tell ); - } - else - { - p_area->i_part = 1; - p_dvd->i_chapter = 1; - } - } + p_input->stream.p_selected_area->i_tell = DVDTell; /* warn interface that something has changed */ p_input->stream.b_seekable = 1; - p_input->stream.b_changed = 1; + p_input->stream.b_changed = 1; return 0; } +#undef vts +#undef vmg #define title \ p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title - + /***************************************************************************** * DVDRead: reads data packets. ***************************************************************************** @@ -539,108 +511,49 @@ static int DVDRead( input_thread_t * p_input, byte_t * p_buffer, size_t i_count ) { thread_dvd_data_t * p_dvd; - int i_block_once; - int i_read_blocks; - int i_read_total; - int i_sector; + int i_read; int i_blocks; - boolean_t b_eoc; + int i_block_once = 0; p_dvd = (thread_dvd_data_t *)(p_input->p_access_data); - i_sector = 0; - i_read_total = 0; - i_read_blocks = 0; - b_eoc = 0; - + i_read = 0; i_blocks = OFF2LB(i_count); while( i_blocks ) { - i_sector = p_dvd->i_title_start + p_dvd->i_sector; - i_block_once = p_dvd->i_end_sector - p_dvd->i_sector + 1; - - /* Get the position of the next cell if we're at cell end */ - if( i_block_once <= 0 ) + if( ( i_block_once = __MIN( LbMaxOnce( p_dvd ), i_blocks ) ) <= 0 ) { - int i_angle; - - p_dvd->i_cell++; - p_dvd->i_angle_cell++; - - /* Find cell index in adress map */ - if( DVDFindSector( p_dvd ) < 0 ) - { - intf_ErrMsg( "dvd error: can't find next cell" ); - return 1; - } - - /* Position the fd pointer on the right address */ - if( ( i_sector = dvdcss_seek( p_dvd->dvdhandle, - p_dvd->i_title_start + p_dvd->i_sector, - DVDCSS_SEEK_MPEG ) ) < 0 ) - { - intf_ErrMsg( "dvd error: %s", - dvdcss_error( p_dvd->dvdhandle ) ); - return -1; - } - - /* update chapter : it will be easier when we have navigation - * ES support */ - if( p_dvd->i_chapter < ( p_dvd->i_chapter_nb - 1 ) ) - { - if( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 ) - { - i_angle = p_dvd->i_angle - 1; - } - else - { - i_angle = 0; - } - if( title.chapter_map.pi_start_cell[p_dvd->i_chapter] <= - ( p_dvd->i_prg_cell - i_angle + 1 ) ) - { - p_dvd->i_chapter++; - b_eoc = 1; - } - } - - i_block_once = p_dvd->i_end_sector - p_dvd->i_sector + 1; + /* EOT */ + break; } - /* The number of blocks read is the max between the requested - * value and the leaving block in the cell */ - if( i_block_once > i_blocks ) + if( i_block_once != dvdcss_read( p_dvd->dvdhandle, p_buffer, + i_block_once, DVDCSS_READ_DECRYPT ) ) { - i_block_once = i_blocks; + return -1; } - /* Reads from DVD */ - i_read_blocks = dvdcss_read( p_dvd->dvdhandle, p_buffer, - i_block_once, DVDCSS_READ_DECRYPT ); - - i_blocks -= i_read_blocks; - p_buffer += LB2OFF( i_read_blocks ); - i_read_total += i_read_blocks; + i_blocks -= i_block_once; + i_read += i_block_once; + p_buffer += LB2OFF( i_block_once ); /* Update global position */ - p_dvd->i_sector += i_read_blocks; + p_dvd->i_vts_lb += i_block_once; } vlc_mutex_lock( &p_input->stream.stream_lock ); - p_input->stream.p_selected_area->i_tell = - LB2OFF( i_sector + i_read_total ) - - p_input->stream.p_selected_area->i_start; - if( b_eoc ) + p_input->stream.p_selected_area->i_tell += LB2OFF( i_read ); + if( p_dvd->b_new_chapter ) { - /* We modify i_part only at end of chapter not to erase - * some modification from the interface */ p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; + p_dvd->b_new_chapter = 0; } - if( p_input->stream.p_selected_area->i_tell + if( ( p_input->stream.p_selected_area->i_tell >= p_input->stream.p_selected_area->i_size ) + || ( i_block_once < 0 ) ) { if( ( p_dvd->i_title + 1 ) >= p_input->stream.i_area_nb ) { @@ -657,7 +570,7 @@ static int DVDRead( input_thread_t * p_input, vlc_mutex_unlock( &p_input->stream.stream_lock ); - return LB2OFF( i_read_total ); + return LB2OFF( i_read ); } /***************************************************************************** @@ -670,101 +583,30 @@ static int DVDRead( input_thread_t * p_input, static void DVDSeek( input_thread_t * p_input, off_t i_off ) { thread_dvd_data_t * p_dvd; - int i_block; - int i_prg_cell; - int i_cell; - int i_chapter; - int i_angle; p_dvd = ( thread_dvd_data_t * )(p_input->p_access_data); vlc_mutex_lock( &p_input->stream.stream_lock ); - /* we have to take care of offset of beginning of title */ - p_dvd->i_sector = OFF2LB(i_off + p_input->stream.p_selected_area->i_start) - - p_dvd->i_title_start; + p_dvd->i_vts_lb = OFF2LB(i_off + p_input->stream.p_selected_area->i_start) + - p_dvd->i_vts_start; vlc_mutex_unlock( &p_input->stream.stream_lock ); - i_prg_cell = 0; - i_chapter = 0; - - /* parse vobu address map to find program cell */ - while( title.p_cell_play[i_prg_cell].i_end_sector < p_dvd->i_sector ) - { - i_prg_cell++; - } - - p_dvd->i_prg_cell = i_prg_cell; - - if( DVDChooseAngle( p_dvd ) < 0 ) - { - p_input->b_error = 1; - return; - } - - p_dvd->i_cell = 0; - - /* Find first title cell which is inside program cell */ - if( DVDFindCell( p_dvd ) < 0 ) - { - /* no following cell : we're at eof */ - intf_ErrMsg( "dvd error: cell seeking failed" ); - p_input->b_error = 1; - return; - } - - i_cell = p_dvd->i_cell; - -#define cell p_dvd->p_ifo->vts.cell_inf.p_cell_map[i_cell] - /* parse cell address map to find title cell containing sector */ - while( cell.i_end_sector < p_dvd->i_sector ) - { - i_cell++; - } - - p_dvd->i_cell = i_cell; - - /* if we're inside a multi-angle zone, we have to choose i_sector - * in the current angle ; we can't do it all the time since cells - * can be very wide out of such zones */ - if( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 ) - { - p_dvd->i_sector = __MAX( - cell.i_start_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_start_sector ); - } - - p_dvd->i_end_sector = __MIN( - cell.i_end_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); -#undef cell - /* update chapter */ - if( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 ) - { - i_angle = p_dvd->i_angle - 1; - } - else - { - i_angle = 0; - } - if( p_dvd->i_chapter_nb > 1 ) - { - while( ( title.chapter_map.pi_start_cell[i_chapter] <= - ( p_dvd->i_prg_cell - i_angle + 1 ) ) && - ( i_chapter < ( p_dvd->i_chapter_nb - 1 ) ) ) - { - i_chapter++; - } - } - else + p_dvd->i_prg_cell = Lb2CellPrg( p_dvd ); + p_dvd->i_map_cell = Lb2CellMap( p_dvd ); + + if( CellIsInterleaved( p_dvd ) ) { - i_chapter = 1; + /* if we're inside a multi-angle zone, we have to choose i_sector + * in the current angle ; we can't do it all the time since cells + * can be very wide out of such zones */ + p_dvd->i_vts_lb = CellStartSector( p_dvd ); } + + p_dvd->i_end_lb = CellEndSector ( p_dvd ); + p_dvd->i_chapter = CellPrg2Chapter( p_dvd ); - p_dvd->i_chapter = i_chapter; - - if( ( i_block = dvdcss_seek( p_dvd->dvdhandle, - p_dvd->i_title_start + p_dvd->i_sector, - DVDCSS_SEEK_MPEG ) ) < 0 ) + if( dvdcss_seek( p_dvd->dvdhandle, DVDLB, + DVDCSS_SEEK_MPEG ) < 0 ) { intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); p_input->b_error = 1; @@ -773,12 +615,11 @@ static void DVDSeek( input_thread_t * p_input, off_t i_off ) vlc_mutex_lock( &p_input->stream.stream_lock ); p_input->stream.p_selected_area->i_part = p_dvd->i_chapter; - p_input->stream.p_selected_area->i_tell = - LB2OFF ( i_block ) - p_input->stream.p_selected_area->i_start; + p_input->stream.p_selected_area->i_tell = DVDTell; vlc_mutex_unlock( &p_input->stream.stream_lock ); - intf_WarnMsg( 4, "Program Cell: %d Cell: %d Chapter: %d", - p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter ); + intf_WarnMsg( 4, "Program Cell: %d Cell: %d Chapter: %d tell %lld", + p_dvd->i_prg_cell, p_dvd->i_map_cell, p_dvd->i_chapter, DVDTell ); return; } diff --git a/plugins/dvd/dvd_es.c b/plugins/dvd/dvd_es.c index 44d6743cab..835c6721c9 100644 --- a/plugins/dvd/dvd_es.c +++ b/plugins/dvd/dvd_es.c @@ -1,7 +1,7 @@ /* dvd_es.c: functions to find and select ES ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_es.c,v 1.1 2002/03/06 01:20:56 stef Exp $ + * $Id: dvd_es.c,v 1.2 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -70,27 +70,37 @@ void DVDLaunchDecoders( input_thread_t * p_input ); #define vmg p_dvd->p_ifo->vmg #define vts p_dvd->p_ifo->vts +#define ADDES( stream_id, private_id, type, cat, lang ) \ + i_id = ( (private_id) << 8 ) | (stream_id); \ + p_es = input_AddES( p_input, NULL, i_id, 0 ); \ + p_es->i_stream_id = (stream_id); \ + p_es->i_type = (type); \ + p_es->i_cat = (cat); \ + if( lang ) \ + { \ + strcpy( p_es->psz_desc, DecodeLanguage( hton16( lang ) ) ); \ + } + + /***************************************************************************** - * DVDReadVideo + * DVDReadVideo: read video ES *****************************************************************************/ void DVDReadVideo( input_thread_t * p_input ) { thread_dvd_data_t * p_dvd; es_descriptor_t * p_es; + int i_id; p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); /* ES 0 -> video MPEG2 */ IfoPrintVideo( p_dvd ); - p_es = input_AddES( p_input, NULL, 0xe0, 0 ); - p_es->i_stream_id = 0xe0; - p_es->i_type = MPEG2_VIDEO_ES; - p_es->i_cat = VIDEO_ES; + ADDES( 0xe0, 0, MPEG2_VIDEO_ES, VIDEO_ES, 0 ); } /***************************************************************************** - * DVDReadAudio + * DVDReadAudio: read audio ES *****************************************************************************/ #define audio_status \ vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1] @@ -99,10 +109,12 @@ void DVDReadAudio( input_thread_t * p_input ) { thread_dvd_data_t * p_dvd; es_descriptor_t * p_es; + int i_lang; int i_id; int i; p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + p_dvd->i_audio_nb = 0; /* Audio ES, in the order they appear in .ifo */ for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ ) @@ -113,44 +125,30 @@ void DVDReadAudio( input_thread_t * p_input ) if( audio_status.i_available ) { p_dvd->i_audio_nb++; + i_lang = vts.manager_inf.p_audio_attr[i-1].i_lang_code; + i_id = audio_status.i_position; switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode ) { case 0x00: /* AC3 */ - i_id = ( ( 0x80 + audio_status.i_position ) << 8 ) | 0xbd; - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = 0xbd; - p_es->i_type = AC3_AUDIO_ES; + ADDES( 0xbd, 0x80 + audio_status.i_position, + AC3_AUDIO_ES, AUDIO_ES, i_lang ); p_es->b_audio = 1; - p_es->i_cat = AUDIO_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); strcat( p_es->psz_desc, " (ac3)" ); break; case 0x02: case 0x03: /* MPEG audio */ - i_id = 0xc0 + audio_status.i_position; - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = i_id; - p_es->i_type = MPEG2_AUDIO_ES; + ADDES( 0xc0 + audio_status.i_position, 0, + MPEG2_AUDIO_ES, AUDIO_ES, i_lang ); p_es->b_audio = 1; - p_es->i_cat = AUDIO_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); strcat( p_es->psz_desc, " (mpeg)" ); break; case 0x04: /* LPCM */ - - i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd; - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = 0xbd; - p_es->i_type = LPCM_AUDIO_ES; + ADDES( 0xbd, 0xa0 + audio_status.i_position, + LPCM_AUDIO_ES, AUDIO_ES, i_lang ); p_es->b_audio = 1; - p_es->i_cat = AUDIO_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); strcat( p_es->psz_desc, " (lpcm)" ); break; @@ -170,7 +168,7 @@ void DVDReadAudio( input_thread_t * p_input ) #undef audio_status /***************************************************************************** - * DVDReadSPU: Read subpictures ES + * DVDReadSPU: read subpictures ES *****************************************************************************/ #define spu_status \ vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1] @@ -183,6 +181,7 @@ void DVDReadSPU( input_thread_t * p_input ) int i; p_dvd = (thread_dvd_data_t*)(p_input->p_access_data); + p_dvd->i_spu_nb = 0; for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ ) { @@ -199,31 +198,24 @@ void DVDReadSPU( input_thread_t * p_input ) switch( vts.manager_inf.video_attr.i_perm_displ ) { case 1: - i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 ) - | 0xbd; + i_id = spu_status.i_position_pan; break; case 2: - i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 ) - | 0xbd; + i_id = spu_status.i_position_letter; break; default: - i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 ) - | 0xbd; + i_id = spu_status.i_position_wide; break; } } else { /* 4:3 */ - i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 ) - | 0xbd; + i_id = spu_status.i_position_43; } - p_es = input_AddES( p_input, NULL, i_id, 0 ); - p_es->i_stream_id = 0xbd; - p_es->i_type = DVD_SPU_ES; - p_es->i_cat = SPU_ES; - strcpy( p_es->psz_desc, DecodeLanguage( hton16( - vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) ); + + ADDES( 0xbd, 0x20 + i_id, DVD_SPU_ES, SPU_ES, + vts.manager_inf.p_spu_attr[i-1].i_lang_code ); } } } @@ -233,7 +225,7 @@ void DVDReadSPU( input_thread_t * p_input ) #undef vmg /***************************************************************************** - * DVDLaunchDecoders + * DVDLaunchDecoders: select ES for video, audio and spu *****************************************************************************/ void DVDLaunchDecoders( input_thread_t * p_input ) { @@ -250,44 +242,42 @@ void DVDLaunchDecoders( input_thread_t * p_input ) } /* Select audio stream */ - if( p_main->b_audio ) + if( p_main->b_audio && p_dvd->i_audio_nb > 0 ) { /* For audio: first one if none or a not existing one specified */ i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR ); - if( i_audio < 0 || i_audio > p_dvd->i_audio_nb ) + if( i_audio <= 0 || i_audio > p_dvd->i_audio_nb ) { config_PutIntVariable( INPUT_CHANNEL_VAR, 1 ); i_audio = 1; } - if( i_audio > 0 && p_dvd->i_audio_nb > 0 ) + + if( config_GetIntVariable( AOUT_SPDIF_VAR ) || + ( config_GetIntVariable( INPUT_AUDIO_VAR ) == + REQUESTED_AC3 ) ) { - if( config_GetIntVariable( AOUT_SPDIF_VAR ) || - ( config_GetIntVariable( INPUT_AUDIO_VAR ) == - REQUESTED_AC3 ) ) + int i_ac3 = i_audio; + while( ( p_input->stream.pp_es[i_ac3]->i_type != + AC3_AUDIO_ES ) && ( i_ac3 <= + p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) ) { - int i_ac3 = i_audio; - while( ( p_input->stream.pp_es[i_ac3]->i_type != - AC3_AUDIO_ES ) && ( i_ac3 <= - p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) ) - { - i_ac3++; - } - if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES ) - { - input_SelectES( p_input, - p_input->stream.pp_es[i_ac3] ); - } + i_ac3++; } - else + if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES ) { input_SelectES( p_input, - p_input->stream.pp_es[i_audio] ); + p_input->stream.pp_es[i_ac3] ); } } + else + { + input_SelectES( p_input, + p_input->stream.pp_es[i_audio] ); + } } /* Select subtitle */ - if( p_main->b_video ) + if( p_main->b_video && p_dvd->i_spu_nb > 0 ) { /* for spu, default is none */ i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR ); @@ -296,7 +286,7 @@ void DVDLaunchDecoders( input_thread_t * p_input ) config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 ); i_spu = 0; } - if( i_spu > 0 && p_dvd->i_spu_nb > 0 ) + if( i_spu > 0 ) { i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb; input_SelectES( p_input, p_input->stream.pp_es[i_spu] ); diff --git a/plugins/dvd/dvd_ifo.c b/plugins/dvd/dvd_ifo.c index 1258d38eea..e62c7093f8 100644 --- a/plugins/dvd/dvd_ifo.c +++ b/plugins/dvd/dvd_ifo.c @@ -2,7 +2,7 @@ * dvd_ifo.c: Functions for ifo parsing ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: dvd_ifo.c,v 1.44 2002/03/06 01:20:56 stef Exp $ + * $Id: dvd_ifo.c,v 1.45 2002/03/08 22:58:12 stef Exp $ * * Authors: Stéphane Borel * German Tischler @@ -438,7 +438,7 @@ int IfoInit( ifo_t * p_ifo ) /***************************************************************************** * IfoTitleSet: Parse vts*.ifo files to fill the Video Title Set structure. *****************************************************************************/ -int IfoTitleSet( ifo_t * p_ifo ) +int IfoTitleSet( ifo_t * p_ifo, int i_title ) { u8 p_buf[DVD_LB_SIZE]; u8 * p_tmp; @@ -453,7 +453,7 @@ int IfoTitleSet( ifo_t * p_ifo ) FreeTitleSet( &p_ifo->vts ); } - i_off = p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_start_sector + i_off = p_ifo->vmg.title_inf.p_attr[i_title-1].i_start_sector + p_ifo->i_start; //fprintf(stderr, "offset: %d\n" , i_off ); @@ -748,8 +748,8 @@ int IfoTitleSet( ifo_t * p_ifo ) } #undef MGINF - intf_WarnMsg( 2, "ifo info: vts %d initialized", - p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_title_set_num ); + intf_WarnMsg( 4, "ifo info: vts %d initialized", + p_ifo->vmg.title_inf.p_attr[i_title-1].i_title_set_num ); p_ifo->vts.b_initialized = 1; diff --git a/plugins/dvd/dvd_ifo.h b/plugins/dvd/dvd_ifo.h index 309e507bda..6758e261f0 100644 --- a/plugins/dvd/dvd_ifo.h +++ b/plugins/dvd/dvd_ifo.h @@ -2,7 +2,7 @@ * dvd_ifo.h: Structures for ifo parsing ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: dvd_ifo.h,v 1.17 2001/06/12 22:14:44 sam Exp $ + * $Id: dvd_ifo.h,v 1.18 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -543,7 +543,6 @@ typedef struct ifo_s int i_pos; /* Position of stream pointer */ boolean_t b_error; /* Error Management */ vmg_t vmg; /* Structure described in video_ts */ - int i_title; /* Current title number */ vts_t vts; /* Vts ifo for current title set */ /* Remap buffer for unaligned reads */ @@ -559,6 +558,6 @@ struct thread_dvd_data_s; int IfoCreate ( struct thread_dvd_data_s * ); int IfoInit ( struct ifo_s * ); -int IfoTitleSet ( struct ifo_s * ); +int IfoTitleSet ( struct ifo_s *, int ); void IfoDestroy ( struct ifo_s * ); diff --git a/plugins/dvd/dvd_seek.c b/plugins/dvd/dvd_seek.c index 9c6b3f639b..7254722622 100644 --- a/plugins/dvd/dvd_seek.c +++ b/plugins/dvd/dvd_seek.c @@ -1,7 +1,7 @@ /* dvd_seek.c: functions to navigate through DVD. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_seek.c,v 1.1 2002/03/06 01:20:56 stef Exp $ + * $Id: dvd_seek.c,v 1.2 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -64,159 +64,255 @@ p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title #define cell p_dvd->p_ifo->vts.cell_inf -/***************************************************************************** - * DVDFindCell: adjust the title cell index with the program cell - *****************************************************************************/ -int DVDFindCell( thread_dvd_data_t * p_dvd ) +int CellIsInterleaved( thread_dvd_data_t * p_dvd ) +{ + return title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000; +} + +u32 CellPrg2Map( thread_dvd_data_t * p_dvd ) { - int i_cell; - int i_index; + u32 i_cell; - i_cell = p_dvd->i_cell; - i_index = p_dvd->i_prg_cell; + i_cell = p_dvd->i_map_cell; if( i_cell >= cell.i_cell_nb ) { return -1; } - while( ( ( title.p_cell_pos[i_index].i_vob_id != + while( ( ( title.p_cell_pos[p_dvd->i_prg_cell].i_vob_id != cell.p_cell_map[i_cell].i_vob_id ) || - ( title.p_cell_pos[i_index].i_cell_id != + ( title.p_cell_pos[p_dvd->i_prg_cell].i_cell_id != cell.p_cell_map[i_cell].i_cell_id ) ) && - ( i_cell < cell.i_cell_nb - 1 ) ) + ( i_cell < cell.i_cell_nb ) ) { i_cell++; } + + if( i_cell >= cell.i_cell_nb ) + { + return -1; + } -/* -intf_WarnMsg( 12, "FindCell: i_cell %d i_index %d found %d nb %d", - p_dvd->i_cell, - p_dvd->i_prg_cell, - i_cell, - cell.i_cell_nb ); -*/ + return i_cell; +} - p_dvd->i_cell = i_cell; +u32 CellAngleOffset( thread_dvd_data_t * p_dvd, u32 i_prg_cell ) +{ + u32 i_cell_off; + + /* basic handling of angles */ + switch( ( ( title.p_cell_play[i_prg_cell].i_category & 0xf000 ) + >> 12 ) ) + { + /* we enter a muli-angle section */ + case 0x5: + i_cell_off = p_dvd->i_angle - 1; + p_dvd->i_angle_cell = 0; + break; + /* we exit a multi-angle section */ + case 0x9: + case 0xd: + i_cell_off = p_dvd->i_angle_nb - p_dvd->i_angle; + break; + default: + i_cell_off = 0; + } - return 0; + return i_cell_off; } -#undef cell - -/***************************************************************************** - * DVDFindSector: find cell index in adress map from index in - * information table program map and give corresponding sectors. - *****************************************************************************/ -int DVDFindSector( thread_dvd_data_t * p_dvd ) +u32 CellStartSector( thread_dvd_data_t * p_dvd ) { + return __MAX( cell.p_cell_map[p_dvd->i_map_cell].i_start_sector, + title.p_cell_play[p_dvd->i_prg_cell].i_start_sector ); +} + +u32 CellEndSector( thread_dvd_data_t * p_dvd ) +{ + return __MIN( cell.p_cell_map[p_dvd->i_map_cell].i_end_sector, + title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); +} - if( p_dvd->i_sector > title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ) +u32 NextCellPrg( thread_dvd_data_t * p_dvd ) +{ + u32 i_cell = p_dvd->i_prg_cell; + + if( p_dvd->i_vts_lb > title.p_cell_play[i_cell].i_end_sector ) { - p_dvd->i_prg_cell++; + i_cell ++; + i_cell += CellAngleOffset( p_dvd, i_cell ); - if( DVDChooseAngle( p_dvd ) < 0 ) + if( i_cell >= title.i_cell_nb ) { return -1; } } + + return i_cell; +} - if( DVDFindCell( p_dvd ) < 0 ) +u32 Lb2CellPrg( thread_dvd_data_t * p_dvd ) +{ + u32 i_cell = 0; + + while( p_dvd->i_vts_lb > title.p_cell_play[i_cell].i_end_sector ) { - intf_ErrMsg( "dvd error: can't find sector" ); - return -1; + i_cell ++; + i_cell += CellAngleOffset( p_dvd, i_cell ); + + if( i_cell >= title.i_cell_nb ) + { + return -1; + } } - /* Find start and end sectors of new cell */ -#if 1 - p_dvd->i_sector = __MAX( - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_start_sector ); - p_dvd->i_end_sector = __MIN( - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_end_sector ); -#else - p_dvd->i_sector = title.p_cell_play[p_dvd->i_prg_cell].i_start_sector; - p_dvd->i_end_sector = title.p_cell_play[p_dvd->i_prg_cell].i_end_sector; -#endif - -/* - intf_WarnMsg( 12, "cell: %d sector1: 0x%x end1: 0x%x\n" - "index: %d sector2: 0x%x end2: 0x%x\n" - "category: 0x%x ilvu end: 0x%x vobu start 0x%x", - p_dvd->i_cell, - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_start_sector, - p_dvd->p_ifo->vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector, - p_dvd->i_prg_cell, - title.p_cell_play[p_dvd->i_prg_cell].i_start_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_end_sector, - title.p_cell_play[p_dvd->i_prg_cell].i_category, - title.p_cell_play[p_dvd->i_prg_cell].i_first_ilvu_vobu_esector, - title.p_cell_play[p_dvd->i_prg_cell].i_last_vobu_start_sector ); -*/ - - return 0; + return i_cell; } -/***************************************************************************** - * DVDChapterSelect: find the cell corresponding to requested chapter - *****************************************************************************/ -int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter ) +u32 Lb2CellMap( thread_dvd_data_t * p_dvd ) { + u32 i_cell = 0; + + while( p_dvd->i_vts_lb > cell.p_cell_map[i_cell].i_end_sector ) + { + i_cell ++; - /* Find cell index in Program chain for current chapter */ - p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1; - p_dvd->i_cell = 0; - p_dvd->i_sector = 0; + if( i_cell >= cell.i_cell_nb ) + { + return -1; + } + } + + return i_cell; +} - DVDChooseAngle( p_dvd ); +u32 LbMaxOnce( thread_dvd_data_t * p_dvd ) +{ + u32 i_block_once = p_dvd->i_end_lb - p_dvd->i_vts_lb + 1; - /* Search for cell_index in cell adress_table and initialize - * start sector */ - if( DVDFindSector( p_dvd ) < 0 ) + /* Get the position of the next cell if we're at cell end */ + if( i_block_once <= 0 ) { - intf_ErrMsg( "dvd error: can't select chapter" ); - return -1; + p_dvd->i_map_cell++; + p_dvd->i_angle_cell++; + + if( ( p_dvd->i_prg_cell = NextCellPrg( p_dvd ) ) < 0 ) + { + /* EOF */ + return 0; + } + + if( ( p_dvd->i_map_cell = CellPrg2Map( p_dvd ) ) < 0 ) + { + return 0; + } + + p_dvd->i_vts_lb = CellStartSector( p_dvd ); + p_dvd->i_end_lb = CellEndSector( p_dvd ); + + /* Position the fd pointer on the right address */ + if( ( dvdcss_seek( p_dvd->dvdhandle, + p_dvd->i_vts_start + p_dvd->i_vts_lb, + DVDCSS_SEEK_MPEG ) ) < 0 ) + { + intf_ErrMsg( "dvd error: %s", + dvdcss_error( p_dvd->dvdhandle ) ); + return 0; + } + + p_dvd->i_chapter = NextChapter( p_dvd ); + + i_block_once = p_dvd->i_end_lb - p_dvd->i_vts_lb + 1; } - /* start is : beginning of vts vobs + offset to vob x */ - p_dvd->i_start = p_dvd->i_title_start + p_dvd->i_sector; + return i_block_once; +} + - /* Position the fd pointer on the right address */ - if( ( p_dvd->i_start = dvdcss_seek( p_dvd->dvdhandle, - p_dvd->i_start, - DVDCSS_SEEK_MPEG ) ) < 0 ) +int CellPrg2Chapter( thread_dvd_data_t * p_dvd ) +{ + int i_chapter = 1; + int i_cell = p_dvd->i_prg_cell; + + if( CellIsInterleaved( p_dvd ) ) { - intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); - return -1; + i_cell -= (p_dvd->i_angle - 1); + } + + while( title.chapter_map.pi_start_cell[i_chapter] <= i_cell+1 ) + { + i_chapter ++; + if( i_chapter >= p_dvd->i_chapter_nb ) + { + return p_dvd->i_chapter_nb; + } } - p_dvd->i_chapter = i_chapter; - return 0; + return i_chapter; } -/***************************************************************************** - * DVDChooseAngle: select the cell corresponding to the selected angle - *****************************************************************************/ -int DVDChooseAngle( thread_dvd_data_t * p_dvd ) +int NextChapter( thread_dvd_data_t * p_dvd ) { - /* basic handling of angles */ - switch( ( ( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 ) - >> 12 ) ) + int i_cell = p_dvd->i_prg_cell; + + if( CellIsInterleaved( p_dvd ) ) { - /* we enter a muli-angle section */ - case 0x5: - p_dvd->i_prg_cell += p_dvd->i_angle - 1; - p_dvd->i_angle_cell = 0; - break; - /* we exit a multi-angle section */ - case 0x9: - case 0xd: - p_dvd->i_prg_cell += p_dvd->i_angle_nb - p_dvd->i_angle; - break; + i_cell -= (p_dvd->i_angle - 1); + } + + if( title.chapter_map.pi_start_cell[p_dvd->i_chapter] <= i_cell+1 ) + { + p_dvd->i_chapter++; + if( p_dvd->i_chapter >= p_dvd->i_chapter_nb ) + { + return 0; + } + p_dvd->b_new_chapter = 1; + return p_dvd->i_chapter; } - return 0; + return p_dvd->i_chapter; } + + +int DVDSetChapter( thread_dvd_data_t * p_dvd, int i_chapter ) +{ + if( i_chapter <= 0 || i_chapter > p_dvd->i_chapter_nb ) + { + i_chapter = 1; + } + + if( p_dvd->i_chapter != i_chapter ) + { + /* Find cell index in Program chain for current chapter */ + p_dvd->i_prg_cell = title.chapter_map.pi_start_cell[i_chapter-1] - 1; + p_dvd->i_prg_cell += CellAngleOffset( p_dvd, p_dvd->i_prg_cell ); + if( i_chapter < p_dvd->i_chapter ) + { + p_dvd->i_map_cell = 0; + } + p_dvd->i_map_cell = CellPrg2Map( p_dvd ); + p_dvd->i_vts_lb = CellStartSector( p_dvd ); + p_dvd->i_end_lb = CellEndSector( p_dvd ); + + /* Position the fd pointer on the right address */ + if( dvdcss_seek( p_dvd->dvdhandle, + p_dvd->i_vts_start + p_dvd->i_vts_lb, + DVDCSS_SEEK_MPEG ) < 0 ) + { + intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) ); + return -1; + } + + intf_WarnMsg( 4, "dvd info: chapter %d prg_cell %d map_cell %d", + i_chapter, p_dvd->i_prg_cell, p_dvd->i_map_cell ); + } + + return i_chapter; +} + + +#undef cell #undef title diff --git a/plugins/dvd/dvd_seek.h b/plugins/dvd/dvd_seek.h index feba1b48b3..7204f82b39 100644 --- a/plugins/dvd/dvd_seek.h +++ b/plugins/dvd/dvd_seek.h @@ -1,7 +1,7 @@ /* dvd_seek.h: DVD access plugin. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_seek.h,v 1.1 2002/03/06 01:20:56 stef Exp $ + * $Id: dvd_seek.h,v 1.2 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -20,7 +20,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ -int DVDChooseAngle( thread_dvd_data_t * ); -int DVDFindCell( thread_dvd_data_t * ); -int DVDFindSector( thread_dvd_data_t * ); -int DVDChapterSelect( thread_dvd_data_t *, int ); +int CellIsInterleaved( thread_dvd_data_t * ); +u32 CellAngleOffset ( thread_dvd_data_t *, u32 ); +u32 CellPrg2Map ( thread_dvd_data_t * ); +u32 CellStartSector ( thread_dvd_data_t * ); +u32 CellEndSector ( thread_dvd_data_t * ); + +u32 NextCellPrg ( thread_dvd_data_t * ); +u32 Lb2CellPrg ( thread_dvd_data_t * ); +u32 Lb2CellMap ( thread_dvd_data_t * ); +u32 LbMaxOnce ( thread_dvd_data_t * ); + +int CellPrg2Chapter ( thread_dvd_data_t * ); +int NextChapter ( thread_dvd_data_t * ); +int DVDSetChapter ( thread_dvd_data_t *, int ); + diff --git a/plugins/dvd/dvd_summary.c b/plugins/dvd/dvd_summary.c index 79f5ff43d8..d3289cad59 100644 --- a/plugins/dvd/dvd_summary.c +++ b/plugins/dvd/dvd_summary.c @@ -3,7 +3,7 @@ * found in .ifo. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: dvd_summary.c,v 1.14 2002/03/06 01:20:56 stef Exp $ + * $Id: dvd_summary.c,v 1.15 2002/03/08 22:58:12 stef Exp $ * * Author: Stéphane Borel * @@ -68,13 +68,11 @@ ****************************************************************************/ void IfoPrintTitle( thread_dvd_data_t * p_dvd ) { - intf_WarnMsg( 5, "dvd info: title %d, %d chapter%s, %d angle%s, " - "vobstart at %d blocks, stream size %d blocks", + intf_WarnMsg( 5, "dvd info: title %d, %d chapter%s, %d angle%s", p_dvd->i_title, p_dvd->i_chapter_nb, (p_dvd->i_chapter_nb == 1) ? "" : "s", p_dvd->i_angle_nb, - (p_dvd->i_angle_nb == 1) ? "" : "s", - p_dvd->i_start, p_dvd->i_size ); + (p_dvd->i_angle_nb == 1) ? "" : "s" ); } /****************************************************************************