]> git.sesse.net Git - vlc/blob - plugins/dvd/dvd_es.c
*Removed an occurance of former angle item in gtk.
[vlc] / plugins / dvd / dvd_es.c
1 /* dvd_es.c: functions to find and select ES
2  *****************************************************************************
3  * Copyright (C) 1998-2001 VideoLAN
4  * $Id: dvd_es.c,v 1.1 2002/03/06 01:20:56 stef Exp $
5  *
6  * Author: Stéphane Borel <stef@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <videolan/vlc.h>
31
32 #ifdef HAVE_UNISTD_H
33 #   include <unistd.h>
34 #endif
35
36 #include <fcntl.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <string.h>
40 #include <errno.h>
41
42 #ifdef STRNCASECMP_IN_STRINGS_H
43 #   include <strings.h>
44 #endif
45
46 #ifdef GOD_DAMN_DMCA
47 #   include "dummy_dvdcss.h"
48 #else
49 #   include <videolan/dvdcss.h>
50 #endif
51
52 #include "stream_control.h"
53 #include "input_ext-intf.h"
54 #include "input_ext-dec.h"
55 #include "input_ext-plugins.h"
56
57 #include "dvd.h"
58 #include "dvd_ifo.h"
59 #include "dvd_summary.h"
60 #include "iso_lang.h"
61
62 #include "debug.h"
63
64 /*****************************************************************************
65  * Local prototypes
66  *****************************************************************************/
67
68 void DVDLaunchDecoders( input_thread_t * p_input );
69
70 #define vmg p_dvd->p_ifo->vmg
71 #define vts p_dvd->p_ifo->vts
72
73 /*****************************************************************************
74  * DVDReadVideo
75  *****************************************************************************/
76 void DVDReadVideo( input_thread_t * p_input )
77 {
78     thread_dvd_data_t * p_dvd;
79     es_descriptor_t *   p_es;
80
81     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
82
83     /* ES 0 -> video MPEG2 */
84     IfoPrintVideo( p_dvd );
85
86     p_es = input_AddES( p_input, NULL, 0xe0, 0 );
87     p_es->i_stream_id = 0xe0;
88     p_es->i_type = MPEG2_VIDEO_ES;
89     p_es->i_cat = VIDEO_ES;
90 }
91
92 /*****************************************************************************
93  * DVDReadAudio
94  *****************************************************************************/
95 #define audio_status \
96     vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
97     
98 void DVDReadAudio( input_thread_t * p_input )
99 {
100     thread_dvd_data_t * p_dvd;
101     es_descriptor_t *   p_es;
102     int                 i_id;
103     int                 i;
104
105     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
106     
107     /* Audio ES, in the order they appear in .ifo */
108     for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
109     {
110         IfoPrintAudio( p_dvd, i );
111
112         /* audio channel is active if first byte is 0x80 */
113         if( audio_status.i_available )
114         {
115             p_dvd->i_audio_nb++;
116
117             switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
118             {
119             case 0x00:              /* AC3 */
120                 i_id = ( ( 0x80 + audio_status.i_position ) << 8 ) | 0xbd;
121                 p_es = input_AddES( p_input, NULL, i_id, 0 );
122                 p_es->i_stream_id = 0xbd;
123                 p_es->i_type = AC3_AUDIO_ES;
124                 p_es->b_audio = 1;
125                 p_es->i_cat = AUDIO_ES;
126                 strcpy( p_es->psz_desc, DecodeLanguage( hton16(
127                     vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); 
128                 strcat( p_es->psz_desc, " (ac3)" );
129
130                 break;
131             case 0x02:
132             case 0x03:              /* MPEG audio */
133                 i_id = 0xc0 + audio_status.i_position;
134                 p_es = input_AddES( p_input, NULL, i_id, 0 );
135                 p_es->i_stream_id = i_id;
136                 p_es->i_type = MPEG2_AUDIO_ES;
137                 p_es->b_audio = 1;
138                 p_es->i_cat = AUDIO_ES;
139                 strcpy( p_es->psz_desc, DecodeLanguage( hton16(
140                     vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); 
141                 strcat( p_es->psz_desc, " (mpeg)" );
142
143                 break;
144             case 0x04:              /* LPCM */
145
146                 i_id = ( ( 0xa0 + audio_status.i_position ) << 8 ) | 0xbd;
147                 p_es = input_AddES( p_input, NULL, i_id, 0 );
148                 p_es->i_stream_id = 0xbd;
149                 p_es->i_type = LPCM_AUDIO_ES;
150                 p_es->b_audio = 1;
151                 p_es->i_cat = AUDIO_ES;
152                 strcpy( p_es->psz_desc, DecodeLanguage( hton16(
153                     vts.manager_inf.p_audio_attr[i-1].i_lang_code ) ) ); 
154                 strcat( p_es->psz_desc, " (lpcm)" );
155
156                 break;
157             case 0x06:              /* DTS */
158                 i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd;
159                 intf_ErrMsg( "dvd warning: DTS audio not handled yet"
160                              "(0x%x)", i_id );
161                 break;
162             default:
163                 i_id = 0;
164                 intf_ErrMsg( "dvd warning: unknown audio type %.2x",
165                          vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
166             }
167         }
168     }
169 }
170 #undef audio_status
171
172 /*****************************************************************************
173  * DVDReadSPU: Read subpictures ES
174  *****************************************************************************/
175 #define spu_status \
176     vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
177
178 void DVDReadSPU( input_thread_t * p_input )
179 {
180     thread_dvd_data_t * p_dvd;
181     es_descriptor_t *   p_es;
182     int                 i_id;
183     int                 i;
184            
185     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
186
187     for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
188     {
189         IfoPrintSpu( p_dvd, i );
190
191         if( spu_status.i_available )
192         {
193             p_dvd->i_spu_nb++;
194
195             /*  there are several streams for one spu */
196             if(  vts.manager_inf.video_attr.i_ratio )
197             {
198                 /* 16:9 */
199                 switch( vts.manager_inf.video_attr.i_perm_displ )
200                 {
201                 case 1:
202                     i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 )
203                            | 0xbd;
204                     break;
205                 case 2:
206                     i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 )
207                            | 0xbd;
208                     break;
209                 default:
210                     i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 )
211                            | 0xbd;
212                     break;
213                 }
214             }
215             else
216             {
217                 /* 4:3 */
218                 i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 )
219                        | 0xbd;
220             }
221             p_es = input_AddES( p_input, NULL, i_id, 0 );
222             p_es->i_stream_id = 0xbd;
223             p_es->i_type = DVD_SPU_ES;
224             p_es->i_cat = SPU_ES;
225             strcpy( p_es->psz_desc, DecodeLanguage( hton16(
226                 vts.manager_inf.p_spu_attr[i-1].i_lang_code ) ) ); 
227         }
228     }
229 }
230 #undef spu_status
231
232 #undef vts
233 #undef vmg
234
235 /*****************************************************************************
236  * DVDLaunchDecoders
237  *****************************************************************************/
238 void DVDLaunchDecoders( input_thread_t * p_input )
239 {
240     thread_dvd_data_t *  p_dvd;
241     int                  i_audio;
242     int                  i_spu;
243
244     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
245
246     /* Select Video stream (always 0) */
247     if( p_main->b_video )
248     {
249         input_SelectES( p_input, p_input->stream.pp_es[0] );
250     }
251
252     /* Select audio stream */
253     if( p_main->b_audio )
254     {
255         /* For audio: first one if none or a not existing one specified */
256         i_audio = config_GetIntVariable( INPUT_CHANNEL_VAR );
257         if( i_audio < 0 || i_audio > p_dvd->i_audio_nb )
258         {
259             config_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
260             i_audio = 1;
261         }
262         if( i_audio > 0 && p_dvd->i_audio_nb > 0 )
263         {
264             if( config_GetIntVariable( AOUT_SPDIF_VAR ) ||
265                 ( config_GetIntVariable( INPUT_AUDIO_VAR ) ==
266                   REQUESTED_AC3 ) )
267             {
268                 int     i_ac3 = i_audio;
269                 while( ( p_input->stream.pp_es[i_ac3]->i_type !=
270                          AC3_AUDIO_ES ) && ( i_ac3 <=
271                          p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) )
272                 {
273                     i_ac3++;
274                 }
275                 if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES )
276                 {
277                     input_SelectES( p_input,
278                                     p_input->stream.pp_es[i_ac3] );
279                 }
280             }
281             else
282             {
283                 input_SelectES( p_input,
284                                 p_input->stream.pp_es[i_audio] );
285             }
286         }
287     }
288
289     /* Select subtitle */
290     if( p_main->b_video )
291     {
292         /* for spu, default is none */
293         i_spu = config_GetIntVariable( INPUT_SUBTITLE_VAR );
294         if( i_spu < 0 || i_spu > p_dvd->i_spu_nb )
295         {
296             config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 );
297             i_spu = 0;
298         }
299         if( i_spu > 0 && p_dvd->i_spu_nb > 0 )
300         {
301             i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb;
302             input_SelectES( p_input, p_input->stream.pp_es[i_spu] );
303         }
304     }
305 }