Commit f25a4c6a authored by Stéphane Borel's avatar Stéphane Borel

-CSS support kludged for current DVD input.

It is very slow now but will be more adapted to the forthcoming DVD
input.
It should read the first title of many DVDs but has been tested with few.

-Beginning of ifo commands to implement DVD navigation.
parent a9299a6f
......@@ -275,11 +275,11 @@ int CSSGetASF( int i_fd )
{
if( !( ioctl( i_fd, DVD_AUTH, &ai ) ) )
{
fprintf( stderr, "%sAuthenticated\n", (ai.lsasf.asf) ? "" : "not");
intf_Msg("CSS: %sAuthenticated\n", (ai.lsasf.asf) ? "" : "not");
return 0;
}
}
intf_ErrMsg( "CSS Error : GetASF" );
intf_ErrMsg( "CSS Error: GetASF" );
return -1;
}
......@@ -376,12 +376,11 @@ static void CSSCryptKey( int i_key_type, int i_varient,
pi_bits[--i_index] = i_val & 0xFF;
i_val >>= 8;
fprintf(stderr, "lfsr0=%08x lfsr1=%08x\n", i_lfsr0, i_lfsr1);
} while( i_index > 0 );
i_css_varient = pi_css_varients[i_css_varient];
fprintf( stderr, "CSE : %d\n", i_css_varient );
intf_WarnMsg( 3, "CSS varient: %d\n", i_css_varient );
/*
* Mangling
......@@ -442,13 +441,11 @@ static int CSSAuthHost( dvd_authinfo *ai, disc_t *disc )
{
/* Host data receive (host changes state) */
case DVD_LU_SEND_AGID:
// _CSSPrintDebug ("AGID %d\n", ai->lsa.agid);
ai->type = DVD_HOST_SEND_CHALLENGE;
break;
case DVD_LU_SEND_KEY1:
// _CSSPrintDebugBytes ("LU sent key1", ai->lsk.key, LEN_KEY);
for( i=0; i<KEY_SIZE; i++ )
{
......@@ -463,7 +460,7 @@ static int CSSAuthHost( dvd_authinfo *ai, disc_t *disc )
if( memcmp( disc->pi_key_check,
disc->pi_key1, KEY_SIZE ) == 0 )
{
fprintf( stderr, "Drive Authentic - using varient %d\n", i);
intf_WarnMsg( 3, "CSS: Drive Authentic - using varient %d\n", i);
disc->i_varient = i;
ai->type = DVD_LU_SEND_CHALLENGE;
break;
......@@ -479,7 +476,6 @@ static int CSSAuthHost( dvd_authinfo *ai, disc_t *disc )
{
disc->pi_challenge[i] = ai->hsc.chal[9-i];
}
// _CSSPrintDebugBytes ("LU sent challenge", ai->hsc.chal, 10);
CSSCryptKey( 1, disc->i_varient, disc->pi_challenge,
disc->pi_key2 );
ai->type = DVD_HOST_SEND_KEY2;
......@@ -491,7 +487,6 @@ static int CSSAuthHost( dvd_authinfo *ai, disc_t *disc )
{
ai->hsc.chal[9-i] = disc->pi_challenge[i];
}
// _CSSPrintDebugBytes ("Host sending challenge", ai->hsc.chal, 10);
/* Returning data, let LU change state */
break;
......@@ -500,12 +495,11 @@ static int CSSAuthHost( dvd_authinfo *ai, disc_t *disc )
{
ai->hsk.key[4-i] = disc->pi_key2[i];
}
// _CSSPrintDebugBytes ("Host sending key 2", &disc->Key2[0], LEN_KEY);
/* Returning data, let LU change state */
break;
default:
intf_ErrMsg( "Got invalid state %d", ai->type );
intf_ErrMsg( "CSS: Got invalid state %d", ai->type );
return -22;
}
......@@ -552,7 +546,7 @@ static int CSScracker( int StartVal,
{
if (invtab4[ i ] != 1)
{
printf( "Permutation error\n" );
intf_ErrMsg( "CSS: Permutation error" );
exit( -1 );
}
}
......@@ -591,7 +585,6 @@ static int CSScracker( int StartVal,
t6 -= t4;
t5 += t6 + t4;
t6 = invtab4[ t6 ];
/* printf( "%02x/%02x ", t4, t6 ); */
/* feed / advance t3 / t5 */
t3 = (t3 << 8) | t6;
t5 >>= 8;
......@@ -677,6 +670,8 @@ css_t CSSInit( int i_fd )
int rv = -1;
int i;
css.i_fd = i_fd;
memset( &ai, 0, sizeof(ai) );
// if (CSSGetASF (i_fd))
......@@ -686,14 +681,13 @@ css_t CSSInit( int i_fd )
/* Init sequence, request AGID */
for( i=1; (i<4)&&(rv== -1) ; ++i )
{
fprintf( stderr, "Request AGID [%d]...", i );
intf_WarnMsg( 3, "CSS: Request AGID [%d]...", i );
ai.type = DVD_LU_SEND_AGID;
ai.lsa.agid = 0;
rv = ioctl (i_fd, DVD_AUTH, &ai);
fprintf( stderr, "%d %d\n" , rv, ai.lsa.agid );
if (rv == -1)
{
fprintf( stderr, "N/A, invalidating" );
intf_ErrMsg( "CSS: N/A, invalidating" );
ai.type = DVD_INVALIDATE_AGID;
ai.lsa.agid = 0;
ioctl( i_fd, DVD_AUTH, &ai );
......@@ -701,26 +695,25 @@ css_t CSSInit( int i_fd )
}
if( rv==-1 )
{
fprintf( stderr, "Cannot get AGID\n" );
intf_ErrMsg( "CSS: Cannot get AGID\n" );
}
for( i=0 ; i<10; ++i )
{
// disc->Challenge[i] = i;
css.disc.pi_challenge[i] = i;
}
/* Send AGID to host */
if( CSSAuthHost(&ai, &(css.disc) )<0 )
{
intf_ErrMsg( "CSS Error :Send AGID to host failed" );
intf_ErrMsg( "CSS Error: Send AGID to host failed" );
return css;
}
/* Get challenge from host */
if( CSSAuthHost( &ai, &(css.disc) )<0)
{
intf_ErrMsg( "CSS Error :Get challenge from host failed" );
intf_ErrMsg( "CSS Error: Get challenge from host failed" );
return css;
}
css.i_agid = ai.lsa.agid;
......@@ -728,14 +721,14 @@ css_t CSSInit( int i_fd )
/* Send challenge to LU */
if( ioctl( i_fd, DVD_AUTH, &ai )<0 )
{
intf_ErrMsg( "CSS Error :Send challenge to LU failed ");
intf_ErrMsg( "CSS Error: Send challenge to LU failed ");
return css;
}
/* Get key1 from LU */
if( ioctl( i_fd, DVD_AUTH, &ai )<0)
{
intf_ErrMsg( "CSS Error :Get key1 from LU failed ");
intf_ErrMsg( "CSS Error: Get key1 from LU failed ");
return css;
}
......@@ -743,45 +736,45 @@ css_t CSSInit( int i_fd )
// if (_CSSAuthHost(&ai, disc) < 0) {
if( CSSAuthHost( &ai, &(css.disc) )<0)
{
intf_ErrMsg( "CSS Error :Send key1 to host failed" );
intf_ErrMsg( "CSS Error: Send key1 to host failed" );
return css;
}
/* Get challenge from LU */
if( ioctl( i_fd, DVD_AUTH, &ai)<0 )
{
intf_ErrMsg( "CSS Error :Get challenge from LU failed ");
intf_ErrMsg( "CSS Error: Get challenge from LU failed ");
return css;
}
/* Send challenge to host */
if( CSSAuthHost( &ai, &(css.disc) )<0 )
{
intf_ErrMsg( "CSS Error :Send challenge to host failed");
intf_ErrMsg( "CSS Error: Send challenge to host failed");
return css;
}
/* Get key2 from host */
if( CSSAuthHost( &ai, &(css.disc) )<0 )
{
intf_ErrMsg( "CSS Error :Get key2 from host failed" );
intf_ErrMsg( "CSS Error: Get key2 from host failed" );
return css;
}
/* Send key2 to LU */
if( ioctl( i_fd, DVD_AUTH, &ai )<0 )
{
intf_ErrMsg( "CSS Error :Send key2 to LU failed (expected)" );
intf_ErrMsg( "CSS Error: Send key2 to LU failed (expected)" );
return css;
}
if( ai.type == DVD_AUTH_ESTABLISHED )
{
intf_ErrMsg("CSS Error :DVD is authenticated");
intf_WarnMsg( 3, "DVD is authenticated");
}
else if( ai.type == DVD_AUTH_FAILURE )
{
intf_ErrMsg("CSS Error :DVD authentication failed");
intf_ErrMsg("CSS Error: DVD authentication failed");
}
memcpy( css.disc.pi_challenge, css.disc.pi_key1, KEY_SIZE );
......@@ -790,12 +783,7 @@ css_t CSSInit( int i_fd )
css.disc.pi_challenge,
css.disc.pi_key_check );
intf_Msg( "Received Session Key\n" );
for( i=0 ; i<KEY_SIZE ; i++ )
{
intf_Msg( "%02x", &(css.disc.pi_key_check[i]) );
}
intf_Msg( "\n" );
intf_WarnMsg( 3, "CSS: Received Session Key\n" );
if( css.i_agid < 0 )
{
......@@ -811,7 +799,7 @@ css_t CSSInit( int i_fd )
if( ioctl( i_fd, DVD_READ_STRUCT, &dvd )<0 )
{
fprintf( stderr, "Error : Could not read Disc Key" );
intf_ErrMsg( "CSS Error: Could not read Disc Key" );
css.b_error = 1;
return css;
}
......@@ -820,7 +808,6 @@ css_t CSSInit( int i_fd )
{
dvd.disckey.value[i] ^= css.disc.pi_key_check[4 - (i % KEY_SIZE)];
}
// _CSSPrintDebugBytes ("Received Disc Key", s.disckey.value, 10);
memcpy( css.disc.pi_key_check, dvd.disckey.value, 2048 );
//
// if (CSSGetASF (i_fd) < 0)
......@@ -838,21 +825,7 @@ css_t CSSInit( int i_fd )
* The DVD should have been opened before.
*****************************************************************************/
#define MaxKeys 1000
#define REPEAT 20
struct
{
int verbosity ; /* 0-9 */
int repetitions ;
int scanall ;
char *infile ;
} params ;
typedef struct
{
int occ;
DVD_key_t key;
} KeyOcc;
#define REPEAT 2
int CSSGetKeys( css_t * p_css )
{
......@@ -935,7 +908,7 @@ int CSSGetKeys( css_t * p_css )
DVD_key_t my_key;
title_key_t title_key[MaxKeys] ;
int i_title;
int i_pos = 0;
off64_t i_pos = 0;
int i_bytes_read;
int i_best_plen;
int i_best_p;
......@@ -951,12 +924,6 @@ int CSSGetKeys( css_t * p_css )
for( i_title=0 ; i_title<1/*p_css->i_title_nb*/ ; i_title++ )
{
i_pos = p_css->p_title_key[i_title].i;
// FIXME : Ugly Kludge
#if 1
i_fd = open( "/dvd/video_ts/vts_01_1.vob", O_RDONLY|O_NONBLOCK);
fprintf( stderr, "CSS:File opened\n" );
i_pos = 0;
#endif
do
{
i_pos = lseek64( i_fd, i_pos, SEEK_SET );
......@@ -1003,11 +970,6 @@ i_pos = 0;
title_key[i_registered_keys++].i = 1;
i_total_keys_found++;
}
fprintf(stderr, "\nOfs:%08X - Key: %02X %02X %02X %02X %02X\n",
i_pos, my_key[0], my_key[1], my_key[2],
my_key[3], my_key[4] );
i = CSScracker( i, &pi_buf[0x80],
&pi_buf[0x80 -( i_best_plen / i_best_p) *i_best_p],
(DVD_key_t*)&pi_buf[0x54], &my_key);
......@@ -1023,17 +985,17 @@ i_pos = 0;
if( b_stop_scanning)
{
fprintf( stderr,
"Found enough occurancies of the same key. Scan stopped.\n" );
intf_WarnMsg( 3,
"CSS: Found enough occurancies of the same key." );
}
if( !b_encrypted )
{
fprintf(stderr, "This file was _NOT_ encrypted!\n");
intf_WarnMsg( 3, "CSS: This file was _NOT_ encrypted!");
return(0);
}
if( b_encrypted && i_registered_keys == 0 )
{
fprintf(stderr, "Sorry... Unable to determine keys from file.\n");
intf_WarnMsg( 3 , "CSS: Unable to determine keys from file.");
return(1);
}
for( i=0 ; i<i_registered_keys-1 ; i++ )
......@@ -1052,8 +1014,9 @@ i_pos = 0;
}
}
}
fprintf(stderr, " Key(s) & key probability\n---------------------\n");
i_highest = 0;
#if 0
fprintf(stderr, " Key(s) & key probability\n---------------------\n");
for( i=0 ; i<i_registered_keys ; i++ )
{
fprintf(stderr, "%d) %02X %02X %02X %02X %02X - %3.2f%%\n", i,
......@@ -1068,12 +1031,14 @@ i_pos = 0;
}
}
fprintf(stderr, "\n");
#endif
/* 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)
*/
printf( "%02X %02X %02X %02X %02X\n",
intf_WarnMsg( 3, "CSS: Title %d key: %02X %02X %02X %02X %02X\n",
i_title+1,
title_key[i_highest].key[0],
title_key[i_highest].key[1],
title_key[i_highest].key[2],
......@@ -1093,17 +1058,17 @@ i_pos = 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 key, u8* pi_sec )
{
unsigned int i_t1, i_t2, i_t3, i_t4, i_t5, i_t6;
u8* pi_end = pi_sec + 0x800;
if( pi_sec[0x14] & 0x30) // PES_scrambling_control
{
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 = ((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]) |
(pi_sec[0x57] << 8) | (pi_sec[0x58] << 16));
i_t4 = i_t3 & 7;
i_t3 = i_t3 * 2 + 8 - i_t4;
......
......@@ -58,4 +58,5 @@ typedef struct css_s
*****************************************************************************/
struct css_s CSSInit ( int );
int CSSGetKeys ( struct css_s* );
int CSSDescrambleSector( DVD_key_t , u8* );
#endif
......@@ -59,7 +59,7 @@ static int IfoFindVMG( ifo_t* p_ifo )
}
p_ifo->i_off = p_ifo->i_pos;
fprintf( stderr, "VMG Off : %lld\n", (long long)(p_ifo->i_off) );
//fprintf( stderr, "VMG Off : %lld\n", (long long)(p_ifo->i_off) );
return 0;
}
......@@ -84,7 +84,7 @@ static int IfoFindVTS( ifo_t* p_ifo )
}
p_ifo->i_off = p_ifo->i_pos;
fprintf( stderr, "VTS Off : %lld\n", (long long)(p_ifo->i_off) );
//fprintf( stderr, "VTS Off : %lld\n", (long long)(p_ifo->i_off) );
return 0;
}
......@@ -159,9 +159,9 @@ void IfoEnd( ifo_t* p_ifo )
free( p_ifo->vmg.pgc.p_cell_pos_inf );
free( p_ifo->vmg.pgc.p_cell_play_inf );
free( p_ifo->vmg.pgc.prg_map.pi_entry_cell );
free( p_ifo->vmg.pgc.com_tab.ps_cell_com );
free( p_ifo->vmg.pgc.com_tab.ps_post_com );
free( p_ifo->vmg.pgc.com_tab.ps_pre_com );
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 );
return;
}
......@@ -173,9 +173,9 @@ void IfoEnd( ifo_t* p_ifo )
#define GET( p_field , i_len ) \
{ \
read( p_ifo->i_fd , (p_field) , (i_len) ); \
fprintf(stderr, "Pos : %lld Val : %llx\n", \
/*fprintf(stderr, "Pos : %lld Val : %llx\n", \
(long long)(p_ifo->i_pos - i_start), \
(long long)*(p_field) ); \
(long long)*(p_field) ); */ \
p_ifo->i_pos = \
lseek64( p_ifo->i_fd, p_ifo->i_pos + (i_len), SEEK_SET );\
}
......@@ -183,9 +183,9 @@ fprintf(stderr, "Pos : %lld Val : %llx\n", \
#define GETC( p_field ) \
{ \
read( p_ifo->i_fd , (p_field) , 1 ); \
fprintf(stderr, "Pos : %lld Value : %d\n", \
/*fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
*(p_field) );*/ \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 1 , SEEK_SET );\
}
......@@ -193,9 +193,9 @@ fprintf(stderr, "Pos : %lld Value : %d\n", \
{ \
read( p_ifo->i_fd , (p_field) , 2 ); \
*(p_field) = ntohs( *(p_field) ); \
fprintf(stderr, "Pos : %lld Value : %d\n", \
/*fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
*(p_field) );*/ \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 2 , SEEK_SET );\
}
......@@ -203,9 +203,9 @@ fprintf(stderr, "Pos : %lld Value : %d\n", \
{ \
read( p_ifo->i_fd , (p_field) , 4 ); \
*(p_field) = ntohl( *(p_field) ); \
fprintf(stderr, "Pos : %lld Value : %d\n", \
/*fprintf(stderr, "Pos : %lld Value : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
*(p_field) );*/ \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 4 , SEEK_SET );\
}
......@@ -213,15 +213,15 @@ fprintf(stderr, "Pos : %lld Value : %d\n", \
{ \
read( p_ifo->i_fd , (p_field) , 8 ); \
*(p_field) = ntoh64( *(p_field) ); \
fprintf(stderr, "Pos : %lld Value : %lld\n", \
/*fprintf(stderr, "Pos : %lld Value : %lld\n", \
(long long)(p_ifo->i_pos - i_start), \
*(p_field) ); \
*(p_field) );*/ \
p_ifo->i_pos = lseek64( p_ifo->i_fd , p_ifo->i_pos + 8 , SEEK_SET );\
}
#define FLUSH( i_len ) \
{ \
fprintf(stderr, "Pos : %lld\n", (long long)(p_ifo->i_pos - i_start)); \
/*fprintf(stderr, "Pos : %lld\n", (long long)(p_ifo->i_pos - i_start));*/ \
p_ifo->i_pos = lseek64( p_ifo->i_fd , \
p_ifo->i_pos + (i_len), SEEK_SET ); \
}
......@@ -233,13 +233,31 @@ fprintf(stderr, "Pos : %lld\n", (long long)(p_ifo->i_pos - i_start)); \
/*****************************************************************************
* ReadPGC : Fills the Program Chain structure.
*****************************************************************************/
#define GETCOMMAND( p_com ) \
{ \
read( p_ifo->i_fd , (p_com) , 8 ); \
/*fprintf(stderr, "Pos : %lld Type : %d direct : %d cmd : %d dircmp : %d cmp : %d subcmd : %d v0 : %d v2 : %d v4 : %d\n", \
(long long)(p_ifo->i_pos - i_start), \
(int)((p_com)->i_type), \
(int)((p_com)->i_direct), \
(int)((p_com)->i_cmd), \
(int)((p_com)->i_dir_cmp), \
(int)((p_com)->i_cmp), \
(int)((p_com)->i_sub_cmd), \
(int)((p_com)->i_v0), \
(int)((p_com)->i_v2), \
(int)((p_com)->i_v4) );*/ \
p_ifo->i_pos = \
lseek64( p_ifo->i_fd, p_ifo->i_pos + 8, SEEK_SET ); \
}
static pgc_t ReadPGC( ifo_t* p_ifo )
{
pgc_t pgc;
int i;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "PGC\n" );
//fprintf( stderr, "PGC\n" );
FLUSH(2);
GETC( &pgc.i_prg_nb );
......@@ -280,42 +298,48 @@ fprintf( stderr, "PGC\n" );
FLUSH( 2 );
if( pgc.com_tab.i_pre_com_nb )
{
pgc.com_tab.ps_pre_com =
malloc(pgc.com_tab.i_pre_com_nb *COMMAND_SIZE);
if( pgc.com_tab.ps_pre_com == NULL )
pgc.com_tab.p_pre_com =
malloc(pgc.com_tab.i_pre_com_nb *sizeof(ifo_command_t));
if( pgc.com_tab.p_pre_com == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.com_tab.ps_pre_com,
pgc.com_tab.i_pre_com_nb *COMMAND_SIZE );
for( i=0 ; i<pgc.com_tab.i_pre_com_nb ; i++ )
{
GETCOMMAND( &pgc.com_tab.p_pre_com[i] );
}
}
if( pgc.com_tab.i_post_com_nb )
{
pgc.com_tab.ps_post_com =
malloc(pgc.com_tab.i_post_com_nb *COMMAND_SIZE);
if( pgc.com_tab.ps_post_com == NULL )
pgc.com_tab.p_post_com =
malloc(pgc.com_tab.i_post_com_nb *sizeof(ifo_command_t));
if( pgc.com_tab.p_post_com == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.com_tab.ps_post_com,
pgc.com_tab.i_post_com_nb *COMMAND_SIZE );
for( i=0 ; i<pgc.com_tab.i_post_com_nb ; i++ )
{
GETCOMMAND( &pgc.com_tab.p_post_com[i] );
}
}
if( pgc.com_tab.i_cell_com_nb )
{
pgc.com_tab.ps_cell_com =
malloc(pgc.com_tab.i_cell_com_nb *COMMAND_SIZE);
if( pgc.com_tab.ps_cell_com == NULL )
pgc.com_tab.p_cell_com =
malloc(pgc.com_tab.i_cell_com_nb *sizeof(ifo_command_t));
if( pgc.com_tab.p_cell_com == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.com_tab.ps_cell_com,
pgc.com_tab.i_cell_com_nb *COMMAND_SIZE );
for( i=0 ; i<pgc.com_tab.i_cell_com_nb ; i++ )
{
GETCOMMAND( &pgc.com_tab.p_cell_com[i] );
}
}
}
/* Parsing of pgc_prg_map_t */
......@@ -389,7 +413,7 @@ static pgci_inf_t ReadUnit( ifo_t* p_ifo )
int i;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "Unit\n" );
//fprintf( stderr, "Unit\n" );
GETS( &inf.i_srp_nb );
FLUSH( 2 );
......@@ -428,7 +452,7 @@ static pgci_ut_t ReadUnitTable( ifo_t* p_ifo )
int i;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "Unit Table\n" );
//fprintf( stderr, "Unit Table\n" );
GETS( &pgci.i_lu_nb );
FLUSH( 2 );
......@@ -474,7 +498,7 @@ static c_adt_t ReadCellInf( ifo_t* p_ifo )
int i, i_max;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "CELL ADD\n" );
//fprintf( stderr, "CELL ADD\n" );
GETS( &c_adt.i_vob_nb );
FLUSH( 2 );
......@@ -508,7 +532,7 @@ static vobu_admap_t ReadMap( ifo_t* p_ifo )
int i, i_max;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "VOBU ADMAP\n" );
//fprintf( stderr, "VOBU ADMAP\n" );
GETL( &map.i_ebyte );
i_max = ( i_start + map.i_ebyte + 1 - p_ifo->i_pos ) / sizeof(u32);
......@@ -533,9 +557,9 @@ static vmgi_mat_t ReadVMGInfMat( ifo_t* p_ifo )
{
vmgi_mat_t mat;
int i;
off64_t i_start = p_ifo->i_pos;
// off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "VMGI\n" );
//fprintf( stderr, "VMGI\n" );
GET( mat.psz_id , 12 );
mat.psz_id[12] = '\0';
......@@ -590,9 +614,9 @@ static vmg_ptt_srpt_t ReadVMGTitlePointer( ifo_t* p_ifo )
{
vmg_ptt_srpt_t ptr;
int i;
off64_t i_start = p_ifo->i_pos;
// off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "PTR\n" );
//fprintf( stderr, "PTR\n" );
GETS( &ptr.i_ttu_nb );
FLUSH( 2 );
......@@ -628,7 +652,7 @@ static vmg_ptl_mait_t ReadParentalInf( ifo_t* p_ifo )
int i, j, k;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "PTL\n" );
//fprintf( stderr, "PTL\n" );
GETS( &par.i_country_nb );
GETS( &par.i_vts_nb );
......@@ -687,7 +711,7 @@ static vmg_vts_atrt_t ReadVTSAttr( ifo_t* p_ifo )
int i, j;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "VTS ATTR\n" );
//fprintf( stderr, "VTS ATTR\n" );
GETS( &atrt.i_vts_nb );
FLUSH( 2 );
......@@ -820,9 +844,9 @@ static vtsi_mat_t ReadVTSInfMat( ifo_t* p_ifo )
{
vtsi_mat_t mat;
int i;
off64_t i_start = p_ifo->i_pos;
// off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "VTSI\n" );
//fprintf( stderr, "VTSI\n" );
GET( mat.psz_id , 12 );
mat.psz_id[12] = '\0';
......@@ -888,7 +912,7 @@ static vts_ptt_srpt_t ReadVTSTitlePointer( ifo_t* p_ifo )
int i;
off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "PTR\n" );
//fprintf( stderr, "PTR\n" );
GETS( &ptr.i_ttu_nb );
FLUSH( 2 );
......@@ -930,9 +954,9 @@ static vts_tmap_ti_t ReadVTSTimeMap( ifo_t* p_ifo )
{
vts_tmap_ti_t tmap;
int i,j;
off64_t i_start = p_ifo->i_pos;
// off64_t i_start = p_ifo->i_pos;
fprintf( stderr, "TMAP\n" );
//fprintf( stderr, "TMAP\n" );
GETS( &tmap.i_nb );
FLUSH( 2 );
......@@ -1069,10 +1093,10 @@ void IfoRead( ifo_t* p_ifo )
p_ifo->b_error = 1;
return;
}
for( i=0 ; i<1 /*p_ifo->vmg.mat.i_tts_nb*/ ; i++ )
for( i=0 ; i<1/*p_ifo->vmg.mat.i_tts_nb*/ ; i++ )
{
fprintf( stderr, "######### VTS %d #############\n", i+1 );
intf_WarnMsg( 3, "######### VTS %d #############\n", i+1 );
i_off = p_ifo->vmg.ptt_srpt.p_tts[i].i_ssector *DVD_LB_SIZE;
p_ifo->i_pos = lseek64( p_ifo->i_fd, i_off, SEEK_SET );
......@@ -1082,3 +1106,23 @@ fprintf( stderr, "######### VTS %d #############\n", i+1 );
}
return;
}
/*
* IFO virtual machine : a set of commands that give the behaviour of the dvd
*/
/*****************************************************************************
* CommandRead : translates the command strings in ifo into command
* structures.
*****************************************************************************/
ifo_command_t CommandRead( ifo_t* p_ifo )
{
ifo_command_t com;
return com;
}
/*****************************************************************************
*
*****************************************************************************/
......@@ -33,6 +33,20 @@
* Program Chain structures
*/
/* Ifo vitual machine Commands */
typedef struct ifo_command_s
{
u8 i_type :3;
u8 i_direct :1;
u8 i_cmd :4;
u8 i_dir_cmp :1;
u8 i_cmp :3;
u8 i_sub_cmd :4;
u16 i_v0 :16;
u16 i_v2 :16;
u16 i_v4 :16;
} ifo_command_t;
/* Program Chain Command Table
- start at i_pgc_com_tab_sbyte */
typedef struct pgc_com_tab_s
......@@ -41,11 +55,10 @@ typedef struct pgc_com_tab_s
u16 i_post_com_nb; // 2 bytes
u16 i_cell_com_nb; // 2 bytes
// char[2] ???
char* ps_pre_com; // i_pre_com_nb * 8 bytes
char* ps_post_com; // i_post_com_nb * 8 bytes
char* ps_cell_com; // i_cell_com_nb * 8 bytes
ifo_command_t* p_pre_com; // i_pre_com_nb * 8 bytes
ifo_command_t* p_post_com; // i_post_com_nb * 8 bytes
ifo_command_t* p_cell_com; // i_cell_com_nb * 8 bytes
} pgc_com_tab_t;
#define COMMAND_SIZE 8
/* Program Chain Map Table
* - start at "i_pgc_prg_map_sbyte" */
......
......@@ -2,7 +2,7 @@
* input_dvd.c: DVD reading
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.6 2001/01/22 05:20:44 stef Exp $
* $Id: input_dvd.c,v 1.7 2001/01/29 06:10:10 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -43,7 +43,7 @@
# include <sys/dvdio.h>
#endif
#ifdef LINUX_DVD
#include <linux/cdrom.h>
# include <linux/cdrom.h>
#endif
#include "config.h"
......@@ -68,6 +68,7 @@
#include "debug.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
......@@ -134,6 +135,7 @@ static void DVDInit( input_thread_t * p_input )
lseek64( p_input->i_handle, 0, SEEK_SET );
/* Ifo initialisation */
intf_Msg( 3, "Ifo: Initialization" );
p_method->ifo = IfoInit( p_input->i_handle );
IfoRead( &(p_method->ifo) );
......@@ -143,9 +145,8 @@ static void DVDInit( input_thread_t * p_input )
{
int i;
fprintf(stderr, " CSS Init start\n" );
intf_Msg( 3, "CSS: Initialization" );
p_method->css = CSSInit( p_input->i_handle );
fprintf(stderr, " CSS Init end\n" );
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 *
......@@ -158,12 +159,10 @@ fprintf(stderr, " CSS Init end\n" );
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;
p_method->ifo.p_vts[i].i_pos +
p_method->ifo.p_vts[i].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
}
fprintf(stderr, " CSS Get start\n" );
CSSGetKeys( &(p_method->css) );
fprintf(stderr, " CSS Get end\n" );
}
#endif
......@@ -171,7 +170,7 @@ fprintf(stderr, " CSS Get end\n" );
p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector *DVD_LB_SIZE;
i_start = lseek64( p_input->i_handle, i_start, SEEK_SET );
fprintf(stderr, "Begin at : %lld\n", (long long)i_start );
intf_Msg( "VOB start at : %lld", (long long)i_start );
#if 1
input_InitStream( p_input, sizeof( stream_ps_data_t ) );
......@@ -315,19 +314,26 @@ static void DVDEnd( input_thread_t * p_input )
static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
size_t i_len )
{
// FIXME : aie aie ugly kludge for testing purposes :)
static byte_t p_tmp[2048];
thread_dvd_data_t * p_method;
int i_nb;
off64_t i_pos;
p_method = (thread_dvd_data_t *)p_input->p_plugin_data;
// if( !p_method->b_encrypted )
// {
i_pos = lseek64( p_input->i_handle, 0, SEEK_CUR );
if( !p_method->b_encrypted )
{
i_nb = read( p_input->i_handle, p_buffer, i_len );
#if 0
}
else
{
i_nb = read( p_input->i_handle, p_buffer, 4096 );
CSSDescrambleSector( p_method->css.p_title_key.key, p_buffer );
lseek64( p_input->i_handle, i_pos & ~0x7FF, SEEK_SET );
i_nb = read( p_input->i_handle, p_tmp, 0x800 );
CSSDescrambleSector( p_method->css.p_title_key[0].key, p_tmp );
memcpy( p_buffer, p_tmp + (i_pos & 0x7FF ), i_len );
}
switch( i_nb )
{
......@@ -335,15 +341,14 @@ static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
/* End of File */
return( 1 );
case -1:
intf_ErrMsg( "Read failed (%s)", strerror(errno) );
intf_ErrMsg( "DVD: Read failed (%s)", strerror(errno) );
return( -1 );
default:
break;
}
#endif
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.i_tell += i_nb; //lseek64( p_input->i_handle,
// p_input->stream.i_tell+i_len, SEEK_SET );
p_input->stream.i_tell =
lseek64( p_input->i_handle, i_pos+i_len, SEEK_SET );
vlc_mutex_unlock( &p_input->stream.stream_lock );
return( 0 );
}
......@@ -379,7 +384,8 @@ static int DVDRead( input_thread_t * p_input,
/* This is not the startcode of a packet. Read the stream
* until we find one. */
u32 i_startcode = U32_AT(p_header);
int i_dummy,i_nb;
int i_nb;
byte_t i_dummy;
if( i_startcode )
{
......@@ -392,7 +398,8 @@ static int DVDRead( input_thread_t * p_input,
while( (i_startcode & 0xFFFFFF00) != 0x100L )
{
i_startcode <<= 8;
if( (i_nb = read( p_input->i_handle, &i_dummy, 1 )) != 0 )
fprintf( stderr, "sprotch\n" );
if( (i_nb = SafeRead( p_input, &i_dummy, 1 )) != 0 )
{
i_startcode |= i_dummy;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment