* 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.13 2001/02/20 07:49:12 sam Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
#include "intf_msg.h"
#include "dvd_ifo.h"
+#include "dvd_udf.h"
+#include "dvd_css.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.
*/
-/*****************************************************************************
- * 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.
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 );
+
+ /* 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;
}
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++ )
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
+ pgc.i_cell_pos_inf_sbyte, SEEK_SET );
pgc.p_cell_pos_inf = malloc( pgc.i_cell_nb *sizeof(cell_pos_inf_t) );
- if( pgc.p_cell_play_inf == NULL )
+ if( pgc.p_cell_pos_inf == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
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 );
}
//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_ptt_nb, ptr.p_tts[i].i_tts_nb,ptr.p_tts[i].i_vts_ttn );
}
return ptr;
//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.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 );
}
- 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 )
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;
}
-
+#endif
/*
* IFO virtual machine : a set of commands that give the
* interactive behaviour of the dvd