1 /* dvd_es.c: functions to find and select ES
2 *****************************************************************************
3 * Copyright (C) 1998-2001 VideoLAN
4 * $Id: dvd_es.c,v 1.9 2002/04/25 21:52:42 sam 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 <dvdcss/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"
62 /*****************************************************************************
64 *****************************************************************************/
66 void DVDLaunchDecoders( input_thread_t
* p_input
);
68 #define vmg p_dvd->p_ifo->vmg
69 #define vts p_dvd->p_ifo->vts
71 #define ADDES( stream_id, private_id, type, cat, lang, size ) \
72 i_id = ( (private_id) << 8 ) | (stream_id); \
73 p_es = input_AddES( p_input, NULL, i_id, size ); \
74 p_es->i_stream_id = (stream_id); \
75 p_es->i_type = (type); \
76 p_es->i_cat = (cat); \
79 strcpy( p_es->psz_desc, DecodeLanguage( hton16( lang ) ) ); \
83 /*****************************************************************************
84 * DVDReadVideo: read video ES
85 *****************************************************************************/
86 void DVDReadVideo( input_thread_t
* p_input
)
88 thread_dvd_data_t
* p_dvd
;
89 es_descriptor_t
* p_es
;
93 p_dvd
= (thread_dvd_data_t
*)(p_input
->p_access_data
);
95 /* ES 0 -> video MPEG2 */
96 IfoPrintVideo( p_dvd
);
97 i_ratio
= vts
.manager_inf
.video_attr
.i_ratio
;
101 ADDES( 0xe0, 0, MPEG2_VIDEO_ES
, VIDEO_ES
, 0, sizeof(int) );
102 *(int*)(p_es
->p_demux_data
) = i_ratio
;
106 ADDES( 0xe0, 0, MPEG2_VIDEO_ES
, VIDEO_ES
, 0, 0 );
111 /*****************************************************************************
112 * DVDReadAudio: read audio ES
113 *****************************************************************************/
114 #define audio_status \
115 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
117 void DVDReadAudio( input_thread_t
* p_input
)
119 thread_dvd_data_t
* p_dvd
;
120 es_descriptor_t
* p_es
;
125 p_dvd
= (thread_dvd_data_t
*)(p_input
->p_access_data
);
126 p_dvd
->i_audio_nb
= 0;
128 /* Audio ES, in the order they appear in .ifo */
129 for( i
= 1 ; i
<= vts
.manager_inf
.i_audio_nb
; i
++ )
131 IfoPrintAudio( p_dvd
, i
);
133 /* audio channel is active if first byte is 0x80 */
134 if( audio_status
.i_available
)
137 i_lang
= vts
.manager_inf
.p_audio_attr
[i
-1].i_lang_code
;
138 i_id
= audio_status
.i_position
;
140 switch( vts
.manager_inf
.p_audio_attr
[i
-1].i_coding_mode
)
143 ADDES( 0xbd, 0x80 + audio_status
.i_position
,
144 AC3_AUDIO_ES
, AUDIO_ES
, i_lang
, 0 );
146 strcat( p_es
->psz_desc
, " (ac3)" );
150 case 0x03: /* MPEG audio */
151 ADDES( 0xc0 + audio_status
.i_position
, 0,
152 MPEG2_AUDIO_ES
, AUDIO_ES
, i_lang
, 0 );
154 strcat( p_es
->psz_desc
, " (mpeg)" );
157 case 0x04: /* LPCM */
158 ADDES( 0xbd, 0xa0 + audio_status
.i_position
,
159 LPCM_AUDIO_ES
, AUDIO_ES
, i_lang
, 0 );
161 strcat( p_es
->psz_desc
, " (lpcm)" );
165 i_id
= ( ( 0x88 + audio_status
.i_position
) << 8 ) | 0xbd;
166 intf_ErrMsg( "dvd warning: DTS audio not handled yet"
171 intf_ErrMsg( "dvd warning: unknown audio type %.2x",
172 vts
.manager_inf
.p_audio_attr
[i
-1].i_coding_mode
);
179 /*****************************************************************************
180 * DVDReadSPU: read subpictures ES
181 *****************************************************************************/
183 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
185 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_yuv_color
187 void DVDReadSPU( input_thread_t
* p_input
)
189 thread_dvd_data_t
* p_dvd
;
190 es_descriptor_t
* p_es
;
194 p_dvd
= (thread_dvd_data_t
*)(p_input
->p_access_data
);
197 for( i
= 1 ; i
<= vts
.manager_inf
.i_spu_nb
; i
++ )
199 IfoPrintSpu( p_dvd
, i
);
201 if( spu_status
.i_available
)
205 /* there are several streams for one spu */
206 if( vts
.manager_inf
.video_attr
.i_ratio
)
209 switch( vts
.manager_inf
.video_attr
.i_perm_displ
)
212 i_id
= spu_status
.i_position_pan
;
215 i_id
= spu_status
.i_position_letter
;
218 i_id
= spu_status
.i_position_wide
;
225 i_id
= spu_status
.i_position_43
;
228 if( vmg
.title
.pi_yuv_color
)
230 ADDES( 0xbd, 0x20 + i_id
, DVD_SPU_ES
, SPU_ES
,
231 vts
.manager_inf
.p_spu_attr
[i
-1].i_lang_code
,
232 sizeof(int) + 16*sizeof(u32
) );
233 *(int*)p_es
->p_demux_data
= 0xBeeF;
234 memcpy( (void*)p_es
->p_demux_data
+ sizeof(int),
235 palette
, 16*sizeof(u32
) );
239 ADDES( 0xbd, 0x20 + i_id
, DVD_SPU_ES
, SPU_ES
,
240 vts
.manager_inf
.p_spu_attr
[i
-1].i_lang_code
, 0 );
251 /*****************************************************************************
252 * DVDLaunchDecoders: select ES for video, audio and spu
253 *****************************************************************************/
254 void DVDLaunchDecoders( input_thread_t
* p_input
)
256 thread_dvd_data_t
* p_dvd
;
260 p_dvd
= (thread_dvd_data_t
*)(p_input
->p_access_data
);
262 /* Select Video stream (always 0) */
263 if( p_main
->b_video
)
265 input_SelectES( p_input
, p_input
->stream
.pp_es
[0] );
268 /* Select audio stream */
269 if( p_main
->b_audio
&& p_dvd
->i_audio_nb
> 0 )
271 /* For audio: first one if none or a not existing one specified */
272 i_audio
= config_GetIntVariable( "audio-channel" );
273 if( i_audio
<= 0 || i_audio
> p_dvd
->i_audio_nb
)
275 config_PutIntVariable( "audio-channel", 1 );
279 if( ( config_GetIntVariable( "audio-type" ) == REQUESTED_AC3
) )
282 while( ( p_input
->stream
.pp_es
[i_ac3
]->i_type
!=
283 AC3_AUDIO_ES
) && ( i_ac3
<=
284 p_dvd
->p_ifo
->vts
.manager_inf
.i_audio_nb
) )
288 if( p_input
->stream
.pp_es
[i_ac3
]->i_type
== AC3_AUDIO_ES
)
290 input_SelectES( p_input
,
291 p_input
->stream
.pp_es
[i_ac3
] );
296 input_SelectES( p_input
,
297 p_input
->stream
.pp_es
[i_audio
] );
301 /* Select subtitle */
302 if( p_main
->b_video
&& p_dvd
->i_spu_nb
> 0 )
304 /* for spu, default is none */
305 i_spu
= config_GetIntVariable( "spu-channel" );
306 if( i_spu
< 0 || i_spu
> p_dvd
->i_spu_nb
)
308 config_PutIntVariable( "spu-channel", 0 );
313 i_spu
+= p_dvd
->p_ifo
->vts
.manager_inf
.i_audio_nb
;
314 input_SelectES( p_input
, p_input
->stream
.pp_es
[i_spu
] );