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