qt: playlist: use item title if available
[vlc.git] / src / input / decoder.c
blob1ac909a08304c28bf427e6bd89ce86f036438409
1 /*****************************************************************************
2 * decoder.c: Functions for the management of decoders
3 *****************************************************************************
4 * Copyright (C) 1999-2019 VLC authors, VideoLAN and Videolabs SAS
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
7 * Gildas Bazin <gbazin@videolan.org>
8 * Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31 #include <assert.h>
32 #include <stdatomic.h>
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>
47 #include "audio_output/aout_internal.h"
48 #include "stream_output/stream_output.h"
49 #include "../clock/clock.h"
50 #include "decoder.h"
51 #include "resource.h"
52 #include "libvlc.h"
54 #include "../video_output/vout_internal.h"
57 * Possibles values set in p_owner->reload atomic
59 enum reload
61 RELOAD_NO_REQUEST,
62 RELOAD_DECODER, /* Reload the decoder module */
63 RELOAD_DECODER_AOUT /* Stop the aout and reload the decoder module */
66 struct vlc_input_decoder_t
68 decoder_t dec;
69 input_resource_t*p_resource;
70 vlc_clock_t *p_clock;
72 const struct vlc_input_decoder_callbacks *cbs;
73 void *cbs_userdata;
75 ssize_t i_spu_channel;
76 int64_t i_spu_order;
78 sout_instance_t *p_sout;
79 sout_packetizer_input_t *p_sout_input;
81 vlc_thread_t thread;
83 /* Some decoders require already packetized data (ie. not truncated) */
84 decoder_t *p_packetizer;
85 bool b_packetizer;
87 /* Current format in use by the output */
88 es_format_t fmt;
89 vlc_video_context *vctx;
91 /* */
92 atomic_bool b_fmt_description;
93 vlc_meta_t *p_description;
94 atomic_int reload;
96 /* fifo */
97 block_fifo_t *p_fifo;
99 /* Lock for communication with decoder thread */
100 vlc_mutex_t lock;
101 vlc_cond_t wait_request;
102 vlc_cond_t wait_acknowledge;
103 vlc_cond_t wait_fifo; /* TODO: merge with wait_acknowledge */
105 /* pool to use when the decoder doesn't use its own */
106 struct picture_pool_t *out_pool;
109 * 3 threads can read/write these output variables, the DecoderThread, the
110 * input thread, and the ModuleThread. The ModuleThread is either the
111 * DecoderThread for synchronous modules or any thread for asynchronous
112 * modules.
114 * Asynchronous modules are responsible for serializing/locking every
115 * output calls in any thread as long as the decoder_UpdateVideoFormat() or
116 * decoder_NewPicture() calls are not concurrent, cf.
117 * decoder_UpdateVideoFormat() and decoder_NewPicture() notes.
119 * The ModuleThread is the owner of these variables, it should hold
120 * the lock when writing them but doesn't have to hold it when using them.
122 * The DecoderThread should always hold the lock when reading/using
123 * aout/vouts.
125 * The input thread can read these variables in order to stop outputs, when
126 * both ModuleThread and DecoderThread are stopped (from DecoderDelete()).
128 audio_output_t *p_aout;
130 vout_thread_t *p_vout;
131 bool vout_started;
132 enum vlc_vout_order vout_order;
134 /* -- Theses variables need locking on read *and* write -- */
135 /* Preroll */
136 vlc_tick_t i_preroll_end;
138 #define PREROLL_NONE INT64_MIN // vlc_tick_t
139 #define PREROLL_FORCED INT64_MAX // vlc_tick_t
141 /* Pause & Rate */
142 bool reset_out_state;
143 vlc_tick_t pause_date;
144 vlc_tick_t delay;
145 float request_rate, output_rate;
146 unsigned frames_countdown;
147 bool paused;
149 bool error;
151 /* Waiting */
152 bool b_waiting;
153 bool b_first;
154 bool b_has_data;
156 /* Flushing */
157 bool flushing;
158 bool b_draining;
159 atomic_bool drained;
160 bool b_idle;
161 bool aborting;
163 /* CC */
164 #define MAX_CC_DECODERS 64 /* The es_out only creates one type of es */
165 struct
167 bool b_supported;
168 decoder_cc_desc_t desc;
169 vlc_input_decoder_t *pp_decoder[MAX_CC_DECODERS];
170 bool b_sout_created;
171 sout_packetizer_input_t *p_sout_input;
172 } cc;
174 /* Mouse event */
175 vlc_mutex_t mouse_lock;
176 vlc_mouse_event mouse_event;
177 void *mouse_opaque;
180 /* Pictures which are DECODER_BOGUS_VIDEO_DELAY or more in advance probably have
181 * a bogus PTS and won't be displayed */
182 #define DECODER_BOGUS_VIDEO_DELAY ((vlc_tick_t)(DEFAULT_PTS_DELAY * 30))
184 /* */
185 #define DECODER_SPU_VOUT_WAIT_DURATION VLC_TICK_FROM_MS(200)
186 #define BLOCK_FLAG_CORE_PRIVATE_RELOADED (1 << BLOCK_FLAG_CORE_PRIVATE_SHIFT)
188 #define decoder_Notify(decoder_priv, event, ...) \
189 if (decoder_priv->cbs && decoder_priv->cbs->event) \
190 decoder_priv->cbs->event(decoder_priv, __VA_ARGS__, \
191 decoder_priv->cbs_userdata);
193 static inline vlc_input_decoder_t *dec_get_owner( decoder_t *p_dec )
195 return container_of( p_dec, vlc_input_decoder_t, dec );
199 * Load a decoder module
201 static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
202 const es_format_t *restrict p_fmt )
204 decoder_Init( p_dec, p_fmt );
206 p_dec->b_frame_drop_allowed = true;
208 /* Find a suitable decoder/packetizer module */
209 if( !b_packetizer )
211 static const char caps[ES_CATEGORY_COUNT][16] = {
212 [VIDEO_ES] = "video decoder",
213 [AUDIO_ES] = "audio decoder",
214 [SPU_ES] = "spu decoder",
216 p_dec->p_module = module_need_var( p_dec, caps[p_dec->fmt_in.i_cat],
217 "codec" );
219 else
220 p_dec->p_module = module_need_var( p_dec, "packetizer", "packetizer" );
222 if( !p_dec->p_module )
224 decoder_Clean( p_dec );
225 return -1;
227 return 0;
230 static int DecoderThread_Reload( vlc_input_decoder_t *p_owner,
231 const es_format_t *restrict p_fmt,
232 enum reload reload )
234 /* Copy p_fmt since it can be destroyed by decoder_Clean */
235 decoder_t *p_dec = &p_owner->dec;
236 es_format_t fmt_in;
237 if( es_format_Copy( &fmt_in, p_fmt ) != VLC_SUCCESS )
239 p_owner->error = true;
240 return VLC_EGENERIC;
243 /* Restart the decoder module */
244 decoder_Clean( p_dec );
245 p_owner->error = false;
247 if( reload == RELOAD_DECODER_AOUT )
249 assert( p_owner->fmt.i_cat == AUDIO_ES );
250 audio_output_t *p_aout = p_owner->p_aout;
251 // no need to lock, the decoder and ModuleThread are dead
252 p_owner->p_aout = NULL;
253 if( p_aout )
255 aout_DecDelete( p_aout );
256 input_resource_PutAout( p_owner->p_resource, p_aout );
260 if( LoadDecoder( p_dec, false, &fmt_in ) )
262 p_owner->error = true;
263 es_format_Clean( &fmt_in );
264 return VLC_EGENERIC;
266 es_format_Clean( &fmt_in );
267 return VLC_SUCCESS;
270 static void DecoderUpdateFormatLocked( vlc_input_decoder_t *p_owner )
272 decoder_t *p_dec = &p_owner->dec;
274 vlc_mutex_assert( &p_owner->lock );
276 es_format_Clean( &p_owner->fmt );
277 es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
279 assert( p_owner->fmt.i_cat == p_dec->fmt_in.i_cat );
281 /* Move p_description */
282 if( p_dec->p_description != NULL )
284 if( p_owner->p_description != NULL )
285 vlc_meta_Delete( p_owner->p_description );
286 p_owner->p_description = p_dec->p_description;
287 p_dec->p_description = NULL;
290 atomic_store_explicit( &p_owner->b_fmt_description, true,
291 memory_order_release );
294 static void MouseEvent( const vlc_mouse_t *newmouse, void *user_data )
296 decoder_t *dec = user_data;
297 vlc_input_decoder_t *owner = dec_get_owner( dec );
299 vlc_mutex_lock( &owner->mouse_lock );
300 if( owner->mouse_event )
301 owner->mouse_event( newmouse, owner->mouse_opaque);
302 vlc_mutex_unlock( &owner->mouse_lock );
305 /*****************************************************************************
306 * Buffers allocation callbacks for the decoders
307 *****************************************************************************/
308 static bool aout_replaygain_changed( const audio_replay_gain_t *a,
309 const audio_replay_gain_t *b )
311 for( size_t i=0; i<AUDIO_REPLAY_GAIN_MAX; i++ )
313 if( a->pb_gain[i] != b->pb_gain[i] ||
314 a->pb_peak[i] != b->pb_peak[i] ||
315 (a->pb_gain[i] && a->pf_gain[i] != b->pf_gain[i]) ||
316 (a->pb_peak[i] && a->pf_peak[i] != b->pf_peak[i]) )
317 return true;
319 return false;
322 static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
324 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
326 if( p_owner->p_aout &&
327 ( !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) ||
328 p_dec->fmt_out.i_codec != p_dec->fmt_out.audio.i_format ||
329 p_dec->fmt_out.i_profile != p_owner->fmt.i_profile ) )
331 audio_output_t *p_aout = p_owner->p_aout;
333 /* Parameters changed, restart the aout */
334 vlc_mutex_lock( &p_owner->lock );
335 p_owner->p_aout = NULL; // the DecoderThread should not use the old aout anymore
336 vlc_mutex_unlock( &p_owner->lock );
337 aout_DecDelete( p_aout );
339 input_resource_PutAout( p_owner->p_resource, p_aout );
342 /* Check if only replay gain has changed */
343 if( aout_replaygain_changed( &p_dec->fmt_in.audio_replay_gain,
344 &p_owner->fmt.audio_replay_gain ) )
346 p_dec->fmt_out.audio_replay_gain = p_dec->fmt_in.audio_replay_gain;
347 if( p_owner->p_aout )
349 p_owner->fmt.audio_replay_gain = p_dec->fmt_in.audio_replay_gain;
350 var_TriggerCallback( p_owner->p_aout, "audio-replay-gain-mode" );
354 if( p_owner->p_aout == NULL )
356 p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
358 audio_sample_format_t format = p_dec->fmt_out.audio;
359 aout_FormatPrepare( &format );
361 const int i_force_dolby = var_InheritInteger( p_dec, "force-dolby-surround" );
362 if( i_force_dolby &&
363 format.i_physical_channels == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
365 if( i_force_dolby == 1 )
366 format.i_chan_mode |= AOUT_CHANMODE_DOLBYSTEREO;
367 else /* i_force_dolby == 2 */
368 format.i_chan_mode &= ~AOUT_CHANMODE_DOLBYSTEREO;
371 audio_output_t *p_aout;
373 p_aout = input_resource_GetAout( p_owner->p_resource );
374 if( p_aout )
376 if( aout_DecNew( p_aout, &format, p_dec->fmt_out.i_profile,
377 p_owner->p_clock,
378 &p_dec->fmt_out.audio_replay_gain ) )
380 input_resource_PutAout( p_owner->p_resource, p_aout );
381 p_aout = NULL;
385 vlc_mutex_lock( &p_owner->lock );
386 p_owner->p_aout = p_aout;
388 DecoderUpdateFormatLocked( p_owner );
389 aout_FormatPrepare( &p_owner->fmt.audio );
390 vlc_mutex_unlock( &p_owner->lock );
392 if( p_aout == NULL )
393 return -1;
395 p_dec->fmt_out.audio.i_bytes_per_frame =
396 p_owner->fmt.audio.i_bytes_per_frame;
397 p_dec->fmt_out.audio.i_frame_length =
398 p_owner->fmt.audio.i_frame_length;
400 vlc_fifo_Lock( p_owner->p_fifo );
401 p_owner->reset_out_state = true;
402 vlc_fifo_Unlock( p_owner->p_fifo );
404 return 0;
407 static int CreateVoutIfNeeded(vlc_input_decoder_t *);
410 static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *vctx )
412 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
414 int created_vout = CreateVoutIfNeeded(p_owner);
415 if (created_vout == -1)
416 return -1; // error
417 if (created_vout == 0)
419 // video context didn't change
420 if (vctx != NULL && p_owner->vctx == vctx)
421 return 0;
423 assert(p_owner->p_vout);
425 if (p_owner->vctx)
426 vlc_video_context_Release(p_owner->vctx);
427 p_owner->vctx = vctx ? vlc_video_context_Hold(vctx) : NULL;
429 // configure the new vout
431 if ( p_owner->out_pool == NULL )
433 unsigned dpb_size;
434 switch( p_dec->fmt_in.i_codec )
436 case VLC_CODEC_HEVC:
437 case VLC_CODEC_H264:
438 case VLC_CODEC_DIRAC: /* FIXME valid ? */
439 dpb_size = 18;
440 break;
441 case VLC_CODEC_AV1:
442 dpb_size = 10;
443 break;
444 case VLC_CODEC_MP4V:
445 case VLC_CODEC_VP5:
446 case VLC_CODEC_VP6:
447 case VLC_CODEC_VP6F:
448 case VLC_CODEC_VP8:
449 dpb_size = 3;
450 break;
451 default:
452 dpb_size = 2;
453 break;
455 picture_pool_t *pool = picture_pool_NewFromFormat( &p_dec->fmt_out.video,
456 dpb_size + p_dec->i_extra_picture_buffers + 1 );
458 if( pool == NULL)
460 msg_Err(p_dec, "Failed to create a pool of %d %4.4s pictures",
461 dpb_size + p_dec->i_extra_picture_buffers + 1,
462 (char*)&p_dec->fmt_out.video.i_chroma);
463 goto error;
466 vlc_mutex_lock( &p_owner->lock );
467 p_owner->out_pool = pool;
468 vlc_mutex_unlock( &p_owner->lock );
472 vout_configuration_t cfg = {
473 .vout = p_owner->p_vout, .clock = p_owner->p_clock, .fmt = &p_dec->fmt_out.video,
474 .mouse_event = MouseEvent, .mouse_opaque = p_dec,
476 bool has_started;
477 vout_thread_t *p_vout =
478 input_resource_RequestVout(p_owner->p_resource, vctx, &cfg, NULL,
479 &has_started);
480 if (p_vout != NULL)
482 vlc_mutex_lock( &p_owner->lock );
483 p_owner->vout_started = true;
484 vlc_mutex_unlock( &p_owner->lock );
486 if (has_started)
488 vlc_fifo_Lock( p_owner->p_fifo );
489 p_owner->reset_out_state = true;
490 vlc_fifo_Unlock( p_owner->p_fifo );
492 decoder_Notify(p_owner, on_vout_started, p_vout, p_owner->vout_order);
494 return 0;
497 error:
498 /* Clean fmt and vctx to trigger a new vout creation on the next update
499 * call */
500 vlc_mutex_lock( &p_owner->lock );
501 es_format_Clean( &p_owner->fmt );
502 vlc_mutex_unlock( &p_owner->lock );
504 if (p_owner->vctx != NULL)
506 vlc_video_context_Release(p_owner->vctx);
507 p_owner->vctx = NULL;
509 return -1;
512 static int CreateVoutIfNeeded(vlc_input_decoder_t *p_owner)
514 decoder_t *p_dec = &p_owner->dec;
515 bool need_vout = false;
517 if( p_owner->p_vout == NULL )
519 msg_Dbg(p_dec, "vout: none found");
520 need_vout = true;
522 if( p_dec->fmt_out.video.i_width != p_owner->fmt.video.i_width
523 || p_dec->fmt_out.video.i_height != p_owner->fmt.video.i_height )
525 msg_Dbg(p_dec, "vout change: decoder size");
526 need_vout = true;
528 if( p_dec->fmt_out.video.i_visible_width != p_owner->fmt.video.i_visible_width
529 || p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
530 || p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
531 || p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset )
533 msg_Dbg(p_dec, "vout change: visible size");
534 need_vout = true;
536 if( p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma )
538 msg_Dbg(p_dec, "vout change: chroma");
539 need_vout = true;
541 if( (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
542 (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num )
544 msg_Dbg(p_dec, "vout change: SAR");
545 need_vout = true;
547 if( p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation )
549 msg_Dbg(p_dec, "vout change: orientation");
550 need_vout = true;
552 if( p_dec->fmt_out.video.multiview_mode != p_owner->fmt.video.multiview_mode )
554 msg_Dbg(p_dec, "vout change: multiview");
555 need_vout = true;
558 if( !need_vout )
559 return 0; // vout unchanged
561 vlc_mutex_lock( &p_owner->lock );
563 vout_thread_t *p_vout = p_owner->p_vout;
564 p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
565 p_owner->vout_started = false;
566 vlc_mutex_unlock( &p_owner->lock );
568 enum vlc_vout_order order;
569 const vout_configuration_t cfg = { .vout = p_vout, .fmt = NULL };
570 p_vout = input_resource_RequestVout( p_owner->p_resource, NULL, &cfg, &order, NULL );
572 vlc_mutex_lock( &p_owner->lock );
573 p_owner->p_vout = p_vout;
574 p_owner->vout_order = order;
576 DecoderUpdateFormatLocked( p_owner );
577 p_owner->fmt.video.i_chroma = p_dec->fmt_out.i_codec;
578 picture_pool_t *pool = p_owner->out_pool;
579 p_owner->out_pool = NULL;
580 vlc_mutex_unlock( &p_owner->lock );
582 if ( pool != NULL )
583 picture_pool_Release( pool );
585 if( p_vout == NULL )
587 msg_Err( p_dec, "failed to create video output" );
588 return -1;
591 return 1; // new vout was created
594 static vlc_decoder_device * ModuleThread_GetDecoderDevice( decoder_t *p_dec )
596 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
598 /* Requesting a decoder device will automatically enable hw decoding */
599 if( !var_InheritBool( p_dec, "hw-dec" ) )
600 return NULL;
602 int created_vout = CreateVoutIfNeeded(p_owner);
603 if (created_vout == -1)
604 return NULL; // error
606 assert(p_owner->p_vout);
607 vlc_decoder_device *dec_device = vout_GetDevice(p_owner->p_vout);
608 if (created_vout == 1)
609 return dec_device; // new vout was created with a decoder device
611 bool need_format_update = false;
612 if ( memcmp( &p_dec->fmt_out.video.mastering,
613 &p_owner->fmt.video.mastering,
614 sizeof(p_owner->fmt.video.mastering)) )
616 msg_Dbg(p_dec, "vout update: mastering data");
617 need_format_update = true;
619 if ( p_dec->fmt_out.video.lighting.MaxCLL !=
620 p_owner->fmt.video.lighting.MaxCLL ||
621 p_dec->fmt_out.video.lighting.MaxFALL !=
622 p_owner->fmt.video.lighting.MaxFALL )
624 msg_Dbg(p_dec, "vout update: lighting data");
625 need_format_update = true;
628 if ( need_format_update )
630 /* the format has changed but we don't need a new vout */
631 vlc_mutex_lock( &p_owner->lock );
632 DecoderUpdateFormatLocked( p_owner );
633 vlc_mutex_unlock( &p_owner->lock );
635 return dec_device;
638 static picture_t *ModuleThread_NewVideoBuffer( decoder_t *p_dec )
640 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
641 assert( p_owner->p_vout );
642 assert( p_owner->out_pool );
644 picture_t *pic = picture_pool_Wait( p_owner->out_pool );
645 if (pic)
646 picture_Reset( pic );
647 return pic;
650 static subpicture_t *ModuleThread_NewSpuBuffer( decoder_t *p_dec,
651 const subpicture_updater_t *p_updater )
653 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
654 vout_thread_t *p_vout = NULL;
655 subpicture_t *p_subpic;
656 int i_attempts = 30;
658 while( i_attempts-- )
660 if( p_owner->error )
661 break;
663 p_vout = input_resource_HoldVout( p_owner->p_resource );
664 if( p_vout )
665 break;
667 vlc_tick_sleep( DECODER_SPU_VOUT_WAIT_DURATION );
670 if( !p_vout )
672 msg_Warn( p_dec, "no vout found, dropping subpicture" );
673 if( p_owner->p_vout )
675 assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
676 decoder_Notify(p_owner, on_vout_stopped, p_owner->p_vout);
678 vlc_mutex_lock( &p_owner->lock );
679 vout_UnregisterSubpictureChannel(p_owner->p_vout,
680 p_owner->i_spu_channel);
681 p_owner->i_spu_channel = VOUT_SPU_CHANNEL_INVALID;
683 vout_Release(p_owner->p_vout);
684 p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
685 vlc_mutex_unlock( &p_owner->lock );
687 return NULL;
690 if( p_owner->p_vout != p_vout )
692 if (p_owner->p_vout) /* notify the previous vout deletion unlocked */
693 decoder_Notify(p_owner, on_vout_stopped, p_owner->p_vout);
695 vlc_mutex_lock(&p_owner->lock);
697 if (p_owner->p_vout)
699 /* Unregister the SPU channel of the previous vout */
700 assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
701 vout_UnregisterSubpictureChannel(p_owner->p_vout,
702 p_owner->i_spu_channel);
703 vout_Release(p_owner->p_vout);
704 p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
707 enum vlc_vout_order channel_order;
708 p_owner->i_spu_channel =
709 vout_RegisterSubpictureChannelInternal(p_vout, p_owner->p_clock,
710 &channel_order);
711 p_owner->i_spu_order = 0;
713 if (p_owner->i_spu_channel == VOUT_SPU_CHANNEL_INVALID)
715 /* The new vout doesn't support SPU, aborting... */
716 vlc_mutex_unlock(&p_owner->lock);
717 vout_Release(p_vout);
718 return NULL;
721 p_owner->p_vout = p_vout;
722 p_owner->vout_order = channel_order;
723 vlc_mutex_unlock(&p_owner->lock);
725 assert(channel_order != VLC_VOUT_ORDER_NONE);
726 decoder_Notify(p_owner, on_vout_started, p_vout, channel_order);
728 else
729 vout_Release(p_vout);
731 p_subpic = subpicture_New( p_updater );
732 if( p_subpic )
734 p_subpic->i_channel = p_owner->i_spu_channel;
735 p_subpic->i_order = p_owner->i_spu_order++;
736 p_subpic->b_subtitle = true;
739 return p_subpic;
742 static int InputThread_GetInputAttachments( decoder_t *p_dec,
743 input_attachment_t ***ppp_attachment,
744 int *pi_attachment )
746 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
747 if (!p_owner->cbs || !p_owner->cbs->get_attachments)
748 return VLC_ENOOBJ;
750 int ret = p_owner->cbs->get_attachments(p_owner, ppp_attachment,
751 p_owner->cbs_userdata);
752 if (ret < 0)
753 return VLC_EGENERIC;
754 *pi_attachment = ret;
755 return VLC_SUCCESS;
758 static vlc_tick_t ModuleThread_GetDisplayDate( decoder_t *p_dec,
759 vlc_tick_t system_now, vlc_tick_t i_ts )
761 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
763 vlc_mutex_lock( &p_owner->lock );
764 if( p_owner->b_waiting || p_owner->paused )
765 i_ts = VLC_TICK_INVALID;
766 float rate = p_owner->output_rate;
767 vlc_mutex_unlock( &p_owner->lock );
769 if( !p_owner->p_clock || i_ts == VLC_TICK_INVALID )
770 return i_ts;
772 return vlc_clock_ConvertToSystem( p_owner->p_clock, system_now, i_ts, rate );
775 static float ModuleThread_GetDisplayRate( decoder_t *p_dec )
777 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
779 if( !p_owner->p_clock )
780 return 1.f;
781 vlc_mutex_lock( &p_owner->lock );
782 float rate = p_owner->output_rate;
783 vlc_mutex_unlock( &p_owner->lock );
784 return rate;
787 /*****************************************************************************
788 * Public functions
789 *****************************************************************************/
790 block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples )
792 assert( dec->fmt_out.audio.i_frame_length > 0
793 && dec->fmt_out.audio.i_bytes_per_frame > 0 );
795 size_t length = samples * dec->fmt_out.audio.i_bytes_per_frame
796 / dec->fmt_out.audio.i_frame_length;
797 block_t *block = block_Alloc( length );
798 if( likely(block != NULL) )
800 block->i_nb_samples = samples;
801 block->i_pts = block->i_length = 0;
803 return block;
806 static void RequestReload( vlc_input_decoder_t *p_owner )
808 /* Don't override reload if it's RELOAD_DECODER_AOUT */
809 int expected = RELOAD_NO_REQUEST;
810 atomic_compare_exchange_strong( &p_owner->reload, &expected, RELOAD_DECODER );
813 static void DecoderWaitUnblock( vlc_input_decoder_t *p_owner )
815 vlc_mutex_assert( &p_owner->lock );
817 for( ;; )
819 if( !p_owner->b_waiting || !p_owner->b_has_data )
820 break;
821 vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
825 static inline void DecoderUpdatePreroll( vlc_tick_t *pi_preroll, const block_t *p )
827 if( p->i_flags & BLOCK_FLAG_PREROLL )
828 *pi_preroll = PREROLL_FORCED;
829 /* Check if we can use the packet for end of preroll */
830 else if( (p->i_flags & BLOCK_FLAG_DISCONTINUITY) &&
831 (p->i_buffer == 0 || (p->i_flags & BLOCK_FLAG_CORRUPTED)) )
832 *pi_preroll = PREROLL_FORCED;
833 else if( p->i_dts != VLC_TICK_INVALID )
834 *pi_preroll = __MIN( *pi_preroll, p->i_dts );
835 else if( p->i_pts != VLC_TICK_INVALID )
836 *pi_preroll = __MIN( *pi_preroll, p->i_pts );
839 #ifdef ENABLE_SOUT
840 static int DecoderThread_PlaySout( vlc_input_decoder_t *p_owner, block_t *p_sout_block )
842 assert( !p_sout_block->p_next );
844 vlc_mutex_lock( &p_owner->lock );
846 if( p_owner->b_waiting )
848 p_owner->b_has_data = true;
849 vlc_cond_signal( &p_owner->wait_acknowledge );
852 DecoderWaitUnblock( p_owner );
854 vlc_mutex_unlock( &p_owner->lock );
856 /* FIXME --VLC_TICK_INVALID inspect stream_output*/
857 return sout_InputSendBuffer( p_owner->p_sout, p_owner->p_sout_input,
858 p_sout_block );
861 /* This function process a block for sout
863 static void DecoderThread_ProcessSout( vlc_input_decoder_t *p_owner, block_t *p_block )
865 decoder_t *p_dec = &p_owner->dec;
866 block_t *p_sout_block;
867 block_t **pp_block = p_block ? &p_block : NULL;
869 while( ( p_sout_block =
870 p_dec->pf_packetize( p_dec, pp_block ) ) )
872 if( p_owner->p_sout_input == NULL )
874 vlc_mutex_lock( &p_owner->lock );
875 DecoderUpdateFormatLocked( p_owner );
877 p_owner->fmt.i_group = p_dec->fmt_in.i_group;
878 p_owner->fmt.i_id = p_dec->fmt_in.i_id;
879 if( p_dec->fmt_in.psz_language )
881 free( p_owner->fmt.psz_language );
882 p_owner->fmt.psz_language =
883 strdup( p_dec->fmt_in.psz_language );
885 vlc_mutex_unlock( &p_owner->lock );
887 p_owner->p_sout_input =
888 sout_InputNew( p_owner->p_sout, &p_owner->fmt );
890 if( p_owner->p_sout_input == NULL )
892 msg_Err( p_dec, "cannot create packetized sout output (%4.4s)",
893 (char *)&p_owner->fmt.i_codec );
894 p_owner->error = true;
896 if(p_block)
897 block_Release(p_block);
899 block_ChainRelease(p_sout_block);
900 break;
904 while( p_sout_block )
906 block_t *p_next = p_sout_block->p_next;
908 p_sout_block->p_next = NULL;
910 if( p_owner->p_sout->b_wants_substreams && p_dec->pf_get_cc )
912 if( p_owner->cc.p_sout_input ||
913 !p_owner->cc.b_sout_created )
915 decoder_cc_desc_t desc;
916 block_t *p_cc = p_dec->pf_get_cc( p_dec, &desc );
917 if( p_cc )
919 if(!p_owner->cc.b_sout_created)
921 es_format_t ccfmt;
922 es_format_Init(&ccfmt, SPU_ES, VLC_CODEC_CEA608);
923 ccfmt.i_group = p_owner->fmt.i_group;
924 ccfmt.subs.cc.i_reorder_depth = desc.i_reorder_depth;
925 p_owner->cc.p_sout_input = sout_InputNew( p_owner->p_sout, &ccfmt );
926 es_format_Clean(&ccfmt);
927 p_owner->cc.b_sout_created = true;
930 if( !p_owner->cc.p_sout_input ||
931 sout_InputSendBuffer( p_owner->p_sout, p_owner->cc.p_sout_input, p_cc ) )
933 block_Release( p_cc );
939 if( DecoderThread_PlaySout( p_owner, p_sout_block ) == VLC_EGENERIC )
941 msg_Err( p_dec, "cannot continue streaming due to errors with codec %4.4s",
942 (char *)&p_owner->fmt.i_codec );
944 p_owner->error = true;
946 /* Cleanup */
948 if( p_block )
949 block_Release( p_block );
951 block_ChainRelease( p_next );
952 return;
955 p_sout_block = p_next;
959 #endif
961 static void DecoderPlayCc( vlc_input_decoder_t *p_owner, block_t *p_cc,
962 const decoder_cc_desc_t *p_desc )
964 vlc_mutex_lock( &p_owner->lock );
966 p_owner->cc.desc = *p_desc;
968 /* Fanout data to all decoders. We do not know if es_out
969 selected 608 or 708. */
970 uint64_t i_bitmap = p_owner->cc.desc.i_608_channels |
971 p_owner->cc.desc.i_708_channels;
973 for( int i=0; i_bitmap > 0; i_bitmap >>= 1, i++ )
975 vlc_input_decoder_t *p_ccowner = p_owner->cc.pp_decoder[i];
976 if( !p_ccowner )
977 continue;
979 if( i_bitmap > 1 )
981 block_FifoPut( p_ccowner->p_fifo, block_Duplicate(p_cc) );
983 else
985 block_FifoPut( p_ccowner->p_fifo, p_cc );
986 p_cc = NULL; /* was last dec */
990 vlc_mutex_unlock( &p_owner->lock );
992 if( p_cc ) /* can have bitmap set but no created decs */
993 block_Release( p_cc );
996 static void PacketizerGetCc( vlc_input_decoder_t *p_owner, decoder_t *p_dec_cc )
998 block_t *p_cc;
999 decoder_cc_desc_t desc;
1001 /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
1002 if( !p_owner->cc.b_supported )
1003 return;
1005 assert( p_dec_cc->pf_get_cc != NULL );
1007 p_cc = p_dec_cc->pf_get_cc( p_dec_cc, &desc );
1008 if( !p_cc )
1009 return;
1010 DecoderPlayCc( p_owner, p_cc, &desc );
1013 static void ModuleThread_QueueCc( decoder_t *p_videodec, block_t *p_cc,
1014 const decoder_cc_desc_t *p_desc )
1016 vlc_input_decoder_t *p_owner = dec_get_owner( p_videodec );
1018 if( unlikely( p_cc != NULL ) )
1020 if( p_owner->cc.b_supported &&
1021 ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
1022 DecoderPlayCc( p_owner, p_cc, p_desc );
1023 else
1024 block_Release( p_cc );
1028 static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_picture )
1030 decoder_t *p_dec = &p_owner->dec;
1031 vout_thread_t *p_vout = p_owner->p_vout;
1033 if( p_picture->date == VLC_TICK_INVALID )
1034 /* FIXME: VLC_TICK_INVALID -- verify video_output */
1036 msg_Warn( p_dec, "non-dated video buffer received" );
1037 picture_Release( p_picture );
1038 return VLC_EGENERIC;
1041 vlc_mutex_lock( &p_owner->lock );
1042 assert( p_owner->vout_started );
1044 bool prerolled = p_owner->i_preroll_end != PREROLL_NONE;
1045 if( prerolled && p_owner->i_preroll_end > p_picture->date )
1047 vlc_mutex_unlock( &p_owner->lock );
1048 picture_Release( p_picture );
1049 return VLC_SUCCESS;
1052 p_owner->i_preroll_end = PREROLL_NONE;
1054 if( unlikely(prerolled) )
1056 msg_Dbg( p_dec, "end of video preroll" );
1058 if( p_vout )
1059 vout_FlushAll( p_vout );
1062 if( p_owner->b_waiting && !p_owner->b_first )
1064 p_owner->b_has_data = true;
1065 vlc_cond_signal( &p_owner->wait_acknowledge );
1068 DecoderWaitUnblock( p_owner );
1070 if( p_owner->b_waiting )
1072 assert( p_owner->b_first );
1073 msg_Dbg( p_dec, "Received first picture" );
1074 p_owner->b_first = false;
1075 p_picture->b_force = true;
1078 vlc_mutex_unlock( &p_owner->lock );
1080 /* FIXME: The *input* FIFO should not be locked here. This will not work
1081 * properly if/when pictures are queued asynchronously. */
1082 vlc_fifo_Lock( p_owner->p_fifo );
1083 if( unlikely(p_owner->paused) && likely(p_owner->frames_countdown > 0) )
1084 p_owner->frames_countdown--;
1085 vlc_fifo_Unlock( p_owner->p_fifo );
1087 /* */
1088 if( p_vout == NULL )
1090 picture_Release( p_picture );
1091 return VLC_EGENERIC;
1094 if( p_picture->b_still )
1096 /* Ensure no earlier higher pts breaks still state */
1097 vout_Flush( p_vout, p_picture->date );
1099 vout_PutPicture( p_vout, p_picture );
1101 return VLC_SUCCESS;
1104 static void ModuleThread_UpdateStatVideo( vlc_input_decoder_t *p_owner,
1105 bool lost )
1107 unsigned displayed = 0;
1108 unsigned vout_lost = 0;
1109 unsigned vout_late = 0;
1110 if( p_owner->p_vout != NULL )
1112 vout_GetResetStatistic( p_owner->p_vout, &displayed, &vout_lost, &vout_late );
1114 if (lost) vout_lost++;
1116 decoder_Notify(p_owner, on_new_video_stats, 1, vout_lost, displayed, vout_late);
1119 static void ModuleThread_QueueVideo( decoder_t *p_dec, picture_t *p_pic )
1121 assert( p_pic );
1122 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1124 int success = ModuleThread_PlayVideo( p_owner, p_pic );
1126 ModuleThread_UpdateStatVideo( p_owner, success != VLC_SUCCESS );
1129 static vlc_decoder_device * thumbnailer_get_device( decoder_t *p_dec )
1131 VLC_UNUSED(p_dec);
1132 // no hardware decoder on purpose
1133 // we don't want to load many DLLs and allocate many pictures
1134 // just to decode one picture
1135 return NULL;
1138 static picture_t *thumbnailer_buffer_new( decoder_t *p_dec )
1140 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1141 /* Avoid decoding more than one frame when a thumbnail was
1142 * already generated */
1143 vlc_mutex_lock( &p_owner->lock );
1144 if( !p_owner->b_first )
1146 vlc_mutex_unlock( &p_owner->lock );
1147 return NULL;
1149 vlc_mutex_unlock( &p_owner->lock );
1150 return picture_NewFromFormat( &p_dec->fmt_out.video );
1153 static void ModuleThread_QueueThumbnail( decoder_t *p_dec, picture_t *p_pic )
1155 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1156 bool b_first;
1158 vlc_mutex_lock( &p_owner->lock );
1159 b_first = p_owner->b_first;
1160 p_owner->b_first = false;
1161 vlc_mutex_unlock( &p_owner->lock );
1163 if( b_first )
1164 decoder_Notify(p_owner, on_thumbnail_ready, p_pic);
1165 picture_Release( p_pic );
1169 static int ModuleThread_PlayAudio( vlc_input_decoder_t *p_owner, block_t *p_audio )
1171 decoder_t *p_dec = &p_owner->dec;
1173 assert( p_audio != NULL );
1175 if( p_audio->i_pts == VLC_TICK_INVALID ) // FIXME --VLC_TICK_INVALID verify audio_output/*
1177 msg_Warn( p_dec, "non-dated audio buffer received" );
1178 block_Release( p_audio );
1179 return VLC_EGENERIC;
1182 vlc_mutex_lock( &p_owner->lock );
1183 bool prerolled = p_owner->i_preroll_end != PREROLL_NONE;
1184 if( prerolled && p_owner->i_preroll_end > p_audio->i_pts )
1186 vlc_mutex_unlock( &p_owner->lock );
1187 block_Release( p_audio );
1188 return VLC_SUCCESS;
1191 p_owner->i_preroll_end = PREROLL_NONE;
1192 vlc_mutex_unlock( &p_owner->lock );
1194 if( unlikely(prerolled) )
1196 msg_Dbg( p_dec, "end of audio preroll" );
1198 if( p_owner->p_aout )
1199 aout_DecFlush( p_owner->p_aout );
1202 /* */
1203 /* */
1204 vlc_mutex_lock( &p_owner->lock );
1205 if( p_owner->b_waiting )
1207 p_owner->b_has_data = true;
1208 vlc_cond_signal( &p_owner->wait_acknowledge );
1211 /* */
1212 DecoderWaitUnblock( p_owner );
1213 vlc_mutex_unlock( &p_owner->lock );
1215 audio_output_t *p_aout = p_owner->p_aout;
1217 if( p_aout == NULL )
1219 msg_Dbg( p_dec, "discarded audio buffer" );
1220 block_Release( p_audio );
1221 return VLC_EGENERIC;
1224 int status = aout_DecPlay( p_aout, p_audio );
1225 if( status == AOUT_DEC_CHANGED )
1227 /* Only reload the decoder */
1228 RequestReload( p_owner );
1230 else if( status == AOUT_DEC_FAILED )
1232 /* If we reload because the aout failed, we should release it. That
1233 * way, a next call to ModuleThread_UpdateAudioFormat() won't re-use the
1234 * previous (failing) aout but will try to create a new one. */
1235 atomic_store( &p_owner->reload, RELOAD_DECODER_AOUT );
1237 return VLC_SUCCESS;
1240 static void ModuleThread_UpdateStatAudio( vlc_input_decoder_t *p_owner,
1241 bool lost )
1243 unsigned played = 0;
1244 unsigned aout_lost = 0;
1245 if( p_owner->p_aout != NULL )
1247 aout_DecGetResetStats( p_owner->p_aout, &aout_lost, &played );
1249 if (lost) aout_lost++;
1251 decoder_Notify(p_owner, on_new_audio_stats, 1, aout_lost, played);
1254 static void ModuleThread_QueueAudio( decoder_t *p_dec, block_t *p_aout_buf )
1256 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1258 int success = ModuleThread_PlayAudio( p_owner, p_aout_buf );
1260 ModuleThread_UpdateStatAudio( p_owner, success != VLC_SUCCESS );
1263 static void ModuleThread_PlaySpu( vlc_input_decoder_t *p_owner, subpicture_t *p_subpic )
1265 decoder_t *p_dec = &p_owner->dec;
1266 vout_thread_t *p_vout = p_owner->p_vout;
1268 /* */
1269 if( p_subpic->i_start == VLC_TICK_INVALID )
1271 msg_Warn( p_dec, "non-dated spu buffer received" );
1272 subpicture_Delete( p_subpic );
1273 return;
1276 /* */
1277 vlc_mutex_lock( &p_owner->lock );
1279 if( p_owner->b_waiting )
1281 p_owner->b_has_data = true;
1282 vlc_cond_signal( &p_owner->wait_acknowledge );
1285 DecoderWaitUnblock( p_owner );
1286 vlc_mutex_unlock( &p_owner->lock );
1288 if( p_subpic->i_start == VLC_TICK_INVALID )
1290 subpicture_Delete( p_subpic );
1291 return;
1294 vout_PutSubpicture( p_vout, p_subpic );
1297 static void ModuleThread_QueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
1299 assert( p_spu );
1300 vlc_input_decoder_t *p_owner = dec_get_owner( p_dec );
1302 /* The vout must be created from a previous decoder_NewSubpicture call. */
1303 assert( p_owner->p_vout );
1305 /* Preroll does not work very well with subtitle */
1306 vlc_mutex_lock( &p_owner->lock );
1307 if( p_spu->i_start != VLC_TICK_INVALID &&
1308 p_spu->i_start < p_owner->i_preroll_end &&
1309 ( p_spu->i_stop == VLC_TICK_INVALID || p_spu->i_stop < p_owner->i_preroll_end ) )
1311 vlc_mutex_unlock( &p_owner->lock );
1312 subpicture_Delete( p_spu );
1314 else
1316 vlc_mutex_unlock( &p_owner->lock );
1317 ModuleThread_PlaySpu( p_owner, p_spu );
1321 static void DecoderThread_ProcessInput( vlc_input_decoder_t *p_owner, block_t *p_block );
1322 static void DecoderThread_DecodeBlock( vlc_input_decoder_t *p_owner, block_t *p_block )
1324 decoder_t *p_dec = &p_owner->dec;
1326 int ret = p_dec->pf_decode( p_dec, p_block );
1327 switch( ret )
1329 case VLCDEC_SUCCESS:
1330 break;
1331 case VLCDEC_ECRITICAL:
1332 p_owner->error = true;
1333 break;
1334 case VLCDEC_RELOAD:
1335 RequestReload( p_owner );
1336 if( unlikely( p_block == NULL ) )
1337 break;
1338 if( !( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
1340 p_block->i_flags |= BLOCK_FLAG_CORE_PRIVATE_RELOADED;
1341 DecoderThread_ProcessInput( p_owner, p_block );
1343 else /* We prefer loosing this block than an infinite recursion */
1344 block_Release( p_block );
1345 break;
1346 default:
1347 vlc_assert_unreachable();
1352 * Decode a block
1354 * \param p_dec the decoder object
1355 * \param p_block the block to decode
1357 static void DecoderThread_ProcessInput( vlc_input_decoder_t *p_owner, block_t *p_block )
1359 decoder_t *p_dec = &p_owner->dec;
1361 if( p_owner->error )
1362 goto error;
1364 /* Here, the atomic doesn't prevent to miss a reload request.
1365 * DecoderThread_ProcessInput() can still be called after the decoder module or the
1366 * audio output requested a reload. This will only result in a drop of an
1367 * input block or an output buffer. */
1368 enum reload reload;
1369 if( ( reload = atomic_exchange( &p_owner->reload, RELOAD_NO_REQUEST ) ) )
1371 msg_Warn( p_dec, "Reloading the decoder module%s",
1372 reload == RELOAD_DECODER_AOUT ? " and the audio output" : "" );
1374 if( DecoderThread_Reload( p_owner, &p_dec->fmt_in, reload ) != VLC_SUCCESS )
1375 goto error;
1378 bool packetize = p_owner->p_packetizer != NULL;
1379 if( p_block )
1381 if( p_block->i_buffer <= 0 )
1382 goto error;
1384 vlc_mutex_lock( &p_owner->lock );
1385 DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
1386 vlc_mutex_unlock( &p_owner->lock );
1387 if( unlikely( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
1389 /* This block has already been packetized */
1390 packetize = false;
1394 #ifdef ENABLE_SOUT
1395 if( p_owner->p_sout != NULL )
1397 DecoderThread_ProcessSout( p_owner, p_block );
1398 return;
1400 #endif
1401 if( packetize )
1403 block_t *p_packetized_block;
1404 block_t **pp_block = p_block ? &p_block : NULL;
1405 decoder_t *p_packetizer = p_owner->p_packetizer;
1407 while( (p_packetized_block =
1408 p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
1410 if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
1412 msg_Dbg( p_dec, "restarting module due to input format change");
1414 /* Drain the decoder module */
1415 DecoderThread_DecodeBlock( p_owner, NULL );
1417 if( DecoderThread_Reload( p_owner, &p_packetizer->fmt_out,
1418 RELOAD_DECODER ) != VLC_SUCCESS )
1420 block_ChainRelease( p_packetized_block );
1421 return;
1425 if( p_packetizer->pf_get_cc )
1426 PacketizerGetCc( p_owner, p_packetizer );
1428 while( p_packetized_block )
1430 block_t *p_next = p_packetized_block->p_next;
1431 p_packetized_block->p_next = NULL;
1433 DecoderThread_DecodeBlock( p_owner, p_packetized_block );
1434 if( p_owner->error )
1436 block_ChainRelease( p_next );
1437 return;
1440 p_packetized_block = p_next;
1443 /* Drain the decoder after the packetizer is drained */
1444 if( !pp_block )
1445 DecoderThread_DecodeBlock( p_owner, NULL );
1447 else
1448 DecoderThread_DecodeBlock( p_owner, p_block );
1449 return;
1451 error:
1452 if( p_block )
1453 block_Release( p_block );
1456 static void DecoderThread_Flush( vlc_input_decoder_t *p_owner )
1458 decoder_t *p_dec = &p_owner->dec;
1459 decoder_t *p_packetizer = p_owner->p_packetizer;
1461 if( p_owner->error )
1462 return;
1464 if( p_packetizer != NULL && p_packetizer->pf_flush != NULL )
1465 p_packetizer->pf_flush( p_packetizer );
1467 if ( p_dec->pf_flush != NULL )
1468 p_dec->pf_flush( p_dec );
1470 /* flush CC sub decoders */
1471 if( p_owner->cc.b_supported )
1473 for( int i=0; i<MAX_CC_DECODERS; i++ )
1475 vlc_input_decoder_t *p_ccowner = p_owner->cc.pp_decoder[i];
1476 if( p_ccowner && p_ccowner->dec.pf_flush )
1477 p_ccowner->dec.pf_flush( &p_ccowner->dec );
1481 vlc_mutex_lock( &p_owner->lock );
1482 #ifdef ENABLE_SOUT
1483 if ( p_owner->p_sout_input != NULL )
1485 sout_InputFlush( p_owner->p_sout, p_owner->p_sout_input );
1487 #endif
1488 if( p_dec->fmt_out.i_cat == AUDIO_ES )
1490 if( p_owner->p_aout )
1491 aout_DecFlush( p_owner->p_aout );
1493 else if( p_dec->fmt_out.i_cat == VIDEO_ES )
1495 if( p_owner->p_vout && p_owner->vout_started )
1496 vout_FlushAll( p_owner->p_vout );
1498 /* Reset the pool cancel state, previously set by
1499 * vlc_input_decoder_Flush() */
1500 if( p_owner->out_pool != NULL )
1501 picture_pool_Cancel( p_owner->out_pool, false );
1503 else if( p_dec->fmt_out.i_cat == SPU_ES )
1505 if( p_owner->p_vout )
1507 assert( p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID );
1508 vout_FlushSubpictureChannel( p_owner->p_vout, p_owner->i_spu_channel );
1512 p_owner->i_preroll_end = PREROLL_NONE;
1513 vlc_mutex_unlock( &p_owner->lock );
1516 static void DecoderThread_ChangePause( vlc_input_decoder_t *p_owner, bool paused, vlc_tick_t date )
1518 decoder_t *p_dec = &p_owner->dec;
1520 msg_Dbg( p_dec, "toggling %s", paused ? "resume" : "pause" );
1521 switch( p_dec->fmt_out.i_cat )
1523 case VIDEO_ES:
1524 vlc_mutex_lock( &p_owner->lock );
1525 if( p_owner->p_vout != NULL && p_owner->vout_started )
1526 vout_ChangePause( p_owner->p_vout, paused, date );
1527 vlc_mutex_unlock( &p_owner->lock );
1528 break;
1529 case AUDIO_ES:
1530 vlc_mutex_lock( &p_owner->lock );
1531 if( p_owner->p_aout != NULL )
1532 aout_DecChangePause( p_owner->p_aout, paused, date );
1533 vlc_mutex_unlock( &p_owner->lock );
1534 break;
1535 case SPU_ES:
1536 break;
1537 default:
1538 vlc_assert_unreachable();
1542 static void DecoderThread_ChangeRate( vlc_input_decoder_t *p_owner, float rate )
1544 decoder_t *p_dec = &p_owner->dec;
1546 msg_Dbg( p_dec, "changing rate: %f", rate );
1547 vlc_mutex_lock( &p_owner->lock );
1548 switch( p_dec->fmt_out.i_cat )
1550 case VIDEO_ES:
1551 if( p_owner->p_vout != NULL && p_owner->vout_started )
1552 vout_ChangeRate( p_owner->p_vout, rate );
1553 break;
1554 case AUDIO_ES:
1555 if( p_owner->p_aout != NULL )
1556 aout_DecChangeRate( p_owner->p_aout, rate );
1557 break;
1558 case SPU_ES:
1559 if( p_owner->p_vout != NULL )
1561 assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
1562 vout_ChangeSpuRate(p_owner->p_vout, p_owner->i_spu_channel,
1563 rate );
1565 break;
1566 default:
1567 vlc_assert_unreachable();
1569 p_owner->output_rate = rate;
1570 vlc_mutex_unlock( &p_owner->lock );
1573 static void DecoderThread_ChangeDelay( vlc_input_decoder_t *p_owner, vlc_tick_t delay )
1575 decoder_t *p_dec = &p_owner->dec;
1577 msg_Dbg( p_dec, "changing delay: %"PRId64, delay );
1579 switch( p_dec->fmt_out.i_cat )
1581 case VIDEO_ES:
1582 vlc_mutex_lock( &p_owner->lock );
1583 if( p_owner->p_vout != NULL && p_owner->vout_started )
1584 vout_ChangeDelay( p_owner->p_vout, delay );
1585 vlc_mutex_unlock( &p_owner->lock );
1586 break;
1587 case AUDIO_ES:
1588 vlc_mutex_lock( &p_owner->lock );
1589 if( p_owner->p_aout != NULL )
1590 aout_DecChangeDelay( p_owner->p_aout, delay );
1591 vlc_mutex_unlock( &p_owner->lock );
1592 break;
1593 case SPU_ES:
1594 vlc_mutex_lock( &p_owner->lock );
1595 if( p_owner->p_vout != NULL )
1597 assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
1598 vout_ChangeSpuDelay(p_owner->p_vout, p_owner->i_spu_channel,
1599 delay);
1601 vlc_mutex_unlock( &p_owner->lock );
1602 break;
1603 default:
1604 vlc_assert_unreachable();
1609 * The decoding main loop
1611 * \param p_dec the decoder
1613 static void *DecoderThread( void *p_data )
1615 vlc_input_decoder_t *p_owner = (vlc_input_decoder_t *)p_data;
1616 float rate = 1.f;
1617 vlc_tick_t delay = 0;
1618 bool paused = false;
1620 /* The decoder's main loop */
1621 vlc_fifo_Lock( p_owner->p_fifo );
1623 while( !p_owner->aborting )
1625 if( p_owner->flushing )
1626 { /* Flush before/regardless of pause. We do not want to resume just
1627 * for the sake of flushing (glitches could otherwise happen). */
1628 vlc_fifo_Unlock( p_owner->p_fifo );
1630 /* Flush the decoder (and the output) */
1631 DecoderThread_Flush( p_owner );
1633 vlc_fifo_Lock( p_owner->p_fifo );
1635 /* Reset flushing after DecoderThread_ProcessInput in case vlc_input_decoder_Flush
1636 * is called again. This will avoid a second useless flush (but
1637 * harmless). */
1638 p_owner->flushing = false;
1640 continue;
1643 /* Reset the original pause/rate state when a new aout/vout is created:
1644 * this will trigger the DecoderThread_ChangePause/DecoderThread_ChangeRate code path
1645 * if needed. */
1646 if( p_owner->reset_out_state )
1648 rate = 1.f;
1649 paused = false;
1650 delay = 0;
1651 p_owner->reset_out_state = false;
1654 if( paused != p_owner->paused )
1655 { /* Update playing/paused status of the output */
1656 vlc_tick_t date = p_owner->pause_date;
1658 paused = p_owner->paused;
1659 vlc_fifo_Unlock( p_owner->p_fifo );
1661 DecoderThread_ChangePause( p_owner, paused, date );
1663 vlc_fifo_Lock( p_owner->p_fifo );
1664 continue;
1667 if( rate != p_owner->request_rate )
1669 rate = p_owner->request_rate;
1670 vlc_fifo_Unlock( p_owner->p_fifo );
1672 DecoderThread_ChangeRate( p_owner, rate );
1674 vlc_fifo_Lock( p_owner->p_fifo );
1675 continue;
1678 if( delay != p_owner->delay )
1680 delay = p_owner->delay;
1681 vlc_fifo_Unlock( p_owner->p_fifo );
1683 DecoderThread_ChangeDelay( p_owner, delay );
1685 vlc_fifo_Lock( p_owner->p_fifo );
1686 continue;
1689 if( p_owner->paused && p_owner->frames_countdown == 0 )
1690 { /* Wait for resumption from pause */
1691 p_owner->b_idle = true;
1692 vlc_cond_signal( &p_owner->wait_acknowledge );
1693 vlc_fifo_Wait( p_owner->p_fifo );
1694 p_owner->b_idle = false;
1695 continue;
1698 vlc_cond_signal( &p_owner->wait_fifo );
1700 block_t *p_block = vlc_fifo_DequeueUnlocked( p_owner->p_fifo );
1701 if( p_block == NULL )
1703 if( likely(!p_owner->b_draining) )
1704 { /* Wait for a block to decode (or a request to drain) */
1705 p_owner->b_idle = true;
1706 vlc_cond_signal( &p_owner->wait_acknowledge );
1707 vlc_fifo_Wait( p_owner->p_fifo );
1708 p_owner->b_idle = false;
1709 continue;
1711 /* We have emptied the FIFO and there is a pending request to
1712 * drain. Pass p_block = NULL to decoder just once. */
1715 vlc_fifo_Unlock( p_owner->p_fifo );
1717 DecoderThread_ProcessInput( p_owner, p_block );
1719 if( p_block == NULL && p_owner->dec.fmt_out.i_cat == AUDIO_ES )
1720 { /* Draining: the decoder is drained and all decoded buffers are
1721 * queued to the output at this point. Now drain the output. */
1722 if( p_owner->p_aout != NULL )
1723 aout_DecDrain( p_owner->p_aout );
1726 /* TODO? Wait for draining instead of polling. */
1727 vlc_mutex_lock( &p_owner->lock );
1728 vlc_fifo_Lock( p_owner->p_fifo );
1729 if( p_owner->b_draining && (p_block == NULL) )
1731 p_owner->b_draining = false;
1732 p_owner->drained = true;
1734 vlc_cond_signal( &p_owner->wait_acknowledge );
1735 vlc_mutex_unlock( &p_owner->lock );
1738 vlc_fifo_Unlock( p_owner->p_fifo );
1739 return NULL;
1742 static const struct decoder_owner_callbacks dec_video_cbs =
1744 .video = {
1745 .get_device = ModuleThread_GetDecoderDevice,
1746 .format_update = ModuleThread_UpdateVideoFormat,
1747 .buffer_new = ModuleThread_NewVideoBuffer,
1748 .queue = ModuleThread_QueueVideo,
1749 .queue_cc = ModuleThread_QueueCc,
1750 .get_display_date = ModuleThread_GetDisplayDate,
1751 .get_display_rate = ModuleThread_GetDisplayRate,
1753 .get_attachments = InputThread_GetInputAttachments,
1755 static const struct decoder_owner_callbacks dec_thumbnailer_cbs =
1757 .video = {
1758 .get_device = thumbnailer_get_device,
1759 .buffer_new = thumbnailer_buffer_new,
1760 .queue = ModuleThread_QueueThumbnail,
1762 .get_attachments = InputThread_GetInputAttachments,
1764 static const struct decoder_owner_callbacks dec_audio_cbs =
1766 .audio = {
1767 .format_update = ModuleThread_UpdateAudioFormat,
1768 .queue = ModuleThread_QueueAudio,
1770 .get_attachments = InputThread_GetInputAttachments,
1772 static const struct decoder_owner_callbacks dec_spu_cbs =
1774 .spu = {
1775 .buffer_new = ModuleThread_NewSpuBuffer,
1776 .queue = ModuleThread_QueueSpu,
1778 .get_attachments = InputThread_GetInputAttachments,
1782 * Create a decoder object
1784 * \param p_input the input thread
1785 * \param p_es the es descriptor
1786 * \param b_packetizer instead of a decoder
1787 * \return the decoder object
1789 static vlc_input_decoder_t *
1790 CreateDecoder( vlc_object_t *p_parent,
1791 const es_format_t *fmt, vlc_clock_t *p_clock,
1792 input_resource_t *p_resource, sout_instance_t *p_sout,
1793 bool b_thumbnailing, const struct vlc_input_decoder_callbacks *cbs,
1794 void *cbs_userdata )
1796 decoder_t *p_dec;
1797 vlc_input_decoder_t *p_owner;
1798 static_assert(offsetof(vlc_input_decoder_t, dec) == 0,
1799 "the decoder must be first in the owner structure");
1801 p_owner = vlc_custom_create( p_parent, sizeof( *p_owner ), "decoder" );
1802 if( p_owner == NULL )
1803 return NULL;
1804 p_dec = &p_owner->dec;
1806 p_owner->p_clock = p_clock;
1807 p_owner->i_preroll_end = PREROLL_NONE;
1808 p_owner->p_resource = p_resource;
1809 p_owner->cbs = cbs;
1810 p_owner->cbs_userdata = cbs_userdata;
1811 p_owner->p_aout = NULL;
1812 p_owner->p_vout = NULL;
1813 p_owner->vout_started = false;
1814 p_owner->i_spu_channel = VOUT_SPU_CHANNEL_INVALID;
1815 p_owner->i_spu_order = 0;
1816 p_owner->p_sout = p_sout;
1817 p_owner->p_sout_input = NULL;
1818 p_owner->p_packetizer = NULL;
1820 atomic_init( &p_owner->b_fmt_description, false );
1821 p_owner->p_description = NULL;
1823 p_owner->reset_out_state = false;
1824 p_owner->delay = 0;
1825 p_owner->output_rate = p_owner->request_rate = 1.f;
1826 p_owner->paused = false;
1827 p_owner->pause_date = VLC_TICK_INVALID;
1828 p_owner->frames_countdown = 0;
1830 p_owner->b_waiting = false;
1831 p_owner->b_first = true;
1832 p_owner->b_has_data = false;
1834 p_owner->error = false;
1836 p_owner->flushing = false;
1837 p_owner->b_draining = false;
1838 p_owner->drained = false;
1839 atomic_init( &p_owner->reload, RELOAD_NO_REQUEST );
1840 p_owner->b_idle = false;
1842 p_owner->mouse_event = NULL;
1843 p_owner->mouse_opaque = NULL;
1845 es_format_Init( &p_owner->fmt, fmt->i_cat, 0 );
1847 /* decoder fifo */
1848 p_owner->p_fifo = block_FifoNew();
1849 if( unlikely(p_owner->p_fifo == NULL) )
1851 vlc_object_delete(p_dec);
1852 return NULL;
1855 vlc_mutex_init( &p_owner->lock );
1856 vlc_mutex_init( &p_owner->mouse_lock );
1857 vlc_cond_init( &p_owner->wait_request );
1858 vlc_cond_init( &p_owner->wait_acknowledge );
1859 vlc_cond_init( &p_owner->wait_fifo );
1861 /* Load a packetizer module if the input is not already packetized */
1862 if( p_sout == NULL && !fmt->b_packetized )
1864 p_owner->p_packetizer =
1865 vlc_custom_create( p_parent, sizeof( decoder_t ), "packetizer" );
1866 if( p_owner->p_packetizer )
1868 if( LoadDecoder( p_owner->p_packetizer, true, fmt ) )
1870 vlc_object_delete(p_owner->p_packetizer);
1871 p_owner->p_packetizer = NULL;
1873 else
1875 p_owner->p_packetizer->fmt_out.b_packetized = true;
1876 fmt = &p_owner->p_packetizer->fmt_out;
1881 switch( fmt->i_cat )
1883 case VIDEO_ES:
1884 if( !b_thumbnailing )
1885 p_dec->cbs = &dec_video_cbs;
1886 else
1887 p_dec->cbs = &dec_thumbnailer_cbs;
1888 break;
1889 case AUDIO_ES:
1890 p_dec->cbs = &dec_audio_cbs;
1891 break;
1892 case SPU_ES:
1893 p_dec->cbs = &dec_spu_cbs;
1894 break;
1895 default:
1896 msg_Err( p_dec, "unknown ES format" );
1897 return p_owner;
1900 /* Find a suitable decoder/packetizer module */
1901 if( LoadDecoder( p_dec, p_sout != NULL, fmt ) )
1902 return p_owner;
1904 assert( p_dec->fmt_in.i_cat == p_dec->fmt_out.i_cat && fmt->i_cat == p_dec->fmt_in.i_cat);
1906 /* Copy ourself the input replay gain */
1907 if( fmt->i_cat == AUDIO_ES )
1909 for( unsigned i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
1911 if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
1913 p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
1914 p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
1916 if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
1918 p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
1919 p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
1924 /* */
1925 p_owner->cc.b_supported = ( p_sout == NULL );
1927 p_owner->cc.desc.i_608_channels = 0;
1928 p_owner->cc.desc.i_708_channels = 0;
1929 for( unsigned i = 0; i < MAX_CC_DECODERS; i++ )
1930 p_owner->cc.pp_decoder[i] = NULL;
1931 p_owner->cc.p_sout_input = NULL;
1932 p_owner->cc.b_sout_created = false;
1933 return p_owner;
1937 * Destroys a decoder object
1939 * \param p_dec the decoder object
1940 * \return nothing
1942 static void DeleteDecoder( vlc_input_decoder_t *p_owner )
1944 decoder_t *p_dec = &p_owner->dec;
1945 msg_Dbg( p_dec, "killing decoder fourcc `%4.4s'",
1946 (char*)&p_dec->fmt_in.i_codec );
1948 const enum es_format_category_e i_cat =p_dec->fmt_in.i_cat;
1949 decoder_Clean( p_dec );
1950 if ( p_owner->out_pool )
1952 picture_pool_Release( p_owner->out_pool );
1953 p_owner->out_pool = NULL;
1956 if (p_owner->vctx)
1957 vlc_video_context_Release( p_owner->vctx );
1959 /* Free all packets still in the decoder fifo. */
1960 block_FifoRelease( p_owner->p_fifo );
1962 /* Cleanup */
1963 #ifdef ENABLE_SOUT
1964 if( p_owner->p_sout_input )
1966 sout_InputDelete( p_owner->p_sout, p_owner->p_sout_input );
1967 if( p_owner->cc.p_sout_input )
1968 sout_InputDelete( p_owner->p_sout, p_owner->cc.p_sout_input );
1970 #endif
1972 switch( i_cat )
1974 case AUDIO_ES:
1975 if( p_owner->p_aout )
1977 /* TODO: REVISIT gap-less audio */
1978 aout_DecDelete( p_owner->p_aout );
1979 input_resource_PutAout( p_owner->p_resource, p_owner->p_aout );
1981 break;
1982 case VIDEO_ES: {
1983 vout_thread_t *vout = p_owner->p_vout;
1985 if (vout != NULL)
1987 /* Hold the vout since PutVout will likely release it and a
1988 * last reference is needed for notify callbacks */
1989 vout_Hold(vout);
1991 bool has_stopped;
1992 input_resource_PutVout(p_owner->p_resource, vout, &has_stopped);
1993 if (has_stopped)
1994 decoder_Notify(p_owner, on_vout_stopped, vout);
1996 vout_Release(vout);
1998 break;
2000 case SPU_ES:
2002 if( p_owner->p_vout )
2004 assert( p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID );
2005 decoder_Notify(p_owner, on_vout_stopped, p_owner->p_vout);
2007 vout_UnregisterSubpictureChannel( p_owner->p_vout,
2008 p_owner->i_spu_channel );
2009 vout_Release(p_owner->p_vout);
2011 break;
2013 case DATA_ES:
2014 case UNKNOWN_ES:
2015 break;
2016 default:
2017 vlc_assert_unreachable();
2020 es_format_Clean( &p_owner->fmt );
2022 if( p_owner->p_description )
2023 vlc_meta_Delete( p_owner->p_description );
2025 decoder_Destroy( p_owner->p_packetizer );
2026 decoder_Destroy( &p_owner->dec );
2029 /* */
2030 static void DecoderUnsupportedCodec( decoder_t *p_dec, const es_format_t *fmt, bool b_decoding )
2032 if (fmt->i_codec != VLC_CODEC_UNKNOWN && fmt->i_codec) {
2033 const char *desc = vlc_fourcc_GetDescription(fmt->i_cat, fmt->i_codec);
2034 if (!desc || !*desc)
2035 desc = N_("No description for this codec");
2036 msg_Err( p_dec, "Codec `%4.4s' (%s) is not supported.", (char*)&fmt->i_codec, desc );
2037 vlc_dialog_display_error( p_dec, _("Codec not supported"),
2038 _("VLC could not decode the format \"%4.4s\" (%s)"),
2039 (char*)&fmt->i_codec, desc );
2040 } else if( b_decoding ){
2041 msg_Err( p_dec, "could not identify codec" );
2042 vlc_dialog_display_error( p_dec, _("Unidentified codec"),
2043 _("VLC could not identify the audio or video codec" ) );
2047 /* TODO: pass p_sout through p_resource? -- Courmisch */
2048 static vlc_input_decoder_t *
2049 decoder_New( vlc_object_t *p_parent, const es_format_t *fmt,
2050 vlc_clock_t *p_clock, input_resource_t *p_resource,
2051 sout_instance_t *p_sout, bool thumbnailing,
2052 const struct vlc_input_decoder_callbacks *cbs, void *userdata)
2054 const char *psz_type = p_sout ? N_("packetizer") : N_("decoder");
2055 int i_priority;
2057 /* Create the decoder configuration structure */
2058 vlc_input_decoder_t *p_owner =
2059 CreateDecoder( p_parent, fmt, p_clock, p_resource, p_sout,
2060 thumbnailing, cbs, userdata );
2061 if( p_owner == NULL )
2063 msg_Err( p_parent, "could not create %s", psz_type );
2064 vlc_dialog_display_error( p_parent, _("Streaming / Transcoding failed"),
2065 _("VLC could not open the %s module."), vlc_gettext( psz_type ) );
2066 return NULL;
2069 decoder_t *p_dec = &p_owner->dec;
2070 if( !p_dec->p_module )
2072 DecoderUnsupportedCodec( p_dec, fmt, !p_sout );
2074 DeleteDecoder( p_owner );
2075 return NULL;
2078 assert( p_dec->fmt_in.i_cat != UNKNOWN_ES );
2080 #if VLC_THREAD_PRIORITY_AUDIO != VLC_THREAD_PRIORITY_VIDEO
2081 if( p_dec->fmt_in.i_cat == AUDIO_ES )
2082 i_priority = VLC_THREAD_PRIORITY_AUDIO;
2083 else
2084 #endif
2085 i_priority = VLC_THREAD_PRIORITY_VIDEO;
2087 #ifdef ENABLE_SOUT
2088 /* Do not delay sout creation for SPU or DATA. */
2089 if( p_sout && fmt->b_packetized &&
2090 (fmt->i_cat != VIDEO_ES && fmt->i_cat != AUDIO_ES) )
2092 p_owner->p_sout_input = sout_InputNew( p_owner->p_sout, fmt );
2093 if( p_owner->p_sout_input == NULL )
2095 msg_Err( p_dec, "cannot create sout input (%4.4s)",
2096 (char *)&fmt->i_codec );
2097 p_owner->error = true;
2100 #endif
2102 /* Spawn the decoder thread */
2103 if( vlc_clone( &p_owner->thread, DecoderThread, p_owner, i_priority ) )
2105 msg_Err( p_dec, "cannot spawn decoder thread" );
2106 DeleteDecoder( p_owner );
2107 return NULL;
2110 return p_owner;
2115 * Spawns a new decoder thread from the input thread
2117 * \param p_input the input thread
2118 * \param p_es the es descriptor
2119 * \return the spawned decoder object
2121 vlc_input_decoder_t *
2122 vlc_input_decoder_New( vlc_object_t *parent, es_format_t *fmt,
2123 vlc_clock_t *p_clock, input_resource_t *resource,
2124 sout_instance_t *p_sout, bool thumbnailing,
2125 const struct vlc_input_decoder_callbacks *cbs,
2126 void *cbs_userdata)
2128 return decoder_New( parent, fmt, p_clock, resource, p_sout, thumbnailing,
2129 cbs, cbs_userdata );
2133 * Spawn a decoder thread outside of the input thread.
2135 vlc_input_decoder_t *
2136 vlc_input_decoder_Create( vlc_object_t *p_parent, const es_format_t *fmt,
2137 input_resource_t *p_resource )
2139 return decoder_New( p_parent, fmt, NULL, p_resource, NULL, false, NULL,
2140 NULL );
2145 * Kills a decoder thread and waits until it's finished
2147 * \param p_input the input thread
2148 * \param p_es the es descriptor
2149 * \return nothing
2151 void vlc_input_decoder_Delete( vlc_input_decoder_t *p_owner )
2153 decoder_t *p_dec = &p_owner->dec;
2155 vlc_fifo_Lock( p_owner->p_fifo );
2156 p_owner->aborting = true;
2157 p_owner->flushing = true;
2158 vlc_fifo_Signal( p_owner->p_fifo );
2159 vlc_fifo_Unlock( p_owner->p_fifo );
2161 /* Make sure we aren't waiting/decoding anymore */
2162 vlc_mutex_lock( &p_owner->lock );
2163 p_owner->b_waiting = false;
2164 vlc_cond_signal( &p_owner->wait_request );
2166 /* If the video output is paused or slow, or if the picture pool size was
2167 * under-estimated (e.g. greedy video filter, buggy decoder...), the
2168 * the picture pool may be empty, and the decoder thread or any decoder
2169 * module worker threads may be stuck waiting for free picture buffers.
2171 * This unblocks the thread, allowing the decoder module to join all its
2172 * worker threads (if any) and the decoder thread to terminate. */
2173 if( p_dec->fmt_in.i_cat == VIDEO_ES && p_owner->p_vout != NULL
2174 && p_owner->vout_started )
2176 if (p_owner->out_pool)
2177 picture_pool_Cancel( p_owner->out_pool, true );
2179 if( p_owner->paused )
2181 /* The DecoderThread could be stuck in pf_decode(). This is likely the
2182 * case with paused asynchronous decoder modules that have a limited
2183 * input and output pool size. Indeed, with such decoders, you have to
2184 * release an output buffer to get an input buffer. So, when paused and
2185 * flushed, the DecoderThread could be waiting for an output buffer to
2186 * be released (or rendered). In that case, the DecoderThread will
2187 * never be flushed since it be never leave pf_decode(). To fix this
2188 * issue, pre-flush the vout from here. The vout will have to be
2189 * flushed again since the module could be outputting more buffers just
2190 * after being unstuck. */
2192 vout_FlushAll( p_owner->p_vout );
2195 vlc_mutex_unlock( &p_owner->lock );
2197 vlc_join( p_owner->thread, NULL );
2199 /* */
2200 if( p_owner->cc.b_supported )
2202 for( int i = 0; i < MAX_CC_DECODERS; i++ )
2203 vlc_input_decoder_SetCcState( p_owner, VLC_CODEC_CEA608, i, false );
2206 /* Delete decoder */
2207 DeleteDecoder( p_owner );
2211 * Put a block_t in the decoder's fifo.
2212 * Thread-safe w.r.t. the decoder. May be a cancellation point.
2214 * \param p_dec the decoder object
2215 * \param p_block the data block
2217 void vlc_input_decoder_Decode( vlc_input_decoder_t *p_owner, block_t *p_block,
2218 bool b_do_pace )
2220 vlc_fifo_Lock( p_owner->p_fifo );
2221 if( !b_do_pace )
2223 /* FIXME: ideally we would check the time amount of data
2224 * in the FIFO instead of its size. */
2225 /* 400 MiB, i.e. ~ 50mb/s for 60s */
2226 if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )
2228 msg_Warn( &p_owner->dec, "decoder/packetizer fifo full (data not "
2229 "consumed quickly enough), resetting fifo!" );
2230 block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2231 p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2234 else
2235 if( !p_owner->b_waiting )
2236 { /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
2237 * Locking is not necessary as b_waiting is only read, not written by
2238 * the decoder thread. */
2239 while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
2240 vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_fifo );
2243 vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
2244 vlc_fifo_Unlock( p_owner->p_fifo );
2247 bool vlc_input_decoder_IsEmpty( vlc_input_decoder_t * p_owner )
2249 assert( !p_owner->b_waiting );
2251 vlc_fifo_Lock( p_owner->p_fifo );
2252 if( !vlc_fifo_IsEmpty( p_owner->p_fifo ) || p_owner->b_draining )
2254 vlc_fifo_Unlock( p_owner->p_fifo );
2255 return false;
2257 vlc_fifo_Unlock( p_owner->p_fifo );
2259 bool b_empty;
2261 vlc_mutex_lock( &p_owner->lock );
2262 #ifdef ENABLE_SOUT
2263 if( p_owner->p_sout_input != NULL )
2264 b_empty = true;
2265 else
2266 #endif
2267 if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->p_vout != NULL )
2268 b_empty = vout_IsEmpty( p_owner->p_vout );
2269 else if( p_owner->fmt.i_cat == AUDIO_ES )
2270 b_empty = !p_owner->b_draining || p_owner->drained;
2271 else
2272 b_empty = true; /* TODO subtitles support */
2273 vlc_mutex_unlock( &p_owner->lock );
2275 return b_empty;
2279 * Signals that there are no further blocks to decode, and requests that the
2280 * decoder drain all pending buffers. This is used to ensure that all
2281 * intermediate buffers empty and no samples get lost at the end of the stream.
2283 * @note The function does not actually wait for draining. It just signals that
2284 * draining should be performed once the decoder has emptied FIFO.
2286 void vlc_input_decoder_Drain( vlc_input_decoder_t *p_owner )
2288 vlc_fifo_Lock( p_owner->p_fifo );
2289 p_owner->b_draining = true;
2290 vlc_fifo_Signal( p_owner->p_fifo );
2291 vlc_fifo_Unlock( p_owner->p_fifo );
2295 * Requests that the decoder immediately discard all pending buffers.
2296 * This is useful when seeking or when deselecting a stream.
2298 void vlc_input_decoder_Flush( vlc_input_decoder_t *p_owner )
2300 enum es_format_category_e cat = p_owner->dec.fmt_in.i_cat;
2302 vlc_fifo_Lock( p_owner->p_fifo );
2304 /* Empty the fifo */
2305 block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2307 /* Don't need to wait for the DecoderThread to flush. Indeed, if called a
2308 * second time, this function will clear the FIFO again before anything was
2309 * dequeued by DecoderThread and there is no need to flush a second time in
2310 * a row. */
2311 p_owner->flushing = true;
2313 /* Flush video/spu decoder when paused: increment frames_countdown in order
2314 * to display one frame/subtitle */
2315 if( p_owner->paused && ( cat == VIDEO_ES || cat == SPU_ES )
2316 && p_owner->frames_countdown == 0 )
2317 p_owner->frames_countdown++;
2319 vlc_fifo_Signal( p_owner->p_fifo );
2321 vlc_fifo_Unlock( p_owner->p_fifo );
2323 if ( cat == VIDEO_ES )
2325 /* Set the pool cancel state. This will unblock the module if it is
2326 * waiting for new pictures (likely). This state will be reset back
2327 * from the DecoderThread once the flush request is processed. */
2328 vlc_mutex_lock( &p_owner->lock );
2329 if( p_owner->out_pool != NULL )
2330 picture_pool_Cancel( p_owner->out_pool, true );
2331 vlc_mutex_unlock( &p_owner->lock );
2334 if( p_owner->paused )
2336 /* The DecoderThread could be stuck in pf_decode(). This is likely the
2337 * case with paused asynchronous decoder modules that have a limited
2338 * input and output pool size. Indeed, with such decoders, you have to
2339 * release an output buffer to get an input buffer. So, when paused and
2340 * flushed, the DecoderThread could be waiting for an output buffer to
2341 * be released (or rendered). In that case, the DecoderThread will
2342 * never be flushed since it be never leave pf_decode(). To fix this
2343 * issue, pre-flush the vout from here. The vout will have to be
2344 * flushed again since the module could be outputting more buffers just
2345 * after being unstuck. */
2347 vlc_mutex_lock( &p_owner->lock );
2348 if( cat == VIDEO_ES && p_owner->p_vout && p_owner->vout_started )
2349 vout_FlushAll( p_owner->p_vout );
2350 vlc_mutex_unlock( &p_owner->lock );
2354 void vlc_input_decoder_GetCcDesc( vlc_input_decoder_t *p_owner,
2355 decoder_cc_desc_t *p_desc )
2357 vlc_mutex_lock( &p_owner->lock );
2358 *p_desc = p_owner->cc.desc;
2359 vlc_mutex_unlock( &p_owner->lock );
2362 static bool vlc_input_decoder_HasCCChanFlag( vlc_input_decoder_t *p_owner,
2363 vlc_fourcc_t codec, int i_channel )
2365 int i_max_channels;
2366 uint64_t i_bitmap;
2367 if( codec == VLC_CODEC_CEA608 )
2369 i_max_channels = 4;
2370 i_bitmap = p_owner->cc.desc.i_608_channels;
2372 else if( codec == VLC_CODEC_CEA708 )
2374 i_max_channels = 64;
2375 i_bitmap = p_owner->cc.desc.i_708_channels;
2377 else return false;
2379 return ( i_channel >= 0 && i_channel < i_max_channels &&
2380 ( i_bitmap & ((uint64_t)1 << i_channel) ) );
2383 int vlc_input_decoder_SetCcState( vlc_input_decoder_t *p_owner, vlc_fourcc_t codec,
2384 int i_channel, bool b_decode )
2386 decoder_t *p_dec = &p_owner->dec;
2387 //msg_Warn( p_dec, "vlc_input_decoder_SetCcState: %d @%x", b_decode, i_channel );
2389 if( !vlc_input_decoder_HasCCChanFlag( p_owner, codec, i_channel ) )
2390 return VLC_EGENERIC;
2392 if( b_decode )
2394 vlc_input_decoder_t *p_ccowner;
2395 es_format_t fmt;
2397 es_format_Init( &fmt, SPU_ES, codec );
2398 fmt.subs.cc.i_channel = i_channel;
2399 fmt.subs.cc.i_reorder_depth = p_owner->cc.desc.i_reorder_depth;
2400 p_ccowner = vlc_input_decoder_New( VLC_OBJECT(p_dec), &fmt, p_owner->p_clock,
2401 p_owner->p_resource, p_owner->p_sout, false,
2402 NULL, NULL );
2403 if( !p_ccowner )
2405 msg_Err( p_dec, "could not create decoder" );
2406 vlc_dialog_display_error( p_dec,
2407 _("Streaming / Transcoding failed"), "%s",
2408 _("VLC could not open the decoder module.") );
2409 return VLC_EGENERIC;
2411 else if( !p_ccowner->dec.p_module )
2413 DecoderUnsupportedCodec( p_dec, &fmt, true );
2414 vlc_input_decoder_Delete(p_ccowner);
2415 return VLC_EGENERIC;
2417 p_ccowner->p_clock = p_owner->p_clock;
2419 vlc_mutex_lock( &p_owner->lock );
2420 p_owner->cc.pp_decoder[i_channel] = p_ccowner;
2421 vlc_mutex_unlock( &p_owner->lock );
2423 else
2425 vlc_input_decoder_t *p_cc;
2427 vlc_mutex_lock( &p_owner->lock );
2428 p_cc = p_owner->cc.pp_decoder[i_channel];
2429 p_owner->cc.pp_decoder[i_channel] = NULL;
2430 vlc_mutex_unlock( &p_owner->lock );
2432 if( p_cc )
2433 vlc_input_decoder_Delete(p_cc);
2435 return VLC_SUCCESS;
2438 int vlc_input_decoder_GetCcState( vlc_input_decoder_t *p_owner, vlc_fourcc_t codec,
2439 int i_channel, bool *pb_decode )
2441 if( !vlc_input_decoder_HasCCChanFlag( p_owner, codec, i_channel ) )
2442 return VLC_EGENERIC;
2444 vlc_mutex_lock( &p_owner->lock );
2445 *pb_decode = p_owner->cc.pp_decoder[i_channel] != NULL;
2446 vlc_mutex_unlock( &p_owner->lock );
2447 return VLC_SUCCESS;
2450 void vlc_input_decoder_ChangePause( vlc_input_decoder_t *p_owner,
2451 bool b_paused, vlc_tick_t i_date )
2453 /* Normally, p_owner->b_paused != b_paused here. But if a track is added
2454 * while the input is paused (e.g. add sub file), then b_paused is
2455 * (incorrectly) false. FIXME: This is a bug in the decoder owner. */
2456 vlc_fifo_Lock( p_owner->p_fifo );
2457 p_owner->paused = b_paused;
2458 p_owner->pause_date = i_date;
2459 p_owner->frames_countdown = 0;
2460 vlc_fifo_Signal( p_owner->p_fifo );
2461 vlc_fifo_Unlock( p_owner->p_fifo );
2464 void vlc_input_decoder_ChangeRate( vlc_input_decoder_t *owner, float rate )
2466 vlc_fifo_Lock( owner->p_fifo );
2467 owner->request_rate = rate;
2468 vlc_fifo_Unlock( owner->p_fifo );
2471 void vlc_input_decoder_ChangeDelay( vlc_input_decoder_t *owner, vlc_tick_t delay )
2473 vlc_fifo_Lock( owner->p_fifo );
2474 owner->delay = delay;
2475 vlc_fifo_Unlock( owner->p_fifo );
2478 void vlc_input_decoder_StartWait( vlc_input_decoder_t *p_owner )
2480 assert( !p_owner->b_waiting );
2482 vlc_mutex_lock( &p_owner->lock );
2483 p_owner->b_first = true;
2484 p_owner->b_has_data = false;
2485 p_owner->b_waiting = true;
2486 vlc_cond_signal( &p_owner->wait_request );
2487 vlc_mutex_unlock( &p_owner->lock );
2490 void vlc_input_decoder_StopWait( vlc_input_decoder_t *p_owner )
2492 assert( p_owner->b_waiting );
2494 vlc_mutex_lock( &p_owner->lock );
2495 p_owner->b_waiting = false;
2496 vlc_cond_signal( &p_owner->wait_request );
2497 vlc_mutex_unlock( &p_owner->lock );
2500 void vlc_input_decoder_Wait( vlc_input_decoder_t *p_owner )
2502 assert( p_owner->b_waiting );
2504 vlc_mutex_lock( &p_owner->lock );
2505 while( !p_owner->b_has_data )
2507 /* Don't need to lock p_owner->paused since it's only modified by the
2508 * owner */
2509 if( p_owner->paused )
2510 break;
2511 vlc_fifo_Lock( p_owner->p_fifo );
2512 if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
2514 msg_Err( &p_owner->dec, "buffer deadlock prevented" );
2515 vlc_fifo_Unlock( p_owner->p_fifo );
2516 break;
2518 vlc_fifo_Unlock( p_owner->p_fifo );
2519 vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
2521 vlc_mutex_unlock( &p_owner->lock );
2524 void vlc_input_decoder_FrameNext( vlc_input_decoder_t *p_owner,
2525 vlc_tick_t *pi_duration )
2527 assert( p_owner->paused );
2528 *pi_duration = 0;
2530 vlc_fifo_Lock( p_owner->p_fifo );
2531 p_owner->frames_countdown++;
2532 vlc_fifo_Signal( p_owner->p_fifo );
2533 vlc_fifo_Unlock( p_owner->p_fifo );
2535 vlc_mutex_lock( &p_owner->lock );
2536 if( p_owner->dec.fmt_in.i_cat == VIDEO_ES )
2538 if( p_owner->p_vout )
2539 vout_NextPicture( p_owner->p_vout, pi_duration );
2541 vlc_mutex_unlock( &p_owner->lock );
2544 bool vlc_input_decoder_HasFormatChanged( vlc_input_decoder_t *p_owner,
2545 es_format_t *p_fmt, vlc_meta_t **pp_meta )
2547 if( !atomic_exchange_explicit( &p_owner->b_fmt_description, false,
2548 memory_order_acquire ) )
2549 return false;
2551 vlc_mutex_lock( &p_owner->lock );
2553 if( p_owner->fmt.i_cat == UNKNOWN_ES )
2555 /* The format changed but the output creation failed */
2556 vlc_mutex_unlock( &p_owner->lock );
2557 return false;
2560 if( p_fmt != NULL )
2561 es_format_Copy( p_fmt, &p_owner->fmt );
2563 if( pp_meta )
2565 *pp_meta = NULL;
2566 if( p_owner->p_description )
2568 *pp_meta = vlc_meta_New();
2569 if( *pp_meta )
2570 vlc_meta_Merge( *pp_meta, p_owner->p_description );
2573 vlc_mutex_unlock( &p_owner->lock );
2574 return true;
2577 size_t vlc_input_decoder_GetFifoSize( vlc_input_decoder_t *p_owner )
2579 return block_FifoSize( p_owner->p_fifo );
2582 static bool DecoderHasVbi( decoder_t *dec )
2584 return dec->fmt_in.i_cat == SPU_ES && dec->fmt_in.i_codec == VLC_CODEC_TELETEXT
2585 && var_Type( dec, "vbi-page" ) == VLC_VAR_INTEGER;
2588 int vlc_input_decoder_GetVbiPage( vlc_input_decoder_t *owner, bool *opaque )
2590 decoder_t *dec = &owner->dec;
2591 if( !DecoderHasVbi( dec ) )
2592 return -1;
2593 *opaque = var_GetBool( dec, "vbi-opaque" );
2594 return var_GetInteger( dec, "vbi-page" );
2597 int vlc_input_decoder_SetVbiPage( vlc_input_decoder_t *owner, unsigned page )
2599 decoder_t *dec = &owner->dec;
2600 if( !DecoderHasVbi( dec ) )
2601 return VLC_EGENERIC;
2602 return var_SetInteger( dec, "vbi-page", page );
2605 int vlc_input_decoder_SetVbiOpaque( vlc_input_decoder_t *owner, bool opaque )
2607 decoder_t *dec = &owner->dec;
2608 if( !DecoderHasVbi( dec ) )
2609 return VLC_EGENERIC;
2610 return var_SetBool( dec, "vbi-opaque", opaque );
2613 void vlc_input_decoder_SetVoutMouseEvent( vlc_input_decoder_t *owner,
2614 vlc_mouse_event mouse_event,
2615 void *user_data )
2617 assert( owner->dec.fmt_in.i_cat == VIDEO_ES );
2619 vlc_mutex_lock( &owner->mouse_lock );
2621 owner->mouse_event = mouse_event;
2622 owner->mouse_opaque = user_data;
2624 vlc_mutex_unlock( &owner->mouse_lock );
2627 int vlc_input_decoder_AddVoutOverlay( vlc_input_decoder_t *owner, subpicture_t *sub,
2628 size_t *channel )
2630 assert( owner->dec.fmt_in.i_cat == VIDEO_ES );
2631 assert( sub && channel );
2633 vlc_mutex_lock( &owner->lock );
2635 if( !owner->p_vout )
2637 vlc_mutex_unlock( &owner->lock );
2638 return VLC_EGENERIC;
2640 ssize_t channel_id =
2641 vout_RegisterSubpictureChannel( owner->p_vout );
2642 if (channel_id == -1)
2644 vlc_mutex_unlock( &owner->lock );
2645 return VLC_EGENERIC;
2647 sub->i_start = sub->i_stop = vlc_tick_now();
2648 sub->i_channel = *channel = channel_id;
2649 sub->i_order = 0;
2650 sub->b_ephemer = true;
2651 vout_PutSubpicture( owner->p_vout, sub );
2653 vlc_mutex_unlock( &owner->lock );
2654 return VLC_SUCCESS;
2657 int vlc_input_decoder_DelVoutOverlay( vlc_input_decoder_t *owner, size_t channel )
2659 assert( owner->dec.fmt_in.i_cat == VIDEO_ES );
2661 vlc_mutex_lock( &owner->lock );
2663 if( !owner->p_vout )
2665 vlc_mutex_unlock( &owner->lock );
2666 return VLC_EGENERIC;
2668 vout_UnregisterSubpictureChannel( owner->p_vout, channel );
2670 vlc_mutex_unlock( &owner->lock );
2671 return VLC_SUCCESS;
2674 int vlc_input_decoder_SetSpuHighlight( vlc_input_decoder_t *p_owner,
2675 const vlc_spu_highlight_t *spu_hl )
2677 assert( p_owner->dec.fmt_in.i_cat == SPU_ES );
2679 #ifdef ENABLE_SOUT
2680 if( p_owner->p_sout_input )
2681 sout_InputControl( p_owner->p_sout, p_owner->p_sout_input,
2682 SOUT_INPUT_SET_SPU_HIGHLIGHT, spu_hl );
2683 #endif
2685 vlc_mutex_lock( &p_owner->lock );
2686 if( !p_owner->p_vout )
2688 vlc_mutex_unlock( &p_owner->lock );
2689 return VLC_EGENERIC;
2692 vout_SetSpuHighlight( p_owner->p_vout, spu_hl );
2694 vlc_mutex_unlock( &p_owner->lock );
2695 return VLC_SUCCESS;