1 /*******************************************************************************
2 * input_ctrl.c: Decodeur control
4 *******************************************************************************
5 * Control the extraction and the decoding of the programs elements carried in
7 *******************************************************************************/
9 /*******************************************************************************
11 *******************************************************************************/
17 #include <sys/uio.h> /* iovec */
18 #include <stdlib.h> /* atoi(), malloc(), free() */
24 #include <X11/extensions/XShm.h>
25 #include <sys/soundcard.h>
26 #include <netinet/in.h> /* ntohs */
31 #include "vlc_thread.h"
36 #include "input_netlist.h"
38 #include "decoder_fifo.h"
40 #include "audio_output.h"
41 #include "audio_dsp.h"
42 #include "audio_decoder.h"
45 #include "video_output.h"
46 #include "video_decoder.h"
50 /******************************************************************************
51 * input_AddPgrmElem: Start the extraction and the decoding of a program element
52 ******************************************************************************
53 * Add the element given by its PID in the list of PID to extract and spawn
54 * the decoding thread.
55 * This function only modifies the table of selected es, but must NOT modify
56 * the table of ES itself.
57 ******************************************************************************/
58 int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
60 int i_es_loop, i_selected_es_loop;
62 /* Since this function is intended to be called by interface, lock the
63 * elementary stream structure. */
64 vlc_mutex_lock( &p_input->es_lock );
66 /* Find out which PID we need. */
67 for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
69 if( p_input->p_es[i_es_loop].i_id == i_current_id )
71 if( p_input->p_es[i_es_loop].p_dec != NULL )
73 /* We already have a decoder for that PID. */
74 vlc_mutex_unlock( &p_input->es_lock );
75 intf_ErrMsg("input error: PID %d already selected\n",
80 intf_DbgMsg("Requesting selection of PID %d\n",
83 /* Find a free spot in pp_selected_es. */
84 for( i_selected_es_loop = 0; p_input->pp_selected_es[i_selected_es_loop] != NULL
85 && i_selected_es_loop < INPUT_MAX_SELECTED_ES; i_selected_es_loop++ );
87 if( i_selected_es_loop == INPUT_MAX_SELECTED_ES )
90 vlc_mutex_unlock( &p_input->es_lock );
91 intf_ErrMsg("input error: MAX_SELECTED_ES reached: try increasing it in config.h\n");
95 /* Don't decode PSI streams ! */
96 if( p_input->p_es[i_es_loop].b_psi )
98 intf_ErrMsg("input_error: trying to decode PID %d which is the one of a PSI\n", i_current_id);
99 vlc_mutex_unlock( &p_input->es_lock );
104 /* Spawn the decoder. */
105 switch( p_input->p_es[i_es_loop].i_type )
108 /* Spawn ac3 thread */
109 if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
110 ac3dec_CreateThread(p_input)) == NULL )
112 intf_ErrMsg( "Could not start ac3 decoder\n" );
113 vlc_mutex_unlock( &p_input->es_lock );
120 /* Spawn audio thread. */
121 if( ((adec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
122 adec_CreateThread( p_input )) == NULL )
124 intf_ErrMsg("Could not start audio decoder\n");
125 vlc_mutex_unlock( &p_input->es_lock );
132 /* Spawn video thread. */
133 /* Les 2 pointeurs NULL ne doivent pas etre NULL sinon on segfault !!!! */
135 if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
136 vdec_CreateThread( p_input )) == NULL )
138 if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
139 vpar_CreateThread( p_input )) == NULL )
143 intf_ErrMsg("Could not start video decoder\n");
145 intf_ErrMsg("Could not start video parser\n");
147 vlc_mutex_unlock( &p_input->es_lock );
153 /* That should never happen. */
154 intf_DbgMsg("input error: unknown stream type (0x%.2x)\n",
155 p_input->p_es[i_es_loop].i_type);
156 vlc_mutex_unlock( &p_input->es_lock );
161 /* Initialise the demux */
162 p_input->p_es[i_es_loop].p_pes_packet = NULL;
163 p_input->p_es[i_es_loop].i_continuity_counter = 0xFF;
164 p_input->p_es[i_es_loop].b_random = 0;
166 /* Mark stream to be demultiplexed. */
167 intf_DbgMsg("Stream %d added in %d\n", i_current_id, i_selected_es_loop);
168 p_input->pp_selected_es[i_selected_es_loop] = &p_input->p_es[i_es_loop];
169 vlc_mutex_unlock( &p_input->es_lock );
175 /* We haven't found this PID in the current stream. */
176 vlc_mutex_unlock( &p_input->es_lock );
177 intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
181 /******************************************************************************
182 * input_DelPgrmElem: Stop the decoding of a program element
183 ******************************************************************************
184 * Stop the extraction of the element given by its PID and kill the associated
186 * This function only modifies the table of selected es, but must NOT modify
187 * the table of ES itself.
188 ******************************************************************************/
189 int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
191 int i_selected_es_loop, i_last_selected;
193 /* Since this function is intended to be called by interface, lock the
195 vlc_mutex_lock( &p_input->es_lock );
197 /* Find out which PID we need. */
198 for( i_selected_es_loop = 0; i_selected_es_loop < INPUT_MAX_SELECTED_ES;
199 i_selected_es_loop++ )
201 if( p_input->pp_selected_es[i_selected_es_loop] )
203 if( p_input->pp_selected_es[i_selected_es_loop]->i_id == i_current_id )
205 if( !(p_input->pp_selected_es[i_selected_es_loop]->p_dec) )
207 /* We don't have a decoder for that PID. */
208 vlc_mutex_unlock( &p_input->es_lock );
209 intf_ErrMsg("input error: PID %d already deselected\n",
214 intf_DbgMsg("input debug: requesting termination of PID %d\n",
217 /* Cancel the decoder. */
218 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
221 ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
226 adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
232 vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
234 vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
240 p_input->pp_selected_es[i_selected_es_loop]->p_dec = NULL;
242 /* Find last selected stream. */
243 for( i_last_selected = i_selected_es_loop;
244 p_input->pp_selected_es[i_last_selected]
245 && i_last_selected < INPUT_MAX_SELECTED_ES;
248 /* Exchange streams. */
249 p_input->pp_selected_es[i_selected_es_loop] =
250 p_input->pp_selected_es[i_last_selected];
251 p_input->pp_selected_es[i_last_selected] = NULL;
253 vlc_mutex_unlock( &p_input->es_lock );
259 /* We haven't found this PID in the current stream. */
260 vlc_mutex_unlock( &p_input->es_lock );
261 intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
267 /******************************************************************************
268 * input_IsElemRecv: Test if an element given by its PID is currently received
269 ******************************************************************************
270 * Cannot return the position of the es in the pp_selected_es, for it can
271 * change once we have released the lock
272 ******************************************************************************/
273 boolean_t input_IsElemRecv( input_thread_t *p_input, int i_id )
275 boolean_t b_is_recv = 0;
278 /* Since this function is intended to be called by interface, lock the
280 vlc_mutex_lock( &p_input->es_lock );
283 while( i_index < INPUT_MAX_SELECTED_ES && !p_input->pp_selected_es[i_index] )
285 if( p_input->pp_selected_es[i_index]->i_id == i_id )
292 /* Unlock the structure */
293 vlc_mutex_unlock( &p_input->es_lock );