]> git.sesse.net Git - vlc/blob - src/input/decoder.c
Don't include config.h from the headers - refs #297.
[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 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc/vlc.h>
34
35 #include <vlc_block.h>
36 #include <vlc_vout.h>
37 #include <vlc_aout.h>
38 #include <vlc_sout.h>
39 #include <vlc_codec.h>
40 #include <vlc_osd.h>
41
42 #include <vlc_interface.h>
43 #include "audio_output/aout_internal.h"
44 #include "stream_output/stream_output.h"
45 #include "input_internal.h"
46
47 static decoder_t * CreateDecoder( input_thread_t *, es_format_t *, int );
48 static void        DeleteDecoder( decoder_t * );
49
50 static int         DecoderThread( decoder_t * );
51 static int         DecoderDecode( decoder_t * p_dec, block_t *p_block );
52
53 /* Buffers allocation callbacks for the decoders */
54 static aout_buffer_t *aout_new_buffer( decoder_t *, int );
55 static void aout_del_buffer( decoder_t *, aout_buffer_t * );
56
57 static picture_t *vout_new_buffer( decoder_t * );
58 static void vout_del_buffer( decoder_t *, picture_t * );
59 static void vout_link_picture( decoder_t *, picture_t * );
60 static void vout_unlink_picture( decoder_t *, picture_t * );
61
62 static subpicture_t *spu_new_buffer( decoder_t * );
63 static void spu_del_buffer( decoder_t *, subpicture_t * );
64
65 static es_format_t null_es_format;
66
67 struct decoder_owner_sys_t
68 {
69     vlc_bool_t      b_own_thread;
70
71     int64_t         i_preroll_end;
72
73     input_thread_t  *p_input;
74
75     aout_instance_t *p_aout;
76     aout_input_t    *p_aout_input;
77
78     vout_thread_t   *p_vout;
79
80     vout_thread_t   *p_spu_vout;
81     int              i_spu_channel;
82
83     sout_instance_t         *p_sout;
84     sout_packetizer_input_t *p_sout_input;
85
86     /* Some decoders require already packetized data (ie. not truncated) */
87     decoder_t *p_packetizer;
88
89     /* Current format in use by the output */
90     video_format_t video;
91     audio_format_t audio;
92     es_format_t    sout;
93
94     /* fifo */
95     block_fifo_t *p_fifo;
96
97     /* CC */
98     vlc_bool_t b_cc_supported;
99     vlc_mutex_t lock_cc;
100     vlc_bool_t pb_cc_present[4];
101     decoder_t *pp_cc[4];
102 };
103
104 /* */
105 static void DecoderUnsupportedCodec( decoder_t *p_dec, vlc_fourcc_t codec )
106 {
107     msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n"
108              "VLC probably does not support this sound or video format.",
109              (char*)&codec );
110     intf_UserFatal( p_dec, VLC_FALSE, _("No suitable decoder module"), 
111                     _("VLC does not support the audio or video format \"%4.4s\". "
112                       "Unfortunately there is no way for you to fix this."), (char*)&codec );
113 }
114
115 /* decoder_GetInputAttachment:
116  */
117 input_attachment_t *decoder_GetInputAttachment( decoder_t *p_dec,
118                                                 const char *psz_name )
119 {
120     input_attachment_t *p_attachment;
121     if( input_Control( p_dec->p_owner->p_input, INPUT_GET_ATTACHMENT, &p_attachment, psz_name ) )
122         return NULL;
123     return p_attachment;
124 }
125 /* decoder_GetInputAttachments:
126  */
127 int decoder_GetInputAttachments( decoder_t *p_dec,
128                                  input_attachment_t ***ppp_attachment,
129                                  int *pi_attachment )
130 {
131     return input_Control( p_dec->p_owner->p_input, INPUT_GET_ATTACHMENTS,
132                           ppp_attachment, pi_attachment );
133 }
134 /* decoder_GetDisplayDate:
135  */
136 mtime_t decoder_GetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
137 {
138     return i_ts;
139 }
140
141 /**
142  * Spawns a new decoder thread
143  *
144  * \param p_input the input thread
145  * \param p_es the es descriptor
146  * \return the spawned decoder object
147  */
148 decoder_t *input_DecoderNew( input_thread_t *p_input,
149                              es_format_t *fmt, vlc_bool_t b_force_decoder )
150 {
151     decoder_t   *p_dec = NULL;
152     vlc_value_t val;
153
154     /* If we are in sout mode, search for packetizer module */
155     if( p_input->p->p_sout && !b_force_decoder )
156     {
157         /* Create the decoder configuration structure */
158         p_dec = CreateDecoder( p_input, fmt, VLC_OBJECT_PACKETIZER );
159         if( p_dec == NULL )
160         {
161             msg_Err( p_input, "could not create packetizer" );
162             intf_UserFatal( p_input, VLC_FALSE, _("Streaming / Transcoding failed"),
163                             _("VLC could not open the packetizer module.") );
164             return NULL;
165         }
166     }
167     else
168     {
169         /* Create the decoder configuration structure */
170         p_dec = CreateDecoder( p_input, fmt, VLC_OBJECT_DECODER );
171         if( p_dec == NULL )
172         {
173             msg_Err( p_input, "could not create decoder" );
174             intf_UserFatal( p_input, VLC_FALSE, _("Streaming / Transcoding failed"),
175                             _("VLC could not open the decoder module.") );
176             return NULL;
177         }
178     }
179
180     if( !p_dec->p_module )
181     {
182         DecoderUnsupportedCodec( p_dec, fmt->i_codec );
183
184         DeleteDecoder( p_dec );
185         vlc_object_destroy( p_dec );
186         return NULL;
187     }
188
189     if( p_input->p->p_sout && p_input->p->input.b_can_pace_control &&
190         !b_force_decoder )
191     {
192         msg_Dbg( p_input, "stream out mode -> no decoder thread" );
193         p_dec->p_owner->b_own_thread = VLC_FALSE;
194     }
195     else
196     {
197         var_Get( p_input, "minimize-threads", &val );
198         p_dec->p_owner->b_own_thread = !val.b_bool;
199     }
200
201     if( p_dec->p_owner->b_own_thread )
202     {
203         int i_priority;
204         if( fmt->i_cat == AUDIO_ES )
205             i_priority = VLC_THREAD_PRIORITY_AUDIO;
206         else
207             i_priority = VLC_THREAD_PRIORITY_VIDEO;
208
209         /* Spawn the decoder thread */
210         if( vlc_thread_create( p_dec, "decoder", DecoderThread,
211                                i_priority, VLC_FALSE ) )
212         {
213             msg_Err( p_dec, "cannot spawn decoder thread" );
214             module_Unneed( p_dec, p_dec->p_module );
215             DeleteDecoder( p_dec );
216             vlc_object_destroy( p_dec );
217             return NULL;
218         }
219     }
220
221     return p_dec;
222 }
223
224 /**
225  * Kills a decoder thread and waits until it's finished
226  *
227  * \param p_input the input thread
228  * \param p_es the es descriptor
229  * \return nothing
230  */
231 void input_DecoderDelete( decoder_t *p_dec )
232 {
233     vlc_object_kill( p_dec );
234
235     if( p_dec->p_owner->b_own_thread )
236     {
237         /* Make sure the thread leaves the function by
238          * sending it an empty block. */
239         block_t *p_block = block_New( p_dec, 0 );
240         input_DecoderDecode( p_dec, p_block );
241
242         vlc_thread_join( p_dec );
243
244         /* Don't module_Unneed() here because of the dll loader that wants
245          * close() in the same thread than open()/decode() */
246     }
247     else
248     {
249         /* Flush */
250         input_DecoderDecode( p_dec, NULL );
251
252         module_Unneed( p_dec, p_dec->p_module );
253     }
254
255     /* */
256     if( p_dec->p_owner->b_cc_supported )
257     {
258         int i;
259         for( i = 0; i < 4; i++ )
260             input_DecoderSetCcState( p_dec, VLC_FALSE, i );
261     }
262
263     /* Delete decoder configuration */
264     DeleteDecoder( p_dec );
265
266     /* Delete the decoder */
267     vlc_object_destroy( p_dec );
268 }
269
270 /**
271  * Put a block_t in the decoder's fifo.
272  *
273  * \param p_dec the decoder object
274  * \param p_block the data block
275  */
276 void input_DecoderDecode( decoder_t * p_dec, block_t *p_block )
277 {
278     if( p_dec->p_owner->b_own_thread )
279     {
280         if( p_dec->p_owner->p_input->p->b_out_pace_control )
281         {
282             /* FIXME !!!!! */
283             while( !p_dec->b_die && !p_dec->b_error &&
284                    block_FifoCount( p_dec->p_owner->p_fifo ) > 10 )
285             {
286                 msleep( 1000 );
287             }
288         }
289         else if( block_FifoSize( p_dec->p_owner->p_fifo ) > 50000000 /* 50 MB */ )
290         {
291             /* FIXME: ideally we would check the time amount of data
292              * in the fifo instead of its size. */
293             msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
294                       "consumed quickly enough), resetting fifo!" );
295             block_FifoEmpty( p_dec->p_owner->p_fifo );
296         }
297
298         block_FifoPut( p_dec->p_owner->p_fifo, p_block );
299     }
300     else
301     {
302         if( p_dec->b_error || (p_block && p_block->i_buffer <= 0) )
303         {
304             if( p_block ) block_Release( p_block );
305         }
306         else
307         {
308             DecoderDecode( p_dec, p_block );
309         }
310     }
311 }
312
313 void input_DecoderDiscontinuity( decoder_t * p_dec, vlc_bool_t b_flush )
314 {
315     block_t *p_null;
316
317     /* Empty the fifo */
318     if( p_dec->p_owner->b_own_thread && b_flush )
319         block_FifoEmpty( p_dec->p_owner->p_fifo );
320
321     /* Send a special block */
322     p_null = block_New( p_dec, 128 );
323     p_null->i_flags |= BLOCK_FLAG_DISCONTINUITY;
324     /* FIXME check for p_packetizer or b_packitized from es_format_t of input ? */
325     if( p_dec->p_owner->p_packetizer && b_flush )
326         p_null->i_flags |= BLOCK_FLAG_CORRUPTED;
327     memset( p_null->p_buffer, 0, p_null->i_buffer );
328
329     input_DecoderDecode( p_dec, p_null );
330 }
331
332 vlc_bool_t input_DecoderEmpty( decoder_t * p_dec )
333 {
334     if( p_dec->p_owner->b_own_thread
335      && block_FifoCount( p_dec->p_owner->p_fifo ) > 0 )
336     {
337         return VLC_FALSE;
338     }
339     return VLC_TRUE;
340 }
341
342 void input_DecoderIsCcPresent( decoder_t *p_dec, vlc_bool_t pb_present[4] )
343 {
344     int i;
345
346     vlc_mutex_lock( &p_dec->p_owner->lock_cc );
347     for( i = 0; i < 4; i++ )
348         pb_present[i] =  p_dec->p_owner->pb_cc_present[i];
349     vlc_mutex_unlock( &p_dec->p_owner->lock_cc );
350 }
351 int input_DecoderSetCcState( decoder_t *p_dec, vlc_bool_t b_decode, int i_channel )
352 {
353     decoder_owner_sys_t *p_owner = p_dec->p_owner;
354
355     //msg_Warn( p_dec, "input_DecoderSetCcState: %d @%d", b_decode, i_channel );
356
357     if( i_channel < 0 || i_channel >= 4 || !p_owner->pb_cc_present[i_channel] )
358         return VLC_EGENERIC;
359
360     if( b_decode )
361     {
362         static const vlc_fourcc_t fcc[4] = {
363             VLC_FOURCC('c', 'c', '1', ' '),
364             VLC_FOURCC('c', 'c', '2', ' '),
365             VLC_FOURCC('c', 'c', '3', ' '),
366             VLC_FOURCC('c', 'c', '4', ' '),
367         };
368         decoder_t *p_cc;
369         es_format_t fmt;
370
371         es_format_Init( &fmt, SPU_ES, fcc[i_channel] );
372         p_cc = CreateDecoder( p_owner->p_input, &fmt, VLC_OBJECT_DECODER );
373         if( !p_cc )
374         {
375             msg_Err( p_dec, "could not create decoder" );
376             intf_UserFatal( p_dec, VLC_FALSE, _("Streaming / Transcoding failed"),
377                             _("VLC could not open the decoder module.") );
378             return VLC_EGENERIC;
379         }
380         else if( !p_cc->p_module )
381         {
382             DecoderUnsupportedCodec( p_dec, fcc[i_channel] );
383             DeleteDecoder( p_cc );
384             vlc_object_destroy( p_cc );
385             return VLC_EGENERIC;
386         }
387
388         vlc_mutex_lock( &p_owner->lock_cc );
389         p_dec->p_owner->pp_cc[i_channel] = p_cc;
390         vlc_mutex_unlock( &p_owner->lock_cc );
391     }
392     else
393     {
394         decoder_t *p_cc;
395
396         vlc_mutex_lock( &p_owner->lock_cc );
397         p_cc = p_dec->p_owner->pp_cc[i_channel];
398         p_dec->p_owner->pp_cc[i_channel] = NULL;
399         vlc_mutex_unlock( &p_dec->p_owner->lock_cc );
400
401         if( p_cc )
402         {
403             vlc_object_kill( p_cc );
404             module_Unneed( p_cc, p_cc->p_module );
405             DeleteDecoder( p_cc );
406             vlc_object_destroy( p_cc );
407         }
408     }
409     return VLC_SUCCESS;
410 }
411 int input_DecoderGetCcState( decoder_t *p_dec, vlc_bool_t *pb_decode, int i_channel )
412 {
413     decoder_owner_sys_t *p_owner = p_dec->p_owner;
414
415     *pb_decode = VLC_FALSE;
416     if( i_channel < 0 || i_channel >= 4 || !p_owner->pb_cc_present[i_channel] )
417         return VLC_EGENERIC;
418
419     vlc_mutex_lock( &p_owner->lock_cc );
420     *pb_decode = p_dec->p_owner->pp_cc[i_channel] != NULL;
421     vlc_mutex_unlock( &p_dec->p_owner->lock_cc );
422     return VLC_EGENERIC;
423 }
424
425 /**
426  * Create a decoder object
427  *
428  * \param p_input the input thread
429  * \param p_es the es descriptor
430  * \param i_object_type Object type as define in include/vlc_objects.h
431  * \return the decoder object
432  */
433 static decoder_t * CreateDecoder( input_thread_t *p_input,
434                                   es_format_t *fmt, int i_object_type )
435 {
436     decoder_t *p_dec;
437     decoder_owner_sys_t *p_owner;
438     int i;
439
440     p_dec = vlc_object_create( p_input, i_object_type );
441     if( p_dec == NULL )
442     {
443         msg_Err( p_input, "out of memory" );
444         return NULL;
445     }
446
447     p_dec->pf_decode_audio = 0;
448     p_dec->pf_decode_video = 0;
449     p_dec->pf_decode_sub = 0;
450     p_dec->pf_get_cc = 0;
451     p_dec->pf_packetize = 0;
452
453     /* Initialize the decoder fifo */
454     p_dec->p_module = NULL;
455
456     memset( &null_es_format, 0, sizeof(es_format_t) );
457     es_format_Copy( &p_dec->fmt_in, fmt );
458     es_format_Copy( &p_dec->fmt_out, &null_es_format );
459
460     /* Allocate our private structure for the decoder */
461     p_dec->p_owner = p_owner = malloc( sizeof( decoder_owner_sys_t ) );
462     if( p_dec->p_owner == NULL )
463     {
464         msg_Err( p_dec, "out of memory" );
465         return NULL;
466     }
467     p_dec->p_owner->b_own_thread = VLC_TRUE;
468     p_dec->p_owner->i_preroll_end = -1;
469     p_dec->p_owner->p_input = p_input;
470     p_dec->p_owner->p_aout = NULL;
471     p_dec->p_owner->p_aout_input = NULL;
472     p_dec->p_owner->p_vout = NULL;
473     p_dec->p_owner->p_spu_vout = NULL;
474     p_dec->p_owner->i_spu_channel = 0;
475     p_dec->p_owner->p_sout = p_input->p->p_sout;
476     p_dec->p_owner->p_sout_input = NULL;
477     p_dec->p_owner->p_packetizer = NULL;
478
479     /* decoder fifo */
480     if( ( p_dec->p_owner->p_fifo = block_FifoNew( p_dec ) ) == NULL )
481     {
482         msg_Err( p_dec, "out of memory" );
483         return NULL;
484     }
485
486     /* Set buffers allocation callbacks for the decoders */
487     p_dec->pf_aout_buffer_new = aout_new_buffer;
488     p_dec->pf_aout_buffer_del = aout_del_buffer;
489     p_dec->pf_vout_buffer_new = vout_new_buffer;
490     p_dec->pf_vout_buffer_del = vout_del_buffer;
491     p_dec->pf_picture_link    = vout_link_picture;
492     p_dec->pf_picture_unlink  = vout_unlink_picture;
493     p_dec->pf_spu_buffer_new  = spu_new_buffer;
494     p_dec->pf_spu_buffer_del  = spu_del_buffer;
495
496     vlc_object_attach( p_dec, p_input );
497
498     /* Find a suitable decoder/packetizer module */
499     if( i_object_type == VLC_OBJECT_DECODER )
500         p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
501     else
502         p_dec->p_module = module_Need( p_dec, "packetizer", "$packetizer", 0 );
503
504     /* Check if decoder requires already packetized data */
505     if( i_object_type == VLC_OBJECT_DECODER &&
506         p_dec->b_need_packetized && !p_dec->fmt_in.b_packetized )
507     {
508         p_dec->p_owner->p_packetizer =
509             vlc_object_create( p_input, VLC_OBJECT_PACKETIZER );
510         if( p_dec->p_owner->p_packetizer )
511         {
512             es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_in,
513                             &p_dec->fmt_in );
514
515             es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_out,
516                             &null_es_format );
517
518             vlc_object_attach( p_dec->p_owner->p_packetizer, p_input );
519
520             p_dec->p_owner->p_packetizer->p_module =
521                 module_Need( p_dec->p_owner->p_packetizer,
522                              "packetizer", "$packetizer", 0 );
523
524             if( !p_dec->p_owner->p_packetizer->p_module )
525             {
526                 es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
527                 vlc_object_detach( p_dec->p_owner->p_packetizer );
528                 vlc_object_destroy( p_dec->p_owner->p_packetizer );
529             }
530         }
531     }
532
533     /* Copy ourself the input replay gain */
534     if( fmt->i_cat == AUDIO_ES )
535     {
536         for( i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
537         {
538             if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
539             {
540                 p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
541                 p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
542             }
543             if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
544             {
545                 p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
546                 p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
547             }
548         }
549     }
550     /* */
551     p_owner->b_cc_supported = VLC_FALSE;
552     if( i_object_type == VLC_OBJECT_DECODER )
553     {
554         if( p_owner->p_packetizer && p_owner->p_packetizer->pf_get_cc )
555             p_owner->b_cc_supported = VLC_TRUE;
556         if( p_dec->pf_get_cc )
557             p_owner->b_cc_supported = VLC_TRUE;
558     }
559
560     vlc_mutex_init( p_dec, &p_owner->lock_cc );
561     for( i = 0; i < 4; i++ )
562     {
563         p_owner->pb_cc_present[i] = VLC_FALSE;
564         p_owner->pp_cc[i] = NULL;
565     }
566     return p_dec;
567 }
568
569 /**
570  * The decoding main loop
571  *
572  * \param p_dec the decoder
573  * \return 0
574  */
575 static int DecoderThread( decoder_t * p_dec )
576 {
577     block_t *p_block;
578
579     /* The decoder's main loop */
580     while( !p_dec->b_die && !p_dec->b_error )
581     {
582         if( ( p_block = block_FifoGet( p_dec->p_owner->p_fifo ) ) == NULL )
583         {
584             p_dec->b_error = 1;
585             break;
586         }
587         if( DecoderDecode( p_dec, p_block ) != VLC_SUCCESS )
588         {
589             break;
590         }
591     }
592
593     while( !p_dec->b_die )
594     {
595         /* Trash all received PES packets */
596         p_block = block_FifoGet( p_dec->p_owner->p_fifo );
597         if( p_block ) block_Release( p_block );
598     }
599
600     /* We do it here because of the dll loader that wants close() in the
601      * same thread than open()/decode() */
602     module_Unneed( p_dec, p_dec->p_module );
603
604     return 0;
605 }
606
607 static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
608 {
609     if( p->i_flags & (BLOCK_FLAG_PREROLL|BLOCK_FLAG_DISCONTINUITY) )
610         *pi_preroll = INT64_MAX;
611     else if( p->i_pts > 0 )
612         *pi_preroll = __MIN( *pi_preroll, p->i_pts );
613     else if( p->i_dts > 0 )
614         *pi_preroll = __MIN( *pi_preroll, p->i_dts );
615 }
616 static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
617 {
618     input_thread_t *p_input = p_dec->p_owner->p_input;
619     const int i_rate = p_block->i_rate;
620     aout_buffer_t *p_aout_buf;
621
622     while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
623     {
624         vlc_mutex_lock( &p_input->p->counters.counters_lock );
625         stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_audio, 1, NULL );
626         vlc_mutex_unlock( &p_input->p->counters.counters_lock );
627
628         if( p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )
629         {
630             aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
631                                   p_dec->p_owner->p_aout_input, p_aout_buf );
632             continue;
633         }
634
635         if( p_dec->p_owner->i_preroll_end > 0 )
636         {
637             /* FIXME TODO flush audio output (don't know how to do that) */
638             msg_Dbg( p_dec, "End of audio preroll" );
639             p_dec->p_owner->i_preroll_end = -1;
640         }
641         aout_DecPlay( p_dec->p_owner->p_aout,
642                       p_dec->p_owner->p_aout_input,
643                       p_aout_buf, i_rate );
644     }
645 }
646 static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
647 {
648     block_t *p_cc;
649     vlc_bool_t pb_present[4];
650     int i;
651     int i_cc_decoder;
652
653     assert( p_dec_cc->pf_get_cc != NULL );
654
655     /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
656     if( !p_dec->p_owner->b_cc_supported )
657         return;
658
659     p_cc = p_dec_cc->pf_get_cc( p_dec_cc, pb_present );
660     if( !p_cc )
661         return;
662
663     vlc_mutex_lock( &p_dec->p_owner->lock_cc );
664     for( i = 0, i_cc_decoder = 0; i < 4; i++ )
665     {
666         p_dec->p_owner->pb_cc_present[i] |= pb_present[i];
667         if( p_dec->p_owner->pp_cc[i] )
668             i_cc_decoder++;
669     }
670
671     for( i = 0; i < 4; i++ )
672     {
673         if( !p_dec->p_owner->pp_cc[i] )
674             continue;
675
676         if( i_cc_decoder > 1 )
677             DecoderDecode( p_dec->p_owner->pp_cc[i], block_Duplicate( p_cc ) );
678         else
679             DecoderDecode( p_dec->p_owner->pp_cc[i], p_cc );
680         i_cc_decoder--;
681     }
682     vlc_mutex_unlock( &p_dec->p_owner->lock_cc );
683 }
684 static void VoutDisplayedPicture( vout_thread_t *p_vout, picture_t *p_pic )
685 {
686     vlc_mutex_lock( &p_vout->picture_lock );
687
688     if( p_pic->i_status == READY_PICTURE )
689     {
690         /* Grr cannot destroy ready picture by myself so be sure vout won't like it */
691         p_pic->date = 1;
692     }
693     else if( p_pic->i_refcount > 0 )
694     {
695         p_pic->i_status = DISPLAYED_PICTURE;
696     }
697     else
698     {
699         p_pic->i_status = DESTROYED_PICTURE;
700         p_vout->i_heap_size--;
701     }
702
703     vlc_mutex_unlock( &p_vout->picture_lock );
704 }
705 static void VoutFlushPicture( vout_thread_t *p_vout )
706 {
707     int i;
708     vlc_mutex_lock( &p_vout->picture_lock );
709     for( i = 0; i < p_vout->render.i_pictures; i++ )
710     {
711         picture_t *p_pic = p_vout->render.pp_picture[i];
712
713         if( p_pic->i_status == READY_PICTURE ||
714             p_pic->i_status == DISPLAYED_PICTURE )
715         {
716             /* We cannot change picture status if it is in READY_PICTURE state,
717              * Just make sure they won't be displayed */
718             p_pic->date = 1;
719         }
720     }
721     vlc_mutex_unlock( &p_vout->picture_lock );
722 }
723 static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
724 {
725     input_thread_t *p_input = p_dec->p_owner->p_input;
726     picture_t *p_pic;
727
728     while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
729     {
730         vlc_mutex_lock( &p_input->p->counters.counters_lock );
731         stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_video, 1, NULL );
732         vlc_mutex_unlock( &p_input->p->counters.counters_lock );
733
734         if( p_pic->date < p_dec->p_owner->i_preroll_end )
735         {
736             VoutDisplayedPicture( p_dec->p_owner->p_vout, p_pic );
737             continue;
738         }
739
740         if( p_dec->p_owner->i_preroll_end > 0 )
741         {
742             msg_Dbg( p_dec, "End of video preroll" );
743             if( p_dec->p_owner->p_vout )
744                 VoutFlushPicture( p_dec->p_owner->p_vout );
745             /* */
746             p_dec->p_owner->i_preroll_end = -1;
747         }
748
749         if( ( !p_dec->p_owner->p_packetizer || !p_dec->p_owner->p_packetizer->pf_get_cc ) && p_dec->pf_get_cc )
750             DecoderGetCc( p_dec, p_dec );
751
752         vout_DatePicture( p_dec->p_owner->p_vout, p_pic,
753                           p_pic->date );
754         vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
755     }
756 }
757
758 /**
759  * Decode a block
760  *
761  * \param p_dec the decoder object
762  * \param p_block the block to decode
763  * \return VLC_SUCCESS or an error code
764  */
765 static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
766 {
767     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
768     const int i_rate = p_block ? p_block->i_rate : INPUT_RATE_DEFAULT;
769
770     if( p_block && p_block->i_buffer <= 0 )
771     {
772         block_Release( p_block );
773         return VLC_SUCCESS;
774     }
775
776     if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
777     {
778         block_t *p_sout_block;
779
780         while( ( p_sout_block =
781                      p_dec->pf_packetize( p_dec, p_block ? &p_block : 0 ) ) )
782         {
783             if( !p_dec->p_owner->p_sout_input )
784             {
785                 es_format_Copy( &p_dec->p_owner->sout, &p_dec->fmt_out );
786
787                 p_dec->p_owner->sout.i_group = p_dec->fmt_in.i_group;
788                 p_dec->p_owner->sout.i_id = p_dec->fmt_in.i_id;
789                 if( p_dec->fmt_in.psz_language )
790                 {
791                     if( p_dec->p_owner->sout.psz_language )
792                         free( p_dec->p_owner->sout.psz_language );
793                     p_dec->p_owner->sout.psz_language =
794                         strdup( p_dec->fmt_in.psz_language );
795                 }
796
797                 p_dec->p_owner->p_sout_input =
798                     sout_InputNew( p_dec->p_owner->p_sout,
799                                    &p_dec->p_owner->sout );
800
801                 if( p_dec->p_owner->p_sout_input == NULL )
802                 {
803                     msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
804                              (char *)&p_dec->p_owner->sout.i_codec );
805                     p_dec->b_error = VLC_TRUE;
806
807                     while( p_sout_block )
808                     {
809                         block_t *p_next = p_sout_block->p_next;
810                         block_Release( p_sout_block );
811                         p_sout_block = p_next;
812                     }
813                     break;
814                 }
815             }
816
817             while( p_sout_block )
818             {
819                 block_t *p_next = p_sout_block->p_next;
820
821                 p_sout_block->p_next = NULL;
822                 p_sout_block->i_rate = i_rate;
823
824                 sout_InputSendBuffer( p_dec->p_owner->p_sout_input,
825                                       p_sout_block );
826
827                 p_sout_block = p_next;
828             }
829
830             /* For now it's enough, as only sout inpact on this flag */
831             if( p_dec->p_owner->p_sout->i_out_pace_nocontrol > 0 &&
832                 p_dec->p_owner->p_input->p->b_out_pace_control )
833             {
834                 msg_Dbg( p_dec, "switching to sync mode" );
835                 p_dec->p_owner->p_input->p->b_out_pace_control = VLC_FALSE;
836             }
837             else if( p_dec->p_owner->p_sout->i_out_pace_nocontrol <= 0 &&
838                      !p_dec->p_owner->p_input->p->b_out_pace_control )
839             {
840                 msg_Dbg( p_dec, "switching to async mode" );
841                 p_dec->p_owner->p_input->p->b_out_pace_control = VLC_TRUE;
842             }
843         }
844     }
845     else if( p_dec->fmt_in.i_cat == AUDIO_ES )
846     {
847         if( p_block )
848             DecoderUpdatePreroll( &p_dec->p_owner->i_preroll_end, p_block );
849
850         if( p_dec->p_owner->p_packetizer )
851         {
852             block_t *p_packetized_block;
853             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
854
855             while( (p_packetized_block =
856                     p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) )
857             {
858                 if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
859                 {
860                     es_format_Clean( &p_dec->fmt_in );
861                     es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
862                 }
863
864                 while( p_packetized_block )
865                 {
866                     block_t *p_next = p_packetized_block->p_next;
867                     p_packetized_block->p_next = NULL;
868                     p_packetized_block->i_rate = i_rate;
869
870                     DecoderDecodeAudio( p_dec, p_packetized_block );
871
872                     p_packetized_block = p_next;
873                 }
874             }
875         }
876         else if( p_block )
877         {
878             DecoderDecodeAudio( p_dec, p_block );
879         }
880     }
881     else if( p_dec->fmt_in.i_cat == VIDEO_ES )
882     {
883         if( p_block )
884             DecoderUpdatePreroll( &p_dec->p_owner->i_preroll_end, p_block );
885
886         if( p_dec->p_owner->p_packetizer )
887         {
888             block_t *p_packetized_block;
889             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
890
891             while( (p_packetized_block =
892                     p_packetizer->pf_packetize( p_packetizer, p_block ? &p_block : NULL )) )
893             {
894                 if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )
895                 {
896                     es_format_Clean( &p_dec->fmt_in );
897                     es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );
898                 }
899                 if( p_packetizer->pf_get_cc )
900                     DecoderGetCc( p_dec, p_packetizer );
901
902                 while( p_packetized_block )
903                 {
904                     block_t *p_next = p_packetized_block->p_next;
905                     p_packetized_block->p_next = NULL;
906                     p_packetized_block->i_rate = i_rate;
907
908                     DecoderDecodeVideo( p_dec, p_packetized_block );
909
910                     p_packetized_block = p_next;
911                 }
912             }
913         }
914         else if( p_block )
915         {
916             DecoderDecodeVideo( p_dec, p_block );
917         }
918     }
919     else if( p_dec->fmt_in.i_cat == SPU_ES )
920     {
921         input_thread_t *p_input = p_dec->p_owner->p_input;
922         vout_thread_t *p_vout;
923         subpicture_t *p_spu;
924
925         if( p_block )
926             DecoderUpdatePreroll( &p_dec->p_owner->i_preroll_end, p_block );
927
928         while( (p_spu = p_dec->pf_decode_sub( p_dec, p_block ? &p_block : NULL ) ) )
929         {
930             vlc_mutex_lock( &p_input->p->counters.counters_lock );
931             stats_UpdateInteger( p_dec, p_input->p->counters.p_decoded_sub, 1, NULL );
932             vlc_mutex_unlock( &p_input->p->counters.counters_lock );
933
934             p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
935             if( p_vout && p_sys->p_spu_vout == p_vout )
936             {
937                 /* Prerool does not work very well with subtitle */
938                 if( p_spu->i_start < p_dec->p_owner->i_preroll_end &&
939                     ( p_spu->i_stop <= 0 || p_spu->i_stop < p_dec->p_owner->i_preroll_end ) )
940                     spu_DestroySubpicture( p_vout->p_spu, p_spu );
941                 else
942                     spu_DisplaySubpicture( p_vout->p_spu, p_spu );
943             }
944             else
945             {
946                 msg_Warn( p_dec, "no vout found, leaking subpicture" );
947             }
948             if( p_vout )
949                 vlc_object_release( p_vout );
950         }
951     }
952     else
953     {
954         msg_Err( p_dec, "unknown ES format" );
955         p_dec->b_error = 1;
956     }
957
958     return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS;
959 }
960
961 /**
962  * Destroys a decoder object
963  *
964  * \param p_dec the decoder object
965  * \return nothing
966  */
967 static void DeleteDecoder( decoder_t * p_dec )
968 {
969     msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %u PES in FIFO",
970              (char*)&p_dec->fmt_in.i_codec,
971              (unsigned)block_FifoCount( p_dec->p_owner->p_fifo ) );
972
973     /* Free all packets still in the decoder fifo. */
974     block_FifoEmpty( p_dec->p_owner->p_fifo );
975     block_FifoRelease( p_dec->p_owner->p_fifo );
976
977     /* Cleanup */
978     if( p_dec->p_owner->p_aout_input )
979         aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );
980
981     if( p_dec->p_owner->p_vout )
982     {
983         int i_pic;
984
985 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
986         /* Hack to make sure all the the pictures are freed by the decoder */
987         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
988              i_pic++ )
989         {
990             if( p_pic->i_status == RESERVED_PICTURE )
991                 vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
992             if( p_pic->i_refcount > 0 )
993                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
994         }
995 #undef p_pic
996
997         /* We are about to die. Reattach video output to p_vlc. */
998         vout_Request( p_dec, p_dec->p_owner->p_vout, 0 );
999     }
1000
1001     if( p_dec->p_owner->p_sout_input )
1002     {
1003         sout_InputDelete( p_dec->p_owner->p_sout_input );
1004         es_format_Clean( &p_dec->p_owner->sout );
1005     }
1006
1007     if( p_dec->fmt_in.i_cat == SPU_ES )
1008     {
1009         vout_thread_t *p_vout;
1010
1011         p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1012         if( p_vout )
1013         {
1014             spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,
1015                          p_dec->p_owner->i_spu_channel );
1016             vlc_object_release( p_vout );
1017         }
1018     }
1019
1020     es_format_Clean( &p_dec->fmt_in );
1021     es_format_Clean( &p_dec->fmt_out );
1022
1023     if( p_dec->p_owner->p_packetizer )
1024     {
1025         module_Unneed( p_dec->p_owner->p_packetizer,
1026                        p_dec->p_owner->p_packetizer->p_module );
1027         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
1028         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_out );
1029         vlc_object_detach( p_dec->p_owner->p_packetizer );
1030         vlc_object_destroy( p_dec->p_owner->p_packetizer );
1031     }
1032
1033     vlc_mutex_destroy( &p_dec->p_owner->lock_cc );
1034
1035     vlc_object_detach( p_dec );
1036
1037     free( p_dec->p_owner );
1038 }
1039
1040 /*****************************************************************************
1041  * Buffers allocation callbacks for the decoders
1042  *****************************************************************************/
1043 static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
1044 {
1045     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1046     aout_buffer_t *p_buffer;
1047
1048     if( p_sys->p_aout_input != NULL &&
1049         ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||
1050           p_dec->fmt_out.audio.i_original_channels !=
1051               p_sys->audio.i_original_channels ||
1052           p_dec->fmt_out.audio.i_bytes_per_frame !=
1053               p_sys->audio.i_bytes_per_frame ) )
1054     {
1055         /* Parameters changed, restart the aout */
1056         aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
1057         p_sys->p_aout_input = NULL;
1058     }
1059
1060     if( p_sys->p_aout_input == NULL )
1061     {
1062         audio_sample_format_t format;
1063         int i_force_dolby = config_GetInt( p_dec, "force-dolby-surround" );
1064
1065         p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
1066         p_sys->audio = p_dec->fmt_out.audio;
1067
1068         memcpy( &format, &p_sys->audio, sizeof( audio_sample_format_t ) );
1069         if ( i_force_dolby && (format.i_original_channels&AOUT_CHAN_PHYSMASK)
1070                                     == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
1071         {
1072             if ( i_force_dolby == 1 )
1073             {
1074                 format.i_original_channels = format.i_original_channels |
1075                                              AOUT_CHAN_DOLBYSTEREO;
1076             }
1077             else /* i_force_dolby == 2 */
1078             {
1079                 format.i_original_channels = format.i_original_channels &
1080                                              ~AOUT_CHAN_DOLBYSTEREO;
1081             }
1082         }
1083
1084         p_sys->p_aout_input =
1085             aout_DecNew( p_dec, &p_sys->p_aout, &format, &p_dec->fmt_out.audio_replay_gain );
1086         if( p_sys->p_aout_input == NULL )
1087         {
1088             msg_Err( p_dec, "failed to create audio output" );
1089             p_dec->b_error = VLC_TRUE;
1090             return NULL;
1091         }
1092         p_dec->fmt_out.audio.i_bytes_per_frame =
1093             p_sys->audio.i_bytes_per_frame;
1094     }
1095
1096     p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
1097                                   i_samples );
1098
1099     return p_buffer;
1100 }
1101
1102 static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
1103 {
1104     aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
1105                           p_dec->p_owner->p_aout_input, p_buffer );
1106 }
1107
1108 static picture_t *vout_new_buffer( decoder_t *p_dec )
1109 {
1110     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1111     picture_t *p_pic;
1112
1113     if( p_sys->p_vout == NULL ||
1114         p_dec->fmt_out.video.i_width != p_sys->video.i_width ||
1115         p_dec->fmt_out.video.i_height != p_sys->video.i_height ||
1116         p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||
1117         p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )
1118     {
1119         if( !p_dec->fmt_out.video.i_width ||
1120             !p_dec->fmt_out.video.i_height )
1121         {
1122             /* Can't create a new vout without display size */
1123             return NULL;
1124         }
1125
1126         if( !p_dec->fmt_out.video.i_visible_width ||
1127             !p_dec->fmt_out.video.i_visible_height )
1128         {
1129             if( p_dec->fmt_in.video.i_visible_width &&
1130                 p_dec->fmt_in.video.i_visible_height )
1131             {
1132                 p_dec->fmt_out.video.i_visible_width =
1133                     p_dec->fmt_in.video.i_visible_width;
1134                 p_dec->fmt_out.video.i_visible_height =
1135                     p_dec->fmt_in.video.i_visible_height;
1136             }
1137             else
1138             {
1139                 p_dec->fmt_out.video.i_visible_width =
1140                     p_dec->fmt_out.video.i_width;
1141                 p_dec->fmt_out.video.i_visible_height =
1142                     p_dec->fmt_out.video.i_height;
1143             }
1144         }
1145
1146         if( p_dec->fmt_out.video.i_visible_height == 1088 &&
1147             var_CreateGetBool( p_dec, "hdtv-fix" ) )
1148         {
1149             p_dec->fmt_out.video.i_visible_height = 1080;
1150             p_dec->fmt_out.video.i_sar_num *= 135;
1151             p_dec->fmt_out.video.i_sar_den *= 136;
1152             msg_Warn( p_dec, "Fixing broken HDTV stream (display_height=1088)");
1153         }
1154
1155         if( !p_dec->fmt_out.video.i_sar_num ||
1156             !p_dec->fmt_out.video.i_sar_den )
1157         {
1158             p_dec->fmt_out.video.i_sar_num = p_dec->fmt_out.video.i_aspect *
1159               p_dec->fmt_out.video.i_visible_height;
1160
1161             p_dec->fmt_out.video.i_sar_den = VOUT_ASPECT_FACTOR *
1162               p_dec->fmt_out.video.i_visible_width;
1163         }
1164
1165         vlc_ureduce( &p_dec->fmt_out.video.i_sar_num,
1166                      &p_dec->fmt_out.video.i_sar_den,
1167                      p_dec->fmt_out.video.i_sar_num,
1168                      p_dec->fmt_out.video.i_sar_den, 50000 );
1169
1170         p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
1171         p_sys->video = p_dec->fmt_out.video;
1172
1173         p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
1174                                       &p_dec->fmt_out.video );
1175         if( p_sys->p_vout == NULL )
1176         {
1177             msg_Err( p_dec, "failed to create video output" );
1178             p_dec->b_error = VLC_TRUE;
1179             return NULL;
1180         }
1181
1182         if( p_sys->video.i_rmask )
1183             p_sys->p_vout->render.i_rmask = p_sys->video.i_rmask;
1184         if( p_sys->video.i_gmask )
1185             p_sys->p_vout->render.i_gmask = p_sys->video.i_gmask;
1186         if( p_sys->video.i_bmask )
1187             p_sys->p_vout->render.i_bmask = p_sys->video.i_bmask;
1188     }
1189
1190     /* Get a new picture */
1191     while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
1192     {
1193         int i_pic, i_ready_pic = 0;
1194
1195         if( p_dec->b_die || p_dec->b_error )
1196         {
1197             return NULL;
1198         }
1199
1200 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
1201         /* Check the decoder doesn't leak pictures */
1202         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
1203              i_pic++ )
1204         {
1205             if( p_pic->i_status == READY_PICTURE )
1206             {
1207                 if( i_ready_pic++ > 0 ) break;
1208                 else continue;
1209             }
1210
1211             if( p_pic->i_status != DISPLAYED_PICTURE &&
1212                 p_pic->i_status != RESERVED_PICTURE &&
1213                 p_pic->i_status != READY_PICTURE ) break;
1214
1215             if( !p_pic->i_refcount && p_pic->i_status != RESERVED_PICTURE )
1216                 break;
1217         }
1218         if( i_pic == p_dec->p_owner->p_vout->render.i_pictures )
1219         {
1220             msg_Err( p_dec, "decoder is leaking pictures, resetting the heap" );
1221
1222             /* Just free all the pictures */
1223             for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
1224                  i_pic++ )
1225             {
1226                 if( p_pic->i_status == RESERVED_PICTURE )
1227                     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
1228                 if( p_pic->i_refcount > 0 )
1229                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
1230             }
1231         }
1232 #undef p_pic
1233
1234         msleep( VOUT_OUTMEM_SLEEP );
1235     }
1236
1237     return p_pic;
1238 }
1239
1240 static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
1241 {
1242     VoutDisplayedPicture( p_dec->p_owner->p_vout, p_pic );
1243 }
1244
1245 static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic )
1246 {
1247     vout_LinkPicture( p_dec->p_owner->p_vout, p_pic );
1248 }
1249
1250 static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
1251 {
1252     vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
1253 }
1254
1255 static subpicture_t *spu_new_buffer( decoder_t *p_dec )
1256 {
1257     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1258     vout_thread_t *p_vout = NULL;
1259     subpicture_t *p_subpic;
1260     int i_attempts = 30;
1261
1262     while( i_attempts-- )
1263     {
1264         if( p_dec->b_die || p_dec->b_error ) break;
1265
1266         p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1267         if( p_vout ) break;
1268
1269         msleep( VOUT_DISPLAY_DELAY );
1270     }
1271
1272     if( !p_vout )
1273     {
1274         msg_Warn( p_dec, "no vout found, dropping subpicture" );
1275         return NULL;
1276     }
1277
1278     if( p_sys->p_spu_vout != p_vout )
1279     {
1280         spu_Control( p_vout->p_spu, SPU_CHANNEL_REGISTER,
1281                      &p_sys->i_spu_channel );
1282         p_sys->p_spu_vout = p_vout;
1283     }
1284
1285     p_subpic = spu_CreateSubpicture( p_vout->p_spu );
1286     if( p_subpic )
1287     {
1288         p_subpic->i_channel = p_sys->i_spu_channel;
1289     }
1290
1291     vlc_object_release( p_vout );
1292
1293     return p_subpic;
1294 }
1295
1296 static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
1297 {
1298     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
1299     vout_thread_t *p_vout = NULL;
1300
1301     p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );
1302     if( !p_vout || p_sys->p_spu_vout != p_vout )
1303     {
1304         if( p_vout )
1305             vlc_object_release( p_vout );
1306         msg_Warn( p_dec, "no vout found, leaking subpicture" );
1307         return;
1308     }
1309
1310     spu_DestroySubpicture( p_vout->p_spu, p_subpic );
1311
1312     vlc_object_release( p_vout );
1313 }
1314