Commit 8e3c802c authored by Stéphane Borel's avatar Stéphane Borel

-UDF filesystem support so that we know the location of the first video

related file with 100% reliability (great change that should make DVDs
with binaries and extra stuff work with vlc).

-Correction of a bug in ifo reading that falsified the adress of
video titles.

-Changed the method for selecting title at start. It is _not_ reliable
though, but it is better than the preceding one.
parent f1175e71
......@@ -294,6 +294,7 @@ PLUGIN_DUMMY = plugins/dummy/dummy.o \
PLUGIN_DVD = plugins/dvd/dvd.o \
plugins/dvd/input_dvd.o \
plugins/dvd/dvd_ifo.o \
plugins/dvd/dvd_udf.o \
plugins/dvd/dvd_css.o
PLUGIN_ESD = plugins/esd/esd.o \
......
......@@ -2,7 +2,7 @@
* dvd_css.c: Functions for DVD authentification and unscrambling
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_css.c,v 1.9 2001/02/15 21:03:27 stef Exp $
* $Id: dvd_css.c,v 1.10 2001/02/18 01:42:04 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -1052,7 +1052,7 @@ int CSSGetKeys( css_t * p_css )
int i_highest;
int i,j,k;
for( i_title = 0 ; i_title < 1/*p_css->i_title_nb*/ ; i_title++ )
for( i_title = 0 ; i_title < p_css->i_title_nb ; i_title++ )
{
/* Initialization for each title */
memset( p_title_key, 0, 10 );
......
......@@ -2,7 +2,7 @@
* dvd_ifo.c: Functions for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: dvd_ifo.c,v 1.8 2001/02/15 21:03:27 stef Exp $
* $Id: dvd_ifo.c,v 1.9 2001/02/18 01:42:05 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -38,6 +38,7 @@
#include "intf_msg.h"
#include "dvd_ifo.h"
#include "dvd_udf.h"
#include "input_dvd.h"
void CommandRead( ifo_command_t );
......@@ -46,57 +47,6 @@ void CommandRead( ifo_command_t );
* IFO Management.
*/
/*****************************************************************************
* IfoFindVMG : When reading directly on a device, finds the offset to the
* beginning of video_ts.ifo.
*****************************************************************************/
static int IfoFindVMG( ifo_t* p_ifo )
{
char psz_ifo_start[12] = "DVDVIDEO-VMG";
char psz_test[12];
read( p_ifo->i_fd, psz_test, 12 );
while( strncmp( psz_test, psz_ifo_start, 12 ) != 0 )
{
/* The start of ifo file is on a sector boundary */
p_ifo->i_pos = lseek( p_ifo->i_fd,
p_ifo->i_pos + DVD_LB_SIZE,
SEEK_SET );
read( p_ifo->i_fd, psz_test, 12 );
}
p_ifo->i_off = p_ifo->i_pos;
fprintf( stderr, "VMG Off : %lld\n", (long long)(p_ifo->i_off) );
return 0;
}
/*****************************************************************************
* IfoFindVTS : beginning of vts_*.ifo.
*****************************************************************************/
static int IfoFindVTS( ifo_t* p_ifo )
{
char psz_ifo_start[12] = "DVDVIDEO-VTS";
char psz_test[12];
read( p_ifo->i_fd, psz_test, 12 );
while( strncmp( psz_test, psz_ifo_start, 12 ) != 0 )
{
/* The start of ifo file is on a sector boundary */
p_ifo->i_pos = lseek( p_ifo->i_fd,
p_ifo->i_pos + DVD_LB_SIZE,
SEEK_SET );
read( p_ifo->i_fd, psz_test, 12 );
}
p_ifo->i_off = p_ifo->i_pos;
fprintf( stderr, "VTS Off : %lld\n", (long long)(p_ifo->i_off) );
return 0;
}
/*****************************************************************************
* IfoInit : Creates an ifo structure and prepares for parsing directly
* on DVD device.
......@@ -104,14 +54,15 @@ fprintf( stderr, "VTS Off : %lld\n", (long long)(p_ifo->i_off) );
ifo_t IfoInit( int i_fd )
{
ifo_t ifo;
u32 i_lba;
/* If we are here the dvd device has already been opened */
ifo.i_fd = i_fd;
/* No data at the beginning of the disk
* 512000 bytes is just another value :) */
ifo.i_pos = lseek( ifo.i_fd, 250 *DVD_LB_SIZE, SEEK_SET );
/* FIXME : use udf filesystem to find the beginning of the file */
IfoFindVMG( &ifo );
i_lba = UDFFindFile( i_fd, "/VIDEO_TS/VIDEO_TS.IFO");
ifo.i_off = (off_t)(i_lba) * DVD_LB_SIZE;
ifo.i_pos = lseek( ifo.i_fd, ifo.i_off, SEEK_SET );
return ifo;
}
......@@ -648,6 +599,7 @@ static vmg_ptt_srpt_t ReadVMGTitlePointer( ifo_t* p_ifo )
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 );
}
return ptr;
......@@ -1030,56 +982,56 @@ static vts_t ReadVTS( ifo_t* p_ifo )
vts.mat = ReadVTSInfMat( p_ifo );
if( vts.mat.i_ptt_srpt_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_ptt_srpt_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.ptt_srpt = ReadVTSTitlePointer( p_ifo );
}
if( vts.mat.i_m_pgci_ut_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_m_pgci_ut_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.pgci_ut = ReadUnitTable( p_ifo );
}
if( vts.mat.i_pgcit_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_pgcit_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.pgci_ti = ReadUnit( p_ifo );
}
if( vts.mat.i_tmap_ti_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_tmap_ti_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.tmap_ti = ReadVTSTimeMap( p_ifo );
}
if( vts.mat.i_m_c_adt_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_m_c_adt_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.m_c_adt = ReadCellInf( p_ifo );
}
if( vts.mat.i_m_vobu_admap_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_m_vobu_admap_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.m_vobu_admap = ReadMap( p_ifo );
}
if( vts.mat.i_c_adt_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_c_adt_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.c_adt = ReadCellInf( p_ifo );
}
if( vts.mat.i_vobu_admap_ssector )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, p_ifo->i_off +
p_ifo->i_pos = lseek( p_ifo->i_fd, vts.i_pos +
vts.mat.i_vobu_admap_ssector *DVD_LB_SIZE,
SEEK_SET );
vts.vobu_admap = ReadMap( p_ifo );
......@@ -1113,19 +1065,24 @@ void IfoRead( ifo_t* p_ifo )
p_ifo->b_error = 1;
return;
}
for( i=0 ; i<p_ifo->vmg.mat.i_tts_nb ; i++ )
{
intf_WarnMsg( 2, "ifo: initializing VTS %d", i+1 );
i_off = (off_t)(p_ifo->vmg.ptt_srpt.p_tts[i].i_ssector) *DVD_LB_SIZE;
i_off = (off_t)( p_ifo->vmg.ptt_srpt.p_tts[i].i_ssector ) *DVD_LB_SIZE
+ p_ifo->i_off;
p_ifo->i_pos = lseek( p_ifo->i_fd, i_off, SEEK_SET );
fprintf( stderr, "%lld\n" , p_ifo->i_pos );
/* FIXME : use udf filesystem to avoid this */
IfoFindVTS( p_ifo );
/* FIXME : I really don't know why udf find file
* does not give the exact beginning of file */
p_ifo->p_vts[i] = ReadVTS( p_ifo );
}
return;
}
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
* dvd_udf.h: structures for udf filesystem tools.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: dvd_udf.h,v 1.1 2001/02/15 21:03:27 stef Exp $
* $Id: dvd_udf.h,v 1.2 2001/02/18 01:42:05 stef Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
......@@ -23,3 +23,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*
* Fonctions in dvd_udf.c
*/
u32 UDFFindFile( int, char * );
......@@ -10,7 +10,7 @@
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_dvd.c,v 1.12 2001/02/16 09:25:03 sam Exp $
* $Id: input_dvd.c,v 1.13 2001/02/18 01:42:05 stef Exp $
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
......@@ -159,6 +159,16 @@ static int DVDCheckCSS( input_thread_t * p_input )
#endif
}
/*****************************************************************************
* DVDSetRegion: initialize input data for title x, chapter y. It should
* be called for each user navigation request.
*****************************************************************************/
static int DVDSetRegion( int i_title, int i_chapter )
{
return 0;
}
/*****************************************************************************
* DVDInit: initializes DVD structures
*****************************************************************************/
......@@ -182,7 +192,6 @@ static void DVDInit( input_thread_t * p_input )
p_method->i_fd = p_input->i_handle;
/* FIXME: read several packets once */
p_method->i_read_once = 1;
p_method->i_title = 0;
p_method->b_encrypted = DVDCheckCSS( p_input );
lseek( p_input->i_handle, 0, SEEK_SET );
......@@ -194,6 +203,9 @@ static void DVDInit( input_thread_t * p_input )
/* Ifo initialisation */
p_method->ifo = IfoInit( p_input->i_handle );
/* FIXME: kludge */
p_method->i_title = p_method->ifo.vmg.ptt_srpt.p_tts[0].i_tts_nb;
/* CSS initialisation */
if( p_method->b_encrypted )
{
......@@ -217,7 +229,7 @@ static void DVDInit( input_thread_t * p_input )
IfoRead( &(p_method->ifo) );
intf_WarnMsg( 3, "Ifo: Initialized" );
/* CSS title keys */
/* CSS title keys decryption */
if( p_method->b_encrypted )
{
......@@ -260,8 +272,8 @@ static void DVDInit( input_thread_t * p_input )
i_end_cell = 0;
/* Loop on the number of vobs */
while( p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_cell].i_vob_id <=
p_method->ifo.p_vts[0].c_adt.i_vob_nb )
while( p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_cell].i_vob_id <=
p_method->ifo.p_vts[p_method->i_title].c_adt.i_vob_nb )
{
i_cell_1 = i_cell;
......@@ -269,17 +281,17 @@ static void DVDInit( input_thread_t * p_input )
do
{
i_cell++;
if( i_cell >= p_method->ifo.p_vts[0].c_adt.i_cell_nb )
if( i_cell >= p_method->ifo.p_vts[p_method->i_title].c_adt.i_cell_nb )
{
break;
}
}
while( p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_cell-1].i_cell_id <
p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_cell].i_cell_id );
while( p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_cell-1].i_cell_id <
p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_cell].i_cell_id );
if( p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_cell-1].i_cell_id >
p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_end_cell].i_cell_id )
if( p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_cell-1].i_cell_id >
p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_end_cell].i_cell_id )
{
i_start_cell = i_cell_1;
i_end_cell = i_cell - 1;
......@@ -288,7 +300,7 @@ static void DVDInit( input_thread_t * p_input )
/* The preceding does not work with all DVD, so we give the
* last cell of the title as end */
i_end_cell = p_method->ifo.p_vts[0].c_adt.i_cell_nb - 1;
i_end_cell = p_method->ifo.p_vts[p_method->i_title].c_adt.i_cell_nb - 1;
intf_WarnMsg( 2, "DVD: Start cell: %d End Cell: %d",
i_start_cell, i_end_cell );
......@@ -297,17 +309,17 @@ static void DVDInit( input_thread_t * p_input )
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[0].i_pos + DVD_LB_SIZE *
( p_method->ifo.p_vts[0].mat.i_tt_vobs_ssector +
p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_start_cell].i_ssector );
i_start = p_method->ifo.p_vts[p_method->i_title].i_pos + DVD_LB_SIZE *
( p_method->ifo.p_vts[p_method->i_title].mat.i_tt_vobs_ssector +
p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_start_cell].i_ssector );
p_method->i_start_byte = i_start;
i_start = lseek( p_input->i_handle, i_start, SEEK_SET );
intf_WarnMsg( 3, "DVD: VOBstart at: %lld", i_start );
i_size = (off_t)
( p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_end_cell].i_esector -
p_method->ifo.p_vts[0].c_adt.p_cell_inf[i_start_cell].i_ssector + 1 )
( p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_end_cell].i_esector -
p_method->ifo.p_vts[p_method->i_title].c_adt.p_cell_inf[i_start_cell].i_ssector + 1 )
*DVD_LB_SIZE;
intf_WarnMsg( 3, "DVD: stream size: %lld", i_size );
......
......@@ -27,7 +27,7 @@
#define DVD_LB_SIZE 2048
/*****************************************************************************
* thread_dvd_data_t: extension of input_thread_t for DVD specificity
* thread_dvd_data_t: extension of input_thread_t for DVD specificity.
*****************************************************************************/
typedef struct thread_dvd_data_s
{
......@@ -36,7 +36,6 @@ typedef struct thread_dvd_data_s
int i_read_once; // NB of bytes read by DVDRead
int i_title; // Current Title
/* FIXME: include these in a struct */
int i_start_byte;
int i_start_cell;
int i_end_cell;
......
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