dvd_ifo.c 66.1 KB
Newer Older
Stéphane Borel's avatar
Stéphane Borel committed
1 2 3 4
/*****************************************************************************
 * dvd_ifo.c: Functions for ifo parsing
 *****************************************************************************
 * Copyright (C) 1999-2001 VideoLAN
5
 * $Id: dvd_ifo.c,v 1.37 2001/08/09 20:16:17 jlj Exp $
Stéphane Borel's avatar
Stéphane Borel committed
6
 *
Sam Hocevar's avatar
 
Sam Hocevar committed
7 8
 * Authors: Stphane Borel <stef@via.ecp.fr>
 *          German Tischler <tanis@gaspode.franken.de>
Stéphane Borel's avatar
Stéphane Borel committed
9
 *
10 11 12 13 14
 * based on:
 *  - libifo by Thomas Mirlacher <dent@cosy.sbg.ac.at>
 *  - IFO structure documentation by Thomas Mirlacher, Bjrn Englund,
 *  Hkan Hjort
 *
Stéphane Borel's avatar
Stéphane Borel committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
 * 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
 *****************************************************************************/
33 34 35
#include "defs.h"
#include "config.h"

Stéphane Borel's avatar
Stéphane Borel committed
36
#include <stdio.h>
37
#include <stdlib.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
38 39

#ifdef HAVE_UNISTD_H
Sam Hocevar's avatar
 
Sam Hocevar committed
40
#   include <unistd.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
41
#elif defined( _MSC_VER ) && defined( _WIN32 )
Sam Hocevar's avatar
 
Sam Hocevar committed
42
#   include <io.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
43 44
#endif

Stéphane Borel's avatar
Stéphane Borel committed
45 46 47
#include <string.h>
#include <fcntl.h>

Sam Hocevar's avatar
 
Sam Hocevar committed
48 49 50 51 52
#ifdef GOD_DAMN_DMCA
#   include "dummy_dvdcss.h"
#else
#   include <videolan/dvdcss.h>
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
53

Sam Hocevar's avatar
 
Sam Hocevar committed
54
#include "config.h"
Stéphane Borel's avatar
Stéphane Borel committed
55
#include "common.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
56 57
#include "threads.h"
#include "mtime.h"
Stéphane Borel's avatar
Stéphane Borel committed
58 59

#include "intf_msg.h"
Sam Hocevar's avatar
 
Sam Hocevar committed
60

Sam Hocevar's avatar
 
Sam Hocevar committed
61
#include "input_dvd.h"
Stéphane Borel's avatar
Stéphane Borel committed
62
#include "dvd_ifo.h"
63
#include "dvd_udf.h"
Stéphane Borel's avatar
Stéphane Borel committed
64

Sam Hocevar's avatar
 
Sam Hocevar committed
65 66 67
#include "modules.h"
#include "modules_export.h"

Sam Hocevar's avatar
 
Sam Hocevar committed
68
/*****************************************************************************
Stéphane Borel's avatar
 
Stéphane Borel committed
69
 * Local prototypes
Sam Hocevar's avatar
 
Sam Hocevar committed
70
 *****************************************************************************/
71
void            CommandRead     ( command_desc_t );
Sam Hocevar's avatar
 
Sam Hocevar committed
72
static int      ReadTitle       ( ifo_t * , title_t *, int, int );
73
static int      FreeTitle       ( title_t * );
Sam Hocevar's avatar
 
Sam Hocevar committed
74
static int      ReadUnitInf     ( ifo_t * , unit_inf_t *, int, int );
75
static int      FreeUnitInf     ( unit_inf_t * );
Sam Hocevar's avatar
 
Sam Hocevar committed
76
static int      ReadTitleUnit   ( ifo_t * , title_unit_t *, int );
77
static int      FreeTitleUnit   ( title_unit_t * );
Sam Hocevar's avatar
 
Sam Hocevar committed
78
static int      ReadVobuMap     ( ifo_t * , vobu_map_t *, int );
79
static int      FreeVobuMap     ( vobu_map_t * );
Sam Hocevar's avatar
 
Sam Hocevar committed
80
static int      ReadCellInf     ( ifo_t * , cell_inf_t *, int );
81 82
static int      FreeCellInf     ( cell_inf_t * );
static int      FreeTitleSet    ( vts_t * );
Stéphane Borel's avatar
Stéphane Borel committed
83

Sam Hocevar's avatar
 
Sam Hocevar committed
84 85 86 87 88 89 90
static u8*      FillBuffer      ( ifo_t *, u8 *, int );
static u8       ReadByte        ( ifo_t *, u8 *, u8 ** );
static void     ReadBytes       ( ifo_t *, u8 *, u8 **, u8 *, int );
static void     DumpBytes       ( ifo_t *, u8 *, u8 **, int );
static u16      ReadWord        ( ifo_t *, u8 *, u8 ** );
static u32      ReadDouble      ( ifo_t *, u8 *, u8 ** );
static u64      ReadQuad        ( ifo_t *, u8 *, u8 ** );
91

Stéphane Borel's avatar
Stéphane Borel committed
92
/*
93
 * IFO Management.
Stéphane Borel's avatar
Stéphane Borel committed
94
 */
Sam Hocevar's avatar
 
Sam Hocevar committed
95

Stéphane Borel's avatar
Stéphane Borel committed
96
/*****************************************************************************
97 98
 * IfoCreate : Creates an ifo structure and prepares for parsing directly
 *             on DVD device
Stéphane Borel's avatar
Stéphane Borel committed
99
 *****************************************************************************/
100
int IfoCreate( thread_dvd_data_t * p_dvd )
101
{
102 103
    p_dvd->p_ifo = malloc( sizeof(ifo_t) );
    if( p_dvd->p_ifo == NULL )
104 105 106
    {
        intf_ErrMsg( "ifo error: unable to allocate memory. aborting" );
        return -1;
107 108
    }

109
    /* if we are here the dvd device has already been opened */
Sam Hocevar's avatar
 
Sam Hocevar committed
110
    p_dvd->p_ifo->dvdhandle = p_dvd->dvdhandle;
111 112 113 114 115 116 117 118 119

    return 0;
}

/*****************************************************************************
 * IfoInit : Reads information from the management table.
 *****************************************************************************/
int IfoInit( ifo_t * p_ifo )
{
Sam Hocevar's avatar
 
Sam Hocevar committed
120 121
    u8                  p_buf[DVD_LB_SIZE];
    u8*                 p_tmp;
122 123
    u64                 i_temp;
    int                 i, j, k;
Sam Hocevar's avatar
 
Sam Hocevar committed
124
    int                 i_start;
Stéphane Borel's avatar
Stéphane Borel committed
125

126
    /* find the start sector of video information on the dvd */
Sam Hocevar's avatar
 
Sam Hocevar committed
127
    p_ifo->i_start = UDFFindFile( p_ifo->dvdhandle, "/VIDEO_TS/VIDEO_TS.IFO" );
gbazin's avatar
 
gbazin committed
128
    if( !p_ifo->i_start ) return -1;
129

Sam Hocevar's avatar
 
Sam Hocevar committed
130 131
    p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start );
    //i_start = p_ifo->i_pos;
132 133 134 135

    /*
     * read the video manager information table
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
#define MGINF     p_ifo->vmg.manager_inf
    //fprintf( stderr, "VMGI\n" );

    ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.psz_id, 12 );
    MGINF.psz_id[12] = '\0';
    MGINF.i_vmg_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 12 );
    MGINF.i_vmg_inf_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
    MGINF.i_spec_ver = ReadByte( p_ifo, p_buf, &p_tmp );
    MGINF.i_cat = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_volume_nb = ReadWord( p_ifo, p_buf, &p_tmp );
    MGINF.i_volume = ReadWord( p_ifo, p_buf, &p_tmp );
    MGINF.i_disc_side = ReadByte( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 19 );
    MGINF.i_title_set_nb = ReadWord( p_ifo, p_buf, &p_tmp );
    ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.ps_provider_id, 32 );
    MGINF.i_pos_code = ReadQuad( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 24 );
    MGINF.i_vmg_inf_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_first_play_title_start_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 56 );
    MGINF.i_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_title_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_title_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_parental_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_vts_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_text_data_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 32 );
    DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
    MGINF.i_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );
    //fprintf( stderr, "vmgi audio nb : %d\n", MGINF.i_audio_nb );

    for( i = 0 ; i < 8 ; i++ )
    {
        i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
    }

    DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
    MGINF.i_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );
    //fprintf( stderr, "vmgi subpic nb : %d\n", MGINF.i_spu_nb );

    for( i = 0 ; i < MGINF.i_spu_nb ; i++ )
    {
        ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
184 185 186 187 188 189
        /* FIXME : take care of endianness */
    }

    /*
     * read first play title.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
190 191 192 193
    //fprintf(stderr,"readtitle %i\n", MGINF.i_first_play_title_start_byte & 0x7ff );
    if( ReadTitle( p_ifo, &p_ifo->vmg.title, p_ifo->i_start
                           + OFF2LB( MGINF.i_first_play_title_start_byte ),
                   MGINF.i_first_play_title_start_byte & 0x7ff ) < 0 )
Stéphane Borel's avatar
Stéphane Borel committed
194
    {
195
        return -1;
Stéphane Borel's avatar
Stéphane Borel committed
196 197
    }

198 199 200
    /*
     * fills the title information structure.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
201 202
#define TITINF       p_ifo->vmg.title_inf
    if( MGINF.i_title_inf_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
203
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
204 205 206
        p_tmp = FillBuffer( p_ifo, p_buf,
                        p_ifo->i_start + MGINF.i_title_inf_start_sector );
        //fprintf( stderr, "title inf %d\n", p_ifo->i_pos );
207
    
Sam Hocevar's avatar
 
Sam Hocevar committed
208 209 210 211
        TITINF.i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp );
        //fprintf( stderr, "title_inf: TTU nb %d\n", TITINF.i_title_nb );
        DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
        TITINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
212 213
    
        /* parsing of title attributes */
Sam Hocevar's avatar
 
Sam Hocevar committed
214 215
        TITINF.p_attr = malloc( TITINF.i_title_nb *sizeof(title_attr_t) );
        if( TITINF.p_attr == NULL )
Stéphane Borel's avatar
Stéphane Borel committed
216
        {
217 218
            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
            return -1;
Stéphane Borel's avatar
Stéphane Borel committed
219
        }
220
    
Sam Hocevar's avatar
 
Sam Hocevar committed
221
        for( i = 0 ; i < TITINF.i_title_nb ; i++ )
Stéphane Borel's avatar
Stéphane Borel committed
222
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
223 224 225 226 227 228 229 230
            TITINF.p_attr[i].i_play_type = ReadByte( p_ifo, p_buf, &p_tmp );
            TITINF.p_attr[i].i_angle_nb = ReadByte( p_ifo, p_buf, &p_tmp );
            TITINF.p_attr[i].i_chapter_nb = ReadWord( p_ifo, p_buf, &p_tmp );
            TITINF.p_attr[i].i_parental_id = ReadWord( p_ifo, p_buf, &p_tmp );
            TITINF.p_attr[i].i_title_set_num = ReadByte( p_ifo, p_buf, &p_tmp );
            TITINF.p_attr[i].i_title_num = ReadByte( p_ifo, p_buf, &p_tmp );
            TITINF.p_attr[i].i_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
            //fprintf( stderr, "title_inf: %d %d %d\n", TITINF.p_attr[i].i_chapter_nb, TITINF.p_attr[i].i_title_set_num, TITINF.p_attr[i].i_title_num );
Stéphane Borel's avatar
Stéphane Borel committed
231 232
        }
    }
233
    else
Stéphane Borel's avatar
Stéphane Borel committed
234
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
235
        TITINF.p_attr = NULL;
Stéphane Borel's avatar
Stéphane Borel committed
236
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
237
#undef TITINF
238 239 240 241

    /*
     * fills the title unit structure.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
242
    if( MGINF.i_title_unit_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
243
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
244 245
        if( ReadTitleUnit( p_ifo, &p_ifo->vmg.title_unit, p_ifo->i_start
                            + MGINF.i_title_unit_start_sector ) < 0 )
Stéphane Borel's avatar
Stéphane Borel committed
246
        {
247
            return -1;
Stéphane Borel's avatar
Stéphane Borel committed
248 249
        }
    }
250 251 252 253

    /*
     * fills the structure about parental information.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
254 255
#define PARINF        p_ifo->vmg.parental_inf
    if( MGINF.i_parental_inf_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
256
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
257 258
        p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start +
                                MGINF.i_parental_inf_start_sector );
259 260
        i_start = p_ifo->i_pos;

Sam Hocevar's avatar
 
Sam Hocevar committed
261
        //fprintf( stderr, "PTL\n" );
262
    
Sam Hocevar's avatar
 
Sam Hocevar committed
263 264 265
        PARINF.i_country_nb = ReadWord( p_ifo, p_buf, &p_tmp );
        PARINF.i_vts_nb = ReadWord( p_ifo, p_buf, &p_tmp );
        PARINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
266
        
Sam Hocevar's avatar
 
Sam Hocevar committed
267 268 269
        PARINF.p_parental_desc = malloc( PARINF.i_country_nb
                                          * sizeof(parental_desc_t) );
        if( PARINF.p_parental_desc == NULL )
Stéphane Borel's avatar
Stéphane Borel committed
270
        {
271 272
            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
            return -1;
Stéphane Borel's avatar
Stéphane Borel committed
273
        }
274

Sam Hocevar's avatar
 
Sam Hocevar committed
275
        for( i = 0 ; i < PARINF.i_country_nb ; i++ )
Stéphane Borel's avatar
Stéphane Borel committed
276
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
277 278 279 280 281 282
            ReadBytes( p_ifo, p_buf, &p_tmp,
                       PARINF.p_parental_desc[i].ps_country_code, 2 );
            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
            PARINF.p_parental_desc[i].i_parental_mask_start_byte =
                                            ReadWord( p_ifo, p_buf, &p_tmp );
            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
Stéphane Borel's avatar
Stéphane Borel committed
283
        }
284

Sam Hocevar's avatar
 
Sam Hocevar committed
285 286 287
        PARINF.p_parental_mask = malloc( PARINF.i_country_nb
                                          * sizeof(parental_mask_t) );
        if( PARINF.p_parental_mask == NULL )
288
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
289
            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
290 291
            return -1;
        }
292

Sam Hocevar's avatar
 
Sam Hocevar committed
293
        for( i = 0 ; i < PARINF.i_country_nb ; i++ )
294
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
295 296 297
            p_tmp = FillBuffer( p_ifo, p_buf, i_start + OFF2LB(
                      PARINF.p_parental_desc[i].i_parental_mask_start_byte ) )
              + (PARINF.p_parental_desc[i].i_parental_mask_start_byte & 0x7ff);
Sam Hocevar's avatar
 
Sam Hocevar committed
298

299 300
            for( j = 0 ; j < 8 ; j++ )
            {
Sam Hocevar's avatar
 
Sam Hocevar committed
301 302 303 304
                PARINF.p_parental_mask[i].ppi_mask[j] =
                            malloc( ( PARINF.i_vts_nb + 1 ) * sizeof(u16) );

                if( PARINF.p_parental_mask[i].ppi_mask[j] == NULL )
305 306 307
                {
                    intf_ErrMsg( "ifo error: out of memory in IfoInit" );
                    return -1;
Sam Hocevar's avatar
 
Sam Hocevar committed
308 309 310
                }

                for( k = 0 ; k < PARINF.i_vts_nb + 1 ; k++ )
311
                {
Sam Hocevar's avatar
 
Sam Hocevar committed
312 313
                    PARINF.p_parental_mask[i].ppi_mask[j][k] =
                                            ReadWord( p_ifo, p_buf, &p_tmp );
314 315 316
                }
            }
        }
317
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
318
#undef PARINF
319 320 321 322

    /*
     * information and attributes about for each vts.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
323 324
#define VTSINF     p_ifo->vmg.vts_inf
    if( MGINF.i_vts_inf_start_sector )
325
    {
326
        u64             i_temp;
327

Sam Hocevar's avatar
 
Sam Hocevar committed
328 329
        p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->i_start +
                                MGINF.i_vts_inf_start_sector );
330 331
        i_start = p_ifo->i_pos;
    
Sam Hocevar's avatar
 
Sam Hocevar committed
332
        //fprintf( stderr, "VTS ATTR\n" );
333
    
Sam Hocevar's avatar
 
Sam Hocevar committed
334 335 336 337 338 339 340
        VTSINF.i_vts_nb = ReadWord( p_ifo, p_buf, &p_tmp );;
        //fprintf( stderr, "VTS ATTR Nb: %d\n", VTSINF.i_vts_nb );
        DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
        VTSINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
        VTSINF.pi_vts_attr_start_byte =
                            malloc( VTSINF.i_vts_nb * sizeof(u32) );
        if( VTSINF.pi_vts_attr_start_byte == NULL )
341 342 343 344
        {
            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
            return -1;
        }
345

Sam Hocevar's avatar
 
Sam Hocevar committed
346
        for( i = 0 ; i < VTSINF.i_vts_nb ; i++ )
347
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
348 349
            VTSINF.pi_vts_attr_start_byte[i] =
                                      ReadDouble( p_ifo, p_buf, &p_tmp );
350
        }
Stéphane Borel's avatar
Stéphane Borel committed
351

Sam Hocevar's avatar
 
Sam Hocevar committed
352 353
        VTSINF.p_vts_attr = malloc( VTSINF.i_vts_nb * sizeof(vts_attr_t) );
        if( VTSINF.p_vts_attr == NULL )
354
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
355
            intf_ErrMsg( "ifo error: out of memory in IfoInit" );
356 357
            return -1;
        }
Stéphane Borel's avatar
Stéphane Borel committed
358

Sam Hocevar's avatar
 
Sam Hocevar committed
359
        for( i = 0 ; i < VTSINF.i_vts_nb ; i++ )
360
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
361 362 363 364 365 366 367 368 369 370 371 372 373 374
            p_tmp = FillBuffer( p_ifo, p_buf, i_start +
                                OFF2LB( VTSINF.pi_vts_attr_start_byte[i] ) )
                     + ( VTSINF.pi_vts_attr_start_byte[i] & 0x7ff );

            VTSINF.p_vts_attr[i].i_end_byte =
                                ReadDouble( p_ifo, p_buf, &p_tmp );
            VTSINF.p_vts_attr[i].i_cat_app_type =
                                ReadDouble( p_ifo, p_buf, &p_tmp );
            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
            DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
            VTSINF.p_vts_attr[i].i_vts_menu_audio_nb =
                                ReadByte( p_ifo, p_buf, &p_tmp );
            //fprintf( stderr, "m audio nb : %d\n", VTSINF.p_vts_attr[i].i_vts_menu_audio_nb );

375 376
            for( j = 0 ; j < 8 ; j++ )
            {
Sam Hocevar's avatar
 
Sam Hocevar committed
377
                i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
378
            }
Sam Hocevar's avatar
 
Sam Hocevar committed
379 380 381 382 383 384

            DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
            VTSINF.p_vts_attr[i].i_vts_menu_spu_nb =
                                ReadByte( p_ifo, p_buf, &p_tmp );
            //fprintf( stderr, "m subp nb : %d\n", VTSINF.p_vts_attr[i].i_vts_menu_spu_nb );

385 386 387
            for( j = 0 ; j < 28 ; j++ )
            {
                /* FIXME : Fix endianness issue here */
Sam Hocevar's avatar
 
Sam Hocevar committed
388
                ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
389
            }
Sam Hocevar's avatar
 
Sam Hocevar committed
390 391 392 393 394 395 396 397

            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
            DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
            DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
            VTSINF.p_vts_attr[i].i_vts_title_audio_nb =
                                ReadDouble( p_ifo, p_buf, &p_tmp );
            //fprintf( stderr, "tt audio nb : %d\n", VTSINF.p_vts_attr[i].i_vts_title_audio_nb );

398 399
            for( j = 0 ; j < 8 ; j++ )
            {
Sam Hocevar's avatar
 
Sam Hocevar committed
400
                i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );;
401
            }
Sam Hocevar's avatar
 
Sam Hocevar committed
402 403 404 405 406 407 408

            DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
            VTSINF.p_vts_attr[i].i_vts_title_spu_nb =
                                ReadByte( p_ifo, p_buf, &p_tmp );
            //fprintf( stderr, "tt subp nb : %d\n", VTSINF.p_vts_attr[i].i_vts_title_spu_nb );

            for( j = 0 ; j < 28 /*VTSINF.p_vts_vts_inf[i].i_vtstt_subpic_nb*/ ; j++ )
409 410
            {
                /* FIXME : Fix endianness issue here */
Sam Hocevar's avatar
 
Sam Hocevar committed
411
                ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
412 413
            }
        }
Stéphane Borel's avatar
Stéphane Borel committed
414
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
415
#undef VTSINF
416 417 418 419

    /*
     * global cell map.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
420
    if( MGINF.i_cell_inf_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
421
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
422 423
        if( ReadCellInf( p_ifo, &p_ifo->vmg.cell_inf, p_ifo->i_start +
                         MGINF.i_cell_inf_start_sector ) < 0 )
424 425 426
        {
            return -1;
        }
Stéphane Borel's avatar
Stéphane Borel committed
427
    }
428 429 430 431

    /*
     * global vob unit map.
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
432
    if( MGINF.i_vobu_map_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
433
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
434 435
        if( ReadVobuMap( p_ifo, &p_ifo->vmg.vobu_map, p_ifo->i_start +
                         MGINF.i_vobu_map_start_sector ) < 0 )
436 437 438
        {
            return -1;
        }
Stéphane Borel's avatar
Stéphane Borel committed
439
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
440
#undef MGINF
Stéphane Borel's avatar
Stéphane Borel committed
441

442
    p_ifo->vts.b_initialized = 0;
Stéphane Borel's avatar
Stéphane Borel committed
443

444
    intf_WarnMsg( 2, "ifo info: vmg initialized" );
Stéphane Borel's avatar
Stéphane Borel committed
445

446
    return 0;
Stéphane Borel's avatar
Stéphane Borel committed
447 448 449
}

/*****************************************************************************
450
 * IfoTitleSet: Parse vts*.ifo files to fill the Video Title Set structure.
Stéphane Borel's avatar
Stéphane Borel committed
451
 *****************************************************************************/
452
int IfoTitleSet( ifo_t * p_ifo )
Stéphane Borel's avatar
Stéphane Borel committed
453
{
Sam Hocevar's avatar
 
Sam Hocevar committed
454 455 456 457
    u8          p_buf[DVD_LB_SIZE];
    u8 *        p_tmp;
    int         i_off;
    int         i_start;
458
    u64         i_temp;
459
    u16         i_short;
460
    int         i, j;
Stéphane Borel's avatar
Stéphane Borel committed
461

462
    if( p_ifo->vts.b_initialized )
Stéphane Borel's avatar
Stéphane Borel committed
463
    {
464
        FreeTitleSet( &p_ifo->vts );
Stéphane Borel's avatar
Stéphane Borel committed
465 466
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
467 468
    i_off = p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_start_sector
                   + p_ifo->i_start;
Stéphane Borel's avatar
Stéphane Borel committed
469

Sam Hocevar's avatar
 
Sam Hocevar committed
470
    //fprintf(stderr, "offset: %d\n" , i_off );
Stéphane Borel's avatar
Stéphane Borel committed
471

Sam Hocevar's avatar
 
Sam Hocevar committed
472
    p_tmp = FillBuffer( p_ifo, p_buf, i_off );
Sam Hocevar's avatar
 
Sam Hocevar committed
473
    //i_start = p_ifo->i_pos;
474 475
    p_ifo->vts.i_pos = p_ifo->i_pos;

Sam Hocevar's avatar
 
Sam Hocevar committed
476
#define MGINF p_ifo->vts.manager_inf
Sam Hocevar's avatar
 
Sam Hocevar committed
477

478
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
479
     * read manager information
480
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
481
    //fprintf( stderr, "VTSI\n" );
Stéphane Borel's avatar
Stéphane Borel committed
482

Sam Hocevar's avatar
 
Sam Hocevar committed
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
    ReadBytes( p_ifo, p_buf, &p_tmp, MGINF.psz_id , 12 );
    MGINF.psz_id[12] = '\0';
    MGINF.i_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 12 );
    MGINF.i_inf_end_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
    MGINF.i_spec_ver = ReadByte( p_ifo, p_buf, &p_tmp );
    MGINF.i_cat = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 90 );
    MGINF.i_inf_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 60 );
    MGINF.i_menu_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_title_vob_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_title_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_title_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_menu_unit_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_time_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_menu_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_menu_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_cell_inf_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    MGINF.i_vobu_map_start_sector = ReadDouble( p_ifo, p_buf, &p_tmp );
    DumpBytes( p_ifo, p_buf, &p_tmp, 24 );
    DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
    MGINF.i_menu_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );

509
    for( i = 0 ; i < 8 ; i++ )
Stéphane Borel's avatar
Stéphane Borel committed
510
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
511
        i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
Stéphane Borel's avatar
Stéphane Borel committed
512
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
513 514 515 516

    DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
    MGINF.i_menu_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );

517
    for( i = 0 ; i < 28 ; i++ )
Stéphane Borel's avatar
Stéphane Borel committed
518 519
    {
        /* FIXME : take care of endianness */
Sam Hocevar's avatar
 
Sam Hocevar committed
520
        ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
Stéphane Borel's avatar
Stéphane Borel committed
521
    }
522

Sam Hocevar's avatar
 
Sam Hocevar committed
523 524 525
    DumpBytes( p_ifo, p_buf, &p_tmp, 2 );

    i_short = ReadWord( p_ifo, p_buf, &p_tmp );
526
    i_short >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
527
    MGINF.video_attr.i_mode = i_short & 0x1;
528
    i_short >>= 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
529
    MGINF.video_attr.i_letterboxed = i_short & 0x1;
530
    i_short >>= 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
531
    MGINF.video_attr.i_source_res = i_short & 0x3;
532
    i_short >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
533
    MGINF.video_attr.i_line21_2 = i_short & 0x1;
534
    i_short >>= 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
535
    MGINF.video_attr.i_line21_1 = i_short & 0x1;
536
    i_short >>= 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
537
    MGINF.video_attr.i_perm_displ = i_short & 0x3;
538
    i_short >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
539
    MGINF.video_attr.i_ratio = i_short & 0x3;
540
    i_short >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
541
    MGINF.video_attr.i_system = i_short & 0x3;
542
    i_short >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
543 544 545 546 547
    MGINF.video_attr.i_compression = i_short & 0x3;

    DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
    MGINF.i_audio_nb = ReadByte( p_ifo, p_buf, &p_tmp );
    //fprintf( stderr, "vtsi audio nb : %d\n", MGINF.i_audio_nb );
548

549
    for( i = 0 ; i < 8 ; i++ )
Stéphane Borel's avatar
Stéphane Borel committed
550
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
551 552
        i_temp = ReadQuad( p_ifo, p_buf, &p_tmp );
        //fprintf( stderr, "Audio %d: %llx\n", i, i_temp );
Stéphane Borel's avatar
Stéphane Borel committed
553
        i_temp >>= 8;
Sam Hocevar's avatar
 
Sam Hocevar committed
554
        MGINF.p_audio_attr[i].i_bar = i_temp & 0xff;
Stéphane Borel's avatar
Stéphane Borel committed
555
        i_temp >>= 8;
Sam Hocevar's avatar
 
Sam Hocevar committed
556
        MGINF.p_audio_attr[i].i_caption = i_temp & 0xff;
Stéphane Borel's avatar
Stéphane Borel committed
557
        i_temp >>= 8;
Sam Hocevar's avatar
 
Sam Hocevar committed
558
        MGINF.p_audio_attr[i].i_foo = i_temp & 0xff;
Stéphane Borel's avatar
Stéphane Borel committed
559
        i_temp >>= 8;
Sam Hocevar's avatar
 
Sam Hocevar committed
560
        MGINF.p_audio_attr[i].i_lang_code = i_temp & 0xffff;
561
        i_temp >>= 16;
Sam Hocevar's avatar
 
Sam Hocevar committed
562
        MGINF.p_audio_attr[i].i_num_channels = i_temp & 0x7;
Stéphane Borel's avatar
Stéphane Borel committed
563
        i_temp >>= 3;
Sam Hocevar's avatar
 
Sam Hocevar committed
564
        MGINF.p_audio_attr[i].i_test = i_temp & 0x1;
Stéphane Borel's avatar
Stéphane Borel committed
565
        i_temp >>= 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
566
        MGINF.p_audio_attr[i].i_sample_freq = i_temp & 0x3;
567
        i_temp >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
568
        MGINF.p_audio_attr[i].i_quantization = i_temp & 0x3;
569
        i_temp >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
570
        MGINF.p_audio_attr[i].i_appl_mode = i_temp & 0x3;
571
        i_temp >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
572
        MGINF.p_audio_attr[i].i_type = i_temp & 0x3;
573
        i_temp >>= 2;
Sam Hocevar's avatar
 
Sam Hocevar committed
574
        MGINF.p_audio_attr[i].i_multichannel_extension = i_temp & 0x1;
575
        i_temp >>= 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
576
        MGINF.p_audio_attr[i].i_coding_mode = i_temp & 0x7;
577
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
578 579 580 581 582 583

    DumpBytes( p_ifo, p_buf, &p_tmp, 17 );
    MGINF.i_spu_nb = ReadByte( p_ifo, p_buf, &p_tmp );
    //fprintf( stderr, "vtsi subpic nb : %d\n", MGINF.i_spu_nb );

    for( i=0 ; i<MGINF.i_spu_nb ; i++ )
Stéphane Borel's avatar
Stéphane Borel committed
584
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
585
        ReadBytes( p_ifo, p_buf, &p_tmp, (u8*)(&i_temp), 6 );
586
        i_temp = hton64( i_temp ) >> 16;
Sam Hocevar's avatar
 
Sam Hocevar committed
587 588
        //fprintf( stderr, "Subpic %d: %llx\n", i, i_temp );
        MGINF.p_spu_attr[i].i_caption = i_temp & 0xff;
589
        i_temp >>= 8;
Sam Hocevar's avatar
 
Sam Hocevar committed
590
        MGINF.p_spu_attr[i].i_foo = i_temp & 0xff;
591
        i_temp >>= 8;
Sam Hocevar's avatar
 
Sam Hocevar committed
592
        MGINF.p_spu_attr[i].i_lang_code = i_temp & 0xffff;
593
        i_temp >>= 16;
Sam Hocevar's avatar
 
Sam Hocevar committed
594
        MGINF.p_spu_attr[i].i_prefix = i_temp & 0xffff;
Stéphane Borel's avatar
Stéphane Borel committed
595
    }
596 597

    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
598
     * read title information: set of pointers to title
599
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
600 601
#define TITINF p_ifo->vts.title_inf
    if( MGINF.i_title_inf_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
602
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
603
        p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->vts.i_pos +
Sam Hocevar's avatar
 
Sam Hocevar committed
604
                                          MGINF.i_title_inf_start_sector );
605 606 607

        i_start = p_ifo->i_pos;
    
Sam Hocevar's avatar
 
Sam Hocevar committed
608
        //fprintf( stderr, "VTS PTR\n" );
609
   
Sam Hocevar's avatar
 
Sam Hocevar committed
610 611 612 613
        TITINF.i_title_nb = ReadWord( p_ifo, p_buf, &p_tmp );
        //fprintf( stderr, "VTS title_inf nb: %d\n", TITINF.i_title_nb );
        DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
        TITINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
614

Sam Hocevar's avatar
 
Sam Hocevar committed
615 616
        TITINF.pi_start_byte = malloc( TITINF.i_title_nb * sizeof(u32) );
        if( TITINF.pi_start_byte == NULL )
617 618 619 620 621
        {
            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
            return -1;
        }

Sam Hocevar's avatar
 
Sam Hocevar committed
622
        for( i = 0 ; i < TITINF.i_title_nb ; i++ )
623
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
624
            TITINF.pi_start_byte[i] = ReadDouble( p_ifo, p_buf, &p_tmp );
625 626 627
        }

        /* Parsing of tts */
Sam Hocevar's avatar
 
Sam Hocevar committed
628 629 630
        TITINF.p_title_start = malloc( TITINF.i_title_nb
                                         * sizeof(title_start_t) );
        if( TITINF.p_title_start == NULL )
631 632 633 634 635
        {
            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
            return -1;
        }

Sam Hocevar's avatar
 
Sam Hocevar committed
636
        for( i = 0 ; i < TITINF.i_title_nb ; i++ )
637
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
638 639
            p_tmp = FillBuffer( p_ifo, p_buf, i_start +
                                OFF2LB( TITINF.pi_start_byte[i] ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
640
                     + (TITINF.pi_start_byte[i] & 0x7ff);
641

Sam Hocevar's avatar
 
Sam Hocevar committed
642 643 644 645
            TITINF.p_title_start[i].i_title_id =
                                   ReadWord( p_ifo, p_buf, &p_tmp );
            TITINF.p_title_start[i].i_chapter =
                                   ReadWord( p_ifo, p_buf, &p_tmp );
646
        }
Stéphane Borel's avatar
Stéphane Borel committed
647
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
648
#undef TITINF
649 650 651 652

    /*
     * menu unit information
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
653
    if( MGINF.i_menu_unit_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
654
    {
655
        if( ReadTitleUnit( p_ifo, &p_ifo->vts.menu_unit, p_ifo->vts.i_pos +
Sam Hocevar's avatar
 
Sam Hocevar committed
656
                     MGINF.i_menu_unit_start_sector ) < 0 )
657 658 659
        {
            return -1;
        }
Stéphane Borel's avatar
Stéphane Borel committed
660
    }
661 662 663 664

    /*
     * title unit information
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
665
    if( MGINF.i_title_unit_start_sector )
Stéphane Borel's avatar
Stéphane Borel committed
666
    {
667
        if( ReadUnitInf( p_ifo, &p_ifo->vts.title_unit, p_ifo->vts.i_pos +
Sam Hocevar's avatar
 
Sam Hocevar committed
668
                         MGINF.i_title_unit_start_sector, 0  ) < 0 )
669 670 671 672 673 674
        {
            return -1;
        }
    }

    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
675
     * time map information
676
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
677 678
#define TIMINF p_ifo->vts.time_inf
    if( MGINF.i_time_inf_start_sector )
679
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
680
        u8      p_buf[DVD_LB_SIZE];
681

Sam Hocevar's avatar
 
Sam Hocevar committed
682
        p_tmp = FillBuffer( p_ifo, p_buf, p_ifo->vts.i_pos +
Sam Hocevar's avatar
 
Sam Hocevar committed
683
                                          MGINF.i_time_inf_start_sector );
684

Sam Hocevar's avatar
 
Sam Hocevar committed
685
        //fprintf( stderr, "TMAP\n" );
686

Sam Hocevar's avatar
 
Sam Hocevar committed
687 688 689
        TIMINF.i_nb = ReadWord( p_ifo, p_buf, &p_tmp );;
        DumpBytes( p_ifo, p_buf, &p_tmp, 2 );
        TIMINF.i_end_byte = ReadDouble( p_ifo, p_buf, &p_tmp );
690

Sam Hocevar's avatar
 
Sam Hocevar committed
691 692
        TIMINF.pi_start_byte = malloc( TIMINF.i_nb * sizeof(u32) );
        if( TIMINF.pi_start_byte == NULL )
Stéphane Borel's avatar
Stéphane Borel committed
693
        {
694 695 696 697
            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
            return -1;
        }

Sam Hocevar's avatar
 
Sam Hocevar committed
698
        for( i = 0 ; i < TIMINF.i_nb ; i++ )
699
        {    
Sam Hocevar's avatar
 
Sam Hocevar committed
700
            TIMINF.pi_start_byte[i] = ReadDouble( p_ifo, p_buf, &p_tmp );
701 702
        }

Sam Hocevar's avatar
 
Sam Hocevar committed
703 704
        TIMINF.p_time_map = malloc( TIMINF.i_nb * sizeof(time_map_t) );
        if( TIMINF.p_time_map == NULL )
705 706 707 708 709
        {
            intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
            return -1;
        }

Sam Hocevar's avatar
 
Sam Hocevar committed
710
        for( i = 0 ; i < TIMINF.i_nb ; i++ )
711
        {    
Sam Hocevar's avatar
 
Sam Hocevar committed
712 713 714
            TIMINF.p_time_map[i].i_time_unit = ReadByte( p_ifo, p_buf, &p_tmp );
            DumpBytes( p_ifo, p_buf, &p_tmp, 1 );
            TIMINF.p_time_map[i].i_entry_nb = ReadWord( p_ifo, p_buf, &p_tmp );
715

Sam Hocevar's avatar
 
Sam Hocevar committed
716 717 718
            TIMINF.p_time_map[i].pi_sector =
                     malloc( TIMINF.p_time_map[i].i_entry_nb * sizeof(u32) );
            if( TIMINF.p_time_map[i].pi_sector == NULL )
Stéphane Borel's avatar
Stéphane Borel committed
719
            {
720 721 722 723
                intf_ErrMsg( "ifo error: out of memory in IfoTitleSet" );
                return -1;
            }

Sam Hocevar's avatar
 
Sam Hocevar committed
724
            for( j = 0 ; j < TIMINF.p_time_map[i].i_entry_nb ; j++ )
Stéphane Borel's avatar
Stéphane Borel committed
725
            {
Sam Hocevar's avatar
 
Sam Hocevar committed
726 727
                TIMINF.p_time_map[i].pi_sector[j] =
                                        ReadDouble( p_ifo, p_buf, &p_tmp );
Stéphane Borel's avatar
Stéphane Borel committed
728 729 730
            }
        }
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
731
#undef TIMINF
732

Sam Hocevar's avatar
 
Sam Hocevar committed
733 734 735
    if( MGINF.i_menu_cell_inf_start_sector
         && ReadCellInf( p_ifo, &p_ifo->vts.menu_cell_inf, p_ifo->vts.i_pos +
                         MGINF.i_menu_cell_inf_start_sector ) < 0 )
736
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
737
        return -1;
738 739
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
740 741 742
    if( MGINF.i_menu_vobu_map_start_sector
         && ReadVobuMap( p_ifo, &p_ifo->vts.menu_vobu_map, p_ifo->vts.i_pos +
                         MGINF.i_menu_vobu_map_start_sector ) < 0 )
743
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
744
        return -1;
745 746
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
747 748 749
    if( MGINF.i_cell_inf_start_sector
         && ReadCellInf( p_ifo, &p_ifo->vts.cell_inf, p_ifo->vts.i_pos +
                         MGINF.i_cell_inf_start_sector ) )
750
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
751
        return -1;
752 753
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
754 755 756
    if( MGINF.i_vobu_map_start_sector
         && ReadVobuMap( p_ifo, &p_ifo->vts.vobu_map, p_ifo->vts.i_pos +
                         MGINF.i_vobu_map_start_sector ) )
757
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
758
        return -1;
759
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
760
#undef MGINF
761

762
    intf_WarnMsg( 2, "ifo info: vts %d initialized",
763 764 765 766 767
         p_ifo->vmg.title_inf.p_attr[p_ifo->i_title-1].i_title_set_num );

    p_ifo->vts.b_initialized = 1;

    return 0;
Stéphane Borel's avatar
Stéphane Borel committed
768 769 770
}

/*****************************************************************************
771
 * FreeTitleSet : free all structures allocated by IfoTitleSet
Stéphane Borel's avatar
Stéphane Borel committed
772
 *****************************************************************************/
773
static int FreeTitleSet( vts_t * p_vts )
Stéphane Borel's avatar
Stéphane Borel committed
774
{
775
    int     i;