1 /* dvd_es.c: functions to find and select ES
2 *****************************************************************************
3 * Copyright (C) 1998-2001 VideoLAN
4 * $Id: dvd_es.c,v 1.8 2002/04/23 20:58:23 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"
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 #define ADDES( stream_id, private_id, type, cat, lang, size ) \
74 i_id = ( (private_id) << 8 ) | (stream_id); \
75 p_es = input_AddES( p_input, NULL, i_id, size ); \
76 p_es->i_stream_id = (stream_id); \
77 p_es->i_type = (type); \
78 p_es->i_cat = (cat); \
81 strcpy( p_es->psz_desc, DecodeLanguage( hton16( lang ) ) ); \
85 /*****************************************************************************
86 * DVDReadVideo: read video ES
87 *****************************************************************************/
88 void DVDReadVideo( input_thread_t * p_input )
90 thread_dvd_data_t * p_dvd;
91 es_descriptor_t * p_es;
95 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
97 /* ES 0 -> video MPEG2 */
98 IfoPrintVideo( p_dvd );
99 i_ratio = vts.manager_inf.video_attr.i_ratio;
103 ADDES( 0xe0, 0, MPEG2_VIDEO_ES, VIDEO_ES, 0, sizeof(int) );
104 *(int*)(p_es->p_demux_data) = i_ratio;
108 ADDES( 0xe0, 0, MPEG2_VIDEO_ES, VIDEO_ES, 0, 0 );
113 /*****************************************************************************
114 * DVDReadAudio: read audio ES
115 *****************************************************************************/
116 #define audio_status \
117 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_audio_status[i-1]
119 void DVDReadAudio( input_thread_t * p_input )
121 thread_dvd_data_t * p_dvd;
122 es_descriptor_t * p_es;
127 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
128 p_dvd->i_audio_nb = 0;
130 /* Audio ES, in the order they appear in .ifo */
131 for( i = 1 ; i <= vts.manager_inf.i_audio_nb ; i++ )
133 IfoPrintAudio( p_dvd, i );
135 /* audio channel is active if first byte is 0x80 */
136 if( audio_status.i_available )
139 i_lang = vts.manager_inf.p_audio_attr[i-1].i_lang_code;
140 i_id = audio_status.i_position;
142 switch( vts.manager_inf.p_audio_attr[i-1].i_coding_mode )
145 ADDES( 0xbd, 0x80 + audio_status.i_position,
146 AC3_AUDIO_ES, AUDIO_ES, i_lang, 0 );
148 strcat( p_es->psz_desc, " (ac3)" );
152 case 0x03: /* MPEG audio */
153 ADDES( 0xc0 + audio_status.i_position, 0,
154 MPEG2_AUDIO_ES, AUDIO_ES, i_lang, 0 );
156 strcat( p_es->psz_desc, " (mpeg)" );
159 case 0x04: /* LPCM */
160 ADDES( 0xbd, 0xa0 + audio_status.i_position,
161 LPCM_AUDIO_ES, AUDIO_ES, i_lang, 0 );
163 strcat( p_es->psz_desc, " (lpcm)" );
167 i_id = ( ( 0x88 + audio_status.i_position ) << 8 ) | 0xbd;
168 intf_ErrMsg( "dvd warning: DTS audio not handled yet"
173 intf_ErrMsg( "dvd warning: unknown audio type %.2x",
174 vts.manager_inf.p_audio_attr[i-1].i_coding_mode );
181 /*****************************************************************************
182 * DVDReadSPU: read subpictures ES
183 *****************************************************************************/
185 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_spu_status[i-1]
187 vts.title_unit.p_title[p_dvd->i_title_id-1].title.pi_yuv_color
189 void DVDReadSPU( input_thread_t * p_input )
191 thread_dvd_data_t * p_dvd;
192 es_descriptor_t * p_es;
196 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
199 for( i = 1 ; i <= vts.manager_inf.i_spu_nb; i++ )
201 IfoPrintSpu( p_dvd, i );
203 if( spu_status.i_available )
207 /* there are several streams for one spu */
208 if( vts.manager_inf.video_attr.i_ratio )
211 switch( vts.manager_inf.video_attr.i_perm_displ )
214 i_id = spu_status.i_position_pan;
217 i_id = spu_status.i_position_letter;
220 i_id = spu_status.i_position_wide;
227 i_id = spu_status.i_position_43;
230 if( vmg.title.pi_yuv_color )
232 ADDES( 0xbd, 0x20 + i_id, DVD_SPU_ES, SPU_ES,
233 vts.manager_inf.p_spu_attr[i-1].i_lang_code,
234 sizeof(int) + 16*sizeof(u32) );
235 *(int*)p_es->p_demux_data = 0xBeeF;
236 memcpy( (void*)p_es->p_demux_data + sizeof(int),
237 palette, 16*sizeof(u32) );
241 ADDES( 0xbd, 0x20 + i_id, DVD_SPU_ES, SPU_ES,
242 vts.manager_inf.p_spu_attr[i-1].i_lang_code, 0 );
253 /*****************************************************************************
254 * DVDLaunchDecoders: select ES for video, audio and spu
255 *****************************************************************************/
256 void DVDLaunchDecoders( input_thread_t * p_input )
258 thread_dvd_data_t * p_dvd;
262 p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
264 /* Select Video stream (always 0) */
265 if( p_main->b_video )
267 input_SelectES( p_input, p_input->stream.pp_es[0] );
270 /* Select audio stream */
271 if( p_main->b_audio && p_dvd->i_audio_nb > 0 )
273 /* For audio: first one if none or a not existing one specified */
274 i_audio = config_GetIntVariable( "audio-channel" );
275 if( i_audio <= 0 || i_audio > p_dvd->i_audio_nb )
277 config_PutIntVariable( "audio-channel", 1 );
281 if( ( config_GetIntVariable( "audio-type" ) == REQUESTED_AC3 ) )
284 while( ( p_input->stream.pp_es[i_ac3]->i_type !=
285 AC3_AUDIO_ES ) && ( i_ac3 <=
286 p_dvd->p_ifo->vts.manager_inf.i_audio_nb ) )
290 if( p_input->stream.pp_es[i_ac3]->i_type == AC3_AUDIO_ES )
292 input_SelectES( p_input,
293 p_input->stream.pp_es[i_ac3] );
298 input_SelectES( p_input,
299 p_input->stream.pp_es[i_audio] );
303 /* Select subtitle */
304 if( p_main->b_video && p_dvd->i_spu_nb > 0 )
306 /* for spu, default is none */
307 i_spu = config_GetIntVariable( "spu-channel" );
308 if( i_spu < 0 || i_spu > p_dvd->i_spu_nb )
310 config_PutIntVariable( "spu-channel", 0 );
315 i_spu += p_dvd->p_ifo->vts.manager_inf.i_audio_nb;
316 input_SelectES( p_input, p_input->stream.pp_es[i_spu] );