]> git.sesse.net Git - vlc/blob - src/input/decoder.c
Factorize code.
[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     vlc_object_kill( p_dec );
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 inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
451 {
452     if( p->i_pts > 0 )
453         *pi_preroll = __MIN( *pi_preroll, p->i_pts );
454     else if( p->i_dts > 0 )
455         *pi_preroll = __MIN( *pi_preroll, p->i_dts );
456 }
457 static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
458 {
459     input_thread_t *p_input = p_dec->p_owner->p_input;
460     aout_buffer_t *p_aout_buf;
461
462     //DecoderUpdatePreroll( &p_dec->p_owner->i_preroll_end, p_block );
463     while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
464     {
465         vlc_mutex_lock( &p_input->p->counters.counters_lock );
466         stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_audio, 1, NULL );
467         vlc_mutex_unlock( &p_input->p->counters.counters_lock );
468
469         /* FIXME the best would be to handle the case
470          * start_date < preroll < end_date
471          * but that's not easy with non raw audio stream */
472 //        if( p_dec->p_owner->i_preroll_end > 0 )
473 //            msg_Err( p_dec, "Prerolling %lld - %lld", p_dec->p_owner->i_preroll_end, p_aout_buf->start_date );
474
475         if( p_dec->p_owner->i_preroll_end > 0 &&
476             p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
477         {
478             aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
479                                   p_dec->p_owner->p_aout_input, p_aout_buf );
480         }
481         else
482         {
483             p_dec->p_owner->i_preroll_end = -1;
484             aout_DecPlay( p_dec->p_owner->p_aout,
485                           p_dec->p_owner->p_aout_input,
486                           p_aout_buf );
487         }
488     }
489 }
490 static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
491 {
492     input_thread_t *p_input = p_dec->p_owner->p_input;
493     picture_t *p_pic;
494
495     //DecoderUpdatePreroll( &p_dec->p_owner->i_preroll_end, p_block );
496     while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
497     {
498         vlc_mutex_lock( &p_input->p->counters.counters_lock );
499         stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_video, 1, NULL );
500         vlc_mutex_unlock( &p_input->p->counters.counters_lock );
501
502         if( p_dec->p_owner->i_preroll_end > 0 &&
503             p_pic->date < p_dec->p_owner->i_preroll_end )
504         {
505             vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
506         }
507         else
508         {
509             p_dec->p_owner->i_preroll_end = -1;
510             vout_DatePicture( p_dec->p_owner->p_vout, p_pic,
511                               p_pic->date );
512             vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
513         }
514     }
515 }
516
517
518 static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
519 {
520     int i_rate = p_block ? p_block->i_rate : 1000;
521
522     if( p_block && p_block->i_buffer <= 0 )
523     {
524         block_Release( p_block );
525         return VLC_SUCCESS;
526     }
527
528     if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
529     {
530         block_t *p_sout_block;
531
532         while( ( p_sout_block =
533                      p_dec->pf_packetize( p_dec, p_block ? &p_block : 0 ) ) )
534         {
535             if( !p_dec->p_owner->p_sout_input )
536             {
537                 es_format_Copy( &p_dec->p_owner->sout, &p_dec->fmt_out );
538
539                 p_dec->p_owner->sout.i_group = p_dec->fmt_in.i_group;
540                 p_dec->p_owner->sout.i_id = p_dec->fmt_in.i_id;
541                 if( p_dec->fmt_in.psz_language )
542                 {
543                     if( p_dec->p_owner->sout.psz_language )
544                         free( p_dec->p_owner->sout.psz_language );
545                     p_dec->p_owner->sout.psz_language =
546                         strdup( p_dec->fmt_in.psz_language );
547                 }
548
549                 p_dec->p_owner->p_sout_input =
550                     sout_InputNew( p_dec->p_owner->p_sout,
551                                    &p_dec->p_owner->sout );
552
553                 if( p_dec->p_owner->p_sout_input == NULL )
554                 {
555                     msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
556                              (char *)&p_dec->p_owner->sout.i_codec );
557                     p_dec->b_error = VLC_TRUE;
558
559                     while( p_sout_block )
560                     {
561                         block_t *p_next = p_sout_block->p_next;
562                         block_Release( p_sout_block );
563                         p_sout_block = p_next;
564                     }
565                     break;
566                 }
567             }
568
569             while( p_sout_block )
570             {
571                 block_t *p_next = p_sout_block->p_next;
572
573                 p_sout_block->p_next = NULL;
574                 p_sout_block->i_rate = i_rate;
575
576                 sout_InputSendBuffer( p_dec->p_owner->p_sout_input,
577                                       p_sout_block );
578
579                 p_sout_block = p_next;
580             }
581
582             /* For now it's enough, as only sout inpact on this flag */
583             if( p_dec->p_owner->p_sout->i_out_pace_nocontrol > 0 &&
584                 p_dec->p_owner->p_input->p->b_out_pace_control )
585             {
586                 msg_Dbg( p_dec, "switching to sync mode" );
587                 p_dec->p_owner->p_input->p->b_out_pace_control = VLC_FALSE;
588             }
589             else if( p_dec->p_owner->p_sout->i_out_pace_nocontrol <= 0 &&
590                      !p_dec->p_owner->p_input->p->b_out_pace_control )
591             {
592                 msg_Dbg( p_dec, "switching to async mode" );
593                 p_dec->p_owner->p_input->p->b_out_pace_control = VLC_TRUE;
594             }
595         }
596     }
597     else if( p_dec->fmt_in.i_cat == AUDIO_ES )
598     {
599         if( p_dec->p_owner->p_packetizer )
600         {
601             block_t *p_packetized_block;
602             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
603
604             while( (p_packetized_block =
605                     p_packetizer->pf_packetize( p_packetizer, &p_block )) )
606             {
607                 if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
608                 {
609                     es_format_Clean( &p_dec->fmt_in );
610                     es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
611                 }
612
613                 while( p_packetized_block )
614                 {
615                     block_t *p_next = p_packetized_block->p_next;
616                     p_packetized_block->p_next = NULL;
617                     p_packetized_block->i_rate = i_rate;
618
619                     DecoderDecodeAudio( p_dec, p_packetized_block );
620
621                     p_packetized_block = p_next;
622                 }
623             }
624         }
625         else
626         {
627             DecoderDecodeAudio( p_dec, p_block );
628         }
629     }
630     else if( p_dec->fmt_in.i_cat == VIDEO_ES )
631     {
632         if( p_dec->p_owner->p_packetizer )
633         {
634             block_t *p_packetized_block;
635             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
636
637             while( (p_packetized_block =
638                     p_packetizer->pf_packetize( p_packetizer, &p_block )) )
639             {
640                 if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
641                 {
642                     es_format_Clean( &p_dec->fmt_in );
643                     es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
644                 }
645
646                 while( p_packetized_block )
647                 {
648                     block_t *p_next = p_packetized_block->p_next;
649                     p_packetized_block->p_next = NULL;
650                     p_packetized_block->i_rate = i_rate;
651
652                     DecoderDecodeVideo( p_dec, p_packetized_block );
653
654                     p_packetized_block = p_next;
655                 }
656             }
657         }
658         else
659         {
660             DecoderDecodeVideo( p_dec, p_block );
661         }
662     }
663     else if( p_dec->fmt_in.i_cat == SPU_ES )
664     {
665         input_thread_t *p_input = p_dec->p_owner->p_input;
666         vout_thread_t *p_vout;
667         subpicture_t *p_spu;
668         //DecoderUpdatePreroll( &p_dec->p_owner->i_preroll_end, p_block );
669         while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) )
670         {
671             vlc_mutex_lock( &p_input->p->counters.counters_lock );
672             stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_sub, 1, NULL );
673             vlc_mutex_unlock( &p_input->p->counters.counters_lock );
674
675             if( p_dec->p_owner->i_preroll_end > 0 &&
676                 p_spu->i_start < p_dec->p_owner->i_preroll_end &&
677                 ( p_spu->i_stop <= 0 || p_spu->i_stop <= p_dec->p_owner->i_preroll_end ) )
678             {
679                 spu_DestroySubpicture( p_dec->p_owner->p_vout->p_spu, p_spu );
680                 continue;
681             }
682
683             p_dec->p_owner->i_preroll_end = -1;
684             p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
685             if( p_vout )
686             {
687                 spu_DisplaySubpicture( p_vout->p_spu, p_spu );
688                 vlc_object_release( p_vout );
689             }
690         }
691     }
692     else
693     {
694         msg_Err( p_dec, "unknown ES format" );
695         p_dec->b_error = 1;
696     }
697
698     return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS;
699 }
700
701 /**
702  * Destroys a decoder object
703  *
704  * \param p_dec the decoder object
705  * \return nothing
706  */
707 static void DeleteDecoder( decoder_t * p_dec )
708 {
709     msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %d PES in FIFO",
710              (char*)&p_dec->fmt_in.i_codec,
711              p_dec->p_owner->p_fifo->i_depth );
712
713     /* Free all packets still in the decoder fifo. */
714     block_FifoEmpty( p_dec->p_owner->p_fifo );
715     block_FifoRelease( p_dec->p_owner->p_fifo );
716
717     /* Cleanup */
718     if( p_dec->p_owner->p_aout_input )
719         aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );
720
721     if( p_dec->p_owner->p_vout )
722     {
723         int i_pic;
724
725 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
726         /* Hack to make sure all the the pictures are freed by the decoder */
727         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
728              i_pic++ )
729         {
730             if( p_pic->i_status == RESERVED_PICTURE )
731                 vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
732             if( p_pic->i_refcount > 0 )
733                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
734         }
735 #undef p_pic
736
737         /* We are about to die. Reattach video output to p_vlc. */
738         vout_Request( p_dec, p_dec->p_owner->p_vout, 0 );
739     }
740
741     if( p_dec->p_owner->p_sout_input )
742     {
743         sout_InputDelete( p_dec->p_owner->p_sout_input );
744         es_format_Clean( &p_dec->p_owner->sout );
745     }
746
747     if( p_dec->fmt_in.i_cat == SPU_ES )
748     {
749         vout_thread_t *p_vout;
750
751         p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
752         if( p_vout )
753         {
754             spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,
755                          p_dec->p_owner->i_spu_channel );
756             vlc_object_release( p_vout );
757         }
758     }
759
760     es_format_Clean( &p_dec->fmt_in );
761     es_format_Clean( &p_dec->fmt_out );
762
763     if( p_dec->p_owner->p_packetizer )
764     {
765         module_Unneed( p_dec->p_owner->p_packetizer,
766                        p_dec->p_owner->p_packetizer->p_module );
767         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
768         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_out );
769         vlc_object_detach( p_dec->p_owner->p_packetizer );
770         vlc_object_destroy( p_dec->p_owner->p_packetizer );
771     }
772
773     vlc_object_detach( p_dec );
774
775     free( p_dec->p_owner );
776 }
777
778 /*****************************************************************************
779  * Buffers allocation callbacks for the decoders
780  *****************************************************************************/
781 static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
782 {
783     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
784     aout_buffer_t *p_buffer;
785
786     if( p_sys->p_aout_input != NULL &&
787         ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||
788           p_dec->fmt_out.audio.i_original_channels !=
789               p_sys->audio.i_original_channels ||
790           p_dec->fmt_out.audio.i_bytes_per_frame !=
791               p_sys->audio.i_bytes_per_frame ) )
792     {
793         /* Parameters changed, restart the aout */
794         aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
795         p_sys->p_aout_input = NULL;
796     }
797
798     if( p_sys->p_aout_input == NULL )
799     {
800         audio_sample_format_t format;
801         int i_force_dolby = config_GetInt( p_dec, "force-dolby-surround" );
802
803         p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
804         p_sys->audio = p_dec->fmt_out.audio;
805
806         memcpy( &format, &p_sys->audio, sizeof( audio_sample_format_t ) );
807         if ( i_force_dolby && (format.i_original_channels&AOUT_CHAN_PHYSMASK)
808                                     == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
809         {
810             if ( i_force_dolby == 1 )
811             {
812                 format.i_original_channels = format.i_original_channels |
813                                              AOUT_CHAN_DOLBYSTEREO;
814             }
815             else /* i_force_dolby == 2 */
816             {
817                 format.i_original_channels = format.i_original_channels &
818                                              ~AOUT_CHAN_DOLBYSTEREO;
819             }
820         }
821
822         p_sys->p_aout_input =
823             aout_DecNew( p_dec, &p_sys->p_aout, &format );
824         if( p_sys->p_aout_input == NULL )
825         {
826             msg_Err( p_dec, "failed to create audio output" );
827             p_dec->b_error = VLC_TRUE;
828             return NULL;
829         }
830         p_dec->fmt_out.audio.i_bytes_per_frame =
831             p_sys->audio.i_bytes_per_frame;
832     }
833
834     p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
835                                   i_samples );
836
837     return p_buffer;
838 }
839
840 static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
841 {
842     aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
843                           p_dec->p_owner->p_aout_input, p_buffer );
844 }
845
846 static picture_t *vout_new_buffer( decoder_t *p_dec )
847 {
848     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
849     picture_t *p_pic;
850
851     if( p_sys->p_vout == NULL ||
852         p_dec->fmt_out.video.i_width != p_sys->video.i_width ||
853         p_dec->fmt_out.video.i_height != p_sys->video.i_height ||
854         p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||
855         p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )
856     {
857         if( !p_dec->fmt_out.video.i_width ||
858             !p_dec->fmt_out.video.i_height )
859         {
860             /* Can't create a new vout without display size */
861             return NULL;
862         }
863
864         if( !p_dec->fmt_out.video.i_visible_width ||
865             !p_dec->fmt_out.video.i_visible_height )
866         {
867             if( p_dec->fmt_in.video.i_visible_width &&
868                 p_dec->fmt_in.video.i_visible_height )
869             {
870                 p_dec->fmt_out.video.i_visible_width =
871                     p_dec->fmt_in.video.i_visible_width;
872                 p_dec->fmt_out.video.i_visible_height =
873                     p_dec->fmt_in.video.i_visible_height;
874             }
875             else
876             {
877                 p_dec->fmt_out.video.i_visible_width =
878                     p_dec->fmt_out.video.i_width;
879                 p_dec->fmt_out.video.i_visible_height =
880                     p_dec->fmt_out.video.i_height;
881             }
882         }
883
884         if( p_dec->fmt_out.video.i_visible_height == 1088 &&
885             var_CreateGetBool( p_dec, "hdtv-fix" ) )
886         {
887             p_dec->fmt_out.video.i_visible_height = 1080;
888             p_dec->fmt_out.video.i_sar_num *= 135;
889             p_dec->fmt_out.video.i_sar_den *= 136;
890             msg_Warn( p_dec, "Fixing broken HDTV stream (display_height=1088)");
891         }
892
893         if( !p_dec->fmt_out.video.i_sar_num ||
894             !p_dec->fmt_out.video.i_sar_den )
895         {
896             p_dec->fmt_out.video.i_sar_num = p_dec->fmt_out.video.i_aspect *
897               p_dec->fmt_out.video.i_visible_height;
898
899             p_dec->fmt_out.video.i_sar_den = VOUT_ASPECT_FACTOR *
900               p_dec->fmt_out.video.i_visible_width;
901         }
902
903         vlc_ureduce( &p_dec->fmt_out.video.i_sar_num,
904                      &p_dec->fmt_out.video.i_sar_den,
905                      p_dec->fmt_out.video.i_sar_num,
906                      p_dec->fmt_out.video.i_sar_den, 50000 );
907
908         p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
909         p_sys->video = p_dec->fmt_out.video;
910
911         p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
912                                       &p_dec->fmt_out.video );
913         if( p_sys->p_vout == NULL )
914         {
915             msg_Err( p_dec, "failed to create video output" );
916             p_dec->b_error = VLC_TRUE;
917             return NULL;
918         }
919
920         if( p_sys->video.i_rmask )
921             p_sys->p_vout->render.i_rmask = p_sys->video.i_rmask;
922         if( p_sys->video.i_gmask )
923             p_sys->p_vout->render.i_gmask = p_sys->video.i_gmask;
924         if( p_sys->video.i_bmask )
925             p_sys->p_vout->render.i_bmask = p_sys->video.i_bmask;
926     }
927
928     /* Get a new picture */
929     while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
930     {
931         int i_pic, i_ready_pic = 0;
932
933         if( p_dec->b_die || p_dec->b_error )
934         {
935             return NULL;
936         }
937
938 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
939         /* Check the decoder doesn't leak pictures */
940         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
941              i_pic++ )
942         {
943             if( p_pic->i_status == READY_PICTURE )
944             {
945                 if( i_ready_pic++ > 0 ) break;
946                 else continue;
947             }
948
949             if( p_pic->i_status != DISPLAYED_PICTURE &&
950                 p_pic->i_status != RESERVED_PICTURE &&
951                 p_pic->i_status != READY_PICTURE ) break;
952
953             if( !p_pic->i_refcount && p_pic->i_status != RESERVED_PICTURE )
954                 break;
955         }
956         if( i_pic == p_dec->p_owner->p_vout->render.i_pictures )
957         {
958             msg_Err( p_dec, "decoder is leaking pictures, resetting the heap" );
959
960             /* Just free all the pictures */
961             for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
962                  i_pic++ )
963             {
964                 if( p_pic->i_status == RESERVED_PICTURE )
965                     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
966                 if( p_pic->i_refcount > 0 )
967                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
968             }
969         }
970 #undef p_pic
971
972         msleep( VOUT_OUTMEM_SLEEP );
973     }
974
975     return p_pic;
976 }
977
978 static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
979 {
980     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
981 }
982
983 static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic )
984 {
985     vout_LinkPicture( p_dec->p_owner->p_vout, p_pic );
986 }
987
988 static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
989 {
990     vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
991 }
992
993 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
994 {
995     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
996     vout_thread_t *p_vout = NULL;
997     subpicture_t *p_subpic;
998     int i_attempts = 30;
999
1000     while( i_attempts-- )
1001     {
1002         if( p_dec->b_die || p_dec->b_error ) break;
1003
1004         p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1005         if( p_vout ) break;
1006
1007         msleep( VOUT_DISPLAY_DELAY );
1008     }
1009
1010     if( !p_vout )
1011     {
1012         msg_Warn( p_dec, "no vout found, dropping subpicture" );
1013         return NULL;
1014     }
1015
1016     if( p_sys->p_spu_vout != p_vout )
1017     {
1018         spu_Control( p_vout->p_spu, SPU_CHANNEL_REGISTER,
1019                      &p_sys->i_spu_channel );
1020         p_sys->p_spu_vout = p_vout;
1021     }
1022
1023     p_subpic = spu_CreateSubpicture( p_vout->p_spu );
1024     if( p_subpic )
1025     {
1026         p_subpic->i_channel = p_sys->i_spu_channel;
1027     }
1028
1029     vlc_object_release( p_vout );
1030
1031     return p_subpic;
1032 }
1033
1034 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
1035 {
1036     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1037     vout_thread_t *p_vout = NULL;
1038
1039     p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1040     if( !p_vout || p_sys->p_spu_vout != p_vout )
1041     {
1042         if( p_vout )
1043             vlc_object_release( p_vout );
1044         msg_Warn( p_dec, "no vout found, leaking subpicture" );
1045         return;
1046     }
1047
1048     spu_DestroySubpicture( p_vout->p_spu, p_subpic );
1049
1050     vlc_object_release( p_vout );
1051 }
1052