]> git.sesse.net Git - vlc/blob - src/input/input_dec.c
* include/vlc_codec.h: defines decoders/encoders related structures here.
[vlc] / src / input / input_dec.c
1 /*****************************************************************************
2  * input_dec.c: Functions for the management of decoders
3  *****************************************************************************
4  * Copyright (C) 1999-2001 VideoLAN
5  * $Id: input_dec.c,v 1.64 2003/10/08 21:01:07 gbazin Exp $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>
28 #include <string.h>                                    /* memcpy(), memset() */
29
30 #include <vlc/vlc.h>
31 #include <vlc/decoder.h>
32
33 #include "input_ext-intf.h"
34 #include "input_ext-plugins.h"
35
36 static decoder_t * CreateDecoder( input_thread_t *, es_descriptor_t * );
37 static int         DecoderThread( decoder_t * );
38 static void        DeleteDecoder( decoder_t * );
39
40 /*****************************************************************************
41  * input_RunDecoder: spawns a new decoder thread
42  *****************************************************************************/
43 decoder_fifo_t * input_RunDecoder( input_thread_t * p_input,
44                                    es_descriptor_t * p_es )
45 {
46     vlc_value_t    val;
47     decoder_t      *p_dec;
48     int            i_priority;
49
50     /* Create the decoder configuration structure */
51     p_dec = CreateDecoder( p_input, p_es );
52     if( p_dec == NULL )
53     {
54         msg_Err( p_input, "could not create decoder" );
55         return NULL;
56     }
57
58     p_dec->p_module = NULL;
59
60     /* If we are in sout mode, search for packetizer module */
61     var_Get( p_input, "sout", &val );
62     if( !p_es->b_force_decoder && val.psz_string && *val.psz_string )
63     {
64         free( val.psz_string );
65         val.b_bool = VLC_TRUE;
66
67         if( p_es->i_cat == AUDIO_ES )
68         {
69             var_Get( p_input, "sout-audio", &val );
70         }
71         else if( p_es->i_cat == VIDEO_ES )
72         {
73             var_Get( p_input, "sout-video", &val );
74         }
75
76         if( val.b_bool )
77         {
78             p_dec->p_module =
79                 module_Need( p_dec, "packetizer", "$packetizer" );
80         }
81     }
82     else
83     {
84         /* default Get a suitable decoder module */
85         p_dec->p_module = module_Need( p_dec, "decoder", "$codec" );
86
87         if( val.psz_string ) free( val.psz_string );
88     }
89
90     if( p_dec->p_module == NULL )
91     {
92         msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n"
93                  "VLC probably does not support this sound or video format.",
94                  (char*)&p_dec->p_fifo->i_fourcc );
95
96         DeleteDecoder( p_dec );
97         vlc_object_destroy( p_dec );
98         return NULL;
99     }
100
101     if ( p_es->i_cat == AUDIO_ES )
102     {
103         i_priority = VLC_THREAD_PRIORITY_AUDIO;
104     }
105     else
106     {
107         i_priority = VLC_THREAD_PRIORITY_VIDEO;
108     }
109
110     /* Spawn the decoder thread */
111     if( vlc_thread_create( p_dec, "decoder", DecoderThread,
112                            i_priority, VLC_FALSE ) )
113     {
114         msg_Err( p_dec, "cannot spawn decoder thread \"%s\"",
115                          p_dec->p_module->psz_object_name );
116         module_Unneed( p_dec, p_dec->p_module );
117         DeleteDecoder( p_dec );
118         vlc_object_destroy( p_dec );
119         return NULL;
120     }
121
122     p_input->stream.b_changed = 1;
123
124     return p_dec->p_fifo;
125 }
126
127 /*****************************************************************************
128  * input_EndDecoder: kills a decoder thread and waits until it's finished
129  *****************************************************************************/
130 void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
131 {
132     int i_dummy;
133     decoder_t *p_dec = p_es->p_decoder_fifo->p_dec;
134
135     p_es->p_decoder_fifo->b_die = 1;
136
137     /* Make sure the thread leaves the NextDataPacket() function by
138      * sending it a few null packets. */
139     for( i_dummy = 0; i_dummy < PADDING_PACKET_NUMBER; i_dummy++ )
140     {
141         input_NullPacket( p_input, p_es );
142     }
143
144     if( p_es->p_pes != NULL )
145     {
146         input_DecodePES( p_es->p_decoder_fifo, p_es->p_pes );
147     }
148
149     /* Waiting for the thread to exit */
150     /* I thought that unlocking was better since thread join can be long
151      * but it actually creates late pictures and freezes --stef */
152     /* vlc_mutex_unlock( &p_input->stream.stream_lock ); */
153     vlc_thread_join( p_dec );
154     /* vlc_mutex_lock( &p_input->stream.stream_lock ); */
155
156     /* Unneed module */
157     module_Unneed( p_dec, p_dec->p_module );
158
159     /* Delete decoder configuration */
160     DeleteDecoder( p_dec );
161
162     /* Delete the decoder */
163     vlc_object_destroy( p_dec );
164
165     /* Tell the input there is no more decoder */
166     p_es->p_decoder_fifo = NULL;
167
168     p_input->stream.b_changed = 1;
169 }
170
171 /*****************************************************************************
172  * input_DecodePES
173  *****************************************************************************
174  * Put a PES in the decoder's fifo.
175  *****************************************************************************/
176 void input_DecodePES( decoder_fifo_t * p_decoder_fifo, pes_packet_t * p_pes )
177 {
178     vlc_mutex_lock( &p_decoder_fifo->data_lock );
179
180     p_pes->p_next = NULL;
181     *p_decoder_fifo->pp_last = p_pes;
182     p_decoder_fifo->pp_last = &p_pes->p_next;
183     p_decoder_fifo->i_depth++;
184
185     /* Warn the decoder that it's got work to do. */
186     vlc_cond_signal( &p_decoder_fifo->data_wait );
187     vlc_mutex_unlock( &p_decoder_fifo->data_lock );
188 }
189
190 /*****************************************************************************
191  * Create a NULL packet for padding in case of a data loss
192  *****************************************************************************/
193 void input_NullPacket( input_thread_t * p_input,
194                        es_descriptor_t * p_es )
195 {
196     data_packet_t *             p_pad_data;
197     pes_packet_t *              p_pes;
198
199     if( (p_pad_data = input_NewPacketForce( p_input->p_method_data,
200                     PADDING_PACKET_SIZE)) == NULL )
201     {
202         msg_Err( p_input, "no new packet" );
203         p_input->b_error = 1;
204         return;
205     }
206
207     memset( p_pad_data->p_payload_start, 0, PADDING_PACKET_SIZE );
208     p_pad_data->b_discard_payload = 1;
209     p_pes = p_es->p_pes;
210
211     if( p_pes != NULL )
212     {
213         p_pes->b_discontinuity = 1;
214         p_pes->p_last->p_next = p_pad_data;
215         p_pes->p_last = p_pad_data;
216         p_pes->i_nb_data++;
217     }
218     else
219     {
220         if( (p_pes = input_NewPES( p_input->p_method_data )) == NULL )
221         {
222             msg_Err( p_input, "no PES packet" );
223             p_input->b_error = 1;
224             return;
225         }
226
227         p_pes->i_rate = p_input->stream.control.i_rate;
228         p_pes->p_first = p_pes->p_last = p_pad_data;
229         p_pes->i_nb_data = 1;
230         p_pes->b_discontinuity = 1;
231         input_DecodePES( p_es->p_decoder_fifo, p_pes );
232     }
233 }
234
235 /*****************************************************************************
236  * input_EscapeDiscontinuity: send a NULL packet to the decoders
237  *****************************************************************************/
238 void input_EscapeDiscontinuity( input_thread_t * p_input )
239 {
240     unsigned int i_es, i;
241
242     for( i_es = 0; i_es < p_input->stream.i_selected_es_number; i_es++ )
243     {
244         es_descriptor_t * p_es = p_input->stream.pp_selected_es[i_es];
245
246         if( p_es->p_decoder_fifo != NULL )
247         {
248             for( i = 0; i < PADDING_PACKET_NUMBER; i++ )
249             {
250                 input_NullPacket( p_input, p_es );
251             }
252         }
253     }
254 }
255
256 /*****************************************************************************
257  * input_EscapeAudioDiscontinuity: send a NULL packet to the audio decoders
258  *****************************************************************************/
259 void input_EscapeAudioDiscontinuity( input_thread_t * p_input )
260 {
261     unsigned int i_es, i;
262
263     for( i_es = 0; i_es < p_input->stream.i_selected_es_number; i_es++ )
264     {
265         es_descriptor_t * p_es = p_input->stream.pp_selected_es[i_es];
266
267         if( p_es->p_decoder_fifo != NULL && p_es->i_cat == AUDIO_ES )
268         {
269             for( i = 0; i < PADDING_PACKET_NUMBER; i++ )
270             {
271                 input_NullPacket( p_input, p_es );
272             }
273         }
274     }
275 }
276
277 /*****************************************************************************
278  * CreateDecoderFifo: create a decoder_fifo_t
279  *****************************************************************************/
280 static decoder_t * CreateDecoder( input_thread_t * p_input,
281                                   es_descriptor_t * p_es )
282 {
283     decoder_t * p_dec;
284
285     p_dec = vlc_object_create( p_input, VLC_OBJECT_DECODER );
286     if( p_dec == NULL )
287     {
288         msg_Err( p_input, "out of memory" );
289         return NULL;
290     }
291
292     p_dec->pf_init = 0;
293     p_dec->pf_decode = 0;
294     p_dec->pf_end = 0;
295     p_dec->pf_run = 0;
296
297     /* Select a new ES */
298     INSERT_ELEM( p_input->stream.pp_selected_es,
299                  p_input->stream.i_selected_es_number,
300                  p_input->stream.i_selected_es_number,
301                  p_es );
302
303     /* Allocate the memory needed to store the decoder's fifo */
304     //p_dec->p_fifo = (decoder_fifo_t *)malloc(sizeof(decoder_fifo_t));
305     p_dec->p_fifo = vlc_object_create( p_input, VLC_OBJECT_DECODER_FIFO );
306     if( p_dec->p_fifo == NULL )
307     {
308         msg_Err( p_input, "out of memory" );
309         return NULL;
310     }
311
312     /* Initialize the decoder fifo */
313     //memset( p_dec->p_fifo, 0, sizeof(decoder_fifo_t) );
314     p_dec->p_module = NULL;
315
316     /* Initialize the p_fifo structure */
317     vlc_mutex_init( p_input, &p_dec->p_fifo->data_lock );
318     vlc_cond_init( p_input, &p_dec->p_fifo->data_wait );
319     p_es->p_decoder_fifo = p_dec->p_fifo;
320
321     p_dec->p_fifo->i_id = p_es->i_id;
322     p_dec->p_fifo->i_fourcc = p_es->i_fourcc;
323     p_dec->p_fifo->p_demux_data   = p_es->p_demux_data;
324     p_dec->p_fifo->p_waveformatex = p_es->p_waveformatex;
325     p_dec->p_fifo->p_bitmapinfoheader = p_es->p_bitmapinfoheader;
326     p_dec->p_fifo->p_stream_ctrl = &p_input->stream.control;
327     p_dec->p_fifo->p_sout = p_input->stream.p_sout;
328
329     p_dec->p_fifo->p_first = NULL;
330     p_dec->p_fifo->pp_last = &p_dec->p_fifo->p_first;
331     p_dec->p_fifo->i_depth = 0;
332     p_dec->p_fifo->b_die = p_dec->p_fifo->b_error = 0;
333     p_dec->p_fifo->p_packets_mgt = p_input->p_method_data;
334
335     p_dec->p_fifo->p_dec = p_dec;
336
337     vlc_object_attach( p_dec->p_fifo, p_input );
338     vlc_object_attach( p_dec, p_input );
339
340     return p_dec;
341 }
342
343 /*****************************************************************************
344  * DecoderThread: the decoding main loop
345  *****************************************************************************/
346 static int DecoderThread( decoder_t * p_dec )
347 {
348     pes_packet_t  *p_pes;
349     data_packet_t *p_data;
350     block_t       *p_block;
351
352     /* Temporary wrapper to keep old decoder api functional */
353     if( p_dec->pf_run )
354     {
355         p_dec->pf_run( p_dec->p_fifo );
356         return 0;
357     }
358
359
360     /* Initialize the decoder */
361     p_dec->p_fifo->b_error = p_dec->pf_init( p_dec );
362
363     /* The decoder's main loop */
364     while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
365     {
366         int i_size;
367
368         input_ExtractPES( p_dec->p_fifo, &p_pes );
369         if( !p_pes )
370         {
371             p_dec->p_fifo->b_error = 1;
372             break;
373         }
374
375         for( i_size = 0, p_data = p_pes->p_first;
376              p_data != NULL; p_data = p_data->p_next )
377         {
378             i_size += p_data->p_payload_end - p_data->p_payload_start;
379         }
380         p_block = block_New( p_dec, i_size );
381         for( i_size = 0, p_data = p_pes->p_first;
382              p_data != NULL; p_data = p_data->p_next )
383         {
384             if( p_data->p_payload_end == p_data->p_payload_start )
385                 continue;
386             memcpy( p_block->p_buffer + i_size, p_data->p_payload_start,
387                     p_data->p_payload_end - p_data->p_payload_start );
388             i_size += p_data->p_payload_end - p_data->p_payload_start;
389         }
390
391         p_block->i_pts = p_pes->i_pts;
392         p_block->i_dts = p_pes->i_dts;
393         p_block->b_discontinuity = p_pes->b_discontinuity;
394         p_dec->p_fifo->b_error = p_dec->pf_decode( p_dec, p_block );
395
396         input_DeletePES( p_dec->p_fifo->p_packets_mgt, p_pes );
397     }
398
399     /* If b_error is set, the decoder thread enters the error loop */
400     if( p_dec->p_fifo->b_error )
401     {
402         /* Wait until a `die' order is sent */
403         while( !p_dec->p_fifo->b_die )
404         {
405             /* Trash all received PES packets */
406             input_ExtractPES( p_dec->p_fifo, NULL );
407         }
408     }
409
410     /* End of the decoder */
411     p_dec->pf_end( p_dec );
412
413     return 0;
414 }
415
416 /*****************************************************************************
417  * DeleteDecoderFifo: destroy a decoder_fifo_t
418  *****************************************************************************/
419 static void DeleteDecoder( decoder_t * p_dec )
420 {
421     vlc_object_detach( p_dec );
422     vlc_object_detach( p_dec->p_fifo );
423
424     msg_Dbg( p_dec,
425              "killing decoder for 0x%x, fourcc `%4.4s', %d PES in FIFO",
426              p_dec->p_fifo->i_id, (char*)&p_dec->p_fifo->i_fourcc,
427              p_dec->p_fifo->i_depth );
428
429     /* Free all packets still in the decoder fifo. */
430     input_DeletePES( p_dec->p_fifo->p_packets_mgt,
431                      p_dec->p_fifo->p_first );
432
433     /* Destroy the lock and cond */
434     vlc_cond_destroy( &p_dec->p_fifo->data_wait );
435     vlc_mutex_destroy( &p_dec->p_fifo->data_lock );
436
437     /* Free fifo */
438     vlc_object_destroy( p_dec->p_fifo );
439     //free( p_dec->p_fifo );
440 }