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