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