1ac909a08304c28bf427e6bd89ce86f036438409
[vlc.git] / src / input / decoder.c
1 /*****************************************************************************
2  * decoder.c: Functions for the management of decoders
3  *****************************************************************************
4  * Copyright (C) 1999-2019 VLC authors, VideoLAN and Videolabs SAS
5  *
6  * Authors: Christophe Massiot <massiot@via.ecp.fr>
7  *          Gildas Bazin <gbazin@videolan.org>
8  *          Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31 #include <assert.h>
32 #include <stdatomic.h>
33
34 #include <vlc_common.h>
35 #include <vlc_block.h>
36 #include <vlc_vout.h>
37 #include <vlc_aout.h>
38 #include <vlc_sout.h>
39 #include <vlc_codec.h>
40 #include <vlc_spu.h>
41 #include <vlc_meta.h>
42 #include <vlc_dialog.h>
43 #include <vlc_modules.h>
44 #include <vlc_decoder.h>
45 #include <vlc_picture_pool.h>
46
47 #include "audio_output/aout_internal.h"
48 #include "stream_output/stream_output.h"
49 #include "../clock/clock.h"
50 #include "decoder.h"
51 #include "resource.h"
52 #include "libvlc.h"
53
54 #include "../video_output/vout_internal.h"
55
56 /*
57  * Possibles values set in p_owner->reload atomic
58  */
59 enum reload
60 {
61     RELOAD_NO_REQUEST,
62     RELOAD_DECODER,     /* Reload the decoder module */
63     RELOAD_DECODER_AOUT /* Stop the aout and reload the decoder module */
64 };
65
66 struct vlc_input_decoder_t
67 {
68     decoder_t        dec;
69     input_resource_t*p_resource;
70     vlc_clock_t     *p_clock;
71
72     const struct vlc_input_decoder_callbacks *cbs;
73     void *cbs_userdata;
74
75     ssize_t          i_spu_channel;
76     int64_t          i_spu_order;
77
78     sout_instance_t         *p_sout;
79     sout_packetizer_input_t *p_sout_input;
80
81     vlc_thread_t     thread;
82
83     /* Some decoders require already packetized data (ie. not truncated) */
84     decoder_t *p_packetizer;
85     bool b_packetizer;
86
87     /* Current format in use by the output */
88     es_format_t    fmt;
89     vlc_video_context *vctx;
90
91     /* */
92     atomic_bool    b_fmt_description;
93     vlc_meta_t     *p_description;
94     atomic_int     reload;
95
96     /* fifo */
97     block_fifo_t *p_fifo;
98
99     /* Lock for communication with decoder thread */
100     vlc_mutex_t lock;
101     vlc_cond_t  wait_request;
102     vlc_cond_t  wait_acknowledge;
103     vlc_cond_t  wait_fifo; /* TODO: merge with wait_acknowledge */
104
105     /* pool to use when the decoder doesn't use its own */
106     struct picture_pool_t *out_pool;
107
108     /*
109      * 3 threads can read/write these output variables, the DecoderThread, the
110      * input thread, and the ModuleThread. The ModuleThread is either the
111      * DecoderThread for synchronous modules or any thread for asynchronous
112      * modules.
113      *
114      * Asynchronous modules are responsible for serializing/locking every
115      * output calls in any thread as long as the decoder_UpdateVideoFormat() or
116      * decoder_NewPicture() calls are not concurrent, cf.
117      * decoder_UpdateVideoFormat() and decoder_NewPicture() notes.
118      *
119      * The ModuleThread is the owner of these variables, it should hold
120      * the lock when writing them but doesn't have to hold it when using them.
121      *
122      * The DecoderThread should always hold the lock when reading/using
123      * aout/vouts.
124      *
125      * The input thread can read these variables in order to stop outputs, when
126      * both ModuleThread and DecoderThread are stopped (from DecoderDelete()).
127      */
128     audio_output_t *p_aout;
129
130     vout_thread_t   *p_vout;
131     bool             vout_started;
132     enum vlc_vout_order vout_order;
133
134     /* -- Theses variables need locking on read *and* write -- */
135     /* Preroll */
136     vlc_tick_t i_preroll_end;
137
138 #define PREROLL_NONE    INT64_MIN // vlc_tick_t
139 #define PREROLL_FORCED  INT64_MAX // vlc_tick_t
140
141     /* Pause & Rate */
142     bool reset_out_state;
143     vlc_tick_t pause_date;
144     vlc_tick_t delay;
145     float request_rate, output_rate;
146     unsigned frames_countdown;
147     bool paused;
148
149     bool error;
150
151     /* Waiting */
152     bool b_waiting;
153     bool b_first;
154     bool b_has_data;
155
156     /* Flushing */
157     bool flushing;
158     bool b_draining;
159     atomic_bool drained;
160     bool b_idle;
161     bool aborting;
162
163     /* CC */
164 #define MAX_CC_DECODERS 64 /* The es_out only creates one type of es */
165     struct
166     {
167         bool b_supported;
168         decoder_cc_desc_t desc;
169         vlc_input_decoder_t *pp_decoder[MAX_CC_DECODERS];
170         bool b_sout_created;
171         sout_packetizer_input_t *p_sout_input;
172     } cc;
173
174     /* Mouse event */
175     vlc_mutex_t     mouse_lock;
176     vlc_mouse_event mouse_event;
177     void           *mouse_opaque;
178 };
179
180 /* Pictures which are DECODER_BOGUS_VIDEO_DELAY or more in advance probably have
181  * a bogus PTS and won't be displayed */
182 #define DECODER_BOGUS_VIDEO_DELAY                ((vlc_tick_t)(DEFAULT_PTS_DELAY * 30))
183
184 /* */
185 #define DECODER_SPU_VOUT_WAIT_DURATION   VLC_TICK_FROM_MS(200)
186 #define BLOCK_FLAG_CORE_PRIVATE_RELOADED (1 << BLOCK_FLAG_CORE_PRIVATE_SHIFT)
187
188 #define decoder_Notify(decoder_priv, event, ...) \
189     if (decoder_priv->cbs && decoder_priv->cbs->event) \
190         decoder_priv->cbs->event(decoder_priv, __VA_ARGS__, \
191                                  decoder_priv->cbs_userdata);
192
193 static inline vlc_input_decoder_t *dec_get_owner( decoder_t *p_dec )
194 {
195     return container_of( p_dec, vlc_input_decoder_t, dec );
196 }
197
198 /**
199  * Load a decoder module
200  */
201 static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
202                         const es_format_t *restrict p_fmt )
203 {
204     decoder_Init( p_dec, p_fmt );
205
206     p_dec->b_frame_drop_allowed = true;
207
208     /* Find a suitable decoder/packetizer module */
209     if( !b_packetizer )
210     {
211         static const char caps[ES_CATEGORY_COUNT][16] = {
212             [VIDEO_ES] = "video decoder",
213             [AUDIO_ES] = "audio decoder",
214             [SPU_ES] = "spu decoder",
215         };
216         p_dec->p_module = module_need_var( p_dec, caps[p_dec->fmt_in.i_cat],
217                                            "codec" );
218     }
219     else
220         p_dec->p_module = module_need_var( p_dec, "packetizer", "packetizer" );
221
222     if( !p_dec->p_module )
223     {
224         decoder_Clean( p_dec );
225         return -1;
226     }
227     return 0;
228 }
229
230 static int DecoderThread_Reload( vlc_input_decoder_t *p_owner,
231                                  const es_format_t *restrict p_fmt,
232                                  enum reload reload )
233 {
234     /* Copy p_fmt since it can be destroyed by decoder_Clean */
235     decoder_t *p_dec = &p_owner->dec;
236     es_format_t fmt_in;
237     if( es_format_Copy( &fmt_in, p_fmt ) != VLC_SUCCESS )
238     {
239         p_owner->error = true;
240         return VLC_EGENERIC;
241     }
242
243     /* Restart the decoder module */
244     decoder_Clean( p_dec );
245     p_owner->error = false;
246
247     if( reload == RELOAD_DECODER_AOUT )
248     {
249         assert( p_owner->fmt.i_cat == AUDIO_ES );
250         audio_output_t *p_aout = p_owner->p_aout;
251         // no need to lock, the decoder and ModuleThread are dead
252         p_owner->p_aout = NULL;
253         if( p_aout )
254         {
255             aout_DecDelete( p_aout );
256             input_resource_PutAout( p_owner->p_resource, p_aout );
257         }
258     }
259
260     if( LoadDecoder( p_dec, false, &fmt_in ) )
261     {
262         p_owner->error = true;
263         es_format_Clean( &fmt_in );
264         return VLC_EGENERIC;
265     }
266     es_format_Clean( &fmt_in );
267     return VLC_SUCCESS;
268 }
269
270 static void DecoderUpdateFormatLocked( vlc_input_decoder_t *p_owner )
271 {
272     decoder_t *p_dec = &p_owner->dec;
273
274     vlc_mutex_assert( &p_owner->lock );
275
276     es_format_Clean( &p_owner->fmt );
277     es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
278
279     assert( p_owner->fmt.i_cat == p_dec->fmt_in.i_cat );
280
281     /* Move p_description */
282     if( p_dec->p_description != NULL )
283     {
284         if( p_owner->p_description != NULL )
285             vlc_meta_Delete( p_owner->p_description );
286         p_owner->p_description = p_dec->p_description;
287         p_dec->p_description = NULL;
288     }
289
290     atomic_store_explicit( &p_owner->b_fmt_description, true,
291                            memory_order_release );
292 }
293
294 static void MouseEvent( const vlc_mouse_t *newmouse, void *user_data )
295 {
296     decoder_t *dec = user_data;
297     vlc_input_decoder_t *owner = dec_get_owner( dec );
298
299     vlc_mutex_lock( &owner->mouse_lock );
300     if( owner->mouse_event )
301         owner->mouse_event( newmouse, owner->mouse_opaque);
302     vlc_mutex_unlock( &owner->mouse_lock );
303 }
304
305 /*****************************************************************************
306  * Buffers allocation callbacks for the decoders
307  *****************************************************************************/
308 static bool aout_replaygain_changed( const audio_replay_gain_t *a,
309                                      const audio_replay_gain_t *b )
310 {
311     for( size_t i=0; i<AUDIO_REPLAY_GAIN_MAX; i++ )
312     {
313         if( a->pb_gain[i] != b->pb_gain[i] ||
314             a->pb_peak[i] != b->pb_peak[i] ||
315             (a->pb_gain[i] && a->pf_gain[i] != b->pf_gain[i]) ||
316             (a->pb_peak[i] && a->pf_peak[i] != b->pf_peak[i]) )
317             return true;
318     }
319     return false;
320 }
321
322 static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
323 {
324     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
325
326     if( p_owner->p_aout &&
327        ( !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) ||
328          p_dec->fmt_out.i_codec != p_dec->fmt_out.audio.i_format ||
329          p_dec->fmt_out.i_profile != p_owner->fmt.i_profile ) )
330     {
331         audio_output_t *p_aout = p_owner->p_aout;
332
333         /* Parameters changed, restart the aout */
334         vlc_mutex_lock( &p_owner->lock );
335         p_owner->p_aout = NULL; // the DecoderThread should not use the old aout anymore
336         vlc_mutex_unlock( &p_owner->lock );
337         aout_DecDelete( p_aout );
338
339         input_resource_PutAout( p_owner->p_resource, p_aout );
340     }
341
342     /* Check if only replay gain has changed */
343     if( aout_replaygain_changed( &p_dec->fmt_in.audio_replay_gain,
344                                  &p_owner->fmt.audio_replay_gain ) )
345     {
346         p_dec->fmt_out.audio_replay_gain = p_dec->fmt_in.audio_replay_gain;
347         if( p_owner->p_aout )
348         {
349             p_owner->fmt.audio_replay_gain = p_dec->fmt_in.audio_replay_gain;
350             var_TriggerCallback( p_owner->p_aout, "audio-replay-gain-mode" );
351         }
352     }
353
354     if( p_owner->p_aout == NULL )
355     {
356         p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
357
358         audio_sample_format_t format = p_dec->fmt_out.audio;
359         aout_FormatPrepare( &format );
360
361         const int i_force_dolby = var_InheritInteger( p_dec, "force-dolby-surround" );
362         if( i_force_dolby &&
363             format.i_physical_channels == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
364         {
365             if( i_force_dolby == 1 )
366                 format.i_chan_mode |= AOUT_CHANMODE_DOLBYSTEREO;
367             else /* i_force_dolby == 2 */
368                 format.i_chan_mode &= ~AOUT_CHANMODE_DOLBYSTEREO;
369         }
370
371         audio_output_t *p_aout;
372
373         p_aout = input_resource_GetAout( p_owner->p_resource );
374         if( p_aout )
375         {
376             if( aout_DecNew( p_aout, &format, p_dec->fmt_out.i_profile,
377                              p_owner->p_clock,
378                              &p_dec->fmt_out.audio_replay_gain ) )
379             {
380                 input_resource_PutAout( p_owner->p_resource, p_aout );
381                 p_aout = NULL;
382             }
383         }
384
385         vlc_mutex_lock( &p_owner->lock );
386         p_owner->p_aout = p_aout;
387
388         DecoderUpdateFormatLocked( p_owner );
389         aout_FormatPrepare( &p_owner->fmt.audio );
390         vlc_mutex_unlock( &p_owner->lock );
391
392         if( p_aout == NULL )
393             return -1;
394
395         p_dec->fmt_out.audio.i_bytes_per_frame =
396             p_owner->fmt.audio.i_bytes_per_frame;
397         p_dec->fmt_out.audio.i_frame_length =
398             p_owner->fmt.audio.i_frame_length;
399
400         vlc_fifo_Lock( p_owner->p_fifo );
401         p_owner->reset_out_state = true;
402         vlc_fifo_Unlock( p_owner->p_fifo );
403     }
404     return 0;
405 }
406
407 static int CreateVoutIfNeeded(vlc_input_decoder_t *);
408
409
410 static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *vctx )
411 {
412     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
413
414     int created_vout = CreateVoutIfNeeded(p_owner);
415     if (created_vout == -1)
416         return -1; // error
417     if (created_vout == 0)
418     {
419         // video context didn't change
420         if (vctx != NULL && p_owner->vctx == vctx)
421             return 0;
422     }
423     assert(p_owner->p_vout);
424
425     if (p_owner->vctx)
426         vlc_video_context_Release(p_owner->vctx);
427     p_owner->vctx = vctx ? vlc_video_context_Hold(vctx) : NULL;
428
429     // configure the new vout
430
431     if ( p_owner->out_pool == NULL )
432     {
433         unsigned dpb_size;
434         switch( p_dec->fmt_in.i_codec )
435         {
436         case VLC_CODEC_HEVC:
437         case VLC_CODEC_H264:
438         case VLC_CODEC_DIRAC: /* FIXME valid ? */
439             dpb_size = 18;
440             break;
441         case VLC_CODEC_AV1:
442             dpb_size = 10;
443             break;
444         case VLC_CODEC_MP4V:
445         case VLC_CODEC_VP5:
446         case VLC_CODEC_VP6:
447         case VLC_CODEC_VP6F:
448         case VLC_CODEC_VP8:
449             dpb_size = 3;
450             break;
451         default:
452             dpb_size = 2;
453             break;
454         }
455         picture_pool_t *pool = picture_pool_NewFromFormat( &p_dec->fmt_out.video,
456                             dpb_size + p_dec->i_extra_picture_buffers + 1 );
457
458         if( pool == NULL)
459         {
460             msg_Err(p_dec, "Failed to create a pool of %d %4.4s pictures",
461                            dpb_size + p_dec->i_extra_picture_buffers + 1,
462                            (char*)&p_dec->fmt_out.video.i_chroma);
463             goto error;
464         }
465
466         vlc_mutex_lock( &p_owner->lock );
467         p_owner->out_pool = pool;
468         vlc_mutex_unlock( &p_owner->lock );
469
470     }
471
472     vout_configuration_t cfg = {
473         .vout = p_owner->p_vout, .clock = p_owner->p_clock, .fmt = &p_dec->fmt_out.video,
474         .mouse_event = MouseEvent, .mouse_opaque = p_dec,
475     };
476     bool has_started;
477     vout_thread_t *p_vout =
478         input_resource_RequestVout(p_owner->p_resource, vctx, &cfg, NULL,
479                                    &has_started);
480     if (p_vout != NULL)
481     {
482         vlc_mutex_lock( &p_owner->lock );
483         p_owner->vout_started = true;
484         vlc_mutex_unlock( &p_owner->lock );
485
486         if (has_started)
487         {
488             vlc_fifo_Lock( p_owner->p_fifo );
489             p_owner->reset_out_state = true;
490             vlc_fifo_Unlock( p_owner->p_fifo );
491
492             decoder_Notify(p_owner, on_vout_started, p_vout, p_owner->vout_order);
493         }
494         return 0;
495     }
496
497 error:
498     /* Clean fmt and vctx to trigger a new vout creation on the next update
499      * call */
500     vlc_mutex_lock( &p_owner->lock );
501     es_format_Clean( &p_owner->fmt );
502     vlc_mutex_unlock( &p_owner->lock );
503
504     if (p_owner->vctx != NULL)
505     {
506         vlc_video_context_Release(p_owner->vctx);
507         p_owner->vctx = NULL;
508     }
509     return -1;
510 }
511
512 static int CreateVoutIfNeeded(vlc_input_decoder_t *p_owner)
513 {
514     decoder_t *p_dec = &p_owner->dec;
515     bool need_vout = false;
516
517     if( p_owner->p_vout == NULL )
518     {
519         msg_Dbg(p_dec, "vout: none found");
520         need_vout = true;
521     }
522     if( p_dec->fmt_out.video.i_width != p_owner->fmt.video.i_width
523              || p_dec->fmt_out.video.i_height != p_owner->fmt.video.i_height )
524     {
525         msg_Dbg(p_dec, "vout change: decoder size");
526         need_vout = true;
527     }
528     if( p_dec->fmt_out.video.i_visible_width != p_owner->fmt.video.i_visible_width
529              || p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
530              || p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
531              || p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset )
532     {
533         msg_Dbg(p_dec, "vout change: visible size");
534         need_vout = true;
535     }
536     if( p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma )
537     {
538         msg_Dbg(p_dec, "vout change: chroma");
539         need_vout = true;
540     }
541     if( (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
542              (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num )
543     {
544         msg_Dbg(p_dec, "vout change: SAR");
545         need_vout = true;
546     }
547     if( p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation )
548     {
549         msg_Dbg(p_dec, "vout change: orientation");
550         need_vout = true;
551     }
552     if( p_dec->fmt_out.video.multiview_mode != p_owner->fmt.video.multiview_mode )
553     {
554         msg_Dbg(p_dec, "vout change: multiview");
555         need_vout = true;
556     }
557
558     if( !need_vout )
559         return 0; // vout unchanged
560
561     vlc_mutex_lock( &p_owner->lock );
562
563     vout_thread_t *p_vout = p_owner->p_vout;
564     p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
565     p_owner->vout_started = false;
566     vlc_mutex_unlock( &p_owner->lock );
567
568     enum vlc_vout_order order;
569     const vout_configuration_t cfg = { .vout = p_vout, .fmt = NULL };
570     p_vout = input_resource_RequestVout( p_owner->p_resource, NULL, &cfg, &order, NULL );
571
572     vlc_mutex_lock( &p_owner->lock );
573     p_owner->p_vout = p_vout;
574     p_owner->vout_order = order;
575
576     DecoderUpdateFormatLocked( p_owner );
577     p_owner->fmt.video.i_chroma = p_dec->fmt_out.i_codec;
578     picture_pool_t *pool = p_owner->out_pool;
579     p_owner->out_pool = NULL;
580     vlc_mutex_unlock( &p_owner->lock );
581
582      if ( pool != NULL )
583          picture_pool_Release( pool );
584
585     if( p_vout == NULL )
586     {
587         msg_Err( p_dec, "failed to create video output" );
588         return -1;
589     }
590
591     return 1; // new vout was created
592 }
593
594 static vlc_decoder_device * ModuleThread_GetDecoderDevice( decoder_t *p_dec )
595 {
596     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
597
598     /* Requesting a decoder device will automatically enable hw decoding */
599     if( !var_InheritBool( p_dec, "hw-dec" ) )
600         return NULL;
601
602     int created_vout = CreateVoutIfNeeded(p_owner);
603     if (created_vout == -1)
604         return NULL;  // error
605
606     assert(p_owner->p_vout);
607     vlc_decoder_device *dec_device = vout_GetDevice(p_owner->p_vout);
608     if (created_vout == 1)
609         return dec_device; // new vout was created with a decoder device
610
611     bool need_format_update = false;
612     if ( memcmp( &p_dec->fmt_out.video.mastering,
613                  &p_owner->fmt.video.mastering,
614                  sizeof(p_owner->fmt.video.mastering)) )
615     {
616         msg_Dbg(p_dec, "vout update: mastering data");
617         need_format_update = true;
618     }
619     if ( p_dec->fmt_out.video.lighting.MaxCLL !=
620          p_owner->fmt.video.lighting.MaxCLL ||
621          p_dec->fmt_out.video.lighting.MaxFALL !=
622          p_owner->fmt.video.lighting.MaxFALL )
623     {
624         msg_Dbg(p_dec, "vout update: lighting data");
625         need_format_update = true;
626     }
627
628     if ( need_format_update )
629     {
630         /* the format has changed but we don't need a new vout */
631         vlc_mutex_lock( &p_owner->lock );
632         DecoderUpdateFormatLocked( p_owner );
633         vlc_mutex_unlock( &p_owner->lock );
634     }
635     return dec_device;
636 }
637
638 static picture_t *ModuleThread_NewVideoBuffer( decoder_t *p_dec )
639 {
640     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
641     assert( p_owner->p_vout );
642     assert( p_owner->out_pool );
643
644     picture_t *pic = picture_pool_Wait( p_owner->out_pool );
645     if (pic)
646         picture_Reset( pic );
647     return pic;
648 }
649
650 static subpicture_t *ModuleThread_NewSpuBuffer( decoder_t *p_dec,
651                                      const subpicture_updater_t *p_updater )
652 {
653     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
654     vout_thread_t *p_vout = NULL;
655     subpicture_t *p_subpic;
656     int i_attempts = 30;
657
658     while( i_attempts-- )
659     {
660         if( p_owner->error )
661             break;
662
663         p_vout = input_resource_HoldVout( p_owner->p_resource );
664         if( p_vout )
665             break;
666
667         vlc_tick_sleep( DECODER_SPU_VOUT_WAIT_DURATION );
668     }
669
670     if( !p_vout )
671     {
672         msg_Warn( p_dec, "no vout found, dropping subpicture" );
673         if( p_owner->p_vout )
674         {
675             assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
676             decoder_Notify(p_owner, on_vout_stopped, p_owner->p_vout);
677
678             vlc_mutex_lock( &p_owner->lock );
679             vout_UnregisterSubpictureChannel(p_owner->p_vout,
680                                              p_owner->i_spu_channel);
681             p_owner->i_spu_channel = VOUT_SPU_CHANNEL_INVALID;
682
683             vout_Release(p_owner->p_vout);
684             p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
685             vlc_mutex_unlock( &p_owner->lock );
686         }
687         return NULL;
688     }
689
690     if( p_owner->p_vout != p_vout )
691     {
692         if (p_owner->p_vout) /* notify the previous vout deletion unlocked */
693             decoder_Notify(p_owner, on_vout_stopped, p_owner->p_vout);
694
695         vlc_mutex_lock(&p_owner->lock);
696
697         if (p_owner->p_vout)
698         {
699             /* Unregister the SPU channel of the previous vout */
700             assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
701             vout_UnregisterSubpictureChannel(p_owner->p_vout,
702                                              p_owner->i_spu_channel);
703             vout_Release(p_owner->p_vout);
704             p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
705         }
706
707         enum vlc_vout_order channel_order;
708         p_owner->i_spu_channel =
709             vout_RegisterSubpictureChannelInternal(p_vout, p_owner->p_clock,
710                                                    &channel_order);
711         p_owner->i_spu_order = 0;
712
713         if (p_owner->i_spu_channel == VOUT_SPU_CHANNEL_INVALID)
714         {
715             /* The new vout doesn't support SPU, aborting... */
716             vlc_mutex_unlock(&p_owner->lock);
717             vout_Release(p_vout);
718             return NULL;
719         }
720
721         p_owner->p_vout = p_vout;
722         p_owner->vout_order = channel_order;
723         vlc_mutex_unlock(&p_owner->lock);
724
725         assert(channel_order != VLC_VOUT_ORDER_NONE);
726         decoder_Notify(p_owner, on_vout_started, p_vout, channel_order);
727     }
728     else
729         vout_Release(p_vout);
730
731     p_subpic = subpicture_New( p_updater );
732     if( p_subpic )
733     {
734         p_subpic->i_channel = p_owner->i_spu_channel;
735         p_subpic->i_order = p_owner->i_spu_order++;
736         p_subpic->b_subtitle = true;
737     }
738
739     return p_subpic;
740 }
741
742 static int InputThread_GetInputAttachments( decoder_t *p_dec,
743                                        input_attachment_t ***ppp_attachment,
744                                        int *pi_attachment )
745 {
746     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
747     if (!p_owner->cbs || !p_owner->cbs->get_attachments)
748         return VLC_ENOOBJ;
749
750     int ret = p_owner->cbs->get_attachments(p_owner, ppp_attachment,
751                                             p_owner->cbs_userdata);
752     if (ret < 0)
753         return VLC_EGENERIC;
754     *pi_attachment = ret;
755     return VLC_SUCCESS;
756 }
757
758 static vlc_tick_t ModuleThread_GetDisplayDate( decoder_t *p_dec,
759                                        vlc_tick_t system_now, vlc_tick_t i_ts )
760 {
761     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
762
763     vlc_mutex_lock( &p_owner->lock );
764     if( p_owner->b_waiting || p_owner->paused )
765         i_ts = VLC_TICK_INVALID;
766     float rate = p_owner->output_rate;
767     vlc_mutex_unlock( &p_owner->lock );
768
769     if( !p_owner->p_clock || i_ts == VLC_TICK_INVALID )
770         return i_ts;
771
772     return vlc_clock_ConvertToSystem( p_owner->p_clock, system_now, i_ts, rate );
773 }
774
775 static float ModuleThread_GetDisplayRate( decoder_t *p_dec )
776 {
777     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
778
779     if( !p_owner->p_clock )
780         return 1.f;
781     vlc_mutex_lock( &p_owner->lock );
782     float rate = p_owner->output_rate;
783     vlc_mutex_unlock( &p_owner->lock );
784     return rate;
785 }
786
787 /*****************************************************************************
788  * Public functions
789  *****************************************************************************/
790 block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples )
791 {
792     assert( dec->fmt_out.audio.i_frame_length > 0
793          && dec->fmt_out.audio.i_bytes_per_frame  > 0 );
794
795     size_t length = samples * dec->fmt_out.audio.i_bytes_per_frame
796                             / dec->fmt_out.audio.i_frame_length;
797     block_t *block = block_Alloc( length );
798     if( likely(block != NULL) )
799     {
800         block->i_nb_samples = samples;
801         block->i_pts = block->i_length = 0;
802     }
803     return block;
804 }
805
806 static void RequestReload( vlc_input_decoder_t *p_owner )
807 {
808     /* Don't override reload if it's RELOAD_DECODER_AOUT */
809     int expected = RELOAD_NO_REQUEST;
810     atomic_compare_exchange_strong( &p_owner->reload, &expected, RELOAD_DECODER );
811 }
812
813 static void DecoderWaitUnblock( vlc_input_decoder_t *p_owner )
814 {
815     vlc_mutex_assert( &p_owner->lock );
816
817     for( ;; )
818     {
819         if( !p_owner->b_waiting || !p_owner->b_has_data )
820             break;
821         vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
822     }
823 }
824
825 static inline void DecoderUpdatePreroll( vlc_tick_t *pi_preroll, const block_t *p )
826 {
827     if( p->i_flags & BLOCK_FLAG_PREROLL )
828         *pi_preroll = PREROLL_FORCED;
829     /* Check if we can use the packet for end of preroll */
830     else if( (p->i_flags & BLOCK_FLAG_DISCONTINUITY) &&
831              (p->i_buffer == 0 || (p->i_flags & BLOCK_FLAG_CORRUPTED)) )
832         *pi_preroll = PREROLL_FORCED;
833     else if( p->i_dts != VLC_TICK_INVALID )
834         *pi_preroll = __MIN( *pi_preroll, p->i_dts );
835     else if( p->i_pts != VLC_TICK_INVALID )
836         *pi_preroll = __MIN( *pi_preroll, p->i_pts );
837 }
838
839 #ifdef ENABLE_SOUT
840 static int DecoderThread_PlaySout( vlc_input_decoder_t *p_owner, block_t *p_sout_block )
841 {
842     assert( !p_sout_block->p_next );
843
844     vlc_mutex_lock( &p_owner->lock );
845
846     if( p_owner->b_waiting )
847     {
848         p_owner->b_has_data = true;
849         vlc_cond_signal( &p_owner->wait_acknowledge );
850     }
851
852     DecoderWaitUnblock( p_owner );
853
854     vlc_mutex_unlock( &p_owner->lock );
855
856     /* FIXME --VLC_TICK_INVALID inspect stream_output*/
857     return sout_InputSendBuffer( p_owner->p_sout, p_owner->p_sout_input,
858                                  p_sout_block );
859 }
860
861 /* This function process a block for sout
862  */
863 static void DecoderThread_ProcessSout( vlc_input_decoder_t *p_owner, block_t *p_block )
864 {
865     decoder_t *p_dec = &p_owner->dec;
866     block_t *p_sout_block;
867     block_t **pp_block = p_block ? &p_block : NULL;
868
869     while( ( p_sout_block =
870                  p_dec->pf_packetize( p_dec, pp_block ) ) )
871     {
872         if( p_owner->p_sout_input == NULL )
873         {
874             vlc_mutex_lock( &p_owner->lock );
875             DecoderUpdateFormatLocked( p_owner );
876
877             p_owner->fmt.i_group = p_dec->fmt_in.i_group;
878             p_owner->fmt.i_id = p_dec->fmt_in.i_id;
879             if( p_dec->fmt_in.psz_language )
880             {
881                 free( p_owner->fmt.psz_language );
882                 p_owner->fmt.psz_language =
883                     strdup( p_dec->fmt_in.psz_language );
884             }
885             vlc_mutex_unlock( &p_owner->lock );
886
887             p_owner->p_sout_input =
888                 sout_InputNew( p_owner->p_sout, &p_owner->fmt );
889
890             if( p_owner->p_sout_input == NULL )
891             {
892                 msg_Err( p_dec, "cannot create packetized sout output (%4.4s)",
893                          (char *)&p_owner->fmt.i_codec );
894                 p_owner->error = true;
895
896                 if(p_block)
897                     block_Release(p_block);
898
899                 block_ChainRelease(p_sout_block);
900                 break;
901             }
902         }
903
904         while( p_sout_block )
905         {
906             block_t *p_next = p_sout_block->p_next;
907
908             p_sout_block->p_next = NULL;
909
910             if( p_owner->p_sout->b_wants_substreams && p_dec->pf_get_cc )
911             {
912                 if( p_owner->cc.p_sout_input ||
913                     !p_owner->cc.b_sout_created )
914                 {
915                     decoder_cc_desc_t desc;
916                     block_t *p_cc = p_dec->pf_get_cc( p_dec, &desc );
917                     if( p_cc )
918                     {
919                         if(!p_owner->cc.b_sout_created)
920                         {
921                             es_format_t ccfmt;
922                             es_format_Init(&ccfmt, SPU_ES, VLC_CODEC_CEA608);
923                             ccfmt.i_group = p_owner->fmt.i_group;
924                             ccfmt.subs.cc.i_reorder_depth = desc.i_reorder_depth;
925                             p_owner->cc.p_sout_input = sout_InputNew( p_owner->p_sout, &ccfmt );
926                             es_format_Clean(&ccfmt);
927                             p_owner->cc.b_sout_created = true;
928                         }
929
930                         if( !p_owner->cc.p_sout_input ||
931                             sout_InputSendBuffer( p_owner->p_sout, p_owner->cc.p_sout_input, p_cc ) )
932                         {
933                             block_Release( p_cc );
934                         }
935                     }
936                 }
937             }
938
939             if( DecoderThread_PlaySout( p_owner, p_sout_block ) == VLC_EGENERIC )
940             {
941                 msg_Err( p_dec, "cannot continue streaming due to errors with codec %4.4s",
942                                 (char *)&p_owner->fmt.i_codec );
943
944                 p_owner->error = true;
945
946                 /* Cleanup */
947
948                 if( p_block )
949                     block_Release( p_block );
950
951                 block_ChainRelease( p_next );
952                 return;
953             }
954
955             p_sout_block = p_next;
956         }
957     }
958 }
959 #endif
960
961 static void DecoderPlayCc( vlc_input_decoder_t *p_owner, block_t *p_cc,
962                            const decoder_cc_desc_t *p_desc )
963 {
964     vlc_mutex_lock( &p_owner->lock );
965
966     p_owner->cc.desc = *p_desc;
967
968     /* Fanout data to all decoders. We do not know if es_out
969        selected 608 or 708. */
970     uint64_t i_bitmap = p_owner->cc.desc.i_608_channels |
971                         p_owner->cc.desc.i_708_channels;
972
973     for( int i=0; i_bitmap > 0; i_bitmap >>= 1, i++ )
974     {
975         vlc_input_decoder_t *p_ccowner = p_owner->cc.pp_decoder[i];
976         if( !p_ccowner )
977             continue;
978
979         if( i_bitmap > 1 )
980         {
981             block_FifoPut( p_ccowner->p_fifo, block_Duplicate(p_cc) );
982         }
983         else
984         {
985             block_FifoPut( p_ccowner->p_fifo, p_cc );
986             p_cc = NULL; /* was last dec */
987         }
988     }
989
990     vlc_mutex_unlock( &p_owner->lock );
991
992     if( p_cc ) /* can have bitmap set but no created decs */
993         block_Release( p_cc );
994 }
995
996 static void PacketizerGetCc( vlc_input_decoder_t *p_owner, decoder_t *p_dec_cc )
997 {
998     block_t *p_cc;
999     decoder_cc_desc_t desc;
1000
1001     /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
1002     if( !p_owner->cc.b_supported )
1003         return;
1004
1005     assert( p_dec_cc->pf_get_cc != NULL );
1006
1007     p_cc = p_dec_cc->pf_get_cc( p_dec_cc, &desc );
1008     if( !p_cc )
1009         return;
1010     DecoderPlayCc( p_owner, p_cc, &desc );
1011 }
1012
1013 static void ModuleThread_QueueCc( decoder_t *p_videodec, block_t *p_cc,
1014                                   const decoder_cc_desc_t *p_desc )
1015 {
1016     vlc_input_decoder_t *p_owner = dec_get_owner( p_videodec );
1017
1018     if( unlikely( p_cc != NULL ) )
1019     {
1020         if( p_owner->cc.b_supported &&
1021            ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
1022             DecoderPlayCc( p_owner, p_cc, p_desc );
1023         else
1024             block_Release( p_cc );
1025     }
1026 }
1027
1028 static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_picture )
1029 {
1030     decoder_t *p_dec = &p_owner->dec;
1031     vout_thread_t  *p_vout = p_owner->p_vout;
1032
1033     if( p_picture->date == VLC_TICK_INVALID )
1034         /* FIXME: VLC_TICK_INVALID -- verify video_output */
1035     {
1036         msg_Warn( p_dec, "non-dated video buffer received" );
1037         picture_Release( p_picture );
1038         return VLC_EGENERIC;
1039     }
1040
1041     vlc_mutex_lock( &p_owner->lock );
1042     assert( p_owner->vout_started );
1043
1044     bool prerolled = p_owner->i_preroll_end != PREROLL_NONE;
1045     if( prerolled && p_owner->i_preroll_end > p_picture->date )
1046     {
1047         vlc_mutex_unlock( &p_owner->lock );
1048         picture_Release( p_picture );
1049         return VLC_SUCCESS;
1050     }
1051
1052     p_owner->i_preroll_end = PREROLL_NONE;
1053
1054     if( unlikely(prerolled) )
1055     {
1056         msg_Dbg( p_dec, "end of video preroll" );
1057
1058         if( p_vout )
1059             vout_FlushAll( p_vout );
1060     }
1061
1062     if( p_owner->b_waiting && !p_owner->b_first )
1063     {
1064         p_owner->b_has_data = true;
1065         vlc_cond_signal( &p_owner->wait_acknowledge );
1066     }
1067
1068     DecoderWaitUnblock( p_owner );
1069
1070     if( p_owner->b_waiting )
1071     {
1072         assert( p_owner->b_first );
1073         msg_Dbg( p_dec, "Received first picture" );
1074         p_owner->b_first = false;
1075         p_picture->b_force = true;
1076     }
1077
1078     vlc_mutex_unlock( &p_owner->lock );
1079
1080     /* FIXME: The *input* FIFO should not be locked here. This will not work
1081      * properly if/when pictures are queued asynchronously. */
1082     vlc_fifo_Lock( p_owner->p_fifo );
1083     if( unlikely(p_owner->paused) && likely(p_owner->frames_countdown > 0) )
1084         p_owner->frames_countdown--;
1085     vlc_fifo_Unlock( p_owner->p_fifo );
1086
1087     /* */
1088     if( p_vout == NULL )
1089     {
1090         picture_Release( p_picture );
1091         return VLC_EGENERIC;
1092     }
1093
1094     if( p_picture->b_still )
1095     {
1096         /* Ensure no earlier higher pts breaks still state */
1097         vout_Flush( p_vout, p_picture->date );
1098     }
1099     vout_PutPicture( p_vout, p_picture );
1100
1101     return VLC_SUCCESS;
1102 }
1103
1104 static void ModuleThread_UpdateStatVideo( vlc_input_decoder_t *p_owner,
1105                                           bool lost )
1106 {
1107     unsigned displayed = 0;
1108     unsigned vout_lost = 0;
1109     unsigned vout_late = 0;
1110     if( p_owner->p_vout != NULL )
1111     {
1112         vout_GetResetStatistic( p_owner->p_vout, &displayed, &vout_lost, &vout_late );
1113     }
1114     if (lost) vout_lost++;
1115
1116     decoder_Notify(p_owner, on_new_video_stats, 1, vout_lost, displayed, vout_late);
1117 }
1118
1119 static void ModuleThread_QueueVideo( decoder_t *p_dec, picture_t *p_pic )
1120 {
1121     assert( p_pic );
1122     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1123
1124     int success = ModuleThread_PlayVideo( p_owner, p_pic );
1125
1126     ModuleThread_UpdateStatVideo( p_owner, success != VLC_SUCCESS );
1127 }
1128
1129 static vlc_decoder_device * thumbnailer_get_device( decoder_t *p_dec )
1130 {
1131     VLC_UNUSED(p_dec);
1132     // no hardware decoder on purpose
1133     // we don't want to load many DLLs and allocate many pictures
1134     // just to decode one picture
1135     return NULL;
1136 }
1137
1138 static picture_t *thumbnailer_buffer_new( decoder_t *p_dec )
1139 {
1140     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1141     /* Avoid decoding more than one frame when a thumbnail was
1142      * already generated */
1143     vlc_mutex_lock( &p_owner->lock );
1144     if( !p_owner->b_first )
1145     {
1146         vlc_mutex_unlock( &p_owner->lock );
1147         return NULL;
1148     }
1149     vlc_mutex_unlock( &p_owner->lock );
1150     return picture_NewFromFormat( &p_dec->fmt_out.video );
1151 }
1152
1153 static void ModuleThread_QueueThumbnail( decoder_t *p_dec, picture_t *p_pic )
1154 {
1155     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1156     bool b_first;
1157
1158     vlc_mutex_lock( &p_owner->lock );
1159     b_first = p_owner->b_first;
1160     p_owner->b_first = false;
1161     vlc_mutex_unlock( &p_owner->lock );
1162
1163     if( b_first )
1164         decoder_Notify(p_owner, on_thumbnail_ready, p_pic);
1165     picture_Release( p_pic );
1166
1167 }
1168
1169 static int ModuleThread_PlayAudio( vlc_input_decoder_t *p_owner, block_t *p_audio )
1170 {
1171     decoder_t *p_dec = &p_owner->dec;
1172
1173     assert( p_audio != NULL );
1174
1175     if( p_audio->i_pts == VLC_TICK_INVALID ) // FIXME --VLC_TICK_INVALID verify audio_output/*
1176     {
1177         msg_Warn( p_dec, "non-dated audio buffer received" );
1178         block_Release( p_audio );
1179         return VLC_EGENERIC;
1180     }
1181
1182     vlc_mutex_lock( &p_owner->lock );
1183     bool prerolled = p_owner->i_preroll_end != PREROLL_NONE;
1184     if( prerolled && p_owner->i_preroll_end > p_audio->i_pts )
1185     {
1186         vlc_mutex_unlock( &p_owner->lock );
1187         block_Release( p_audio );
1188         return VLC_SUCCESS;
1189     }
1190
1191     p_owner->i_preroll_end = PREROLL_NONE;
1192     vlc_mutex_unlock( &p_owner->lock );
1193
1194     if( unlikely(prerolled) )
1195     {
1196         msg_Dbg( p_dec, "end of audio preroll" );
1197
1198         if( p_owner->p_aout )
1199             aout_DecFlush( p_owner->p_aout );
1200     }
1201
1202     /* */
1203     /* */
1204     vlc_mutex_lock( &p_owner->lock );
1205     if( p_owner->b_waiting )
1206     {
1207         p_owner->b_has_data = true;
1208         vlc_cond_signal( &p_owner->wait_acknowledge );
1209     }
1210
1211     /* */
1212     DecoderWaitUnblock( p_owner );
1213     vlc_mutex_unlock( &p_owner->lock );
1214
1215     audio_output_t *p_aout = p_owner->p_aout;
1216
1217     if( p_aout == NULL )
1218     {
1219         msg_Dbg( p_dec, "discarded audio buffer" );
1220         block_Release( p_audio );
1221         return VLC_EGENERIC;
1222     }
1223
1224     int status = aout_DecPlay( p_aout, p_audio );
1225     if( status == AOUT_DEC_CHANGED )
1226     {
1227         /* Only reload the decoder */
1228         RequestReload( p_owner );
1229     }
1230     else if( status == AOUT_DEC_FAILED )
1231     {
1232         /* If we reload because the aout failed, we should release it. That
1233             * way, a next call to ModuleThread_UpdateAudioFormat() won't re-use the
1234             * previous (failing) aout but will try to create a new one. */
1235         atomic_store( &p_owner->reload, RELOAD_DECODER_AOUT );
1236     }
1237     return VLC_SUCCESS;
1238 }
1239
1240 static void ModuleThread_UpdateStatAudio( vlc_input_decoder_t *p_owner,
1241                                           bool lost )
1242 {
1243     unsigned played = 0;
1244     unsigned aout_lost = 0;
1245     if( p_owner->p_aout != NULL )
1246     {
1247         aout_DecGetResetStats( p_owner->p_aout, &aout_lost, &played );
1248     }
1249     if (lost) aout_lost++;
1250
1251     decoder_Notify(p_owner, on_new_audio_stats, 1, aout_lost, played);
1252 }
1253
1254 static void ModuleThread_QueueAudio( decoder_t *p_dec, block_t *p_aout_buf )
1255 {
1256     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1257
1258     int success = ModuleThread_PlayAudio( p_owner, p_aout_buf );
1259
1260     ModuleThread_UpdateStatAudio( p_owner, success != VLC_SUCCESS );
1261 }
1262
1263 static void ModuleThread_PlaySpu( vlc_input_decoder_t *p_owner, subpicture_t *p_subpic )
1264 {
1265     decoder_t *p_dec = &p_owner->dec;
1266     vout_thread_t *p_vout = p_owner->p_vout;
1267
1268     /* */
1269     if( p_subpic->i_start == VLC_TICK_INVALID )
1270     {
1271         msg_Warn( p_dec, "non-dated spu buffer received" );
1272         subpicture_Delete( p_subpic );
1273         return;
1274     }
1275
1276     /* */
1277     vlc_mutex_lock( &p_owner->lock );
1278
1279     if( p_owner->b_waiting )
1280     {
1281         p_owner->b_has_data = true;
1282         vlc_cond_signal( &p_owner->wait_acknowledge );
1283     }
1284
1285     DecoderWaitUnblock( p_owner );
1286     vlc_mutex_unlock( &p_owner->lock );
1287
1288     if( p_subpic->i_start == VLC_TICK_INVALID )
1289     {
1290         subpicture_Delete( p_subpic );
1291         return;
1292     }
1293
1294     vout_PutSubpicture( p_vout, p_subpic );
1295 }
1296
1297 static void ModuleThread_QueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
1298 {
1299     assert( p_spu );
1300     vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1301
1302     /* The vout must be created from a previous decoder_NewSubpicture call. */
1303     assert( p_owner->p_vout );
1304
1305     /* Preroll does not work very well with subtitle */
1306     vlc_mutex_lock( &p_owner->lock );
1307     if( p_spu->i_start != VLC_TICK_INVALID &&
1308         p_spu->i_start < p_owner->i_preroll_end &&
1309         ( p_spu->i_stop == VLC_TICK_INVALID || p_spu->i_stop < p_owner->i_preroll_end ) )
1310     {
1311         vlc_mutex_unlock( &p_owner->lock );
1312         subpicture_Delete( p_spu );
1313     }
1314     else
1315     {
1316         vlc_mutex_unlock( &p_owner->lock );
1317         ModuleThread_PlaySpu( p_owner, p_spu );
1318     }
1319 }
1320
1321 static void DecoderThread_ProcessInput( vlc_input_decoder_t *p_owner, block_t *p_block );
1322 static void DecoderThread_DecodeBlock( vlc_input_decoder_t *p_owner, block_t *p_block )
1323 {
1324     decoder_t *p_dec = &p_owner->dec;
1325
1326     int ret = p_dec->pf_decode( p_dec, p_block );
1327     switch( ret )
1328     {
1329         case VLCDEC_SUCCESS:
1330             break;
1331         case VLCDEC_ECRITICAL:
1332             p_owner->error = true;
1333             break;
1334         case VLCDEC_RELOAD:
1335             RequestReload( p_owner );
1336             if( unlikely( p_block == NULL ) )
1337                 break;
1338             if( !( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
1339             {
1340                 p_block->i_flags |= BLOCK_FLAG_CORE_PRIVATE_RELOADED;
1341                 DecoderThread_ProcessInput( p_owner, p_block );
1342             }
1343             else /* We prefer loosing this block than an infinite recursion */
1344                 block_Release( p_block );
1345             break;
1346         default:
1347             vlc_assert_unreachable();
1348     }
1349 }
1350
1351 /**
1352  * Decode a block
1353  *
1354  * \param p_dec the decoder object
1355  * \param p_block the block to decode
1356  */
1357 static void DecoderThread_ProcessInput( vlc_input_decoder_t *p_owner, block_t *p_block )
1358 {
1359     decoder_t *p_dec = &p_owner->dec;
1360
1361     if( p_owner->error )
1362         goto error;
1363
1364     /* Here, the atomic doesn't prevent to miss a reload request.
1365      * DecoderThread_ProcessInput() can still be called after the decoder module or the
1366      * audio output requested a reload. This will only result in a drop of an
1367      * input block or an output buffer. */
1368     enum reload reload;
1369     if( ( reload = atomic_exchange( &p_owner->reload, RELOAD_NO_REQUEST ) ) )
1370     {
1371         msg_Warn( p_dec, "Reloading the decoder module%s",
1372                   reload == RELOAD_DECODER_AOUT ? " and the audio output" : "" );
1373
1374         if( DecoderThread_Reload( p_owner, &p_dec->fmt_in, reload ) != VLC_SUCCESS )
1375             goto error;
1376     }
1377
1378     bool packetize = p_owner->p_packetizer != NULL;
1379     if( p_block )
1380     {
1381         if( p_block->i_buffer <= 0 )
1382             goto error;
1383
1384         vlc_mutex_lock( &p_owner->lock );
1385         DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
1386         vlc_mutex_unlock( &p_owner->lock );
1387         if( unlikely( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
1388         {
1389             /* This block has already been packetized */
1390             packetize = false;
1391         }
1392     }
1393
1394 #ifdef ENABLE_SOUT
1395     if( p_owner->p_sout != NULL )
1396     {
1397         DecoderThread_ProcessSout( p_owner, p_block );
1398         return;
1399     }
1400 #endif
1401     if( packetize )
1402     {
1403         block_t *p_packetized_block;
1404         block_t **pp_block = p_block ? &p_block : NULL;
1405         decoder_t *p_packetizer = p_owner->p_packetizer;
1406
1407         while( (p_packetized_block =
1408                 p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
1409         {
1410             if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
1411             {
1412                 msg_Dbg( p_dec, "restarting module due to input format change");
1413
1414                 /* Drain the decoder module */
1415                 DecoderThread_DecodeBlock( p_owner, NULL );
1416
1417                 if( DecoderThread_Reload( p_owner, &p_packetizer->fmt_out,
1418                                           RELOAD_DECODER ) != VLC_SUCCESS )
1419                 {
1420                     block_ChainRelease( p_packetized_block );
1421                     return;
1422                 }
1423             }
1424
1425             if( p_packetizer->pf_get_cc )
1426                 PacketizerGetCc( p_owner, p_packetizer );
1427
1428             while( p_packetized_block )
1429             {
1430                 block_t *p_next = p_packetized_block->p_next;
1431                 p_packetized_block->p_next = NULL;
1432
1433                 DecoderThread_DecodeBlock( p_owner, p_packetized_block );
1434                 if( p_owner->error )
1435                 {
1436                     block_ChainRelease( p_next );
1437                     return;
1438                 }
1439
1440                 p_packetized_block = p_next;
1441             }
1442         }
1443         /* Drain the decoder after the packetizer is drained */
1444         if( !pp_block )
1445             DecoderThread_DecodeBlock( p_owner, NULL );
1446     }
1447     else
1448         DecoderThread_DecodeBlock( p_owner, p_block );
1449     return;
1450
1451 error:
1452     if( p_block )
1453         block_Release( p_block );
1454 }
1455
1456 static void DecoderThread_Flush( vlc_input_decoder_t *p_owner )
1457 {
1458     decoder_t *p_dec = &p_owner->dec;
1459     decoder_t *p_packetizer = p_owner->p_packetizer;
1460
1461     if( p_owner->error )
1462         return;
1463
1464     if( p_packetizer != NULL && p_packetizer->pf_flush != NULL )
1465         p_packetizer->pf_flush( p_packetizer );
1466
1467     if ( p_dec->pf_flush != NULL )
1468         p_dec->pf_flush( p_dec );
1469
1470     /* flush CC sub decoders */
1471     if( p_owner->cc.b_supported )
1472     {
1473         for( int i=0; i<MAX_CC_DECODERS; i++ )
1474         {
1475             vlc_input_decoder_t *p_ccowner = p_owner->cc.pp_decoder[i];
1476             if( p_ccowner && p_ccowner->dec.pf_flush )
1477                 p_ccowner->dec.pf_flush( &p_ccowner->dec );
1478         }
1479     }
1480
1481     vlc_mutex_lock( &p_owner->lock );
1482 #ifdef ENABLE_SOUT
1483     if ( p_owner->p_sout_input != NULL )
1484     {
1485         sout_InputFlush( p_owner->p_sout, p_owner->p_sout_input );
1486     }
1487 #endif
1488     if( p_dec->fmt_out.i_cat == AUDIO_ES )
1489     {
1490         if( p_owner->p_aout )
1491             aout_DecFlush( p_owner->p_aout );
1492     }
1493     else if( p_dec->fmt_out.i_cat == VIDEO_ES )
1494     {
1495         if( p_owner->p_vout && p_owner->vout_started )
1496             vout_FlushAll( p_owner->p_vout );
1497
1498         /* Reset the pool cancel state, previously set by
1499          * vlc_input_decoder_Flush() */
1500         if( p_owner->out_pool != NULL )
1501             picture_pool_Cancel( p_owner->out_pool, false );
1502     }
1503     else if( p_dec->fmt_out.i_cat == SPU_ES )
1504     {
1505         if( p_owner->p_vout )
1506         {
1507             assert( p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID );
1508             vout_FlushSubpictureChannel( p_owner->p_vout, p_owner->i_spu_channel );
1509         }
1510     }
1511
1512     p_owner->i_preroll_end = PREROLL_NONE;
1513     vlc_mutex_unlock( &p_owner->lock );
1514 }
1515
1516 static void DecoderThread_ChangePause( vlc_input_decoder_t *p_owner, bool paused, vlc_tick_t date )
1517 {
1518     decoder_t *p_dec = &p_owner->dec;
1519
1520     msg_Dbg( p_dec, "toggling %s", paused ? "resume" : "pause" );
1521     switch( p_dec->fmt_out.i_cat )
1522     {
1523         case VIDEO_ES:
1524             vlc_mutex_lock( &p_owner->lock );
1525             if( p_owner->p_vout != NULL && p_owner->vout_started )
1526                 vout_ChangePause( p_owner->p_vout, paused, date );
1527             vlc_mutex_unlock( &p_owner->lock );
1528             break;
1529         case AUDIO_ES:
1530             vlc_mutex_lock( &p_owner->lock );
1531             if( p_owner->p_aout != NULL )
1532                 aout_DecChangePause( p_owner->p_aout, paused, date );
1533             vlc_mutex_unlock( &p_owner->lock );
1534             break;
1535         case SPU_ES:
1536             break;
1537         default:
1538             vlc_assert_unreachable();
1539     }
1540 }
1541
1542 static void DecoderThread_ChangeRate( vlc_input_decoder_t *p_owner, float rate )
1543 {
1544     decoder_t *p_dec = &p_owner->dec;
1545
1546     msg_Dbg( p_dec, "changing rate: %f", rate );
1547     vlc_mutex_lock( &p_owner->lock );
1548     switch( p_dec->fmt_out.i_cat )
1549     {
1550         case VIDEO_ES:
1551             if( p_owner->p_vout != NULL && p_owner->vout_started )
1552                 vout_ChangeRate( p_owner->p_vout, rate );
1553             break;
1554         case AUDIO_ES:
1555             if( p_owner->p_aout != NULL )
1556                 aout_DecChangeRate( p_owner->p_aout, rate );
1557             break;
1558         case SPU_ES:
1559             if( p_owner->p_vout != NULL )
1560             {
1561                 assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
1562                 vout_ChangeSpuRate(p_owner->p_vout, p_owner->i_spu_channel,
1563                                    rate );
1564             }
1565             break;
1566         default:
1567             vlc_assert_unreachable();
1568     }
1569     p_owner->output_rate = rate;
1570     vlc_mutex_unlock( &p_owner->lock );
1571 }
1572
1573 static void DecoderThread_ChangeDelay( vlc_input_decoder_t *p_owner, vlc_tick_t delay )
1574 {
1575     decoder_t *p_dec = &p_owner->dec;
1576
1577     msg_Dbg( p_dec, "changing delay: %"PRId64, delay );
1578
1579     switch( p_dec->fmt_out.i_cat )
1580     {
1581         case VIDEO_ES:
1582             vlc_mutex_lock( &p_owner->lock );
1583             if( p_owner->p_vout != NULL && p_owner->vout_started )
1584                 vout_ChangeDelay( p_owner->p_vout, delay );
1585             vlc_mutex_unlock( &p_owner->lock );
1586             break;
1587         case AUDIO_ES:
1588             vlc_mutex_lock( &p_owner->lock );
1589             if( p_owner->p_aout != NULL )
1590                 aout_DecChangeDelay( p_owner->p_aout, delay );
1591             vlc_mutex_unlock( &p_owner->lock );
1592             break;
1593         case SPU_ES:
1594             vlc_mutex_lock( &p_owner->lock );
1595             if( p_owner->p_vout != NULL )
1596             {
1597                 assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
1598                 vout_ChangeSpuDelay(p_owner->p_vout, p_owner->i_spu_channel,
1599                                     delay);
1600             }
1601             vlc_mutex_unlock( &p_owner->lock );
1602             break;
1603         default:
1604             vlc_assert_unreachable();
1605     }
1606 }
1607
1608 /**
1609  * The decoding main loop
1610  *
1611  * \param p_dec the decoder
1612  */
1613 static void *DecoderThread( void *p_data )
1614 {
1615     vlc_input_decoder_t *p_owner = (vlc_input_decoder_t *)p_data;
1616     float rate = 1.f;
1617     vlc_tick_t delay = 0;
1618     bool paused = false;
1619
1620     /* The decoder's main loop */
1621     vlc_fifo_Lock( p_owner->p_fifo );
1622
1623     while( !p_owner->aborting )
1624     {
1625         if( p_owner->flushing )
1626         {   /* Flush before/regardless of pause. We do not want to resume just
1627              * for the sake of flushing (glitches could otherwise happen). */
1628             vlc_fifo_Unlock( p_owner->p_fifo );
1629
1630             /* Flush the decoder (and the output) */
1631             DecoderThread_Flush( p_owner );
1632
1633             vlc_fifo_Lock( p_owner->p_fifo );
1634
1635             /* Reset flushing after DecoderThread_ProcessInput in case vlc_input_decoder_Flush
1636              * is called again. This will avoid a second useless flush (but
1637              * harmless). */
1638             p_owner->flushing = false;
1639
1640             continue;
1641         }
1642
1643         /* Reset the original pause/rate state when a new aout/vout is created:
1644          * this will trigger the DecoderThread_ChangePause/DecoderThread_ChangeRate code path
1645          * if needed. */
1646         if( p_owner->reset_out_state )
1647         {
1648             rate = 1.f;
1649             paused = false;
1650             delay = 0;
1651             p_owner->reset_out_state = false;
1652         }
1653
1654         if( paused != p_owner->paused )
1655         {   /* Update playing/paused status of the output */
1656             vlc_tick_t date = p_owner->pause_date;
1657
1658             paused = p_owner->paused;
1659             vlc_fifo_Unlock( p_owner->p_fifo );
1660
1661             DecoderThread_ChangePause( p_owner, paused, date );
1662
1663             vlc_fifo_Lock( p_owner->p_fifo );
1664             continue;
1665         }
1666
1667         if( rate != p_owner->request_rate )
1668         {
1669             rate = p_owner->request_rate;
1670             vlc_fifo_Unlock( p_owner->p_fifo );
1671
1672             DecoderThread_ChangeRate( p_owner, rate );
1673
1674             vlc_fifo_Lock( p_owner->p_fifo );
1675             continue;
1676         }
1677
1678         if( delay != p_owner->delay )
1679         {
1680             delay = p_owner->delay;
1681             vlc_fifo_Unlock( p_owner->p_fifo );
1682
1683             DecoderThread_ChangeDelay( p_owner, delay );
1684
1685             vlc_fifo_Lock( p_owner->p_fifo );
1686             continue;
1687         }
1688
1689         if( p_owner->paused && p_owner->frames_countdown == 0 )
1690         {   /* Wait for resumption from pause */
1691             p_owner->b_idle = true;
1692             vlc_cond_signal( &p_owner->wait_acknowledge );
1693             vlc_fifo_Wait( p_owner->p_fifo );
1694             p_owner->b_idle = false;
1695             continue;
1696         }
1697
1698         vlc_cond_signal( &p_owner->wait_fifo );
1699
1700         block_t *p_block = vlc_fifo_DequeueUnlocked( p_owner->p_fifo );
1701         if( p_block == NULL )
1702         {
1703             if( likely(!p_owner->b_draining) )
1704             {   /* Wait for a block to decode (or a request to drain) */
1705                 p_owner->b_idle = true;
1706                 vlc_cond_signal( &p_owner->wait_acknowledge );
1707                 vlc_fifo_Wait( p_owner->p_fifo );
1708                 p_owner->b_idle = false;
1709                 continue;
1710             }
1711             /* We have emptied the FIFO and there is a pending request to
1712              * drain. Pass p_block = NULL to decoder just once. */
1713         }
1714
1715         vlc_fifo_Unlock( p_owner->p_fifo );
1716
1717         DecoderThread_ProcessInput( p_owner, p_block );
1718
1719         if( p_block == NULL && p_owner->dec.fmt_out.i_cat == AUDIO_ES )
1720         {   /* Draining: the decoder is drained and all decoded buffers are
1721              * queued to the output at this point. Now drain the output. */
1722             if( p_owner->p_aout != NULL )
1723                 aout_DecDrain( p_owner->p_aout );
1724         }
1725
1726         /* TODO? Wait for draining instead of polling. */
1727         vlc_mutex_lock( &p_owner->lock );
1728         vlc_fifo_Lock( p_owner->p_fifo );
1729         if( p_owner->b_draining && (p_block == NULL) )
1730         {
1731             p_owner->b_draining = false;
1732             p_owner->drained = true;
1733         }
1734         vlc_cond_signal( &p_owner->wait_acknowledge );
1735         vlc_mutex_unlock( &p_owner->lock );
1736     }
1737
1738     vlc_fifo_Unlock( p_owner->p_fifo );
1739     return NULL;
1740 }
1741
1742 static const struct decoder_owner_callbacks dec_video_cbs =
1743 {
1744     .video = {
1745         .get_device = ModuleThread_GetDecoderDevice,
1746         .format_update = ModuleThread_UpdateVideoFormat,
1747         .buffer_new = ModuleThread_NewVideoBuffer,
1748         .queue = ModuleThread_QueueVideo,
1749         .queue_cc = ModuleThread_QueueCc,
1750         .get_display_date = ModuleThread_GetDisplayDate,
1751         .get_display_rate = ModuleThread_GetDisplayRate,
1752     },
1753     .get_attachments = InputThread_GetInputAttachments,
1754 };
1755 static const struct decoder_owner_callbacks dec_thumbnailer_cbs =
1756 {
1757     .video = {
1758         .get_device = thumbnailer_get_device,
1759         .buffer_new = thumbnailer_buffer_new,
1760         .queue = ModuleThread_QueueThumbnail,
1761     },
1762     .get_attachments = InputThread_GetInputAttachments,
1763 };
1764 static const struct decoder_owner_callbacks dec_audio_cbs =
1765 {
1766     .audio = {
1767         .format_update = ModuleThread_UpdateAudioFormat,
1768         .queue = ModuleThread_QueueAudio,
1769     },
1770     .get_attachments = InputThread_GetInputAttachments,
1771 };
1772 static const struct decoder_owner_callbacks dec_spu_cbs =
1773 {
1774     .spu = {
1775         .buffer_new = ModuleThread_NewSpuBuffer,
1776         .queue = ModuleThread_QueueSpu,
1777     },
1778     .get_attachments = InputThread_GetInputAttachments,
1779 };
1780
1781 /**
1782  * Create a decoder object
1783  *
1784  * \param p_input the input thread
1785  * \param p_es the es descriptor
1786  * \param b_packetizer instead of a decoder
1787  * \return the decoder object
1788  */
1789 static vlc_input_decoder_t *
1790 CreateDecoder( vlc_object_t *p_parent,
1791                const es_format_t *fmt, vlc_clock_t *p_clock,
1792                input_resource_t *p_resource, sout_instance_t *p_sout,
1793                bool b_thumbnailing, const struct vlc_input_decoder_callbacks *cbs,
1794                void *cbs_userdata )
1795 {
1796     decoder_t *p_dec;
1797     vlc_input_decoder_t *p_owner;
1798     static_assert(offsetof(vlc_input_decoder_t, dec) == 0,
1799                   "the decoder must be first in the owner structure");
1800
1801     p_owner = vlc_custom_create( p_parent, sizeof( *p_owner ), "decoder" );
1802     if( p_owner == NULL )
1803         return NULL;
1804     p_dec = &p_owner->dec;
1805
1806     p_owner->p_clock = p_clock;
1807     p_owner->i_preroll_end = PREROLL_NONE;
1808     p_owner->p_resource = p_resource;
1809     p_owner->cbs = cbs;
1810     p_owner->cbs_userdata = cbs_userdata;
1811     p_owner->p_aout = NULL;
1812     p_owner->p_vout = NULL;
1813     p_owner->vout_started = false;
1814     p_owner->i_spu_channel = VOUT_SPU_CHANNEL_INVALID;
1815     p_owner->i_spu_order = 0;
1816     p_owner->p_sout = p_sout;
1817     p_owner->p_sout_input = NULL;
1818     p_owner->p_packetizer = NULL;
1819
1820     atomic_init( &p_owner->b_fmt_description, false );
1821     p_owner->p_description = NULL;
1822
1823     p_owner->reset_out_state = false;
1824     p_owner->delay = 0;
1825     p_owner->output_rate = p_owner->request_rate = 1.f;
1826     p_owner->paused = false;
1827     p_owner->pause_date = VLC_TICK_INVALID;
1828     p_owner->frames_countdown = 0;
1829
1830     p_owner->b_waiting = false;
1831     p_owner->b_first = true;
1832     p_owner->b_has_data = false;
1833
1834     p_owner->error = false;
1835
1836     p_owner->flushing = false;
1837     p_owner->b_draining = false;
1838     p_owner->drained = false;
1839     atomic_init( &p_owner->reload, RELOAD_NO_REQUEST );
1840     p_owner->b_idle = false;
1841
1842     p_owner->mouse_event = NULL;
1843     p_owner->mouse_opaque = NULL;
1844
1845     es_format_Init( &p_owner->fmt, fmt->i_cat, 0 );
1846
1847     /* decoder fifo */
1848     p_owner->p_fifo = block_FifoNew();
1849     if( unlikely(p_owner->p_fifo == NULL) )
1850     {
1851         vlc_object_delete(p_dec);
1852         return NULL;
1853     }
1854
1855     vlc_mutex_init( &p_owner->lock );
1856     vlc_mutex_init( &p_owner->mouse_lock );
1857     vlc_cond_init( &p_owner->wait_request );
1858     vlc_cond_init( &p_owner->wait_acknowledge );
1859     vlc_cond_init( &p_owner->wait_fifo );
1860
1861     /* Load a packetizer module if the input is not already packetized */
1862     if( p_sout == NULL && !fmt->b_packetized )
1863     {
1864         p_owner->p_packetizer =
1865             vlc_custom_create( p_parent, sizeof( decoder_t ), "packetizer" );
1866         if( p_owner->p_packetizer )
1867         {
1868             if( LoadDecoder( p_owner->p_packetizer, true, fmt ) )
1869             {
1870                 vlc_object_delete(p_owner->p_packetizer);
1871                 p_owner->p_packetizer = NULL;
1872             }
1873             else
1874             {
1875                 p_owner->p_packetizer->fmt_out.b_packetized = true;
1876                 fmt = &p_owner->p_packetizer->fmt_out;
1877             }
1878         }
1879     }
1880
1881     switch( fmt->i_cat )
1882     {
1883         case VIDEO_ES:
1884             if( !b_thumbnailing )
1885                 p_dec->cbs = &dec_video_cbs;
1886             else
1887                 p_dec->cbs = &dec_thumbnailer_cbs;
1888             break;
1889         case AUDIO_ES:
1890             p_dec->cbs = &dec_audio_cbs;
1891             break;
1892         case SPU_ES:
1893             p_dec->cbs = &dec_spu_cbs;
1894             break;
1895         default:
1896             msg_Err( p_dec, "unknown ES format" );
1897             return p_owner;
1898     }
1899
1900     /* Find a suitable decoder/packetizer module */
1901     if( LoadDecoder( p_dec, p_sout != NULL, fmt ) )
1902         return p_owner;
1903
1904     assert( p_dec->fmt_in.i_cat == p_dec->fmt_out.i_cat && fmt->i_cat == p_dec->fmt_in.i_cat);
1905
1906     /* Copy ourself the input replay gain */
1907     if( fmt->i_cat == AUDIO_ES )
1908     {
1909         for( unsigned i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
1910         {
1911             if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
1912             {
1913                 p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
1914                 p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
1915             }
1916             if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
1917             {
1918                 p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
1919                 p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
1920             }
1921         }
1922     }
1923
1924     /* */
1925     p_owner->cc.b_supported = ( p_sout == NULL );
1926
1927     p_owner->cc.desc.i_608_channels = 0;
1928     p_owner->cc.desc.i_708_channels = 0;
1929     for( unsigned i = 0; i < MAX_CC_DECODERS; i++ )
1930         p_owner->cc.pp_decoder[i] = NULL;
1931     p_owner->cc.p_sout_input = NULL;
1932     p_owner->cc.b_sout_created = false;
1933     return p_owner;
1934 }
1935
1936 /**
1937  * Destroys a decoder object
1938  *
1939  * \param p_dec the decoder object
1940  * \return nothing
1941  */
1942 static void DeleteDecoder( vlc_input_decoder_t *p_owner )
1943 {
1944     decoder_t *p_dec = &p_owner->dec;
1945     msg_Dbg( p_dec, "killing decoder fourcc `%4.4s'",
1946              (char*)&p_dec->fmt_in.i_codec );
1947
1948     const enum es_format_category_e i_cat =p_dec->fmt_in.i_cat;
1949     decoder_Clean( p_dec );
1950     if ( p_owner->out_pool )
1951     {
1952         picture_pool_Release( p_owner->out_pool );
1953         p_owner->out_pool = NULL;
1954     }
1955
1956     if (p_owner->vctx)
1957         vlc_video_context_Release( p_owner->vctx );
1958
1959     /* Free all packets still in the decoder fifo. */
1960     block_FifoRelease( p_owner->p_fifo );
1961
1962     /* Cleanup */
1963 #ifdef ENABLE_SOUT
1964     if( p_owner->p_sout_input )
1965     {
1966         sout_InputDelete( p_owner->p_sout, p_owner->p_sout_input );
1967         if( p_owner->cc.p_sout_input )
1968             sout_InputDelete( p_owner->p_sout, p_owner->cc.p_sout_input );
1969     }
1970 #endif
1971
1972     switch( i_cat )
1973     {
1974         case AUDIO_ES:
1975             if( p_owner->p_aout )
1976             {
1977                 /* TODO: REVISIT gap-less audio */
1978                 aout_DecDelete( p_owner->p_aout );
1979                 input_resource_PutAout( p_owner->p_resource, p_owner->p_aout );
1980             }
1981             break;
1982         case VIDEO_ES: {
1983             vout_thread_t *vout = p_owner->p_vout;
1984
1985             if (vout != NULL)
1986             {
1987                 /* Hold the vout since PutVout will likely release it and a
1988                  * last reference is needed for notify callbacks */
1989                 vout_Hold(vout);
1990
1991                 bool has_stopped;
1992                 input_resource_PutVout(p_owner->p_resource, vout, &has_stopped);
1993                 if (has_stopped)
1994                     decoder_Notify(p_owner, on_vout_stopped, vout);
1995
1996                 vout_Release(vout);
1997             }
1998             break;
1999         }
2000         case SPU_ES:
2001         {
2002             if( p_owner->p_vout )
2003             {
2004                 assert( p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID );
2005                 decoder_Notify(p_owner, on_vout_stopped, p_owner->p_vout);
2006
2007                 vout_UnregisterSubpictureChannel( p_owner->p_vout,
2008                                                   p_owner->i_spu_channel );
2009                 vout_Release(p_owner->p_vout);
2010             }
2011             break;
2012         }
2013         case DATA_ES:
2014         case UNKNOWN_ES:
2015             break;
2016         default:
2017             vlc_assert_unreachable();
2018     }
2019
2020     es_format_Clean( &p_owner->fmt );
2021
2022     if( p_owner->p_description )
2023         vlc_meta_Delete( p_owner->p_description );
2024
2025     decoder_Destroy( p_owner->p_packetizer );
2026     decoder_Destroy( &p_owner->dec );
2027 }
2028
2029 /* */
2030 static void DecoderUnsupportedCodec( decoder_t *p_dec, const es_format_t *fmt, bool b_decoding )
2031 {
2032     if (fmt->i_codec != VLC_CODEC_UNKNOWN && fmt->i_codec) {
2033         const char *desc = vlc_fourcc_GetDescription(fmt->i_cat, fmt->i_codec);
2034         if (!desc || !*desc)
2035             desc = N_("No description for this codec");
2036         msg_Err( p_dec, "Codec `%4.4s' (%s) is not supported.", (char*)&fmt->i_codec, desc );
2037         vlc_dialog_display_error( p_dec, _("Codec not supported"),
2038             _("VLC could not decode the format \"%4.4s\" (%s)"),
2039             (char*)&fmt->i_codec, desc );
2040     } else if( b_decoding ){
2041         msg_Err( p_dec, "could not identify codec" );
2042         vlc_dialog_display_error( p_dec, _("Unidentified codec"),
2043             _("VLC could not identify the audio or video codec" ) );
2044     }
2045 }
2046
2047 /* TODO: pass p_sout through p_resource? -- Courmisch */
2048 static vlc_input_decoder_t *
2049 decoder_New( vlc_object_t *p_parent, const es_format_t *fmt,
2050              vlc_clock_t *p_clock, input_resource_t *p_resource,
2051              sout_instance_t *p_sout, bool thumbnailing,
2052              const struct vlc_input_decoder_callbacks *cbs, void *userdata)
2053 {
2054     const char *psz_type = p_sout ? N_("packetizer") : N_("decoder");
2055     int i_priority;
2056
2057     /* Create the decoder configuration structure */
2058     vlc_input_decoder_t *p_owner =
2059         CreateDecoder( p_parent, fmt, p_clock, p_resource, p_sout,
2060                        thumbnailing, cbs, userdata );
2061     if( p_owner == NULL )
2062     {
2063         msg_Err( p_parent, "could not create %s", psz_type );
2064         vlc_dialog_display_error( p_parent, _("Streaming / Transcoding failed"),
2065             _("VLC could not open the %s module."), vlc_gettext( psz_type ) );
2066         return NULL;
2067     }
2068
2069     decoder_t *p_dec = &p_owner->dec;
2070     if( !p_dec->p_module )
2071     {
2072         DecoderUnsupportedCodec( p_dec, fmt, !p_sout );
2073
2074         DeleteDecoder( p_owner );
2075         return NULL;
2076     }
2077
2078     assert( p_dec->fmt_in.i_cat != UNKNOWN_ES );
2079
2080 #if VLC_THREAD_PRIORITY_AUDIO != VLC_THREAD_PRIORITY_VIDEO
2081     if( p_dec->fmt_in.i_cat == AUDIO_ES )
2082         i_priority = VLC_THREAD_PRIORITY_AUDIO;
2083     else
2084 #endif
2085         i_priority = VLC_THREAD_PRIORITY_VIDEO;
2086
2087 #ifdef ENABLE_SOUT
2088     /* Do not delay sout creation for SPU or DATA. */
2089     if( p_sout && fmt->b_packetized &&
2090         (fmt->i_cat != VIDEO_ES && fmt->i_cat != AUDIO_ES) )
2091     {
2092         p_owner->p_sout_input = sout_InputNew( p_owner->p_sout, fmt );
2093         if( p_owner->p_sout_input == NULL )
2094         {
2095             msg_Err( p_dec, "cannot create sout input (%4.4s)",
2096                      (char *)&fmt->i_codec );
2097             p_owner->error = true;
2098         }
2099     }
2100 #endif
2101
2102     /* Spawn the decoder thread */
2103     if( vlc_clone( &p_owner->thread, DecoderThread, p_owner, i_priority ) )
2104     {
2105         msg_Err( p_dec, "cannot spawn decoder thread" );
2106         DeleteDecoder( p_owner );
2107         return NULL;
2108     }
2109
2110     return p_owner;
2111 }
2112
2113
2114 /**
2115  * Spawns a new decoder thread from the input thread
2116  *
2117  * \param p_input the input thread
2118  * \param p_es the es descriptor
2119  * \return the spawned decoder object
2120  */
2121 vlc_input_decoder_t *
2122 vlc_input_decoder_New( vlc_object_t *parent, es_format_t *fmt,
2123                   vlc_clock_t *p_clock, input_resource_t *resource,
2124                   sout_instance_t *p_sout, bool thumbnailing,
2125                   const struct vlc_input_decoder_callbacks *cbs,
2126                   void *cbs_userdata)
2127 {
2128     return decoder_New( parent, fmt, p_clock, resource, p_sout, thumbnailing,
2129                         cbs, cbs_userdata );
2130 }
2131
2132 /**
2133  * Spawn a decoder thread outside of the input thread.
2134  */
2135 vlc_input_decoder_t *
2136 vlc_input_decoder_Create( vlc_object_t *p_parent, const es_format_t *fmt,
2137                      input_resource_t *p_resource )
2138 {
2139     return decoder_New( p_parent, fmt, NULL, p_resource, NULL, false, NULL,
2140                         NULL );
2141 }
2142
2143
2144 /**
2145  * Kills a decoder thread and waits until it's finished
2146  *
2147  * \param p_input the input thread
2148  * \param p_es the es descriptor
2149  * \return nothing
2150  */
2151 void vlc_input_decoder_Delete( vlc_input_decoder_t *p_owner )
2152 {
2153     decoder_t *p_dec = &p_owner->dec;
2154
2155     vlc_fifo_Lock( p_owner->p_fifo );
2156     p_owner->aborting = true;
2157     p_owner->flushing = true;
2158     vlc_fifo_Signal( p_owner->p_fifo );
2159     vlc_fifo_Unlock( p_owner->p_fifo );
2160
2161     /* Make sure we aren't waiting/decoding anymore */
2162     vlc_mutex_lock( &p_owner->lock );
2163     p_owner->b_waiting = false;
2164     vlc_cond_signal( &p_owner->wait_request );
2165
2166     /* If the video output is paused or slow, or if the picture pool size was
2167      * under-estimated (e.g. greedy video filter, buggy decoder...), the
2168      * the picture pool may be empty, and the decoder thread or any decoder
2169      * module worker threads may be stuck waiting for free picture buffers.
2170      *
2171      * This unblocks the thread, allowing the decoder module to join all its
2172      * worker threads (if any) and the decoder thread to terminate. */
2173     if( p_dec->fmt_in.i_cat == VIDEO_ES && p_owner->p_vout != NULL
2174      && p_owner->vout_started )
2175     {
2176         if (p_owner->out_pool)
2177             picture_pool_Cancel( p_owner->out_pool, true );
2178
2179         if( p_owner->paused )
2180         {
2181             /* The DecoderThread could be stuck in pf_decode(). This is likely the
2182             * case with paused asynchronous decoder modules that have a limited
2183             * input and output pool size. Indeed, with such decoders, you have to
2184             * release an output buffer to get an input buffer. So, when paused and
2185             * flushed, the DecoderThread could be waiting for an output buffer to
2186             * be released (or rendered). In that case, the DecoderThread will
2187             * never be flushed since it be never leave pf_decode(). To fix this
2188             * issue, pre-flush the vout from here. The vout will have to be
2189             * flushed again since the module could be outputting more buffers just
2190             * after being unstuck. */
2191
2192             vout_FlushAll( p_owner->p_vout );
2193         }
2194     }
2195     vlc_mutex_unlock( &p_owner->lock );
2196
2197     vlc_join( p_owner->thread, NULL );
2198
2199     /* */
2200     if( p_owner->cc.b_supported )
2201     {
2202         for( int i = 0; i < MAX_CC_DECODERS; i++ )
2203             vlc_input_decoder_SetCcState( p_owner, VLC_CODEC_CEA608, i, false );
2204     }
2205
2206     /* Delete decoder */
2207     DeleteDecoder( p_owner );
2208 }
2209
2210 /**
2211  * Put a block_t in the decoder's fifo.
2212  * Thread-safe w.r.t. the decoder. May be a cancellation point.
2213  *
2214  * \param p_dec the decoder object
2215  * \param p_block the data block
2216  */
2217 void vlc_input_decoder_Decode( vlc_input_decoder_t *p_owner, block_t *p_block,
2218                                bool b_do_pace )
2219 {
2220     vlc_fifo_Lock( p_owner->p_fifo );
2221     if( !b_do_pace )
2222     {
2223         /* FIXME: ideally we would check the time amount of data
2224          * in the FIFO instead of its size. */
2225         /* 400 MiB, i.e. ~ 50mb/s for 60s */
2226         if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )
2227         {
2228             msg_Warn( &p_owner->dec, "decoder/packetizer fifo full (data not "
2229                       "consumed quickly enough), resetting fifo!" );
2230             block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2231             p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2232         }
2233     }
2234     else
2235     if( !p_owner->b_waiting )
2236     {   /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
2237          * Locking is not necessary as b_waiting is only read, not written by
2238          * the decoder thread. */
2239         while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
2240             vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_fifo );
2241     }
2242
2243     vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
2244     vlc_fifo_Unlock( p_owner->p_fifo );
2245 }
2246
2247 bool vlc_input_decoder_IsEmpty( vlc_input_decoder_t * p_owner )
2248 {
2249     assert( !p_owner->b_waiting );
2250
2251     vlc_fifo_Lock( p_owner->p_fifo );
2252     if( !vlc_fifo_IsEmpty( p_owner->p_fifo ) || p_owner->b_draining )
2253     {
2254         vlc_fifo_Unlock( p_owner->p_fifo );
2255         return false;
2256     }
2257     vlc_fifo_Unlock( p_owner->p_fifo );
2258
2259     bool b_empty;
2260
2261     vlc_mutex_lock( &p_owner->lock );
2262 #ifdef ENABLE_SOUT
2263     if( p_owner->p_sout_input != NULL )
2264         b_empty = true;
2265     else
2266 #endif
2267     if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->p_vout != NULL )
2268         b_empty = vout_IsEmpty( p_owner->p_vout );
2269     else if( p_owner->fmt.i_cat == AUDIO_ES )
2270         b_empty = !p_owner->b_draining || p_owner->drained;
2271     else
2272         b_empty = true; /* TODO subtitles support */
2273     vlc_mutex_unlock( &p_owner->lock );
2274
2275     return b_empty;
2276 }
2277
2278 /**
2279  * Signals that there are no further blocks to decode, and requests that the
2280  * decoder drain all pending buffers. This is used to ensure that all
2281  * intermediate buffers empty and no samples get lost at the end of the stream.
2282  *
2283  * @note The function does not actually wait for draining. It just signals that
2284  * draining should be performed once the decoder has emptied FIFO.
2285  */
2286 void vlc_input_decoder_Drain( vlc_input_decoder_t *p_owner )
2287 {
2288     vlc_fifo_Lock( p_owner->p_fifo );
2289     p_owner->b_draining = true;
2290     vlc_fifo_Signal( p_owner->p_fifo );
2291     vlc_fifo_Unlock( p_owner->p_fifo );
2292 }
2293
2294 /**
2295  * Requests that the decoder immediately discard all pending buffers.
2296  * This is useful when seeking or when deselecting a stream.
2297  */
2298 void vlc_input_decoder_Flush( vlc_input_decoder_t *p_owner )
2299 {
2300     enum es_format_category_e cat = p_owner->dec.fmt_in.i_cat;
2301
2302     vlc_fifo_Lock( p_owner->p_fifo );
2303
2304     /* Empty the fifo */
2305     block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2306
2307     /* Don't need to wait for the DecoderThread to flush. Indeed, if called a
2308      * second time, this function will clear the FIFO again before anything was
2309      * dequeued by DecoderThread and there is no need to flush a second time in
2310      * a row. */
2311     p_owner->flushing = true;
2312
2313     /* Flush video/spu decoder when paused: increment frames_countdown in order
2314      * to display one frame/subtitle */
2315     if( p_owner->paused && ( cat == VIDEO_ES || cat == SPU_ES )
2316      && p_owner->frames_countdown == 0 )
2317         p_owner->frames_countdown++;
2318
2319     vlc_fifo_Signal( p_owner->p_fifo );
2320
2321     vlc_fifo_Unlock( p_owner->p_fifo );
2322
2323     if ( cat == VIDEO_ES )
2324     {
2325         /* Set the pool cancel state. This will unblock the module if it is
2326          * waiting for new pictures (likely). This state will be reset back
2327          * from the DecoderThread once the flush request is processed. */
2328         vlc_mutex_lock( &p_owner->lock );
2329         if( p_owner->out_pool != NULL )
2330             picture_pool_Cancel( p_owner->out_pool, true );
2331         vlc_mutex_unlock( &p_owner->lock );
2332     }
2333
2334     if( p_owner->paused )
2335     {
2336         /* The DecoderThread could be stuck in pf_decode(). This is likely the
2337          * case with paused asynchronous decoder modules that have a limited
2338          * input and output pool size. Indeed, with such decoders, you have to
2339          * release an output buffer to get an input buffer. So, when paused and
2340          * flushed, the DecoderThread could be waiting for an output buffer to
2341          * be released (or rendered). In that case, the DecoderThread will
2342          * never be flushed since it be never leave pf_decode(). To fix this
2343          * issue, pre-flush the vout from here. The vout will have to be
2344          * flushed again since the module could be outputting more buffers just
2345          * after being unstuck. */
2346
2347         vlc_mutex_lock( &p_owner->lock );
2348         if( cat == VIDEO_ES && p_owner->p_vout && p_owner->vout_started )
2349             vout_FlushAll( p_owner->p_vout );
2350         vlc_mutex_unlock( &p_owner->lock );
2351     }
2352 }
2353
2354 void vlc_input_decoder_GetCcDesc( vlc_input_decoder_t *p_owner,
2355                                   decoder_cc_desc_t *p_desc )
2356 {
2357     vlc_mutex_lock( &p_owner->lock );
2358     *p_desc = p_owner->cc.desc;
2359     vlc_mutex_unlock( &p_owner->lock );
2360 }
2361
2362 static bool vlc_input_decoder_HasCCChanFlag( vlc_input_decoder_t *p_owner,
2363                                              vlc_fourcc_t codec, int i_channel )
2364 {
2365     int i_max_channels;
2366     uint64_t i_bitmap;
2367     if( codec == VLC_CODEC_CEA608 )
2368     {
2369         i_max_channels = 4;
2370         i_bitmap = p_owner->cc.desc.i_608_channels;
2371     }
2372     else if( codec == VLC_CODEC_CEA708 )
2373     {
2374         i_max_channels = 64;
2375         i_bitmap = p_owner->cc.desc.i_708_channels;
2376     }
2377     else return false;
2378
2379     return ( i_channel >= 0 && i_channel < i_max_channels &&
2380              ( i_bitmap & ((uint64_t)1 << i_channel) ) );
2381 }
2382
2383 int vlc_input_decoder_SetCcState( vlc_input_decoder_t *p_owner, vlc_fourcc_t codec,
2384                                   int i_channel, bool b_decode )
2385 {
2386     decoder_t *p_dec = &p_owner->dec;
2387     //msg_Warn( p_dec, "vlc_input_decoder_SetCcState: %d @%x", b_decode, i_channel );
2388
2389     if( !vlc_input_decoder_HasCCChanFlag( p_owner, codec, i_channel ) )
2390         return VLC_EGENERIC;
2391
2392     if( b_decode )
2393     {
2394         vlc_input_decoder_t *p_ccowner;
2395         es_format_t fmt;
2396
2397         es_format_Init( &fmt, SPU_ES, codec );
2398         fmt.subs.cc.i_channel = i_channel;
2399         fmt.subs.cc.i_reorder_depth = p_owner->cc.desc.i_reorder_depth;
2400         p_ccowner = vlc_input_decoder_New( VLC_OBJECT(p_dec), &fmt, p_owner->p_clock,
2401                                       p_owner->p_resource, p_owner->p_sout, false,
2402                                       NULL, NULL );
2403         if( !p_ccowner )
2404         {
2405             msg_Err( p_dec, "could not create decoder" );
2406             vlc_dialog_display_error( p_dec,
2407                 _("Streaming / Transcoding failed"), "%s",
2408                 _("VLC could not open the decoder module.") );
2409             return VLC_EGENERIC;
2410         }
2411         else if( !p_ccowner->dec.p_module )
2412         {
2413             DecoderUnsupportedCodec( p_dec, &fmt, true );
2414             vlc_input_decoder_Delete(p_ccowner);
2415             return VLC_EGENERIC;
2416         }
2417         p_ccowner->p_clock = p_owner->p_clock;
2418
2419         vlc_mutex_lock( &p_owner->lock );
2420         p_owner->cc.pp_decoder[i_channel] = p_ccowner;
2421         vlc_mutex_unlock( &p_owner->lock );
2422     }
2423     else
2424     {
2425         vlc_input_decoder_t *p_cc;
2426
2427         vlc_mutex_lock( &p_owner->lock );
2428         p_cc = p_owner->cc.pp_decoder[i_channel];
2429         p_owner->cc.pp_decoder[i_channel] = NULL;
2430         vlc_mutex_unlock( &p_owner->lock );
2431
2432         if( p_cc )
2433             vlc_input_decoder_Delete(p_cc);
2434     }
2435     return VLC_SUCCESS;
2436 }
2437
2438 int vlc_input_decoder_GetCcState( vlc_input_decoder_t *p_owner, vlc_fourcc_t codec,
2439                                   int i_channel, bool *pb_decode )
2440 {
2441     if( !vlc_input_decoder_HasCCChanFlag( p_owner, codec, i_channel ) )
2442         return VLC_EGENERIC;
2443
2444     vlc_mutex_lock( &p_owner->lock );
2445     *pb_decode = p_owner->cc.pp_decoder[i_channel] != NULL;
2446     vlc_mutex_unlock( &p_owner->lock );
2447     return VLC_SUCCESS;
2448 }
2449
2450 void vlc_input_decoder_ChangePause( vlc_input_decoder_t *p_owner,
2451                                     bool b_paused, vlc_tick_t i_date )
2452 {
2453     /* Normally, p_owner->b_paused != b_paused here. But if a track is added
2454      * while the input is paused (e.g. add sub file), then b_paused is
2455      * (incorrectly) false. FIXME: This is a bug in the decoder owner. */
2456     vlc_fifo_Lock( p_owner->p_fifo );
2457     p_owner->paused = b_paused;
2458     p_owner->pause_date = i_date;
2459     p_owner->frames_countdown = 0;
2460     vlc_fifo_Signal( p_owner->p_fifo );
2461     vlc_fifo_Unlock( p_owner->p_fifo );
2462 }
2463
2464 void vlc_input_decoder_ChangeRate( vlc_input_decoder_t *owner, float rate )
2465 {
2466     vlc_fifo_Lock( owner->p_fifo );
2467     owner->request_rate = rate;
2468     vlc_fifo_Unlock( owner->p_fifo );
2469 }
2470
2471 void vlc_input_decoder_ChangeDelay( vlc_input_decoder_t *owner, vlc_tick_t delay )
2472 {
2473     vlc_fifo_Lock( owner->p_fifo );
2474     owner->delay = delay;
2475     vlc_fifo_Unlock( owner->p_fifo );
2476 }
2477
2478 void vlc_input_decoder_StartWait( vlc_input_decoder_t *p_owner )
2479 {
2480     assert( !p_owner->b_waiting );
2481
2482     vlc_mutex_lock( &p_owner->lock );
2483     p_owner->b_first = true;
2484     p_owner->b_has_data = false;
2485     p_owner->b_waiting = true;
2486     vlc_cond_signal( &p_owner->wait_request );
2487     vlc_mutex_unlock( &p_owner->lock );
2488 }
2489
2490 void vlc_input_decoder_StopWait( vlc_input_decoder_t *p_owner )
2491 {
2492     assert( p_owner->b_waiting );
2493
2494     vlc_mutex_lock( &p_owner->lock );
2495     p_owner->b_waiting = false;
2496     vlc_cond_signal( &p_owner->wait_request );
2497     vlc_mutex_unlock( &p_owner->lock );
2498 }
2499
2500 void vlc_input_decoder_Wait( vlc_input_decoder_t *p_owner )
2501 {
2502     assert( p_owner->b_waiting );
2503
2504     vlc_mutex_lock( &p_owner->lock );
2505     while( !p_owner->b_has_data )
2506     {
2507         /* Don't need to lock p_owner->paused since it's only modified by the
2508          * owner */
2509         if( p_owner->paused )
2510             break;
2511         vlc_fifo_Lock( p_owner->p_fifo );
2512         if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
2513         {
2514             msg_Err( &p_owner->dec, "buffer deadlock prevented" );
2515             vlc_fifo_Unlock( p_owner->p_fifo );
2516             break;
2517         }
2518         vlc_fifo_Unlock( p_owner->p_fifo );
2519         vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
2520     }
2521     vlc_mutex_unlock( &p_owner->lock );
2522 }
2523
2524 void vlc_input_decoder_FrameNext( vlc_input_decoder_t *p_owner,
2525                                   vlc_tick_t *pi_duration )
2526 {
2527     assert( p_owner->paused );
2528     *pi_duration = 0;
2529
2530     vlc_fifo_Lock( p_owner->p_fifo );
2531     p_owner->frames_countdown++;
2532     vlc_fifo_Signal( p_owner->p_fifo );
2533     vlc_fifo_Unlock( p_owner->p_fifo );
2534
2535     vlc_mutex_lock( &p_owner->lock );
2536     if( p_owner->dec.fmt_in.i_cat == VIDEO_ES )
2537     {
2538         if( p_owner->p_vout )
2539             vout_NextPicture( p_owner->p_vout, pi_duration );
2540     }
2541     vlc_mutex_unlock( &p_owner->lock );
2542 }
2543
2544 bool vlc_input_decoder_HasFormatChanged( vlc_input_decoder_t *p_owner,
2545                                          es_format_t *p_fmt, vlc_meta_t **pp_meta )
2546 {
2547     if( !atomic_exchange_explicit( &p_owner->b_fmt_description, false,
2548                                    memory_order_acquire ) )
2549         return false;
2550
2551     vlc_mutex_lock( &p_owner->lock );
2552
2553     if( p_owner->fmt.i_cat == UNKNOWN_ES )
2554     {
2555         /* The format changed but the output creation failed */
2556         vlc_mutex_unlock( &p_owner->lock );
2557         return false;
2558     }
2559
2560     if( p_fmt != NULL )
2561         es_format_Copy( p_fmt, &p_owner->fmt );
2562
2563     if( pp_meta )
2564     {
2565         *pp_meta = NULL;
2566         if( p_owner->p_description )
2567         {
2568             *pp_meta = vlc_meta_New();
2569             if( *pp_meta )
2570                 vlc_meta_Merge( *pp_meta, p_owner->p_description );
2571         }
2572     }
2573     vlc_mutex_unlock( &p_owner->lock );
2574     return true;
2575 }
2576
2577 size_t vlc_input_decoder_GetFifoSize( vlc_input_decoder_t *p_owner )
2578 {
2579     return block_FifoSize( p_owner->p_fifo );
2580 }
2581
2582 static bool DecoderHasVbi( decoder_t *dec )
2583 {
2584     return dec->fmt_in.i_cat == SPU_ES && dec->fmt_in.i_codec == VLC_CODEC_TELETEXT
2585         && var_Type( dec, "vbi-page" ) == VLC_VAR_INTEGER;
2586 }
2587
2588 int vlc_input_decoder_GetVbiPage( vlc_input_decoder_t *owner, bool *opaque )
2589 {
2590     decoder_t *dec = &owner->dec;
2591     if( !DecoderHasVbi( dec ) )
2592         return -1;
2593     *opaque = var_GetBool( dec, "vbi-opaque" );
2594     return var_GetInteger( dec, "vbi-page" );
2595 }
2596
2597 int vlc_input_decoder_SetVbiPage( vlc_input_decoder_t *owner, unsigned page )
2598 {
2599     decoder_t *dec = &owner->dec;
2600     if( !DecoderHasVbi( dec ) )
2601         return VLC_EGENERIC;
2602     return var_SetInteger( dec, "vbi-page", page );
2603 }
2604
2605 int vlc_input_decoder_SetVbiOpaque( vlc_input_decoder_t *owner, bool opaque )
2606 {
2607     decoder_t *dec = &owner->dec;
2608     if( !DecoderHasVbi( dec ) )
2609         return VLC_EGENERIC;
2610     return var_SetBool( dec, "vbi-opaque", opaque );
2611 }
2612
2613 void vlc_input_decoder_SetVoutMouseEvent( vlc_input_decoder_t *owner,
2614                                           vlc_mouse_event mouse_event,
2615                                           void *user_data )
2616 {
2617     assert( owner->dec.fmt_in.i_cat == VIDEO_ES );
2618
2619     vlc_mutex_lock( &owner->mouse_lock );
2620
2621     owner->mouse_event = mouse_event;
2622     owner->mouse_opaque = user_data;
2623
2624     vlc_mutex_unlock( &owner->mouse_lock );
2625 }
2626
2627 int vlc_input_decoder_AddVoutOverlay( vlc_input_decoder_t *owner, subpicture_t *sub,
2628                                       size_t *channel )
2629 {
2630     assert( owner->dec.fmt_in.i_cat == VIDEO_ES );
2631     assert( sub && channel );
2632
2633     vlc_mutex_lock( &owner->lock );
2634
2635     if( !owner->p_vout )
2636     {
2637         vlc_mutex_unlock( &owner->lock );
2638         return VLC_EGENERIC;
2639     }
2640     ssize_t channel_id =
2641         vout_RegisterSubpictureChannel( owner->p_vout );
2642     if (channel_id == -1)
2643     {
2644         vlc_mutex_unlock( &owner->lock );
2645         return VLC_EGENERIC;
2646     }
2647     sub->i_start = sub->i_stop = vlc_tick_now();
2648     sub->i_channel = *channel = channel_id;
2649     sub->i_order = 0;
2650     sub->b_ephemer = true;
2651     vout_PutSubpicture( owner->p_vout, sub );
2652
2653     vlc_mutex_unlock( &owner->lock );
2654     return VLC_SUCCESS;
2655 }
2656
2657 int vlc_input_decoder_DelVoutOverlay( vlc_input_decoder_t *owner, size_t channel )
2658 {
2659     assert( owner->dec.fmt_in.i_cat == VIDEO_ES );
2660
2661     vlc_mutex_lock( &owner->lock );
2662
2663     if( !owner->p_vout )
2664     {
2665         vlc_mutex_unlock( &owner->lock );
2666         return VLC_EGENERIC;
2667     }
2668     vout_UnregisterSubpictureChannel( owner->p_vout, channel );
2669
2670     vlc_mutex_unlock( &owner->lock );
2671     return VLC_SUCCESS;
2672 }
2673
2674 int vlc_input_decoder_SetSpuHighlight( vlc_input_decoder_t *p_owner,
2675                                        const vlc_spu_highlight_t *spu_hl )
2676 {
2677     assert( p_owner->dec.fmt_in.i_cat == SPU_ES );
2678
2679 #ifdef ENABLE_SOUT
2680     if( p_owner->p_sout_input )
2681         sout_InputControl( p_owner->p_sout, p_owner->p_sout_input,
2682                            SOUT_INPUT_SET_SPU_HIGHLIGHT, spu_hl );
2683 #endif
2684
2685     vlc_mutex_lock( &p_owner->lock );
2686     if( !p_owner->p_vout )
2687     {
2688         vlc_mutex_unlock( &p_owner->lock );
2689         return VLC_EGENERIC;
2690     }
2691
2692     vout_SetSpuHighlight( p_owner->p_vout, spu_hl );
2693
2694     vlc_mutex_unlock( &p_owner->lock );
2695     return VLC_SUCCESS;
2696 }