* ./modules/demux/mpeg/system.c: added a helper plugin for MPEG-related
[vlc.git] / modules / access / dvdread / input.c
1 /*****************************************************************************
2  * input.c: DvdRead plugin.
3  *****************************************************************************
4  * This plugins should handle all the known specificities of the DVD format,
5  * especially the 2048 bytes logical block size.
6  * It depends on: libdvdread for ifo files and block reading.
7  *****************************************************************************
8  * Copyright (C) 2001 VideoLAN
9  * $Id: input.c,v 1.2 2002/08/07 00:29:36 sam Exp $
10  *
11  * Author: St├ęphane Borel <stef@via.ecp.fr>
12  *
13  * Some code taken form the play_title.c by Billy Biggs <vektor@dumbterm.net>
14  * in libdvdread.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  * 
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
29  *****************************************************************************/
30
31 /*****************************************************************************
32  * Preamble
33  *****************************************************************************/
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #include <vlc/vlc.h>
38 #include <vlc/input.h>
39
40 #include "../../demux/mpeg/system.h"
41
42 #ifdef HAVE_UNISTD_H
43 #   include <unistd.h>
44 #endif
45
46 #include <fcntl.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <string.h>
50 #include <errno.h>
51 #include <assert.h>
52
53 #ifdef STRNCASECMP_IN_STRINGS_H
54 #   include <strings.h>
55 #endif
56
57 #if defined( WIN32 )
58 #   include <io.h>                                                 /* read() */
59 #else
60 #   include <sys/uio.h>                                      /* struct iovec */
61 #endif
62
63 #if defined( WIN32 )
64 #   include "input_iovec.h"
65 #endif
66
67 #include <dvdread/dvd_reader.h>
68 #include <dvdread/ifo_types.h>
69 #include <dvdread/ifo_read.h>
70 #include <dvdread/nav_read.h>
71 #include <dvdread/nav_print.h>
72
73 #include "input.h"
74
75 #include "iso_lang.h"
76
77 /* how many blocks DVDRead will read in each loop */
78 #define DVD_BLOCK_READ_ONCE 64
79
80 /*****************************************************************************
81  * Private structure
82  *****************************************************************************/
83 struct demux_sys_t
84 {
85     module_t *   p_module;
86     mpeg_demux_t mpeg;
87 };
88
89 /*****************************************************************************
90  * Local prototypes
91  *****************************************************************************/
92 /* called from outside */
93 static int  DvdReadDemux    ( input_thread_t * );
94 static int  DvdReadRewind   ( input_thread_t * );
95
96 static int  DvdReadSetArea    ( input_thread_t *, input_area_t * );
97 static int  DvdReadSetProgram ( input_thread_t *, pgrm_descriptor_t * );
98 static int  DvdReadRead       ( input_thread_t *, byte_t *, size_t );
99 static void DvdReadSeek       ( input_thread_t *, off_t );
100
101 /* called only from here */
102 static void DvdReadLauchDecoders( input_thread_t * p_input );
103 static void DvdReadHandleDSI( thread_dvd_data_t * p_dvd, u8 * p_data );
104 static void DvdReadFindCell ( thread_dvd_data_t * p_dvd );
105
106 /*
107  * Data demux functions
108  */
109
110 /*****************************************************************************
111  * InitDVD: initialize DVD structures
112  *****************************************************************************/
113 int E_(InitDVD) ( vlc_object_t *p_this )
114 {
115     input_thread_t *p_input = (input_thread_t *)p_this;
116     demux_sys_t *   p_demux;
117
118     if( p_input->stream.i_method != INPUT_METHOD_DVD )
119     {
120         return -1;
121     }
122
123     p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
124     if( p_demux == NULL )
125     {
126         return -1;
127     }
128
129     p_input->p_private = (void*)&p_demux->mpeg;
130     p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
131     if( p_demux->p_module == NULL )
132     {
133         free( p_input->p_demux_data );
134         return -1;
135     }
136
137     p_input->pf_demux = DvdReadDemux;
138     p_input->pf_rewind = NULL;
139
140     vlc_mutex_lock( &p_input->stream.stream_lock );
141     
142     DvdReadLauchDecoders( p_input );
143     
144     vlc_mutex_unlock( &p_input->stream.stream_lock );
145
146     return 0;
147 }
148
149 /*****************************************************************************
150  * EndDVD: end DVD structures
151  *****************************************************************************/
152 void E_(EndDVD) ( vlc_object_t *p_this )
153 {
154     input_thread_t *p_input = (input_thread_t *)p_this;
155
156     module_Unneed( p_input, p_input->p_demux_data->p_module );
157     free( p_input->p_demux_data );
158 }
159
160 /*****************************************************************************
161  * DvdReadDemux
162  *****************************************************************************/
163 #define PEEK( SIZE )                                                        \
164     i_result = input_Peek( p_input, &p_peek, SIZE );                        \
165     if( i_result == -1 )                                                    \
166     {                                                                       \
167         return( -1 );                                                       \
168     }                                                                       \
169     else if( i_result < SIZE )                                              \
170     {                                                                       \
171         /* EOF */                                                           \
172         return( 0 );                                                        \
173     }
174
175 static int DvdReadDemux( input_thread_t * p_input )
176 {
177     int                 i;
178     byte_t *            p_peek;
179     data_packet_t *     p_data;
180     ssize_t             i_result;
181     int                 i_packet_size;
182
183
184     /* Read headers to compute payload length */
185     for( i = 0 ; i < DVD_BLOCK_READ_ONCE ; i++ )
186     {
187
188         /* Read what we believe to be a packet header. */
189         PEEK( 4 );
190             
191         /* Default header */ 
192         if( U32_AT( p_peek ) != 0x1BA )
193         {
194             /* That's the case for all packets, except pack header. */
195             i_packet_size = U16_AT( p_peek + 4 );
196         }
197         else
198         {
199             /* MPEG-2 Pack header. */
200             i_packet_size = 8;
201         }
202
203         /* Fetch a packet of the appropriate size. */
204         i_result = input_SplitBuffer( p_input, &p_data, i_packet_size + 6 );
205         if( i_result <= 0 )
206         {
207             return( i_result );
208         }
209
210         /* In MPEG-2 pack headers we still have to read stuffing bytes. */
211         if( (p_data->p_demux_start[3] == 0xBA) && (i_packet_size == 8) )
212         {
213             size_t i_stuffing = (p_data->p_demux_start[13] & 0x7);
214             /* Force refill of the input buffer - though we don't care
215              * about p_peek. Please note that this is unoptimized. */
216             PEEK( i_stuffing );
217             p_input->p_current_data += i_stuffing;
218         }
219
220         p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );
221      
222     }
223
224     return i;
225 }
226
227 /*****************************************************************************
228  * DVDRewind : reads a stream backward
229  *****************************************************************************/
230 static int DvdReadRewind( input_thread_t * p_input )
231 {
232     return( -1 );
233 }
234
235 /*
236  * Data access functions
237  */
238
239 /*****************************************************************************
240  * OpenDVD: open libdvdread
241  *****************************************************************************/
242 int E_(OpenDVD) ( vlc_object_t *p_this )
243 {
244     input_thread_t *        p_input = (input_thread_t *)p_this;
245     char *                  psz_orig;
246     char *                  psz_parser;
247     char *                  psz_source;
248     char *                  psz_next;
249     struct stat             stat_info;
250     thread_dvd_data_t *     p_dvd;
251     dvd_reader_t *          p_dvdread;
252     input_area_t *          p_area;
253     int                     i_title = 1;
254     int                     i_chapter = 1;
255     int                     i_angle = 1;
256     int                     i;
257
258     psz_orig = psz_parser = psz_source = strdup( p_input->psz_name );
259     if( !psz_orig )
260     {
261         return( -1 );
262     }
263
264     p_input->pf_read = DvdReadRead;
265     p_input->pf_seek = DvdReadSeek;
266     p_input->pf_set_area = DvdReadSetArea;
267     p_input->pf_set_program = DvdReadSetProgram;
268
269     while( *psz_parser && *psz_parser != '@' )
270     {
271         psz_parser++;
272     }
273
274     if( *psz_parser == '@' )
275     {
276         /* Found options */
277         *psz_parser = '\0';
278         ++psz_parser;
279
280         i_title = (int)strtol( psz_parser, &psz_next, 10 );
281         if( *psz_next )
282         {
283             psz_parser = psz_next + 1;
284             i_chapter = (int)strtol( psz_parser, &psz_next, 10 );
285             if( *psz_next )
286             {
287                 i_angle = (int)strtol( psz_next + 1, NULL, 10 );
288             }
289         }
290
291         i_title = i_title ? i_title : 1;
292         i_chapter = i_chapter ? i_chapter : 1;
293         i_angle = i_angle ? i_angle : 1;
294     }
295
296     if( !*psz_source )
297     {
298         if( !p_input->psz_access )
299         {
300             free( psz_orig );
301             return -1;
302         }
303         psz_source = config_GetPsz( p_input, "dvd" );
304     }
305
306     if( stat( psz_source, &stat_info ) == -1 )
307     {
308         msg_Err( p_input, "cannot stat() source `%s' (%s)",
309                           psz_source, strerror(errno));
310         return( -1 );
311     }
312     if( !S_ISBLK(stat_info.st_mode) &&
313         !S_ISCHR(stat_info.st_mode) &&
314         !S_ISDIR(stat_info.st_mode) )
315     {
316         msg_Warn( p_input, "dvdread module discarded (not a valid source)" );
317         return -1;
318     }
319     
320     msg_Dbg( p_input, "dvdroot=%s title=%d chapter=%d angle=%d",
321                       psz_source, i_title, i_chapter, i_angle );
322     
323
324     p_dvdread = DVDOpen( psz_source );
325
326     /* free allocated strings */
327     if( psz_source != psz_orig )
328         free( psz_source );
329     free( psz_orig );
330
331     if( ! p_dvdread )
332     {
333         msg_Err( p_input, "libdvdcss cannot open source" );
334         return -1;
335     }
336
337     /* set up input  */
338     p_input->i_mtu = 0;
339
340     p_dvd = malloc( sizeof(thread_dvd_data_t) );
341     if( p_dvd == NULL )
342     {
343         msg_Err( p_input, "out of memory" );
344         return -1;
345     }
346
347     p_dvd->p_dvdread = p_dvdread;
348     p_dvd->p_title = NULL;
349     p_dvd->p_vts_file = NULL;
350
351
352     p_input->p_access_data = (void *)p_dvd;
353
354     /* Ifo allocation & initialisation */
355     if( ! ( p_dvd->p_vmg_file = ifoOpen( p_dvd->p_dvdread, 0 ) ) )
356     {
357         msg_Err( p_input, "cannot open VMG info" );
358         free( p_dvd );
359         return -1;
360     }
361     msg_Dbg( p_input, "VMG opened" );
362
363     /* Set stream and area data */
364     vlc_mutex_lock( &p_input->stream.stream_lock );
365
366     p_input->stream.i_method = INPUT_METHOD_DVD;
367
368     /* If we are here we can control the pace... */
369     p_input->stream.b_pace_control = 1;
370     p_input->stream.b_seekable = 1;
371     
372     p_input->stream.p_selected_area->i_size = 0;
373     p_input->stream.p_selected_area->i_tell = 0;
374
375     /* Initialize ES structures */
376     input_InitStream( p_input, sizeof( stream_ps_data_t ) );
377
378     /* disc input method */
379     p_input->stream.i_method = INPUT_METHOD_DVD;
380
381 #define tt_srpt p_dvd->p_vmg_file->tt_srpt
382     msg_Dbg( p_input, "number of titles: %d", tt_srpt->nr_of_srpts );
383
384 #define area p_input->stream.pp_areas
385     /* We start from 1 here since the default area 0
386      * is reserved for video_ts.vob */
387     for( i = 1 ; i <= tt_srpt->nr_of_srpts ; i++ )
388     {
389         input_AddArea( p_input );
390
391         /* Titles are Program Chains */
392         area[i]->i_id = i;
393
394         /* Absolute start offset and size
395          * We can only set that with vts ifo, so we do it during the
396          * first call to DVDSetArea */
397         area[i]->i_start = 0;
398         area[i]->i_size = 0;
399
400         /* Number of chapters */
401         area[i]->i_part_nb = tt_srpt->title[i-1].nr_of_ptts;
402         area[i]->i_part = 1;
403
404         area[i]->i_plugin_data = tt_srpt->title[i-1].title_set_nr;
405     }
406 #undef area
407
408     p_dvd->i_title = i_title <= tt_srpt->nr_of_srpts ? i_title : 1;
409 #undef tt_srpt
410
411     p_area = p_input->stream.pp_areas[p_dvd->i_title];
412     p_dvd->i_chapter = i_chapter;
413
414     p_dvd->i_chapter = i_chapter < p_area->i_part_nb ? i_chapter : 1;
415     p_area->i_part = p_dvd->i_chapter;
416     
417     p_dvd->i_angle = i_angle;
418
419     /* set title, chapter, audio and subpic */
420     if( DvdReadSetArea( p_input, p_area ) )
421     {
422         vlc_mutex_unlock( &p_input->stream.stream_lock );
423         return -1;
424     }
425
426     vlc_mutex_unlock( &p_input->stream.stream_lock );
427
428     p_input->psz_demux = "dvdread";
429
430     return 0;
431 }
432
433 /*****************************************************************************
434  * CloseDVD: close libdvdread
435  *****************************************************************************/
436 void E_(CloseDVD) ( vlc_object_t *p_this )
437 {
438     input_thread_t *    p_input = (input_thread_t *)p_this;
439     thread_dvd_data_t * p_dvd = (thread_dvd_data_t *)p_input->p_access_data;
440
441     /* close libdvdread */
442     DVDCloseFile( p_dvd->p_title );
443     ifoClose( p_dvd->p_vts_file );
444     ifoClose( p_dvd->p_vmg_file );
445
446     DVDClose( p_dvd->p_dvdread );
447     free( p_dvd );
448     p_input->p_access_data = NULL;
449
450 }
451
452 /*****************************************************************************
453  * DvdReadSetProgram: Does nothing, a DVD is mono-program
454  *****************************************************************************/
455 static int DvdReadSetProgram( input_thread_t * p_input,
456                               pgrm_descriptor_t * p_program )
457 {
458     if( p_input->stream.p_selected_program != p_program )
459     {
460         thread_dvd_data_t *  p_dvd;
461     
462         p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
463         p_dvd->i_angle = p_program->i_number;
464
465         memcpy( p_program, p_input->stream.p_selected_program,
466                 sizeof(pgrm_descriptor_t) );
467         p_program->i_number = p_dvd->i_angle;
468         p_input->stream.p_selected_program = p_program;
469
470         msg_Dbg( p_input, "angle %d selected", p_dvd->i_angle );
471     }
472
473     return 0;
474 }
475
476 #define p_pgc         p_dvd->p_cur_pgc
477
478 /*****************************************************************************
479  * DvdReadSetArea: initialize input data for title x, chapter y.
480  * It should be called for each user navigation request.
481  *****************************************************************************
482  * Take care that i_title starts from 0 (vmg) and i_chapter start from 1.
483  * Note that you have to take the lock before entering here.
484  *****************************************************************************/
485 static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
486 {
487     thread_dvd_data_t *  p_dvd;
488     int                  pgc_id = 0;
489     int                  pgn = 0;
490
491     p_dvd = (thread_dvd_data_t*)p_input->p_access_data;
492
493     /* we can't use the interface slider until initilization is complete */
494     p_input->stream.b_seekable = 0;
495
496     if( p_area != p_input->stream.p_selected_area )
497     {
498         es_descriptor_t *    p_es;
499         int                  i_cell = 0;
500         int                  i_audio_nb = 0;
501         int                  i_spu_nb = 0;
502         int                  i;
503
504 #define p_vmg         p_dvd->p_vmg_file
505 #define p_vts         p_dvd->p_vts_file
506         if( p_dvd->p_title != NULL )
507         {
508             DVDCloseFile( p_dvd->p_title );
509         }
510
511         if( p_vts != NULL )
512         {
513             ifoClose( p_vts );
514         }
515
516         /* Reset the Chapter position of the old title */
517         p_input->stream.p_selected_area->i_part = 1;
518
519         /*
520          *  We have to load all title information
521          */
522         /* Change the default area */
523         p_input->stream.p_selected_area = p_area;
524
525         msg_Dbg( p_input, "open VTS %d, for title %d",
526             p_vmg->tt_srpt->title[ p_area->i_id - 1 ].title_set_nr,
527             p_area->i_id );
528
529         /* ifo vts */
530         if( ! ( p_vts = ifoOpen( p_dvd->p_dvdread,
531                 p_vmg->tt_srpt->title[ p_area->i_id - 1 ].title_set_nr ) ) )
532         {
533             msg_Err( p_input, "fatal error in vts ifo" );
534             ifoClose( p_vmg );
535             DVDClose( p_dvd->p_dvdread );
536             return -1;
537         }
538
539         /* title position inside the selected vts */
540         p_dvd->i_ttn = p_vmg->tt_srpt->title[ p_area->i_id - 1 ].vts_ttn;
541
542         /*
543          * Set selected title start
544          */
545         pgc_id = p_vts->vts_ptt_srpt->title[p_dvd->i_ttn-1].ptt[0].pgcn;
546         pgn = p_vts->vts_ptt_srpt->title[p_dvd->i_ttn-1].ptt[0].pgn;
547         p_pgc = p_vts->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc;
548         i_cell = p_pgc->program_map[ pgn - 1 ] - 1;
549
550         p_area->i_start =
551             LB2OFF( p_dvd->p_cur_pgc->cell_playback[ i_cell ].first_sector );
552
553         msg_Dbg( p_input, "start %d vts_title %d pgc %d pgn %d",
554                   p_area->i_id, p_dvd->i_ttn, pgc_id, pgn );
555
556         /*
557          * Find title end
558          */
559         i_cell = p_dvd->p_cur_pgc->nr_of_cells - 1;
560
561         p_dvd->i_end_block = p_pgc->cell_playback[ i_cell ].last_sector;
562         p_area->i_size = LB2OFF( p_dvd->i_end_block )- p_area->i_start;
563
564         msg_Dbg( p_input, "start %lld size %lld end %d",
565                   p_area->i_start , p_area->i_size, p_dvd->i_end_block );
566
567         /*
568          * Set properties for current chapter
569          */
570         /* Remeber current chapter */
571         p_dvd->i_chapter = p_area->i_part;
572         p_dvd->b_eoc = 0;
573
574         pgc_id = p_vts->vts_ptt_srpt->title[
575                     p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgcn;
576         pgn = p_vts->vts_ptt_srpt->title[
577                     p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgn;
578
579         p_pgc = p_vts->vts_pgcit->pgci_srp[pgc_id-1].pgc;
580         p_dvd->i_pack_len = 0;
581         p_dvd->i_next_cell = p_dvd->i_cur_cell = p_pgc->program_map[pgn-1] - 1;
582         DvdReadFindCell( p_dvd );
583
584         p_dvd->i_next_vobu = p_dvd->i_cur_block =
585             p_pgc->cell_playback[p_dvd->i_cur_cell].first_sector;
586
587         /*
588          * Angle management
589          */
590         p_dvd->i_angle_nb = p_vmg->tt_srpt->title[p_area->i_id-1].nr_of_angles;
591
592         if( p_dvd->i_angle > p_dvd->i_angle_nb )
593         {
594             p_dvd->i_angle = 1;
595         }
596
597         /*
598          * We've got enough info, time to open the title set data.
599          */
600         if( ! ( p_dvd->p_title = DVDOpenFile( p_dvd->p_dvdread,
601             p_vmg->tt_srpt->title[ p_area->i_id - 1 ].title_set_nr,
602             DVD_READ_TITLE_VOBS ) ) )
603         {
604             msg_Err( p_input, "cannot open title (VTS_%02d_1.VOB)",
605                      p_vmg->tt_srpt->title[p_area->i_id-1].title_set_nr );
606             ifoClose( p_vts );
607             ifoClose( p_vmg );
608             DVDClose( p_dvd->p_dvdread );
609             return -1;
610         }
611
612 //        IfoPrintTitle( p_dvd );
613
614         /*
615          * Destroy obsolete ES by reinitializing program 0
616          * and find all ES in title with ifo data
617          */
618         if( p_input->stream.pp_programs != NULL )
619         {
620             /* We don't use input_EndStream here since
621              * we keep area structures */
622
623             while( p_input->stream.i_es_number )
624             {
625                 input_DelES( p_input, p_input->stream.pp_es[0] );
626             }
627
628             while( p_input->stream.i_pgrm_number )
629             {
630                 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
631             }
632
633             if( p_input->stream.pp_selected_es )
634             {
635                 free( p_input->stream.pp_selected_es );
636                 p_input->stream.pp_selected_es = NULL;
637             }
638             p_input->stream.i_selected_es_number = 0;
639         }
640
641         input_AddProgram( p_input, 1, sizeof( stream_ps_data_t ) );
642         p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
643
644         for( i = 1 ; i < p_dvd->i_angle_nb ; i++ )
645         {
646             input_AddProgram( p_input, i+1, 0 );
647         }
648         
649         DvdReadSetProgram( p_input,
650                            p_input->stream.pp_programs[p_dvd->i_angle-1] ); 
651
652         /* No PSM to read in DVD mode, we already have all information */
653         p_input->stream.p_selected_program->b_is_ok = 1;
654
655         p_es = NULL;
656
657         /* ES 0 -> video MPEG2 */
658 //        IfoPrintVideo( p_dvd );
659
660         p_es = input_AddES( p_input, NULL, 0xe0, 0 );
661         p_es->i_stream_id = 0xe0;
662         p_es->i_fourcc = VLC_FOURCC('m','p','g','v');
663         p_es->i_cat = VIDEO_ES;
664
665 #define audio_control \
666     p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->audio_control[i-1]
667         /* Audio ES, in the order they appear in .ifo */
668         for( i = 1 ; i <= p_vts->vtsi_mat->nr_of_vts_audio_streams ; i++ )
669         {
670             int i_position = 0;
671             u16 i_id;
672
673 //            IfoPrintAudio( p_dvd, i );
674
675             /* audio channel is active if first byte is 0x80 */
676             if( audio_control & 0x8000 )
677             {
678                 i_audio_nb++;
679                 i_position = ( audio_control & 0x7F00 ) >> 8;
680
681             msg_Dbg( p_input, "audio position  %d", i_position );
682                 switch( p_vts->vtsi_mat->vts_audio_attr[i-1].audio_format )
683                 {
684                 case 0x00:              /* A52 */
685                     i_id = ( ( 0x80 + i_position ) << 8 ) | 0xbd;
686                     p_es = input_AddES( p_input, NULL, i_id, 0 );
687                     p_es->i_stream_id = 0xbd;
688                     p_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
689                     p_es->i_cat = AUDIO_ES;
690                     strcpy( p_es->psz_desc, DecodeLanguage(
691                         p_vts->vtsi_mat->vts_audio_attr[i-1].lang_code ) ); 
692                     strcat( p_es->psz_desc, " (A52)" );
693
694                     break;
695                 case 0x02:
696                 case 0x03:              /* MPEG audio */
697                     i_id = 0xc0 + i_position;
698                     p_es = input_AddES( p_input, NULL, i_id, 0 );
699                     p_es->i_stream_id = i_id;
700                     p_es->i_fourcc = VLC_FOURCC('m','p','g','a');
701                     p_es->i_cat = AUDIO_ES;
702                     strcpy( p_es->psz_desc, DecodeLanguage(
703                         p_vts->vtsi_mat->vts_audio_attr[i-1].lang_code ) ); 
704                     strcat( p_es->psz_desc, " (mpeg)" );
705
706                     break;
707                 case 0x04:              /* LPCM */
708
709                     i_id = ( ( 0xa0 + i_position ) << 8 ) | 0xbd;
710                     p_es = input_AddES( p_input, NULL, i_id, 0 );
711                     p_es->i_stream_id = i_id;
712                     p_es->i_fourcc = VLC_FOURCC('l','p','c','m');
713                     p_es->i_cat = AUDIO_ES;
714                     strcpy( p_es->psz_desc, DecodeLanguage(
715                         p_vts->vtsi_mat->vts_audio_attr[i-1].lang_code ) ); 
716                     strcat( p_es->psz_desc, " (lpcm)" );
717
718                     break;
719                 case 0x06:              /* DTS */
720                     i_id = ( ( 0x88 + i_position ) << 8 ) | 0xbd;
721                     msg_Err( p_input, "DTS audio not handled yet"
722                                       "(0x%x)", i_id );
723                     break;
724                 default:
725                     i_id = 0;
726                     msg_Err( p_input, "unknown audio type %.2x",
727                           p_vts->vtsi_mat->vts_audio_attr[i-1].audio_format );
728                 }
729             }
730         }
731 #undef audio_control
732 #define spu_control \
733     p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc->subp_control[i-1]
734
735         /* Sub Picture ES */
736
737         for( i = 1 ; i <= p_vts->vtsi_mat->nr_of_vts_subp_streams; i++ )
738         {
739             int i_position = 0;
740             u16 i_id;
741
742 //            IfoPrintSpu( p_dvd, i );
743             msg_Dbg( p_input, "spu %d 0x%02x", i, spu_control );
744
745             if( spu_control & 0x80000000 )
746             {
747                 i_spu_nb++;
748
749                 /*  there are several streams for one spu */
750                 if(  p_vts->vtsi_mat->vts_video_attr.display_aspect_ratio )
751                 {
752                     /* 16:9 */
753                     switch( p_vts->vtsi_mat->vts_video_attr.permitted_df )
754                     {
755                     case 1:
756                         i_position = spu_control & 0xff;
757                         break;
758                     case 2:
759                         i_position = ( spu_control >> 8 ) & 0xff;
760                         break;
761                     default:
762                         i_position = ( spu_control >> 16 ) & 0xff;
763                         break;
764                     }
765                 }
766                 else
767                 {
768                     /* 4:3 */
769                     i_position = ( spu_control >> 24 ) & 0x7F;
770                 }
771
772                 i_id = ( ( 0x20 + i_position ) << 8 ) | 0xbd;
773                 p_es = input_AddES( p_input, NULL, i_id, 0 );
774                 p_es->i_stream_id = 0xbd;
775                 p_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
776                 p_es->i_cat = SPU_ES;
777                 strcpy( p_es->psz_desc, DecodeLanguage(
778                     p_vts->vtsi_mat->vts_subp_attr[i-1].lang_code ) ); 
779             }
780         }
781 #undef spu_control
782
783         /* FIXME: hack to check that the demuxer is ready, and set
784          * the decoders */
785         if( p_input->p_demux )
786         {
787             DvdReadLauchDecoders( p_input );
788         }
789             
790     } /* i_title >= 0 */
791     else
792     {
793         p_area = p_input->stream.p_selected_area;
794     }
795
796     /*
797      * Chapter selection
798      */
799
800     if( p_area->i_part != p_dvd->i_chapter )
801     {
802         if( ( p_area->i_part > 0 ) &&
803             ( p_area->i_part <= p_area->i_part_nb ))
804         {
805             p_dvd->i_ttn = p_vmg->tt_srpt->title[p_area->i_id-1].vts_ttn;
806             pgc_id = p_vts->vts_ptt_srpt->title[
807                         p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgcn;
808             pgn = p_vts->vts_ptt_srpt->title[
809                         p_dvd->i_ttn-1].ptt[p_area->i_part-1].pgn;
810
811             p_pgc = p_vts->vts_pgcit->pgci_srp[ pgc_id - 1 ].pgc;
812
813             p_dvd->i_cur_cell = p_pgc->program_map[ pgn - 1 ] - 1;
814             p_dvd->i_chapter = p_area->i_part;
815             DvdReadFindCell( p_dvd );
816
817             p_dvd->i_pack_len = 0;
818             p_dvd->i_next_vobu = p_dvd->i_cur_block =
819                     p_pgc->cell_playback[p_dvd->i_cur_cell].first_sector;
820         }
821         else
822         {
823             p_area->i_part = p_dvd->i_chapter;
824         }
825     }
826 #undef p_vts
827 #undef p_vmg
828
829     /* warn interface that something has changed */
830     p_area->i_tell = LB2OFF( p_dvd->i_next_vobu ) - p_area->i_start;
831     p_input->stream.b_seekable = 1;
832     p_input->stream.b_changed = 1;
833
834     return 0;
835 }
836
837
838 /*****************************************************************************
839  * DvdReadRead: reads data packets into the netlist.
840  *****************************************************************************
841  * Returns -1 in case of error, 0 if everything went well, and 1 in case of
842  * EOF.
843  *****************************************************************************/
844 static int DvdReadRead( input_thread_t * p_input,
845                         byte_t * p_buffer, size_t i_count )
846 {
847     thread_dvd_data_t *     p_dvd;
848     byte_t *                p_buf;
849     int                     i_blocks_once;
850     int                     i_blocks;
851     int                     i_read;
852     int                     i_read_total;
853     vlc_bool_t              b_eot = 0;
854
855     p_dvd = (thread_dvd_data_t *)p_input->p_access_data;
856     p_buf = p_buffer;
857
858     /*
859      * Playback by cell in this pgc, starting at the cell for our chapter.
860      */
861     i_blocks = OFF2LB( i_count );
862     i_read_total = 0;
863     i_read = 0;
864
865     while( i_blocks )
866     {
867         /* 
868          * End of pack, we select the following one
869          */
870         if( ! p_dvd->i_pack_len )
871         {
872             /*
873              * Read NAV packet.
874              */
875             if( ( i_read = DVDReadBlocks( p_dvd->p_title, p_dvd->i_next_vobu,
876                            1, p_buf ) ) != 1 )
877             {
878                 msg_Err( p_input, "read failed for block %d",
879                                   p_dvd->i_next_vobu );
880                 return -1;
881             }
882
883             /* basic check to be sure we don't have a empty title
884              * go to next title if so */
885             //assert( p_buffer[41] == 0xbf && p_buffer[1027] == 0xbf );
886             
887             /*
888              * Parse the contained dsi packet.
889              */
890
891             DvdReadHandleDSI( p_dvd, p_buf );
892
893             /* End of File */
894             if( p_dvd->i_next_vobu >= p_dvd->i_end_block + 1 )
895             {
896                 return 1;
897             }
898
899             assert( p_dvd->i_pack_len < 1024 );
900             /* FIXME: Ugly kludge: we send the pack block to the input for it
901              * sometimes has a zero scr and restart the sync */
902             p_dvd->i_cur_block ++;
903             //p_dvd->i_pack_len++;
904
905             i_read_total++;
906             p_buf += DVD_VIDEO_LB_LEN;
907             i_blocks--;
908         }
909
910         /*
911          * Compute the number of blocks to read
912          */
913         i_blocks_once = p_dvd->i_pack_len >= i_blocks
914                  ? i_blocks : p_dvd->i_pack_len;
915         p_dvd->i_pack_len -= i_blocks_once;
916
917         /* Reads from DVD */
918         i_read = DVDReadBlocks( p_dvd->p_title, p_dvd->i_cur_block,
919                                 i_blocks_once, p_buf );
920         if( i_read != i_blocks_once )
921         {
922             msg_Err( p_input, "read failed for %d/%d blocks at 0x%02x",
923                               i_read, i_blocks_once, p_dvd->i_cur_block );
924             return -1;
925         }
926
927         i_blocks -= i_read;
928         i_read_total += i_read;
929         p_dvd->i_cur_block += i_read;
930         p_buf += LB2OFF( i_read );
931
932     }
933 /*
934     msg_Dbg( p_input, "i_blocks: %d len: %d current: 0x%02x", i_read, p_dvd->i_pack_len, p_dvd->i_cur_block );
935 */
936
937     vlc_mutex_lock( &p_input->stream.stream_lock );
938
939     p_input->stream.p_selected_area->i_tell =
940         LB2OFF( p_dvd->i_cur_block ) -
941             p_input->stream.p_selected_area->i_start;
942
943     if( p_dvd->b_eoc )
944     {
945         /* We modify i_part only at end of chapter not to erase
946          * some modification from the interface */
947         p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
948         p_dvd->b_eoc = 0;
949     }
950     
951     if( p_input->stream.p_selected_area->i_tell
952             >= p_input->stream.p_selected_area->i_size || b_eot )
953     {
954         if( ( p_input->stream.p_selected_area->i_id + 1 ) >= 
955                         p_input->stream.i_area_nb )
956         {
957             /* EOF */
958             vlc_mutex_unlock( &p_input->stream.stream_lock );
959             return 1;
960         }
961
962         /* EOT */
963         msg_Dbg( p_input, "new title" );
964         DvdReadSetArea( p_input, p_input->stream.pp_areas[
965                         p_input->stream.p_selected_area->i_id+1] );
966         vlc_mutex_unlock( &p_input->stream.stream_lock );
967         return 0;
968     }
969
970     vlc_mutex_unlock( &p_input->stream.stream_lock );
971
972     return LB2OFF( i_read_total );
973 }
974 #undef p_pgc
975
976 /*****************************************************************************
977  * DvdReadSeek : Goes to a given position on the stream.
978  *****************************************************************************
979  * This one is used by the input and translate chronological position from
980  * input to logical position on the device.
981  * The lock should be taken before calling this function.
982  *****************************************************************************/
983 static void DvdReadSeek( input_thread_t * p_input, off_t i_off )
984 {
985     thread_dvd_data_t *     p_dvd;
986     int                     i_lb;
987     int                     i_tmp;
988     int                     i_chapter = 0;
989     int                     i_cell = 0;
990     int                     i_vobu = 0;
991     int                     i_sub_cell = 0;
992
993     vlc_mutex_lock( &p_input->stream.stream_lock );
994     i_off += p_input->stream.p_selected_area->i_start;
995     vlc_mutex_unlock( &p_input->stream.stream_lock );
996     
997     i_lb = OFF2LB( i_off );
998     p_dvd = ( thread_dvd_data_t * )p_input->p_access_data;
999
1000     /* find cell */
1001     while( p_dvd->p_cur_pgc->cell_playback[i_cell].last_sector < i_lb )
1002     {
1003         i_cell++;
1004     }
1005
1006     /* find chapter */
1007     do
1008     {
1009         pgc_t *     p_pgc;
1010         int         pgc_id, pgn;
1011
1012         i_chapter++;
1013         pgc_id = p_dvd->p_vts_file->vts_ptt_srpt->title[
1014                     p_dvd->i_ttn-1].ptt[i_chapter-1].pgcn;
1015         pgn = p_dvd->p_vts_file->vts_ptt_srpt->title[
1016                     p_dvd->i_ttn-1].ptt[i_chapter-1].pgn;
1017
1018         p_pgc = p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;
1019         i_tmp = p_pgc->program_map[pgn-1];
1020
1021     } while( i_tmp <= i_cell );
1022
1023     /* find vobu */
1024     while( p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu]
1025             <= i_lb )
1026     {
1027         i_vobu++;
1028     }
1029
1030     /* find sub_cell */
1031     while( p_dvd->p_vts_file->vts_c_adt->cell_adr_table[i_sub_cell].start_sector <
1032             p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu-1] )
1033     {
1034         i_sub_cell++;
1035     }
1036
1037 /*
1038     msg_Dbg( p_input, "cell %d i_sub_cell %d chapter %d vobu %d cell_sector %d vobu_sector %d sub_cell_sector %d",
1039             i_cell, i_sub_cell,i_chapter, i_vobu,
1040             p_dvd->p_cur_pgc->cell_playback[i_cell].first_sector,
1041             p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu],
1042             p_dvd->p_vts_file->vts_c_adt->cell_adr_table[i_sub_cell-1].start_sector);
1043 */
1044     p_dvd->i_cur_block = i_lb;
1045     p_dvd->i_next_vobu =
1046         p_dvd->p_vts_file->vts_vobu_admap->vobu_start_sectors[i_vobu];
1047     p_dvd->i_pack_len = p_dvd->i_next_vobu - i_lb;
1048     p_dvd->i_cur_cell = i_cell;
1049     p_dvd->i_chapter = i_chapter;
1050     DvdReadFindCell( p_dvd );
1051
1052     vlc_mutex_lock( &p_input->stream.stream_lock );
1053     p_input->stream.p_selected_area->i_tell =
1054         LB2OFF ( p_dvd->i_cur_block )
1055          - p_input->stream.p_selected_area->i_start;
1056     p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
1057     vlc_mutex_unlock( &p_input->stream.stream_lock );
1058
1059     return;
1060 }
1061
1062 /*****************************************************************************
1063  * DvdReadHandleDSI
1064  *****************************************************************************/
1065 static void DvdReadHandleDSI( thread_dvd_data_t * p_dvd, u8 * p_data )
1066 {
1067     navRead_DSI( &(p_dvd->dsi_pack), &(p_data[ DSI_START_BYTE ]) );
1068
1069     /*
1070      * Determine where we go next.  These values are the ones we mostly
1071      * care about.
1072      */
1073     p_dvd->i_cur_block = p_dvd->dsi_pack.dsi_gi.nv_pck_lbn;
1074
1075     /*
1076      * If we're not at the end of this cell, we can determine the next
1077      * VOBU to display using the VOBU_SRI information section of the
1078      * DSI.  Using this value correctly follows the current angle,
1079      * avoiding the doubled scenes in The Matrix, and makes our life
1080      * really happy.
1081      */
1082     if( p_dvd->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL )
1083     {
1084 #if 1
1085         switch( ( p_dvd->dsi_pack.sml_pbi.category & 0xf000 ) >> 12 )
1086         {
1087             case 0x4:
1088                 /* interleaved unit with no angle */
1089                 if( p_dvd->dsi_pack.sml_pbi.ilvu_sa != -1 )
1090                 {
1091                     p_dvd->i_next_vobu = p_dvd->i_cur_block +
1092                         p_dvd->dsi_pack.sml_pbi.ilvu_sa;
1093                     p_dvd->i_pack_len = p_dvd->dsi_pack.sml_pbi.ilvu_ea;
1094                 }
1095                 else
1096                 {
1097                     p_dvd->i_next_vobu = p_dvd->i_cur_block +
1098                         p_dvd->dsi_pack.dsi_gi.vobu_ea + 1;
1099                     p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;
1100                 }
1101                 break;
1102             case 0x5:
1103                 /* vobu is end of ilvu */
1104                 if( p_dvd->dsi_pack.sml_agli.data[p_dvd->i_angle-1].address )
1105                 {
1106                     p_dvd->i_next_vobu = p_dvd->i_cur_block +
1107                         p_dvd->dsi_pack.sml_agli.data[p_dvd->i_angle-1].address;
1108                     p_dvd->i_pack_len = p_dvd->dsi_pack.sml_pbi.ilvu_ea;
1109
1110                     break;
1111                 }
1112             case 0x6:
1113                 /* vobu is beginning of ilvu */
1114             case 0x9:
1115                 /* next scr is 0 */
1116             case 0xa:
1117                 /* entering interleaved section */
1118             case 0x8:
1119                 /* non interleaved cells in interleaved section */
1120             default:
1121                 p_dvd->i_next_vobu = p_dvd->i_cur_block +
1122                     ( p_dvd->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
1123                 p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;
1124                 break;
1125         }
1126 #else
1127         p_dvd->i_next_vobu = p_dvd->i_cur_block +
1128             ( p_dvd->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
1129         p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;
1130 #endif
1131     }
1132     else
1133     {
1134         p_dvd->i_cur_cell = p_dvd->i_next_cell;
1135         DvdReadFindCell( p_dvd );
1136
1137         p_dvd->i_pack_len = p_dvd->dsi_pack.dsi_gi.vobu_ea;
1138         p_dvd->i_next_vobu =
1139             p_dvd->p_cur_pgc->cell_playback[p_dvd->i_cur_cell].first_sector;
1140     }
1141
1142 #if 0
1143     msg_Dbg( p_input, 12, "scr %d lbn 0x%02x vobu_ea %d vob_id %d c_id %d",
1144              p_dvd->dsi_pack.dsi_gi.nv_pck_scr,
1145              p_dvd->dsi_pack.dsi_gi.nv_pck_lbn,
1146              p_dvd->dsi_pack.dsi_gi.vobu_ea,
1147              p_dvd->dsi_pack.dsi_gi.vobu_vob_idn,
1148              p_dvd->dsi_pack.dsi_gi.vobu_c_idn );
1149
1150     msg_Dbg( p_input, 12, "cat 0x%02x ilvu_ea %d ilvu_sa %d size %d", 
1151              p_dvd->dsi_pack.sml_pbi.category,
1152              p_dvd->dsi_pack.sml_pbi.ilvu_ea,
1153              p_dvd->dsi_pack.sml_pbi.ilvu_sa,
1154              p_dvd->dsi_pack.sml_pbi.size );
1155
1156     msg_Dbg( p_input, 12, "next_vobu %d next_ilvu1 %d next_ilvu2 %d",
1157              p_dvd->dsi_pack.vobu_sri.next_vobu & 0x7fffffff,
1158              p_dvd->dsi_pack.sml_agli.data[ p_dvd->i_angle - 1 ].address,
1159              p_dvd->dsi_pack.sml_agli.data[ p_dvd->i_angle ].address);
1160 #endif
1161 }
1162
1163 /*****************************************************************************
1164  * DvdReadFindCell
1165  *****************************************************************************/
1166 static void DvdReadFindCell( thread_dvd_data_t * p_dvd )
1167 {
1168     int         pgc_id, pgn;
1169     int         i = 0;
1170     pgc_t *     p_pgc;
1171 #define cell p_dvd->p_cur_pgc->cell_playback
1172     if( cell[p_dvd->i_cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK )
1173     {
1174 #if 0
1175         p_dvd->i_next_cell = p_dvd->i_cur_cell + p_dvd->i_angle_nb;
1176         p_dvd->i_cur_cell += p_dvd->i_angle - 1;
1177 #else
1178         p_dvd->i_cur_cell += p_dvd->i_angle - 1;
1179
1180         while( cell[p_dvd->i_cur_cell+i].block_mode != BLOCK_MODE_LAST_CELL )
1181         {
1182             i++;
1183         }
1184         p_dvd->i_next_cell = p_dvd->i_cur_cell + i + 1;
1185 #endif
1186     }
1187     else
1188     {
1189         p_dvd->i_next_cell = p_dvd->i_cur_cell + 1;
1190     }
1191 #undef cell
1192     pgc_id = p_dvd->p_vts_file->vts_ptt_srpt->title[
1193                 p_dvd->i_ttn-1].ptt[p_dvd->i_chapter-1].pgcn;
1194     pgn = p_dvd->p_vts_file->vts_ptt_srpt->title[
1195                 p_dvd->i_ttn-1].ptt[p_dvd->i_chapter-1].pgn;
1196     p_pgc = p_dvd->p_vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;
1197
1198     if( p_pgc->program_map[pgn-1] <= p_dvd->i_cur_cell )
1199     {
1200         p_dvd->i_chapter++;
1201         p_dvd->b_eoc = 1;
1202     }
1203 }
1204
1205 /*****************************************************************************
1206  * DvdReadLaunchDecoders
1207  *****************************************************************************/
1208 static void DvdReadLauchDecoders( input_thread_t * p_input )
1209 {
1210     thread_dvd_data_t *  p_dvd;
1211     
1212     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);            
1213             
1214     if( config_GetInt( p_input, "video" ) )
1215     {
1216         input_SelectES( p_input, p_input->stream.pp_es[0] );
1217     }
1218
1219     if( config_GetInt( p_input, "audio" ) )
1220     {
1221         /* For audio: first one if none or a not existing one specified */
1222         int i_audio = config_GetInt( p_input, "audio-channel" );
1223         if( i_audio < 0 /*|| i_audio > i_audio_nb*/ )
1224         {
1225             config_PutInt( p_input, "audio-channel", 1 );
1226             i_audio = 1;
1227         }
1228         if( i_audio > 0/* && i_audio_nb > 0*/ )
1229         {
1230             if( config_GetInt( p_input, "audio-type" )
1231                  == REQUESTED_A52 )
1232             {
1233                 int     i_a52 = i_audio;
1234                 while( ( p_input->stream.pp_es[i_a52]->i_fourcc !=
1235                        VLC_FOURCC('a','5','2',' ') ) && ( i_a52 <=
1236                        p_dvd->p_vts_file->vtsi_mat->nr_of_vts_audio_streams ) )
1237                 {
1238                     i_a52++;
1239                 }
1240                 if( p_input->stream.pp_es[i_a52]->i_fourcc
1241                      == VLC_FOURCC('a','5','2',' ') )
1242                 {
1243                     input_SelectES( p_input,
1244                                     p_input->stream.pp_es[i_a52] );
1245                 }
1246             }
1247             else
1248             {
1249                 input_SelectES( p_input,
1250                                 p_input->stream.pp_es[i_audio] );
1251             }
1252         }
1253     }
1254
1255     if( config_GetInt( p_input, "video" ) )
1256     {
1257         /* for spu, default is none */
1258         int i_spu = config_GetInt( p_input, "spu-channel" );
1259         if( i_spu < 0 /*|| i_spu > i_spu_nb*/ )
1260         {
1261             config_PutInt( p_input, "spu-channel", 0 );
1262             i_spu = 0;
1263         }
1264         if( i_spu > 0 /*&& i_spu_nb > 0*/ )
1265         {
1266             i_spu += p_dvd->p_vts_file->vtsi_mat->nr_of_vts_audio_streams;
1267             input_SelectES( p_input, p_input->stream.pp_es[i_spu] );
1268         }
1269     }
1270 }