]> git.sesse.net Git - vlc/blob - src/input/input_dec.c
* src/input/demux.c, src/misc/objects.c: demux2 has the VLC_OBJECT_DEMUX type.
[vlc] / src / input / input_dec.c
1 /*****************************************************************************
2  * input_dec.c: Functions for the management of decoders
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VideoLAN
5  * $Id$
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>
29 #include <string.h>                                    /* memcpy(), memset() */
30
31 #include <vlc/vlc.h>
32 #include <vlc/decoder.h>
33 #include <vlc/vout.h>
34
35 #include "stream_output.h"
36
37 #include "input_ext-intf.h"
38 #include "input_ext-plugins.h"
39
40 #include "codecs.h"
41
42 static void input_NullPacket( input_thread_t *, es_descriptor_t * );
43
44 static decoder_t * CreateDecoder( input_thread_t *, es_descriptor_t *, int );
45 static int         DecoderThread( decoder_t * );
46 static int         DecoderDecode( decoder_t * p_dec, block_t *p_block );
47 static void        DeleteDecoder( decoder_t * );
48
49 /* Buffers allocation callbacks for the decoders */
50 static aout_buffer_t *aout_new_buffer( decoder_t *, int );
51 static void aout_del_buffer( decoder_t *, aout_buffer_t * );
52
53 static picture_t *vout_new_buffer( decoder_t * );
54 static void vout_del_buffer( decoder_t *, picture_t * );
55 static void vout_link_picture( decoder_t *, picture_t * );
56 static void vout_unlink_picture( decoder_t *, picture_t * );
57
58 static es_format_t null_es_format = {0};
59
60 struct decoder_owner_sys_t
61 {
62     vlc_bool_t      b_own_thread;
63
64     input_thread_t  *p_input;
65
66     aout_instance_t *p_aout;
67     aout_input_t    *p_aout_input;
68
69     vout_thread_t   *p_vout;
70
71     sout_instance_t         *p_sout;
72     sout_packetizer_input_t *p_sout_input;
73
74     /* Some decoders require already packetized data (ie. not truncated) */
75     decoder_t *p_packetizer;
76
77     /* Current format in use by the output */
78     video_format_t video;
79     audio_format_t audio;
80     es_format_t    sout;
81
82     /* fifo */
83     block_fifo_t *p_fifo;
84
85     /* */
86     input_buffers_t *p_method_data;
87     es_descriptor_t *p_es_descriptor;
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_RunDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
99 {
100     decoder_t   *p_dec = NULL;
101     vlc_value_t val;
102
103     /* If we are in sout mode, search for packetizer module */
104     if( !p_es->b_force_decoder && p_input->stream.p_sout )
105     {
106         /* Create the decoder configuration structure */
107         p_dec = CreateDecoder( p_input, p_es, VLC_OBJECT_PACKETIZER );
108         if( p_dec == NULL )
109         {
110             msg_Err( p_input, "could not create packetizer" );
111             return NULL;
112         }
113     }
114     else
115     {
116         /* Create the decoder configuration structure */
117         p_dec = CreateDecoder( p_input, p_es, VLC_OBJECT_DECODER );
118         if( p_dec == NULL )
119         {
120             msg_Err( p_input, "could not create decoder" );
121             return NULL;
122         }
123     }
124
125     if( !p_dec->p_module )
126     {
127         msg_Err( p_dec, "no suitable decoder module for fourcc `%4.4s'.\n"
128                  "VLC probably does not support this sound or video format.",
129                  (char*)&p_dec->fmt_in.i_codec );
130
131         DeleteDecoder( p_dec );
132         vlc_object_destroy( p_dec );
133         return NULL;
134     }
135
136     if( !p_es->b_force_decoder && p_input->stream.p_sout && p_input->stream.b_pace_control )
137     {
138         msg_Dbg( p_input, "stream out mode -> no decoder thread" );
139         p_dec->p_owner->b_own_thread = VLC_FALSE;
140     }
141     else
142     {
143         var_Get( p_input, "minimize-threads", &val );
144         p_dec->p_owner->b_own_thread = !val.b_bool;
145     }
146
147     if( p_dec->p_owner->b_own_thread )
148     {
149         int i_priority;
150         if ( p_es->i_cat == AUDIO_ES )
151         {
152             i_priority = VLC_THREAD_PRIORITY_AUDIO;
153         }
154         else
155         {
156             i_priority = VLC_THREAD_PRIORITY_VIDEO;
157         }
158
159         /* Spawn the decoder thread */
160         if( vlc_thread_create( p_dec, "decoder", DecoderThread,
161                                i_priority, VLC_FALSE ) )
162         {
163             msg_Err( p_dec, "cannot spawn decoder thread \"%s\"",
164                              p_dec->p_module->psz_object_name );
165             module_Unneed( p_dec, p_dec->p_module );
166             DeleteDecoder( p_dec );
167             vlc_object_destroy( p_dec );
168             return NULL;
169         }
170     }
171
172     /* Select a new ES */
173     INSERT_ELEM( p_input->stream.pp_selected_es,
174                  p_input->stream.i_selected_es_number,
175                  p_input->stream.i_selected_es_number,
176                  p_es );
177
178     p_input->stream.b_changed = 1;
179
180     return p_dec;
181 }
182
183 /**
184  * Kills a decoder thread and waits until it's finished
185  *
186  * \param p_input the input thread
187  * \param p_es the es descriptor
188  * \return nothing
189  */
190 void input_EndDecoder( input_thread_t * p_input, es_descriptor_t * p_es )
191 {
192     decoder_t *p_dec = p_es->p_dec;
193
194     p_dec->b_die = VLC_TRUE;
195
196     if( p_dec->p_owner->b_own_thread )
197     {
198         /* Make sure the thread leaves the function by
199          * sending it an empty block. */
200         block_t *p_block = block_New( p_dec, 0 );
201         input_DecodeBlock( p_dec, p_block );
202
203         vlc_thread_join( p_dec );
204
205         /* Don't module_Unneed() here because of the dll loader that wants
206          * close() in the same thread than open()/decode() */
207     }
208     else
209     {
210         module_Unneed( p_dec, p_dec->p_module );
211     }
212
213     /* Delete decoder configuration */
214     DeleteDecoder( p_dec );
215
216     /* Delete the decoder */
217     vlc_object_destroy( p_dec );
218
219     /* Tell the input there is no more decoder */
220     p_es->p_dec = NULL;
221
222     p_input->stream.b_changed = 1;
223 }
224
225 /**
226  * Put a PES in the decoder's fifo.
227  *
228  * \param p_dec the decoder object
229  * \param p_pes the pes packet
230  * \return nothing
231  */
232 void input_DecodePES( decoder_t * p_dec, pes_packet_t * p_pes )
233 {
234     data_packet_t *p_data;
235     int     i_size = 0;
236
237     for( p_data = p_pes->p_first; p_data != NULL; p_data = p_data->p_next )
238     {
239         i_size += p_data->p_payload_end - p_data->p_payload_start;
240     }
241     if( i_size > 0 )
242     {
243         block_t *p_block = block_New( p_dec, i_size );
244         if( p_block )
245         {
246             uint8_t *p_buffer = p_block->p_buffer;
247
248             for( p_data = p_pes->p_first; p_data; p_data = p_data->p_next )
249             {
250                 int i_copy = p_data->p_payload_end - p_data->p_payload_start;
251
252                 memcpy( p_buffer, p_data->p_payload_start, i_copy );
253
254                 p_buffer += i_copy;
255             }
256             p_block->i_pts = p_pes->i_pts;
257             p_block->i_dts = p_pes->i_dts;
258             if( p_pes->b_discontinuity )
259                 p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
260             p_block->i_rate = p_pes->i_rate;
261
262             input_DecodeBlock( p_dec, p_block );
263         }
264     }
265
266     input_DeletePES( p_dec->p_owner->p_method_data, p_pes );
267 }
268
269 /**
270  * Put a block_t in the decoder's fifo.
271  *
272  * \param p_dec the decoder object
273  * \param p_block the data block
274  */
275 void input_DecodeBlock( decoder_t * p_dec, block_t *p_block )
276 {
277     if( p_dec->p_owner->b_own_thread )
278     {
279         block_FifoPut( p_dec->p_owner->p_fifo, p_block );
280
281         if( p_dec->p_owner->p_input->b_out_pace_control )
282         {
283             /* FIXME !!!!! */
284             while( !p_dec->b_die && !p_dec->b_error &&
285                    p_dec->p_owner->p_fifo->i_depth > 10 )
286             {
287                 msleep( 1000 );
288             }
289         }
290     }
291     else
292     {
293         if( p_dec->b_error || p_block->i_buffer <= 0 )
294         {
295             block_Release( p_block );
296         }
297         else
298         {
299             DecoderDecode( p_dec, p_block );
300         }
301     }
302 }
303
304 /**
305  * Create a NULL packet for padding in case of a data loss
306  *
307  * \param p_input the input thread
308  * \param p_es es descriptor
309  * \return nothing
310  */
311 static void input_NullPacket( input_thread_t * p_input,
312                               es_descriptor_t * p_es )
313 {
314     block_t *p_block = block_New( p_input, PADDING_PACKET_SIZE );
315     if( p_block )
316     {
317         memset( p_block->p_buffer, 0, PADDING_PACKET_SIZE );
318         p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
319
320         block_FifoPut( p_es->p_dec->p_owner->p_fifo, p_block );
321     }
322 }
323
324 /**
325  * Send a NULL packet to the decoders
326  *
327  * \param p_input the input thread
328  * \return nothing
329  */
330 void input_EscapeDiscontinuity( input_thread_t * p_input )
331 {
332     unsigned int i_es, i;
333
334     for( i_es = 0; i_es < p_input->stream.i_selected_es_number; i_es++ )
335     {
336         es_descriptor_t * p_es = p_input->stream.pp_selected_es[i_es];
337
338         if( p_es->p_dec != NULL )
339         {
340             for( i = 0; i < PADDING_PACKET_NUMBER; i++ )
341             {
342                 input_NullPacket( p_input, p_es );
343             }
344         }
345     }
346 }
347
348 /**
349  * Send a NULL packet to the audio decoders
350  *
351  * \param p_input the input thread
352  * \return nothing
353  */
354 void input_EscapeAudioDiscontinuity( input_thread_t * p_input )
355 {
356     unsigned int i_es, i;
357
358     for( i_es = 0; i_es < p_input->stream.i_selected_es_number; i_es++ )
359     {
360         es_descriptor_t * p_es = p_input->stream.pp_selected_es[i_es];
361
362         if( p_es->p_dec != NULL && p_es->i_cat == AUDIO_ES )
363         {
364             for( i = 0; i < PADDING_PACKET_NUMBER; i++ )
365             {
366                 input_NullPacket( p_input, p_es );
367             }
368         }
369     }
370 }
371
372 /**
373  * Create a decoder object
374  *
375  * \param p_input the input thread
376  * \param p_es the es descriptor
377  * \param i_object_type Object type as define in include/vlc_objects.h
378  * \return the decoder object
379  */
380 static decoder_t * CreateDecoder( input_thread_t * p_input,
381                                   es_descriptor_t * p_es, int i_object_type )
382 {
383     decoder_t *p_dec;
384
385     p_dec = vlc_object_create( p_input, i_object_type );
386     if( p_dec == NULL )
387     {
388         msg_Err( p_input, "out of memory" );
389         return NULL;
390     }
391
392     p_dec->pf_decode_audio = 0;
393     p_dec->pf_decode_video = 0;
394     p_dec->pf_decode_sub = 0;
395     p_dec->pf_packetize = 0;
396
397     /* Initialize the decoder fifo */
398     p_dec->p_module = NULL;
399
400     es_format_Copy( &p_dec->fmt_in, &p_es->fmt );
401
402     if( p_es->p_waveformatex )
403     {
404 #define p_wf ((WAVEFORMATEX *)p_es->p_waveformatex)
405         p_dec->fmt_in.audio.i_channels = p_wf->nChannels;
406         p_dec->fmt_in.audio.i_rate = p_wf->nSamplesPerSec;
407         p_dec->fmt_in.i_bitrate = p_wf->nAvgBytesPerSec * 8;
408         p_dec->fmt_in.audio.i_blockalign = p_wf->nBlockAlign;
409         p_dec->fmt_in.audio.i_bitspersample = p_wf->wBitsPerSample;
410         p_dec->fmt_in.i_extra = p_wf->cbSize;
411         p_dec->fmt_in.p_extra = NULL;
412         if( p_wf->cbSize )
413         {
414             p_dec->fmt_in.p_extra = malloc( p_wf->cbSize );
415             memcpy( p_dec->fmt_in.p_extra, &p_wf[1], p_wf->cbSize );
416         }
417     }
418
419     if( p_es->p_bitmapinfoheader )
420     {
421 #define p_bih ((BITMAPINFOHEADER *) p_es->p_bitmapinfoheader)
422         p_dec->fmt_in.i_extra = p_bih->biSize - sizeof(BITMAPINFOHEADER);
423         p_dec->fmt_in.p_extra = NULL;
424         if( p_dec->fmt_in.i_extra )
425         {
426             p_dec->fmt_in.p_extra = malloc( p_dec->fmt_in.i_extra );
427             memcpy( p_dec->fmt_in.p_extra, &p_bih[1], p_dec->fmt_in.i_extra );
428         }
429
430         p_dec->fmt_in.video.i_width = p_bih->biWidth;
431         p_dec->fmt_in.video.i_height = p_bih->biHeight;
432     }
433
434     /* FIXME
435      *  - 1: beurk
436      *  - 2: I'm not sure there isn't any endian problem here (spu)... */
437     if( p_es->i_cat == SPU_ES && p_es->p_demux_data )
438     {
439         if( ( p_es->i_fourcc == VLC_FOURCC( 's', 'p', 'u', ' ' ) ||
440               p_es->i_fourcc == VLC_FOURCC( 's', 'p', 'u', 'b' ) ) &&
441             *((uint32_t*)p_es->p_demux_data) == 0xBeef )
442         {
443             memcpy( p_dec->fmt_in.subs.spu.palette,
444                     p_es->p_demux_data, 17 * 4 );
445         }
446         else if( p_es->i_fourcc == VLC_FOURCC( 'd', 'v', 'b', 's' ) )
447         {
448             dvb_spuinfo_t *p_dvbs = (dvb_spuinfo_t*)p_es->p_demux_data;
449
450             p_dec->fmt_in.subs.dvb.i_id = p_dvbs->i_id;
451         }
452     }
453
454     p_dec->fmt_in.i_cat = p_es->i_cat;
455     p_dec->fmt_in.i_codec = p_es->i_fourcc;
456
457     p_dec->fmt_out = null_es_format;
458
459     /* Allocate our private structure for the decoder */
460     p_dec->p_owner = (decoder_owner_sys_t*)malloc(sizeof(decoder_owner_sys_t));
461     if( p_dec->p_owner == NULL )
462     {
463         msg_Err( p_dec, "out of memory" );
464         return NULL;
465     }
466     p_dec->p_owner->b_own_thread = VLC_TRUE;
467     p_dec->p_owner->p_input = p_input;
468     p_dec->p_owner->p_aout = NULL;
469     p_dec->p_owner->p_aout_input = NULL;
470     p_dec->p_owner->p_vout = NULL;
471     p_dec->p_owner->p_sout = p_input->stream.p_sout;
472     p_dec->p_owner->p_sout_input = NULL;
473     p_dec->p_owner->p_packetizer = NULL;
474     p_dec->p_owner->p_es_descriptor = p_es;
475
476
477     /* decoder fifo */
478     if( ( p_dec->p_owner->p_fifo = block_FifoNew( p_dec ) ) == NULL )
479     {
480         msg_Err( p_dec, "out of memory" );
481         return NULL;
482     }
483     p_dec->p_owner->p_method_data = p_input->p_method_data;
484
485     /* Set buffers allocation callbacks for the decoders */
486     p_dec->pf_aout_buffer_new = aout_new_buffer;
487     p_dec->pf_aout_buffer_del = aout_del_buffer;
488     p_dec->pf_vout_buffer_new = vout_new_buffer;
489     p_dec->pf_vout_buffer_del = vout_del_buffer;
490     p_dec->pf_picture_link    = vout_link_picture;
491     p_dec->pf_picture_unlink  = vout_unlink_picture;
492
493     vlc_object_attach( p_dec, p_input );
494
495     /* Find a suitable decoder/packetizer module */
496     if( i_object_type == VLC_OBJECT_DECODER )
497         p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );
498     else
499         p_dec->p_module = module_Need( p_dec, "packetizer", "$packetizer", 0 );
500
501     /* Check if decoder requires already packetized data */
502     if( i_object_type == VLC_OBJECT_DECODER &&
503         p_dec->b_need_packetized && !p_dec->fmt_in.b_packetized )
504     {
505         p_dec->p_owner->p_packetizer =
506             vlc_object_create( p_input, VLC_OBJECT_PACKETIZER );
507         if( p_dec->p_owner->p_packetizer )
508         {
509             p_dec->p_owner->p_packetizer->fmt_in = null_es_format;
510             p_dec->p_owner->p_packetizer->fmt_out = null_es_format;
511             es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_in,
512                             &p_dec->fmt_in );
513
514             vlc_object_attach( p_dec->p_owner->p_packetizer, p_input );
515
516             p_dec->p_owner->p_packetizer->p_module =
517                 module_Need( p_dec->p_owner->p_packetizer,
518                              "packetizer", "$packetizer", 0 );
519
520             if( !p_dec->p_owner->p_packetizer->p_module )
521             {
522                 es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
523                 vlc_object_detach( p_dec->p_owner->p_packetizer );
524                 vlc_object_destroy( p_dec->p_owner->p_packetizer );
525             }
526         }
527     }
528
529     return p_dec;
530 }
531
532 /**
533  * The decoding main loop
534  *
535  * \param p_dec the decoder
536  * \return 0
537  */
538 static int DecoderThread( decoder_t * p_dec )
539 {
540     block_t *p_block;
541
542     /* The decoder's main loop */
543     while( !p_dec->b_die && !p_dec->b_error )
544     {
545         if( ( p_block = block_FifoGet( p_dec->p_owner->p_fifo ) ) == NULL )
546         {
547             p_dec->b_error = 1;
548             break;
549         }
550         if( DecoderDecode( p_dec, p_block ) != VLC_SUCCESS )
551         {
552             break;
553         }
554     }
555
556     while( !p_dec->b_die )
557     {
558         /* Trash all received PES packets */
559         p_block = block_FifoGet( p_dec->p_owner->p_fifo );
560         if( p_block ) block_Release( p_block );
561     }
562
563     /* We do it here because of the dll loader that wants close() in the
564      * same thread than open()/decode() */
565     module_Unneed( p_dec, p_dec->p_module );
566
567     return 0;
568 }
569
570 /**
571  * Decode a block
572  *
573  * \param p_dec the decoder object
574  * \param p_block the block to decode
575  * \return VLC_SUCCESS or an error code
576  */
577 static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
578 {
579     if( p_block->i_buffer <= 0 )
580     {
581         block_Release( p_block );
582         return VLC_SUCCESS;
583     }
584
585     if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )
586     {
587         block_t *p_sout_block;
588
589         while( (p_sout_block = p_dec->pf_packetize( p_dec, &p_block )) )
590         {
591             if( !p_dec->p_owner->p_sout_input )
592             {
593                 es_format_Copy( &p_dec->p_owner->sout, &p_dec->fmt_out );
594                 if( p_dec->p_owner->p_es_descriptor->p_pgrm )
595                 {
596                     p_dec->p_owner->sout.i_group =
597                         p_dec->p_owner->p_es_descriptor->p_pgrm->i_number;
598                 }
599                 p_dec->p_owner->sout.i_id =
600                     p_dec->p_owner->p_es_descriptor->i_id - 1;
601                 if( p_dec->fmt_in.psz_language )
602                 {
603                     p_dec->p_owner->sout.psz_language =
604                         strdup( p_dec->fmt_in.psz_language );
605                 }
606
607                 p_dec->p_owner->p_sout_input =
608                     sout_InputNew( p_dec->p_owner->p_sout,
609                                    &p_dec->p_owner->sout );
610
611                 if( p_dec->p_owner->p_sout_input == NULL )
612                 {
613                     msg_Err( p_dec, "cannot create packetizer output" );
614                     p_dec->b_error = VLC_TRUE;
615
616                     while( p_sout_block )
617                     {
618                         block_t *p_next = p_sout_block->p_next;
619                         block_Release( p_sout_block );
620                         p_sout_block = p_next;
621                     }
622                     break;
623                 }
624             }
625
626             while( p_sout_block )
627             {
628                 block_t       *p_next = p_sout_block->p_next;
629
630                 p_sout_block->p_next = NULL;
631
632                 sout_InputSendBuffer( p_dec->p_owner->p_sout_input,
633                                       p_sout_block );
634
635                 p_sout_block = p_next;
636             }
637
638             /* For now it's enough, as only sout inpact on this flag */
639             if( p_dec->p_owner->p_sout->i_out_pace_nocontrol > 0 &&
640                 p_dec->p_owner->p_input->b_out_pace_control )
641             {
642                 msg_Dbg( p_dec, "switching to synch mode" );
643                 p_dec->p_owner->p_input->b_out_pace_control = VLC_FALSE;
644             }
645             else if( p_dec->p_owner->p_sout->i_out_pace_nocontrol <= 0 &&
646                      !p_dec->p_owner->p_input->b_out_pace_control )
647             {
648                 msg_Dbg( p_dec, "switching to asynch mode" );
649                 p_dec->p_owner->p_input->b_out_pace_control = VLC_TRUE;
650             }
651         }
652     }
653     else if( p_dec->fmt_in.i_cat == AUDIO_ES )
654     {
655         aout_buffer_t *p_aout_buf;
656
657         if( p_dec->p_owner->p_packetizer )
658         {
659             block_t *p_packetized_block;
660             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
661
662             while( (p_packetized_block =
663                     p_packetizer->pf_packetize( p_packetizer, &p_block )) )
664             {
665                 while( (p_aout_buf =
666                         p_dec->pf_decode_audio( p_dec, &p_packetized_block )) )
667                 {
668                     aout_DecPlay( p_dec->p_owner->p_aout,
669                                   p_dec->p_owner->p_aout_input, p_aout_buf );
670                 }
671             }
672         }
673         else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
674         {
675             aout_DecPlay( p_dec->p_owner->p_aout,
676                           p_dec->p_owner->p_aout_input, p_aout_buf );
677         }
678     }
679     else if( p_dec->fmt_in.i_cat == VIDEO_ES )
680     {
681         picture_t *p_pic;
682
683         if( p_dec->p_owner->p_packetizer )
684         {
685             block_t *p_packetized_block;
686             decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;
687
688             while( (p_packetized_block =
689                     p_packetizer->pf_packetize( p_packetizer, &p_block )) )
690             {
691                 while( (p_pic =
692                         p_dec->pf_decode_video( p_dec, &p_packetized_block )) )
693                 {
694                     vout_DatePicture( p_dec->p_owner->p_vout, p_pic,
695                                       p_pic->date );
696                     vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
697                 }
698             }
699         }
700         else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
701         {
702             vout_DatePicture( p_dec->p_owner->p_vout, p_pic, p_pic->date );
703             vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );
704         }
705     }
706     else if( p_dec->fmt_in.i_cat == SPU_ES )
707     {
708         p_dec->pf_decode_sub( p_dec, &p_block );
709     }
710     else
711     {
712         msg_Err( p_dec, "unknown ES format" );
713         p_dec->b_error = 1;
714     }
715
716     return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS;
717 }
718
719 /**
720  * Destroys a decoder object
721  *
722  * \param p_dec the decoder object
723  * \return nothing
724  */
725 static void DeleteDecoder( decoder_t * p_dec )
726 {
727     vlc_object_detach( p_dec );
728
729     msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %d PES in FIFO",
730              (char*)&p_dec->fmt_in.i_codec,
731              p_dec->p_owner->p_fifo->i_depth );
732
733     /* Free all packets still in the decoder fifo. */
734     block_FifoEmpty( p_dec->p_owner->p_fifo );
735     block_FifoRelease( p_dec->p_owner->p_fifo );
736
737    /* Cleanup */
738     if( p_dec->p_owner->p_aout_input )
739         aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );
740
741     if( p_dec->p_owner->p_vout )
742     {
743         int i_pic;
744
745 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
746         /* Hack to make sure all the the pictures are freed by the decoder */
747         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
748              i_pic++ )
749         {
750             if( p_pic->i_status == RESERVED_PICTURE )
751                 vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
752             if( p_pic->i_refcount > 0 )
753                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
754         }
755 #undef p_pic
756
757         /* We are about to die. Reattach video output to p_vlc. */
758         vout_Request( p_dec, p_dec->p_owner->p_vout, 0, 0, 0, 0 );
759     }
760
761     if( p_dec->p_owner->p_sout_input )
762     {
763         sout_InputDelete( p_dec->p_owner->p_sout_input );
764         es_format_Clean( &p_dec->p_owner->sout );
765     }
766
767     es_format_Clean( &p_dec->fmt_in );
768     es_format_Clean( &p_dec->fmt_out );
769
770     if( p_dec->p_owner->p_packetizer )
771     {
772         module_Unneed( p_dec->p_owner->p_packetizer,
773                        p_dec->p_owner->p_packetizer->p_module );
774         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );
775         es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_out );
776         vlc_object_detach( p_dec->p_owner->p_packetizer );
777         vlc_object_destroy( p_dec->p_owner->p_packetizer );
778     }
779
780     free( p_dec->p_owner );
781 }
782
783 /*****************************************************************************
784  * Buffers allocation callbacks for the decoders
785  *****************************************************************************/
786 static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples )
787 {
788     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
789     aout_buffer_t *p_buffer;
790
791     if( p_sys->p_aout_input != NULL &&
792         ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||
793           p_dec->fmt_out.audio.i_original_channels !=
794               p_sys->audio.i_original_channels ||
795           p_dec->fmt_out.audio.i_bytes_per_frame !=
796               p_sys->audio.i_bytes_per_frame ) )
797     {
798         /* Parameters changed, restart the aout */
799         aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
800         p_sys->p_aout_input = NULL;
801     }
802
803     if( p_sys->p_aout_input == NULL )
804     {
805         p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
806         p_sys->audio = p_dec->fmt_out.audio;
807         p_sys->p_aout_input =
808             aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->audio );
809         if( p_sys->p_aout_input == NULL )
810         {
811             msg_Err( p_dec, "failed to create audio output" );
812             p_dec->b_error = VLC_TRUE;
813             return NULL;
814         }
815         p_dec->fmt_out.audio.i_bytes_per_frame =
816             p_sys->audio.i_bytes_per_frame;
817     }
818
819     p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
820                                   i_samples );
821
822     return p_buffer;
823 }
824
825 static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer )
826 {
827     aout_DecDeleteBuffer( p_dec->p_owner->p_aout,
828                           p_dec->p_owner->p_aout_input, p_buffer );
829 }
830
831 static picture_t *vout_new_buffer( decoder_t *p_dec )
832 {
833     decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
834     picture_t *p_pic;
835
836     if( p_sys->p_vout == NULL ||
837         p_dec->fmt_out.video.i_width != p_sys->video.i_width ||
838         p_dec->fmt_out.video.i_height != p_sys->video.i_height ||
839         p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||
840         p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )
841     {
842         if( !p_dec->fmt_out.video.i_width ||
843             !p_dec->fmt_out.video.i_height )
844         {
845             /* Can't create a new vout without display size */
846             return NULL;
847         }
848
849         p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
850         p_sys->video = p_dec->fmt_out.video;
851
852         p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,
853                                       p_sys->video.i_width,
854                                       p_sys->video.i_height,
855                                       p_sys->video.i_chroma,
856                                       p_sys->video.i_aspect );
857
858         if( p_sys->p_vout == NULL )
859         {
860             msg_Err( p_dec, "failed to create video output" );
861             p_dec->b_error = VLC_TRUE;
862             return NULL;
863         }
864     }
865
866     /* Get a new picture */
867     while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )
868     {
869         int i_pic, i_ready_pic = 0;
870
871         if( p_dec->b_die || p_dec->b_error )
872         {
873             return NULL;
874         }
875
876 #define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]
877         /* Check the decoder doesn't leak pictures */
878         for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
879              i_pic++ )
880         {
881             if( p_pic->i_status == READY_PICTURE && i_ready_pic++ > 0 ) break;
882
883             if( p_pic->i_status != DISPLAYED_PICTURE &&
884                 p_pic->i_status != RESERVED_PICTURE &&
885                 p_pic->i_status != READY_PICTURE ) break;
886
887             if( !p_pic->i_refcount ) break;
888         }
889         if( i_pic == p_dec->p_owner->p_vout->render.i_pictures )
890         {
891             msg_Err( p_dec, "decoder is leaking pictures, resetting the heap" );
892
893             /* Just free all the pictures */
894             for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;
895                  i_pic++ )
896             {
897                 if( p_pic->i_status == RESERVED_PICTURE )
898                     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
899                 if( p_pic->i_refcount > 0 )
900                 vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
901             }
902         }
903 #undef p_pic
904
905         msleep( VOUT_OUTMEM_SLEEP );
906     }
907
908     return p_pic;
909 }
910
911 static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
912 {
913     vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );
914 }
915
916 static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic )
917 {
918     vout_LinkPicture( p_dec->p_owner->p_vout, p_pic );
919 }
920
921 static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
922 {
923     vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
924 }