1 /*****************************************************************************
2 * input_ctrl.c: Decoder control
3 * Controls the extraction and the decoding of the programs elements carried
5 *****************************************************************************
6 * Copyright (C) 1999, 2000 VideoLAN
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
29 #include <sys/types.h> /* on BSD, uio.h needs types.h */
30 #include <sys/uio.h> /* "input.h" */
32 #include <netinet/in.h> /* ntohs */
43 #include "input_netlist.h"
44 #include "decoder_fifo.h"
46 #include "audio_output.h" /* aout_thread_t */
48 #include "audio_decoder.h" /* adec_thread_t */
50 #include "ac3_decoder.h" /* ac3dec_t (for ac3_decoder_thread.h) */
51 #include "ac3_decoder_thread.h" /* ac3dec_thread_t */
53 #include "video.h" /* picture_t (for video_output.h) */
54 #include "video_output.h" /* vout_thread_t */
56 #include "vdec_idct.h" /* dctelem_t (for video_parser.h) */
57 #include "vdec_motion.h" /* f_motion_t (for video_parser.h) */
58 #include "vpar_blocks.h" /* macroblock_t (for video_parser.h) */
59 #include "vpar_headers.h" /* sequence_t (for video_parser.h) */
60 #include "vpar_synchro.h" /* video_synchro_t (for video_parser.h) */
61 #include "video_parser.h" /* vpar_thread_t */
63 #include "spu_decoder.h" /* spudec_thread_t */
65 /*****************************************************************************
66 * input_AddPgrmElem: Start the extraction and the decoding of a program element
67 *****************************************************************************
68 * Add the element given by its PID in the list of PID to extract and spawn
69 * the decoding thread.
70 * This function only modifies the table of selected es, but must NOT modify
71 * the table of ES itself.
72 *****************************************************************************/
73 int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
75 int i_es_loop, i_selected_es_loop;
77 /* Since this function is intended to be called by interface, lock the
78 * elementary stream structure. */
79 vlc_mutex_lock( &p_input->es_lock );
81 /* Find out which PID we need. */
82 for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
84 if( p_input->p_es[i_es_loop].i_id == i_current_id )
86 if( p_input->p_es[i_es_loop].p_dec != NULL )
88 /* We already have a decoder for that PID. */
89 vlc_mutex_unlock( &p_input->es_lock );
90 intf_ErrMsg("input error: PID %d already selected\n",
95 intf_DbgMsg("Requesting selection of PID %d\n",
98 /* Find a free spot in pp_selected_es. */
99 for( i_selected_es_loop = 0; p_input->pp_selected_es[i_selected_es_loop] != NULL
100 && i_selected_es_loop < INPUT_MAX_SELECTED_ES; i_selected_es_loop++ );
102 if( i_selected_es_loop == INPUT_MAX_SELECTED_ES )
105 vlc_mutex_unlock( &p_input->es_lock );
106 intf_ErrMsg("input error: MAX_SELECTED_ES reached: try increasing it in config.h\n");
110 /* Don't decode PSI streams ! */
111 if( p_input->p_es[i_es_loop].b_psi )
113 intf_ErrMsg("input_error: trying to decode PID %d which is the one of a PSI\n", i_current_id);
114 vlc_mutex_unlock( &p_input->es_lock );
119 /* Spawn the decoder. */
120 switch( p_input->p_es[i_es_loop].i_type )
123 /* Spawn ac3 thread */
124 if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
125 ac3dec_CreateThread(p_input)) == NULL )
127 intf_ErrMsg( "Could not start ac3 decoder\n" );
128 vlc_mutex_unlock( &p_input->es_lock );
134 /* Spawn spu thread */
135 if ( ((spudec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
136 spudec_CreateThread(p_input)) == NULL )
138 intf_ErrMsg( "Could not start spu decoder\n" );
139 vlc_mutex_unlock( &p_input->es_lock );
146 /* Spawn audio thread. */
147 if( ((adec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
148 adec_CreateThread( p_input )) == NULL )
150 intf_ErrMsg("Could not start audio decoder\n");
151 vlc_mutex_unlock( &p_input->es_lock );
158 /* Spawn video thread. */
160 if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
161 vdec_CreateThread( p_input )) == NULL )
163 if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
164 vpar_CreateThread( p_input )) == NULL )
168 intf_ErrMsg("Could not start video decoder\n");
170 intf_ErrMsg("Could not start video parser\n");
172 vlc_mutex_unlock( &p_input->es_lock );
178 /* That should never happen. */
179 intf_DbgMsg("input error: unknown stream type (0x%.2x)\n",
180 p_input->p_es[i_es_loop].i_type);
181 vlc_mutex_unlock( &p_input->es_lock );
186 /* Initialise the demux */
187 p_input->p_es[i_es_loop].p_pes_packet = NULL;
188 p_input->p_es[i_es_loop].i_continuity_counter = 0xff;
189 p_input->p_es[i_es_loop].b_random = 0;
191 /* Mark stream to be demultiplexed. */
192 intf_DbgMsg("Stream %d added in %d\n", i_current_id, i_selected_es_loop);
193 p_input->pp_selected_es[i_selected_es_loop] = &p_input->p_es[i_es_loop];
194 vlc_mutex_unlock( &p_input->es_lock );
200 /* We haven't found this PID in the current stream. */
201 vlc_mutex_unlock( &p_input->es_lock );
202 intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
206 /*****************************************************************************
207 * input_DelPgrmElem: Stop the decoding of a program element
208 *****************************************************************************
209 * Stop the extraction of the element given by its PID and kill the associated
211 * This function only modifies the table of selected es, but must NOT modify
212 * the table of ES itself.
213 *****************************************************************************/
214 int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
216 int i_selected_es_loop, i_last_selected;
218 /* Since this function is intended to be called by interface, lock the
220 vlc_mutex_lock( &p_input->es_lock );
222 /* Find out which PID we need. */
223 for( i_selected_es_loop = 0; i_selected_es_loop < INPUT_MAX_SELECTED_ES;
224 i_selected_es_loop++ )
226 if( p_input->pp_selected_es[i_selected_es_loop] )
228 if( p_input->pp_selected_es[i_selected_es_loop]->i_id == i_current_id )
230 if( !(p_input->pp_selected_es[i_selected_es_loop]->p_dec) )
232 /* We don't have a decoder for that PID. */
233 vlc_mutex_unlock( &p_input->es_lock );
234 intf_ErrMsg("input error: PID %d already deselected\n",
239 intf_DbgMsg("input debug: requesting termination of PID %d\n",
242 /* Cancel the decoder. */
243 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
246 ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
250 spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
255 adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
261 vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
263 vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
269 p_input->pp_selected_es[i_selected_es_loop]->p_dec = NULL;
271 /* Find last selected stream. */
272 for( i_last_selected = i_selected_es_loop;
273 p_input->pp_selected_es[i_last_selected]
274 && i_last_selected < INPUT_MAX_SELECTED_ES;
277 /* Exchange streams. */
278 p_input->pp_selected_es[i_selected_es_loop] =
279 p_input->pp_selected_es[i_last_selected];
280 p_input->pp_selected_es[i_last_selected] = NULL;
282 vlc_mutex_unlock( &p_input->es_lock );
288 /* We haven't found this PID in the current stream. */
289 vlc_mutex_unlock( &p_input->es_lock );
290 intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
296 /*****************************************************************************
297 * input_IsElemRecv: Test if an element given by its PID is currently received
298 *****************************************************************************
299 * Cannot return the position of the es in the pp_selected_es, for it can
300 * change once we have released the lock
301 *****************************************************************************/
302 boolean_t input_IsElemRecv( input_thread_t *p_input, int i_id )
304 boolean_t b_is_recv = 0;
307 /* Since this function is intended to be called by interface, lock the
309 vlc_mutex_lock( &p_input->es_lock );
312 while( i_index < INPUT_MAX_SELECTED_ES && !p_input->pp_selected_es[i_index] )
314 if( p_input->pp_selected_es[i_index]->i_id == i_id )
321 /* Unlock the structure */
322 vlc_mutex_unlock( &p_input->es_lock );