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