]> git.sesse.net Git - vlc/blob - src/input/input_ctrl.c
41c7b015a67236d99a3b3578a27401b20d906d6f
[vlc] / src / input / input_ctrl.c
1 /*****************************************************************************
2  * input_ctrl.c: Decoder control
3  * Controls the extraction and the decoding of the programs elements carried
4  * within a stream.
5  *****************************************************************************
6  * Copyright (C) 1999, 2000 VideoLAN
7  *
8  * Authors:
9  *
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.
14  *
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.
19  *
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  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <sys/types.h>                        /* on BSD, uio.h needs types.h */
30 #include <sys/uio.h>                                            /* "input.h" */
31
32 #include <netinet/in.h>                                             /* ntohs */
33
34 #include "common.h"
35 #include "config.h"
36 #include "mtime.h"
37 #include "threads.h"
38 #include "intf_msg.h"
39 #include "debug.h"
40
41 #include "input.h"
42 #include "input_netlist.h"
43 #include "decoder_fifo.h"
44
45 #include "audio_output.h"                                   /* aout_thread_t */
46
47 #include "audio_decoder.h"                                  /* adec_thread_t */
48
49 #include "ac3_decoder.h"              /* ac3dec_t (for ac3_decoder_thread.h) */
50 #include "ac3_decoder_thread.h"                           /* ac3dec_thread_t */
51
52 #include "video.h"                          /* picture_t (for video_output.h) */
53 #include "video_output.h"                                   /* vout_thread_t */
54
55 #include "vdec_idct.h"                     /* dctelem_t (for video_parser.h) */
56 #include "vdec_motion.h"                  /* f_motion_t (for video_parser.h) */
57 #include "vpar_blocks.h"                /* macroblock_t (for video_parser.h) */
58 #include "vpar_headers.h"                 /* sequence_t (for video_parser.h) */
59 #include "vpar_synchro.h"            /* video_synchro_t (for video_parser.h) */
60 #include "video_parser.h"                                   /* vpar_thread_t */
61
62 #include "spu_decoder.h"                                  /* spudec_thread_t */
63
64 /*****************************************************************************
65  * input_AddPgrmElem: Start the extraction and the decoding of a program element
66  *****************************************************************************
67  * Add the element given by its PID in the list of PID to extract and spawn
68  * the decoding thread.
69  * This function only modifies the table of selected es, but must NOT modify
70  * the table of ES itself.
71  *****************************************************************************/
72 int input_AddPgrmElem( input_thread_t *p_input, int i_current_id )
73 {
74     int i_es_loop, i_selected_es_loop;
75
76     /* Since this function is intended to be called by interface, lock the
77      * elementary stream structure. */
78     vlc_mutex_lock( &p_input->es_lock );
79
80     /* Find out which PID we need. */
81     for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
82     {
83         if( p_input->p_es[i_es_loop].i_id == i_current_id )
84         {
85             if( p_input->p_es[i_es_loop].p_dec != NULL )
86             {
87                 /* We already have a decoder for that PID. */
88                 vlc_mutex_unlock( &p_input->es_lock );
89                 intf_ErrMsg("input error: PID %d already selected\n",
90                             i_current_id);
91                 return( -1 );
92             }
93
94             intf_DbgMsg("Requesting selection of PID %d\n",
95                         i_current_id);
96
97             /* Find a free spot in pp_selected_es. */
98             for( i_selected_es_loop = 0; p_input->pp_selected_es[i_selected_es_loop] != NULL
99                   && i_selected_es_loop < INPUT_MAX_SELECTED_ES; i_selected_es_loop++ );
100
101             if( i_selected_es_loop == INPUT_MAX_SELECTED_ES )
102             {
103                 /* array full */
104                 vlc_mutex_unlock( &p_input->es_lock );
105                 intf_ErrMsg("input error: MAX_SELECTED_ES reached: try increasing it in config.h\n");
106                 return( -1 );
107             }
108
109             /* Don't decode PSI streams ! */
110             if( p_input->p_es[i_es_loop].b_psi )
111             {
112                 intf_ErrMsg("input_error: trying to decode PID %d which is the one of a PSI\n", i_current_id);
113                 vlc_mutex_unlock( &p_input->es_lock );
114                 return( -1 );
115             }
116             else
117             {
118                 /* Spawn the decoder. */
119                 switch( p_input->p_es[i_es_loop].i_type )
120                 {
121                     case AC3_AUDIO_ES:
122                         /* Spawn ac3 thread */
123                         if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
124                             ac3dec_CreateThread(p_input)) == NULL )
125                         {
126                             intf_ErrMsg( "Could not start ac3 decoder\n" );
127                             vlc_mutex_unlock( &p_input->es_lock );
128                             return( -1 );
129                         }
130                         break;
131
132                     case DVD_SPU_ES:
133                         /* Spawn spu thread */
134                         if ( ((spudec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
135                             spudec_CreateThread(p_input)) == NULL )
136                         {
137                             intf_ErrMsg( "Could not start spu decoder\n" );
138                             vlc_mutex_unlock( &p_input->es_lock );
139                             return( -1 );
140                         }
141                         break;
142
143                     case MPEG1_AUDIO_ES:
144                     case MPEG2_AUDIO_ES:
145                         /* Spawn audio thread. */
146                         if( ((adec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
147                             adec_CreateThread( p_input )) == NULL )
148                         {
149                             intf_ErrMsg("Could not start audio decoder\n");
150                             vlc_mutex_unlock( &p_input->es_lock );
151                             return( -1 );
152                         }
153                         break;
154
155                     case MPEG1_VIDEO_ES:
156                     case MPEG2_VIDEO_ES:
157                         /* Spawn video thread. */
158 #ifdef OLD_DECODER
159                         if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
160                             vdec_CreateThread( p_input )) == NULL )
161 #else
162                         if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
163                             vpar_CreateThread( p_input )) == NULL )
164 #endif
165                         {
166 #ifdef OLD_DECODER
167                             intf_ErrMsg("Could not start video decoder\n");
168 #else
169                             intf_ErrMsg("Could not start video parser\n");
170 #endif
171                             vlc_mutex_unlock( &p_input->es_lock );
172                             return( -1 );
173                         }
174                         break;
175
176                     default:
177                         /* That should never happen. */
178                         intf_DbgMsg("input error: unknown stream type (0x%.2x)\n",
179                                     p_input->p_es[i_es_loop].i_type);
180                         vlc_mutex_unlock( &p_input->es_lock );
181                         return( -1 );
182                         break;
183                 }
184
185                 /* Initialise the demux */
186                 p_input->p_es[i_es_loop].p_pes_packet = NULL;
187                 p_input->p_es[i_es_loop].i_continuity_counter = 0xff;
188                 p_input->p_es[i_es_loop].b_random = 0;
189
190                 /* Mark stream to be demultiplexed. */
191                 intf_DbgMsg("Stream %d added in %d\n", i_current_id, i_selected_es_loop);
192                 p_input->pp_selected_es[i_selected_es_loop] = &p_input->p_es[i_es_loop];
193                 vlc_mutex_unlock( &p_input->es_lock );
194                 return( 0 );
195             }
196         }
197     }
198
199     /* We haven't found this PID in the current stream. */
200     vlc_mutex_unlock( &p_input->es_lock );
201     intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
202     return( -1 );
203 }
204
205 /*****************************************************************************
206  * input_DelPgrmElem: Stop the decoding of a program element
207  *****************************************************************************
208  * Stop the extraction of the element given by its PID and kill the associated
209  * decoder thread
210  * This function only modifies the table of selected es, but must NOT modify
211  * the table of ES itself.
212  *****************************************************************************/
213 int input_DelPgrmElem( input_thread_t *p_input, int i_current_id )
214 {
215     int i_selected_es_loop, i_last_selected;
216
217     /* Since this function is intended to be called by interface, lock the
218        structure. */
219     vlc_mutex_lock( &p_input->es_lock );
220
221     /* Find out which PID we need. */
222     for( i_selected_es_loop = 0; i_selected_es_loop < INPUT_MAX_SELECTED_ES;
223          i_selected_es_loop++ )
224     {
225         if( p_input->pp_selected_es[i_selected_es_loop] )
226         {
227             if( p_input->pp_selected_es[i_selected_es_loop]->i_id == i_current_id )
228             {
229                 if( !(p_input->pp_selected_es[i_selected_es_loop]->p_dec) )
230                 {
231                     /* We don't have a decoder for that PID. */
232                     vlc_mutex_unlock( &p_input->es_lock );
233                     intf_ErrMsg("input error: PID %d already deselected\n",
234                                 i_current_id);
235                     return( -1 );
236                 }
237
238                 intf_DbgMsg("input debug: requesting termination of PID %d\n",
239                             i_current_id);
240
241                 /* Cancel the decoder. */
242                 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
243                 {
244                     case AC3_AUDIO_ES:
245                         ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
246                         break;
247
248                     case DVD_SPU_ES:
249                         spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
250                         break;
251
252                     case MPEG1_AUDIO_ES:
253                     case MPEG2_AUDIO_ES:
254                         adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
255                         break;
256
257                     case MPEG1_VIDEO_ES:
258                     case MPEG2_VIDEO_ES:
259 #ifdef OLD_DECODER
260                         vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
261 #else
262                         vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
263 #endif
264                         break;
265                 }
266
267                 /* Unmark stream. */
268                 p_input->pp_selected_es[i_selected_es_loop]->p_dec = NULL;
269
270                 /* Find last selected stream. */
271                 for( i_last_selected = i_selected_es_loop;
272                         p_input->pp_selected_es[i_last_selected]
273                         && i_last_selected < INPUT_MAX_SELECTED_ES;
274                      i_last_selected++ );
275
276                 /* Exchange streams. */
277                 p_input->pp_selected_es[i_selected_es_loop] =
278                             p_input->pp_selected_es[i_last_selected];
279                 p_input->pp_selected_es[i_last_selected] = NULL;
280
281                 vlc_mutex_unlock( &p_input->es_lock );
282                 return( 0 );
283             }
284         }
285     }
286
287     /* We haven't found this PID in the current stream. */
288     vlc_mutex_unlock( &p_input->es_lock );
289     intf_ErrMsg("input error: can't find PID %d\n", i_current_id);
290     return( -1 );
291 }
292
293
294
295 /*****************************************************************************
296  * input_IsElemRecv: Test if an element given by its PID is currently received
297  *****************************************************************************
298  * Cannot return the position of the es in the pp_selected_es, for it can
299  * change once we have released the lock
300  *****************************************************************************/
301 boolean_t input_IsElemRecv( input_thread_t *p_input, int i_id )
302 {
303   boolean_t b_is_recv = 0;
304     int i_index = 0;
305
306    /* Since this function is intended to be called by interface, lock the
307        structure. */
308     vlc_mutex_lock( &p_input->es_lock );
309
310     /* Scan the table */
311     while( i_index < INPUT_MAX_SELECTED_ES && !p_input->pp_selected_es[i_index] )
312     {
313       if( p_input->pp_selected_es[i_index]->i_id == i_id )
314       {
315         b_is_recv = 1;
316         break;
317       }
318     }
319
320     /* Unlock the structure */
321     vlc_mutex_unlock( &p_input->es_lock );
322
323     return( b_is_recv );
324 }