]> git.sesse.net Git - vlc/blob - src/input/decoder.c
* decoder: fix a crash with delete spu.
[vlc] / src / input / decoder.c
1 /*****************************************************************************
2  * decoder.c: Functions for the management of decoders
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Laurent Aimar <fenrir@via.ecp.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include <stdlib.h>
30 #include <vlc/vlc.h>
31
32 #include <vlc/decoder.h>
33 #include <vlc/vout.h>
34 #include <vlc/input.h>
35
36 #include "stream_output.h"
37 #include "input_internal.h"
38
39 static decoder_t * CreateDecoder( input_thread_t *, es_format_t *, int );
40 static void        DeleteDecoder( decoder_t * );
41
42 static int         DecoderThread( decoder_t * );
43 static int         DecoderDecode( decoder_t * p_dec, block_t *p_block );
44
45 /* Buffers allocation callbacks for the decoders */
46 static aout_buffer_t *aout_new_buffer( decoder_t *, int );
47 static void aout_del_buffer( decoder_t *, aout_buffer_t * );
48
49 static picture_t *vout_new_buffer( decoder_t * );
50 static void vout_del_buffer( decoder_t *, picture_t * );
51 static void vout_link_picture( decoder_t *, picture_t * );
52 static void vout_unlink_picture( decoder_t *, picture_t * );
53
54 static subpicture_t *spu_new_buffer( decoder_t * );
55 static void spu_del_buffer( decoder_t *, subpicture_t * );
56
57 static es_format_t null_es_format = {0};
58
59 struct decoder_owner_sys_t
60 {
61     vlc_bool_t      b_own_thread;
62
63     int64_t         i_preroll_end;
64
65     input_thread_t  *p_input;
66
67     aout_instance_t *p_aout;
68     aout_input_t    *p_aout_input;
69
70     vout_thread_t   *p_vout;
71
72     vout_thread_t   *p_spu_vout;
73     int              i_spu_channel;
74
75     sout_instance_t         *p_sout;
76     sout_packetizer_input_t *p_sout_input;
77
78     /* Some decoders require already packetized data (ie. not truncated) */
79     decoder_t *p_packetizer;
80
81     /* Current format in use by the output */
82     video_format_t video;
83     audio_format_t audio;
84     es_format_t    sout;
85
86     /* fifo */
87     block_fifo_t *p_fifo;
88 };
89
90
91 /**
92  * Spawns a new decoder thread
93  *
94  * \param p_input the input thread
95  * \param p_es the es descriptor
96  * \return the spawned decoder object
97  */
98 decoder_t *input_DecoderNew( input_thread_t *p_input,
99                              es_format_t *fmt, vlc_bool_t b_force_decoder )
100 {
101     decoder_t   *p_dec = NULL;
102     vlc_value_t val;
103
104     /* If we are in sout mode, search for packetizer module */
105     if( p_input->p_sout && !b_force_decoder )
106     {
107         /* Create the decoder configuration structure */
108         p_dec = CreateDecoder( p_input, fmt, VLC_OBJECT_PACKETIZER );
109         if( p_dec == NULL )
110         {
111             msg_Err( p_input, "could not create packetizer" );
112             return NULL;
113         }
114     }
115     else
116     {
117         /* Create the decoder configuration structure */
118         p_dec = CreateDecoder( p_input, fmt, VLC_OBJECT_DECODER );
119         if( p_dec == NULL )
120         {
121             msg_Err( p_input, "could not create decoder" );
122             return NULL;
123         }
124     }
125
126     if( !p_dec->p_module )
127     {
128         msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n"
129                  "VLC probably does not support this sound or video format.",
130                  (char*)&p_dec->fmt_in.i_codec );
131
132         DeleteDecoder( p_dec );
133         vlc_object_destroy( p_dec );
134         return NULL;
135     }
136
137     if( p_input->p_sout && p_input->input.b_can_pace_control &&
138         !b_force_decoder )
139     {
140         msg_Dbg( p_input, "stream out mode -> no decoder thread" );
141         p_dec->p_owner->b_own_thread = VLC_FALSE;
142     }
143     else
144     {
145         var_Get( p_input, "minimize-threads", &val );
146         p_dec->p_owner->b_own_thread = !val.b_bool;
147     }
148
149     if( p_dec->p_owner->b_own_thread )
150     {
151         int i_priority;
152         if( fmt->i_cat == AUDIO_ES )
153             i_priority = VLC_THREAD_PRIORITY_AUDIO;
154         else
155             i_priority = VLC_THREAD_PRIORITY_VIDEO;
156
157         /* Spawn the decoder thread */
158         if( vlc_thread_create( p_dec, "decoder", DecoderThread,
159                                i_priority, VLC_FALSE ) )
160         {
161             msg_Err( p_dec, "cannot spawn decoder thread \"%s\"",
162                              p_dec->p_module->psz_object_name );
163             module_Unneed( p_dec, p_dec->p_module );
164             DeleteDecoder( p_dec );
165             vlc_object_destroy( p_dec );
166             return NULL;
167         }
168     }
169
170     return p_dec;
171 }
172
173 /**
174  * Kills a decoder thread and waits until it's finished
175  *
176  * \param p_input the input thread
177  * \param p_es the es descriptor
178  * \return nothing
179  */
180 void input_DecoderDelete( decoder_t *p_dec )
181 {
182     p_dec->b_die = VLC_TRUE;
183
184     if( p_dec->p_owner->b_own_thread )
185     {
186         /* Make sure the thread leaves the function by
187          * sending it an empty block. */
188         block_t *p_block = block_New( p_dec, 0 );
189         input_DecoderDecode( p_dec, p_block );
190
191         vlc_thread_join( p_dec );
192
193         /* Don't module_Unneed() here because of the dll loader that wants
194          * close() in the same thread than open()/decode() */
195     }
196     else
197     {
198         /* Flush */
199         input_DecoderDecode( p_dec, NULL );
200
201         module_Unneed( p_dec, p_dec->p_module );
202     }
203
204     /* Delete decoder configuration */
205     DeleteDecoder( p_dec );
206
207     /* Delete the decoder */
208     vlc_object_destroy( p_dec );
209 }
210
211 /**
212  * Put a block_t in the decoder's fifo.
213  *
214  * \param p_dec the decoder object
215  * \param p_block the data block
216  */
217 void input_DecoderDecode( decoder_t * p_dec, block_t *p_block )
218 {
219     if( p_dec->p_owner->b_own_thread )
220     {
221         if( p_dec->p_owner->p_input->b_out_pace_control )
222         {
223             /* FIXME !!!!! */
224             while( !p_dec->b_die && !p_dec->b_error &&
225                    p_dec->p_owner->p_fifo->i_depth > 10 )
226             {
227                 msleep( 1000 );
228             }
229         }
230         else if( p_dec->p_owner->p_fifo->i_size > 50000000 /* 50 MB */ )
231         {
232             /* FIXME: ideally we would check the time amount of data
233              * in the fifo instead of its size. */
234             msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
235                       "consummed quickly enough), resetting fifo!" );
236             block_FifoEmpty( p_dec->p_owner->p_fifo );
237         }
238
239         block_FifoPut( p_dec->p_owner->p_fifo, p_block );
240     }
241     else
242     {
243         if( p_dec->b_error || (p_block && p_block->i_buffer <= 0) )
244         {
245             if( p_block ) block_Release( p_block );
246         }
247         else
248         {
249             DecoderDecode( p_dec, p_block );
250         }
251     }
252 }
253
254 void input_DecoderDiscontinuity( decoder_t * p_dec )
255 {
256     block_t *p_null;
257
258     /* Empty the fifo */
259     if( p_dec->p_owner->b_own_thread )
260     {
261         block_FifoEmpty( p_dec->p_owner->p_fifo );
262     }
263
264     /* Send a special block */
265     p_null = block_New( p_dec, 128 );
266     p_null->i_flags |= BLOCK_FLAG_DISCONTINUITY;
267     memset( p_null->p_buffer, 0, p_null->i_buffer );
268
269     input_DecoderDecode( p_dec, p_null );
270 }
271
272 vlc_bool_t input_DecoderEmpty( decoder_t * p_dec )
273 {
274     if( p_dec->p_owner->b_own_thread && p_dec->p_owner->p_fifo->i_depth > 0 )
275     {
276         return VLC_FALSE;
277     }
278     return VLC_TRUE;
279 }
280
281 void input_DecoderPreroll( decoder_t *p_dec, int64_t i_preroll_end )
282 {
283     p_dec->p_owner->i_preroll_end = i_preroll_end;
284 }
285
286 #if 0
287 /**
288  * Create a NULL packet for padding in case of a data loss
289  *
290  * \param p_input the input thread
291  * \param p_es es descriptor
292  * \return nothing
293  */
294 static void input_NullPacket( input_thread_t * p_input,
295                               es_descriptor_t * p_es )
296 {
297 #if 0
298     block_t *p_block = block_New( p_input, PADDING_PACKET_SIZE );
299     if( p_block )
300     {
301         memset( p_block->p_buffer, 0, PADDING_PACKET_SIZE );
302         p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
303
304         block_FifoPut( p_es->p_dec->p_owner->p_fifo, p_block );
305     }
306 #endif
307 }
308
309 /**
310  * Send a NULL packet to the decoders
311  *
312  * \param p_input the input thread
313  * \return nothing
314  */
315 void input_EscapeDiscontinuity( input_thread_t * p_input )
316 {
317 #if 0
318     unsigned int i_es, i;
319
320     for( i_es = 0; i_es < p_input->stream.i_selected_es_number; i_es++ )
321     {
322         es_descriptor_t * p_es = p_input->stream.pp_selected_es[i_es];
323
324         if( p_es->p_dec != NULL )
325         {
326             for( i = 0; i < PADDING_PACKET_NUMBER; i++ )
327             {
328                 input_NullPacket( p_input, p_es );
329             }
330         }
331     }
332 #endif
333 }
334
335 /**
336  * Send a NULL packet to the audio decoders
337  *
338  * \param p_input the input thread
339  * \return nothing
340  */
341 void input_EscapeAudioDiscontinuity( input_thread_t * p_input )
342 {
343 #if 0
344     unsigned int i_es, i;
345
346     for( i_es = 0; i_es < p_input->stream.i_selected_es_number; i_es++ )
347     {
348         es_descriptor_t * p_es = p_input->stream.pp_selected_es[i_es];
349
350         if( p_es->p_dec != NULL && p_es->i_cat == AUDIO_ES )
351         {
352             for( i = 0; i < PADDING_PACKET_NUMBER; i++ )
353             {
354                 input_NullPacket( p_input, p_es );
355             }
356         }
357     }
358 #endif
359 }
360 #endif
361
362 /**
363  * Create a decoder object
364  *
365  * \param p_input the input thread
366  * \param p_es the es descriptor
367  * \param i_object_type Object type as define in include/vlc_objects.h
368  * \return the decoder object
369  */
370 static decoder_t * CreateDecoder( input_thread_t *p_input,
371                                   es_format_t *fmt, int i_object_type )
372 {
373     decoder_t *p_dec;
374
375     p_dec = vlc_object_create( p_input, i_object_type );
376     if( p_dec == NULL )
377     {
378         msg_Err( p_input, "out of memory" );
379         return NULL;
380     }
381
382     p_dec->pf_decode_audio = 0;
383     p_dec->pf_decode_video = 0;
384     p_dec->pf_decode_sub = 0;
385     p_dec->pf_packetize = 0;
386
387     /* Initialize the decoder fifo */
388     p_dec->p_module = NULL;
389
390
391     es_format_Copy( &p_dec->fmt_in, fmt );
392     es_format_Copy( &p_dec->fmt_out, &null_es_format );
393
394     /* Allocate our private structure for the decoder */
395     p_dec->p_owner = malloc( sizeof( decoder_owner_sys_t ) );
396     if( p_dec->p_owner == NULL )
397     {
398         msg_Err( p_dec, "out of memory" );
399         return NULL;
400     }
401     p_dec->p_owner->b_own_thread = VLC_TRUE;
402     p_dec->p_owner->i_preroll_end = -1;
403     p_dec->p_owner->p_input = p_input;
404     p_dec->p_owner->p_aout = NULL;
405     p_dec->p_owner->p_aout_input = NULL;
406     p_dec->p_owner->p_vout = NULL;
407     p_dec->p_owner->p_spu_vout = NULL;
408     p_dec->p_owner->i_spu_channel = 0;
409     p_dec->p_owner->p_sout = p_input->p_sout;
410     p_dec->p_owner->p_sout_input = NULL;
411     p_dec->p_owner->p_packetizer = NULL;
412
413     /* decoder fifo */
414     if( ( p_dec->p_owner->p_fifo = block_FifoNew( p_dec ) ) == NULL )
415     {
416         msg_Err( p_dec, "out of memory" );
417         return NULL;
418     }
419
420     /* Set buffers allocation callbacks for the decoders */
421     p_dec->pf_aout_buffer_new = aout_new_buffer;
422     p_dec->pf_aout_buffer_del = aout_del_buffer;
423     p_dec->pf_vout_buffer_new = vout_new_buffer;
424     p_dec->pf_vout_buffer_del = vout_del_buffer;
425     p_dec->pf_picture_link    = vout_link_picture;
426     p_dec->pf_picture_unlink  = vout_unlink_picture;
427     p_dec->pf_spu_buffer_new  = spu_new_buffer;
428     p_dec->pf_spu_buffer_del  = spu_del_buffer;
429
430     vlc_object_attach( p_dec, p_input );
431
432     /* Find a suitable decoder/packetizer module */
433     if( i_object_type == VLC_OBJECT_DECODER )
434         p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
435     else
436         p_dec->p_module = module_Need( p_dec, "packetizer", "$packetizer", 0 );
437
438     /* Check if decoder requires already packetized data */
439     if( i_object_type == VLC_OBJECT_DECODER &&
440         p_dec->b_need_packetized && !p_dec->fmt_in.b_packetized )
441     {
442         p_dec->p_owner->p_packetizer =
443             vlc_object_create( p_input, VLC_OBJECT_PACKETIZER );
444         if( p_dec->p_owner->p_packetizer )
445         {
446             es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_in,
447                             &p_dec->fmt_in );
448
449             es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_out,
450                             &null_es_format );
451
452             vlc_object_attach( p_dec->p_owner->p_packetizer, p_input );
453
454             p_dec->p_owner->p_packetizer->p_module =
455                 module_Need( p_dec->p_owner->p_packetizer,
456                              "packetizer", "$packetizer", 0 );
457
458             if( !p_dec->p_owner->p_packetizer->p_module )
459             {
460                 es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
461                 vlc_object_detach( p_dec->p_owner->p_packetizer );
462                 vlc_object_destroy( p_dec->p_owner->p_packetizer );
463             }
464         }
465     }
466
467     return p_dec;
468 }
469
470 /**
471  * The decoding main loop
472  *
473  * \param p_dec the decoder
474  * \return 0
475  */
476 static int DecoderThread( decoder_t * p_dec )
477 {
478     block_t *p_block;
479
480     /* The decoder's main loop */
481     while( !p_dec->b_die && !p_dec->b_error )
482     {
483         if( ( p_block = block_FifoGet( p_dec->p_owner->p_fifo ) ) == NULL )
484         {
485             p_dec->b_error = 1;
486             break;
487         }
488         if( DecoderDecode( p_dec, p_block ) != VLC_SUCCESS )
489         {
490             break;
491         }
492     }
493
494     while( !p_dec->b_die )
495     {
496         /* Trash all received PES packets */
497         p_block = block_FifoGet( p_dec->p_owner->p_fifo );
498         if( p_block ) block_Release( p_block );
499     }
500
501     /* We do it here because of the dll loader that wants close() in the
502      * same thread than open()/decode() */
503     module_Unneed( p_dec, p_dec->p_module );
504
505     return 0;
506 }
507
508 /**
509  * Decode a block
510  *
511  * \param p_dec the decoder object
512  * \param p_block the block to decode
513  * \return VLC_SUCCESS or an error code
514  */
515 static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
516 {
517     int i_rate = p_block ? p_block->i_rate : 1000;
518
519     if( p_block && p_block->i_buffer <= 0 )
520     {
521         block_Release( p_block );
522         return VLC_SUCCESS;
523     }
524
525     if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
526     {
527         block_t *p_sout_block;
528
529         while( ( p_sout_block =
530                      p_dec->pf_packetize( p_dec, p_block ? &p_block : 0 ) ) )
531         {
532             if( !p_dec->p_owner->p_sout_input )
533             {
534                 es_format_Copy( &p_dec->p_owner->sout, &p_dec->fmt_out );
535
536                 p_dec->p_owner->sout.i_group = p_dec->fmt_in.i_group;
537                 p_dec->p_owner->sout.i_id = p_dec->fmt_in.i_id;
538                 if( p_dec->fmt_in.psz_language )
539                 {
540                     p_dec->p_owner->sout.psz_language =
541                         strdup( p_dec->fmt_in.psz_language );
542                 }
543
544                 p_dec->p_owner->p_sout_input =
545                     sout_InputNew( p_dec->p_owner->p_sout,
546                                    &p_dec->p_owner->sout );
547
548                 if( p_dec->p_owner->p_sout_input == NULL )
549                 {
550                     msg_Err( p_dec, "cannot create packetizer output" );
551                     p_dec->b_error = VLC_TRUE;
552
553                     while( p_sout_block )
554                     {
555                         block_t *p_next = p_sout_block->p_next;
556                         block_Release( p_sout_block );
557                         p_sout_block = p_next;
558                     }
559                     break;
560                 }
561             }
562
563             while( p_sout_block )
564             {
565                 block_t *p_next = p_sout_block->p_next;
566
567                 p_sout_block->p_next = NULL;
568                 p_sout_block->i_rate = i_rate;
569
570                 sout_InputSendBuffer( p_dec->p_owner->p_sout_input,
571                                       p_sout_block );
572
573                 p_sout_block = p_next;
574             }
575
576             /* For now it's enough, as only sout inpact on this flag */
577             if( p_dec->p_owner->p_sout->i_out_pace_nocontrol > 0 &&
578                 p_dec->p_owner->p_input->b_out_pace_control )
579             {
580                 msg_Dbg( p_dec, "switching to synch mode" );
581                 p_dec->p_owner->p_input->b_out_pace_control = VLC_FALSE;
582             }
583             else if( p_dec->p_owner->p_sout->i_out_pace_nocontrol <= 0 &&
584                      !p_dec->p_owner->p_input->b_out_pace_control )
585             {
586                 msg_Dbg( p_dec, "switching to asynch mode" );
587                 p_dec->p_owner->p_input->b_out_pace_control = VLC_TRUE;
588             }
589         }
590     }
591     else if( p_dec->fmt_in.i_cat == AUDIO_ES )
592     {
593         aout_buffer_t *p_aout_buf;
594
595         if( p_dec->p_owner->p_packetizer )
596         {
597             block_t *p_packetized_block;
598             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
599
600             while( (p_packetized_block =
601                     p_packetizer->pf_packetize( p_packetizer, &p_block )) )
602             {
603                 if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
604                 {
605                     p_dec->fmt_in.i_extra = p_packetizer->fmt_out.i_extra;
606                     p_dec->fmt_in.p_extra = malloc( p_dec->fmt_in.i_extra );
607                     memcpy( p_dec->fmt_in.p_extra,
608                             p_packetizer->fmt_out.p_extra,
609                             p_dec->fmt_in.i_extra );
610                 }
611
612                 while( p_packetized_block )
613                 {
614                     block_t *p_next = p_packetized_block->p_next;
615                     p_packetized_block->p_next = NULL;
616                     p_packetized_block->i_rate = i_rate;
617
618                     while( (p_aout_buf = p_dec->pf_decode_audio( p_dec,
619                                                        &p_packetized_block )) )
620                     {
621                         /* FIXME the best would be to handle the case start_date < preroll < end_date
622                          * but that's not easy with non raw audio stream */
623                         if( p_dec->p_owner->i_preroll_end > 0 &&
624                             p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
625                         {
626                             aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
627                                                   p_dec->p_owner->p_aout_input, p_aout_buf );
628                         }
629                         else
630                         {
631                             p_dec->p_owner->i_preroll_end = -1;
632                             aout_DecPlay( p_dec->p_owner->p_aout,
633                                           p_dec->p_owner->p_aout_input,
634                                           p_aout_buf );
635                         }
636                     }
637
638                     p_packetized_block = p_next;
639                 }
640             }
641         }
642         else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
643         {
644             if( p_dec->p_owner->i_preroll_end > 0 &&
645                 p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
646             {
647                 aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
648                                       p_dec->p_owner->p_aout_input, p_aout_buf );
649             }
650             else
651             {
652                 p_dec->p_owner->i_preroll_end = -1;
653                 aout_DecPlay( p_dec->p_owner->p_aout,
654                               p_dec->p_owner->p_aout_input,
655                               p_aout_buf );
656             }
657         }
658     }
659     else if( p_dec->fmt_in.i_cat == VIDEO_ES )
660     {
661         picture_t *p_pic;
662
663         if( p_dec->p_owner->p_packetizer )
664         {
665             block_t *p_packetized_block;
666             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
667
668             while( (p_packetized_block =
669                     p_packetizer->pf_packetize( p_packetizer, &p_block )) )
670             {
671                 while( p_packetized_block )
672                 {
673                     block_t *p_next = p_packetized_block->p_next;
674                     p_packetized_block->p_next = NULL;
675                     p_packetized_block->i_rate = i_rate;
676
677                     while( (p_pic = p_dec->pf_decode_video( p_dec,
678                                                        &p_packetized_block )) )
679                     {
680                         if( p_dec->p_owner->i_preroll_end > 0 &&
681                             p_pic->date < p_dec->p_owner->i_preroll_end )
682                         {
683                             vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
684                         }
685                         else
686                         {
687                             p_dec->p_owner->i_preroll_end = -1;
688                             vout_DatePicture( p_dec->p_owner->p_vout, p_pic,
689                                               p_pic->date );
690                             vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
691                         }
692                     }
693
694                     p_packetized_block = p_next;
695                 }
696             }
697         }
698         else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
699         {
700             if( p_dec->p_owner->i_preroll_end > 0 &&
701                 p_pic->date < p_dec->p_owner->i_preroll_end )
702             {
703                 vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
704             }
705             else
706             {
707                 p_dec->p_owner->i_preroll_end = -1;
708                 vout_DatePicture( p_dec->p_owner->p_vout, p_pic, p_pic->date );
709                 vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
710             }
711         }
712     }
713     else if( p_dec->fmt_in.i_cat == SPU_ES )
714     {
715         vout_thread_t *p_vout;
716         subpicture_t *p_spu;
717         while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) )
718         {
719             if( p_dec->p_owner->i_preroll_end > 0 &&
720                 p_spu->i_start < p_dec->p_owner->i_preroll_end &&
721                 ( p_spu->i_stop <= 0 || p_spu->i_stop <= p_dec->p_owner->i_preroll_end ) )
722             {
723                 spu_DestroySubpicture( p_dec->p_owner->p_vout->p_spu, p_spu );
724                 continue;
725             }
726
727             p_dec->p_owner->i_preroll_end = -1;
728             p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
729             if( p_vout )
730             {
731                 spu_DisplaySubpicture( p_vout->p_spu, p_spu );
732                 vlc_object_release( p_vout );
733             }
734         }
735     }
736     else
737     {
738         msg_Err( p_dec, "unknown ES format" );
739         p_dec->b_error = 1;
740     }
741
742     return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS;
743 }
744
745 /**
746  * Destroys a decoder object
747  *
748  * \param p_dec the decoder object
749  * \return nothing
750  */
751 static void DeleteDecoder( decoder_t * p_dec )
752 {
753     msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %d PES in FIFO",
754              (char*)&p_dec->fmt_in.i_codec,
755              p_dec->p_owner->p_fifo->i_depth );
756
757     /* Free all packets still in the decoder fifo. */
758     block_FifoEmpty( p_dec->p_owner->p_fifo );
759     block_FifoRelease( p_dec->p_owner->p_fifo );
760
761     /* Cleanup */
762     if( p_dec->p_owner->p_aout_input )
763         aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );
764
765     if( p_dec->p_owner->p_vout )
766     {
767         int i_pic;
768
769 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
770         /* Hack to make sure all the the pictures are freed by the decoder */
771         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
772              i_pic++ )
773         {
774             if( p_pic->i_status == RESERVED_PICTURE )
775                 vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
776             if( p_pic->i_refcount > 0 )
777                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
778         }
779 #undef p_pic
780
781         /* We are about to die. Reattach video output to p_vlc. */
782         vout_Request( p_dec, p_dec->p_owner->p_vout, 0 );
783     }
784
785     if( p_dec->p_owner->p_sout_input )
786     {
787         sout_InputDelete( p_dec->p_owner->p_sout_input );
788         es_format_Clean( &p_dec->p_owner->sout );
789     }
790
791     if( p_dec->fmt_in.i_cat == SPU_ES )
792     {
793         vout_thread_t *p_vout;
794
795         p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
796         if( p_vout )
797         {
798             spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,
799                          p_dec->p_owner->i_spu_channel );
800             vlc_object_release( p_vout );
801         }
802     }
803
804     es_format_Clean( &p_dec->fmt_in );
805     es_format_Clean( &p_dec->fmt_out );
806
807     if( p_dec->p_owner->p_packetizer )
808     {
809         module_Unneed( p_dec->p_owner->p_packetizer,
810                        p_dec->p_owner->p_packetizer->p_module );
811         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
812         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_out );
813         vlc_object_detach( p_dec->p_owner->p_packetizer );
814         vlc_object_destroy( p_dec->p_owner->p_packetizer );
815     }
816
817     vlc_object_detach( p_dec );
818
819     free( p_dec->p_owner );
820 }
821
822 /*****************************************************************************
823  * Buffers allocation callbacks for the decoders
824  *****************************************************************************/
825 static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
826 {
827     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
828     aout_buffer_t *p_buffer;
829
830     if( p_sys->p_aout_input != NULL &&
831         ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||
832           p_dec->fmt_out.audio.i_original_channels !=
833               p_sys->audio.i_original_channels ||
834           p_dec->fmt_out.audio.i_bytes_per_frame !=
835               p_sys->audio.i_bytes_per_frame ) )
836     {
837         /* Parameters changed, restart the aout */
838         aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
839         p_sys->p_aout_input = NULL;
840     }
841
842     if( p_sys->p_aout_input == NULL )
843     {
844         p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
845         p_sys->audio = p_dec->fmt_out.audio;
846         p_sys->p_aout_input =
847             aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->audio );
848         if( p_sys->p_aout_input == NULL )
849         {
850             msg_Err( p_dec, "failed to create audio output" );
851             p_dec->b_error = VLC_TRUE;
852             return NULL;
853         }
854         p_dec->fmt_out.audio.i_bytes_per_frame =
855             p_sys->audio.i_bytes_per_frame;
856     }
857
858     p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
859                                   i_samples );
860
861     return p_buffer;
862 }
863
864 static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
865 {
866     aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
867                           p_dec->p_owner->p_aout_input, p_buffer );
868 }
869
870 static picture_t *vout_new_buffer( decoder_t *p_dec )
871 {
872     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
873     picture_t *p_pic;
874
875     if( p_sys->p_vout == NULL ||
876         p_dec->fmt_out.video.i_width != p_sys->video.i_width ||
877         p_dec->fmt_out.video.i_height != p_sys->video.i_height ||
878         p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||
879         p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )
880     {
881         if( !p_dec->fmt_out.video.i_width ||
882             !p_dec->fmt_out.video.i_height )
883         {
884             /* Can't create a new vout without display size */
885             return NULL;
886         }
887
888         if( !p_dec->fmt_out.video.i_sar_num ||
889             !p_dec->fmt_out.video.i_sar_den )
890         {
891             p_dec->fmt_out.video.i_sar_num =
892               p_dec->fmt_out.video.i_aspect * p_dec->fmt_out.video.i_height;
893
894             p_dec->fmt_out.video.i_sar_den = VOUT_ASPECT_FACTOR *
895               p_dec->fmt_out.video.i_width;
896         }
897
898         vlc_reduce( &p_dec->fmt_out.video.i_sar_num,
899                     &p_dec->fmt_out.video.i_sar_den,
900                     p_dec->fmt_out.video.i_sar_num,
901                     p_dec->fmt_out.video.i_sar_den, 0 );
902
903         if( !p_dec->fmt_out.video.i_visible_width ||
904             !p_dec->fmt_out.video.i_visible_height )
905         {
906             p_dec->fmt_out.video.i_visible_width =
907                 p_dec->fmt_out.video.i_width;
908             p_dec->fmt_out.video.i_visible_height =
909                 p_dec->fmt_out.video.i_height;
910         }
911
912         p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
913         p_sys->video = p_dec->fmt_out.video;
914
915         p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
916                                       &p_dec->fmt_out.video );
917         if( p_sys->p_vout == NULL )
918         {
919             msg_Err( p_dec, "failed to create video output" );
920             p_dec->b_error = VLC_TRUE;
921             return NULL;
922         }
923
924         if( p_sys->video.i_rmask )
925             p_sys->p_vout->render.i_rmask = p_sys->video.i_rmask;
926         if( p_sys->video.i_gmask )
927             p_sys->p_vout->render.i_gmask = p_sys->video.i_gmask;
928         if( p_sys->video.i_bmask )
929             p_sys->p_vout->render.i_bmask = p_sys->video.i_bmask;
930     }
931
932     /* Get a new picture */
933     while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
934     {
935         int i_pic, i_ready_pic = 0;
936
937         if( p_dec->b_die || p_dec->b_error )
938         {
939             return NULL;
940         }
941
942 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
943         /* Check the decoder doesn't leak pictures */
944         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
945              i_pic++ )
946         {
947             if( p_pic->i_status == READY_PICTURE )
948             {
949                 if( i_ready_pic++ > 0 ) break;
950                 else continue;
951             }
952
953             if( p_pic->i_status != DISPLAYED_PICTURE &&
954                 p_pic->i_status != RESERVED_PICTURE &&
955                 p_pic->i_status != READY_PICTURE ) break;
956
957             if( !p_pic->i_refcount && p_pic->i_status != RESERVED_PICTURE )
958                 break;
959         }
960         if( i_pic == p_dec->p_owner->p_vout->render.i_pictures )
961         {
962             msg_Err( p_dec, "decoder is leaking pictures, resetting the heap" );
963
964             /* Just free all the pictures */
965             for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
966                  i_pic++ )
967             {
968                 if( p_pic->i_status == RESERVED_PICTURE )
969                     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
970                 if( p_pic->i_refcount > 0 )
971                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
972             }
973         }
974 #undef p_pic
975
976         msleep( VOUT_OUTMEM_SLEEP );
977     }
978
979     return p_pic;
980 }
981
982 static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
983 {
984     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
985 }
986
987 static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic )
988 {
989     vout_LinkPicture( p_dec->p_owner->p_vout, p_pic );
990 }
991
992 static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
993 {
994     vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
995 }
996
997 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
998 {
999     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1000     vout_thread_t *p_vout = NULL;
1001     subpicture_t *p_subpic;
1002     int i_attempts = 30;
1003
1004     while( i_attempts-- )
1005     {
1006         if( p_dec->b_die || p_dec->b_error ) break;
1007
1008         p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1009         if( p_vout ) break;
1010
1011         msleep( VOUT_DISPLAY_DELAY );
1012     }
1013
1014     if( !p_vout )
1015     {
1016         msg_Warn( p_dec, "no vout found, dropping subpicture" );
1017         return NULL;
1018     }
1019
1020     if( p_sys->p_spu_vout != p_vout )
1021     {
1022         spu_Control( p_vout->p_spu, SPU_CHANNEL_REGISTER,
1023                      &p_sys->i_spu_channel );
1024         p_sys->p_spu_vout = p_vout;
1025     }
1026
1027     p_subpic = spu_CreateSubpicture( p_vout->p_spu );
1028     if( p_subpic )
1029     {
1030         p_subpic->i_channel = p_sys->i_spu_channel;
1031     }
1032
1033     vlc_object_release( p_vout );
1034
1035     return p_subpic;
1036 }
1037
1038 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
1039 {
1040     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1041     vout_thread_t *p_vout = NULL;
1042
1043     p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1044     if( !p_vout || p_sys->p_spu_vout != p_vout )
1045     {
1046         if( p_vout )
1047             vlc_object_release( p_vout );
1048         msg_Warn( p_dec, "no vout found, leaking subpicture" );
1049         return;
1050     }
1051
1052     spu_DestroySubpicture( p_vout->p_spu, p_subpic );
1053
1054     vlc_object_release( p_vout );
1055 }
1056