]> git.sesse.net Git - vlc/blob - src/input/input_ctrl.c
96505db00305e3743ed12bb9705b4e13fa36e775
[vlc] / src / input / input_ctrl.c
1 /*******************************************************************************
2  * input_ctrl.c: Decodeur control
3  * (c)1999 VideoLAN
4  *******************************************************************************
5  * Control the extraction and the decoding of the programs elements carried in
6  * a stream.
7  *******************************************************************************/
8
9 /*******************************************************************************
10  * Preamble
11  *******************************************************************************/
12
13 #include "vlc.h"
14
15 #if 0
16 #include <errno.h>
17 #include <sys/uio.h>                                                 /* iovec */
18 #include <stdlib.h>                               /* atoi(), malloc(), free() */
19 #include <string.h>
20 #include <stdio.h>
21 #include <unistd.h>
22
23 #include <X11/Xlib.h>
24 #include <X11/extensions/XShm.h>
25 #include <sys/soundcard.h>
26 #include <netinet/in.h>                                              /* ntohs */
27
28 #include "common.h"
29 #include "config.h"
30 #include "mtime.h"
31 #include "vlc_thread.h"
32 #include "intf_msg.h"
33 #include "debug.h"
34
35 #include "input.h"
36 #include "input_netlist.h"
37
38 #include "decoder_fifo.h"
39
40 #include "audio_output.h"
41 #include "audio_dsp.h"
42 #include "audio_decoder.h"
43
44 #include "video.h"
45 #include "video_output.h"
46 #include "video_decoder.h"
47
48 #endif
49
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 )
59 {
60     int i_es_loop, i_selected_es_loop;
61     
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 );
65
66     /* Find out which PID we need. */
67     for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
68     {
69         if( p_input->p_es[i_es_loop].i_id == i_current_id )
70         {
71             if( p_input->p_es[i_es_loop].p_dec != NULL )
72             {
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",
76                             i_current_id);
77                 return( -1 );
78             }
79
80             intf_DbgMsg("Requesting selection of PID %d\n",
81                         i_current_id);
82
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++ );
86             
87             if( i_selected_es_loop == INPUT_MAX_SELECTED_ES )
88             {
89                 /* array full */
90                 vlc_mutex_unlock( &p_input->es_lock );
91                 intf_ErrMsg("input error: MAX_SELECTED_ES reached: try increasing it in config.h\n");
92                 return( -1 );
93             }
94
95             /* Don't decode PSI streams ! */
96             if( p_input->p_es[i_es_loop].b_psi )
97             {
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 );
100                 return( -1 );
101             }
102             else
103             {
104                 /* Spawn the decoder. */
105                 switch( p_input->p_es[i_es_loop].i_type )
106                 {
107                     case AC3_AUDIO_ES:
108                         /* Spawn ac3 thread */
109                         if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
110                             ac3dec_CreateThread(p_input)) == NULL )
111                         {
112                             intf_ErrMsg( "Could not start ac3 decoder\n" );
113                             vlc_mutex_unlock( &p_input->es_lock );
114                             return( -1 );
115                         }
116                         break;
117
118                     case MPEG1_AUDIO_ES:
119                     case MPEG2_AUDIO_ES:
120                         /* Spawn audio thread. */
121                         if( ((adec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
122                             adec_CreateThread( p_input )) == NULL )
123                         {
124                             intf_ErrMsg("Could not start audio decoder\n");
125                             vlc_mutex_unlock( &p_input->es_lock );
126                             return( -1 );
127                         }
128                         break;
129
130                     case MPEG1_VIDEO_ES:
131                     case MPEG2_VIDEO_ES:
132                         /* Spawn video thread. */
133 /* Les 2 pointeurs NULL ne doivent pas etre NULL sinon on segfault !!!! */
134 #ifdef OLD_DECODER
135                         if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
136                             vdec_CreateThread( p_input )) == NULL )
137 #else
138                         if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
139                             vpar_CreateThread( p_input )) == NULL )
140 #endif
141                         {
142 #ifdef OLD_DECODER
143                             intf_ErrMsg("Could not start video decoder\n");
144 #else
145                             intf_ErrMsg("Could not start video parser\n");
146 #endif
147                             vlc_mutex_unlock( &p_input->es_lock );
148                             return( -1 );
149                         }
150                         break;
151
152                     default:
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 );
157                         return( -1 );
158                         break;
159                 }
160
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;
165                 
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 );
170                 return( 0 );
171             }
172         }
173     }
174     
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);
178     return( -1 );
179 }
180
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
185  * decoder thread
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 )
190 {
191     int i_selected_es_loop, i_last_selected;
192
193     /* Since this function is intended to be called by interface, lock the
194        structure. */
195     vlc_mutex_lock( &p_input->es_lock );
196
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++ )
200     {
201         if( p_input->pp_selected_es[i_selected_es_loop] )
202         {
203             if( p_input->pp_selected_es[i_selected_es_loop]->i_id == i_current_id )
204             {
205                 if( !(p_input->pp_selected_es[i_selected_es_loop]->p_dec) )
206                 {
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",
210                                 i_current_id);
211                     return( -1 );
212                 }
213
214                 intf_DbgMsg("input debug: requesting termination of PID %d\n",
215                             i_current_id);
216
217                 /* Cancel the decoder. */
218                 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
219                 {
220                     case AC3_AUDIO_ES:
221                         ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
222                         break;
223
224                     case MPEG1_AUDIO_ES:
225                     case MPEG2_AUDIO_ES:
226                         adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
227                         break;
228
229                     case MPEG1_VIDEO_ES:
230                     case MPEG2_VIDEO_ES:
231 #ifdef OLD_DECODER
232                         vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
233 #else
234                         vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
235 #endif
236                         break;
237                 }
238
239                 /* Unmark stream. */
240                 p_input->pp_selected_es[i_selected_es_loop]->p_dec = NULL;
241
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;
246                      i_last_selected++ );
247
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;
252
253                 vlc_mutex_unlock( &p_input->es_lock );
254                 return( 0 );
255             }
256         }
257     }
258
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);
262     return( -1 );
263 }
264
265
266
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 )
274 {
275   boolean_t b_is_recv = 0;
276     int i_index = 0;
277
278    /* Since this function is intended to be called by interface, lock the
279        structure. */
280     vlc_mutex_lock( &p_input->es_lock );
281
282     /* Scan the table */
283     while( i_index < INPUT_MAX_SELECTED_ES && !p_input->pp_selected_es[i_index] )
284     {
285       if( p_input->pp_selected_es[i_index]->i_id == i_id )
286       {
287         b_is_recv = 1;
288         break;
289       }
290     }
291
292     /* Unlock the structure */
293     vlc_mutex_unlock( &p_input->es_lock );
294
295     return( b_is_recv );
296 }