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