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

. Beginning of dvd_input.

. Parsing of ifo file almost completed.
. Still does not work well.
parent e360e2a4
......@@ -186,6 +186,8 @@ INTERFACE = src/interface/main.o \
INPUT = src/input/input_ps.o \
src/input/input_ts.o \
src/input/dvd_ifo.o \
src/input/input_dvd.o \
src/input/mpeg_system.o \
src/input/input_ext-dec.o \
src/input/input_dec.o \
......
......@@ -211,6 +211,8 @@
* mark it to be presented */
#define DEFAULT_PTS_DELAY (.2*CLOCK_FREQ)
#define INPUT_DVD_DEVICE_VAR "vlc_dvd_device"
#define INPUT_DVD_DEVICE_DEFAULT "/dev/dvd"
#define INPUT_DVD_AUDIO_VAR "vlc_dvd_audio"
#define INPUT_DVD_CHANNEL_VAR "vlc_dvd_channel"
#define INPUT_DVD_SUBTITLE_VAR "vlc_dvd_subtitle"
......@@ -243,9 +245,9 @@
#define AOUT_STEREO_DEFAULT 1
/* Volume */
#define VOLUME_DEFAULT 256
#define VOLUME_STEP 5
#define VOLUME_MAX 765
#define VOLUME_DEFAULT 512
#define VOLUME_STEP 128
#define VOLUME_MAX 1024
/* Environment variable for output rate, and default value */
#define AOUT_RATE_VAR "vlc_audio_rate"
......
......@@ -4,7 +4,7 @@
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-intf.h,v 1.8 2000/12/21 19:24:26 massiot Exp $
* $Id: input_ext-intf.h,v 1.9 2001/01/14 07:08:00 stef Exp $
*
* Authors:
*
......@@ -255,6 +255,7 @@ typedef struct input_config_s
/* Input methods */
#define INPUT_METHOD_NONE 0 /* input thread is inactive */
#define INPUT_METHOD_FILE 10 /* stream is read from file p_source */
#define INPUT_METHOD_DVD 11 /* stream is read from dvd device */
#define INPUT_METHOD_UCAST 20 /* UDP unicast */
#define INPUT_METHOD_MCAST 21 /* UDP multicast */
#define INPUT_METHOD_BCAST 22 /* UDP broadcast */
......
......@@ -44,6 +44,7 @@ typedef struct
boolean_t b_audio; /* is audio output allowed ? */
boolean_t b_video; /* is video output allowed ? */
boolean_t b_vlans; /* are vlans supported ? */
boolean_t b_dvd; /* DVD mode ? */
/* Unique threads */
p_aout_thread_t p_aout; /* audio output thread */
......
/*****************************************************************************
* dvd_ifo.c: Functions for ifo parsing
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
*
* Author: Stphane Borel <stef@via.ecp.fr>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <malloc.h>
#include "common.h"
#include "intf_msg.h"
#include "dvd_ifo.h"
/*
* IFO Management.
*/
/*****************************************************************************
* IfoFindStart : When reading directly on a device, finds the offset to the
* beginning of video_ts.ifo.
*****************************************************************************/
static int IfoFindStart( 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 : %d\n", 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 : %d\n", 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;
/* 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 */
IfoFindStart( &ifo );
return ifo;
}
/*****************************************************************************
* IfoEnd : Frees all the memory allocated to ifo structures
*****************************************************************************/
void IfoEnd( ifo_t* p_ifo )
{
int i,j;
/* Free structures from video title sets */
for( j=0 ; j<p_ifo->vmg.mat.i_tts_nb ; j++ )
{
free( p_ifo->p_vts[j].vobu_admap.pi_vobu_ssector );
free( p_ifo->p_vts[j].c_adt.p_cell_inf );
free( p_ifo->p_vts[j].m_vobu_admap.pi_vobu_ssector );
free( p_ifo->p_vts[j].m_c_adt.p_cell_inf );
for( i=0 ; i<p_ifo->p_vts[j].tmap_ti.i_nb ; i++ )
{
free( p_ifo->p_vts[j].tmap_ti.p_tmap[i].pi_sector );
}
free( p_ifo->p_vts[j].tmap_ti.pi_sbyte );
free( p_ifo->p_vts[j].tmap_ti.p_tmap );
free( p_ifo->p_vts[j].pgci_ti.p_lu_desc );
free( p_ifo->p_vts[j].pgci_ti.p_lu );
free( p_ifo->p_vts[j].pgci_ut.p_lu_desc );
free( p_ifo->p_vts[j].pgci_ut.p_lu );
}
free( p_ifo->p_vts );
/* Free structures from video manager */
free( p_ifo->vmg.vobu_admap.pi_vobu_ssector );
free( p_ifo->vmg.c_adt.p_cell_inf );
for( i=0 ; i<p_ifo->vmg.pgci_ut.i_lu_nb ; i++ )
{
free( p_ifo->vmg.pgci_ut.p_lu[i].p_srp );
}
free( p_ifo->vmg.pgci_ut.p_lu_desc );
free( p_ifo->vmg.pgci_ut.p_lu );
for( i=1 ; i<=8 ; i++ )
{
free( p_ifo->vmg.ptl_mait.p_ptl_mask->ppi_ptl_mask[i] );
}
free( p_ifo->vmg.ptl_mait.p_ptl_desc );
free( p_ifo->vmg.ptl_mait.p_ptl_mask );
free( p_ifo->vmg.vts_atrt.pi_vts_atrt_sbyte );
free( p_ifo->vmg.vts_atrt.p_vts_atrt );
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.psz_cell_com );
free( p_ifo->vmg.pgc.com_tab.psz_post_com );
free( p_ifo->vmg.pgc.com_tab.psz_pre_com );
return;
}
/*
* Macros to process ifo files
*/
#define GET( p_field , i_len ) \
{ \
read( p_ifo->i_fd , p_field , i_len ); \
fprintf(stderr, "Pos : %d\n", p_ifo->i_pos - i_start); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + i_len , SEEK_SET );\
}
#define GETC( p_field ) \
{ \
read( p_ifo->i_fd , p_field , 1 ); \
fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \
*p_field ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 1 , SEEK_SET ); \
}
#define GETS( p_field ) \
{ \
read( p_ifo->i_fd , p_field , 2 ); \
*p_field = ntohs( *p_field ); \
fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \
*p_field ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 2 , SEEK_SET ); \
}
#define GETL( p_field ) \
{ \
read( p_ifo->i_fd , p_field , 4 ); \
*p_field = ntohl( *p_field ); \
fprintf(stderr, "Pos : %d Value : %d\n", p_ifo->i_pos - i_start, \
*p_field ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 4 , SEEK_SET ); \
}
#define GETLL( p_field ) \
{ \
read( p_ifo->i_fd , p_field , 8 ); \
*p_field = ntoh64( *p_field ); \
fprintf(stderr, "Pos : %d Value : %lld\n", p_ifo->i_pos - i_start, \
*p_field ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + 8 , SEEK_SET ); \
}
#define FLUSH( i_len ) \
{ \
fprintf(stderr, "Pos : %d\n", p_ifo->i_pos - i_start ); \
p_ifo->i_pos = lseek( p_ifo->i_fd , p_ifo->i_pos + i_len , SEEK_SET );\
}
/*
* Function common to Video Manager and Video Title set Processing
*/
/*****************************************************************************
* ReadPGC : Fills the Program Chain structure.
*****************************************************************************/
static pgc_t ReadPGC( ifo_t* p_ifo )
{
pgc_t pgc;
int i;
int i_start = p_ifo->i_pos;
fprintf( stderr, "PGC\n" );
FLUSH(2);
GETC( &pgc.i_prg_nb );
GETC( &pgc.i_cell_nb );
GETL( &pgc.i_play_time );
GETL( &pgc.i_prohibited_user_op );
for( i=0 ; i<8 ; i++ )
{
GETS( &pgc.pi_audio_status[i] );
}
for( i=0 ; i<32 ; i++ )
{
GETL( &pgc.pi_subpic_status[i] );
}
GETS( &pgc.i_next_pgc_nb );
GETS( &pgc.i_prev_pgc_nb );
GETS( &pgc.i_goup_pgc_nb );
GETC( &pgc.i_still_time );
GETC( &pgc.i_play_mode );
for( i=0 ; i<16 ; i++ )
{
GETL( &pgc.pi_yuv_color[i] );
/* FIXME : We have to erase the extra bit */
}
GETS( &pgc.i_com_tab_sbyte );
GETS( &pgc.i_prg_map_sbyte );
GETS( &pgc.i_cell_play_inf_sbyte );
GETS( &pgc.i_cell_pos_inf_sbyte );
/* Parsing of pgc_com_tab_t */
if( pgc.i_com_tab_sbyte )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
+ pgc.i_com_tab_sbyte, SEEK_SET );
GETS( &pgc.com_tab.i_pre_com_nb );
GETS( &pgc.com_tab.i_post_com_nb );
GETS( &pgc.com_tab.i_cell_com_nb );
pgc.com_tab.psz_pre_com = malloc(sizeof(8*pgc.com_tab.i_pre_com_nb));
if( pgc.com_tab.psz_pre_com == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.com_tab.psz_pre_com, 8*pgc.com_tab.i_pre_com_nb );
pgc.com_tab.psz_post_com = malloc(sizeof(8*pgc.com_tab.i_pre_com_nb));
if( pgc.com_tab.psz_post_com == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.com_tab.psz_post_com, 8*pgc.com_tab.i_post_com_nb );
pgc.com_tab.psz_cell_com = malloc(sizeof(8*pgc.com_tab.i_pre_com_nb));
if( pgc.com_tab.psz_cell_com == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.com_tab.psz_cell_com, 8*pgc.com_tab.i_cell_com_nb );
}
/* Parsing of pgc_prg_map_t */
if( pgc.i_prg_map_sbyte )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
+ pgc.i_prg_map_sbyte, SEEK_SET );
pgc.prg_map.pi_entry_cell = malloc( sizeof(pgc.i_prg_nb) );
if( pgc.prg_map.pi_entry_cell == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
GET( pgc.prg_map.pi_entry_cell, pgc.i_prg_nb );
/* FIXME : check endianness here */
}
/* Parsing of cell_play_inf_t */
if( pgc.i_cell_play_inf_sbyte )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start
+ pgc.i_cell_play_inf_sbyte, SEEK_SET );
pgc.p_cell_play_inf = malloc( pgc.i_cell_nb *sizeof(cell_play_inf_t) );
if( pgc.p_cell_play_inf == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
for( i=0 ; i<pgc.i_cell_nb ; i++ )
{
GETS( &pgc.p_cell_play_inf[i].i_cat );
GETC( &pgc.p_cell_play_inf[i].i_still_time );
GETS( &pgc.p_cell_play_inf[i].i_com_nb );
GETL( &pgc.p_cell_play_inf[i].i_play_time );
GETL( &pgc.p_cell_play_inf[i].i_entry_sector );
GETL( &pgc.p_cell_play_inf[i].i_first_ilvu_vobu_esector );
GETL( &pgc.p_cell_play_inf[i].i_lvobu_ssector );
GETL( &pgc.p_cell_play_inf[i].i_lsector );
}
}
/* Parsing of cell_pos_inf_map */
if( pgc.i_cell_pos_inf_sbyte )
{
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 )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return pgc;
}
for( i=0 ; i<pgc.i_cell_nb ; i++ )
{
GETS( &pgc.p_cell_pos_inf[i].i_vob_id );
FLUSH( 1 );
GETC( &pgc.p_cell_pos_inf[i].i_cell_id );
}
}
return pgc;
}
/*****************************************************************************
* ReadUnitTable : Fills the Language Unit structure.
*****************************************************************************/
static pgci_ut_t ReadUnitTable( ifo_t* p_ifo )
{
pgci_ut_t lang;
int i, j;
int i_start = p_ifo->i_pos;
fprintf( stderr, "LU\n" );
GETS( &lang.i_lu_nb );
FLUSH( 2 );
GETL( &lang.i_ebyte );
lang.p_lu_desc = malloc( lang.i_lu_nb *sizeof(pgci_lu_desc_t) );
if( lang.p_lu_desc == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return lang;
}
for( i=0 ; i<lang.i_lu_nb ; i++ )
{
GETS( &lang.p_lu_desc[i].i_lang_code );
FLUSH( 1 );
GETC( &lang.p_lu_desc[i].i_existence_mask );
GETL( &lang.p_lu_desc[i].i_lu_sbyte );
}
lang.p_lu = malloc( lang.i_lu_nb *sizeof(pgci_lu_t) );
if( lang.p_lu == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return lang;
}
for( i=0 ; i<lang.i_lu_nb ; i++ )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
lang.p_lu_desc[i].i_lu_sbyte,
SEEK_SET );
GETS( &lang.p_lu[i].i_srp_nb );
FLUSH( 2 );
GETL( &lang.p_lu[i].i_lu_ebyte );
lang.p_lu[i].p_srp = malloc( lang.p_lu[i].i_srp_nb *
sizeof(pgci_srp_t) );
if( lang.p_lu[i].p_srp == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return lang;
}
for( j=0 ; j<lang.p_lu[i].i_srp_nb ; j++ )
{
GETC( &lang.p_lu[i].p_srp[j].i_pgc_cat_mask );
GETC( &lang.p_lu[i].p_srp[j].i_pgc_cat );
GETS( &lang.p_lu[i].p_srp[j].i_par_mask );
GETL( &lang.p_lu[i].p_srp[j].i_pgci_sbyte );
}
for( j=0 ; j<lang.p_lu[i].i_srp_nb ; j++ )
{
p_ifo->i_pos = lseek( p_ifo->i_fd,
i_start + lang.p_lu[i].p_srp[j].i_pgci_sbyte,
SEEK_SET );
/* FIXME : Bad parsing somiewhere by here : various information
* don't match */
//lang.p_lu[i].p_srp[j].pgc = ReadPGC( p_ifo );
}
}
return lang;
}
/*****************************************************************************
* ReadCellInf : Fills the Cell Information structure.
*****************************************************************************/
static c_adt_t ReadCellInf( ifo_t* p_ifo )
{
c_adt_t c_adt;
int i, i_max;
int i_start = p_ifo->i_pos;
fprintf( stderr, "CELL ADD\n" );
GETS( &c_adt.i_vob_nb );
FLUSH( 2 );
GETL( &c_adt.i_ebyte );
i_max = ( i_start + c_adt.i_ebyte + 1 - p_ifo->i_pos ) / sizeof(cell_inf_t);
c_adt.p_cell_inf = malloc( i_max *sizeof(cell_inf_t) );
if( c_adt.p_cell_inf == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return c_adt;
}
for( i=0 ; i<i_max ; i++ )
{
GETS( &c_adt.p_cell_inf[i].i_vob_id );
GETC( &c_adt.p_cell_inf[i].i_cell_id );
FLUSH( 1 );
GETL( &c_adt.p_cell_inf[i].i_ssector );
GETL( &c_adt.p_cell_inf[i].i_esector );
}
return c_adt;
}
/*****************************************************************************
* ReadMap : Fills the VOBU Map structure.
*****************************************************************************/
static vobu_admap_t ReadMap( ifo_t* p_ifo )
{
vobu_admap_t map;
int i, i_max;
int i_start = p_ifo->i_pos;
fprintf( stderr, "VOBU ADMAP\n" );
GETL( &map.i_ebyte );
i_max = ( i_start + map.i_ebyte + 1 - p_ifo->i_pos ) / sizeof(u32);
map.pi_vobu_ssector = malloc( i_max *sizeof(u32) );
for( i=0 ; i<i_max ; i++ )
{
GETL( &map.pi_vobu_ssector[i] );
}
return map;
}
/*
* Video Manager Information Processing.
* This is what is contained in video_ts.ifo.
*/
/*****************************************************************************
* ReadVMGInfMat : Fills the Management Information structure.
*****************************************************************************/
static vmgi_mat_t ReadVMGInfMat( ifo_t* p_ifo )
{
vmgi_mat_t mat;
int i;
int i_start = p_ifo->i_pos;
fprintf( stderr, "VMGI\n" );
GET( mat.psz_id , 12 );
mat.psz_id[12] = '\0';
GETL( &mat.i_lsector );
FLUSH( 12 );
GETL( &mat.i_i_lsector );
FLUSH( 1 );
GETC( &mat.i_spec_ver );
GETL( &mat.i_cat );
GETS( &mat.i_vol_nb );
GETS( &mat.i_vol );
GETC( &mat.i_disc_side );
FLUSH( 19 );
GETS( &mat.i_tts_nb );
GET( mat.psz_provider_id, 32 );
GETLL( &mat.i_pos_code );
FLUSH( 24 );
GETL( &mat.i_i_mat_ebyte );
GETL( &mat.i_fp_pgc_sbyte );
FLUSH( 56 );
GETL( &mat.i_vobs_ssector );
GETL( &mat.i_ptt_srpt_ssector );
GETL( &mat.i_pgci_ut_ssector );
GETL( &mat.i_ptl_mait_ssector );
GETL( &mat.i_vts_atrt_ssector );
GETL( &mat.i_txtdt_mg_ssector );
GETL( &mat.i_c_adt_ssector );
GETL( &mat.i_vobu_admap_ssector );
FLUSH( 32 );
GETS( &mat.i_video_atrt );
FLUSH( 1 );
GETC( &mat.i_audio_nb );
for( i=0 ; i < 8 ; i++ )
{
GETLL( &mat.pi_audio_atrt[i] );
}
FLUSH( 17 );
GETC( &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 */
}
return mat;
}
/*****************************************************************************
* ReadVMGTitlePointer : Fills the Part Of Title Search Pointer structure.
*****************************************************************************/
static vmg_ptt_srpt_t ReadVMGTitlePointer( ifo_t* p_ifo )
{
vmg_ptt_srpt_t ptr;
int i;
int i_start = p_ifo->i_pos;
fprintf( stderr, "PTR\n" );
GETS( &ptr.i_ttu_nb );
FLUSH( 2 );
GETL( &ptr.i_ebyte );
/* Parsing of tts */
ptr.p_tts = malloc( ptr.i_ttu_nb *sizeof(tts_t) );
if( ptr.p_tts == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return ptr;
}
for( i=0 ; i<ptr.i_ttu_nb ; i++ )
{
GETC( &ptr.p_tts[i].i_play_type );
GETC( &ptr.p_tts[i].i_angle_nb );
GETS( &ptr.p_tts[i].i_ptt_nb );
GETS( &ptr.p_tts[i].i_parental_id );
GETC( &ptr.p_tts[i].i_tts_nb );
GETC( &ptr.p_tts[i].i_vts_ttn );
GETL( &ptr.p_tts[i].i_ssector );
}
return ptr;
}
/*****************************************************************************
* ReadParentalInf : Fills the Parental Management structure.
*****************************************************************************/
static vmg_ptl_mait_t ReadParentalInf( ifo_t* p_ifo )
{
vmg_ptl_mait_t par;
int i, j, k;
int i_start = p_ifo->i_pos;
fprintf( stderr, "PTL\n" );
GETS( &par.i_country_nb );
GETS( &par.i_vts_nb );
GETL( &par.i_ebyte );
par.p_ptl_desc = malloc( par.i_country_nb *sizeof(vmg_ptl_mai_desc_t) );
if( par.p_ptl_desc == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return par;
}
for( i=0 ; i<par.i_country_nb ; i++ )
{
GETS( &par.p_ptl_desc[i].i_country_code );
FLUSH( 2 );
GETS( &par.p_ptl_desc[i].i_ptl_mai_sbyte );
FLUSH( 2 );
}
par.p_ptl_mask = malloc( par.i_country_nb *sizeof(vmg_ptl_mask_t) );
if( par.p_ptl_mask == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return par;
}
for( i=0 ; i<par.i_country_nb ; i++ )
{
p_ifo->i_pos = lseek( p_ifo->i_fd, i_start +
par.p_ptl_desc[i].i_ptl_mai_sbyte, SEEK_SET );
for( j=1 ; j<=8 ; j++ )
{
par.p_ptl_mask[i].ppi_ptl_mask[j] =
malloc( par.i_vts_nb *sizeof(u16) );
if( par.p_ptl_mask[i].ppi_ptl_mask[j] == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return par;
}
for( k=0 ; k<par.i_vts_nb ; k++ )
{
GETS( &par.p_ptl_mask[i].ppi_ptl_mask[j][k] );
}
}
}
return par;
}
/*****************************************************************************
* ReadVTSAttr : Fills the structure about VTS attributes.
*****************************************************************************/
static vmg_vts_atrt_t ReadVTSAttr( ifo_t* p_ifo )
{
vmg_vts_atrt_t atrt;
int i, j;
int i_start = p_ifo->i_pos;
fprintf( stderr, "VTS ATTR\n" );
GETS( &atrt.i_vts_nb );
FLUSH( 2 );
GETL( &atrt.i_ebyte );
atrt.pi_vts_atrt_sbyte = malloc( atrt.i_vts_nb *sizeof(u32) );
if( atrt.pi_vts_atrt_sbyte == NULL )
{
intf_ErrMsg( "Out of memory" );
p_ifo->b_error = 1;
return atrt;
}