1 /* es.c: functions to find and select ES
2 *****************************************************************************
3 * Copyright (C) 1998-2001 VideoLAN
4 * $Id: es.c,v 1.4 2002/12/06 16:34:04 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 *****************************************************************************/
31 #include <vlc/input.h>
38 #include <sys/types.h>
43 #ifdef STRNCASECMP_IN_STRINGS_H
50 # include <dvdcss/dvdcss.h>
58 /*****************************************************************************
60 *****************************************************************************/
62 void DVDLaunchDecoders( input_thread_t * p_input );
64 #define vmg p_dvd->p_ifo->vmg
65 #define vts p_dvd->p_ifo->vts
67 #define ADDES( stream_id, private_id, fourcc, cat, lang, size ) \
68 i_id = ( (private_id) << 8 ) | (stream_id); \
69 p_es = input_AddES( p_input, NULL, i_id, size ); \
70 p_es->i_stream_id = (stream_id); \
71 p_es->i_fourcc = (fourcc); \
72 p_es->i_cat = (cat); \
75 strcpy( p_es->psz_desc, DecodeLanguage( lang ) ); \
79 /*****************************************************************************
80 * DVDReadVideo: read video ES
81 *****************************************************************************/
82 void DVDReadVideo( input_thread_t * p_input )
84 thread_dvd_data_t * p_dvd;
85 es_descriptor_t * p_es;
89 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
91 /* ES 0 -> video MPEG2 */
92 IfoPrintVideo( p_dvd );
93 i_ratio = vts.manager_inf.video_attr.i_ratio;
97 ADDES( 0xe0, 0, VLC_FOURCC('m','p','g','v'), VIDEO_ES, 0, sizeof(int) );
98 *(int*)(p_es->p_demux_data) = i_ratio;
102 ADDES( 0xe0, 0, VLC_FOURCC('m','p','g','v'), VIDEO_ES, 0, 0 );
107 /*****************************************************************************
108 * DVDReadAudio: read audio ES
109 *****************************************************************************/
110 #define audio_status \
111 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
113 void DVDReadAudio( input_thread_t * p_input )
115 thread_dvd_data_t * p_dvd;
116 es_descriptor_t * p_es;
121 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
122 p_dvd->i_audio_nb = 0;
124 /* Audio ES, in the order they appear in .ifo */
125 for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
127 IfoPrintAudio( p_dvd, i );
129 /* audio channel is active if first byte is 0x80 */
130 if( audio_status.i_available )
133 i_lang = vts.manager_inf.p_audio_attr[i-1].i_lang_code;
134 i_id = audio_status.i_position;
136 switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
139 ADDES( 0xbd, 0x80 + audio_status.i_position,
140 VLC_FOURCC('a','5','2','b'), AUDIO_ES, i_lang, 0 );
141 strcat( p_es->psz_desc, " (A52)" );
145 case 0x03: /* MPEG audio */
146 ADDES( 0xc0 + audio_status.i_position, 0,
147 VLC_FOURCC('m','p','g','a'), AUDIO_ES, i_lang, 0 );
148 strcat( p_es->psz_desc, " (mpeg)" );
151 case 0x04: /* LPCM */
152 ADDES( 0xbd, 0xa0 + audio_status.i_position,
153 VLC_FOURCC('l','p','c','b'), AUDIO_ES, i_lang, 0 );
154 strcat( p_es->psz_desc, " (lpcm)" );
158 ADDES( 0xbd, 0x88 + audio_status.i_position,
159 VLC_FOURCC('d','t','s','b'), AUDIO_ES, i_lang, 0 );
160 strcat( p_es->psz_desc, " (dts)" );
165 msg_Err( p_input, "unknown audio type %.2x",
166 vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
173 /*****************************************************************************
174 * DVDReadSPU: read subpictures ES
175 *****************************************************************************/
177 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
179 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_yuv_color
181 void DVDReadSPU( input_thread_t * p_input )
183 thread_dvd_data_t * p_dvd;
184 es_descriptor_t * p_es;
188 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
191 for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
193 IfoPrintSpu( p_dvd, i );
195 if( spu_status.i_available )
199 /* there are several streams for one spu */
200 if( vts.manager_inf.video_attr.i_ratio )
203 switch( vts.manager_inf.video_attr.i_perm_displ )
206 i_id = spu_status.i_position_pan;
209 i_id = spu_status.i_position_letter;
212 i_id = spu_status.i_position_wide;
219 i_id = spu_status.i_position_43;
222 if( vmg.title.pi_yuv_color )
224 ADDES( 0xbd, 0x20 + i_id, VLC_FOURCC('s','p','u','b'), SPU_ES,
225 vts.manager_inf.p_spu_attr[i-1].i_lang_code,
226 sizeof(int) + 16*sizeof(u32) );
227 *(int*)p_es->p_demux_data = 0xBeeF;
228 memcpy( (char*)p_es->p_demux_data + sizeof(int),
229 palette, 16*sizeof(u32) );
233 ADDES( 0xbd, 0x20 + i_id, VLC_FOURCC('s','p','u','b'), SPU_ES,
234 vts.manager_inf.p_spu_attr[i-1].i_lang_code, 0 );
245 /*****************************************************************************
246 * DVDLaunchDecoders: select ES for video, audio and spu
247 *****************************************************************************/
248 void DVDLaunchDecoders( input_thread_t * p_input )
250 thread_dvd_data_t * p_dvd;
251 unsigned int i_audio;
254 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
256 /* Select Video stream (always 0) */
257 input_SelectES( p_input, p_input->stream.pp_es[0] );
259 /* Select audio stream */
260 if( p_dvd->i_audio_nb > 0 )
262 /* For audio: first one if none or a not existing one specified */
263 i_audio = config_GetInt( p_input, "audio-channel" );
264 if( i_audio <= 0 || i_audio > p_dvd->i_audio_nb )
266 config_PutInt( p_input, "audio-channel", 1 );
270 if( ( config_GetInt( p_input, "audio-type" )
274 while( ( p_input->stream.pp_es[i_a52]->i_fourcc !=
275 VLC_FOURCC('a','5','2','b') ) && ( i_a52 <=
276 p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) )
280 if( p_input->stream.pp_es[i_a52]->i_fourcc
281 == VLC_FOURCC('a','5','2','b') )
283 input_SelectES( p_input,
284 p_input->stream.pp_es[i_a52] );
289 input_SelectES( p_input,
290 p_input->stream.pp_es[i_audio] );
294 /* Select subtitle */
295 if( p_dvd->i_spu_nb )
297 /* for spu, default is none */
298 i_spu = config_GetInt( p_input, "spu-channel" );
299 if( i_spu < 0 || i_spu > p_dvd->i_spu_nb )
301 config_PutInt( p_input, "spu-channel", 0 );
306 unsigned int i = 0, j = 0;
307 for( i = 0; i < p_input->stream.i_es_number; i++ )
309 if ( p_input->stream.pp_es[i]->i_fourcc
310 == VLC_FOURCC('s','p','u','b') )
313 if ( i_spu == j ) break;
318 input_SelectES( p_input, p_input->stream.pp_es[i] );