/*****************************************************************************
* input_dvd.c: DVD raw reading plugin.
- * ---
+ *****************************************************************************
* This plugins should handle all the known specificities of the DVD format,
* especially the 2048 bytes logical block size.
* It depends on:
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.50 2001/04/27 19:29:11 massiot Exp $
+ * $Id: input_dvd.c,v 1.61 2001/05/30 17:03:12 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
#include <sys/uio.h>
#include <string.h>
+#ifdef STRNCASECMP_IN_STRINGS_H
+# include <strings.h>
+#endif
#include <errno.h>
#include "config.h"
#include "dvd_netlist.h"
#include "dvd_ifo.h"
#include "dvd_css.h"
+#include "dvd_summary.h"
#include "input_dvd.h"
#include "mpeg_system.h"
#include "modules.h"
-/*****************************************************************************
- * Local tables
- *****************************************************************************/
-static struct
-{
- char p_code[3];
- char p_lang_long[20];
-}
-
-lang_tbl[] =
-{
- /* The ISO 639 language codes.
- * Language names with * prefix are not spelled in their own language
- */
- { " ", "Not Specified" },
- { "aa", "*Afar" },
- { "ab", "*Abkhazian" },
- { "af", "*Afrikaans" },
- { "am", "*Amharic" },
- { "ar", "*Arabic" },
- { "as", "*Assamese" },
- { "ay", "*Aymara" },
- { "az", "*Azerbaijani" },
- { "ba", "*Bashkir" },
- { "be", "*Byelorussian" },
- { "bg", "*Bulgarian" },
- { "bh", "*Bihari" },
- { "bi", "*Bislama" },
- { "bn", "*Bengali; Bangla" },
- { "bo", "*Tibetan" },
- { "br", "*Breton" },
- { "ca", "*Catalan" },
- { "co", "*Corsican" },
- { "cs", "*Czech(Ceske)" },
- { "cy", "*Welsh" },
- { "da", "Dansk" },
- { "de", "Deutsch" },
- { "dz", "*Bhutani" },
- { "el", "*Greek" },
- { "en", "English" },
- { "eo", "*Esperanto" },
- { "es", "Espanol" },
- { "et", "*Estonian" },
- { "eu", "*Basque" },
- { "fa", "*Persian" },
- { "fi", "Suomi" },
- { "fj", "*Fiji" },
- { "fo", "*Faroese" },
- { "fr", "Francais" },
- { "fy", "*Frisian" },
- { "ga", "*Irish" },
- { "gd", "*Scots Gaelic" },
- { "gl", "*Galician" },
- { "gn", "*Guarani" },
- { "gu", "*Gujarati" },
- { "ha", "*Hausa" },
- { "he", "*Hebrew" }, /* formerly iw */
- { "hi", "*Hindi" },
- { "hr", "Hrvatski" }, /* Croatian */
- { "hu", "Magyar" },
- { "hy", "*Armenian" },
- { "ia", "*Interlingua" },
- { "id", "*Indonesian" }, /* formerly in */
- { "ie", "*Interlingue" },
- { "ik", "*Inupiak" },
- { "in", "*Indonesian" }, /* replaced by id */
- { "is", "Islenska" },
- { "it", "Italiano" },
- { "iu", "*Inuktitut" },
- { "iw", "*Hebrew" }, /* replaced by he */
- { "ja", "*Japanese" },
- { "ji", "*Yiddish" }, /* replaced by yi */
- { "jw", "*Javanese" },
- { "ka", "*Georgian" },
- { "kk", "*Kazakh" },
- { "kl", "*Greenlandic" },
- { "km", "*Cambodian" },
- { "kn", "*Kannada" },
- { "ko", "*Korean" },
- { "ks", "*Kashmiri" },
- { "ku", "*Kurdish" },
- { "ky", "*Kirghiz" },
- { "la", "*Latin" },
- { "ln", "*Lingala" },
- { "lo", "*Laothian" },
- { "lt", "*Lithuanian" },
- { "lv", "*Latvian, Lettish" },
- { "mg", "*Malagasy" },
- { "mi", "*Maori" },
- { "mk", "*Macedonian" },
- { "ml", "*Malayalam" },
- { "mn", "*Mongolian" },
- { "mo", "*Moldavian" },
- { "mr", "*Marathi" },
- { "ms", "*Malay" },
- { "mt", "*Maltese" },
- { "my", "*Burmese" },
- { "na", "*Nauru" },
- { "ne", "*Nepali" },
- { "nl", "Nederlands" },
- { "no", "Norsk" },
- { "oc", "*Occitan" },
- { "om", "*(Afan) Oromo" },
- { "or", "*Oriya" },
- { "pa", "*Punjabi" },
- { "pl", "*Polish" },
- { "ps", "*Pashto, Pushto" },
- { "pt", "Portugues" },
- { "qu", "*Quechua" },
- { "rm", "*Rhaeto-Romance" },
- { "rn", "*Kirundi" },
- { "ro", "*Romanian" },
- { "ru", "*Russian" },
- { "rw", "*Kinyarwanda" },
- { "sa", "*Sanskrit" },
- { "sd", "*Sindhi" },
- { "sg", "*Sangho" },
- { "sh", "*Serbo-Croatian" },
- { "si", "*Sinhalese" },
- { "sk", "*Slovak" },
- { "sl", "*Slovenian" },
- { "sm", "*Samoan" },
- { "sn", "*Shona" },
- { "so", "*Somali" },
- { "sq", "*Albanian" },
- { "sr", "*Serbian" },
- { "ss", "*Siswati" },
- { "st", "*Sesotho" },
- { "su", "*Sundanese" },
- { "sv", "Svenska" },
- { "sw", "*Swahili" },
- { "ta", "*Tamil" },
- { "te", "*Telugu" },
- { "tg", "*Tajik" },
- { "th", "*Thai" },
- { "ti", "*Tigrinya" },
- { "tk", "*Turkmen" },
- { "tl", "*Tagalog" },
- { "tn", "*Setswana" },
- { "to", "*Tonga" },
- { "tr", "*Turkish" },
- { "ts", "*Tsonga" },
- { "tt", "*Tatar" },
- { "tw", "*Twi" },
- { "ug", "*Uighur" },
- { "uk", "*Ukrainian" },
- { "ur", "*Urdu" },
- { "uz", "*Uzbek" },
- { "vi", "*Vietnamese" },
- { "vo", "*Volapuk" },
- { "wo", "*Wolof" },
- { "xh", "*Xhosa" },
- { "yi", "*Yiddish" }, /* formerly ji */
- { "yo", "*Yoruba" },
- { "za", "*Zhuang" },
- { "zh", "*Chinese" },
- { "zu", "*Zulu" },
- { "\0", "" }
-};
-
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int DVDRewind ( struct input_thread_s * );
/* called only inside */
-static char * Language( u16 );
static int DVDChooseAngle( thread_dvd_data_t * );
static int DVDFindCell( thread_dvd_data_t * );
static int DVDFindSector( thread_dvd_data_t * );
#define input p_function_list->functions.input
p_function_list->pf_probe = DVDProbe;
input.pf_init = DVDInit;
- input.pf_open = input_FileOpen;
- input.pf_close = input_FileClose;
+ input.pf_open = NULL; /* Set in DVDInit */
+ input.pf_close = NULL;
input.pf_end = DVDEnd;
input.pf_read = DVDRead;
input.pf_set_area = DVDSetArea;
#undef input
}
-/*
- * Local tools to decode some data in ifo
- */
-
-/*****************************************************************************
- * Language: gives the long language name from the two-letters ISO-639 code
- *****************************************************************************/
-static char * Language( u16 i_code )
-{
- int i = 0;
-
- while( memcmp( lang_tbl[i].p_code, &i_code, 2 ) &&
- lang_tbl[i].p_lang_long[0] )
- {
- i++;
- }
-
- return lang_tbl[i].p_lang_long;
-}
-
/*
* Data reading functions
*/
int i_chapter;
int i;
- /* I don't want DVDs to start playing immediately */
-// p_input->stream.i_new_status = PAUSE_S;
-
p_dvd = malloc( sizeof(thread_dvd_data_t) );
if( p_dvd == NULL )
{
p_input->p_plugin_data = (void *)p_dvd;
p_input->p_method_data = NULL;
+ /* Set callback */
+ p_input->pf_open = p_input->pf_file_open;
+ p_input->pf_close = p_input->pf_file_close;
+
p_dvd->i_fd = p_input->i_handle;
/* reading several block once seems to cause lock-up
* when using input_ToggleES
* who wrote thez damn buggy piece of shit ??? --stef */
- p_dvd->i_block_once = 1;//32;
- p_input->i_read_once = 8;//128;
+ p_dvd->i_block_once = 32;
+ p_input->i_read_once = 128;
i = CSSTest( p_input->i_handle );
if( i < 0 )
{
+ intf_ErrMsg( "dvd error: error in css" );
free( p_dvd );
p_input->b_error = 1;
return;
/* Reading structures initialisation */
p_input->p_method_data =
- DVDNetlistInit( 2048, 8192, 2048, DVD_LB_SIZE, p_dvd->i_block_once );
+ DVDNetlistInit( 2048, 4096, 2048, DVD_LB_SIZE, p_dvd->i_block_once );
intf_WarnMsg( 2, "dvd info: netlist initialized" );
/* Ifo allocation & initialisation */
p_area = p_input->stream.pp_areas[i_title];
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
/* set title, chapter, audio and subpic */
DVDSetArea( p_input, p_area );
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
return;
}
/*****************************************************************************
* DVDSetArea: initialize input data for title x, chapter y.
- * It should be called for each user navigation request, and to change
- * audio or sub-picture streams.
- * ---
+ * It should be called for each user navigation request.
+ *****************************************************************************
* Take care that i_title starts from 0 (vmg) and i_chapter start from 1.
- * i_audio, i_spu start from 1 ; 0 means off.
- * A negative value for an argument means it does not change
+ * Note that you have to take the lock before entering here.
*****************************************************************************/
static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
{
thread_dvd_data_t * p_dvd;
es_descriptor_t * p_es;
+ u16 i_id;
+ int i_vts_title;
int i_audio;
int i_spu;
- u16 i_id;
- u8 i_ac3;
- u8 i_mpeg;
- u8 i_sub_pic;
- u8 i;
+ int i;
int j;
- boolean_t b_last;
p_dvd = (thread_dvd_data_t*)p_input->p_plugin_data;
- vlc_mutex_lock( &p_input->stream.stream_lock );
+ /* 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 )
{
p_input->stream.p_selected_area =
p_input->stream.pp_areas[p_area->i_id];
+ /* release the lock to to let the interface go */
// vlc_mutex_unlock( &p_input->stream.stream_lock );
/* title number: it is not vts nb!,
p_dvd->i_title = p_area->i_id;
p_dvd->p_ifo->i_title = p_dvd->i_title;
- /* uodate title environnement variable so that we don't
- * loop on the same title forever */
- main_PutIntVariable( INPUT_TITLE_VAR, p_dvd->i_title + 1 );
+ /* set number of chapters of current title */
+ p_dvd->i_chapter_nb = p_area->i_part_nb;
/* ifo vts */
if( IfoTitleSet( p_dvd->p_ifo ) < 0 )
#define vmg p_dvd->p_ifo->vmg
#define vts p_dvd->p_ifo->vts
/* title position inside the selected vts */
- p_dvd->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[p_dvd->i_vts_title-1].i_title_id;
+ vts.title_inf.p_title_start[i_vts_title-1].i_title_id;
- intf_WarnMsg( 1, "dvd: title %d vts_title %d pgc %d",
+ intf_WarnMsg( 3, "dvd: title %d vts_title %d pgc %d",
p_dvd->i_title,
- p_dvd->i_vts_title,
+ i_vts_title,
p_dvd->i_title_id );
/* css title key for current vts */
{
p_dvd->i_cell = vts.cell_inf.i_cell_nb - 1;
}
-
-
+
p_dvd->i_sector = 0;
p_dvd->i_size = DVD_LB_SIZE *
(off_t)( vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
intf_WarnMsg( 2, "dvd info: stream size 1: %lld @ %d", p_dvd->i_size,
vts.cell_inf.p_cell_map[p_dvd->i_cell].i_end_sector );
-
+
if( DVDChapterSelect( p_dvd, 1 ) < 0 )
{
intf_ErrMsg( "dvd error: can't find first chapter" );
p_dvd->i_size -= (off_t)( p_dvd->i_sector + 1 ) *DVD_LB_SIZE;
- intf_WarnMsg( 2, "dvd info: title: %d", p_dvd->i_title );
- intf_WarnMsg( 2, "dvd info: vobstart at: %lld", p_dvd->i_start );
- intf_WarnMsg( 2, "dvd info: stream size: %lld", p_dvd->i_size );
- intf_WarnMsg( 2, "dvd info: number of chapters: %d",
- vmg.title_inf.p_attr[p_dvd->i_title-1].i_chapter_nb );
- intf_WarnMsg( 2, "dvd info: number of angles: %d", p_dvd->i_angle_nb );
+ IfoPrintTitle( p_dvd );
// vlc_mutex_lock( &p_input->stream.stream_lock );
p_es = NULL;
/* ES 0 -> video MPEG2 */
+ IfoPrintVideo( p_dvd );
+
p_es = input_AddES( p_input, p_input->stream.pp_programs[0], 0xe0, 0 );
p_es->i_stream_id = 0xe0;
p_es->i_type = MPEG2_VIDEO_ES;
{
input_SelectES( p_input, p_es );
}
+ intf_WarnMsg( 4, "dvd info: video selected" );
+#define audio_status \
+ vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
/* Audio ES, in the order they appear in .ifo */
-
- i_ac3 = 0x7f;
- i_mpeg = 0xc0;
-
for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
{
+ IfoPrintAudio( p_dvd, i );
- intf_WarnMsg( 1, "Audio %d: %x %x %x %x %x %x %x %x %x %x %x %x", i,
- vts.manager_inf.p_audio_attr[i-1].i_num_channels,
- vts.manager_inf.p_audio_attr[i-1].i_coding_mode,
- vts.manager_inf.p_audio_attr[i-1].i_multichannel_extension,
- vts.manager_inf.p_audio_attr[i-1].i_type,
- vts.manager_inf.p_audio_attr[i-1].i_appl_mode,
- vts.manager_inf.p_audio_attr[i-1].i_foo,
- vts.manager_inf.p_audio_attr[i-1].i_test,
- vts.manager_inf.p_audio_attr[i-1].i_bar,
- vts.manager_inf.p_audio_attr[i-1].i_quantization,
- vts.manager_inf.p_audio_attr[i-1].i_sample_freq,
- vts.manager_inf.p_audio_attr[i-1].i_lang_code,
- vts.manager_inf.p_audio_attr[i-1].i_caption );
-
- switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
+ /* audio channel is active if first byte is 0x80 */
+ if( audio_status.i_available )
{
- case 0x00: /* AC3 */
- i_id = ( ( i_ac3 + i ) << 8 ) | 0xbd;
- p_es = input_AddES( p_input,
+ 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,
+ p_input->stream.pp_programs[0], i_id, 0 );
+ p_es->i_stream_id = 0xbd;
+ p_es->i_type = AC3_AUDIO_ES;
+ p_es->b_audio = 1;
+ p_es->i_cat = AUDIO_ES;
+ strcpy( p_es->psz_desc, IfoLanguage( hton16(
+ vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
+ strcat( p_es->psz_desc, " (ac3)" );
+
+ intf_WarnMsg( 3, "dvd info: audio stream %d %s\t(0x%x)",
+ i, p_es->psz_desc, i_id );
+
+ break;
+ case 0x02:
+ case 0x03: /* MPEG audio */
+ i_id = 0xc0 + audio_status.i_position;
+ p_es = input_AddES( p_input,
p_input->stream.pp_programs[0], i_id, 0 );
- p_es->i_stream_id = 0xbd;
- p_es->i_type = AC3_AUDIO_ES;
- p_es->b_audio = 1;
- p_es->i_cat = AUDIO_ES;
- strcpy( p_es->psz_desc, Language( hton16(
- vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
- strcat( p_es->psz_desc, " (ac3)" );
-
- intf_WarnMsg( 1, "dvd info: audio stream %d %s\t(0x%x)",
- i, p_es->psz_desc, i_id );
-
- break;
- case 0x02:
- case 0x03: /* MPEG audio */
- i_id = 0xbf + i;
- p_es = input_AddES( p_input,
+ p_es->i_stream_id = i_id;
+ p_es->i_type = MPEG2_AUDIO_ES;
+ p_es->b_audio = 1;
+ p_es->i_cat = AUDIO_ES;
+ strcpy( p_es->psz_desc, IfoLanguage( hton16(
+ vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
+ strcat( p_es->psz_desc, " (mpeg)" );
+
+ intf_WarnMsg( 3, "dvd info: audio stream %d %s\t(0x%x)",
+ i, p_es->psz_desc, i_id );
+
+ break;
+ case 0x04: /* LPCM */
+
+ i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd;
+ p_es = input_AddES( p_input,
p_input->stream.pp_programs[0], i_id, 0 );
- p_es->i_stream_id = i_id;
- p_es->i_type = MPEG2_AUDIO_ES;
- p_es->b_audio = 1;
- p_es->i_cat = AUDIO_ES;
- strcpy( p_es->psz_desc, Language( hton16(
- vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
- strcat( p_es->psz_desc, " (mpeg)" );
-
- intf_WarnMsg( 1, "dvd info: audio stream %d %s\t(0x%x)",
- i, p_es->psz_desc, i_id );
-
- break;
- case 0x04: /* LPCM */
- i_id = 0;
- intf_ErrMsg( "dvd warning: LPCM audio not handled yet" );
- break;
- case 0x06: /* DTS */
- i_id = 0;
- i_ac3--;
- intf_ErrMsg( "dvd warning: DTS audio not handled yet" );
- break;
- default:
- i_id = 0;
- intf_ErrMsg( "dvd warning: unknown audio type %.2x",
- vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
+ p_es->i_stream_id = i_id;
+ p_es->i_type = LPCM_AUDIO_ES;
+ p_es->b_audio = 1;
+ p_es->i_cat = AUDIO_ES;
+ strcpy( p_es->psz_desc, IfoLanguage( hton16(
+ vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) );
+ strcat( p_es->psz_desc, " (lpcm)" );
+
+ intf_WarnMsg( 3, "dvd info: audio stream %d %s\t(0x%x)",
+ i, p_es->psz_desc, i_id );
+ break;
+ case 0x06: /* DTS */
+ i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd;
+ intf_ErrMsg( "dvd warning: DTS audio not handled yet"
+ "(0x%x)", i_id );
+ break;
+ default:
+ i_id = 0;
+ intf_ErrMsg( "dvd warning: unknown audio type %.2x",
+ vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
+ }
}
-
}
-
+#undef audio_status
+#define spu_status \
+ vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
+
/* Sub Picture ES */
- b_last = 0;
- i_sub_pic = 0x20;
for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
{
- if( !b_last )
+ IfoPrintSpu( p_dvd, i );
+
+ if( spu_status.i_available )
{
- i_id = ( i_sub_pic++ << 8 ) | 0xbd;
+ /* there are several streams for one spu */
+ if( vts.manager_inf.video_attr.i_ratio )
+ {
+ /* 16:9 */
+ switch( vts.manager_inf.video_attr.i_perm_displ )
+ {
+ case 1:
+ i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 )
+ | 0xbd;
+ break;
+ case 2:
+ i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 )
+ | 0xbd;
+ break;
+ default:
+ i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 )
+ | 0xbd;
+ break;
+ }
+ }
+ else
+ {
+ /* 4:3 */
+ i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 )
+ | 0xbd;
+ }
p_es = input_AddES( p_input,
p_input->stream.pp_programs[0], 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, Language( hton16(
+ strcpy( p_es->psz_desc, IfoLanguage( hton16(
vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) );
- intf_WarnMsg( 1, "dvd info: spu stream %d %s\t(0x%x)",
+ intf_WarnMsg( 3, "dvd info: spu stream %d %s\t(0x%x)",
i, p_es->psz_desc, i_id );
-
- /* The before the last spu has a 0x0 prefix */
- b_last =
- ( vts.manager_inf.p_spu_attr[i].i_prefix == 0 );
}
}
-
+#undef spu_status
if( p_main->b_audio )
{
/* For audio: first one if none or a not existing one specified */
p_dvd->i_chapter = 1;
}
}
+
#define title \
p_dvd->p_ifo->vts.title_unit.p_title[p_dvd->i_title_id-1].title
-
if( p_area->i_angle != p_dvd->i_angle )
{
if( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 )
intf_WarnMsg( 2, "dvd info: angle %d selected", p_area->i_angle );
}
- vlc_mutex_unlock( &p_input->stream.stream_lock );
+ /* warn interface that something has changed */
+ p_input->stream.b_seekable = 1;
+ p_input->stream.b_changed = 1;
+
+ p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_REINIT;
return 0;
}
int i_read_blocks;
off_t i_off;
boolean_t b_eof;
+ boolean_t b_eot;
p_dvd = (thread_dvd_data_t *)p_input->p_plugin_data;
p_netlist = (dvd_netlist_t *)p_input->p_method_data;
/* update chapter : it will be easier when we have navigation
* ES support */
- if( title.p_cell_play[p_dvd->i_prg_cell].i_category & 0xf000 )
- {
- i_angle = p_dvd->i_angle - 1;
- }
- else
+ if( p_dvd->i_chapter < ( p_dvd->i_chapter_nb - 1 ) )
{
- i_angle = 0;
- }
- if( title.chapter_map.pi_start_cell[p_dvd->i_chapter-1] <=
- ( p_dvd->i_prg_cell - i_angle ) )
- {
- p_dvd->i_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( title.chapter_map.pi_start_cell[p_dvd->i_chapter] <=
+ ( p_dvd->i_prg_cell - i_angle + 1 ) )
+ {
+ p_dvd->i_chapter++;
+ }
}
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
/* the synchro has to be reinitialized when we change cell */
- p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_START;
+ p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_REINIT;
vlc_mutex_unlock( &p_input->stream.stream_lock );
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell += i_read_bytes;
- b_eof = !( p_input->stream.p_selected_area->i_tell < p_dvd->i_size );
+ b_eot = !( p_input->stream.p_selected_area->i_tell < p_dvd->i_size );
+ b_eof = b_eot && ( ( p_dvd->i_title + 1 ) >= p_input->stream.i_area_nb );
vlc_mutex_unlock( &p_input->stream.stream_lock );
- if( ( i_read_blocks == i_block_once ) && ( !b_eof ) )
+ if( b_eof )
{
+ return 1;
+ }
+
+ if( b_eot )
+ {
+ intf_WarnMsg( 4, "dvd info: new title" );
+ p_dvd->i_title++;
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ DVDSetArea( p_input, p_input->stream.pp_areas[p_dvd->i_title] );
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
return 0;
}
- else
+
+ if( i_read_blocks == i_block_once )
{
- return 1;
+ return 0;
}
+
+ return -1;
}
/*****************************************************************************
}
/*****************************************************************************
- * DVDSeek : Goes to a given position on the stream ; this one is used by the
- * input and translate chronological position from input to logical postion
- * on the device
- * ---
+ * DVDSeek : Goes to a given position on the stream.
+ *****************************************************************************
+ * This one is used by the input and translate chronological position from
+ * input to logical position on the device.
* The lock should be taken before calling this function.
*****************************************************************************/
static void DVDSeek( input_thread_t * p_input, off_t i_off )
p_dvd->i_sector = i_pos >> 11;
i_prg_cell = 0;
- i_chapter = 1;
+ 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 )
/* Find first title cell which is inside program cell */
if( DVDFindCell( p_dvd ) < 0 )
{
- /* no following cell : we're at eof */
+ /* no following cell : we're at eof */
intf_ErrMsg( "dvd error: cell seeking failed" );
p_input->b_error = 1;
return;
{
i_angle = 0;
}
- while( title.chapter_map.pi_start_cell[i_chapter-1] <=
- ( p_dvd->i_prg_cell - i_angle ) )
+ 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++;
}
(off_t)( p_dvd->i_sector ) *DVD_LB_SIZE, SEEK_SET ) -
p_input->stream.p_selected_area->i_start;
/*
- intf_WarnMsg( 1, "Program Cell: %d Cell: %d Chapter: %d",
+ intf_WarnMsg( 3, "Program Cell: %d Cell: %d Chapter: %d",
p_dvd->i_prg_cell, p_dvd->i_cell, p_dvd->i_chapter );
*/
}
#define cell p_dvd->p_ifo->vts.cell_inf
-
+
/*****************************************************************************
* DVDFindCell: adjust the title cell index with the program cell
*****************************************************************************/
}
/*
-intf_WarnMsg( 1, "FindCell: i_cell %d i_index %d found %d nb %d",
+intf_WarnMsg( 3, "FindCell: i_cell %d i_index %d found %d nb %d",
p_dvd->i_cell,
p_dvd->i_prg_cell,
i_cell,
}
/* 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( 1, "cell: %d sector1: 0x%x end1: 0x%x\n"
+ intf_WarnMsg( 3, "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,
DVDChooseAngle( p_dvd );
- /* Search for cell_index in cell adress_table and initialize start sector */
+ /* Search for cell_index in cell adress_table and initialize
+ * start sector */
if( DVDFindSector( p_dvd ) < 0 )
{
intf_ErrMsg( "dvd error: can't select chapter" );
/* start is : beginning of vts vobs + offset to vob x */
p_dvd->i_start = p_dvd->i_title_start +
- DVD_LB_SIZE * (off_t)( p_dvd->i_sector );
+ DVD_LB_SIZE * (off_t)( p_dvd->i_sector );
/* Position the fd pointer on the right address */
p_dvd->i_start = lseek( p_dvd->i_fd, p_dvd->i_start, SEEK_SET );
case 0x5:
p_dvd->i_prg_cell += p_dvd->i_angle - 1;
p_dvd->i_angle_cell = 0;
-// intf_WarnMsg( 1, "dvd info: choosing angle %d", p_dvd->i_angle );
break;
/* we exit a multi-angle section */
case 0x9: