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 /*****************************************************************************
27 *****************************************************************************/
32 #include <stdatomic.h>
34 #include <vlc_common.h>
35 #include <vlc_block.h>
39 #include <vlc_codec.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"
54 #include "../video_output/vout_internal.h"
57 * Possibles values set in p_owner->reload atomic
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
69 input_resource_t
*p_resource
;
72 const struct vlc_input_decoder_callbacks
*cbs
;
75 ssize_t i_spu_channel
;
78 sout_instance_t
*p_sout
;
79 sout_packetizer_input_t
*p_sout_input
;
83 /* Some decoders require already packetized data (ie. not truncated) */
84 decoder_t
*p_packetizer
;
87 /* Current format in use by the output */
89 vlc_video_context
*vctx
;
92 atomic_bool b_fmt_description
;
93 vlc_meta_t
*p_description
;
99 /* Lock for communication with decoder thread */
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
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
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
;
132 enum vlc_vout_order vout_order
;
134 /* -- Theses variables need locking on read *and* write -- */
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
142 bool reset_out_state
;
143 vlc_tick_t pause_date
;
145 float request_rate
, output_rate
;
146 unsigned frames_countdown
;
164 #define MAX_CC_DECODERS 64 /* The es_out only creates one type of es */
168 decoder_cc_desc_t desc
;
169 vlc_input_decoder_t
*pp_decoder
[MAX_CC_DECODERS
];
171 sout_packetizer_input_t
*p_sout_input
;
175 vlc_mutex_t mouse_lock
;
176 vlc_mouse_event mouse_event
;
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))
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 */
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
],
220 p_dec
->p_module
= module_need_var( p_dec
, "packetizer", "packetizer" );
222 if( !p_dec
->p_module
)
224 decoder_Clean( p_dec
);
230 static int DecoderThread_Reload( vlc_input_decoder_t
*p_owner
,
231 const es_format_t
*restrict p_fmt
,
234 /* Copy p_fmt since it can be destroyed by decoder_Clean */
235 decoder_t
*p_dec
= &p_owner
->dec
;
237 if( es_format_Copy( &fmt_in
, p_fmt
) != VLC_SUCCESS
)
239 p_owner
->error
= true;
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
;
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
);
266 es_format_Clean( &fmt_in
);
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
]) )
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" );
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
);
376 if( aout_DecNew( p_aout
, &format
, p_dec
->fmt_out
.i_profile
,
378 &p_dec
->fmt_out
.audio_replay_gain
) )
380 input_resource_PutAout( p_owner
->p_resource
, p_aout
);
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
);
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
);
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)
417 if (created_vout
== 0)
419 // video context didn't change
420 if (vctx
!= NULL
&& p_owner
->vctx
== vctx
)
423 assert(p_owner
->p_vout
);
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
)
434 switch( p_dec
->fmt_in
.i_codec
)
438 case VLC_CODEC_DIRAC
: /* FIXME valid ? */
455 picture_pool_t
*pool
= picture_pool_NewFromFormat( &p_dec
->fmt_out
.video
,
456 dpb_size
+ p_dec
->i_extra_picture_buffers
+ 1 );
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
);
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
,
477 vout_thread_t
*p_vout
=
478 input_resource_RequestVout(p_owner
->p_resource
, vctx
, &cfg
, NULL
,
482 vlc_mutex_lock( &p_owner
->lock
);
483 p_owner
->vout_started
= true;
484 vlc_mutex_unlock( &p_owner
->lock
);
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
);
498 /* Clean fmt and vctx to trigger a new vout creation on the next update
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
;
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");
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");
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");
536 if( p_dec
->fmt_out
.i_codec
!= p_owner
->fmt
.video
.i_chroma
)
538 msg_Dbg(p_dec
, "vout change: chroma");
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");
547 if( p_dec
->fmt_out
.video
.orientation
!= p_owner
->fmt
.video
.orientation
)
549 msg_Dbg(p_dec
, "vout change: orientation");
552 if( p_dec
->fmt_out
.video
.multiview_mode
!= p_owner
->fmt
.video
.multiview_mode
)
554 msg_Dbg(p_dec
, "vout change: multiview");
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
);
583 picture_pool_Release( pool
);
587 msg_Err( p_dec
, "failed to create video output" );
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" ) )
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
);
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
);
646 picture_Reset( 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
;
658 while( i_attempts
-- )
663 p_vout
= input_resource_HoldVout( p_owner
->p_resource
);
667 vlc_tick_sleep( DECODER_SPU_VOUT_WAIT_DURATION
);
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
);
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
);
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
,
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
);
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
);
729 vout_Release(p_vout
);
731 p_subpic
= subpicture_New( p_updater
);
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;
742 static int InputThread_GetInputAttachments( decoder_t
*p_dec
,
743 input_attachment_t
***ppp_attachment
,
746 vlc_input_decoder_t
*p_owner
= dec_get_owner( p_dec
);
747 if (!p_owner
->cbs
|| !p_owner
->cbs
->get_attachments
)
750 int ret
= p_owner
->cbs
->get_attachments(p_owner
, ppp_attachment
,
751 p_owner
->cbs_userdata
);
754 *pi_attachment
= ret
;
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
)
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
)
781 vlc_mutex_lock( &p_owner
->lock
);
782 float rate
= p_owner
->output_rate
;
783 vlc_mutex_unlock( &p_owner
->lock
);
787 /*****************************************************************************
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;
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
);
819 if( !p_owner
->b_waiting
|| !p_owner
->b_has_data
)
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
);
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
,
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;
897 block_Release(p_block
);
899 block_ChainRelease(p_sout_block
);
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
);
919 if(!p_owner
->cc
.b_sout_created
)
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;
949 block_Release( p_block
);
951 block_ChainRelease( p_next
);
955 p_sout_block
= p_next
;
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
];
981 block_FifoPut( p_ccowner
->p_fifo
, block_Duplicate(p_cc
) );
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
)
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
)
1005 assert( p_dec_cc
->pf_get_cc
!= NULL
);
1007 p_cc
= p_dec_cc
->pf_get_cc( p_dec_cc
, &desc
);
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
);
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
);
1052 p_owner
->i_preroll_end
= PREROLL_NONE
;
1054 if( unlikely(prerolled
) )
1056 msg_Dbg( p_dec
, "end of video preroll" );
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
);
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
);
1104 static void ModuleThread_UpdateStatVideo( vlc_input_decoder_t
*p_owner
,
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
)
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
)
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
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
);
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
);
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
);
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
);
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
);
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
);
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
);
1240 static void ModuleThread_UpdateStatAudio( vlc_input_decoder_t
*p_owner
,
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
;
1269 if( p_subpic
->i_start
== VLC_TICK_INVALID
)
1271 msg_Warn( p_dec
, "non-dated spu buffer received" );
1272 subpicture_Delete( p_subpic
);
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
);
1294 vout_PutSubpicture( p_vout
, p_subpic
);
1297 static void ModuleThread_QueueSpu( decoder_t
*p_dec
, subpicture_t
*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
);
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
);
1329 case VLCDEC_SUCCESS
:
1331 case VLCDEC_ECRITICAL
:
1332 p_owner
->error
= true;
1335 RequestReload( p_owner
);
1336 if( unlikely( p_block
== NULL
) )
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
);
1347 vlc_assert_unreachable();
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
)
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. */
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
)
1378 bool packetize
= p_owner
->p_packetizer
!= NULL
;
1381 if( p_block
->i_buffer
<= 0 )
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 */
1395 if( p_owner
->p_sout
!= NULL
)
1397 DecoderThread_ProcessSout( p_owner
, p_block
);
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
);
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
);
1440 p_packetized_block
= p_next
;
1443 /* Drain the decoder after the packetizer is drained */
1445 DecoderThread_DecodeBlock( p_owner
, NULL
);
1448 DecoderThread_DecodeBlock( p_owner
, 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
)
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
);
1483 if ( p_owner
->p_sout_input
!= NULL
)
1485 sout_InputFlush( p_owner
->p_sout
, p_owner
->p_sout_input
);
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
)
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
);
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
);
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
)
1551 if( p_owner
->p_vout
!= NULL
&& p_owner
->vout_started
)
1552 vout_ChangeRate( p_owner
->p_vout
, rate
);
1555 if( p_owner
->p_aout
!= NULL
)
1556 aout_DecChangeRate( p_owner
->p_aout
, rate
);
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
,
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
)
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
);
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
);
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
,
1601 vlc_mutex_unlock( &p_owner
->lock
);
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
;
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
1638 p_owner
->flushing
= false;
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
1646 if( p_owner
->reset_out_state
)
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
);
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
);
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
);
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;
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;
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
);
1742 static const struct decoder_owner_callbacks dec_video_cbs
=
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
=
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
=
1767 .format_update
= ModuleThread_UpdateAudioFormat
,
1768 .queue
= ModuleThread_QueueAudio
,
1770 .get_attachments
= InputThread_GetInputAttachments
,
1772 static const struct decoder_owner_callbacks dec_spu_cbs
=
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
)
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
)
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
;
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;
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 );
1848 p_owner
->p_fifo
= block_FifoNew();
1849 if( unlikely(p_owner
->p_fifo
== NULL
) )
1851 vlc_object_delete(p_dec
);
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
;
1875 p_owner
->p_packetizer
->fmt_out
.b_packetized
= true;
1876 fmt
= &p_owner
->p_packetizer
->fmt_out
;
1881 switch( fmt
->i_cat
)
1884 if( !b_thumbnailing
)
1885 p_dec
->cbs
= &dec_video_cbs
;
1887 p_dec
->cbs
= &dec_thumbnailer_cbs
;
1890 p_dec
->cbs
= &dec_audio_cbs
;
1893 p_dec
->cbs
= &dec_spu_cbs
;
1896 msg_Err( p_dec
, "unknown ES format" );
1900 /* Find a suitable decoder/packetizer module */
1901 if( LoadDecoder( p_dec
, p_sout
!= NULL
, fmt
) )
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
];
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;
1937 * Destroys a decoder object
1939 * \param p_dec the decoder object
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
;
1957 vlc_video_context_Release( p_owner
->vctx
);
1959 /* Free all packets still in the decoder fifo. */
1960 block_FifoRelease( p_owner
->p_fifo
);
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
);
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
);
1983 vout_thread_t
*vout
= p_owner
->p_vout
;
1987 /* Hold the vout since PutVout will likely release it and a
1988 * last reference is needed for notify callbacks */
1992 input_resource_PutVout(p_owner
->p_resource
, vout
, &has_stopped
);
1994 decoder_Notify(p_owner
, on_vout_stopped
, vout
);
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
);
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
);
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");
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
) );
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
);
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
;
2085 i_priority
= VLC_THREAD_PRIORITY_VIDEO
;
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;
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
);
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
,
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
,
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
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
);
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
,
2220 vlc_fifo_Lock( p_owner
->p_fifo
);
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
;
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
);
2257 vlc_fifo_Unlock( p_owner
->p_fifo
);
2261 vlc_mutex_lock( &p_owner
->lock
);
2263 if( p_owner
->p_sout_input
!= NULL
)
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
;
2272 b_empty
= true; /* TODO subtitles support */
2273 vlc_mutex_unlock( &p_owner
->lock
);
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
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
)
2367 if( codec
== VLC_CODEC_CEA608
)
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
;
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
;
2394 vlc_input_decoder_t
*p_ccowner
;
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,
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
);
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
);
2433 vlc_input_decoder_Delete(p_cc
);
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
);
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
2509 if( p_owner
->paused
)
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
);
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
);
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
) )
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
);
2561 es_format_Copy( p_fmt
, &p_owner
->fmt
);
2566 if( p_owner
->p_description
)
2568 *pp_meta
= vlc_meta_New();
2570 vlc_meta_Merge( *pp_meta
, p_owner
->p_description
);
2573 vlc_mutex_unlock( &p_owner
->lock
);
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
) )
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
,
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
,
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
;
2650 sub
->b_ephemer
= true;
2651 vout_PutSubpicture( owner
->p_vout
, sub
);
2653 vlc_mutex_unlock( &owner
->lock
);
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
);
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
);
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
);
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
);