* input.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input.h,v 1.29 2001/02/12 13:20:14 massiot Exp $
+ * $Id: input.h,v 1.30 2001/02/20 02:53:13 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
struct pgrm_descriptor_s * input_AddProgram ( struct input_thread_s *,
u16, size_t );
void input_DelProgram( struct input_thread_s *, struct pgrm_descriptor_s * );
+struct input_area_s * input_AddArea( struct input_thread_s * );
+void input_DelArea ( struct input_thread_s *, struct input_area_s * );
void input_DumpStream( struct input_thread_s * );
struct es_descriptor_s * input_FindES( struct input_thread_s *, u16 );
struct es_descriptor_s * input_AddES ( struct input_thread_s *,
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.22 2001/02/19 19:08:59 massiot Exp $
+ * $Id: input_ext-intf.h,v 1.23 2001/02/20 02:53:13 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
boolean_t b_audio; /* is the stream an audio stream that
* will need to be discarded with
* fast forward and slow motion ? */
+ char psz_desc[20]; /* description of ES: audio language
+ * for instance ; NULL if not
+ * available */
/* Demultiplexer information */
void * p_demux_data;
#define SYNCHRO_START 1
#define SYNCHRO_REINIT 2
+/*****************************************************************************
+ * input_area_t
+ *****************************************************************************
+ * Attributes for current area (title for DVD)
+ *****************************************************************************/
+typedef struct input_area_s
+{
+ /* selected area attributes */
+ int i_id; /* identificator for area */
+ off_t i_start; /* start offset of area */
+ off_t i_size; /* total size of the area
+ * (in arbitrary units) */
+
+ /* navigation parameters */
+ off_t i_tell; /* actual location in the area
+ * (in arbitrary units) */
+ off_t i_seek; /* next requested location
+ * (changed by the interface thread */
+
+ /* area subdivision */
+ int i_part_nb; /* number of parts (chapter for DVD)*/
+ int i_part; /* currently selected part */
+
+ /* offset to plugin related data */
+ off_t i_plugin_data;
+} input_area_t;
+
/*****************************************************************************
* stream_descriptor_t
*****************************************************************************
/* Input method data */
boolean_t b_pace_control; /* can we read when we want ? */
boolean_t b_seekable; /* can we do lseek() ? */
+
/* if (b_seekable) : */
- off_t i_size; /* total size of the file
- * (in arbitrary units) */
- off_t i_tell; /* actual location in the file
- * (in arbitrary units) */
- off_t i_seek; /* next requested location (changed
- * by the interface thread */
+ int i_area_nb;
+ input_area_t ** pp_areas; /* list of areas in stream == offset
+ * interval with own properties */
u32 i_mux_rate; /* the rate we read the stream (in
* units of 50 bytes/s) ; 0 if undef */
- /* For DVD streams: */
- int i_title_nb;
- int * pi_chapter; /* Number of chapter for each title */
- char ** ppsz_audio; /* Audio language names */
- char ** ppsz_spu; /* Sub-pictures names */
- int i_title; /* selected title */
- int i_chapter; /* selected chapter */
- int i_audio; /* selected audio stream */
- int i_spu; /* selected spu */
-
/* New status and rate requested by the interface */
int i_new_status, i_new_rate;
vlc_cond_t stream_wait; /* interface -> input in case of a
void ( * pf_close )( struct input_thread_s * );
void ( * pf_end ) ( struct input_thread_s * );
+ int ( * pf_set_area ) ( struct input_thread_s *,
+ int, int, int, int );
+
int ( * pf_read ) ( struct input_thread_s *,
struct data_packet_s *
pp_packets[] );
* dvd_css.c: Functions for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_css.c,v 1.10 2001/02/18 01:42:04 stef Exp $
+ * $Id: dvd_css.c,v 1.11 2001/02/20 02:53:13 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
static int CSSCracker( int i_start,
unsigned char * p_crypted,
unsigned char * p_decrypted,
- DVD_key_t * p_sector_key,
- DVD_key_t * p_key )
+ dvd_key_t * p_sector_key,
+ dvd_key_t * p_key )
{
unsigned char pi_buffer[10];
unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
}
/*****************************************************************************
- * CSSGetKeys : get the title keys.
+ * CSSGetKey : get title key.
* The DVD should have been opened and authenticated before.
*****************************************************************************/
-int CSSGetKeys( css_t * p_css )
+int CSSGetKey( css_t * p_css )
{
/*
* Title key cracking method from Ethan Hawke,
* with Frank A. Stevenson algorithm.
* Does not use any player key table and ioctls.
*/
- u8 pi_buf[0x800] ;
- DVD_key_t key;
- title_key_t p_title_key[10] ;
+ u8 pi_buf[0x800];
+ dvd_key_t pi_key;
+ title_key_t p_title_key[10];
off_t i_pos;
boolean_t b_encrypted;
boolean_t b_stop_scanning;
int i_highest;
int i,j,k;
- for( i_title = 0 ; i_title < p_css->i_title_nb ; i_title++ )
- {
- /* Initialization for each title */
- memset( p_title_key, 0, 10 );
- memset( &key, 0, 10 );
- b_encrypted = 0;
- b_stop_scanning = 0;
- i_registered_keys = 0 ;
- i_total_keys_found = 0 ;
- i_highest = 0;
-
- /* Position of the title on the disc */
- i_pos = p_css->p_title_key[i_title].i;
+ memset( p_title_key, 0, 10 );
+ memset( &pi_key, 0, 10 );
+ b_encrypted = 0;
+ b_stop_scanning = 0;
+ i_registered_keys = 0 ;
+ i_total_keys_found = 0 ;
+ i_highest = 0;
+
+ /* Position of the title on the disc */
+ i_title = p_css->i_title;
+ i_pos = p_css->i_title_pos;
//fprintf( stderr, "CSS %d start pos: %lld\n", i_title, i_pos );
- do {
- i_pos = lseek( p_css->i_fd, i_pos, SEEK_SET );
- i_bytes_read = read( p_css->i_fd, pi_buf, 0x800 );
+ do {
+ i_pos = lseek( p_css->i_fd, i_pos, SEEK_SET );
+ i_bytes_read = read( p_css->i_fd, pi_buf, 0x800 );
- /* PES_scrambling_control */
- if( pi_buf[0x14] & 0x30 )
- {
- b_encrypted = 1;
- i_best_plen = 0;
- i_best_p = 0;
+ /* PES_scrambling_control */
+ if( pi_buf[0x14] & 0x30 )
+ {
+ b_encrypted = 1;
+ i_best_plen = 0;
+ i_best_p = 0;
- for( i = 2 ; i < 0x30 ; i++ )
+ for( i = 2 ; i < 0x30 ; i++ )
+ {
+ for( j = i ; ( j < 0x80 ) &&
+ ( pi_buf[0x7F - (j%i)] == pi_buf[0x7F-j] ) ; j++ );
{
- for( j = i ; ( j < 0x80 ) &&
- ( pi_buf[0x7F - (j%i)] == pi_buf[0x7F-j] ) ; j++ );
+ if( ( j > i_best_plen ) && ( j > i ) )
{
- if( ( j > i_best_plen ) && ( j > i ) )
- {
- i_best_plen = j;
- i_best_p = i;
- }
+ i_best_plen = j;
+ i_best_p = i;
}
}
+ }
- if( ( i_best_plen > 20 ) && ( i_best_plen / i_best_p >= 2) )
+ if( ( i_best_plen > 20 ) && ( i_best_plen / i_best_p >= 2) )
+ {
+ i = CSSCracker( 0, &pi_buf[0x80],
+ &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
+ (dvd_key_t*)&pi_buf[0x54],
+ &pi_key );
+ while( i>=0 )
{
- i = CSSCracker( 0, &pi_buf[0x80],
- &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
- (DVD_key_t*)&pi_buf[0x54],
- &key );
- while( i>=0 )
+ k = 0;
+ for( j=0 ; j<i_registered_keys ; j++ )
{
- k = 0;
- for( j=0 ; j<i_registered_keys ; j++ )
+ if( memcmp( &(p_title_key[j].pi_key),
+ &pi_key, sizeof(dvd_key_t) ) == 0 )
{
- if( memcmp( &(p_title_key[j].key),
- &key, sizeof(DVD_key_t) ) == 0 )
- {
- p_title_key[j].i++;
- i_total_keys_found++;
- k = 1;
- }
- }
-
- if( k == 0 )
- {
- memcpy( &(p_title_key[i_registered_keys].key),
- &key, sizeof(DVD_key_t) );
- p_title_key[i_registered_keys++].i = 1;
+ p_title_key[j].i_occ++;
i_total_keys_found++;
+ k = 1;
}
- i = CSSCracker( i, &pi_buf[0x80],
- &pi_buf[0x80 -( i_best_plen / i_best_p) *i_best_p],
- (DVD_key_t*)&pi_buf[0x54], &key);
}
- /* Stop search if we find one occurance of the key
- * I have never found a DVD for which it is not enough
- * but we should take care of that */
- if( i_registered_keys == 1 && p_title_key[0].i >= 1 )
+ if( k == 0 )
{
- b_stop_scanning = 1;
+ memcpy( &(p_title_key[i_registered_keys].pi_key),
+ &pi_key, sizeof(dvd_key_t) );
+ p_title_key[i_registered_keys++].i_occ = 1;
+ i_total_keys_found++;
}
+ i = CSSCracker( i, &pi_buf[0x80],
+ &pi_buf[0x80 - ( i_best_plen / i_best_p) *i_best_p],
+ (dvd_key_t*)&pi_buf[0x54], &pi_key);
+ }
+
+ /* Stop search if we find one occurance of the key
+ * I have never found a DVD for which it is not enough
+ * but we should take care of that */
+ if( i_registered_keys == 1 && p_title_key[0].i_occ >= 1 )
+ {
+ b_stop_scanning = 1;
}
}
+ }
- i_pos += i_bytes_read;
- } while( i_bytes_read == 0x800 && !b_stop_scanning);
+ i_pos += i_bytes_read;
+ } while( i_bytes_read == 0x800 && !b_stop_scanning);
- if( b_stop_scanning)
- {
- intf_WarnMsg( 1,
- "CSS: Found enough occurancies of the same key." );
- }
+ if( b_stop_scanning)
+ {
+ intf_WarnMsg( 1,
+ "CSS: Found enough occurancies of the same key." );
+ }
- if( !b_encrypted )
- {
- intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
- return(0);
- }
+ if( !b_encrypted )
+ {
+ intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
+ return(0);
+ }
- if( b_encrypted && i_registered_keys == 0 )
- {
- intf_ErrMsg( "CSS: Unable to determine keys from file.");
- return(1);
- }
+ if( b_encrypted && i_registered_keys == 0 )
+ {
+ intf_ErrMsg( "CSS: Unable to determine keys from file.");
+ return(1);
+ }
- for( i = 0 ; i < i_registered_keys - 1 ; i++ )
+ for( i = 0 ; i < i_registered_keys - 1 ; i++ )
+ {
+ for( j = i + 1 ; j < i_registered_keys ; j++ )
{
- for( j = i + 1 ; j < i_registered_keys ; j++ )
+ if( p_title_key[j].i_occ > p_title_key[i].i_occ )
{
- if( p_title_key[j].i > p_title_key[i].i )
- {
- memcpy( &key, &(p_title_key[j].key), sizeof(DVD_key_t) );
- k = p_title_key[j].i;
+ memcpy( &pi_key, &(p_title_key[j].pi_key), sizeof(dvd_key_t) );
+ k = p_title_key[j].i_occ;
- memcpy( &(p_title_key[j].key),
- &(p_title_key[i].key), sizeof(DVD_key_t) );
- p_title_key[j].i = p_title_key[i].i;
+ memcpy( &(p_title_key[j].pi_key),
+ &(p_title_key[i].pi_key), sizeof(dvd_key_t) );
+ p_title_key[j].i_occ = p_title_key[i].i_occ;
- memcpy( &(p_title_key[i].key),&key, sizeof(DVD_key_t) );
- p_title_key[i].i = k;
- }
+ memcpy( &(p_title_key[i].pi_key),&pi_key, sizeof(dvd_key_t) );
+ p_title_key[i].i_occ = k;
}
}
+ }
#ifdef STATS
- intf_WarnMsg( 1, " Key(s) & key probability\n---------------------");
+ intf_WarnMsg( 1, " Key(s) & key probability\n---------------------");
#endif
- for( i=0 ; i<i_registered_keys ; i++ )
- {
+ for( i=0 ; i<i_registered_keys ; i++ )
+ {
#ifdef STATS
- intf_WarnMsg( 1, "%d) %02X %02X %02X %02X %02X - %3.2f%%", i,
- p_title_key[i].key[0], p_title_key[i].key[1],
- p_title_key[i].key[2], p_title_key[i].key[3],
- p_title_key[i].key[4],
- p_title_key[i].i * 100.0 / i_total_keys_found );
+ intf_WarnMsg( 1, "%d) %02X %02X %02X %02X %02X - %3.2f%%", i,
+ p_title_key[i].key[0], p_title_key[i].key[1],
+ p_title_key[i].key[2], p_title_key[i].key[3],
+ p_title_key[i].key[4],
+ p_title_key[i].i_occ * 100.0 / i_total_keys_found );
#endif
- if( p_title_key[i_highest].i * 100.0 / i_total_keys_found
- <= p_title_key[i].i*100.0 / i_total_keys_found )
- {
- i_highest = i;
- }
+ if( p_title_key[i_highest].i_occ * 100.0 / i_total_keys_found
+ <= p_title_key[i].i_occ*100.0 / i_total_keys_found )
+ {
+ i_highest = i;
}
+ }
- /* The "find the key with the highest probability" code
- * is untested, as I haven't been able to find a VOB that
- * produces multiple keys (RT)
- */
- intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
- i_title + 1,
- p_title_key[i_highest].key[0],
- p_title_key[i_highest].key[1],
- p_title_key[i_highest].key[2],
- p_title_key[i_highest].key[3],
- p_title_key[i_highest].key[4] );
-
- memcpy( p_css->p_title_key[i_title].key,
- p_title_key[i_highest].key, KEY_SIZE );
- }
+ /* The "find the key with the highest probability" code
+ * is untested, as I haven't been able to find a VOB that
+ * produces multiple keys (RT)
+ */
+ intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X",
+ i_title + 1,
+ p_title_key[i_highest].pi_key[0],
+ p_title_key[i_highest].pi_key[1],
+ p_title_key[i_highest].pi_key[2],
+ p_title_key[i_highest].pi_key[3],
+ p_title_key[i_highest].pi_key[4] );
+
+ memcpy( p_css->pi_title_key,
+ p_title_key[i_highest].pi_key, KEY_SIZE );
return 0;
}
* sec : sector to descramble
* key : title key for this sector
*****************************************************************************/
-int CSSDescrambleSector( DVD_key_t key, u8* pi_sec )
+int CSSDescrambleSector( dvd_key_t pi_key, u8* pi_sec )
{
unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
u8* pi_end = pi_sec + 0x800;
/* PES_scrambling_control */
if( pi_sec[0x14] & 0x30)
{
- i_t1 = ((key)[0] ^ pi_sec[0x54]) | 0x100;
- i_t2 = (key)[1] ^ pi_sec[0x55];
- i_t3 = (((key)[2]) | ((key)[3] << 8) |
- ((key)[4] << 16)) ^ ((pi_sec[0x56]) |
+ i_t1 = ((pi_key)[0] ^ pi_sec[0x54]) | 0x100;
+ i_t2 = (pi_key)[1] ^ pi_sec[0x55];
+ i_t3 = (((pi_key)[2]) | ((pi_key)[3] << 8) |
+ ((pi_key)[4] << 16)) ^ ((pi_sec[0x56]) |
(pi_sec[0x57] << 8) | (pi_sec[0x58] << 16));
i_t4 = i_t3 & 7;
i_t3 = i_t3 * 2 + 8 - i_t4;
* dvd_css.h: Structures for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_css.h,v 1.3 2001/02/15 21:03:27 stef Exp $
+ * $Id: dvd_css.h,v 1.4 2001/02/20 02:53:13 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
* - css-auth by Derek Fawcus <derek@spider.com>
* - DVD CSS ioctls example program by Andrew T. Veliath <andrewtv@usa.net>
* - DeCSSPlus by Ethan Hawke
- * - The Divide and conquer attack by Frank A. Stevenson<frank@funcom.com>
+ * - The Divide and conquer attack by Frank A. Stevenson <frank@funcom.com>
*
* 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
*****************************************************************************/
#define KEY_SIZE 5
-typedef u8 DVD_key_t[KEY_SIZE];
+typedef u8 dvd_key_t[KEY_SIZE];
typedef struct disc_s
{
u8 pi_challenge[2*KEY_SIZE];
- u8 pi_key1[KEY_SIZE];
- u8 pi_key2[KEY_SIZE];
- u8 pi_key_check[KEY_SIZE];
+ dvd_key_t pi_key1;
+ dvd_key_t pi_key2;
+ dvd_key_t pi_key_check;
u8 i_varient;
} disc_t;
typedef struct title_key_s
{
- off_t i; /* This signification of this parameter
- depends on the function it is called from :
- *from DVDInit -> i == position
- *from CSSGetKeys -> i == nb occurence */
- DVD_key_t key;
+ int i_occ;
+ dvd_key_t pi_key;
} title_key_t;
typedef struct css_s
int i_agid;
disc_t disc;
u8 pi_disc_key[2048];
- int i_title_nb;
- title_key_t* p_title_key;
+ int i_title;
+ off_t i_title_pos;
+ dvd_key_t pi_title_key;
} css_t;
* dvd_ifo.c: Functions for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.c,v 1.10 2001/02/19 03:12:26 stef Exp $
+ * $Id: dvd_ifo.c,v 1.11 2001/02/20 02:53:13 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
#include "dvd_udf.h"
#include "input_dvd.h"
-void CommandRead( ifo_command_t );
+/*
+ * Local prototypes
+ */
+static vmg_t ReadVMG ( ifo_t* );
+void CommandRead( ifo_command_t );
/*
* IFO Management.
ifo.i_off = (off_t)(i_lba) * DVD_LB_SIZE;
ifo.i_pos = lseek( ifo.i_fd, ifo.i_off, SEEK_SET );
+ /* Video Manager Initialization */
+ intf_WarnMsg( 2, "ifo: initializing VMG" );
+ ifo.vmg = ReadVMG( &ifo );
+
return ifo;
}
*****************************************************************************/
void IfoEnd( ifo_t* p_ifo )
{
+#if 0
int i,j;
/* Free structures from video title sets */
free( p_ifo->vmg.pgc.com_tab.p_cell_com );
free( p_ifo->vmg.pgc.com_tab.p_post_com );
free( p_ifo->vmg.pgc.com_tab.p_pre_com );
-
+#endif
return;
}
int i;
off_t i_start = p_ifo->i_pos;
-//fprintf( stderr, "PGC\n" );
+fprintf( stderr, "PGC\n" );
FLUSH(2);
GETC( &pgc.i_prg_nb );
GETC( &pgc.i_cell_nb );
+fprintf( stderr, "PGC: Prg: %d Cell: %d\n", pgc.i_prg_nb, pgc.i_cell_nb );
GETL( &pgc.i_play_time );
GETL( &pgc.i_prohibited_user_op );
for( i=0 ; i<8 ; i++ )
GETS( &pgc.i_next_pgc_nb );
GETS( &pgc.i_prev_pgc_nb );
GETS( &pgc.i_goup_pgc_nb );
+fprintf( stderr, "PGC: Prev: %d Next: %d Up: %d\n",pgc.i_prev_pgc_nb ,pgc.i_next_pgc_nb, pgc.i_goup_pgc_nb );
GETC( &pgc.i_still_time );
GETC( &pgc.i_play_mode );
for( i=0 ; i<16 ; i++ )
int i;
off_t i_start = p_ifo->i_pos;
-//fprintf( stderr, "Unit\n" );
+fprintf( stderr, "Unit\n" );
GETS( &inf.i_srp_nb );
FLUSH( 2 );
p_ifo->i_pos = lseek( p_ifo->i_fd,
i_start + inf.p_srp[i].i_pgci_sbyte,
SEEK_SET );
+fprintf( stderr, "Unit: PGC %d\n", i );
inf.p_srp[i].pgc = ReadPGC( p_ifo );
}
int i;
off_t i_start = p_ifo->i_pos;
-//fprintf( stderr, "Unit Table\n" );
+fprintf( stderr, "Unit Table\n" );
GETS( &pgci.i_lu_nb );
FLUSH( 2 );
int i;
// off_t i_start = p_ifo->i_pos;
-//fprintf( stderr, "PTR\n" );
+fprintf( stderr, "PTR\n" );
GETS( &ptr.i_ttu_nb );
+fprintf( stderr, "PTR: TTU nb %d\n", ptr.i_ttu_nb );
FLUSH( 2 );
GETL( &ptr.i_ebyte );
/* Parsing of tts */
GETC( &ptr.p_tts[i].i_tts_nb );
GETC( &ptr.p_tts[i].i_vts_ttn );
GETL( &ptr.p_tts[i].i_ssector );
-//fprintf( stderr, "PTR: %d %d %d\n",ptr.p_tts[i].i_tts_nb,ptr.p_tts[i].i_vts_ttn, ptr.p_tts[i].i_ssector );
+fprintf( stderr, "PTR: %d %d %d\n", ptr.p_tts[i].i_ptt_nb, ptr.p_tts[i].i_tts_nb,ptr.p_tts[i].i_vts_ttn );
}
return ptr;
int i, j;
off_t i_start = p_ifo->i_pos;
-//fprintf( stderr, "VTS ATTR\n" );
+fprintf( stderr, "VTS ATTR\n" );
GETS( &atrt.i_vts_nb );
+fprintf( stderr, "VTS ATTR Nb: %d\n", atrt.i_vts_nb );
FLUSH( 2 );
GETL( &atrt.i_ebyte );
atrt.pi_vts_atrt_sbyte = malloc( atrt.i_vts_nb *sizeof(u32) );
int i;
off_t i_start = p_ifo->i_pos;
-//fprintf( stderr, "PTR\n" );
+fprintf( stderr, "VTS PTR\n" );
GETS( &ptr.i_ttu_nb );
+fprintf( stderr, "VTS PTR nb: %d\n", ptr.i_ttu_nb );
FLUSH( 2 );
GETL( &ptr.i_ebyte );
ptr.pi_ttu_sbyte = malloc( ptr.i_ttu_nb *sizeof(u32) );
ptr.pi_ttu_sbyte[i], SEEK_SET );
GETS( &ptr.p_ttu[i].i_pgc_nb );
GETS( &ptr.p_ttu[i].i_prg_nb );
+fprintf( stderr, "VTS %d PTR Pgc: %d Prg: %d\n", i,ptr.p_ttu[i].i_pgc_nb, ptr.p_ttu[i].i_prg_nb );
}
return ptr;
/*****************************************************************************
- * ReadVTS : Parse vts*.ifo files to fill the Video Title Set structure.
+ * IfoReadVTS : Parse vts*.ifo files to fill the Video Title Set structure.
*****************************************************************************/
-static vts_t ReadVTS( ifo_t* p_ifo )
+int IfoReadVTS( ifo_t* p_ifo )
{
vts_t vts;
+ off_t i_off;
+ int i_title;
+
+ 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
+ + p_ifo->i_off;
+
+ p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET );
vts.i_pos = p_ifo->i_pos;
vts.vobu_admap = ReadMap( p_ifo );
}
- return vts;
+ p_ifo->vts = vts;
+
+ return 0;
}
/*
* DVD Information Management
*/
-
+#if 0
/*****************************************************************************
* IfoRead : Function that fills structure and calls specified functions
* to do it.
int i;
off_t i_off;
- /* Video Manager Initialization */
- intf_WarnMsg( 2, "ifo: initializing VMG" );
- p_ifo->vmg = ReadVMG( p_ifo );
-
/* Video Title Sets initialization */
p_ifo->p_vts = malloc( p_ifo->vmg.mat.i_tts_nb *sizeof(vts_t) );
if( p_ifo->p_vts == NULL )
return;
}
-
+#endif
/*
* IFO virtual machine : a set of commands that give the
* interactive behaviour of the dvd
* dvd_ifo.h: Structures for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: dvd_ifo.h,v 1.6 2001/02/15 21:03:27 stef Exp $
+ * $Id: dvd_ifo.h,v 1.7 2001/02/20 02:53:13 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
off_t i_pos;
/* Error Management */
boolean_t b_error;
+ /* Current title set number */
+ int i_title;
/* Structure described in video_ts */
vmg_t vmg;
- /* Table of vts ifos */
- vts_t * p_vts;
+ /* Vts ifo for current title set */
+ vts_t vts;
} ifo_t;
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.14 2001/02/19 03:12:26 stef Exp $
+ * $Id: input_dvd.c,v 1.15 2001/02/20 02:53:13 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
static void DVDInit ( struct input_thread_s * );
static void DVDEnd ( struct input_thread_s * );
static void DVDSeek ( struct input_thread_s *, off_t );
+static int DVDSetArea ( struct input_thread_s *, int, int, int, int );
static int DVDRewind ( struct input_thread_s * );
/*****************************************************************************
input.pf_close = input_FileClose;
input.pf_end = DVDEnd;
input.pf_read = DVDRead;
+ input.pf_set_area = DVDSetArea;
input.pf_demux = input_DemuxPS;
input.pf_new_packet = input_NetlistNewPacket;
input.pf_new_pes = input_NetlistNewPES;
}
/*****************************************************************************
- * DVDSetRegion: initialize input data for title x, chapter y.
+ * 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.
*****************************************************************************/
-static int DVDSetRegionParameters( input_thread_t * p_input,
- int i_title, int i_chapter,
- int i_audio, int i_spu )
+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;
off_t i_start;
off_t i_size;
pgc_t * p_pgc;
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;
- /* Set selected title start and size */
- p_input->stream.i_title = i_title;
+ /* Ifo structures reading */
+ p_method->ifo.i_title = i_title;
+ IfoReadVTS( &(p_method->ifo) );
+ intf_WarnMsg( 2, "Ifo: VTS initialized" );
- p_pgc = &p_method->ifo.p_vts[i_title].pgci_ti.p_srp[0].pgc;
+#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
+ 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" );
+ }
+#endif
+
+ /* 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;
/* 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.p_vts[i_title].c_adt.p_cell_inf[i_cell].i_vob_id )
+ p_method->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.p_vts[i_title].c_adt.p_cell_inf[i_cell].i_cell_id )
+ p_method->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( 2, "DVD: Start cell: %d End Cell: %d",
+ 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;
/* start is : beginning of vts + offset to vobs + offset to vob x */
- i_start = p_method->ifo.p_vts[i_title].i_pos + DVD_LB_SIZE *
- ( p_method->ifo.p_vts[i_title].mat.i_tt_vobs_ssector +
- p_method->ifo.p_vts[i_title].c_adt.p_cell_inf[i_start_cell].i_ssector );
- p_method->i_start_byte = i_start;
-
+ 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 );
+
i_start = lseek( p_input->i_handle, i_start, SEEK_SET );
- intf_WarnMsg( 3, "DVD: VOBstart at: %lld", i_start );
+ intf_WarnMsg( 2, "DVD: VOBstart at: %lld", i_start );
i_size = (off_t)
- ( p_method->ifo.p_vts[i_title].c_adt.p_cell_inf[i_end_cell].i_esector -
- p_method->ifo.p_vts[i_title].c_adt.p_cell_inf[i_start_cell].i_ssector + 1 )
+ ( 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( 3, "DVD: stream size: %lld", i_size );
+ intf_WarnMsg( 2, "DVD: stream size: %lld", i_size );
+
+#if 0
+ p_es = NULL;
+
+ 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++ )
+ {
+ 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 )
+ {
+ input_SelectES( p_input, p_es );
+ }
+ }
+
+ /* 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 == 0 )
+ {
+ input_SelectES( p_input, p_es );
+ }
+
+ }
+
+ /* area definition */
+ p_input->stream.pp_areas[0]->i_start = i_start;
+ p_input->stream.pp_areas[0]->i_size = i_size;
+
+ /* No PSM to read in DVD mode */
+ p_input->stream.pp_programs[0]->b_is_ok = 1;
+
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+#else
if( p_input->stream.b_seekable )
{
}
/* File too big. */
- if( p_input->stream.i_tell > INPUT_PREPARSE_LENGTH )
+ if( p_input->stream.pp_areas[0]->i_tell > INPUT_PREPARSE_LENGTH )
{
break;
}
/* i_tell is an indicator from the beginning of the stream,
* not of the DVD */
- p_input->stream.i_tell = 0;
+ p_input->stream.pp_areas[0]->i_tell = 0;
if( p_demux_data->b_has_PSM )
{
#endif
/* FIXME : ugly kludge */
- p_input->stream.i_size = i_size;
+ p_input->stream.pp_areas[0]->i_size = i_size;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
p_input->stream.pp_programs[0]->b_is_ok = 0;
/* FIXME : ugly kludge */
- p_input->stream.i_size = i_size;
+ p_input->stream.pp_areas[0]->i_size = i_size;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
-
+#endif
return 0;
}
static void DVDInit( input_thread_t * p_input )
{
thread_dvd_data_t * p_method;
+ int i;
if( (p_method = malloc( sizeof(thread_dvd_data_t) )) == NULL )
{
/* Reading structures initialisation */
input_NetlistInit( p_input, 4096, 4096, DVD_LB_SIZE,
p_method->i_read_once );
+ intf_WarnMsg( 2, "DVD: Netlist initialized" );
/* Ifo initialisation */
p_method->ifo = IfoInit( p_input->i_handle );
+ intf_WarnMsg( 2, "Ifo: VMG initialized" );
/* CSS initialisation */
if( p_method->b_encrypted )
intf_ErrMsg( "CSS fatal error" );
return;
}
-#else
- intf_ErrMsg( "Unscrambling not supported" );
- p_input->b_error = 1;
- return;
-#endif
- }
-
- /* Ifo structures reading */
- IfoRead( &(p_method->ifo) );
- intf_WarnMsg( 3, "Ifo: Initialized" );
-
- /* CSS title keys decryption */
- if( p_method->b_encrypted )
- {
-
-#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
- int i;
-
- p_method->css.i_title_nb = p_method->ifo.vmg.mat.i_tts_nb;
-
- if( (p_method->css.p_title_key =
- malloc( p_method->css.i_title_nb *sizeof(title_key_t) ) ) == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- p_input->b_error = 1;
- return;
- }
-
- for( i=0 ; i<p_method->css.i_title_nb ; i++ )
- {
- p_method->css.p_title_key[i].i =
- p_method->ifo.p_vts[i].i_pos +
- p_method->ifo.p_vts[i].mat.i_tt_vobs_ssector * DVD_LB_SIZE;
- }
-
- CSSGetKeys( &(p_method->css) );
-
- intf_WarnMsg( 3, "CSS: initialized" );
+ intf_WarnMsg( 2, "CSS: initialized" );
#else
intf_ErrMsg( "Unscrambling not supported" );
p_input->b_error = 1;
input_InitStream( p_input, sizeof( stream_ps_data_t ) );
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
- /* Set stream data */
+ /* Set stream and area data */
vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.i_title_nb = p_method->ifo.vmg.mat.i_tts_nb;
+
+ /* FIXME: We consider here that one title is one title set
+ * it is not true !!! */
+
+#define area p_input->stream.pp_areas
+ /* We start from 1 here since area 0 is reserved for video_ts.vob */
+ for( i = 1 ; i < p_method->ifo.vmg.mat.i_tts_nb ; i++ )
+ {
+ input_AddArea( p_input );
+
+ /* Should not be so simple eventually :
+ * are title Program Chains, or still something else ? */
+ area[i]->i_id = i;
+
+ /* Absolute start offset and size
+ * We can only set that with vts ifo, so we do it during the
+ * first call to DVDSetArea */
+ area[i]->i_start = 0;
+ area[i]->i_size = 0;
+
+ /* Number of chapter */
+ area[i]->i_part_nb = 0;
+ area[i]->i_part = 1;
+ /* Offset to vts_i_0.ifo */
+ area[i]->i_plugin_data = p_method->ifo.i_off +
+ ( p_method->ifo.vmg.ptt_srpt.p_tts[i-1].i_ssector * DVD_LB_SIZE );
+ }
+#undef area
+
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* By default, set all parameters to 0 */
- /* FIXME: wrong kludge to get title nb */
- DVDSetRegionParameters( p_input,
- p_method->ifo.vmg.ptt_srpt.p_tts[0].i_tts_nb - 1,
- 0, 0, 0 );
+ /* FIXME: wrong kludge to get first title number */
+ DVDSetArea( p_input, p_method->ifo.vmg.ptt_srpt.p_tts[0].i_tts_nb - 1,
+ 0, 0, 0 );
return;
}
{
for( i=0 ; i<p_method->i_read_once ; i++ )
{
- CSSDescrambleSector(
- p_method->css.p_title_key[p_input->stream.i_title].key,
- p_vec[i].iov_base );
+ CSSDescrambleSector( p_method->css.pi_title_key,
+ p_vec[i].iov_base );
((u8*)(p_vec[i].iov_base))[0x14] &= 0x8F;
}
}
pp_packets[i_packet] = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.i_tell += p_method->i_read_once *DVD_LB_SIZE;
+ p_input->stream.pp_areas[0]->i_tell += p_method->i_read_once *DVD_LB_SIZE;
vlc_mutex_unlock( &p_input->stream.stream_lock );
return( 0 );
p_method = ( thread_dvd_data_t * )p_input->p_plugin_data;
/* We have to take care of offset of beginning of title */
- i_pos = i_off + p_method->i_start_byte;
+ i_pos = i_off + p_input->stream.pp_areas[0]->i_start;
/* With DVD, we have to be on a sector boundary */
i_pos = i_pos & (~0x7ff);
i_pos = lseek( p_input->i_handle, i_pos, SEEK_SET );
- p_input->stream.i_tell = i_pos - p_method->i_start_byte;
+ p_input->stream.pp_areas[0]->i_tell = i_pos - p_input->stream.pp_areas[0]->i_start;
return;
}
* Prototypes in dvd_ifo.c
*****************************************************************************/
struct ifo_s IfoInit( int );
+int IfoReadVTS( struct ifo_s * );
void IfoRead( struct ifo_s * );
void IfoEnd( ifo_t * );
#if defined( HAVE_SYS_DVDIO_H ) || defined( LINUX_DVD )
int CSSTest ( int );
struct css_s CSSInit ( int );
-int CSSGetKeys ( struct css_s * );
+int CSSGetKey ( struct css_s * );
int CSSDescrambleSector( u8 * , u8 * );
#endif
if( p_intf->p_input != NULL )
{
- i_seek = (p_adj->value * p_intf->p_input->stream.i_size) / 100;
+ i_seek = (p_adj->value *
+ p_intf->p_input->stream.pp_areas[0]->i_size) / 100;
input_Seek( p_intf->p_input, i_seek );
}
p_intf->p_sys->b_scale_isfree = 1;
* intf_gnome.c: Gnome interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: intf_gnome.c,v 1.13 2001/02/16 06:37:09 sam Exp $
+ * $Id: intf_gnome.c,v 1.14 2001/02/20 02:53:13 stef Exp $
*
* Authors:
*
p_adj = gtk_range_get_adjustment ( GTK_RANGE( p_scale ) );
/* Update the value */
- p_adj->value = ( 100. * p_intf->p_input->stream.i_tell )
- / p_intf->p_input->stream.i_size;
+ p_adj->value = ( 100. * p_intf->p_input->stream.pp_areas[0]->i_tell )
+ / p_intf->p_input->stream.pp_areas[0]->i_size;
/* Gtv does it this way. Why not. */
gtk_range_set_adjustment ( GTK_RANGE( p_scale ), p_adj );
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ps.c,v 1.6 2001/02/16 09:25:03 sam Exp $
+ * $Id: input_ps.c,v 1.7 2001/02/20 02:53:13 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
input.pf_open = input_FileOpen;
input.pf_close = input_FileClose;
input.pf_end = PSEnd;
+ input.pf_set_area = NULL;
input.pf_read = PSRead;
input.pf_demux = input_DemuxPS;
input.pf_new_packet = NewPacket;
}
/* File too big. */
- if( p_input->stream.i_tell > INPUT_PREPARSE_LENGTH )
+ if( p_input->stream.pp_areas[0]->i_tell > INPUT_PREPARSE_LENGTH )
{
break;
}
}
rewind( p_method->stream );
vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.i_tell = 0;
+ p_input->stream.pp_areas[0]->i_tell = 0;
if( p_demux_data->b_has_PSM )
{
/* (The PSM decoder will care about spawning the decoders) */
}
}
vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.i_tell += i_len;
+ p_input->stream.pp_areas[0]->i_tell += i_len;
vlc_mutex_unlock( &p_input->stream.stream_lock );
return( 0 );
}
/* A little bourrin but should work for a while --Meuuh */
fseeko( p_method->stream, i_position, SEEK_SET );
- p_input->stream.i_tell = i_position;
+ p_input->stream.pp_areas[0]->i_tell = i_position;
}
/*
* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ts.c,v 1.3 2001/02/16 09:25:03 sam Exp $
+ * $Id: input_ts.c,v 1.4 2001/02/20 02:53:13 stef Exp $
*
* Authors:
*
input.pf_open = input_FileOpen;
input.pf_close = input_FileClose;
input.pf_end = TSEnd;
+ input.pf_set_area = NULL;
input.pf_read = TSRead;
input.pf_demux = input_DemuxTS;
input.pf_new_packet = input_NetlistNewPacket;
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input.c,v 1.84 2001/02/19 19:08:59 massiot Exp $
+ * $Id: input.c,v 1.85 2001/02/20 02:53:13 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
p_input->stream.i_selected_es_number = 0;
p_input->stream.i_pgrm_number = 0;
p_input->stream.i_new_status = p_input->stream.i_new_rate = 0;
- p_input->stream.i_seek = NO_SEEK;
p_input->stream.i_mux_rate = 0;
+ p_input->stream.i_area_nb = 0;
+ p_input->stream.pp_areas = NULL;
+ /* By default there is one areas in a stream */
+ input_AddArea( p_input );
+ p_input->stream.pp_areas[0]->i_seek = NO_SEEK;
+
/* Initialize stream control properties. */
p_input->stream.control.i_status = PLAYING_S;
p_input->stream.control.i_rate = DEFAULT_RATE;
#endif
vlc_mutex_lock( &p_input->stream.stream_lock );
- if( p_input->stream.i_seek != NO_SEEK )
+ if( p_input->stream.pp_areas[0]->i_seek != NO_SEEK )
{
if( p_input->stream.b_seekable && p_input->pf_seek != NULL )
{
- p_input->pf_seek( p_input, p_input->stream.i_seek );
+ p_input->pf_seek( p_input, p_input->stream.pp_areas[0]->i_seek );
for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
{
p_pgrm->i_synchro_state = SYNCHRO_REINIT;
}
}
- p_input->stream.i_seek = NO_SEEK;
+ p_input->stream.pp_areas[0]->i_seek = NO_SEEK;
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
|| S_ISBLK(stat_info.st_mode) )
{
p_input->stream.b_seekable = 1;
- p_input->stream.i_size = stat_info.st_size;
+ p_input->stream.pp_areas[0]->i_size = stat_info.st_size;
}
else if( S_ISFIFO(stat_info.st_mode)
#ifndef SYS_BEOS
)
{
p_input->stream.b_seekable = 0;
- p_input->stream.i_size = 0;
+ p_input->stream.pp_areas[0]->i_size = 0;
}
else
{
return;
}
- p_input->stream.i_tell = 0;
+ p_input->stream.pp_areas[0]->i_tell = 0;
vlc_mutex_unlock( &p_input->stream.stream_lock );
intf_Msg( "input: opening %s", p_input->p_source );
void input_Seek( input_thread_t * p_input, off_t i_position )
{
vlc_mutex_lock( &p_input->stream.stream_lock );
- p_input->stream.i_seek = i_position;
+ p_input->stream.pp_areas[0]->i_seek = i_position;
intf_Msg( "input: seeking position %lld/%lld", i_position,
- p_input->stream.i_size );
+ p_input->stream.pp_areas[0]->i_size );
vlc_cond_signal( &p_input->stream.stream_wait );
vlc_mutex_unlock( &p_input->stream.stream_lock );
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_programs.c,v 1.31 2001/02/08 17:44:12 massiot Exp $
+ * $Id: input_programs.c,v 1.32 2001/02/20 02:53:13 stef Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
free( p_pgrm );
}
+/*****************************************************************************
+ * input_AddArea: add and init an area descriptor
+ *****************************************************************************
+ * This area descriptor will be referenced in the given stream descriptor
+ *****************************************************************************/
+input_area_t * input_AddArea( input_thread_t * p_input )
+{
+ /* Where to add the pgrm */
+ int i_area_index = p_input->stream.i_area_nb;
+
+ intf_DbgMsg("Adding description for area %d", i_area_index );
+
+ /* Add an entry to the list of program associated with the stream */
+ p_input->stream.i_area_nb++;
+ p_input->stream.pp_areas = realloc( p_input->stream.pp_areas,
+ p_input->stream.i_area_nb
+ * sizeof(input_area_t *) );
+ if( p_input->stream.pp_areas == NULL )
+ {
+ intf_ErrMsg( "Unable to realloc memory in input_AddArea" );
+ return( NULL );
+ }
+
+ /* Allocate the structure to store this description */
+ p_input->stream.pp_areas[i_area_index] =
+ malloc( sizeof(input_area_t) );
+ if( p_input->stream.pp_areas[i_area_index] == NULL )
+ {
+ intf_ErrMsg( "Unable to allocate memory in input_AddArea" );
+ return( NULL );
+ }
+
+ /* Init this entry */
+ p_input->stream.pp_areas[i_area_index]->i_id = 0;
+ p_input->stream.pp_areas[i_area_index]->i_start = 0;
+ p_input->stream.pp_areas[i_area_index]->i_size = 0;
+ p_input->stream.pp_areas[i_area_index]->i_tell = 0;
+ p_input->stream.pp_areas[i_area_index]->i_seek = 0;
+ p_input->stream.pp_areas[i_area_index]->i_part_nb = 0;
+ p_input->stream.pp_areas[i_area_index]->i_part= 0;
+
+ return p_input->stream.pp_areas[i_area_index];
+}
+
+/*****************************************************************************
+ * input_DelArea: destroy a area descriptor
+ *****************************************************************************
+ * All ES descriptions referenced in the descriptor will be deleted.
+ *****************************************************************************/
+void input_DelArea( input_thread_t * p_input, input_area_t * p_area )
+{
+ int i_area_index;
+
+ ASSERT( p_area );
+
+ intf_DbgMsg("Deleting description for area %d", p_area->i_number);
+
+ /* Find the area in the areas table */
+ for( i_area_index = 0; i_area_index < p_input->stream.i_area_nb;
+ i_area_index++ )
+ {
+ if( p_input->stream.pp_areas[i_area_index] == p_area )
+ break;
+ }
+
+ /* Remove this area from the stream's list of areas */
+ p_input->stream.i_area_nb--;
+
+ p_input->stream.pp_areas[i_area_index] =
+ p_input->stream.pp_areas[p_input->stream.i_area_nb];
+ p_input->stream.pp_areas = realloc( p_input->stream.pp_areas,
+ p_input->stream.i_area_nb
+ * sizeof(input_area_t *) );
+
+ if( p_input->stream.i_area_nb && p_input->stream.pp_areas == NULL)
+ {
+ intf_ErrMsg( "input error: unable to realloc area list"
+ " in input_Delarea" );
+ }
+
+ /* Free the description of this area */
+ free( p_area );
+}
+
+
/*****************************************************************************
* input_FindES: returns a pointer to an ES described by its ID
*****************************************************************************/
intf_Msg( "input info: Dumping stream ID 0x%x", S.i_stream_id );
if( S.b_seekable )
intf_Msg( "input info: seekable stream, position: %lld/%lld",
- S.i_tell, S.i_size );
+ S.pp_areas[0].i_tell, S.pp_areas[0].i_size );
else
intf_Msg( "input info: %s", S.b_pace_control ? "pace controlled" :
"pace un-controlled" );