]> git.sesse.net Git - vlc/blob - src/input/input_ctrl.c.new
Pour la plus grande joie de tous, le client compile correctement. Attention
[vlc] / src / input / input_ctrl.c.new
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 #endif
48
49 /******************************************************************************
50  * input_AddPgrmElem: Start the extraction and the decoding of a program element
51  ******************************************************************************
52  * Add the element given by its PID in the list of PID to extract and spawn
53  * the decoding thread. 
54  * This function only modifies the table of selected es, but must NOT modify
55  * the table of ES itself.
56  ******************************************************************************/
57 int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
58 {
59     int i_es_loop, i_selected_es_loop;
60     
61     /* Since this function is intended to be called by interface, lock the
62      * elementary stream structure. */
63     vlc_mutex_lock( &p_input->es_lock );
64
65     /* Find out which PID we need. */
66     for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
67     {
68         if( p_input->p_es[i_es_loop].i_id == i_current_id )
69         {
70             if( p_input->p_es[i_es_loop].p_dec != NULL )
71             {
72                 /* We already have a decoder for that PID. */
73                 vlc_mutex_unlock( &p_input->es_lock );
74                 intf_ErrMsg("input error: PID %d already selected\n",
75                             i_current_id);
76                 return( -1 );
77             }
78
79             intf_DbgMsg("Requesting selection of PID %d\n",
80                         i_current_id);
81
82             /* Find a free spot in pp_selected_es. */
83             for( i_selected_es_loop = 0; p_input->pp_selected_es[i_selected_es_loop] != NULL
84                   && i_selected_es_loop < INPUT_MAX_SELECTED_ES; i_selected_es_loop++ );
85             
86             if( i_selected_es_loop == INPUT_MAX_SELECTED_ES )
87             {
88                 /* array full */
89                 vlc_mutex_unlock( &p_input->es_lock );
90                 intf_ErrMsg("input error: MAX_SELECTED_ES reached: try increasing it in config.h\n");
91                 return( -1 );
92             }
93
94             /* Don't decode PSI streams ! */
95             if( p_input->p_es[i_es_loop].b_psi )
96             {
97                 intf_ErrMsg("input_error: trying to decode PID %d which is the one of a PSI\n");
98                 vlc_mutex_unlock( &p_input->es_lock );
99                 return( -1 );
100             }
101             else
102             {
103                 /* Spawn the decoder. */
104                 switch( p_input->p_es[i_es_loop].i_type )
105                 {
106                     case MPEG1_AUDIO_ES:
107                     case MPEG2_AUDIO_ES:
108                         /* Spawn audio thread. */
109                         if( ((adec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
110                             adec_CreateThread( p_input )) == NULL )
111                         {
112                             intf_ErrMsg("Could not start audio decoder\n");
113                             vlc_mutex_unlock( &p_input->es_lock );
114                             return( -1 );
115                         }
116                         break;
117
118                     case MPEG1_VIDEO_ES:
119                     case MPEG2_VIDEO_ES:
120                         /* Spawn video thread. */
121 /* Les 2 pointeurs NULL ne doivent pas etre NULL sinon on segfault !!!! */
122                         if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
123                             vpar_CreateThread( p_input )) == NULL )
124                         {
125                             intf_ErrMsg("Could not start video parser\n");
126                             vlc_mutex_unlock( &p_input->es_lock );
127                             return( -1 );
128                         }
129                         break;
130
131                     default:
132                         /* That should never happen. */
133                         intf_DbgMsg("input error: unknown stream type (%d)\n",
134                                     p_input->p_es[i_es_loop].i_type);
135                         vlc_mutex_unlock( &p_input->es_lock );
136                         return( -1 );
137                         break;
138                 }
139
140                 /* Initialise the demux */
141                 p_input->p_es[i_es_loop].p_pes_packet = NULL;
142                 p_input->p_es[i_es_loop].i_continuity_counter = 0xFF;
143                 p_input->p_es[i_es_loop].b_random = 0;
144                 
145                 /* Mark stream to be demultiplexed. */
146                 intf_DbgMsg("Stream %d added in %d\n", i_current_id, i_selected_es_loop);
147                 p_input->pp_selected_es[i_selected_es_loop] = &p_input->p_es[i_es_loop];
148                 vlc_mutex_unlock( &p_input->es_lock );
149                 return( 0 );
150             }
151         }
152     }
153     
154     /* We haven't found this PID in the current stream. */
155     vlc_mutex_unlock( &p_input->es_lock );
156     intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
157     return( -1 );
158 }
159
160 /******************************************************************************
161  * input_DelPgrmElem: Stop the decoding of a program element
162  ******************************************************************************
163  * Stop the extraction of the element given by its PID and kill the associated
164  * decoder thread
165  * This function only modifies the table of selected es, but must NOT modify
166  * the table of ES itself.
167  ******************************************************************************/
168 int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
169 {
170     int i_selected_es_loop, i_last_selected;
171
172     /* Since this function is intended to be called by interface, lock the
173        structure. */
174     vlc_mutex_lock( &p_input->es_lock );
175
176     /* Find out which PID we need. */
177     for( i_selected_es_loop = 0; i_selected_es_loop < INPUT_MAX_SELECTED_ES;
178          i_selected_es_loop++ )
179     {
180         if( p_input->pp_selected_es[i_selected_es_loop] )
181         {
182             if( p_input->pp_selected_es[i_selected_es_loop]->i_id == i_current_id )
183             {
184                 if( !(p_input->pp_selected_es[i_selected_es_loop]->p_dec) )
185                 {
186                     /* We don't have a decoder for that PID. */
187                     vlc_mutex_unlock( &p_input->es_lock );
188                     intf_ErrMsg("input error: PID %d already deselected\n",
189                                 i_current_id);
190                     return( -1 );
191                 }
192
193                 intf_DbgMsg("input debug: requesting termination of PID %d\n",
194                             i_current_id);
195
196                 /* Cancel the decoder. */
197                 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
198                 {
199                     case MPEG1_AUDIO_ES:
200                     case MPEG2_AUDIO_ES:
201                         adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
202                         break;
203
204                     case MPEG1_VIDEO_ES:
205                     case MPEG2_VIDEO_ES:
206                         vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
207                         break;
208                 }
209
210                 /* Unmark stream. */
211                 p_input->pp_selected_es[i_selected_es_loop]->p_dec = NULL;
212
213                 /* Find last selected stream. */
214                 for( i_last_selected = i_selected_es_loop;
215                         p_input->pp_selected_es[i_last_selected]
216                         && i_last_selected < INPUT_MAX_SELECTED_ES;
217                      i_last_selected++ );
218
219                 /* Exchange streams. */
220                 p_input->pp_selected_es[i_selected_es_loop] = 
221                             p_input->pp_selected_es[i_last_selected];
222                 p_input->pp_selected_es[i_last_selected] = NULL;
223
224                 vlc_mutex_unlock( &p_input->es_lock );
225                 return( 0 );
226             }
227         }
228     }
229
230     /* We haven't found this PID in the current stream. */
231     vlc_mutex_unlock( &p_input->es_lock );
232     intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
233     return( -1 );
234 }
235
236
237
238 /******************************************************************************
239  * input_IsElemRecv: Test if an element given by its PID is currently received
240  ******************************************************************************
241  * Cannot return the position of the es in the pp_selected_es, for it can
242  * change once we have released the lock
243  ******************************************************************************/
244 boolean_t input_IsElemRecv( input_thread_t *p_input, int i_id )
245 {
246   boolean_t b_is_recv = 0;
247     int i_index = 0;
248
249    /* Since this function is intended to be called by interface, lock the
250        structure. */
251     vlc_mutex_lock( &p_input->es_lock );
252
253     /* Scan the table */
254     while( i_index < INPUT_MAX_SELECTED_ES && !p_input->pp_selected_es[i_index] )
255     {
256       if( p_input->pp_selected_es[i_index]->i_id == i_id )
257       {
258         b_is_recv = 1;
259         break;
260       }
261     }
262
263     /* Unlock the structure */
264     vlc_mutex_unlock( &p_input->es_lock );
265
266     return( b_is_recv );
267 }