Remove useless <sys/stat.h> includes
[vlc.git] / modules / access / dvdread.c
1 /*****************************************************************************
2  * dvdread.c : DvdRead input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2001-2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: St├ęphane Borel <stef@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_input.h>
36 #include <vlc_access.h>
37 #include <vlc_charset.h>
38 #include <vlc_interface.h>
39 #include <vlc_dialog.h>
40
41 #include <vlc_iso_lang.h>
42
43 #include "../demux/ps.h"
44
45 #ifdef HAVE_UNISTD_H
46 #   include <unistd.h>
47 #endif
48
49 #include <fcntl.h>
50 #include <sys/types.h>
51
52 #ifdef HAVE_DVDREAD_DVD_READER_H
53   #include <dvdread/dvd_reader.h>
54   #include <dvdread/ifo_types.h>
55   #include <dvdread/ifo_read.h>
56   #include <dvdread/nav_read.h>
57   #include <dvdread/nav_print.h>
58 #else
59   #include <libdvdread/dvd_reader.h>
60   #include <libdvdread/ifo_types.h>
61   #include <libdvdread/ifo_read.h>
62   #include <libdvdread/nav_read.h>
63   #include <libdvdread/nav_print.h>
64 #endif
65
66 #include <assert.h>
67
68 /*****************************************************************************
69  * Module descriptor
70  *****************************************************************************/
71 #define ANGLE_TEXT N_("DVD angle")
72 #define ANGLE_LONGTEXT N_( \
73     "Default DVD angle." )
74
75 #define CACHING_TEXT N_("Caching value in ms")
76 #define CACHING_LONGTEXT N_( \
77     "Caching value for DVDs. " \
78     "This value should be set in milliseconds." )
79
80 #define CSSMETHOD_TEXT N_("Method used by libdvdcss for decryption")
81 #define CSSMETHOD_LONGTEXT N_( \
82     "Set the method used by libdvdcss for key decryption.\n" \
83     "title: decrypted title key is guessed from the encrypted sectors of " \
84            "the stream. Thus it should work with a file as well as the " \
85            "DVD device. But it sometimes takes much time to decrypt a title " \
86            "key and may even fail. With this method, the key is only checked "\
87            "at the beginning of each title, so it won't work if the key " \
88            "changes in the middle of a title.\n" \
89     "disc: the disc key is first cracked, then all title keys can be " \
90            "decrypted instantly, which allows us to check them often.\n" \
91     "key: the same as \"disc\" if you don't have a file with player keys " \
92            "at compilation time. If you do, the decryption of the disc key " \
93            "will be faster with this method. It is the one that was used by " \
94            "libcss.\n" \
95     "The default method is: key.")
96
97 static const char *const psz_css_list[] = { "title", "disc", "key" };
98 static const char *const psz_css_list_text[] = { N_("title"), N_("Disc"), N_("Key") };
99
100 static int  Open ( vlc_object_t * );
101 static void Close( vlc_object_t * );
102
103 vlc_module_begin ()
104     set_shortname( N_("DVD without menus") )
105     set_description( N_("DVDRead Input (no menu support)") )
106     set_category( CAT_INPUT )
107     set_subcategory( SUBCAT_INPUT_ACCESS )
108     add_integer( "dvdread-angle", 1, NULL, ANGLE_TEXT,
109         ANGLE_LONGTEXT, false )
110     add_integer( "dvdread-caching", DEFAULT_PTS_DELAY / 1000, NULL,
111         CACHING_TEXT, CACHING_LONGTEXT, true )
112     add_string( "dvdread-css-method", NULL, NULL, CSSMETHOD_TEXT,
113                 CSSMETHOD_LONGTEXT, true )
114         change_string_list( psz_css_list, psz_css_list_text, 0 )
115     set_capability( "access_demux", 0 )
116     add_shortcut( "dvd" )
117     add_shortcut( "dvdread" )
118     add_shortcut( "dvdsimple" )
119     set_callbacks( Open, Close )
120 vlc_module_end ()
121
122 /* how many blocks DVDRead will read in each loop */
123 #define DVD_BLOCK_READ_ONCE 4
124
125 /*****************************************************************************
126  * Local prototypes
127  *****************************************************************************/
128
129 struct demux_sys_t
130 {
131     /* DVDRead state */
132     dvd_reader_t *p_dvdread;
133     dvd_file_t   *p_title;
134
135     ifo_handle_t *p_vmg_file;
136     ifo_handle_t *p_vts_file;
137
138     int i_title;
139     int i_chapter, i_chapters;
140     int i_angle, i_angles;
141
142     tt_srpt_t    *p_tt_srpt;
143     pgc_t        *p_cur_pgc;
144     dsi_t        dsi_pack;
145     int          i_ttn;
146
147     int i_pack_len;
148     int i_cur_block;
149     int i_next_vobu;
150
151     int i_mux_rate;
152
153     /* Current title start/end blocks */
154     int i_title_start_block;
155     int i_title_end_block;
156     int i_title_blocks;
157     int i_title_offset;
158     mtime_t i_title_cur_time;
159
160     int i_title_start_cell;
161     int i_title_end_cell;
162     int i_cur_cell;
163     int i_next_cell;
164     mtime_t i_cell_cur_time;
165     mtime_t i_cell_duration;
166
167     /* Track */
168     ps_track_t    tk[PS_TK_COUNT];
169
170     int           i_titles;
171     input_title_t **titles;
172
173     /* Video */
174     int i_sar_num;
175     int i_sar_den;
176
177     /* SPU */
178     uint32_t clut[16];
179 };
180
181 static int Control   ( demux_t *, int, va_list );
182 static int Demux     ( demux_t * );
183 static int DemuxBlock( demux_t *, uint8_t *, int );
184
185 static void DemuxTitles( demux_t *, int * );
186 static void ESNew( demux_t *, int, int );
187
188 static int  DvdReadSetArea  ( demux_t *, int, int, int );
189 static void DvdReadSeek     ( demux_t *, int );
190 static void DvdReadHandleDSI( demux_t *, uint8_t * );
191 static void DvdReadFindCell ( demux_t * );
192
193 /*****************************************************************************
194  * Open:
195  *****************************************************************************/
196 static int Open( vlc_object_t *p_this )
197 {
198     demux_t      *p_demux = (demux_t*)p_this;
199     demux_sys_t  *p_sys;
200     char         *psz_name;
201     char         *psz_dvdcss_env;
202     dvd_reader_t *p_dvdread;
203     ifo_handle_t *p_vmg_file;
204
205     if( !p_demux->psz_path || !*p_demux->psz_path )
206     {
207         /* Only when selected */
208         if( !p_this->b_force ) return VLC_EGENERIC;
209
210         psz_name = var_CreateGetString( p_this, "dvd" );
211         if( !psz_name )
212         {
213             psz_name = strdup("");
214         }
215     }
216     else
217         psz_name = ToLocaleDup( p_demux->psz_path );
218
219 #ifdef WIN32
220     if( psz_name[0] && psz_name[1] == ':' &&
221         psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';
222 #endif
223
224     /* Override environment variable DVDCSS_METHOD with config option */
225     psz_dvdcss_env = var_InheritString( p_demux, "dvdread-css-method" );
226     if( psz_dvdcss_env )
227 #ifdef HAVE_SETENV
228         setenv( "DVDCSS_METHOD", psz_dvdcss_env, 1 );
229 #else
230     {
231         /* FIXME: this create a small memory leak */
232         char *psz_env;
233         psz_env = malloc( strlen("DVDCSS_METHOD=") +
234                           strlen( psz_dvdcss_env ) + 1 );
235         if( !psz_env )
236         {
237             free( psz_dvdcss_env );
238             return VLC_ENOMEM;
239         }
240         sprintf( psz_env, "%s%s", "DVDCSS_METHOD=", psz_dvdcss_env );
241         putenv( psz_env );
242     }
243 #endif
244     free( psz_dvdcss_env );
245
246     /* Open dvdread */
247     if( !(p_dvdread = DVDOpen( psz_name )) )
248     {
249         msg_Err( p_demux, "DVDRead cannot open source: %s", psz_name );
250         dialog_Fatal( p_demux, _("Playback failure"),
251                         _("DVDRead could not open the disc \"%s\"."), psz_name );
252         free( psz_name );
253         return VLC_EGENERIC;
254     }
255     free( psz_name );
256
257     /* Ifo allocation & initialisation */
258     if( !( p_vmg_file = ifoOpen( p_dvdread, 0 ) ) )
259     {
260         msg_Warn( p_demux, "cannot open VMG info" );
261         return VLC_EGENERIC;
262     }
263     msg_Dbg( p_demux, "VMG opened" );
264
265     /* Fill p_demux field */
266     DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
267
268     ps_track_init( p_sys->tk );
269     p_sys->i_sar_num = 0;
270     p_sys->i_sar_den = 0;
271     p_sys->i_title_cur_time = (mtime_t) 0;
272     p_sys->i_cell_cur_time = (mtime_t) 0;
273     p_sys->i_cell_duration = (mtime_t) 0;
274
275     p_sys->p_dvdread = p_dvdread;
276     p_sys->p_vmg_file = p_vmg_file;
277     p_sys->p_title = NULL;
278     p_sys->p_vts_file = NULL;
279
280     p_sys->i_title = p_sys->i_chapter = -1;
281     p_sys->i_mux_rate = 0;
282
283     p_sys->i_angle = var_CreateGetInteger( p_demux, "dvdread-angle" );
284     if( p_sys->i_angle <= 0 ) p_sys->i_angle = 1;
285
286     DemuxTitles( p_demux, &p_sys->i_angle );
287     if( DvdReadSetArea( p_demux, 0, 0, p_sys->i_angle ) != VLC_SUCCESS )
288     {
289         Close( p_this );
290         msg_Err( p_demux, "DvdReadSetArea(0,0,%i) failed (can't decrypt DVD?)",
291                  p_sys->i_angle );
292         return VLC_EGENERIC;
293     }
294
295     /* Update default_pts to a suitable value for dvdread access */
296     var_Create( p_demux, "dvdread-caching",
297                 VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
298
299     return VLC_SUCCESS;
300 }
301
302 /*****************************************************************************
303  * Close:
304  *****************************************************************************/
305 static void Close( vlc_object_t *p_this )
306 {
307     demux_t     *p_demux = (demux_t*)p_this;
308     demux_sys_t *p_sys = p_demux->p_sys;
309     int i;
310
311     for( i = 0; i < PS_TK_COUNT; i++ )
312     {
313         ps_track_t *tk = &p_sys->tk[i];
314         if( tk->b_seen )
315         {
316             es_format_Clean( &tk->fmt );
317             if( tk->es ) es_out_Del( p_demux->out, tk->es );
318         }
319     }
320
321     /* Close libdvdread */
322     if( p_sys->p_title ) DVDCloseFile( p_sys->p_title );
323     if( p_sys->p_vts_file ) ifoClose( p_sys->p_vts_file );
324     if( p_sys->p_vmg_file ) ifoClose( p_sys->p_vmg_file );
325     DVDClose( p_sys->p_dvdread );
326
327     free( p_sys );
328 }
329
330 static int64_t dvdtime_to_time( dvd_time_t *dtime, uint8_t still_time )
331 {
332 /* Macro to convert Binary Coded Decimal to Decimal */
333 #define BCD2D(__x__) (((__x__ & 0xf0) >> 4) * 10 + (__x__ & 0x0f))
334
335     double f_fps, f_ms;
336     int64_t i_micro_second = 0;
337
338     if (still_time == 0 || still_time == 0xFF)
339     {
340         i_micro_second += (int64_t)(BCD2D(dtime->hour)) * 60 * 60 * 1000000;
341         i_micro_second += (int64_t)(BCD2D(dtime->minute)) * 60 * 1000000;
342         i_micro_second += (int64_t)(BCD2D(dtime->second)) * 1000000;
343
344         switch((dtime->frame_u & 0xc0) >> 6)
345         {
346         case 1:
347             f_fps = 25.0;
348             break;
349         case 3:
350             f_fps = 29.97;
351             break;
352         default:
353             f_fps = 2500.0;
354             break;
355         }
356         f_ms = BCD2D(dtime->frame_u&0x3f) * 1000.0 / f_fps;
357         i_micro_second += (int64_t)(f_ms * 1000.0);
358     }
359     else
360     {
361         i_micro_second = still_time;
362         i_micro_second = (int64_t)((double)i_micro_second * 1000000.0);
363     }
364
365     return i_micro_second;
366 }
367
368 /*****************************************************************************
369  * Control:
370  *****************************************************************************/
371 static int Control( demux_t *p_demux, int i_query, va_list args )
372 {
373     demux_sys_t *p_sys = p_demux->p_sys;
374     double f, *pf;
375     bool *pb;
376     int64_t *pi64;
377     input_title_t ***ppp_title;
378     int *pi_int;
379     int i;
380
381     switch( i_query )
382     {
383         case DEMUX_GET_POSITION:
384         {
385             pf = (double*) va_arg( args, double* );
386
387             if( p_sys->i_title_blocks > 0 )
388                 *pf = (double)p_sys->i_title_offset / p_sys->i_title_blocks;
389             else
390                 *pf = 0.0;
391
392             return VLC_SUCCESS;
393         }
394         case DEMUX_SET_POSITION:
395         {
396             f = (double)va_arg( args, double );
397
398             DvdReadSeek( p_demux, f * p_sys->i_title_blocks );
399
400             return VLC_SUCCESS;
401         }
402         case DEMUX_GET_TIME:
403             pi64 = (int64_t*)va_arg( args, int64_t * );
404             if( p_demux->info.i_title >= 0 && p_demux->info.i_title < p_sys->i_titles )
405             {
406                 *pi64 = (int64_t) dvdtime_to_time( &p_sys->p_cur_pgc->playback_time, 0 ) /
407                         p_sys->i_title_blocks * p_sys->i_title_offset;
408                 return VLC_SUCCESS;
409             }
410             *pi64 = 0;
411             return VLC_EGENERIC;
412
413         case DEMUX_GET_LENGTH:
414             pi64 = (int64_t*)va_arg( args, int64_t * );
415             if( p_demux->info.i_title >= 0 && p_demux->info.i_title < p_sys->i_titles )
416             {
417                 *pi64 = (int64_t)dvdtime_to_time( &p_sys->p_cur_pgc->playback_time, 0 );
418                 return VLC_SUCCESS;
419             }
420             *pi64 = 0;
421             return VLC_EGENERIC;
422
423         /* Special for access_demux */
424         case DEMUX_CAN_PAUSE:
425         case DEMUX_CAN_SEEK:
426         case DEMUX_CAN_CONTROL_PACE:
427             /* TODO */
428             pb = (bool*)va_arg( args, bool * );
429             *pb = true;
430             return VLC_SUCCESS;
431
432         case DEMUX_SET_PAUSE_STATE:
433             return VLC_SUCCESS;
434
435         case DEMUX_GET_TITLE_INFO:
436             ppp_title = (input_title_t***)va_arg( args, input_title_t*** );
437             pi_int    = (int*)va_arg( args, int* );
438             *((int*)va_arg( args, int* )) = 1; /* Title offset */
439             *((int*)va_arg( args, int* )) = 1; /* Chapter offset */
440
441             /* Duplicate title infos */
442             *pi_int = p_sys->i_titles;
443             *ppp_title = malloc( sizeof(input_title_t **) * p_sys->i_titles );
444             for( i = 0; i < p_sys->i_titles; i++ )
445             {
446                 (*ppp_title)[i] = vlc_input_title_Duplicate(p_sys->titles[i]);
447             }
448             return VLC_SUCCESS;
449
450         case DEMUX_SET_TITLE:
451             i = (int)va_arg( args, int );
452             if( DvdReadSetArea( p_demux, i, 0, -1 ) != VLC_SUCCESS )
453             {
454                 msg_Warn( p_demux, "cannot set title/chapter" );
455                 return VLC_EGENERIC;
456             }
457             p_demux->info.i_update |=
458                 INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
459             p_demux->info.i_title = i;
460             p_demux->info.i_seekpoint = 0;
461             return VLC_SUCCESS;
462
463         case DEMUX_SET_SEEKPOINT:
464             i = (int)va_arg( args, int );
465             if( DvdReadSetArea( p_demux, -1, i, -1 ) != VLC_SUCCESS )
466             {
467                 msg_Warn( p_demux, "cannot set title/chapter" );
468                 return VLC_EGENERIC;
469             }
470             p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
471             p_demux->info.i_seekpoint = i;
472             return VLC_SUCCESS;
473
474         case DEMUX_GET_PTS_DELAY:
475             pi64 = (int64_t*)va_arg( args, int64_t * );
476             *pi64 = (int64_t)var_GetInteger( p_demux, "dvdread-caching" )*1000;
477             return VLC_SUCCESS;
478
479         /* TODO implement others */
480         default:
481             return VLC_EGENERIC;
482     }
483 }
484
485 /*****************************************************************************
486  * Demux:
487  *****************************************************************************/
488 static int Demux( demux_t *p_demux )
489 {
490     demux_sys_t *p_sys = p_demux->p_sys;
491
492     uint8_t p_buffer[DVD_VIDEO_LB_LEN * DVD_BLOCK_READ_ONCE];
493     int i_blocks_once, i_read;
494     int i;
495
496     /*
497      * Playback by cell in this pgc, starting at the cell for our chapter.
498      */
499
500     /*
501      * Check end of pack, and select the following one
502      */
503     if( !p_sys->i_pack_len )
504     {
505         /* Read NAV packet */
506         if( DVDReadBlocks( p_sys->p_title, p_sys->i_next_vobu,
507                            1, p_buffer ) != 1 )
508         {
509             msg_Err( p_demux, "read failed for block %d", p_sys->i_next_vobu );
510             dialog_Fatal( p_demux, _("Playback failure"),
511                           _("DVDRead could not read block %d."),
512                           p_sys->i_next_vobu );
513             return -1;
514         }
515
516         /* Basic check to be sure we don't have a empty title
517          * go to next title if so */
518         //assert( p_buffer[41] == 0xbf && p_buffer[1027] == 0xbf );
519
520         /* Parse the contained dsi packet */
521         DvdReadHandleDSI( p_demux, p_buffer );
522
523         /* End of title */
524         if( p_sys->i_cur_cell >= p_sys->p_cur_pgc->nr_of_cells )
525         {
526             if( p_sys->i_title + 1 >= p_sys->i_titles )
527             {
528                 return 0; /* EOF */
529             }
530
531             DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 );
532         }
533
534         if( p_sys->i_pack_len >= 1024 )
535         {
536             msg_Err( p_demux, "i_pack_len >= 1024 (%i). "
537                      "This shouldn't happen!", p_sys->i_pack_len );
538             return 0; /* EOF */
539         }
540
541         /* FIXME: Ugly kludge: we send the pack block to the input for it
542          * sometimes has a zero scr and restart the sync */
543         p_sys->i_cur_block++;
544         p_sys->i_title_offset++;
545
546         DemuxBlock( p_demux, p_buffer, DVD_VIDEO_LB_LEN );
547     }
548
549     if( p_sys->i_cur_cell >= p_sys->p_cur_pgc->nr_of_cells )
550     {
551         if( p_sys->i_title + 1 >= p_sys->i_titles )
552         {
553             return 0; /* EOF */
554         }
555
556         DvdReadSetArea( p_demux, p_sys->i_title + 1, 0, -1 );
557     }
558
559     /*
560      * Read actual data
561      */
562     i_blocks_once = __MIN( p_sys->i_pack_len, DVD_BLOCK_READ_ONCE );
563     p_sys->i_pack_len -= i_blocks_once;
564
565     /* Reads from DVD */
566     i_read = DVDReadBlocks( p_sys->p_title, p_sys->i_cur_block,
567                             i_blocks_once, p_buffer );
568     if( i_read != i_blocks_once )
569     {
570         msg_Err( p_demux, "read failed for %d/%d blocks at 0x%02x",
571                  i_read, i_blocks_once, p_sys->i_cur_block );
572         dialog_Fatal( p_demux, _("Playback failure"),
573                         _("DVDRead could not read %d/%d blocks at 0x%02x."),
574                         i_read, i_blocks_once, p_sys->i_cur_block );
575         return -1;
576     }
577
578     p_sys->i_cur_block += i_read;
579     p_sys->i_title_offset += i_read;
580
581 #if 0
582     msg_Dbg( p_demux, "i_blocks: %d len: %d current: 0x%02x",
583              i_read, p_sys->i_pack_len, p_sys->i_cur_block );
584 #endif
585
586     for( i = 0; i < i_read; i++ )
587     {
588         DemuxBlock( p_demux, p_buffer + i * DVD_VIDEO_LB_LEN,
589                     DVD_VIDEO_LB_LEN );
590     }
591
592 #undef p_pgc
593
594     return 1;
595 }
596
597 /*****************************************************************************
598  * DemuxBlock: demux a given block
599  *****************************************************************************/
600 static int DemuxBlock( demux_t *p_demux, uint8_t *pkt, int i_pkt )
601 {
602     demux_sys_t *p_sys = p_demux->p_sys;
603     uint8_t     *p = pkt;
604
605     while( p && p < &pkt[i_pkt] )
606     {
607         block_t *p_pkt;
608         int i_size = &pkt[i_pkt] - p;
609
610         if( i_size < 6 )
611             break;
612  
613         i_size = ps_pkt_size( p, i_size );
614         if( i_size <= 0 )
615         {
616             break;
617         }
618
619         /* Create a block */
620         p_pkt = block_New( p_demux, i_size );
621         memcpy( p_pkt->p_buffer, p, i_size);
622
623         /* Parse it and send it */
624         switch( 0x100 | p[3] )
625         {
626         case 0x1b9:
627         case 0x1bb:
628         case 0x1bc:
629
630 #ifdef DVDREAD_DEBUG
631             if( p[3] == 0xbc )
632             {
633                 msg_Warn( p_demux, "received a PSM packet" );
634             }
635             else if( p[3] == 0xbb )
636             {
637                 msg_Warn( p_demux, "received a SYSTEM packet" );
638             }
639 #endif
640             block_Release( p_pkt );
641             break;
642
643         case 0x1ba:
644         {
645             int64_t i_scr;
646             int i_mux_rate;
647             if( !ps_pkt_parse_pack( p_pkt, &i_scr, &i_mux_rate ) )
648             {
649                 es_out_Control( p_demux->out, ES_OUT_SET_PCR, i_scr );
650                 if( i_mux_rate > 0 ) p_sys->i_mux_rate = i_mux_rate;
651             }
652             block_Release( p_pkt );
653             break;
654         }
655         default:
656         {
657             int i_id = ps_pkt_id( p_pkt );
658             if( i_id >= 0xc0 )
659             {
660                 ps_track_t *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];
661
662                 if( !tk->b_seen )
663                 {
664                     ESNew( p_demux, i_id, 0 );
665                 }
666                 if( tk->b_seen && tk->es &&
667                     !ps_pkt_parse_pes( p_pkt, tk->i_skip ) )
668                 {
669                     es_out_Send( p_demux->out, tk->es, p_pkt );
670                 }
671                 else
672                 {
673                     block_Release( p_pkt );
674                 }
675             }
676             else
677             {
678                 block_Release( p_pkt );
679             }
680             break;
681         }
682         }
683
684         p += i_size;
685     }
686
687     return VLC_SUCCESS;
688 }
689
690 /*****************************************************************************
691  * ESNew: register a new elementary stream
692  *****************************************************************************/
693 static void ESNew( demux_t *p_demux, int i_id, int i_lang )
694 {
695     demux_sys_t *p_sys = p_demux->p_sys;
696     ps_track_t  *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];
697     char psz_language[3];
698
699     if( tk->b_seen ) return;
700
701     if( ps_track_fill( tk, 0, i_id ) )
702     {
703         msg_Warn( p_demux, "unknown codec for id=0x%x", i_id );
704         return;
705     }
706
707     psz_language[0] = psz_language[1] = psz_language[2] = 0;
708     if( i_lang && i_lang != 0xffff )
709     {
710         psz_language[0] = (i_lang >> 8)&0xff;
711         psz_language[1] = (i_lang     )&0xff;
712     }
713
714     /* Add a new ES */
715     if( tk->fmt.i_cat == VIDEO_ES )
716     {
717         tk->fmt.video.i_sar_num = p_sys->i_sar_num;
718         tk->fmt.video.i_sar_den = p_sys->i_sar_den;
719     }
720     else if( tk->fmt.i_cat == AUDIO_ES )
721     {
722         int i_audio = -1;
723         /* find the audio number PLEASE find another way */
724         if( (i_id&0xbdf8) == 0xbd88 )       /* dts */
725         {
726             i_audio = i_id&0x07;
727         }
728         else if( (i_id&0xbdf0) == 0xbd80 )  /* a52 */
729         {
730             i_audio = i_id&0xf;
731         }
732         else if( (i_id&0xbdf0) == 0xbda0 )  /* lpcm */
733         {
734             i_audio = i_id&0x1f;
735         }
736         else if( ( i_id&0xe0 ) == 0xc0 )    /* mpga */
737         {
738             i_audio = i_id&0x1f;
739         }
740
741         if( psz_language[0] ) tk->fmt.psz_language = strdup( psz_language );
742     }
743     else if( tk->fmt.i_cat == SPU_ES )
744     {
745         /* Palette */
746         tk->fmt.subs.spu.palette[0] = 0xBeef;
747         memcpy( &tk->fmt.subs.spu.palette[1], p_sys->clut,
748                 16 * sizeof( uint32_t ) );
749
750         if( psz_language[0] ) tk->fmt.psz_language = strdup( psz_language );
751     }
752
753     tk->es = es_out_Add( p_demux->out, &tk->fmt );
754     tk->b_seen = true;
755 }
756
757 /*****************************************************************************
758  * DvdReadSetArea: initialize input data for title x, chapter y.
759  * It should be called for each user navigation request.
760  *****************************************************************************
761  * Take care that i_title and i_chapter start from 0.
762  *****************************************************************************/
763 static int DvdReadSetArea( demux_t *p_demux, int i_title, int i_chapter,
764                            int i_angle )
765 {
766     VLC_UNUSED( i_angle );
767
768     demux_sys_t *p_sys = p_demux->p_sys;
769     int pgc_id = 0, pgn = 0;
770     int i;
771
772 #define p_pgc p_sys->p_cur_pgc
773 #define p_vmg p_sys->p_vmg_file
774 #define p_vts p_sys->p_vts_file
775
776     if( i_title >= 0 && i_title < p_sys->i_titles &&
777         i_title != p_sys->i_title )
778     {
779         int i_start_cell, i_end_cell;
780
781         if( p_sys->p_title != NULL ) DVDCloseFile( p_sys->p_title );
782         if( p_vts != NULL ) ifoClose( p_vts );
783         p_sys->i_title = i_title;
784
785         /*
786          *  We have to load all title information
787          */
788         msg_Dbg( p_demux, "open VTS %d, for title %d",
789                  p_vmg->tt_srpt->title[i_title].title_set_nr, i_title + 1 );
790
791         /* Ifo vts */
792         if( !( p_vts = ifoOpen( p_sys->p_dvdread,
793                p_vmg->tt_srpt->title[i_title].title_set_nr ) ) )
794         {
795             msg_Err( p_demux, "fatal error in vts ifo" );
796             return VLC_EGENERIC;
797         }
798
799         /* Title position inside the selected vts */
800         p_sys->i_ttn = p_vmg->tt_srpt->title[i_title].vts_ttn;
801
802         /* Find title start/end */
803         pgc_id = p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].ptt[0].pgcn;
804         pgn = p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].ptt[0].pgn;
805         p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc;
806
807         p_sys->i_title_start_cell =
808             i_start_cell = p_pgc->program_map[pgn - 1] - 1;
809         p_sys->i_title_start_block =
810             p_pgc->cell_playback[i_start_cell].first_sector;
811
812         p_sys->i_title_end_cell =
813             i_end_cell = p_pgc->nr_of_cells - 1;
814         p_sys->i_title_end_block =
815             p_pgc->cell_playback[i_end_cell].last_sector;
816
817         p_sys->i_title_offset = 0;
818
819         p_sys->i_title_blocks = 0;
820         for( i = i_start_cell; i <= i_end_cell; i++ )
821         {
822             p_sys->i_title_blocks += p_pgc->cell_playback[i].last_sector -
823                 p_pgc->cell_playback[i].first_sector + 1;
824         }
825
826         msg_Dbg( p_demux, "title %d vts_title %d pgc %d pgn %d "
827                  "start %d end %d blocks: %d",
828                  i_title + 1, p_sys->i_ttn, pgc_id, pgn,
829                  p_sys->i_title_start_block, p_sys->i_title_end_block,
830                  p_sys->i_title_blocks );
831
832         /*
833          * Set properties for current chapter
834          */
835         p_sys->i_chapter = 0;
836         p_sys->i_chapters =
837             p_vts->vts_ptt_srpt->title[p_sys->i_ttn - 1].nr_of_ptts;
838
839         pgc_id = p_vts->vts_ptt_srpt->title[
840                     p_sys->i_ttn - 1].ptt[p_sys->i_chapter].pgcn;
841         pgn = p_vts->vts_ptt_srpt->title[
842                     p_sys->i_ttn - 1].ptt[p_sys->i_chapter].pgn;
843
844         p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc;
845         p_sys->i_pack_len = 0;
846         p_sys->i_next_cell =
847             p_sys->i_cur_cell = p_pgc->program_map[pgn - 1] - 1;
848         DvdReadFindCell( p_demux );
849
850         p_sys->i_next_vobu = p_sys->i_cur_block =
851             p_pgc->cell_playback[p_sys->i_cur_cell].first_sector;
852
853         /*
854          * Angle management
855          */
856         p_sys->i_angles = p_vmg->tt_srpt->title[i_title].nr_of_angles;
857         if( p_sys->i_angle > p_sys->i_angles ) p_sys->i_angle = 1;
858
859         /*
860          * We've got enough info, time to open the title set data.
861          */
862         if( !( p_sys->p_title = DVDOpenFile( p_sys->p_dvdread,
863             p_vmg->tt_srpt->title[i_title].title_set_nr,
864             DVD_READ_TITLE_VOBS ) ) )
865         {
866             msg_Err( p_demux, "cannot open title (VTS_%02d_1.VOB)",
867                      p_vmg->tt_srpt->title[i_title].title_set_nr );
868             return VLC_EGENERIC;
869         }
870
871         //IfoPrintTitle( p_demux );
872
873         /*
874          * Destroy obsolete ES by reinitializing program 0
875          * and find all ES in title with ifo data
876          */
877         es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
878
879         for( i = 0; i < PS_TK_COUNT; i++ )
880         {
881             ps_track_t *tk = &p_sys->tk[i];
882             if( tk->b_seen )
883             {
884                 es_format_Clean( &tk->fmt );
885                 if( tk->es ) es_out_Del( p_demux->out, tk->es );
886             }
887             tk->b_seen = false;
888         }
889
890         if( p_demux->info.i_title != i_title )
891         {
892             p_demux->info.i_update |=
893                 INPUT_UPDATE_TITLE | INPUT_UPDATE_SEEKPOINT;
894             p_demux->info.i_title = i_title;
895             p_demux->info.i_seekpoint = 0;
896         }
897
898         /* TODO: re-add angles */
899
900
901         ESNew( p_demux, 0xe0, 0 ); /* Video, FIXME ? */
902         const video_attr_t *p_attr = &p_vts->vtsi_mat->vts_video_attr;
903         int i_video_height = p_attr->video_format != 0 ? 576 : 480;
904         int i_video_width;
905         switch( p_attr->picture_size )
906         {
907         case 0:
908             i_video_width = 720;
909             break;
910         case 1:
911             i_video_width = 704;
912             break;
913         case 2:
914             i_video_width = 352;
915             break;
916         default:
917         case 3:
918             i_video_width = 352;
919             i_video_height /= 2;
920             break;
921         }
922         switch( p_attr->display_aspect_ratio )
923         {
924         case 0:
925             p_sys->i_sar_num = 4 * i_video_height;
926             p_sys->i_sar_den = 3 * i_video_width;
927             break;
928         case 3:
929             p_sys->i_sar_num = 16 * i_video_height;
930             p_sys->i_sar_den =  9 * i_video_width;
931             break;
932         default:
933             p_sys->i_sar_num = 0;
934             p_sys->i_sar_den = 0;
935             break;
936         }
937
938 #define audio_control \
939     p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i-1]
940
941         /* Audio ES, in the order they appear in the .ifo */
942         for( i = 1; i <= p_vts->vtsi_mat->nr_of_vts_audio_streams; i++ )
943         {
944             int i_position = 0;
945             uint16_t i_id;
946
947             //IfoPrintAudio( p_demux, i );
948
949             /* Audio channel is active if first byte is 0x80 */
950             if( audio_control & 0x8000 )
951             {
952                 i_position = ( audio_control & 0x7F00 ) >> 8;
953
954                 msg_Dbg( p_demux, "audio position  %d", i_position );
955                 switch( p_vts->vtsi_mat->vts_audio_attr[i - 1].audio_format )
956                 {
957                 case 0x00: /* A52 */
958                     i_id = (0x80 + i_position) | 0xbd00;
959                     break;
960                 case 0x02:
961                 case 0x03: /* MPEG audio */
962                     i_id = 0xc000 + i_position;
963                     break;
964                 case 0x04: /* LPCM */
965                     i_id = (0xa0 + i_position) | 0xbd00;
966                     break;
967                 case 0x06: /* DTS */
968                     i_id = (0x88 + i_position) | 0xbd00;
969                     break;
970                 default:
971                     i_id = 0;
972                     msg_Err( p_demux, "unknown audio type %.2x",
973                         p_vts->vtsi_mat->vts_audio_attr[i - 1].audio_format );
974                 }
975
976                 ESNew( p_demux, i_id, p_sys->p_vts_file->vtsi_mat->
977                        vts_audio_attr[i - 1].lang_code );
978             }
979         }
980 #undef audio_control
981
982 #define spu_palette \
983     p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->palette
984
985         memcpy( p_sys->clut, spu_palette, 16 * sizeof( uint32_t ) );
986
987 #define spu_control \
988     p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i-1]
989
990         /* Sub Picture ES */
991         for( i = 1; i <= p_vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
992         {
993             int i_position = 0;
994             uint16_t i_id;
995
996             //IfoPrintSpu( p_sys, i );
997             msg_Dbg( p_demux, "spu %d 0x%02x", i, spu_control );
998
999             if( spu_control & 0x80000000 )
1000             {
1001                 /*  there are several streams for one spu */
1002                 if( p_vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
1003                 {
1004                     /* 16:9 */
1005                     switch( p_vts->vtsi_mat->vts_video_attr.permitted_df )
1006                     {
1007                     case 1: /* letterbox */
1008                         i_position = spu_control & 0xff;
1009                         break;
1010                     case 2: /* pan&scan */
1011                         i_position = ( spu_control >> 8 ) & 0xff;
1012                         break;
1013                     default: /* widescreen */
1014                         i_position = ( spu_control >> 16 ) & 0xff;
1015                         break;
1016                     }
1017                 }
1018                 else
1019                 {
1020                     /* 4:3 */
1021                     i_position = ( spu_control >> 24 ) & 0x7F;
1022                 }
1023
1024                 i_id = (0x20 + i_position) | 0xbd00;
1025
1026                 ESNew( p_demux, i_id, p_sys->p_vts_file->vtsi_mat->
1027                        vts_subp_attr[i - 1].lang_code );
1028             }
1029         }
1030 #undef spu_control
1031
1032     }
1033     else if( i_title != -1 && i_title != p_sys->i_title )
1034
1035     {
1036         return VLC_EGENERIC; /* Couldn't set title */
1037     }
1038
1039     /*
1040      * Chapter selection
1041      */
1042
1043     if( i_chapter >= 0 && i_chapter < p_sys->i_chapters )
1044     {
1045         pgc_id = p_vts->vts_ptt_srpt->title[
1046                      p_sys->i_ttn - 1].ptt[i_chapter].pgcn;
1047         pgn = p_vts->vts_ptt_srpt->title[
1048                   p_sys->i_ttn - 1].ptt[i_chapter].pgn;
1049
1050         p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc;
1051
1052         p_sys->i_cur_cell = p_pgc->program_map[pgn - 1] - 1;
1053         p_sys->i_chapter = i_chapter;
1054         DvdReadFindCell( p_demux );
1055
1056         p_sys->i_title_offset = 0;
1057         for( i = p_sys->i_title_start_cell; i < p_sys->i_cur_cell; i++ )
1058         {
1059             p_sys->i_title_offset += p_pgc->cell_playback[i].last_sector -
1060                 p_pgc->cell_playback[i].first_sector + 1;
1061         }
1062
1063         p_sys->i_pack_len = 0;
1064         p_sys->i_next_vobu = p_sys->i_cur_block =
1065             p_pgc->cell_playback[p_sys->i_cur_cell].first_sector;
1066
1067         if( p_demux->info.i_seekpoint != i_chapter )
1068         {
1069             p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
1070             p_demux->info.i_seekpoint = i_chapter;
1071         }
1072     }
1073     else if( i_chapter != -1 )
1074
1075     {
1076         return VLC_EGENERIC; /* Couldn't set chapter */
1077     }
1078
1079 #undef p_pgc
1080 #undef p_vts
1081 #undef p_vmg
1082
1083     return VLC_SUCCESS;
1084 }
1085
1086 /*****************************************************************************
1087  * DvdReadSeek : Goes to a given position on the stream.
1088  *****************************************************************************
1089  * This one is used by the input and translate chronological position from
1090  * input to logical position on the device.
1091  *****************************************************************************/
1092 static void DvdReadSeek( demux_t *p_demux, int i_block_offset )
1093 {
1094     demux_sys_t *p_sys = p_demux->p_sys;
1095     int i_chapter = 0;
1096     int i_cell = 0;
1097     int i_vobu = 0;
1098     int i_sub_cell = 0;
1099     int i_block;
1100
1101 #define p_pgc p_sys->p_cur_pgc
1102 #define p_vts p_sys->p_vts_file
1103
1104     /* Find cell */
1105     i_block = i_block_offset;
1106     for( i_cell = p_sys->i_title_start_cell;
1107          i_cell <= p_sys->i_title_end_cell; i_cell++ )
1108     {
1109         if( i_block < (int)p_pgc->cell_playback[i_cell].last_sector -
1110             (int)p_pgc->cell_playback[i_cell].first_sector + 1 ) break;
1111
1112         i_block -= (p_pgc->cell_playback[i_cell].last_sector -
1113             p_pgc->cell_playback[i_cell].first_sector + 1);
1114     }
1115     if( i_cell > p_sys->i_title_end_cell )
1116     {
1117         msg_Err( p_demux, "couldn't find cell for block %i", i_block_offset );
1118         return;
1119     }
1120     i_block += p_pgc->cell_playback[i_cell].first_sector;
1121     p_sys->i_title_offset = i_block_offset;
1122
1123     /* Find chapter */
1124     for( i_chapter = 0; i_chapter < p_sys->i_chapters; i_chapter++ )
1125     {
1126         int pgc_id, pgn, i_tmp;
1127
1128         pgc_id = p_vts->vts_ptt_srpt->title[
1129                     p_sys->i_ttn - 1].ptt[i_chapter].pgcn;
1130         pgn = p_vts->vts_ptt_srpt->title[
1131                     p_sys->i_ttn - 1].ptt[i_chapter].pgn;
1132
1133         i_tmp = p_vts->vts_pgcit->pgci_srp[pgc_id - 1].pgc->program_map[pgn-1];
1134
1135         if( i_tmp > i_cell ) break;
1136     }
1137
1138     if( i_chapter < p_sys->i_chapters &&
1139         p_demux->info.i_seekpoint != i_chapter )
1140     {
1141         p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
1142         p_demux->info.i_seekpoint = i_chapter;
1143     }
1144
1145     /* Find vobu */
1146     while( (int)p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu] <= i_block )
1147     {
1148         i_vobu++;
1149     }
1150
1151     /* Find sub_cell */
1152     while( p_vts->vts_c_adt->cell_adr_table[i_sub_cell].start_sector <
1153            p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu-1] )
1154     {
1155         i_sub_cell++;
1156     }
1157
1158 #if 1
1159     msg_Dbg( p_demux, "cell %d i_sub_cell %d chapter %d vobu %d "
1160              "cell_sector %d vobu_sector %d sub_cell_sector %d",
1161              i_cell, i_sub_cell, i_chapter, i_vobu,
1162              p_sys->p_cur_pgc->cell_playback[i_cell].first_sector,
1163              p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu],
1164              p_vts->vts_c_adt->cell_adr_table[i_sub_cell - 1].start_sector);
1165 #endif
1166
1167     p_sys->i_cur_block = i_block;
1168     p_sys->i_next_vobu = p_vts->vts_vobu_admap->vobu_start_sectors[i_vobu];
1169     p_sys->i_pack_len = p_sys->i_next_vobu - i_block;
1170     p_sys->i_cur_cell = i_cell;
1171     p_sys->i_chapter = i_chapter;
1172     DvdReadFindCell( p_demux );
1173
1174 #undef p_vts
1175 #undef p_pgc
1176
1177     return;
1178 }
1179
1180 /*****************************************************************************
1181  * DvdReadHandleDSI
1182  *****************************************************************************/
1183 static void DvdReadHandleDSI( demux_t *p_demux, uint8_t *p_data )
1184 {
1185     demux_sys_t *p_sys = p_demux->p_sys;
1186
1187     navRead_DSI( &p_sys->dsi_pack, &p_data[DSI_START_BYTE] );
1188
1189     /*
1190      * Determine where we go next.  These values are the ones we mostly
1191      * care about.
1192      */
1193     p_sys->i_cur_block = p_sys->dsi_pack.dsi_gi.nv_pck_lbn;
1194     p_sys->i_pack_len = p_sys->dsi_pack.dsi_gi.vobu_ea;
1195
1196     /*
1197      * Store the timecodes so we can get the current time
1198      */
1199     p_sys->i_title_cur_time = (mtime_t) (p_sys->dsi_pack.dsi_gi.nv_pck_scr / 90 * 1000);
1200     p_sys->i_cell_cur_time = (mtime_t) dvdtime_to_time( &p_sys->dsi_pack.dsi_gi.c_eltm, 0 );
1201
1202     /*
1203      * If we're not at the end of this cell, we can determine the next
1204      * VOBU to display using the VOBU_SRI information section of the
1205      * DSI.  Using this value correctly follows the current angle,
1206      * avoiding the doubled scenes in The Matrix, and makes our life
1207      * really happy.
1208      */
1209
1210     p_sys->i_next_vobu = p_sys->i_cur_block +
1211         ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
1212
1213     if( p_sys->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL
1214         && p_sys->i_angle > 1 )
1215     {
1216         switch( ( p_sys->dsi_pack.sml_pbi.category & 0xf000 ) >> 12 )
1217         {
1218         case 0x4:
1219             /* Interleaved unit with no angle */
1220             if( p_sys->dsi_pack.sml_pbi.ilvu_sa != 0 )
1221             {
1222                 p_sys->i_next_vobu = p_sys->i_cur_block +
1223                     p_sys->dsi_pack.sml_pbi.ilvu_sa;
1224                 p_sys->i_pack_len = p_sys->dsi_pack.sml_pbi.ilvu_ea;
1225             }
1226             else
1227             {
1228                 p_sys->i_next_vobu = p_sys->i_cur_block +
1229                     p_sys->dsi_pack.dsi_gi.vobu_ea + 1;
1230             }
1231             break;
1232         case 0x5:
1233             /* vobu is end of ilvu */
1234             if( p_sys->dsi_pack.sml_agli.data[p_sys->i_angle-1].address )
1235             {
1236                 p_sys->i_next_vobu = p_sys->i_cur_block +
1237                     p_sys->dsi_pack.sml_agli.data[p_sys->i_angle-1].address;
1238                 p_sys->i_pack_len = p_sys->dsi_pack.sml_pbi.ilvu_ea;
1239
1240                 break;
1241             }
1242         case 0x6:
1243             /* vobu is beginning of ilvu */
1244         case 0x9:
1245             /* next scr is 0 */
1246         case 0xa:
1247             /* entering interleaved section */
1248         case 0x8:
1249             /* non interleaved cells in interleaved section */
1250         default:
1251             p_sys->i_next_vobu = p_sys->i_cur_block +
1252                 ( p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
1253             break;
1254         }
1255     }
1256     else if( p_sys->dsi_pack.vobu_sri.next_vobu == SRI_END_OF_CELL )
1257     {
1258         p_sys->i_cur_cell = p_sys->i_next_cell;
1259
1260         /* End of title */
1261         if( p_sys->i_cur_cell >= p_sys->p_cur_pgc->nr_of_cells ) return;
1262
1263         DvdReadFindCell( p_demux );
1264
1265         p_sys->i_next_vobu =
1266             p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].first_sector;
1267
1268         p_sys->i_cell_duration = (mtime_t)dvdtime_to_time( &p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].playback_time, 0 );
1269     }
1270
1271
1272 #if 0
1273     msg_Dbg( p_demux, "scr %d lbn 0x%02x vobu_ea %d vob_id %d c_id %d c_time %lld",
1274              p_sys->dsi_pack.dsi_gi.nv_pck_scr,
1275              p_sys->dsi_pack.dsi_gi.nv_pck_lbn,
1276              p_sys->dsi_pack.dsi_gi.vobu_ea,
1277              p_sys->dsi_pack.dsi_gi.vobu_vob_idn,
1278              p_sys->dsi_pack.dsi_gi.vobu_c_idn,
1279              dvdtime_to_time( &p_sys->dsi_pack.dsi_gi.c_eltm, 0 ) );
1280
1281     msg_Dbg( p_demux, "cell duration: %lld",
1282              (mtime_t)dvdtime_to_time( &p_sys->p_cur_pgc->cell_playback[p_sys->i_cur_cell].playback_time, 0 ) );
1283
1284     msg_Dbg( p_demux, "cat 0x%02x ilvu_ea %d ilvu_sa %d size %d",
1285              p_sys->dsi_pack.sml_pbi.category,
1286              p_sys->dsi_pack.sml_pbi.ilvu_ea,
1287              p_sys->dsi_pack.sml_pbi.ilvu_sa,
1288              p_sys->dsi_pack.sml_pbi.size );
1289
1290     msg_Dbg( p_demux, "next_vobu %d next_ilvu1 %d next_ilvu2 %d",
1291              p_sys->dsi_pack.vobu_sri.next_vobu & 0x7fffffff,
1292              p_sys->dsi_pack.sml_agli.data[ p_sys->i_angle - 1 ].address,
1293              p_sys->dsi_pack.sml_agli.data[ p_sys->i_angle ].address);
1294 #endif
1295 }
1296
1297 /*****************************************************************************
1298  * DvdReadFindCell
1299  *****************************************************************************/
1300 static void DvdReadFindCell( demux_t *p_demux )
1301 {
1302     demux_sys_t *p_sys = p_demux->p_sys;
1303
1304     pgc_t *p_pgc;
1305     int   pgc_id, pgn;
1306     int   i = 0;
1307
1308 #define cell p_sys->p_cur_pgc->cell_playback
1309
1310     if( cell[p_sys->i_cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK )
1311     {
1312         p_sys->i_cur_cell += p_sys->i_angle - 1;
1313
1314         while( cell[p_sys->i_cur_cell+i].block_mode != BLOCK_MODE_LAST_CELL )
1315         {
1316             i++;
1317         }
1318         p_sys->i_next_cell = p_sys->i_cur_cell + i + 1;
1319     }
1320     else
1321     {
1322         p_sys->i_next_cell = p_sys->i_cur_cell + 1;
1323     }
1324
1325 #undef cell
1326
1327     if( p_sys->i_chapter + 1 >= p_sys->i_chapters ) return;
1328
1329     pgc_id = p_sys->p_vts_file->vts_ptt_srpt->title[
1330                 p_sys->i_ttn - 1].ptt[p_sys->i_chapter + 1].pgcn;
1331     pgn = p_sys->p_vts_file->vts_ptt_srpt->title[
1332               p_sys->i_ttn - 1].ptt[p_sys->i_chapter + 1].pgn;
1333     p_pgc = p_sys->p_vts_file->vts_pgcit->pgci_srp[pgc_id - 1].pgc;
1334
1335     if( p_sys->i_cur_cell >= p_pgc->program_map[pgn - 1] - 1 )
1336     {
1337         p_sys->i_chapter++;
1338
1339         if( p_sys->i_chapter < p_sys->i_chapters &&
1340             p_demux->info.i_seekpoint != p_sys->i_chapter )
1341         {
1342             p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
1343             p_demux->info.i_seekpoint = p_sys->i_chapter;
1344         }
1345     }
1346 }
1347
1348 /*****************************************************************************
1349  * DemuxTitles: get the titles/chapters structure
1350  *****************************************************************************/
1351 static void DemuxTitles( demux_t *p_demux, int *pi_angle )
1352 {
1353     VLC_UNUSED( pi_angle );
1354
1355     demux_sys_t *p_sys = p_demux->p_sys;
1356     input_title_t *t;
1357     seekpoint_t *s;
1358
1359     /* Find out number of titles/chapters */
1360 #define tt_srpt p_sys->p_vmg_file->tt_srpt
1361
1362     int32_t i_titles = tt_srpt->nr_of_srpts;
1363     msg_Dbg( p_demux, "number of titles: %d", i_titles );
1364
1365     for( int i = 0; i < i_titles; i++ )
1366     {
1367         int32_t i_chapters = 0;
1368         int j;
1369
1370         i_chapters = tt_srpt->title[i].nr_of_ptts;
1371         msg_Dbg( p_demux, "title %d has %d chapters", i, i_chapters );
1372
1373         t = vlc_input_title_New();
1374
1375         for( j = 0; j < __MAX( i_chapters, 1 ); j++ )
1376         {
1377             s = vlc_seekpoint_New();
1378             TAB_APPEND( t->i_seekpoint, t->seekpoint, s );
1379         }
1380
1381         TAB_APPEND( p_sys->i_titles, p_sys->titles, t );
1382     }
1383
1384 #undef tt_srpt
1385 }