Commit 17a54d55 authored by Stéphane Borel's avatar Stéphane Borel

-New ES detection based on .ifo for DVD module. It might fail (I have

found one DVD for which ifo seems false).

-Title and chapter selection on the command line (see -t and -T options)
It will allow to watch some DVD that went through menus by default.

-beginning of menus in gnome interface.
parent 4b1da9cc
......@@ -213,6 +213,8 @@
#define INPUT_DVD_DEVICE_VAR "vlc_dvd_device"
#define INPUT_DVD_DEVICE_DEFAULT "/dev/dvd"
#define INPUT_TITLE_VAR "vlc_input_title"
#define INPUT_CHAPTER_VAR "vlc_input_chapter"
#define INPUT_AUDIO_VAR "vlc_input_audio"
#define INPUT_CHANNEL_VAR "vlc_input_channel"
#define INPUT_SUBTITLE_VAR "vlc_input_subtitle"
......
......@@ -2,7 +2,7 @@
* input.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input.h,v 1.30 2001/02/20 02:53:13 stef Exp $
* $Id: input.h,v 1.31 2001/02/22 08:44:45 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -66,6 +66,7 @@ struct es_descriptor_s * input_AddES ( struct input_thread_s *,
size_t );
void input_DelES ( struct input_thread_s *, struct es_descriptor_s * );
int input_SelectES ( struct input_thread_s *, struct es_descriptor_s * );
int input_UnSelectES( struct input_thread_s *, struct es_descriptor_s * );
/*****************************************************************************
* Prototypes from input_dec.c
......
......@@ -2,7 +2,7 @@
* dvd_css.c: Functions for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.c,v 1.14 2001/02/20 23:30:15 sam Exp $
* $Id: dvd_css.c,v 1.15 2001/02/22 08:44:45 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -1199,7 +1199,7 @@ int CSSGetKey( css_t * p_css )
* produces multiple keys (RT)
*/
intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
i_title + 1,
i_title,
p_title_key[i_highest].pi_key[0],
p_title_key[i_highest].pi_key[1],
p_title_key[i_highest].pi_key[2],
......
......@@ -2,7 +2,7 @@
* dvd_ifo.c: Functions for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.c,v 1.13 2001/02/20 07:49:12 sam Exp $
* $Id: dvd_ifo.c,v 1.14 2001/02/22 08:44:45 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -528,6 +528,7 @@ static vobu_admap_t ReadMap( ifo_t* p_ifo )
static vmgi_mat_t ReadVMGInfMat( ifo_t* p_ifo )
{
vmgi_mat_t mat;
u64 i_temp;
int i;
// off_t i_start = p_ifo->i_pos;
......@@ -561,20 +562,21 @@ static vmgi_mat_t ReadVMGInfMat( ifo_t* p_ifo )
GETL( &mat.i_c_adt_ssector );
GETL( &mat.i_vobu_admap_ssector );
FLUSH( 32 );
GETS( &mat.i_video_atrt );
// GETS( &mat.video_atrt );
FLUSH(2);
FLUSH( 1 );
GETC( &mat.i_audio_nb );
//fprintf( stderr, "vmgi audio nb : %d\n", mat.i_audio_nb );
for( i=0 ; i < 8 ; i++ )
{
GETLL( &mat.pi_audio_atrt[i] );
GETLL( &i_temp );
}
FLUSH( 17 );
GETC( &mat.i_subpic_nb );
//fprintf( stderr, "vmgi subpic nb : %d\n", mat.i_subpic_nb );
for( i=0 ; i < mat.i_subpic_nb ; i++ )
{
GET( &mat.pi_subpic_atrt[i], 6 );
GET( &i_temp, 6 );
/* FIXME : take care of endianness */
}
......@@ -685,6 +687,7 @@ static vmg_vts_atrt_t ReadVTSAttr( ifo_t* p_ifo )
{
vmg_vts_atrt_t atrt;
int i, j;
u64 i_temp;
off_t i_start = p_ifo->i_pos;
//fprintf( stderr, "VTS ATTR\n" );
......@@ -718,37 +721,39 @@ static vmg_vts_atrt_t ReadVTSAttr( ifo_t* p_ifo )
SEEK_SET );
GETL( &atrt.p_vts_atrt[i].i_ebyte );
GETL( &atrt.p_vts_atrt[i].i_cat_app_type );
GETS( &atrt.p_vts_atrt[i].i_vtsm_video_atrt );
// GETS( &atrt.p_vts_atrt[i].vtsm_video_atrt );
FLUSH(2);
FLUSH( 1 );
GETC( &atrt.p_vts_atrt[i].i_vtsm_audio_nb );
//fprintf( stderr, "m audio nb : %d\n", atrt.p_vts_atrt[i].i_vtsm_audio_nb );
for( j=0 ; j<8 ; j++ )
{
GETLL( &atrt.p_vts_atrt[i].pi_vtsm_audio_atrt[j] );
GETLL( &i_temp );
}
FLUSH( 17 );
GETC( &atrt.p_vts_atrt[i].i_vtsm_subpic_nb );
//fprintf( stderr, "m subp nb : %d\n", atrt.p_vts_atrt[i].i_vtsm_subpic_nb );
for( j=0 ; j<28 ; j++ )
{
GET( &atrt.p_vts_atrt[i].pi_vtsm_subpic_atrt[j], 6 );
GET( &i_temp, 6 );
/* FIXME : Fix endianness issue here */
}
FLUSH( 2 );
GETS( &atrt.p_vts_atrt[i].i_vtstt_video_atrt );
// GETS( &atrt.p_vts_atrt[i].vtstt_video_atrt );
FLUSH(2);
FLUSH( 1 );
GETL( &atrt.p_vts_atrt[i].i_vtstt_audio_nb );
//fprintf( stderr, "tt audio nb : %d\n", atrt.p_vts_atrt[i].i_vtstt_audio_nb );
for( j=0 ; j<8 ; j++ )
{
GETLL( &atrt.p_vts_atrt[i].pi_vtstt_audio_atrt[j] );
GETLL( &i_temp );
}
FLUSH( 17 );
GETC( &atrt.p_vts_atrt[i].i_vtstt_subpic_nb );
//fprintf( stderr, "tt subp nb : %d\n", atrt.p_vts_atrt[i].i_vtstt_subpic_nb );
for( j=0 ; j<28/*atrt.p_vts_atrt[i].i_vtstt_subpic_nb*/ ; j++ )
{
GET( &atrt.p_vts_atrt[i].pi_vtstt_subpic_atrt[j], 6 );
GET( &i_temp, 6 );
/* FIXME : Fix endianness issue here */
}
}
......@@ -825,6 +830,7 @@ static vtsi_mat_t ReadVTSInfMat( ifo_t* p_ifo )
{
vtsi_mat_t mat;
int i;
u64 i_temp;
// off_t i_start = p_ifo->i_pos;
//fprintf( stderr, "VTSI\n" );
......@@ -851,36 +857,61 @@ static vtsi_mat_t ReadVTSInfMat( ifo_t* p_ifo )
GETL( &mat.i_c_adt_ssector );
GETL( &mat.i_vobu_admap_ssector );
FLUSH( 24 );
GETS( &mat.i_m_video_atrt );
// GETS( &mat.m_video_atrt );
FLUSH(2);
FLUSH( 1 );
GETC( &mat.i_m_audio_nb );
for( i=0 ; i<8 ; i++ )
{
GETLL( &mat.pi_m_audio_atrt[i] );
GETLL( &i_temp );
}
FLUSH( 17 );
GETC( &mat.i_m_subpic_nb );
for( i=0 ; i<28 ; i++ )
{
GET( &mat.pi_m_subpic_atrt[i], 6 );
GET( &i_temp, 6 );
/* FIXME : take care of endianness */
}
FLUSH( 2 );
GETS( &mat.i_video_atrt );
// GETS( &mat.video_atrt );
FLUSH(2);
FLUSH( 1 );
GETC( &mat.i_audio_nb );
//fprintf( stderr, "vtsi audio nb : %d\n", mat.i_audio_nb );
for( i=0 ; i<8 ; i++ )
{
GETLL( &mat.pi_audio_atrt[i] );
GETLL( &i_temp );
//fprintf( stderr, "Audio %d: %llx\n", i, i_temp );
i_temp >>= 32;
mat.p_audio_atrt[i].i_lang_code = i_temp & 0xffff;
i_temp >>= 16;
mat.p_audio_atrt[i].i_num_channels = i_temp & 0x7;
i_temp >>= 4;
mat.p_audio_atrt[i].i_sample_freq = i_temp & 0x3;
i_temp >>= 2;
mat.p_audio_atrt[i].i_quantization = i_temp & 0x3;
i_temp >>= 2;
mat.p_audio_atrt[i].i_appl_mode = i_temp & 0x3;
i_temp >>= 2;
mat.p_audio_atrt[i].i_type = i_temp & 0x3;
i_temp >>= 2;
mat.p_audio_atrt[i].i_multichannel_extension = i_temp & 0x1;
i_temp >>= 1;
mat.p_audio_atrt[i].i_coding_mode = i_temp & 0x7;
}
FLUSH( 17 );
GETC( &mat.i_subpic_nb );
//fprintf( stderr, "vtsi subpic nb : %d\n", mat.i_subpic_nb );
for( i=0 ; i<mat.i_subpic_nb ; i++ )
{
GET( &mat.pi_subpic_atrt[i], 6 );
/* FIXME : take care of endianness */
GET( &i_temp, 6 );
i_temp = hton64( i_temp ) >> 16;
//fprintf( stderr, "Subpic %d: %llx\n", i, i_temp );
mat.p_subpic_atrt[i].i_caption = i_temp & 0xff;
i_temp >>= 16;
mat.p_subpic_atrt[i].i_lang_code = i_temp & 0xffff;
i_temp >>= 16;
mat.p_subpic_atrt[i].i_prefix = i_temp & 0xffff;
}
return mat;
......@@ -999,7 +1030,8 @@ int IfoReadVTS( ifo_t* p_ifo )
intf_WarnMsg( 2, "ifo: initializing VTS %d", p_ifo->i_title );
i_title = p_ifo->i_title;
i_off = (off_t)( p_ifo->vmg.ptt_srpt.p_tts[i_title].i_ssector ) *DVD_LB_SIZE
i_off = (off_t)( p_ifo->vmg.ptt_srpt.p_tts[i_title-1].i_ssector )
* DVD_LB_SIZE
+ p_ifo->i_off;
p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET );
......
......@@ -2,7 +2,7 @@
* dvd_ifo.h: Structures for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.h,v 1.7 2001/02/20 02:53:13 stef Exp $
* $Id: dvd_ifo.h,v 1.8 2001/02/22 08:44:45 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -33,6 +33,47 @@
/*
* Program Chain structures
*/
typedef struct ifo_video_s
{
u8 i_compression ;// 2;
u8 i_system ;// 2;
u8 i_ratio ;// 2;
u8 i_perm_displ ;// 2;
u8 i_line21_1 ;// 1;
u8 i_line21_2 ;// 1;
u8 i_source_res ;// 2;
u8 i_letterboxed ;// 1;
u8 i_mode ;// 1;
} ifo_video_t;
/* Audio type information */
typedef struct ifo_audio_s
{
u8 i_coding_mode ;// 3;
u8 i_multichannel_extension ;// 1;
u8 i_type ;// 2;
u8 i_appl_mode ;// 2;
u8 i_quantization ;// 2;
u8 i_sample_freq ;// 2;
// u8 ;// 1;
u8 i_num_channels ;// 3;
u16 i_lang_code ;// 16; // <char> description
u8 i_foo ;// 8; // 0x00000000 ?
u8 i_caption ;// 8;
u8 i_bar ;// 8; // 0x00000000 ?
} ifo_audio_t;
typedef struct ifo_spu_t
{
u16 i_prefix ;// 16; // 0x0100 ?
u16 i_lang_code ;// 16; // <char> description
u8 i_foo ;// 8; // dont know
u8 i_caption ;// 8; // 0x00 ?
} ifo_spu_t;
/* Ifo vitual machine Commands */
typedef struct ifo_command_s
......@@ -241,13 +282,13 @@ typedef struct vmgi_mat_s
u32 i_c_adt_ssector; // 4 bytes
u32 i_vobu_admap_ssector; // 4 bytes
// char[2] ???
u16 i_video_atrt; // 2 bytes
ifo_video_t video_atrt; // 2 bytes
// char ???
u8 i_audio_nb; // 1 byte
u64 pi_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
ifo_audio_t p_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
// char[16] ???
u8 i_subpic_nb; // 1 byte
u64 pi_subpic_atrt[32]; // i_subpic_nb * 6 bytes
ifo_spu_t p_subpic_atrt[32]; // i_subpic_nb * 6 bytes
} vmgi_mat_t;
......@@ -315,21 +356,21 @@ typedef struct vts_atrt_s
{
u32 i_ebyte; // 4 bytes
u32 i_cat_app_type; // 4 bytes
u16 i_vtsm_video_atrt; // 2 bytes
ifo_video_t vtsm_video_atrt; // 2 bytes
// char ???
u8 i_vtsm_audio_nb; // 1 byte
u64 pi_vtsm_audio_atrt[8]; // 8 * 8 bytes
ifo_audio_t p_vtsm_audio_atrt[8]; // 8 * 8 bytes
// char[17] ???
u8 i_vtsm_subpic_nb; // 1 byte
u64 pi_vtsm_subpic_atrt[28]; // i_vtsm_subpic_nb * 6 bytes
ifo_spu_t p_vtsm_subpic_atrt[28]; // i_vtsm_subpic_nb * 6 bytes
// char[2] ???
u16 i_vtstt_video_atrt; // 2 bytes
ifo_video_t vtstt_video_atrt; // 2 bytes
// char ???
u8 i_vtstt_audio_nb; // 1 byte
u64 pi_vtstt_audio_atrt[8]; // 8 * 8 bytes
ifo_audio_t p_vtstt_audio_atrt[8]; // 8 * 8 bytes
// char[17] ???
u8 i_vtstt_subpic_nb; // 1 byte
u64 pi_vtstt_subpic_atrt[28]; // i_vtstt_subpic_nb * 6 bytes
ifo_spu_t p_vtstt_subpic_atrt[28]; // i_vtstt_subpic_nb * 6 bytes
} vts_atrt_t;
/* Main struct for vts attributes
......@@ -388,22 +429,22 @@ typedef struct vtsi_mat_s
u32 i_c_adt_ssector; // 4 bytes
u32 i_vobu_admap_ssector; // 4 bytes
// char[24] ???
u16 i_m_video_atrt; // 2 bytes
ifo_video_t m_video_atrt; // 2 bytes
// char ???
u8 i_m_audio_nb; // 1 byte
u64 pi_m_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
ifo_audio_t p_m_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
// char[16] ???
u8 i_m_subpic_nb; // 1 byte
u64 pi_m_subpic_atrt[32]; // i_subpic_nb * 6 bytes
ifo_spu_t p_m_subpic_atrt[32]; // i_subpic_nb * 6 bytes
// !!! only 28 subpics ???
// char[2] ???
u16 i_video_atrt; // 2 bytes
ifo_video_t video_atrt; // 2 bytes
// char ???
u8 i_audio_nb; // 1 byte
u64 pi_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
ifo_audio_t p_audio_atrt[8]; // i_vmgm_audio_nb * 8 bytes
// char[16] ???
u8 i_subpic_nb; // 1 byte
u64 pi_subpic_atrt[32]; // i_subpic_nb * 6 bytes
ifo_spu_t p_subpic_atrt[32]; // i_subpic_nb * 6 bytes
} vtsi_mat_t;
/*
......
......@@ -10,7 +10,7 @@
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.18 2001/02/20 23:30:15 sam Exp $
* $Id: input_dvd.c,v 1.19 2001/02/22 08:44:45 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -278,11 +278,12 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
/*****************************************************************************
* Language: gives the long language name from the two-letters ISO-639 code
*****************************************************************************/
static char * Language( char * p_code )
static char * Language( u16 i_code )
{
int i = 0;
while( !memcmp( lang_tbl[i].p_code, p_code, 2 ) && lang_tbl[i].p_lang_long )
while( memcmp( lang_tbl[i].p_code, &i_code, 2 ) &&
lang_tbl[i].p_lang_long[0] )
{
i++;
}
......@@ -336,291 +337,316 @@ static int DVDCheckCSS( input_thread_t * p_input )
}
/*****************************************************************************
* 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.
* ---
* Take care that i_title and i_chapter start from 0.
* DVDChapterSelect: find the cell corresponding to requested chapter
*****************************************************************************/
static int DVDSetArea( input_thread_t * p_input,
int i_title, int i_chapter,
int i_audio, int i_spu )
static int DVDChapterSelect( thread_dvd_data_t * p_dvd, int i_chapter )
{
thread_dvd_data_t * p_method;
// es_descriptor_t * p_es;
off_t i_start;
off_t i_size;
pgc_t * p_pgc;
int i_start_cell;
int i_end_cell;
int i_index;
int i_cell;
// int i_nb;
// int i_id;
// int i;
p_method = (thread_dvd_data_t*)p_input->p_plugin_data;
/* Ifo structures reading */
p_method->ifo.i_title = i_title;
IfoReadVTS( &(p_method->ifo) );
intf_WarnMsg( 2, "Ifo: VTS initialized" );
p_pgc = &p_dvd->ifo.vts.pgci_ti.p_srp[0].pgc;
if( p_method->b_encrypted )
{
p_method->css.i_title = i_title;
p_method->css.i_title_pos =
p_method->ifo.vts.i_pos +
p_method->ifo.vts.mat.i_tt_vobs_ssector * DVD_LB_SIZE;
CSSGetKey( &(p_method->css) );
intf_WarnMsg( 2, "CSS: VTS key initialized" );
}
/* Set selected title start and size */
p_pgc = &p_method->ifo.vts.pgci_ti.p_srp[0].pgc;
/* Find cell index in Program chain */
i_index = p_pgc->prg_map.pi_entry_cell[i_chapter] - 1;
/* Find cell index in Program chain for current chapter */
i_index = p_pgc->prg_map.pi_entry_cell[i_chapter-1] - 1;
/* Search for cell_index in cell adress_table */
i_cell = 0;
while( p_pgc->p_cell_pos_inf[i_index].i_vob_id >
p_method->ifo.vts.c_adt.p_cell_inf[i_cell].i_vob_id )
p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_vob_id )
{
i_cell++;
}
while( p_pgc->p_cell_pos_inf[i_index].i_cell_id >
p_method->ifo.vts.c_adt.p_cell_inf[i_cell].i_cell_id )
p_dvd->ifo.vts.c_adt.p_cell_inf[i_cell].i_cell_id )
{
i_cell++;
}
i_start_cell = i_cell;
i_end_cell = i_start_cell + p_pgc->i_cell_nb - 1;
intf_WarnMsg( 3, "DVD: Start cell: %d End Cell: %d",
i_start_cell, i_end_cell );
p_method->i_start_cell = i_start_cell;
p_method->i_end_cell = i_end_cell;
i_start_cell = i_cell;
/* start is : beginning of vts + offset to vobs + offset to vob x */
i_start = p_method->ifo.vts.i_pos + DVD_LB_SIZE *
( p_method->ifo.vts.mat.i_tt_vobs_ssector +
p_method->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector );
p_dvd->i_start = p_dvd->ifo.vts.i_pos + DVD_LB_SIZE *
(off_t)( p_dvd->ifo.vts.mat.i_tt_vobs_ssector +
p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector );
i_start = lseek( p_input->i_handle, i_start, SEEK_SET );
intf_WarnMsg( 2, "DVD: VOBstart at: %lld", i_start );
if( i_chapter == 1 )
{
i_end_cell = i_start_cell + p_pgc->i_cell_nb - 1;
p_dvd->i_size = (off_t)DVD_LB_SIZE *
( p_dvd->ifo.vts.c_adt.p_cell_inf[i_end_cell].i_esector -
p_dvd->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector + 1 );
p_dvd->i_chapter_nb = p_pgc->i_cell_nb;
intf_WarnMsg( 3, "DVD: Start cell: %d End Cell: %d",
i_start_cell, i_end_cell );
}
i_size = (off_t)
( p_method->ifo.vts.c_adt.p_cell_inf[i_end_cell].i_esector -
p_method->ifo.vts.c_adt.p_cell_inf[i_start_cell].i_ssector + 1 )
*DVD_LB_SIZE;
intf_WarnMsg( 2, "DVD: stream size: %lld", i_size );
return 0;
}
#if 0
p_es = NULL;
/*****************************************************************************
* 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.
* ---
* 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
*****************************************************************************/
static int DVDSetArea( input_thread_t * p_input,
int i_title, int i_chapter,
int i_audio, int i_spu )
{
thread_dvd_data_t * p_method;
es_descriptor_t * p_es;
int i_index;
int i_nb;
u16 i_id;
u8 i_ac3;
u8 i_mpeg;
u8 i_sub_pic;
u8 i;
boolean_t b_last;
p_method = (thread_dvd_data_t*)p_input->p_plugin_data;
vlc_mutex_lock( &p_input->stream.stream_lock );
/* ES 0 -> video MPEG2 */
intf_WarnMsg( 1, "DVD: Video MPEG2 stream" );
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 );
/* Audio ES, in the order they appear in .ifo */
i_nb = p_method->ifo.vts.mat.i_audio_nb;
intf_WarnMsg( 1, "DVD: Audio streams %d", i_nb );
for( i = 0 ; i < i_nb ; i++ )
if( i_title >= 0 )
{
i_id = ( ( 0x80 + i ) << 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->psz_desc = p_method->ifo.vts.mat.pi_audio_attr[i];
if( i == 0 )
/*
* We have to load all title information
*/
/* Change the default area */
p_input->stream.p_selected_area = p_input->stream.pp_areas[i_title];
/* Ifo VTS, and CSS reading */
p_method->ifo.i_title = i_title;
IfoReadVTS( &(p_method->ifo) );
intf_WarnMsg( 2, "Ifo: VTS initialized" );
if( p_method->b_encrypted )
{
input_SelectES( p_input, p_es );
p_method->css.i_title = i_title;
p_method->css.i_title_pos =
p_method->ifo.vts.i_pos +
p_method->ifo.vts.mat.i_tt_vobs_ssector * DVD_LB_SIZE;
CSSGetKey( &(p_method->css) );
intf_WarnMsg( 2, "CSS: VTS key initialized" );
}
}
/* Sub Picture ES */
i_nb = p_method->ifo.vts.mat.i_subpic_nb;
intf_WarnMsg( 1, "DVD: Subpic streams %d", i_nb );
for( i = 0 ; i < i_nb ; i++ )
{
i_id = ( ( 0x20 + i ) << 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->psz_desc = p_method->ifo.vts.mat.pi_subpic_attr[i];
if( i == 12 )
/*
* Set selected title start and size
*/
DVDChapterSelect( p_method, 1 );
/* start is : beginning of vts + offset to vobs + offset to vob x */
p_method->i_start =
lseek( p_input->i_handle, p_method->i_start, SEEK_SET );
intf_WarnMsg( 2, "DVD: vobstart at: %lld", p_method->i_start );
intf_WarnMsg( 2, "DVD: stream size: %lld", p_method->i_size );
intf_WarnMsg( 2, "DVD: number of chapters: %lld",
p_method->i_chapter_nb );
/* Area definition */
p_input->stream.p_selected_area->i_start = p_method->i_start;
p_input->stream.p_selected_area->i_size = p_method->i_size;
p_input->stream.p_selected_area->i_part_nb = p_method->i_chapter_nb;
/*
* Destroy obsolete ES by reinitializing program 0
* and find all ES in title with ifo data
*/
if( p_input->stream.pp_programs != NULL )
{
input_SelectES( p_input, p_es );
input_DelProgram( p_input, p_input->stream.pp_programs[0] );
}
}
/* area definition */
p_input->stream.pp_areas[i_title]->i_start = i_start;
p_input->stream.pp_areas[i_title]->i_size = i_size;
/* No PSM to read in DVD mode */
p_input->stream.pp_programs[0]->b_is_ok = 1;
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
/* Init has been successfull ; change the default area */
p_input->stream.p_selected_area = p_input->stream.pp_areas[i_title];
p_es = NULL;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* ES 0 -> video MPEG2 */
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( 1, "DVD: Video MPEG2 stream" );
/* Audio ES, in the order they appear in .ifo */
i_nb = p_method->ifo.vts.mat.i_audio_nb;
i_ac3 = 0x80;
i_mpeg = 0xc0;
#else
p_input->stream.p_selected_area = p_input->stream.pp_areas[0];
for( i = 1 ; i <= i_nb ; i++ )
{
if( p_input->stream.b_seekable )
{
stream_ps_data_t * p_demux_data =
(stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
#if 0
fprintf( stderr, "Audio %d: %x %x %x %x %x %x\n", i,
p_method->ifo.vts.mat.p_audio_atrt[i].i_coding_mode,
p_method->ifo.vts.mat.p_audio_atrt[i].i_multichannel_extension,
p_method->ifo.vts.mat.p_audio_atrt[i].i_type,
p_method->ifo.vts.mat.p_audio_atrt[i].i_appl_mode,
p_method->ifo.vts.mat.p_audio_atrt[i].i_foo,
p_method->ifo.vts.mat.p_audio_atrt[i].i_bar );
#endif
/* Pre-parse the stream to gather stream_descriptor_t. */
p_input->stream.pp_programs[0]->b_is_ok = 0;
p_demux_data->i_PSM_version = EMPTY_PSM_VERSION;
switch( p_method->ifo.vts.mat.p_audio_atrt[i].i_coding_mode )
{
case 0x00: /* AC3 */
i_id = ( ( 0x7f + i ) << 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;
strcpy( p_es->psz_desc, Language( hton16(
p_method->ifo.vts.mat.p_audio_atrt[i-1].i_lang_code ) ) );
while( !p_input->b_die && !p_input->b_error
&& !p_demux_data->b_has_PSM )
{
int i_result, i;
data_packet_t * pp_packets[INPUT_READ_ONCE];
break;
case 0x02:
case 0x03: /* MPEG audio */
i_id = 0xbf + i;
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;
strcpy( p_es->psz_desc, Language( hton16(
p_method->ifo.vts.mat.p_audio_atrt[i-1].i_lang_code ) ) );
i_result = DVDRead( p_input, pp_packets );
if( i_result == 1 )
{
/* EOF */
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.pp_programs[0]->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
break;
}
if( i_result == -1 )
{
p_input->b_error = 1;
case 0x04: /* LPCM */
i_id = 0;
intf_ErrMsg( "DVD: LPCM audio not handled yet" );
break;
case 0x06: /* DTS */
i_id = 0;
intf_ErrMsg( "DVD: DTS audio not handled yet" );
break;
default:
i_id = 0;
intf_ErrMsg( "DVD: unkown audio" );
}
for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
intf_WarnMsg( 1, "DVD: Audio stream %d %s\t(0x%x)",
i, p_es->psz_desc, i_id );
}
/* Sub Picture ES */
i_nb = p_method->ifo.vts.mat.i_subpic_nb;