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 $
6 * Author: Stéphane Borel <stef@via.ecp.fr>
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.
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.
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 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
30 #include <videolan/vlc.h>
37 #include <sys/types.h>
42 #ifdef STRNCASECMP_IN_STRINGS_H
47 # include "dummy_dvdcss.h"
49 # include <videolan/dvdcss.h>
52 #include "stream_control.h"
53 #include "input_ext-intf.h"
54 #include "input_ext-dec.h"
55 #include "input_ext-plugins.h"
59 #include "dvd_summary.h"
64 /*****************************************************************************
66 *****************************************************************************/
68 void DVDLaunchDecoders( input_thread_t * p_input );
70 #define vmg p_dvd->p_ifo->vmg
71 #define vts p_dvd->p_ifo->vts
73 /*****************************************************************************
75 *****************************************************************************/
76 void DVDReadVideo( input_thread_t * p_input )
78 thread_dvd_data_t * p_dvd;
79 es_descriptor_t * p_es;
81 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
83 /* ES 0 -> video MPEG2 */
84 IfoPrintVideo( p_dvd );
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;
92 /*****************************************************************************
94 *****************************************************************************/
95 #define audio_status \
96 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
98 void DVDReadAudio( input_thread_t * p_input )
100 thread_dvd_data_t * p_dvd;
101 es_descriptor_t * p_es;
105 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
107 /* Audio ES, in the order they appear in .ifo */
108 for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
110 IfoPrintAudio( p_dvd, i );
112 /* audio channel is active if first byte is 0x80 */
113 if( audio_status.i_available )
117 switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
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;
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)" );
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;
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)" );
144 case 0x04: /* LPCM */
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;
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)" );
158 i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd;
159 intf_ErrMsg( "dvd warning: DTS audio not handled yet"
164 intf_ErrMsg( "dvd warning: unknown audio type %.2x",
165 vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
172 /*****************************************************************************
173 * DVDReadSPU: Read subpictures ES
174 *****************************************************************************/
176 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
178 void DVDReadSPU( input_thread_t * p_input )
180 thread_dvd_data_t * p_dvd;
181 es_descriptor_t * p_es;
185 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
187 for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
189 IfoPrintSpu( p_dvd, i );
191 if( spu_status.i_available )
195 /* there are several streams for one spu */
196 if( vts.manager_inf.video_attr.i_ratio )
199 switch( vts.manager_inf.video_attr.i_perm_displ )
202 i_id = ( ( 0x20 + spu_status.i_position_pan ) << 8 )
206 i_id = ( ( 0x20 + spu_status.i_position_letter ) << 8 )
210 i_id = ( ( 0x20 + spu_status.i_position_wide ) << 8 )
218 i_id = ( ( 0x20 + spu_status.i_position_43 ) << 8 )
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 ) ) );
235 /*****************************************************************************
237 *****************************************************************************/
238 void DVDLaunchDecoders( input_thread_t * p_input )
240 thread_dvd_data_t * p_dvd;
244 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
246 /* Select Video stream (always 0) */
247 if( p_main->b_video )
249 input_SelectES( p_input, p_input->stream.pp_es[0] );
252 /* Select audio stream */
253 if( p_main->b_audio )
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 )
259 config_PutIntVariable( INPUT_CHANNEL_VAR, 1 );
262 if( i_audio > 0 && p_dvd->i_audio_nb > 0 )
264 if( config_GetIntVariable( AOUT_SPDIF_VAR ) ||
265 ( config_GetIntVariable( INPUT_AUDIO_VAR ) ==
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 ) )
275 if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES )
277 input_SelectES( p_input,
278 p_input->stream.pp_es[i_ac3] );
283 input_SelectES( p_input,
284 p_input->stream.pp_es[i_audio] );
289 /* Select subtitle */
290 if( p_main->b_video )
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 )
296 config_PutIntVariable( INPUT_SUBTITLE_VAR, 0 );
299 if( i_spu > 0 && p_dvd->i_spu_nb > 0 )
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] );