]> git.sesse.net Git - vlc/blob - src/input/input_ctrl.c
D�but du portage BeOS. Beaucoup de fuchiers ont �t� modifi� car il a fallu
[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 "threads.h"
35 #include "common.h"
36 #include "config.h"
37 #include "mtime.h"
38 #include "intf_msg.h"
39 #include "plugins.h"
40 #include "debug.h"
41
42 #include "input.h"
43 #include "input_netlist.h"
44 #include "decoder_fifo.h"
45
46 #include "audio_output.h"                                   /* aout_thread_t */
47
48 #include "audio_decoder.h"                                  /* adec_thread_t */
49
50 #include "ac3_decoder.h"              /* ac3dec_t (for ac3_decoder_thread.h) */
51 #include "ac3_decoder_thread.h"                           /* ac3dec_thread_t */
52
53 #include "video.h"                          /* picture_t (for video_output.h) */
54 #include "video_output.h"                                   /* vout_thread_t */
55
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 */
62
63 #include "spu_decoder.h"                                  /* spudec_thread_t */
64
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 )
74 {
75     int i_es_loop, i_selected_es_loop;
76
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 );
80
81     /* Find out which PID we need. */
82     for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
83     {
84         if( p_input->p_es[i_es_loop].i_id == i_current_id )
85         {
86             if( p_input->p_es[i_es_loop].p_dec != NULL )
87             {
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",
91                             i_current_id);
92                 return( -1 );
93             }
94
95             intf_DbgMsg("Requesting selection of PID %d\n",
96                         i_current_id);
97
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++ );
101
102             if( i_selected_es_loop == INPUT_MAX_SELECTED_ES )
103             {
104                 /* array full */
105                 vlc_mutex_unlock( &p_input->es_lock );
106                 intf_ErrMsg("input error: MAX_SELECTED_ES reached: try increasing it in config.h\n");
107                 return( -1 );
108             }
109
110             /* Don't decode PSI streams ! */
111             if( p_input->p_es[i_es_loop].b_psi )
112             {
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 );
115                 return( -1 );
116             }
117             else
118             {
119                 /* Spawn the decoder. */
120                 switch( p_input->p_es[i_es_loop].i_type )
121                 {
122                     case AC3_AUDIO_ES:
123                         /* Spawn ac3 thread */
124                         if ( ((ac3dec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
125                             ac3dec_CreateThread(p_input)) == NULL )
126                         {
127                             intf_ErrMsg( "Could not start ac3 decoder\n" );
128                             vlc_mutex_unlock( &p_input->es_lock );
129                             return( -1 );
130                         }
131                         break;
132
133                     case DVD_SPU_ES:
134                         /* Spawn spu thread */
135                         if ( ((spudec_thread_t *)(p_input->p_es[i_es_loop].p_dec) =
136                             spudec_CreateThread(p_input)) == NULL )
137                         {
138                             intf_ErrMsg( "Could not start spu decoder\n" );
139                             vlc_mutex_unlock( &p_input->es_lock );
140                             return( -1 );
141                         }
142                         break;
143
144                     case MPEG1_AUDIO_ES:
145                     case MPEG2_AUDIO_ES:
146                         /* Spawn audio thread. */
147                         if( ((adec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
148                             adec_CreateThread( p_input )) == NULL )
149                         {
150                             intf_ErrMsg("Could not start audio decoder\n");
151                             vlc_mutex_unlock( &p_input->es_lock );
152                             return( -1 );
153                         }
154                         break;
155
156                     case MPEG1_VIDEO_ES:
157                     case MPEG2_VIDEO_ES:
158                         /* Spawn video thread. */
159 #ifdef OLD_DECODER
160                         if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
161                             vdec_CreateThread( p_input )) == NULL )
162 #else
163                         if( ((vpar_thread_t*)(p_input->p_es[i_es_loop].p_dec) =
164                             vpar_CreateThread( p_input )) == NULL )
165 #endif
166                         {
167 #ifdef OLD_DECODER
168                             intf_ErrMsg("Could not start video decoder\n");
169 #else
170                             intf_ErrMsg("Could not start video parser\n");
171 #endif
172                             vlc_mutex_unlock( &p_input->es_lock );
173                             return( -1 );
174                         }
175                         break;
176
177                     default:
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 );
182                         return( -1 );
183                         break;
184                 }
185
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;
190
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 );
195                 return( 0 );
196             }
197         }
198     }
199
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);
203     return( -1 );
204 }
205
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
210  * decoder thread
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 )
215 {
216     int i_selected_es_loop, i_last_selected;
217
218     /* Since this function is intended to be called by interface, lock the
219        structure. */
220     vlc_mutex_lock( &p_input->es_lock );
221
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++ )
225     {
226         if( p_input->pp_selected_es[i_selected_es_loop] )
227         {
228             if( p_input->pp_selected_es[i_selected_es_loop]->i_id == i_current_id )
229             {
230                 if( !(p_input->pp_selected_es[i_selected_es_loop]->p_dec) )
231                 {
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",
235                                 i_current_id);
236                     return( -1 );
237                 }
238
239                 intf_DbgMsg("input debug: requesting termination of PID %d\n",
240                             i_current_id);
241
242                 /* Cancel the decoder. */
243                 switch( p_input->pp_selected_es[i_selected_es_loop]->i_type )
244                 {
245                     case AC3_AUDIO_ES:
246                         ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
247                         break;
248
249                     case DVD_SPU_ES:
250                         spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
251                         break;
252
253                     case MPEG1_AUDIO_ES:
254                     case MPEG2_AUDIO_ES:
255                         adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) );
256                         break;
257
258                     case MPEG1_VIDEO_ES:
259                     case MPEG2_VIDEO_ES:
260 #ifdef OLD_DECODER
261                         vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
262 #else
263                         vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ );
264 #endif
265                         break;
266                 }
267
268                 /* Unmark stream. */
269                 p_input->pp_selected_es[i_selected_es_loop]->p_dec = NULL;
270
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;
275                      i_last_selected++ );
276
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;
281
282                 vlc_mutex_unlock( &p_input->es_lock );
283                 return( 0 );
284             }
285         }
286     }
287
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);
291     return( -1 );
292 }
293
294
295
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 )
303 {
304   boolean_t b_is_recv = 0;
305     int i_index = 0;
306
307    /* Since this function is intended to be called by interface, lock the
308        structure. */
309     vlc_mutex_lock( &p_input->es_lock );
310
311     /* Scan the table */
312     while( i_index < INPUT_MAX_SELECTED_ES && !p_input->pp_selected_es[i_index] )
313     {
314       if( p_input->pp_selected_es[i_index]->i_id == i_id )
315       {
316         b_is_recv = 1;
317         break;
318       }
319     }
320
321     /* Unlock the structure */
322     vlc_mutex_unlock( &p_input->es_lock );
323
324     return( b_is_recv );
325 }