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