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