1 /*****************************************************************************
2  * decoder.c: Functions for the management of decoders
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VLC authors and VideoLAN
5  * $Id: 775f256313cd2a61eb9187bc72b5af419c808b70 $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *          Laurent Aimar <fenrir@via.ecp.fr>
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation; either version 2.1 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25 
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
33 
34 #include <vlc_common.h>
35 
36 #include <vlc_atomic.h>
37 #include <vlc_block.h>
38 #include <vlc_vout.h>
39 #include <vlc_aout.h>
40 #include <vlc_sout.h>
41 #include <vlc_codec.h>
42 #include <vlc_spu.h>
43 #include <vlc_meta.h>
44 #include <vlc_dialog.h>
45 #include <vlc_modules.h>
46 
47 #include "audio_output/aout_internal.h"
48 #include "stream_output/stream_output.h"
49 #include "input_internal.h"
50 #include "clock.h"
51 #include "decoder.h"
52 #include "event.h"
53 #include "resource.h"
54 
55 #include "../video_output/vout_control.h"
56 
57 /*
58  * Possibles values set in p_owner->reload atomic
59  */
60 enum reload
61 {
62     RELOAD_NO_REQUEST,
63     RELOAD_DECODER,     /* Reload the decoder module */
64     RELOAD_DECODER_AOUT /* Stop the aout and reload the decoder module */
65 };
66 
67 struct decoder_owner_sys_t
68 {
69     input_thread_t  *p_input;
70     input_resource_t*p_resource;
71     input_clock_t   *p_clock;
72     int             i_last_rate;
73 
74     vout_thread_t   *p_spu_vout;
75     int              i_spu_channel;
76     int64_t          i_spu_order;
77 
78     sout_instance_t         *p_sout;
79     sout_packetizer_input_t *p_sout_input;
80 
81     vlc_thread_t     thread;
82 
83     void (*pf_update_stat)( decoder_owner_sys_t *, unsigned decoded, unsigned lost );
84 
85     /* Some decoders require already packetized data (ie. not truncated) */
86     decoder_t *p_packetizer;
87     bool b_packetizer;
88 
89     /* Current format in use by the output */
90     es_format_t    fmt;
91 
92     /* */
93     bool           b_fmt_description;
94     vlc_meta_t     *p_description;
95     atomic_int     reload;
96 
97     /* fifo */
98     block_fifo_t *p_fifo;
99 
100     /* Lock for communication with decoder thread */
101     vlc_mutex_t lock;
102     vlc_cond_t  wait_request;
103     vlc_cond_t  wait_acknowledge;
104     vlc_cond_t  wait_fifo; /* TODO: merge with wait_acknowledge */
105     vlc_cond_t  wait_timed;
106 
107     /* -- These variables need locking on write(only) -- */
108     audio_output_t *p_aout;
109 
110     vout_thread_t   *p_vout;
111 
112     /* -- Theses variables need locking on read *and* write -- */
113     /* Preroll */
114     int64_t i_preroll_end;
115     /* Pause */
116     mtime_t pause_date;
117     unsigned frames_countdown;
118     bool paused;
119 
120     bool error;
121 
122     /* Waiting */
123     bool b_waiting;
124     bool b_first;
125     bool b_has_data;
126 
127     /* Flushing */
128     bool flushing;
129     bool b_draining;
130     atomic_bool drained;
131     bool b_idle;
132 
133     /* CC */
134 #define MAX_CC_DECODERS 64 /* The es_out only creates one type of es */
135     struct
136     {
137         bool b_supported;
138         decoder_cc_desc_t desc;
139         decoder_t *pp_decoder[MAX_CC_DECODERS];
140     } cc;
141 
142     /* Delay */
143     mtime_t i_ts_delay;
144 };
145 
146 /* Pictures which are DECODER_BOGUS_VIDEO_DELAY or more in advance probably have
147  * a bogus PTS and won't be displayed */
148 #define DECODER_BOGUS_VIDEO_DELAY                ((mtime_t)(DEFAULT_PTS_DELAY * 30))
149 
150 /* */
151 #define DECODER_SPU_VOUT_WAIT_DURATION ((int)(0.200*CLOCK_FREQ))
152 #define BLOCK_FLAG_CORE_PRIVATE_RELOADED (1 << BLOCK_FLAG_CORE_PRIVATE_SHIFT)
153 
154 /**
155  * Load a decoder module
156  */
LoadDecoder(decoder_t * p_dec,bool b_packetizer,const es_format_t * restrict p_fmt)157 static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
158                         const es_format_t *restrict p_fmt )
159 {
160     p_dec->b_frame_drop_allowed = true;
161     p_dec->i_extra_picture_buffers = 0;
162 
163     p_dec->pf_decode = NULL;
164     p_dec->pf_get_cc = NULL;
165     p_dec->pf_packetize = NULL;
166     p_dec->pf_flush = NULL;
167 
168     es_format_Copy( &p_dec->fmt_in, p_fmt );
169     es_format_Init( &p_dec->fmt_out, p_fmt->i_cat, 0 );
170 
171     /* Find a suitable decoder/packetizer module */
172     if( !b_packetizer )
173     {
174         static const char caps[ES_CATEGORY_COUNT][16] = {
175             [VIDEO_ES] = "video decoder",
176             [AUDIO_ES] = "audio decoder",
177             [SPU_ES] = "spu decoder",
178         };
179         p_dec->p_module = module_need( p_dec, caps[p_dec->fmt_in.i_cat],
180                                        "$codec", false );
181     }
182     else
183         p_dec->p_module = module_need( p_dec, "packetizer", "$packetizer", false );
184 
185     if( !p_dec->p_module )
186     {
187         es_format_Clean( &p_dec->fmt_in );
188         return -1;
189     }
190     else
191         return 0;
192 }
193 
194 /**
195  * Unload a decoder module
196  */
UnloadDecoder(decoder_t * p_dec)197 static void UnloadDecoder( decoder_t *p_dec )
198 {
199     if( p_dec->p_module )
200     {
201         module_unneed( p_dec, p_dec->p_module );
202         p_dec->p_module = NULL;
203     }
204 
205     if( p_dec->p_description )
206     {
207         vlc_meta_Delete( p_dec->p_description );
208         p_dec->p_description = NULL;
209     }
210 
211     es_format_Clean( &p_dec->fmt_in );
212     es_format_Clean( &p_dec->fmt_out );
213 }
214 
ReloadDecoder(decoder_t * p_dec,bool b_packetizer,const es_format_t * restrict p_fmt,enum reload reload)215 static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer,
216                           const es_format_t *restrict p_fmt, enum reload reload )
217 {
218     /* Copy p_fmt since it can be destroyed by UnloadDecoder */
219     es_format_t fmt_in;
220     if( es_format_Copy( &fmt_in, p_fmt ) != VLC_SUCCESS )
221     {
222         p_dec->p_owner->error = true;
223         return VLC_EGENERIC;
224     }
225 
226     /* Restart the decoder module */
227     UnloadDecoder( p_dec );
228     p_dec->p_owner->error = false;
229 
230     if( reload == RELOAD_DECODER_AOUT )
231     {
232         decoder_owner_sys_t *p_owner = p_dec->p_owner;
233         assert( p_owner->fmt.i_cat == AUDIO_ES );
234         audio_output_t *p_aout = p_owner->p_aout;
235 
236         vlc_mutex_lock( &p_owner->lock );
237         p_owner->p_aout = NULL;
238         vlc_mutex_unlock( &p_owner->lock );
239         if( p_aout )
240         {
241             aout_DecDelete( p_aout );
242             input_resource_PutAout( p_owner->p_resource, p_aout );
243         }
244     }
245 
246     if( LoadDecoder( p_dec, b_packetizer, &fmt_in ) )
247     {
248         p_dec->p_owner->error = true;
249         es_format_Clean( &fmt_in );
250         return VLC_EGENERIC;
251     }
252     es_format_Clean( &fmt_in );
253     return VLC_SUCCESS;
254 }
255 
DecoderUpdateFormatLocked(decoder_t * p_dec)256 static void DecoderUpdateFormatLocked( decoder_t *p_dec )
257 {
258     decoder_owner_sys_t *p_owner = p_dec->p_owner;
259 
260     vlc_assert_locked( &p_owner->lock );
261 
262     es_format_Clean( &p_owner->fmt );
263     es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
264 
265     /* Move p_description */
266     if( p_dec->p_description != NULL )
267     {
268         if( p_owner->p_description != NULL )
269             vlc_meta_Delete( p_owner->p_description );
270         p_owner->p_description = p_dec->p_description;
271         p_dec->p_description = NULL;
272     }
273 
274     p_owner->b_fmt_description = true;
275 }
276 
277 /*****************************************************************************
278  * Buffers allocation callbacks for the decoders
279  *****************************************************************************/
aout_request_vout(void * p_private,vout_thread_t * p_vout,const video_format_t * p_fmt,bool b_recyle)280 static vout_thread_t *aout_request_vout( void *p_private,
281                                          vout_thread_t *p_vout,
282                                          const video_format_t *p_fmt, bool b_recyle )
283 {
284     decoder_t *p_dec = p_private;
285     decoder_owner_sys_t *p_owner = p_dec->p_owner;
286     input_thread_t *p_input = p_owner->p_input;
287     video_format_t fmt;
288 
289     if (p_fmt != NULL)
290     {
291         fmt = *p_fmt;
292         p_fmt = &fmt;
293         video_format_AdjustColorSpace( &fmt );
294     }
295 
296     p_vout = input_resource_RequestVout( p_owner->p_resource, p_vout, p_fmt, 1,
297                                          b_recyle );
298     if( p_input != NULL )
299         input_SendEventVout( p_input );
300 
301     return p_vout;
302 }
303 
aout_replaygain_changed(const audio_replay_gain_t * a,const audio_replay_gain_t * b)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 
aout_update_format(decoder_t * p_dec)318 static int aout_update_format( decoder_t *p_dec )
319 {
320     decoder_owner_sys_t *p_owner = p_dec->p_owner;
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;
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         aout_request_vout_t request_vout = {
368             .pf_request_vout = aout_request_vout,
369             .p_private = p_dec,
370         };
371         audio_output_t *p_aout;
372 
373         p_aout = input_resource_GetAout( p_owner->p_resource );
374         if( p_aout )
375         {
376             /* TODO: 3.0 HACK: we need to put i_profile inside audio_format_t
377              * for 4.0 */
378             if( p_dec->fmt_out.i_codec == VLC_CODEC_DTS )
379                 var_SetBool( p_aout, "dtshd", p_dec->fmt_out.i_profile > 0 );
380 
381             if( aout_DecNew( p_aout, &format,
382                              &p_dec->fmt_out.audio_replay_gain,
383                              &request_vout ) )
384             {
385                 input_resource_PutAout( p_owner->p_resource, p_aout );
386                 p_aout = NULL;
387             }
388         }
389 
390         vlc_mutex_lock( &p_owner->lock );
391         p_owner->p_aout = p_aout;
392 
393         DecoderUpdateFormatLocked( p_dec );
394         aout_FormatPrepare( &p_owner->fmt.audio );
395         vlc_mutex_unlock( &p_owner->lock );
396 
397         if( p_owner->p_input != NULL )
398             input_SendEventAout( p_owner->p_input );
399 
400         if( p_aout == NULL )
401         {
402             msg_Err( p_dec, "failed to create audio output" );
403             return -1;
404         }
405 
406         p_dec->fmt_out.audio.i_bytes_per_frame =
407             p_owner->fmt.audio.i_bytes_per_frame;
408         p_dec->fmt_out.audio.i_frame_length =
409             p_owner->fmt.audio.i_frame_length;
410     }
411     return 0;
412 }
413 
vout_update_format(decoder_t * p_dec)414 static int vout_update_format( decoder_t *p_dec )
415 {
416     decoder_owner_sys_t *p_owner = p_dec->p_owner;
417 
418     if( p_owner->p_vout == NULL
419      || p_dec->fmt_out.video.i_width != p_owner->fmt.video.i_width
420      || p_dec->fmt_out.video.i_height != p_owner->fmt.video.i_height
421      || p_dec->fmt_out.video.i_visible_width != p_owner->fmt.video.i_visible_width
422      || p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
423      || p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
424      || p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset
425      || p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma
426      || (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
427         (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num ||
428         p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation ||
429         p_dec->fmt_out.video.multiview_mode != p_owner->fmt.video.multiview_mode )
430     {
431         vout_thread_t *p_vout;
432 
433         if( !p_dec->fmt_out.video.i_width ||
434             !p_dec->fmt_out.video.i_height ||
435             p_dec->fmt_out.video.i_width < p_dec->fmt_out.video.i_visible_width ||
436             p_dec->fmt_out.video.i_height < p_dec->fmt_out.video.i_visible_height )
437         {
438             /* Can't create a new vout without display size */
439             return -1;
440         }
441 
442         video_format_t fmt = p_dec->fmt_out.video;
443         fmt.i_chroma = p_dec->fmt_out.i_codec;
444 
445         if( vlc_fourcc_IsYUV( fmt.i_chroma ) )
446         {
447             const vlc_chroma_description_t *dsc = vlc_fourcc_GetChromaDescription( fmt.i_chroma );
448             for( unsigned int i = 0; dsc && i < dsc->plane_count; i++ )
449             {
450                 while( fmt.i_width % dsc->p[i].w.den )
451                     fmt.i_width++;
452                 while( fmt.i_height % dsc->p[i].h.den )
453                     fmt.i_height++;
454             }
455         }
456 
457         if( !fmt.i_visible_width || !fmt.i_visible_height )
458         {
459             if( p_dec->fmt_in.video.i_visible_width &&
460                 p_dec->fmt_in.video.i_visible_height )
461             {
462                 fmt.i_visible_width  = p_dec->fmt_in.video.i_visible_width;
463                 fmt.i_visible_height = p_dec->fmt_in.video.i_visible_height;
464                 fmt.i_x_offset       = p_dec->fmt_in.video.i_x_offset;
465                 fmt.i_y_offset       = p_dec->fmt_in.video.i_y_offset;
466             }
467             else
468             {
469                 fmt.i_visible_width  = fmt.i_width;
470                 fmt.i_visible_height = fmt.i_height;
471                 fmt.i_x_offset       = 0;
472                 fmt.i_y_offset       = 0;
473             }
474         }
475 
476         if( fmt.i_visible_height == 1088 &&
477             var_CreateGetBool( p_dec, "hdtv-fix" ) )
478         {
479             fmt.i_visible_height = 1080;
480             if( !(fmt.i_sar_num % 136))
481             {
482                 fmt.i_sar_num *= 135;
483                 fmt.i_sar_den *= 136;
484             }
485             msg_Warn( p_dec, "Fixing broken HDTV stream (display_height=1088)");
486         }
487 
488         if( !fmt.i_sar_num || !fmt.i_sar_den )
489         {
490             fmt.i_sar_num = 1;
491             fmt.i_sar_den = 1;
492         }
493 
494         vlc_ureduce( &fmt.i_sar_num, &fmt.i_sar_den,
495                      fmt.i_sar_num, fmt.i_sar_den, 50000 );
496 
497         video_format_AdjustColorSpace( &fmt );
498 
499         vlc_mutex_lock( &p_owner->lock );
500 
501         p_vout = p_owner->p_vout;
502         p_owner->p_vout = NULL;
503         vlc_mutex_unlock( &p_owner->lock );
504 
505         unsigned dpb_size;
506         switch( p_dec->fmt_in.i_codec )
507         {
508         case VLC_CODEC_HEVC:
509         case VLC_CODEC_H264:
510         case VLC_CODEC_DIRAC: /* FIXME valid ? */
511             dpb_size = 18;
512             break;
513         case VLC_CODEC_VP5:
514         case VLC_CODEC_VP6:
515         case VLC_CODEC_VP6F:
516         case VLC_CODEC_VP8:
517             dpb_size = 3;
518             break;
519         default:
520             dpb_size = 2;
521             break;
522         }
523         p_vout = input_resource_RequestVout( p_owner->p_resource,
524                                              p_vout, &fmt,
525                                              dpb_size +
526                                              p_dec->i_extra_picture_buffers + 1,
527                                              true );
528         vlc_mutex_lock( &p_owner->lock );
529         p_owner->p_vout = p_vout;
530 
531         DecoderUpdateFormatLocked( p_dec );
532         p_owner->fmt.video.i_chroma = p_dec->fmt_out.i_codec;
533         vlc_mutex_unlock( &p_owner->lock );
534 
535         if( p_owner->p_input != NULL )
536             input_SendEventVout( p_owner->p_input );
537         if( p_vout == NULL )
538         {
539             msg_Err( p_dec, "failed to create video output" );
540             return -1;
541         }
542     }
543 
544     if ( memcmp( &p_dec->fmt_out.video.mastering,
545                  &p_owner->fmt.video.mastering,
546                  sizeof(p_owner->fmt.video.mastering)) ||
547          p_dec->fmt_out.video.lighting.MaxCLL !=
548          p_owner->fmt.video.lighting.MaxCLL ||
549          p_dec->fmt_out.video.lighting.MaxFALL !=
550          p_owner->fmt.video.lighting.MaxFALL)
551     {
552         /* the format has changed but we don't need a new vout */
553         vlc_mutex_lock( &p_owner->lock );
554         DecoderUpdateFormatLocked( p_dec );
555         vlc_mutex_unlock( &p_owner->lock );
556     }
557     return 0;
558 }
559 
vout_new_buffer(decoder_t * p_dec)560 static picture_t *vout_new_buffer( decoder_t *p_dec )
561 {
562     decoder_owner_sys_t *p_owner = p_dec->p_owner;
563     assert( p_owner->p_vout );
564 
565     return vout_GetPicture( p_owner->p_vout );
566 }
567 
spu_new_buffer(decoder_t * p_dec,const subpicture_updater_t * p_updater)568 static subpicture_t *spu_new_buffer( decoder_t *p_dec,
569                                      const subpicture_updater_t *p_updater )
570 {
571     decoder_owner_sys_t *p_owner = p_dec->p_owner;
572     vout_thread_t *p_vout = NULL;
573     subpicture_t *p_subpic;
574     int i_attempts = 30;
575 
576     while( i_attempts-- )
577     {
578         if( p_owner->error )
579             break;
580 
581         p_vout = input_resource_HoldVout( p_owner->p_resource );
582         if( p_vout )
583             break;
584 
585         msleep( DECODER_SPU_VOUT_WAIT_DURATION );
586     }
587 
588     if( !p_vout )
589     {
590         msg_Warn( p_dec, "no vout found, dropping subpicture" );
591         return NULL;
592     }
593 
594     if( p_owner->p_spu_vout != p_vout )
595     {
596         p_owner->i_spu_channel = vout_RegisterSubpictureChannel( p_vout );
597         p_owner->i_spu_order = 0;
598         p_owner->p_spu_vout = p_vout;
599     }
600 
601     p_subpic = subpicture_New( p_updater );
602     if( p_subpic )
603     {
604         p_subpic->i_channel = p_owner->i_spu_channel;
605         p_subpic->i_order = p_owner->i_spu_order++;
606         p_subpic->b_subtitle = true;
607     }
608 
609     vlc_object_release( p_vout );
610 
611     return p_subpic;
612 }
613 
DecoderGetInputAttachments(decoder_t * p_dec,input_attachment_t *** ppp_attachment,int * pi_attachment)614 static int DecoderGetInputAttachments( decoder_t *p_dec,
615                                        input_attachment_t ***ppp_attachment,
616                                        int *pi_attachment )
617 {
618     input_thread_t *p_input = p_dec->p_owner->p_input;
619 
620     if( unlikely(p_input == NULL) )
621         return VLC_ENOOBJ;
622     return input_Control( p_input, INPUT_GET_ATTACHMENTS,
623                           ppp_attachment, pi_attachment );
624 }
625 
DecoderGetDisplayDate(decoder_t * p_dec,mtime_t i_ts)626 static mtime_t DecoderGetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
627 {
628     decoder_owner_sys_t *p_owner = p_dec->p_owner;
629 
630     vlc_mutex_lock( &p_owner->lock );
631     if( p_owner->b_waiting || p_owner->paused )
632         i_ts = VLC_TS_INVALID;
633     vlc_mutex_unlock( &p_owner->lock );
634 
635     if( !p_owner->p_clock || i_ts <= VLC_TS_INVALID )
636         return i_ts;
637 
638     if( input_clock_ConvertTS( VLC_OBJECT(p_dec), p_owner->p_clock, NULL, &i_ts, NULL, INT64_MAX ) ) {
639         msg_Err(p_dec, "Could not get display date for timestamp %"PRId64"", i_ts);
640         return VLC_TS_INVALID;
641     }
642 
643     return i_ts;
644 }
645 
DecoderGetDisplayRate(decoder_t * p_dec)646 static int DecoderGetDisplayRate( decoder_t *p_dec )
647 {
648     decoder_owner_sys_t *p_owner = p_dec->p_owner;
649 
650     if( !p_owner->p_clock )
651         return INPUT_RATE_DEFAULT;
652     return input_clock_GetRate( p_owner->p_clock );
653 }
654 
655 /*****************************************************************************
656  * Public functions
657  *****************************************************************************/
decoder_NewAudioBuffer(decoder_t * dec,int samples)658 block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples )
659 {
660     assert( dec->fmt_out.audio.i_frame_length > 0
661          && dec->fmt_out.audio.i_bytes_per_frame  > 0 );
662 
663     size_t length = samples * dec->fmt_out.audio.i_bytes_per_frame
664                             / dec->fmt_out.audio.i_frame_length;
665     block_t *block = block_Alloc( length );
666     if( likely(block != NULL) )
667     {
668         block->i_nb_samples = samples;
669         block->i_pts = block->i_length = 0;
670     }
671     return block;
672 }
673 
decoder_NewSubpicture(decoder_t * p_decoder,const subpicture_updater_t * p_dyn)674 subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
675                                      const subpicture_updater_t *p_dyn )
676 {
677     subpicture_t *p_subpicture = p_decoder->pf_spu_buffer_new( p_decoder, p_dyn );
678     if( !p_subpicture )
679         msg_Warn( p_decoder, "can't get output subpicture" );
680     return p_subpicture;
681 }
682 
RequestReload(decoder_t * p_dec)683 static void RequestReload( decoder_t * p_dec )
684 {
685     decoder_owner_sys_t *p_owner = p_dec->p_owner;
686     /* Don't override reload if it's RELOAD_DECODER_AOUT */
687     int expected = RELOAD_NO_REQUEST;
688     atomic_compare_exchange_strong( &p_owner->reload, &expected, RELOAD_DECODER );
689 }
690 
691 /* decoder_GetInputAttachments:
692  */
decoder_GetInputAttachments(decoder_t * p_dec,input_attachment_t *** ppp_attachment,int * pi_attachment)693 int decoder_GetInputAttachments( decoder_t *p_dec,
694                                  input_attachment_t ***ppp_attachment,
695                                  int *pi_attachment )
696 {
697     if( !p_dec->pf_get_attachments )
698         return VLC_EGENERIC;
699 
700     return p_dec->pf_get_attachments( p_dec, ppp_attachment, pi_attachment );
701 }
702 /* decoder_GetDisplayDate:
703  */
decoder_GetDisplayDate(decoder_t * p_dec,mtime_t i_ts)704 mtime_t decoder_GetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
705 {
706     if( !p_dec->pf_get_display_date )
707         return VLC_TS_INVALID;
708 
709     return p_dec->pf_get_display_date( p_dec, i_ts );
710 }
711 /* decoder_GetDisplayRate:
712  */
decoder_GetDisplayRate(decoder_t * p_dec)713 int decoder_GetDisplayRate( decoder_t *p_dec )
714 {
715     if( !p_dec->pf_get_display_rate )
716         return INPUT_RATE_DEFAULT;
717 
718     return p_dec->pf_get_display_rate( p_dec );
719 }
720 
decoder_AbortPictures(decoder_t * p_dec,bool b_abort)721 void decoder_AbortPictures( decoder_t *p_dec, bool b_abort )
722 {
723     decoder_owner_sys_t *p_owner = p_dec->p_owner;
724 
725     vlc_mutex_lock( &p_owner->lock );
726     if( p_owner->p_vout != NULL )
727         vout_Cancel( p_owner->p_vout, b_abort );
728     vlc_mutex_unlock( &p_owner->lock );
729 }
730 
DecoderWaitUnblock(decoder_t * p_dec)731 static void DecoderWaitUnblock( decoder_t *p_dec )
732 {
733     decoder_owner_sys_t *p_owner = p_dec->p_owner;
734 
735     vlc_assert_locked( &p_owner->lock );
736 
737     for( ;; )
738     {
739         if( !p_owner->b_waiting || !p_owner->b_has_data )
740             break;
741         vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
742     }
743 }
744 
745 /* DecoderTimedWait: Interruptible wait
746  * Returns VLC_SUCCESS if wait was not interrupted, and VLC_EGENERIC otherwise */
DecoderTimedWait(decoder_t * p_dec,mtime_t deadline)747 static int DecoderTimedWait( decoder_t *p_dec, mtime_t deadline )
748 {
749     decoder_owner_sys_t *p_owner = p_dec->p_owner;
750 
751     if (deadline - mdate() <= 0)
752         return VLC_SUCCESS;
753 
754     vlc_fifo_Lock( p_owner->p_fifo );
755     while( !p_owner->flushing
756         && vlc_fifo_TimedWaitCond( p_owner->p_fifo, &p_owner->wait_timed,
757                                    deadline ) == 0 );
758     int ret = p_owner->flushing ? VLC_EGENERIC : VLC_SUCCESS;
759     vlc_fifo_Unlock( p_owner->p_fifo );
760     return ret;
761 }
762 
DecoderUpdatePreroll(int64_t * pi_preroll,const block_t * p)763 static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
764 {
765     if( p->i_flags & BLOCK_FLAG_PREROLL )
766         *pi_preroll = INT64_MAX;
767     /* Check if we can use the packet for end of preroll */
768     else if( (p->i_flags & BLOCK_FLAG_DISCONTINUITY) &&
769              (p->i_buffer == 0 || (p->i_flags & BLOCK_FLAG_CORRUPTED)) )
770         *pi_preroll = INT64_MAX;
771     else if( p->i_dts > VLC_TS_INVALID )
772         *pi_preroll = __MIN( *pi_preroll, p->i_dts );
773     else if( p->i_pts > VLC_TS_INVALID )
774         *pi_preroll = __MIN( *pi_preroll, p->i_pts );
775 }
776 
DecoderFixTs(decoder_t * p_dec,mtime_t * pi_ts0,mtime_t * pi_ts1,mtime_t * pi_duration,int * pi_rate,mtime_t i_ts_bound)777 static void DecoderFixTs( decoder_t *p_dec, mtime_t *pi_ts0, mtime_t *pi_ts1,
778                           mtime_t *pi_duration, int *pi_rate, mtime_t i_ts_bound )
779 {
780     decoder_owner_sys_t *p_owner = p_dec->p_owner;
781     input_clock_t   *p_clock = p_owner->p_clock;
782 
783     vlc_assert_locked( &p_owner->lock );
784 
785     const mtime_t i_es_delay = p_owner->i_ts_delay;
786 
787     if( !p_clock )
788         return;
789 
790     const bool b_ephemere = pi_ts1 && *pi_ts0 == *pi_ts1;
791     int i_rate;
792 
793     if( *pi_ts0 > VLC_TS_INVALID )
794     {
795         *pi_ts0 += i_es_delay;
796         if( pi_ts1 && *pi_ts1 > VLC_TS_INVALID )
797             *pi_ts1 += i_es_delay;
798         if( i_ts_bound != INT64_MAX )
799             i_ts_bound += i_es_delay;
800         if( input_clock_ConvertTS( VLC_OBJECT(p_dec), p_clock, &i_rate, pi_ts0, pi_ts1, i_ts_bound ) ) {
801             const char *psz_name = module_get_name( p_dec->p_module, false );
802             if( pi_ts1 != NULL )
803                 msg_Err(p_dec, "Could not convert timestamps %"PRId64
804                         ", %"PRId64" for %s", *pi_ts0, *pi_ts1, psz_name );
805             else
806                 msg_Err(p_dec, "Could not convert timestamp %"PRId64" for %s", *pi_ts0, psz_name );
807             *pi_ts0 = VLC_TS_INVALID;
808         }
809     }
810     else
811     {
812         i_rate = input_clock_GetRate( p_clock );
813     }
814 
815     /* Do not create ephemere data because of rounding errors */
816     if( !b_ephemere && pi_ts1 && *pi_ts0 == *pi_ts1 )
817         *pi_ts1 += 1;
818 
819     if( pi_duration )
820         *pi_duration = ( *pi_duration * i_rate + INPUT_RATE_DEFAULT-1 )
821             / INPUT_RATE_DEFAULT;
822 
823     if( pi_rate )
824         *pi_rate = i_rate;
825 }
826 
827 #ifdef ENABLE_SOUT
DecoderPlaySout(decoder_t * p_dec,block_t * p_sout_block)828 static int DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block )
829 {
830     decoder_owner_sys_t *p_owner = p_dec->p_owner;
831 
832     assert( p_owner->p_clock );
833     assert( !p_sout_block->p_next );
834 
835     vlc_mutex_lock( &p_owner->lock );
836 
837     if( p_owner->b_waiting )
838     {
839         p_owner->b_has_data = true;
840         vlc_cond_signal( &p_owner->wait_acknowledge );
841     }
842 
843     DecoderWaitUnblock( p_dec );
844     DecoderFixTs( p_dec, &p_sout_block->i_dts, &p_sout_block->i_pts,
845                   &p_sout_block->i_length, NULL, INT64_MAX );
846 
847     vlc_mutex_unlock( &p_owner->lock );
848 
849     /* FIXME --VLC_TS_INVALID inspect stream_output*/
850     return sout_InputSendBuffer( p_owner->p_sout_input, p_sout_block );
851 }
852 
853 /* This function process a block for sout
854  */
DecoderProcessSout(decoder_t * p_dec,block_t * p_block)855 static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block )
856 {
857     decoder_owner_sys_t *p_owner = p_dec->p_owner;
858     block_t *p_sout_block;
859     block_t **pp_block = p_block ? &p_block : NULL;
860 
861     while( ( p_sout_block =
862                  p_dec->pf_packetize( p_dec, pp_block ) ) )
863     {
864         if( p_owner->p_sout_input == NULL )
865         {
866             vlc_mutex_lock( &p_owner->lock );
867             DecoderUpdateFormatLocked( p_dec );
868 
869             p_owner->fmt.i_group = p_dec->fmt_in.i_group;
870             p_owner->fmt.i_id = p_dec->fmt_in.i_id;
871             if( p_dec->fmt_in.psz_language )
872             {
873                 free( p_owner->fmt.psz_language );
874                 p_owner->fmt.psz_language =
875                     strdup( p_dec->fmt_in.psz_language );
876             }
877             vlc_mutex_unlock( &p_owner->lock );
878 
879             p_owner->p_sout_input =
880                 sout_InputNew( p_owner->p_sout, &p_owner->fmt );
881 
882             if( p_owner->p_sout_input == NULL )
883             {
884                 msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
885                          (char *)&p_owner->fmt.i_codec );
886                 p_owner->error = true;
887 
888                 if(p_block)
889                     block_Release(p_block);
890 
891                 block_ChainRelease(p_sout_block);
892                 break;
893             }
894         }
895 
896         while( p_sout_block )
897         {
898             block_t *p_next = p_sout_block->p_next;
899 
900             p_sout_block->p_next = NULL;
901 
902             if( DecoderPlaySout( p_dec, p_sout_block ) == VLC_EGENERIC )
903             {
904                 msg_Err( p_dec, "cannot continue streaming due to errors with codec %4.4s",
905                                 (char *)&p_owner->fmt.i_codec );
906 
907                 p_owner->error = true;
908 
909                 /* Cleanup */
910 
911                 if( p_block )
912                     block_Release( p_block );
913 
914                 block_ChainRelease( p_next );
915                 return;
916             }
917 
918             p_sout_block = p_next;
919         }
920     }
921 }
922 #endif
923 
DecoderPlayCc(decoder_t * p_dec,block_t * p_cc,const decoder_cc_desc_t * p_desc)924 static void DecoderPlayCc( decoder_t *p_dec, block_t *p_cc,
925                            const decoder_cc_desc_t *p_desc )
926 {
927     decoder_owner_sys_t *p_owner = p_dec->p_owner;
928 
929     vlc_mutex_lock( &p_owner->lock );
930 
931     p_owner->cc.desc = *p_desc;
932 
933     /* Fanout data to all decoders. We do not know if es_out
934        selected 608 or 708. */
935     uint64_t i_bitmap = p_owner->cc.desc.i_608_channels |
936                         p_owner->cc.desc.i_708_channels;
937 
938     for( int i=0; i_bitmap > 0; i_bitmap >>= 1, i++ )
939     {
940         decoder_t *p_ccdec = p_owner->cc.pp_decoder[i];
941         if( !p_ccdec )
942             continue;
943 
944         if( i_bitmap > 1 )
945         {
946             block_FifoPut( p_ccdec->p_owner->p_fifo, block_Duplicate(p_cc) );
947         }
948         else
949         {
950             block_FifoPut( p_ccdec->p_owner->p_fifo, p_cc );
951             p_cc = NULL; /* was last dec */
952         }
953     }
954 
955     vlc_mutex_unlock( &p_owner->lock );
956 
957     if( p_cc ) /* can have bitmap set but no created decs */
958         block_Release( p_cc );
959 }
960 
PacketizerGetCc(decoder_t * p_dec,decoder_t * p_dec_cc)961 static void PacketizerGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
962 {
963     decoder_owner_sys_t *p_owner = p_dec->p_owner;
964     block_t *p_cc;
965     decoder_cc_desc_t desc;
966 
967     /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
968     if( !p_owner->cc.b_supported )
969         return;
970 
971     assert( p_dec_cc->pf_get_cc != NULL );
972 
973     p_cc = p_dec_cc->pf_get_cc( p_dec_cc, &desc );
974     if( !p_cc )
975         return;
976     DecoderPlayCc( p_dec, p_cc, &desc );
977 }
978 
DecoderQueueCc(decoder_t * p_videodec,block_t * p_cc,const decoder_cc_desc_t * p_desc)979 static int DecoderQueueCc( decoder_t *p_videodec, block_t *p_cc,
980                            const decoder_cc_desc_t *p_desc )
981 {
982     decoder_owner_sys_t *p_owner = p_videodec->p_owner;
983 
984     if( unlikely( p_cc != NULL ) )
985     {
986         if( p_owner->cc.b_supported &&
987            ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
988             DecoderPlayCc( p_videodec, p_cc, p_desc );
989         else
990             block_Release( p_cc );
991     }
992     return 0;
993 }
994 
DecoderPlayVideo(decoder_t * p_dec,picture_t * p_picture,unsigned * restrict pi_lost_sum)995 static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
996                              unsigned *restrict pi_lost_sum )
997 {
998     decoder_owner_sys_t *p_owner = p_dec->p_owner;
999     vout_thread_t  *p_vout = p_owner->p_vout;
1000     bool prerolled;
1001 
1002     vlc_mutex_lock( &p_owner->lock );
1003     if( p_owner->i_preroll_end > p_picture->date )
1004     {
1005         vlc_mutex_unlock( &p_owner->lock );
1006         picture_Release( p_picture );
1007         return -1;
1008     }
1009 
1010     prerolled = p_owner->i_preroll_end > INT64_MIN;
1011     p_owner->i_preroll_end = INT64_MIN;
1012     vlc_mutex_unlock( &p_owner->lock );
1013 
1014     if( unlikely(prerolled) )
1015     {
1016         msg_Dbg( p_dec, "end of video preroll" );
1017 
1018         if( p_vout )
1019             vout_Flush( p_vout, VLC_TS_INVALID+1 );
1020     }
1021 
1022     if( p_picture->date <= VLC_TS_INVALID )
1023     {
1024         msg_Warn( p_dec, "non-dated video buffer received" );
1025         goto discard;
1026     }
1027 
1028     /* */
1029     vlc_mutex_lock( &p_owner->lock );
1030 
1031     if( p_owner->b_waiting && !p_owner->b_first )
1032     {
1033         p_owner->b_has_data = true;
1034         vlc_cond_signal( &p_owner->wait_acknowledge );
1035     }
1036     bool b_first_after_wait = p_owner->b_waiting && p_owner->b_has_data;
1037 
1038     DecoderWaitUnblock( p_dec );
1039 
1040     if( p_owner->b_waiting )
1041     {
1042         assert( p_owner->b_first );
1043         msg_Dbg( p_dec, "Received first picture" );
1044         p_owner->b_first = false;
1045         p_picture->b_force = true;
1046     }
1047 
1048     const bool b_dated = p_picture->date > VLC_TS_INVALID;
1049     int i_rate = INPUT_RATE_DEFAULT;
1050     DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
1051                   &i_rate, DECODER_BOGUS_VIDEO_DELAY );
1052 
1053     vlc_mutex_unlock( &p_owner->lock );
1054 
1055     /* FIXME: The *input* FIFO should not be locked here. This will not work
1056      * properly if/when pictures are queued asynchronously. */
1057     vlc_fifo_Lock( p_owner->p_fifo );
1058     if( unlikely(p_owner->paused) && likely(p_owner->frames_countdown > 0) )
1059         p_owner->frames_countdown--;
1060     vlc_fifo_Unlock( p_owner->p_fifo );
1061 
1062     /* */
1063     if( p_vout == NULL )
1064         goto discard;
1065 
1066     if( p_picture->b_force || p_picture->date > VLC_TS_INVALID )
1067         /* FIXME: VLC_TS_INVALID -- verify video_output */
1068     {
1069         if( i_rate != p_owner->i_last_rate || b_first_after_wait )
1070         {
1071             /* Be sure to not display old picture after our own */
1072             vout_Flush( p_vout, p_picture->date );
1073             p_owner->i_last_rate = i_rate;
1074         }
1075         vout_PutPicture( p_vout, p_picture );
1076     }
1077     else
1078     {
1079         if( b_dated )
1080             msg_Warn( p_dec, "early picture skipped" );
1081         else
1082             msg_Warn( p_dec, "non-dated video buffer received" );
1083         goto discard;
1084     }
1085 
1086     return 0;
1087 discard:
1088     *pi_lost_sum += 1;
1089     picture_Release( p_picture );
1090     return 0;
1091 }
1092 
DecoderUpdateStatVideo(decoder_owner_sys_t * p_owner,unsigned decoded,unsigned lost)1093 static void DecoderUpdateStatVideo( decoder_owner_sys_t *p_owner,
1094                                     unsigned decoded, unsigned lost )
1095 {
1096     input_thread_t *p_input = p_owner->p_input;
1097     unsigned displayed = 0;
1098 
1099     /* Update ugly stat */
1100     if( p_input == NULL )
1101         return;
1102 
1103     if( p_owner->p_vout != NULL )
1104     {
1105         unsigned vout_lost = 0;
1106 
1107         vout_GetResetStatistic( p_owner->p_vout, &displayed, &vout_lost );
1108         lost += vout_lost;
1109     }
1110 
1111     vlc_mutex_lock( &input_priv(p_input)->counters.counters_lock );
1112     stats_Update( input_priv(p_input)->counters.p_decoded_video, decoded, NULL );
1113     stats_Update( input_priv(p_input)->counters.p_lost_pictures, lost , NULL);
1114     stats_Update( input_priv(p_input)->counters.p_displayed_pictures, displayed, NULL);
1115     vlc_mutex_unlock( &input_priv(p_input)->counters.counters_lock );
1116 }
1117 
DecoderQueueVideo(decoder_t * p_dec,picture_t * p_pic)1118 static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic )
1119 {
1120     assert( p_pic );
1121     unsigned i_lost = 0;
1122     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1123 
1124     int ret = DecoderPlayVideo( p_dec, p_pic, &i_lost );
1125 
1126     p_owner->pf_update_stat( p_owner, 1, i_lost );
1127     return ret;
1128 }
1129 
DecoderPlayAudio(decoder_t * p_dec,block_t * p_audio,unsigned * restrict pi_lost_sum)1130 static int DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
1131                              unsigned *restrict pi_lost_sum )
1132 {
1133     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1134     bool prerolled;
1135 
1136     assert( p_audio != NULL );
1137 
1138     vlc_mutex_lock( &p_owner->lock );
1139     if( p_owner->i_preroll_end > p_audio->i_pts )
1140     {
1141         vlc_mutex_unlock( &p_owner->lock );
1142         block_Release( p_audio );
1143         return -1;
1144     }
1145 
1146     prerolled = p_owner->i_preroll_end > INT64_MIN;
1147     p_owner->i_preroll_end = INT64_MIN;
1148     vlc_mutex_unlock( &p_owner->lock );
1149 
1150     if( unlikely(prerolled) )
1151     {
1152         msg_Dbg( p_dec, "end of audio preroll" );
1153 
1154         if( p_owner->p_aout )
1155             aout_DecFlush( p_owner->p_aout, false );
1156     }
1157 
1158     /* */
1159     if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
1160     {
1161         msg_Warn( p_dec, "non-dated audio buffer received" );
1162         *pi_lost_sum += 1;
1163         block_Release( p_audio );
1164         return 0;
1165     }
1166 
1167     /* */
1168     vlc_mutex_lock( &p_owner->lock );
1169     if( p_owner->b_waiting )
1170     {
1171         p_owner->b_has_data = true;
1172         vlc_cond_signal( &p_owner->wait_acknowledge );
1173     }
1174 
1175     /* */
1176     int i_rate = INPUT_RATE_DEFAULT;
1177 
1178     DecoderWaitUnblock( p_dec );
1179     DecoderFixTs( p_dec, &p_audio->i_pts, NULL, &p_audio->i_length,
1180                   &i_rate, AOUT_MAX_ADVANCE_TIME );
1181     vlc_mutex_unlock( &p_owner->lock );
1182 
1183     audio_output_t *p_aout = p_owner->p_aout;
1184 
1185     if( p_aout != NULL && p_audio->i_pts > VLC_TS_INVALID
1186      && i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE
1187      && i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE
1188      && !DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME ) )
1189     {
1190         int status = aout_DecPlay( p_aout, p_audio, i_rate );
1191         if( status == AOUT_DEC_CHANGED )
1192         {
1193             /* Only reload the decoder */
1194             RequestReload( p_dec );
1195         }
1196         else if( status == AOUT_DEC_FAILED )
1197         {
1198             /* If we reload because the aout failed, we should release it. That
1199              * way, a next call to aout_update_format() won't re-use the
1200              * previous (failing) aout but will try to create a new one. */
1201             atomic_store( &p_owner->reload, RELOAD_DECODER_AOUT );
1202         }
1203     }
1204     else
1205     {
1206         msg_Dbg( p_dec, "discarded audio buffer" );
1207         *pi_lost_sum += 1;
1208         block_Release( p_audio );
1209     }
1210     return 0;
1211 }
1212 
DecoderUpdateStatAudio(decoder_owner_sys_t * p_owner,unsigned decoded,unsigned lost)1213 static void DecoderUpdateStatAudio( decoder_owner_sys_t *p_owner,
1214                                     unsigned decoded, unsigned lost )
1215 {
1216     input_thread_t *p_input = p_owner->p_input;
1217     unsigned played = 0;
1218 
1219     /* Update ugly stat */
1220     if( p_input == NULL )
1221         return;
1222 
1223     if( p_owner->p_aout != NULL )
1224     {
1225         unsigned aout_lost;
1226 
1227         aout_DecGetResetStats( p_owner->p_aout, &aout_lost, &played );
1228         lost += aout_lost;
1229     }
1230 
1231     vlc_mutex_lock( &input_priv(p_input)->counters.counters_lock);
1232     stats_Update( input_priv(p_input)->counters.p_lost_abuffers, lost, NULL );
1233     stats_Update( input_priv(p_input)->counters.p_played_abuffers, played, NULL );
1234     stats_Update( input_priv(p_input)->counters.p_decoded_audio, decoded, NULL );
1235     vlc_mutex_unlock( &input_priv(p_input)->counters.counters_lock);
1236 }
1237 
DecoderQueueAudio(decoder_t * p_dec,block_t * p_aout_buf)1238 static int DecoderQueueAudio( decoder_t *p_dec, block_t *p_aout_buf )
1239 {
1240     unsigned lost = 0;
1241     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1242 
1243     int ret = DecoderPlayAudio( p_dec, p_aout_buf, &lost );
1244 
1245     p_owner->pf_update_stat( p_owner, 1, lost );
1246 
1247     return ret;
1248 }
1249 
DecoderPlaySpu(decoder_t * p_dec,subpicture_t * p_subpic)1250 static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
1251 {
1252     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1253     vout_thread_t *p_vout = p_owner->p_spu_vout;
1254 
1255     /* */
1256     if( p_subpic->i_start <= VLC_TS_INVALID )
1257     {
1258         msg_Warn( p_dec, "non-dated spu buffer received" );
1259         subpicture_Delete( p_subpic );
1260         return;
1261     }
1262 
1263     /* */
1264     vlc_mutex_lock( &p_owner->lock );
1265 
1266     if( p_owner->b_waiting )
1267     {
1268         p_owner->b_has_data = true;
1269         vlc_cond_signal( &p_owner->wait_acknowledge );
1270     }
1271 
1272     DecoderWaitUnblock( p_dec );
1273     DecoderFixTs( p_dec, &p_subpic->i_start, &p_subpic->i_stop, NULL,
1274                   NULL, INT64_MAX );
1275     vlc_mutex_unlock( &p_owner->lock );
1276 
1277     if( p_subpic->i_start <= VLC_TS_INVALID
1278      || DecoderTimedWait( p_dec, p_subpic->i_start - SPU_MAX_PREPARE_TIME ) )
1279     {
1280         subpicture_Delete( p_subpic );
1281         return;
1282     }
1283 
1284     vout_PutSubpicture( p_vout, p_subpic );
1285 }
1286 
DecoderUpdateStatSpu(decoder_owner_sys_t * p_owner,unsigned decoded,unsigned lost)1287 static void DecoderUpdateStatSpu( decoder_owner_sys_t *p_owner,
1288                                   unsigned decoded, unsigned lost )
1289 {
1290     (void) p_owner; (void) decoded; (void) lost;
1291 }
1292 
DecoderQueueSpu(decoder_t * p_dec,subpicture_t * p_spu)1293 static int DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
1294 {
1295     assert( p_spu );
1296     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1297     input_thread_t *p_input = p_owner->p_input;
1298 
1299     if( p_input != NULL )
1300     {
1301         vlc_mutex_lock( &input_priv(p_input)->counters.counters_lock );
1302         stats_Update( input_priv(p_input)->counters.p_decoded_sub, 1, NULL );
1303         vlc_mutex_unlock( &input_priv(p_input)->counters.counters_lock );
1304     }
1305 
1306     int i_ret = -1;
1307     vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
1308     if( p_vout && p_owner->p_spu_vout == p_vout )
1309     {
1310         /* Preroll does not work very well with subtitle */
1311         vlc_mutex_lock( &p_owner->lock );
1312         if( p_spu->i_start > VLC_TS_INVALID &&
1313             p_spu->i_start < p_owner->i_preroll_end &&
1314             ( p_spu->i_stop <= VLC_TS_INVALID || p_spu->i_stop < p_owner->i_preroll_end ) )
1315         {
1316             vlc_mutex_unlock( &p_owner->lock );
1317             subpicture_Delete( p_spu );
1318         }
1319         else
1320         {
1321             vlc_mutex_unlock( &p_owner->lock );
1322             DecoderPlaySpu( p_dec, p_spu );
1323             i_ret = 0;
1324         }
1325     }
1326     else
1327     {
1328         subpicture_Delete( p_spu );
1329     }
1330     if( p_vout )
1331         vlc_object_release( p_vout );
1332     return i_ret;
1333 }
1334 
1335 static void DecoderProcess( decoder_t *p_dec, block_t *p_block );
DecoderDecode(decoder_t * p_dec,block_t * p_block)1336 static void DecoderDecode( decoder_t *p_dec, block_t *p_block )
1337 {
1338     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1339 
1340     int ret = p_dec->pf_decode( p_dec, p_block );
1341     switch( ret )
1342     {
1343         case VLCDEC_SUCCESS:
1344             p_owner->pf_update_stat( p_owner, 1, 0 );
1345             break;
1346         case VLCDEC_ECRITICAL:
1347             p_owner->error = true;
1348             break;
1349         case VLCDEC_RELOAD:
1350             RequestReload( p_dec );
1351             if( unlikely( p_block == NULL ) )
1352                 break;
1353             if( !( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
1354             {
1355                 p_block->i_flags |= BLOCK_FLAG_CORE_PRIVATE_RELOADED;
1356                 DecoderProcess( p_dec, p_block );
1357             }
1358             else /* We prefer loosing this block than an infinite recursion */
1359                 block_Release( p_block );
1360             break;
1361         default:
1362             vlc_assert_unreachable();
1363     }
1364 }
1365 
1366 /**
1367  * Decode a block
1368  *
1369  * \param p_dec the decoder object
1370  * \param p_block the block to decode
1371  */
DecoderProcess(decoder_t * p_dec,block_t * p_block)1372 static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
1373 {
1374     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1375 
1376     if( p_owner->error )
1377         goto error;
1378 
1379     /* Here, the atomic doesn't prevent to miss a reload request.
1380      * DecoderProcess() can still be called after the decoder module or the
1381      * audio output requested a reload. This will only result in a drop of an
1382      * input block or an output buffer. */
1383     enum reload reload;
1384     if( ( reload = atomic_exchange( &p_owner->reload, RELOAD_NO_REQUEST ) ) )
1385     {
1386         msg_Warn( p_dec, "Reloading the decoder module%s",
1387                   reload == RELOAD_DECODER_AOUT ? " and the audio output" : "" );
1388 
1389         if( ReloadDecoder( p_dec, false, &p_dec->fmt_in, reload ) != VLC_SUCCESS )
1390             goto error;
1391     }
1392 
1393     bool packetize = p_owner->p_packetizer != NULL;
1394     if( p_block )
1395     {
1396         if( p_block->i_buffer <= 0 )
1397             goto error;
1398 
1399         vlc_mutex_lock( &p_owner->lock );
1400         DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
1401         vlc_mutex_unlock( &p_owner->lock );
1402         if( unlikely( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
1403         {
1404             /* This block has already been packetized */
1405             packetize = false;
1406         }
1407     }
1408 
1409 #ifdef ENABLE_SOUT
1410     if( p_owner->p_sout != NULL )
1411     {
1412         DecoderProcessSout( p_dec, p_block );
1413         return;
1414     }
1415 #endif
1416     if( packetize )
1417     {
1418         block_t *p_packetized_block;
1419         block_t **pp_block = p_block ? &p_block : NULL;
1420         decoder_t *p_packetizer = p_owner->p_packetizer;
1421 
1422         while( (p_packetized_block =
1423                 p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
1424         {
1425             if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
1426             {
1427                 msg_Dbg( p_dec, "restarting module due to input format change");
1428 
1429                 /* Drain the decoder module */
1430                 DecoderDecode( p_dec, NULL );
1431 
1432                 if( ReloadDecoder( p_dec, false, &p_packetizer->fmt_out,
1433                                    RELOAD_DECODER ) != VLC_SUCCESS )
1434                 {
1435                     block_ChainRelease( p_packetized_block );
1436                     return;
1437                 }
1438             }
1439 
1440             if( p_packetizer->pf_get_cc )
1441                 PacketizerGetCc( p_dec, p_packetizer );
1442 
1443             while( p_packetized_block )
1444             {
1445                 block_t *p_next = p_packetized_block->p_next;
1446                 p_packetized_block->p_next = NULL;
1447 
1448                 DecoderDecode( p_dec, p_packetized_block );
1449                 if( p_owner->error )
1450                 {
1451                     block_ChainRelease( p_next );
1452                     return;
1453                 }
1454 
1455                 p_packetized_block = p_next;
1456             }
1457         }
1458         /* Drain the decoder after the packetizer is drained */
1459         if( !pp_block )
1460             DecoderDecode( p_dec, NULL );
1461     }
1462     else
1463         DecoderDecode( p_dec, p_block );
1464     return;
1465 
1466 error:
1467     if( p_block )
1468         block_Release( p_block );
1469 }
1470 
DecoderProcessFlush(decoder_t * p_dec)1471 static void DecoderProcessFlush( decoder_t *p_dec )
1472 {
1473     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1474     decoder_t *p_packetizer = p_owner->p_packetizer;
1475 
1476     if( p_owner->error )
1477         return;
1478 
1479     if( p_packetizer != NULL && p_packetizer->pf_flush != NULL )
1480         p_packetizer->pf_flush( p_packetizer );
1481 
1482     if ( p_dec->pf_flush != NULL )
1483         p_dec->pf_flush( p_dec );
1484 
1485     /* flush CC sub decoders */
1486     if( p_owner->cc.b_supported )
1487     {
1488         for( int i=0; i<MAX_CC_DECODERS; i++ )
1489         {
1490             decoder_t *p_subdec = p_owner->cc.pp_decoder[i];
1491             if( p_subdec && p_subdec->pf_flush )
1492                 p_subdec->pf_flush( p_subdec );
1493         }
1494     }
1495 
1496 #ifdef ENABLE_SOUT
1497     if ( p_owner->p_sout_input != NULL )
1498     {
1499         sout_InputFlush( p_owner->p_sout_input );
1500     }
1501 #endif
1502     if( p_dec->fmt_out.i_cat == AUDIO_ES )
1503     {
1504         if( p_owner->p_aout )
1505             aout_DecFlush( p_owner->p_aout, false );
1506     }
1507     else if( p_dec->fmt_out.i_cat == VIDEO_ES )
1508     {
1509         if( p_owner->p_vout )
1510             vout_Flush( p_owner->p_vout, VLC_TS_INVALID+1 );
1511     }
1512     else if( p_dec->fmt_out.i_cat == SPU_ES )
1513     {
1514         if( p_owner->p_spu_vout )
1515         {
1516             vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
1517 
1518             if( p_vout && p_owner->p_spu_vout == p_vout )
1519                 vout_FlushSubpictureChannel( p_vout, p_owner->i_spu_channel );
1520 
1521             if( p_vout )
1522                 vlc_object_release( p_vout );
1523         }
1524     }
1525 
1526     vlc_mutex_lock( &p_owner->lock );
1527     p_owner->i_preroll_end = INT64_MIN;
1528     vlc_mutex_unlock( &p_owner->lock );
1529 }
1530 
1531 /**
1532  * The decoding main loop
1533  *
1534  * \param p_dec the decoder
1535  */
DecoderThread(void * p_data)1536 static void *DecoderThread( void *p_data )
1537 {
1538     decoder_t *p_dec = (decoder_t *)p_data;
1539     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1540     bool paused = false;
1541 
1542     /* The decoder's main loop */
1543     vlc_fifo_Lock( p_owner->p_fifo );
1544     vlc_fifo_CleanupPush( p_owner->p_fifo );
1545 
1546     for( ;; )
1547     {
1548         if( p_owner->flushing )
1549         {   /* Flush before/regardless of pause. We do not want to resume just
1550              * for the sake of flushing (glitches could otherwise happen). */
1551             int canc = vlc_savecancel();
1552 
1553             vlc_fifo_Unlock( p_owner->p_fifo );
1554 
1555             /* Flush the decoder (and the output) */
1556             DecoderProcessFlush( p_dec );
1557 
1558             vlc_fifo_Lock( p_owner->p_fifo );
1559             vlc_restorecancel( canc );
1560 
1561             /* Reset flushing after DecoderProcess in case input_DecoderFlush
1562              * is called again. This will avoid a second useless flush (but
1563              * harmless). */
1564             p_owner->flushing = false;
1565 
1566             continue;
1567         }
1568 
1569         if( paused != p_owner->paused )
1570         {   /* Update playing/paused status of the output */
1571             int canc = vlc_savecancel();
1572             mtime_t date = p_owner->pause_date;
1573 
1574             paused = p_owner->paused;
1575             vlc_fifo_Unlock( p_owner->p_fifo );
1576 
1577             /* NOTE: Only the audio and video outputs care about pause. */
1578             msg_Dbg( p_dec, "toggling %s", paused ? "resume" : "pause" );
1579             if( p_owner->p_vout != NULL )
1580                 vout_ChangePause( p_owner->p_vout, paused, date );
1581             if( p_owner->p_aout != NULL )
1582                 aout_DecChangePause( p_owner->p_aout, paused, date );
1583 
1584             vlc_restorecancel( canc );
1585             vlc_fifo_Lock( p_owner->p_fifo );
1586             continue;
1587         }
1588 
1589         if( p_owner->paused && p_owner->frames_countdown == 0 )
1590         {   /* Wait for resumption from pause */
1591             p_owner->b_idle = true;
1592             vlc_cond_signal( &p_owner->wait_acknowledge );
1593             vlc_fifo_Wait( p_owner->p_fifo );
1594             p_owner->b_idle = false;
1595             continue;
1596         }
1597 
1598         vlc_cond_signal( &p_owner->wait_fifo );
1599         vlc_testcancel(); /* forced expedited cancellation in case of stop */
1600 
1601         block_t *p_block = vlc_fifo_DequeueUnlocked( p_owner->p_fifo );
1602         if( p_block == NULL )
1603         {
1604             if( likely(!p_owner->b_draining) )
1605             {   /* Wait for a block to decode (or a request to drain) */
1606                 p_owner->b_idle = true;
1607                 vlc_cond_signal( &p_owner->wait_acknowledge );
1608                 vlc_fifo_Wait( p_owner->p_fifo );
1609                 p_owner->b_idle = false;
1610                 continue;
1611             }
1612             /* We have emptied the FIFO and there is a pending request to
1613              * drain. Pass p_block = NULL to decoder just once. */
1614         }
1615 
1616         vlc_fifo_Unlock( p_owner->p_fifo );
1617 
1618         int canc = vlc_savecancel();
1619         DecoderProcess( p_dec, p_block );
1620 
1621         if( p_block == NULL )
1622         {   /* Draining: the decoder is drained and all decoded buffers are
1623              * queued to the output at this point. Now drain the output. */
1624             if( p_owner->p_aout != NULL )
1625                 aout_DecFlush( p_owner->p_aout, true );
1626         }
1627         vlc_restorecancel( canc );
1628 
1629         /* TODO? Wait for draining instead of polling. */
1630         vlc_mutex_lock( &p_owner->lock );
1631         if( p_owner->b_draining && (p_block == NULL) )
1632         {
1633             p_owner->b_draining = false;
1634             p_owner->drained = true;
1635         }
1636         vlc_fifo_Lock( p_owner->p_fifo );
1637         vlc_cond_signal( &p_owner->wait_acknowledge );
1638         vlc_mutex_unlock( &p_owner->lock );
1639     }
1640     vlc_cleanup_pop();
1641     vlc_assert_unreachable();
1642 }
1643 
1644 /**
1645  * Create a decoder object
1646  *
1647  * \param p_input the input thread
1648  * \param p_es the es descriptor
1649  * \param b_packetizer instead of a decoder
1650  * \return the decoder object
1651  */
CreateDecoder(vlc_object_t * p_parent,input_thread_t * p_input,const es_format_t * fmt,input_resource_t * p_resource,sout_instance_t * p_sout)1652 static decoder_t * CreateDecoder( vlc_object_t *p_parent,
1653                                   input_thread_t *p_input,
1654                                   const es_format_t *fmt,
1655                                   input_resource_t *p_resource,
1656                                   sout_instance_t *p_sout )
1657 {
1658     decoder_t *p_dec;
1659     decoder_owner_sys_t *p_owner;
1660 
1661     p_dec = vlc_custom_create( p_parent, sizeof( *p_dec ), "decoder" );
1662     if( p_dec == NULL )
1663         return NULL;
1664 
1665     /* Allocate our private structure for the decoder */
1666     p_dec->p_owner = p_owner = malloc( sizeof( decoder_owner_sys_t ) );
1667     if( unlikely(p_owner == NULL) )
1668     {
1669         vlc_object_release( p_dec );
1670         return NULL;
1671     }
1672     p_owner->i_preroll_end = INT64_MIN;
1673     p_owner->i_last_rate = INPUT_RATE_DEFAULT;
1674     p_owner->p_input = p_input;
1675     p_owner->p_resource = p_resource;
1676     p_owner->p_aout = NULL;
1677     p_owner->p_vout = NULL;
1678     p_owner->p_spu_vout = NULL;
1679     p_owner->i_spu_channel = 0;
1680     p_owner->i_spu_order = 0;
1681     p_owner->p_sout = p_sout;
1682     p_owner->p_sout_input = NULL;
1683     p_owner->p_packetizer = NULL;
1684 
1685     p_owner->b_fmt_description = false;
1686     p_owner->p_description = NULL;
1687 
1688     p_owner->paused = false;
1689     p_owner->pause_date = VLC_TS_INVALID;
1690     p_owner->frames_countdown = 0;
1691 
1692     p_owner->b_waiting = false;
1693     p_owner->b_first = true;
1694     p_owner->b_has_data = false;
1695 
1696     p_owner->error = false;
1697 
1698     p_owner->flushing = false;
1699     p_owner->b_draining = false;
1700     p_owner->drained = false;
1701     atomic_init( &p_owner->reload, RELOAD_NO_REQUEST );
1702     p_owner->b_idle = false;
1703 
1704     es_format_Init( &p_owner->fmt, fmt->i_cat, 0 );
1705 
1706     /* decoder fifo */
1707     p_owner->p_fifo = block_FifoNew();
1708     if( unlikely(p_owner->p_fifo == NULL) )
1709     {
1710         free( p_owner );
1711         vlc_object_release( p_dec );
1712         return NULL;
1713     }
1714 
1715     vlc_mutex_init( &p_owner->lock );
1716     vlc_cond_init( &p_owner->wait_request );
1717     vlc_cond_init( &p_owner->wait_acknowledge );
1718     vlc_cond_init( &p_owner->wait_fifo );
1719     vlc_cond_init( &p_owner->wait_timed );
1720 
1721     /* Set buffers allocation callbacks for the decoders */
1722     p_dec->pf_aout_format_update = aout_update_format;
1723     p_dec->pf_vout_format_update = vout_update_format;
1724     p_dec->pf_vout_buffer_new = vout_new_buffer;
1725     p_dec->pf_spu_buffer_new  = spu_new_buffer;
1726     /* */
1727     p_dec->pf_get_attachments  = DecoderGetInputAttachments;
1728     p_dec->pf_get_display_date = DecoderGetDisplayDate;
1729     p_dec->pf_get_display_rate = DecoderGetDisplayRate;
1730 
1731     /* Load a packetizer module if the input is not already packetized */
1732     if( p_sout == NULL && !fmt->b_packetized )
1733     {
1734         p_owner->p_packetizer =
1735             vlc_custom_create( p_parent, sizeof( decoder_t ), "packetizer" );
1736         if( p_owner->p_packetizer )
1737         {
1738             if( LoadDecoder( p_owner->p_packetizer, true, fmt ) )
1739             {
1740                 vlc_object_release( p_owner->p_packetizer );
1741                 p_owner->p_packetizer = NULL;
1742             }
1743             else
1744             {
1745                 p_owner->p_packetizer->fmt_out.b_packetized = true;
1746                 fmt = &p_owner->p_packetizer->fmt_out;
1747             }
1748         }
1749     }
1750 
1751     /* Find a suitable decoder/packetizer module */
1752     if( LoadDecoder( p_dec, p_sout != NULL, fmt ) )
1753         return p_dec;
1754 
1755     switch( p_dec->fmt_out.i_cat )
1756     {
1757         case VIDEO_ES:
1758             p_dec->pf_queue_video = DecoderQueueVideo;
1759             p_dec->pf_queue_cc = DecoderQueueCc;
1760             p_owner->pf_update_stat = DecoderUpdateStatVideo;
1761             break;
1762         case AUDIO_ES:
1763             p_dec->pf_queue_audio = DecoderQueueAudio;
1764             p_owner->pf_update_stat = DecoderUpdateStatAudio;
1765             break;
1766         case SPU_ES:
1767             p_dec->pf_queue_sub = DecoderQueueSpu;
1768             p_owner->pf_update_stat = DecoderUpdateStatSpu;
1769             break;
1770         default:
1771             msg_Err( p_dec, "unknown ES format" );
1772             UnloadDecoder( p_dec );
1773             return p_dec;
1774     }
1775     /* Copy ourself the input replay gain */
1776     if( fmt->i_cat == AUDIO_ES )
1777     {
1778         for( unsigned i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
1779         {
1780             if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
1781             {
1782                 p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
1783                 p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
1784             }
1785             if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
1786             {
1787                 p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
1788                 p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
1789             }
1790         }
1791     }
1792 
1793     /* */
1794     p_owner->cc.b_supported = ( p_sout == NULL );
1795 
1796     p_owner->cc.desc.i_608_channels = 0;
1797     p_owner->cc.desc.i_708_channels = 0;
1798     for( unsigned i = 0; i < MAX_CC_DECODERS; i++ )
1799         p_owner->cc.pp_decoder[i] = NULL;
1800     p_owner->i_ts_delay = 0;
1801     return p_dec;
1802 }
1803 
1804 /**
1805  * Destroys a decoder object
1806  *
1807  * \param p_dec the decoder object
1808  * \return nothing
1809  */
DeleteDecoder(decoder_t * p_dec)1810 static void DeleteDecoder( decoder_t * p_dec )
1811 {
1812     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1813 
1814     msg_Dbg( p_dec, "killing decoder fourcc `%4.4s'",
1815              (char*)&p_dec->fmt_in.i_codec );
1816 
1817     const bool b_flush_spu = p_dec->fmt_out.i_cat == SPU_ES;
1818     UnloadDecoder( p_dec );
1819 
1820     /* Free all packets still in the decoder fifo. */
1821     block_FifoRelease( p_owner->p_fifo );
1822 
1823     /* Cleanup */
1824     if( p_owner->p_aout )
1825     {
1826         /* TODO: REVISIT gap-less audio */
1827         aout_DecFlush( p_owner->p_aout, false );
1828         aout_DecDelete( p_owner->p_aout );
1829         input_resource_PutAout( p_owner->p_resource, p_owner->p_aout );
1830         if( p_owner->p_input != NULL )
1831             input_SendEventAout( p_owner->p_input );
1832     }
1833     if( p_owner->p_vout )
1834     {
1835         /* Reset the cancel state that was set before joining the decoder
1836          * thread */
1837         vout_Cancel( p_owner->p_vout, false );
1838 
1839         input_resource_RequestVout( p_owner->p_resource, p_owner->p_vout, NULL,
1840                                     0, true );
1841         if( p_owner->p_input != NULL )
1842             input_SendEventVout( p_owner->p_input );
1843     }
1844 
1845 #ifdef ENABLE_SOUT
1846     if( p_owner->p_sout_input )
1847     {
1848         sout_InputDelete( p_owner->p_sout_input );
1849     }
1850 #endif
1851     es_format_Clean( &p_owner->fmt );
1852 
1853     if( b_flush_spu )
1854     {
1855         vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
1856         if( p_vout )
1857         {
1858             if( p_owner->p_spu_vout == p_vout )
1859                 vout_FlushSubpictureChannel( p_vout, p_owner->i_spu_channel );
1860             vlc_object_release( p_vout );
1861         }
1862     }
1863 
1864     if( p_owner->p_description )
1865         vlc_meta_Delete( p_owner->p_description );
1866 
1867     if( p_owner->p_packetizer )
1868     {
1869         UnloadDecoder( p_owner->p_packetizer );
1870         vlc_object_release( p_owner->p_packetizer );
1871     }
1872 
1873     vlc_cond_destroy( &p_owner->wait_timed );
1874     vlc_cond_destroy( &p_owner->wait_fifo );
1875     vlc_cond_destroy( &p_owner->wait_acknowledge );
1876     vlc_cond_destroy( &p_owner->wait_request );
1877     vlc_mutex_destroy( &p_owner->lock );
1878 
1879     vlc_object_release( p_dec );
1880 
1881     free( p_owner );
1882 }
1883 
1884 /* */
DecoderUnsupportedCodec(decoder_t * p_dec,const es_format_t * fmt,bool b_decoding)1885 static void DecoderUnsupportedCodec( decoder_t *p_dec, const es_format_t *fmt, bool b_decoding )
1886 {
1887     if (fmt->i_codec != VLC_CODEC_UNKNOWN && fmt->i_codec) {
1888         const char *desc = vlc_fourcc_GetDescription(fmt->i_cat, fmt->i_codec);
1889         if (!desc || !*desc)
1890             desc = N_("No description for this codec");
1891         msg_Err( p_dec, "Codec `%4.4s' (%s) is not supported.", (char*)&fmt->i_codec, desc );
1892         vlc_dialog_display_error( p_dec, _("Codec not supported"),
1893             _("VLC could not decode the format \"%4.4s\" (%s)"),
1894             (char*)&fmt->i_codec, desc );
1895     } else if( b_decoding ){
1896         msg_Err( p_dec, "could not identify codec" );
1897         vlc_dialog_display_error( p_dec, _("Unidentified codec"),
1898             _("VLC could not identify the audio or video codec" ) );
1899     }
1900 }
1901 
1902 /* TODO: pass p_sout through p_resource? -- Courmisch */
decoder_New(vlc_object_t * p_parent,input_thread_t * p_input,const es_format_t * fmt,input_clock_t * p_clock,input_resource_t * p_resource,sout_instance_t * p_sout)1903 static decoder_t *decoder_New( vlc_object_t *p_parent, input_thread_t *p_input,
1904                                const es_format_t *fmt, input_clock_t *p_clock,
1905                                input_resource_t *p_resource,
1906                                sout_instance_t *p_sout  )
1907 {
1908     decoder_t *p_dec = NULL;
1909     const char *psz_type = p_sout ? N_("packetizer") : N_("decoder");
1910     int i_priority;
1911 
1912     /* Create the decoder configuration structure */
1913     p_dec = CreateDecoder( p_parent, p_input, fmt, p_resource, p_sout );
1914     if( p_dec == NULL )
1915     {
1916         msg_Err( p_parent, "could not create %s", psz_type );
1917         vlc_dialog_display_error( p_parent, _("Streaming / Transcoding failed"),
1918             _("VLC could not open the %s module."), vlc_gettext( psz_type ) );
1919         return NULL;
1920     }
1921 
1922     if( !p_dec->p_module )
1923     {
1924         DecoderUnsupportedCodec( p_dec, fmt, !p_sout );
1925 
1926         DeleteDecoder( p_dec );
1927         return NULL;
1928     }
1929 
1930     p_dec->p_owner->p_clock = p_clock;
1931     assert( p_dec->fmt_out.i_cat != UNKNOWN_ES );
1932 
1933     if( p_dec->fmt_out.i_cat == AUDIO_ES )
1934         i_priority = VLC_THREAD_PRIORITY_AUDIO;
1935     else
1936         i_priority = VLC_THREAD_PRIORITY_VIDEO;
1937 
1938     /* Spawn the decoder thread */
1939     if( vlc_clone( &p_dec->p_owner->thread, DecoderThread, p_dec, i_priority ) )
1940     {
1941         msg_Err( p_dec, "cannot spawn decoder thread" );
1942         DeleteDecoder( p_dec );
1943         return NULL;
1944     }
1945 
1946     return p_dec;
1947 }
1948 
1949 
1950 /**
1951  * Spawns a new decoder thread from the input thread
1952  *
1953  * \param p_input the input thread
1954  * \param p_es the es descriptor
1955  * \return the spawned decoder object
1956  */
input_DecoderNew(input_thread_t * p_input,es_format_t * fmt,input_clock_t * p_clock,sout_instance_t * p_sout)1957 decoder_t *input_DecoderNew( input_thread_t *p_input,
1958                              es_format_t *fmt, input_clock_t *p_clock,
1959                              sout_instance_t *p_sout  )
1960 {
1961     return decoder_New( VLC_OBJECT(p_input), p_input, fmt, p_clock,
1962                         input_priv(p_input)->p_resource, p_sout );
1963 }
1964 
1965 /**
1966  * Spawn a decoder thread outside of the input thread.
1967  */
input_DecoderCreate(vlc_object_t * p_parent,const es_format_t * fmt,input_resource_t * p_resource)1968 decoder_t *input_DecoderCreate( vlc_object_t *p_parent, const es_format_t *fmt,
1969                                 input_resource_t *p_resource )
1970 {
1971     return decoder_New( p_parent, NULL, fmt, NULL, p_resource, NULL );
1972 }
1973 
1974 
1975 /**
1976  * Kills a decoder thread and waits until it's finished
1977  *
1978  * \param p_input the input thread
1979  * \param p_es the es descriptor
1980  * \return nothing
1981  */
input_DecoderDelete(decoder_t * p_dec)1982 void input_DecoderDelete( decoder_t *p_dec )
1983 {
1984     decoder_owner_sys_t *p_owner = p_dec->p_owner;
1985 
1986     vlc_cancel( p_owner->thread );
1987 
1988     vlc_fifo_Lock( p_owner->p_fifo );
1989     /* Signal DecoderTimedWait */
1990     p_owner->flushing = true;
1991     vlc_cond_signal( &p_owner->wait_timed );
1992     vlc_fifo_Unlock( p_owner->p_fifo );
1993 
1994     /* Make sure we aren't waiting/decoding anymore */
1995     vlc_mutex_lock( &p_owner->lock );
1996     p_owner->b_waiting = false;
1997     vlc_cond_signal( &p_owner->wait_request );
1998 
1999     /* If the video output is paused or slow, or if the picture pool size was
2000      * under-estimated (e.g. greedy video filter, buggy decoder...), the
2001      * the picture pool may be empty, and the decoder thread or any decoder
2002      * module worker threads may be stuck waiting for free picture buffers.
2003      *
2004      * This unblocks the thread, allowing the decoder module to join all its
2005      * worker threads (if any) and the decoder thread to terminate. */
2006     if( p_owner->p_vout != NULL )
2007         vout_Cancel( p_owner->p_vout, true );
2008     vlc_mutex_unlock( &p_owner->lock );
2009 
2010     vlc_join( p_owner->thread, NULL );
2011 
2012     /* */
2013     if( p_dec->p_owner->cc.b_supported )
2014     {
2015         for( int i = 0; i < MAX_CC_DECODERS; i++ )
2016             input_DecoderSetCcState( p_dec, VLC_CODEC_CEA608, i, false );
2017     }
2018 
2019     /* Delete decoder */
2020     DeleteDecoder( p_dec );
2021 }
2022 
2023 /**
2024  * Put a block_t in the decoder's fifo.
2025  * Thread-safe w.r.t. the decoder. May be a cancellation point.
2026  *
2027  * \param p_dec the decoder object
2028  * \param p_block the data block
2029  */
input_DecoderDecode(decoder_t * p_dec,block_t * p_block,bool b_do_pace)2030 void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
2031 {
2032     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2033 
2034     vlc_fifo_Lock( p_owner->p_fifo );
2035     if( !b_do_pace )
2036     {
2037         /* FIXME: ideally we would check the time amount of data
2038          * in the FIFO instead of its size. */
2039         /* 400 MiB, i.e. ~ 50mb/s for 60s */
2040         if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )
2041         {
2042             msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
2043                       "consumed quickly enough), resetting fifo!" );
2044             block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2045             p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2046         }
2047     }
2048     else
2049     if( !p_owner->b_waiting )
2050     {   /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
2051          * Locking is not necessary as b_waiting is only read, not written by
2052          * the decoder thread. */
2053         while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
2054             vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_fifo );
2055     }
2056 
2057     vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
2058     vlc_fifo_Unlock( p_owner->p_fifo );
2059 }
2060 
input_DecoderIsEmpty(decoder_t * p_dec)2061 bool input_DecoderIsEmpty( decoder_t * p_dec )
2062 {
2063     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2064 
2065     assert( !p_owner->b_waiting );
2066 
2067     vlc_fifo_Lock( p_owner->p_fifo );
2068     if( !vlc_fifo_IsEmpty( p_dec->p_owner->p_fifo ) || p_owner->b_draining )
2069     {
2070         vlc_fifo_Unlock( p_owner->p_fifo );
2071         return false;
2072     }
2073     vlc_fifo_Unlock( p_owner->p_fifo );
2074 
2075     bool b_empty;
2076 
2077     vlc_mutex_lock( &p_owner->lock );
2078 #ifdef ENABLE_SOUT
2079     if( p_owner->p_sout_input != NULL )
2080         b_empty = sout_InputIsEmpty( p_owner->p_sout_input );
2081     else
2082 #endif
2083     if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->p_vout != NULL )
2084         b_empty = vout_IsEmpty( p_owner->p_vout );
2085     else if( p_owner->fmt.i_cat == AUDIO_ES )
2086         b_empty = !p_owner->b_draining || p_owner->drained;
2087     else
2088         b_empty = true; /* TODO subtitles support */
2089     vlc_mutex_unlock( &p_owner->lock );
2090 
2091     return b_empty;
2092 }
2093 
2094 /**
2095  * Signals that there are no further blocks to decode, and requests that the
2096  * decoder drain all pending buffers. This is used to ensure that all
2097  * intermediate buffers empty and no samples get lost at the end of the stream.
2098  *
2099  * @note The function does not actually wait for draining. It just signals that
2100  * draining should be performed once the decoder has emptied FIFO.
2101  */
input_DecoderDrain(decoder_t * p_dec)2102 void input_DecoderDrain( decoder_t *p_dec )
2103 {
2104     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2105 
2106     vlc_fifo_Lock( p_owner->p_fifo );
2107     p_owner->b_draining = true;
2108     vlc_fifo_Signal( p_owner->p_fifo );
2109     vlc_fifo_Unlock( p_owner->p_fifo );
2110 }
2111 
2112 /**
2113  * Requests that the decoder immediately discard all pending buffers.
2114  * This is useful when seeking or when deselecting a stream.
2115  */
input_DecoderFlush(decoder_t * p_dec)2116 void input_DecoderFlush( decoder_t *p_dec )
2117 {
2118     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2119 
2120     vlc_fifo_Lock( p_owner->p_fifo );
2121 
2122     /* Empty the fifo */
2123     block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2124 
2125     /* Don't need to wait for the DecoderThread to flush. Indeed, if called a
2126      * second time, this function will clear the FIFO again before anything was
2127      * dequeued by DecoderThread and there is no need to flush a second time in
2128      * a row. */
2129     p_owner->flushing = true;
2130 
2131     /* Flush video/spu decoder when paused: increment frames_countdown in order
2132      * to display one frame/subtitle */
2133     if( p_owner->paused
2134      && ( p_owner->fmt.i_cat == VIDEO_ES || p_owner->fmt.i_cat == SPU_ES )
2135      && p_owner->frames_countdown == 0 )
2136         p_owner->frames_countdown++;
2137 
2138     vlc_fifo_Signal( p_owner->p_fifo );
2139     vlc_cond_signal( &p_owner->wait_timed );
2140 
2141     vlc_fifo_Unlock( p_owner->p_fifo );
2142 }
2143 
input_DecoderGetCcDesc(decoder_t * p_dec,decoder_cc_desc_t * p_desc)2144 void input_DecoderGetCcDesc( decoder_t *p_dec, decoder_cc_desc_t *p_desc )
2145 {
2146     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2147 
2148     vlc_mutex_lock( &p_owner->lock );
2149     *p_desc = p_owner->cc.desc;
2150     vlc_mutex_unlock( &p_owner->lock );
2151 }
2152 
input_DecoderHasCCChanFlag(decoder_t * p_dec,vlc_fourcc_t codec,int i_channel)2153 static bool input_DecoderHasCCChanFlag( decoder_t *p_dec,
2154                                         vlc_fourcc_t codec, int i_channel )
2155 {
2156     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2157 
2158     int i_max_channels;
2159     uint64_t i_bitmap;
2160     if( codec == VLC_CODEC_CEA608 )
2161     {
2162         i_max_channels = 4;
2163         i_bitmap = p_owner->cc.desc.i_608_channels;
2164     }
2165     else if( codec == VLC_CODEC_CEA708 )
2166     {
2167         i_max_channels = 64;
2168         i_bitmap = p_owner->cc.desc.i_708_channels;
2169     }
2170     else return false;
2171 
2172     return ( i_channel >= 0 && i_channel < i_max_channels &&
2173              ( i_bitmap & ((uint64_t)1 << i_channel) ) );
2174 }
2175 
input_DecoderSetCcState(decoder_t * p_dec,vlc_fourcc_t codec,int i_channel,bool b_decode)2176 int input_DecoderSetCcState( decoder_t *p_dec, vlc_fourcc_t codec,
2177                              int i_channel, bool b_decode )
2178 {
2179     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2180 
2181     //msg_Warn( p_dec, "input_DecoderSetCcState: %d @%x", b_decode, i_channel );
2182 
2183     if( !input_DecoderHasCCChanFlag( p_dec, codec, i_channel ) )
2184         return VLC_EGENERIC;
2185 
2186     if( b_decode )
2187     {
2188         decoder_t *p_cc;
2189         es_format_t fmt;
2190 
2191         es_format_Init( &fmt, SPU_ES, codec );
2192         fmt.subs.cc.i_channel = i_channel;
2193         fmt.subs.cc.i_reorder_depth = p_owner->cc.desc.i_reorder_depth;
2194         p_cc = input_DecoderNew( p_owner->p_input, &fmt,
2195                               p_dec->p_owner->p_clock, p_owner->p_sout );
2196         if( !p_cc )
2197         {
2198             msg_Err( p_dec, "could not create decoder" );
2199             vlc_dialog_display_error( p_dec,
2200                 _("Streaming / Transcoding failed"), "%s",
2201                 _("VLC could not open the decoder module.") );
2202             return VLC_EGENERIC;
2203         }
2204         else if( !p_cc->p_module )
2205         {
2206             DecoderUnsupportedCodec( p_dec, &fmt, true );
2207             input_DecoderDelete(p_cc);
2208             return VLC_EGENERIC;
2209         }
2210         p_cc->p_owner->p_clock = p_owner->p_clock;
2211 
2212         vlc_mutex_lock( &p_owner->lock );
2213         p_owner->cc.pp_decoder[i_channel] = p_cc;
2214         vlc_mutex_unlock( &p_owner->lock );
2215     }
2216     else
2217     {
2218         decoder_t *p_cc;
2219 
2220         vlc_mutex_lock( &p_owner->lock );
2221         p_cc = p_owner->cc.pp_decoder[i_channel];
2222         p_owner->cc.pp_decoder[i_channel] = NULL;
2223         vlc_mutex_unlock( &p_owner->lock );
2224 
2225         if( p_cc )
2226             input_DecoderDelete(p_cc);
2227     }
2228     return VLC_SUCCESS;
2229 }
2230 
input_DecoderGetCcState(decoder_t * p_dec,vlc_fourcc_t codec,int i_channel,bool * pb_decode)2231 int input_DecoderGetCcState( decoder_t *p_dec, vlc_fourcc_t codec,
2232                              int i_channel, bool *pb_decode )
2233 {
2234     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2235 
2236     if( !input_DecoderHasCCChanFlag( p_dec, codec, i_channel ) )
2237         return VLC_EGENERIC;
2238 
2239     vlc_mutex_lock( &p_owner->lock );
2240     *pb_decode = p_owner->cc.pp_decoder[i_channel] != NULL;
2241     vlc_mutex_unlock( &p_owner->lock );
2242     return VLC_SUCCESS;
2243 }
2244 
input_DecoderChangePause(decoder_t * p_dec,bool b_paused,mtime_t i_date)2245 void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
2246 {
2247     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2248 
2249     /* Normally, p_owner->b_paused != b_paused here. But if a track is added
2250      * while the input is paused (e.g. add sub file), then b_paused is
2251      * (incorrectly) false. FIXME: This is a bug in the decoder owner. */
2252     vlc_fifo_Lock( p_owner->p_fifo );
2253     p_owner->paused = b_paused;
2254     p_owner->pause_date = i_date;
2255     p_owner->frames_countdown = 0;
2256     vlc_fifo_Signal( p_owner->p_fifo );
2257     vlc_fifo_Unlock( p_owner->p_fifo );
2258 }
2259 
input_DecoderChangeDelay(decoder_t * p_dec,mtime_t i_delay)2260 void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
2261 {
2262     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2263 
2264     vlc_mutex_lock( &p_owner->lock );
2265     p_owner->i_ts_delay = i_delay;
2266     vlc_mutex_unlock( &p_owner->lock );
2267 }
2268 
input_DecoderStartWait(decoder_t * p_dec)2269 void input_DecoderStartWait( decoder_t *p_dec )
2270 {
2271     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2272 
2273     assert( !p_owner->b_waiting );
2274 
2275     vlc_mutex_lock( &p_owner->lock );
2276     p_owner->b_first = true;
2277     p_owner->b_has_data = false;
2278     p_owner->b_waiting = true;
2279     vlc_cond_signal( &p_owner->wait_request );
2280     vlc_mutex_unlock( &p_owner->lock );
2281 }
2282 
input_DecoderStopWait(decoder_t * p_dec)2283 void input_DecoderStopWait( decoder_t *p_dec )
2284 {
2285     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2286 
2287     assert( p_owner->b_waiting );
2288 
2289     vlc_mutex_lock( &p_owner->lock );
2290     p_owner->b_waiting = false;
2291     vlc_cond_signal( &p_owner->wait_request );
2292     vlc_mutex_unlock( &p_owner->lock );
2293 }
2294 
input_DecoderWait(decoder_t * p_dec)2295 void input_DecoderWait( decoder_t *p_dec )
2296 {
2297     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2298 
2299     assert( p_owner->b_waiting );
2300 
2301     vlc_mutex_lock( &p_owner->lock );
2302     while( !p_owner->b_has_data )
2303     {
2304         /* Don't need to lock p_owner->paused since it's only modified by the
2305          * owner */
2306         if( p_owner->paused )
2307             break;
2308         vlc_fifo_Lock( p_owner->p_fifo );
2309         if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
2310         {
2311             msg_Err( p_dec, "buffer deadlock prevented" );
2312             vlc_fifo_Unlock( p_owner->p_fifo );
2313             break;
2314         }
2315         vlc_fifo_Unlock( p_owner->p_fifo );
2316         vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
2317     }
2318     vlc_mutex_unlock( &p_owner->lock );
2319 }
2320 
input_DecoderFrameNext(decoder_t * p_dec,mtime_t * pi_duration)2321 void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration )
2322 {
2323     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2324 
2325     assert( p_owner->paused );
2326     *pi_duration = 0;
2327 
2328     vlc_fifo_Lock( p_owner->p_fifo );
2329     p_owner->frames_countdown++;
2330     vlc_fifo_Signal( p_owner->p_fifo );
2331     vlc_fifo_Unlock( p_owner->p_fifo );
2332 
2333     vlc_mutex_lock( &p_owner->lock );
2334     if( p_owner->fmt.i_cat == VIDEO_ES )
2335     {
2336         if( p_owner->p_vout )
2337             vout_NextPicture( p_owner->p_vout, pi_duration );
2338     }
2339     vlc_mutex_unlock( &p_owner->lock );
2340 }
2341 
input_DecoderHasFormatChanged(decoder_t * p_dec,es_format_t * p_fmt,vlc_meta_t ** pp_meta)2342 bool input_DecoderHasFormatChanged( decoder_t *p_dec, es_format_t *p_fmt, vlc_meta_t **pp_meta )
2343 {
2344     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2345     bool b_changed;
2346 
2347     vlc_mutex_lock( &p_owner->lock );
2348     b_changed = p_owner->b_fmt_description;
2349     if( b_changed )
2350     {
2351         if( p_fmt != NULL )
2352             es_format_Copy( p_fmt, &p_owner->fmt );
2353 
2354         if( pp_meta )
2355         {
2356             *pp_meta = NULL;
2357             if( p_owner->p_description )
2358             {
2359                 *pp_meta = vlc_meta_New();
2360                 if( *pp_meta )
2361                     vlc_meta_Merge( *pp_meta, p_owner->p_description );
2362             }
2363         }
2364         p_owner->b_fmt_description = false;
2365     }
2366     vlc_mutex_unlock( &p_owner->lock );
2367     return b_changed;
2368 }
2369 
input_DecoderGetFifoSize(decoder_t * p_dec)2370 size_t input_DecoderGetFifoSize( decoder_t *p_dec )
2371 {
2372     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2373 
2374     return block_FifoSize( p_owner->p_fifo );
2375 }
2376 
input_DecoderGetObjects(decoder_t * p_dec,vout_thread_t ** pp_vout,audio_output_t ** pp_aout)2377 void input_DecoderGetObjects( decoder_t *p_dec,
2378                               vout_thread_t **pp_vout, audio_output_t **pp_aout )
2379 {
2380     decoder_owner_sys_t *p_owner = p_dec->p_owner;
2381 
2382     vlc_mutex_lock( &p_owner->lock );
2383     if( pp_vout )
2384         *pp_vout = p_owner->p_vout ? vlc_object_hold( p_owner->p_vout ) : NULL;
2385     if( pp_aout )
2386         *pp_aout = p_owner->p_aout ? vlc_object_hold( p_owner->p_aout ) : NULL;
2387     vlc_mutex_unlock( &p_owner->lock );
2388 }
2389