1 /*****************************************************************************
2 * decoder.c: Functions for the management of decoders
3 *****************************************************************************
4 * Copyright (C) 1999-2004 VLC authors and VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
9 * Laurent Aimar <fenrir@via.ecp.fr>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
34 #include <vlc_common.h>
36 #include <vlc_atomic.h>
37 #include <vlc_block.h>
41 #include <vlc_codec.h>
44 #include <vlc_dialog.h>
45 #include <vlc_modules.h>
47 #include "audio_output/aout_internal.h"
48 #include "stream_output/stream_output.h"
49 #include "input_internal.h"
55 #include "../video_output/vout_control.h"
58 * Possibles values set in p_owner->reload atomic
63 RELOAD_DECODER
, /* Reload the decoder module */
64 RELOAD_DECODER_AOUT
/* Stop the aout and reload the decoder module */
67 struct decoder_owner_sys_t
69 input_thread_t
*p_input
;
70 input_resource_t
*p_resource
;
71 input_clock_t
*p_clock
;
74 vout_thread_t
*p_spu_vout
;
78 sout_instance_t
*p_sout
;
79 sout_packetizer_input_t
*p_sout_input
;
83 void (*pf_update_stat
)( decoder_owner_sys_t
*, unsigned decoded
, unsigned lost
);
85 /* Some decoders require already packetized data (ie. not truncated) */
86 decoder_t
*p_packetizer
;
89 /* Current format in use by the output */
93 bool b_fmt_description
;
94 vlc_meta_t
*p_description
;
100 /* Lock for communication with decoder thread */
102 vlc_cond_t wait_request
;
103 vlc_cond_t wait_acknowledge
;
104 vlc_cond_t wait_fifo
; /* TODO: merge with wait_acknowledge */
105 vlc_cond_t wait_timed
;
107 /* -- These variables need locking on write(only) -- */
108 audio_output_t
*p_aout
;
110 vout_thread_t
*p_vout
;
112 /* -- Theses variables need locking on read *and* write -- */
114 int64_t i_preroll_end
;
117 unsigned frames_countdown
;
138 uint8_t i_reorder_depth
;
139 decoder_t
*pp_decoder
[4];
146 /* Pictures which are DECODER_BOGUS_VIDEO_DELAY or more in advance probably have
147 * a bogus PTS and won't be displayed */
148 #define DECODER_BOGUS_VIDEO_DELAY ((mtime_t)(DEFAULT_PTS_DELAY * 30))
151 #define DECODER_SPU_VOUT_WAIT_DURATION ((int)(0.200*CLOCK_FREQ))
152 #define BLOCK_FLAG_CORE_PRIVATE_RELOADED (1 << BLOCK_FLAG_CORE_PRIVATE_SHIFT)
155 * Load a decoder module
157 static int LoadDecoder( decoder_t
*p_dec
, bool b_packetizer
,
158 const es_format_t
*restrict p_fmt
)
160 p_dec
->b_frame_drop_allowed
= true;
161 p_dec
->i_extra_picture_buffers
= 0;
163 p_dec
->pf_decode
= NULL
;
164 p_dec
->pf_get_cc
= NULL
;
165 p_dec
->pf_packetize
= NULL
;
166 p_dec
->pf_flush
= NULL
;
168 es_format_Copy( &p_dec
->fmt_in
, p_fmt
);
169 es_format_Init( &p_dec
->fmt_out
, p_fmt
->i_cat
, 0 );
171 /* Find a suitable decoder/packetizer module */
174 const char caps
[ES_CATEGORY_COUNT
][16] = {
175 [VIDEO_ES
] = "video decoder",
176 [AUDIO_ES
] = "audio decoder",
177 [SPU_ES
] = "spu decoder",
179 p_dec
->p_module
= module_need( p_dec
, caps
[p_dec
->fmt_in
.i_cat
],
183 p_dec
->p_module
= module_need( p_dec
, "packetizer", "$packetizer", false );
185 if( !p_dec
->p_module
)
187 es_format_Clean( &p_dec
->fmt_in
);
195 * Unload a decoder module
197 static void UnloadDecoder( decoder_t
*p_dec
)
199 if( p_dec
->p_module
)
201 module_unneed( p_dec
, p_dec
->p_module
);
202 p_dec
->p_module
= NULL
;
205 if( p_dec
->p_description
)
207 vlc_meta_Delete( p_dec
->p_description
);
208 p_dec
->p_description
= NULL
;
211 es_format_Clean( &p_dec
->fmt_in
);
212 es_format_Clean( &p_dec
->fmt_out
);
215 static int ReloadDecoder( decoder_t
*p_dec
, bool b_packetizer
,
216 const es_format_t
*restrict p_fmt
, enum reload reload
)
218 /* Copy p_fmt since it can be destroyed by UnloadDecoder */
220 if( es_format_Copy( &fmt_in
, p_fmt
) != VLC_SUCCESS
)
222 p_dec
->p_owner
->error
= true;
226 /* Restart the decoder module */
227 UnloadDecoder( p_dec
);
228 p_dec
->p_owner
->error
= false;
230 if( reload
== RELOAD_DECODER_AOUT
)
232 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
233 assert( p_owner
->fmt
.i_cat
== AUDIO_ES
);
234 audio_output_t
*p_aout
= p_owner
->p_aout
;
236 vlc_mutex_lock( &p_owner
->lock
);
237 p_owner
->p_aout
= NULL
;
238 vlc_mutex_unlock( &p_owner
->lock
);
241 aout_DecDelete( p_aout
);
242 input_resource_PutAout( p_owner
->p_resource
, p_aout
);
246 if( LoadDecoder( p_dec
, b_packetizer
, &fmt_in
) )
248 p_dec
->p_owner
->error
= true;
249 es_format_Clean( &fmt_in
);
252 es_format_Clean( &fmt_in
);
256 static void DecoderUpdateFormatLocked( decoder_t
*p_dec
)
258 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
260 vlc_assert_locked( &p_owner
->lock
);
262 es_format_Clean( &p_owner
->fmt
);
263 es_format_Copy( &p_owner
->fmt
, &p_dec
->fmt_out
);
265 /* Move p_description */
266 if( p_dec
->p_description
!= NULL
)
268 if( p_owner
->p_description
!= NULL
)
269 vlc_meta_Delete( p_owner
->p_description
);
270 p_owner
->p_description
= p_dec
->p_description
;
271 p_dec
->p_description
= NULL
;
274 p_owner
->b_fmt_description
= true;
277 /*****************************************************************************
278 * Buffers allocation callbacks for the decoders
279 *****************************************************************************/
280 static vout_thread_t
*aout_request_vout( void *p_private
,
281 vout_thread_t
*p_vout
,
282 const video_format_t
*p_fmt
, bool b_recyle
)
284 decoder_t
*p_dec
= p_private
;
285 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
286 input_thread_t
*p_input
= p_owner
->p_input
;
288 p_vout
= input_resource_RequestVout( p_owner
->p_resource
, p_vout
, p_fmt
, 1,
290 if( p_input
!= NULL
)
291 input_SendEventVout( p_input
);
296 static bool aout_replaygain_changed( const audio_replay_gain_t
*a
,
297 const audio_replay_gain_t
*b
)
299 for( size_t i
=0; i
<AUDIO_REPLAY_GAIN_MAX
; i
++ )
301 if( a
->pb_gain
[i
] != b
->pb_gain
[i
] ||
302 a
->pb_peak
[i
] != b
->pb_peak
[i
] ||
303 a
->pb_gain
[i
] != b
->pb_gain
[i
] ||
304 a
->pb_peak
[i
] != b
->pb_peak
[i
] )
310 static int aout_update_format( decoder_t
*p_dec
)
312 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
314 if( p_owner
->p_aout
&&
315 ( !AOUT_FMTS_IDENTICAL(&p_dec
->fmt_out
.audio
, &p_owner
->fmt
.audio
) ||
316 p_dec
->fmt_out
.i_codec
!= p_dec
->fmt_out
.audio
.i_format
) )
318 audio_output_t
*p_aout
= p_owner
->p_aout
;
320 /* Parameters changed, restart the aout */
321 vlc_mutex_lock( &p_owner
->lock
);
322 p_owner
->p_aout
= NULL
;
323 vlc_mutex_unlock( &p_owner
->lock
);
324 aout_DecDelete( p_aout
);
326 input_resource_PutAout( p_owner
->p_resource
, p_aout
);
329 /* Check if only replay gain has changed */
330 if( aout_replaygain_changed( &p_dec
->fmt_in
.audio_replay_gain
,
331 &p_owner
->fmt
.audio_replay_gain
) )
333 p_dec
->fmt_out
.audio_replay_gain
= p_dec
->fmt_in
.audio_replay_gain
;
334 if( p_owner
->p_aout
)
336 p_owner
->fmt
.audio_replay_gain
= p_dec
->fmt_in
.audio_replay_gain
;
337 var_TriggerCallback( p_owner
->p_aout
, "audio-replay-gain-mode" );
341 if( p_owner
->p_aout
== NULL
)
343 p_dec
->fmt_out
.audio
.i_format
= p_dec
->fmt_out
.i_codec
;
345 audio_sample_format_t format
= p_dec
->fmt_out
.audio
;
346 aout_FormatPrepare( &format
);
348 const int i_force_dolby
= var_InheritInteger( p_dec
, "force-dolby-surround" );
350 (format
.i_original_channels
&AOUT_CHAN_PHYSMASK
) ==
351 (AOUT_CHAN_LEFT
|AOUT_CHAN_RIGHT
) )
353 if( i_force_dolby
== 1 )
355 format
.i_original_channels
= format
.i_original_channels
|
356 AOUT_CHAN_DOLBYSTEREO
;
358 else /* i_force_dolby == 2 */
360 format
.i_original_channels
= format
.i_original_channels
&
361 ~AOUT_CHAN_DOLBYSTEREO
;
365 aout_request_vout_t request_vout
= {
366 .pf_request_vout
= aout_request_vout
,
369 audio_output_t
*p_aout
;
371 p_aout
= input_resource_GetAout( p_owner
->p_resource
);
374 if( aout_DecNew( p_aout
, &format
,
375 &p_dec
->fmt_out
.audio_replay_gain
,
378 input_resource_PutAout( p_owner
->p_resource
, p_aout
);
383 vlc_mutex_lock( &p_owner
->lock
);
384 p_owner
->p_aout
= p_aout
;
386 DecoderUpdateFormatLocked( p_dec
);
387 aout_FormatPrepare( &p_owner
->fmt
.audio
);
388 vlc_mutex_unlock( &p_owner
->lock
);
390 if( p_owner
->p_input
!= NULL
)
391 input_SendEventAout( p_owner
->p_input
);
395 msg_Err( p_dec
, "failed to create audio output" );
399 p_dec
->fmt_out
.audio
.i_bytes_per_frame
=
400 p_owner
->fmt
.audio
.i_bytes_per_frame
;
401 p_dec
->fmt_out
.audio
.i_frame_length
=
402 p_owner
->fmt
.audio
.i_frame_length
;
407 static int vout_update_format( decoder_t
*p_dec
)
409 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
411 if( p_owner
->p_vout
== NULL
412 || p_dec
->fmt_out
.video
.i_width
!= p_owner
->fmt
.video
.i_width
413 || p_dec
->fmt_out
.video
.i_height
!= p_owner
->fmt
.video
.i_height
414 || p_dec
->fmt_out
.video
.i_visible_width
!= p_owner
->fmt
.video
.i_visible_width
415 || p_dec
->fmt_out
.video
.i_visible_height
!= p_owner
->fmt
.video
.i_visible_height
416 || p_dec
->fmt_out
.video
.i_x_offset
!= p_owner
->fmt
.video
.i_x_offset
417 || p_dec
->fmt_out
.video
.i_y_offset
!= p_owner
->fmt
.video
.i_y_offset
418 || p_dec
->fmt_out
.i_codec
!= p_owner
->fmt
.video
.i_chroma
419 || (int64_t)p_dec
->fmt_out
.video
.i_sar_num
* p_owner
->fmt
.video
.i_sar_den
!=
420 (int64_t)p_dec
->fmt_out
.video
.i_sar_den
* p_owner
->fmt
.video
.i_sar_num
||
421 p_dec
->fmt_out
.video
.orientation
!= p_owner
->fmt
.video
.orientation
||
422 p_dec
->fmt_out
.video
.multiview_mode
!= p_owner
->fmt
.video
.multiview_mode
)
424 vout_thread_t
*p_vout
;
426 if( !p_dec
->fmt_out
.video
.i_width
||
427 !p_dec
->fmt_out
.video
.i_height
||
428 p_dec
->fmt_out
.video
.i_width
< p_dec
->fmt_out
.video
.i_visible_width
||
429 p_dec
->fmt_out
.video
.i_height
< p_dec
->fmt_out
.video
.i_visible_height
)
431 /* Can't create a new vout without display size */
435 video_format_t fmt
= p_dec
->fmt_out
.video
;
436 fmt
.i_chroma
= p_dec
->fmt_out
.i_codec
;
438 if( vlc_fourcc_IsYUV( fmt
.i_chroma
) )
440 const vlc_chroma_description_t
*dsc
= vlc_fourcc_GetChromaDescription( fmt
.i_chroma
);
441 for( unsigned int i
= 0; dsc
&& i
< dsc
->plane_count
; i
++ )
443 while( fmt
.i_width
% dsc
->p
[i
].w
.den
)
445 while( fmt
.i_height
% dsc
->p
[i
].h
.den
)
450 if( !fmt
.i_visible_width
|| !fmt
.i_visible_height
)
452 if( p_dec
->fmt_in
.video
.i_visible_width
&&
453 p_dec
->fmt_in
.video
.i_visible_height
)
455 fmt
.i_visible_width
= p_dec
->fmt_in
.video
.i_visible_width
;
456 fmt
.i_visible_height
= p_dec
->fmt_in
.video
.i_visible_height
;
457 fmt
.i_x_offset
= p_dec
->fmt_in
.video
.i_x_offset
;
458 fmt
.i_y_offset
= p_dec
->fmt_in
.video
.i_y_offset
;
462 fmt
.i_visible_width
= fmt
.i_width
;
463 fmt
.i_visible_height
= fmt
.i_height
;
469 if( fmt
.i_visible_height
== 1088 &&
470 var_CreateGetBool( p_dec
, "hdtv-fix" ) )
472 fmt
.i_visible_height
= 1080;
473 if( !(fmt
.i_sar_num
% 136))
475 fmt
.i_sar_num
*= 135;
476 fmt
.i_sar_den
*= 136;
478 msg_Warn( p_dec
, "Fixing broken HDTV stream (display_height=1088)");
481 if( !fmt
.i_sar_num
|| !fmt
.i_sar_den
)
487 vlc_ureduce( &fmt
.i_sar_num
, &fmt
.i_sar_den
,
488 fmt
.i_sar_num
, fmt
.i_sar_den
, 50000 );
490 video_format_AdjustColorSpace( &fmt
);
492 vlc_mutex_lock( &p_owner
->lock
);
494 p_vout
= p_owner
->p_vout
;
495 p_owner
->p_vout
= NULL
;
496 vlc_mutex_unlock( &p_owner
->lock
);
499 switch( p_dec
->fmt_in
.i_codec
)
503 case VLC_CODEC_DIRAC
: /* FIXME valid ? */
516 p_vout
= input_resource_RequestVout( p_owner
->p_resource
,
519 p_dec
->i_extra_picture_buffers
+ 1,
521 vlc_mutex_lock( &p_owner
->lock
);
522 p_owner
->p_vout
= p_vout
;
524 DecoderUpdateFormatLocked( p_dec
);
525 p_owner
->fmt
.video
.i_chroma
= p_dec
->fmt_out
.i_codec
;
526 vlc_mutex_unlock( &p_owner
->lock
);
528 if( p_owner
->p_input
!= NULL
)
529 input_SendEventVout( p_owner
->p_input
);
532 msg_Err( p_dec
, "failed to create video output" );
537 if ( memcmp( &p_dec
->fmt_out
.video
.mastering
,
538 &p_owner
->fmt
.video
.mastering
,
539 sizeof(p_owner
->fmt
.video
.mastering
)) ||
540 p_dec
->fmt_out
.video
.lighting
.MaxCLL
!=
541 p_owner
->fmt
.video
.lighting
.MaxCLL
||
542 p_dec
->fmt_out
.video
.lighting
.MaxFALL
!=
543 p_owner
->fmt
.video
.lighting
.MaxFALL
)
545 /* the format has changed but we don't need a new vout */
546 vlc_mutex_lock( &p_owner
->lock
);
547 DecoderUpdateFormatLocked( p_dec
);
548 vlc_mutex_unlock( &p_owner
->lock
);
553 static picture_t
*vout_new_buffer( decoder_t
*p_dec
)
555 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
556 assert( p_owner
->p_vout
);
558 return vout_GetPicture( p_owner
->p_vout
);
561 static subpicture_t
*spu_new_buffer( decoder_t
*p_dec
,
562 const subpicture_updater_t
*p_updater
)
564 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
565 vout_thread_t
*p_vout
= NULL
;
566 subpicture_t
*p_subpic
;
569 while( i_attempts
-- )
574 p_vout
= input_resource_HoldVout( p_owner
->p_resource
);
578 msleep( DECODER_SPU_VOUT_WAIT_DURATION
);
583 msg_Warn( p_dec
, "no vout found, dropping subpicture" );
587 if( p_owner
->p_spu_vout
!= p_vout
)
589 p_owner
->i_spu_channel
= vout_RegisterSubpictureChannel( p_vout
);
590 p_owner
->i_spu_order
= 0;
591 p_owner
->p_spu_vout
= p_vout
;
594 p_subpic
= subpicture_New( p_updater
);
597 p_subpic
->i_channel
= p_owner
->i_spu_channel
;
598 p_subpic
->i_order
= p_owner
->i_spu_order
++;
599 p_subpic
->b_subtitle
= true;
602 vlc_object_release( p_vout
);
607 static int DecoderGetInputAttachments( decoder_t
*p_dec
,
608 input_attachment_t
***ppp_attachment
,
611 input_thread_t
*p_input
= p_dec
->p_owner
->p_input
;
613 if( unlikely(p_input
== NULL
) )
615 return input_Control( p_input
, INPUT_GET_ATTACHMENTS
,
616 ppp_attachment
, pi_attachment
);
619 static mtime_t
DecoderGetDisplayDate( decoder_t
*p_dec
, mtime_t i_ts
)
621 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
623 vlc_mutex_lock( &p_owner
->lock
);
624 if( p_owner
->b_waiting
)
625 i_ts
= VLC_TS_INVALID
;
626 vlc_mutex_unlock( &p_owner
->lock
);
628 if( !p_owner
->p_clock
|| i_ts
<= VLC_TS_INVALID
)
631 if( input_clock_ConvertTS( VLC_OBJECT(p_dec
), p_owner
->p_clock
, NULL
, &i_ts
, NULL
, INT64_MAX
) ) {
632 msg_Err(p_dec
, "Could not get display date for timestamp %"PRId64
"", i_ts
);
633 return VLC_TS_INVALID
;
639 static int DecoderGetDisplayRate( decoder_t
*p_dec
)
641 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
643 if( !p_owner
->p_clock
)
644 return INPUT_RATE_DEFAULT
;
645 return input_clock_GetRate( p_owner
->p_clock
);
648 /*****************************************************************************
650 *****************************************************************************/
651 block_t
*decoder_NewAudioBuffer( decoder_t
*dec
, int samples
)
653 assert( dec
->fmt_out
.audio
.i_frame_length
> 0
654 && dec
->fmt_out
.audio
.i_bytes_per_frame
> 0 );
656 size_t length
= samples
* dec
->fmt_out
.audio
.i_bytes_per_frame
657 / dec
->fmt_out
.audio
.i_frame_length
;
658 block_t
*block
= block_Alloc( length
);
659 if( likely(block
!= NULL
) )
661 block
->i_nb_samples
= samples
;
662 block
->i_pts
= block
->i_length
= 0;
667 subpicture_t
*decoder_NewSubpicture( decoder_t
*p_decoder
,
668 const subpicture_updater_t
*p_dyn
)
670 subpicture_t
*p_subpicture
= p_decoder
->pf_spu_buffer_new( p_decoder
, p_dyn
);
672 msg_Warn( p_decoder
, "can't get output subpicture" );
676 static void RequestReload( decoder_t
* p_dec
)
678 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
679 /* Don't override reload if it's RELOAD_DECODER_AOUT */
680 int expected
= RELOAD_NO_REQUEST
;
681 atomic_compare_exchange_strong( &p_owner
->reload
, &expected
, RELOAD_DECODER
);
684 /* decoder_GetInputAttachments:
686 int decoder_GetInputAttachments( decoder_t
*p_dec
,
687 input_attachment_t
***ppp_attachment
,
690 if( !p_dec
->pf_get_attachments
)
693 return p_dec
->pf_get_attachments( p_dec
, ppp_attachment
, pi_attachment
);
695 /* decoder_GetDisplayDate:
697 mtime_t
decoder_GetDisplayDate( decoder_t
*p_dec
, mtime_t i_ts
)
699 if( !p_dec
->pf_get_display_date
)
700 return VLC_TS_INVALID
;
702 return p_dec
->pf_get_display_date( p_dec
, i_ts
);
704 /* decoder_GetDisplayRate:
706 int decoder_GetDisplayRate( decoder_t
*p_dec
)
708 if( !p_dec
->pf_get_display_rate
)
709 return INPUT_RATE_DEFAULT
;
711 return p_dec
->pf_get_display_rate( p_dec
);
714 void decoder_AbortPictures( decoder_t
*p_dec
, bool b_abort
)
716 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
718 vlc_mutex_lock( &p_owner
->lock
);
719 if( p_owner
->p_vout
!= NULL
)
720 vout_Cancel( p_owner
->p_vout
, b_abort
);
721 vlc_mutex_unlock( &p_owner
->lock
);
724 static void DecoderWaitUnblock( decoder_t
*p_dec
)
726 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
728 vlc_assert_locked( &p_owner
->lock
);
732 if( !p_owner
->b_waiting
|| !p_owner
->b_has_data
)
734 vlc_cond_wait( &p_owner
->wait_request
, &p_owner
->lock
);
738 /* DecoderTimedWait: Interruptible wait
739 * Returns VLC_SUCCESS if wait was not interrupted, and VLC_EGENERIC otherwise */
740 static int DecoderTimedWait( decoder_t
*p_dec
, mtime_t deadline
)
742 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
744 if (deadline
- mdate() <= 0)
747 vlc_fifo_Lock( p_owner
->p_fifo
);
748 while( !p_owner
->flushing
749 && vlc_fifo_TimedWaitCond( p_owner
->p_fifo
, &p_owner
->wait_timed
,
751 int ret
= p_owner
->flushing
? VLC_EGENERIC
: VLC_SUCCESS
;
752 vlc_fifo_Unlock( p_owner
->p_fifo
);
756 static inline void DecoderUpdatePreroll( int64_t *pi_preroll
, const block_t
*p
)
758 if( p
->i_flags
& BLOCK_FLAG_PREROLL
)
759 *pi_preroll
= INT64_MAX
;
760 /* Check if we can use the packet for end of preroll */
761 else if( (p
->i_flags
& BLOCK_FLAG_DISCONTINUITY
) &&
762 (p
->i_buffer
== 0 || (p
->i_flags
& BLOCK_FLAG_CORRUPTED
)) )
763 *pi_preroll
= INT64_MAX
;
764 else if( p
->i_dts
> VLC_TS_INVALID
)
765 *pi_preroll
= __MIN( *pi_preroll
, p
->i_dts
);
766 else if( p
->i_pts
> VLC_TS_INVALID
)
767 *pi_preroll
= __MIN( *pi_preroll
, p
->i_pts
);
770 static void DecoderFixTs( decoder_t
*p_dec
, mtime_t
*pi_ts0
, mtime_t
*pi_ts1
,
771 mtime_t
*pi_duration
, int *pi_rate
, mtime_t i_ts_bound
)
773 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
774 input_clock_t
*p_clock
= p_owner
->p_clock
;
776 vlc_assert_locked( &p_owner
->lock
);
778 const mtime_t i_es_delay
= p_owner
->i_ts_delay
;
783 const bool b_ephemere
= pi_ts1
&& *pi_ts0
== *pi_ts1
;
786 if( *pi_ts0
> VLC_TS_INVALID
)
788 *pi_ts0
+= i_es_delay
;
789 if( pi_ts1
&& *pi_ts1
> VLC_TS_INVALID
)
790 *pi_ts1
+= i_es_delay
;
791 if( i_ts_bound
!= INT64_MAX
)
792 i_ts_bound
+= i_es_delay
;
793 if( input_clock_ConvertTS( VLC_OBJECT(p_dec
), p_clock
, &i_rate
, pi_ts0
, pi_ts1
, i_ts_bound
) ) {
794 const char *psz_name
= module_get_name( p_dec
->p_module
, false );
796 msg_Err(p_dec
, "Could not convert timestamps %"PRId64
797 ", %"PRId64
" for %s", *pi_ts0
, *pi_ts1
, psz_name
);
799 msg_Err(p_dec
, "Could not convert timestamp %"PRId64
" for %s", *pi_ts0
, psz_name
);
800 *pi_ts0
= VLC_TS_INVALID
;
805 i_rate
= input_clock_GetRate( p_clock
);
808 /* Do not create ephemere data because of rounding errors */
809 if( !b_ephemere
&& pi_ts1
&& *pi_ts0
== *pi_ts1
)
813 *pi_duration
= ( *pi_duration
* i_rate
+ INPUT_RATE_DEFAULT
-1 )
814 / INPUT_RATE_DEFAULT
;
821 static int DecoderPlaySout( decoder_t
*p_dec
, block_t
*p_sout_block
)
823 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
825 assert( p_owner
->p_clock
);
826 assert( !p_sout_block
->p_next
);
828 vlc_mutex_lock( &p_owner
->lock
);
830 if( p_owner
->b_waiting
)
832 p_owner
->b_has_data
= true;
833 vlc_cond_signal( &p_owner
->wait_acknowledge
);
836 DecoderWaitUnblock( p_dec
);
837 DecoderFixTs( p_dec
, &p_sout_block
->i_dts
, &p_sout_block
->i_pts
,
838 &p_sout_block
->i_length
, NULL
, INT64_MAX
);
840 vlc_mutex_unlock( &p_owner
->lock
);
842 /* FIXME --VLC_TS_INVALID inspect stream_output*/
843 return sout_InputSendBuffer( p_owner
->p_sout_input
, p_sout_block
);
846 /* This function process a block for sout
848 static void DecoderProcessSout( decoder_t
*p_dec
, block_t
*p_block
)
850 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
851 block_t
*p_sout_block
;
852 block_t
**pp_block
= p_block
? &p_block
: NULL
;
854 while( ( p_sout_block
=
855 p_dec
->pf_packetize( p_dec
, pp_block
) ) )
857 if( p_owner
->p_sout_input
== NULL
)
859 vlc_mutex_lock( &p_owner
->lock
);
860 DecoderUpdateFormatLocked( p_dec
);
861 vlc_mutex_unlock( &p_owner
->lock
);
863 p_owner
->fmt
.i_group
= p_dec
->fmt_in
.i_group
;
864 p_owner
->fmt
.i_id
= p_dec
->fmt_in
.i_id
;
865 if( p_dec
->fmt_in
.psz_language
)
867 free( p_owner
->fmt
.psz_language
);
868 p_owner
->fmt
.psz_language
=
869 strdup( p_dec
->fmt_in
.psz_language
);
872 p_owner
->p_sout_input
=
873 sout_InputNew( p_owner
->p_sout
, &p_owner
->fmt
);
875 if( p_owner
->p_sout_input
== NULL
)
877 msg_Err( p_dec
, "cannot create packetizer output (%4.4s)",
878 (char *)&p_owner
->fmt
.i_codec
);
879 p_owner
->error
= true;
882 block_Release(p_block
);
884 block_ChainRelease(p_sout_block
);
889 while( p_sout_block
)
891 block_t
*p_next
= p_sout_block
->p_next
;
893 p_sout_block
->p_next
= NULL
;
895 if( DecoderPlaySout( p_dec
, p_sout_block
) == VLC_EGENERIC
)
897 msg_Err( p_dec
, "cannot continue streaming due to errors" );
899 p_owner
->error
= true;
904 block_Release( p_block
);
906 block_ChainRelease( p_next
);
910 p_sout_block
= p_next
;
916 static void DecoderPlayCc( decoder_t
*p_dec
, block_t
*p_cc
,
917 bool pb_present
[4], int i_reorder_depth
)
919 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
920 bool b_processed
= false;
921 int i_cc_decoder
= 0;
923 vlc_mutex_lock( &p_owner
->lock
);
924 for( int i
= 0; i
< 4; i
++ )
926 p_owner
->cc
.pb_present
[i
] |= pb_present
[i
];
927 if( p_owner
->cc
.pp_decoder
[i
] )
930 p_owner
->cc
.i_reorder_depth
= i_reorder_depth
;
932 for( int i
= 0; i
< 4; i
++ )
934 if( !p_owner
->cc
.pp_decoder
[i
] )
937 block_FifoPut( p_owner
->cc
.pp_decoder
[i
]->p_owner
->p_fifo
,
938 (i_cc_decoder
> 1) ? block_Duplicate(p_cc
) : p_cc
);
943 vlc_mutex_unlock( &p_owner
->lock
);
946 block_Release( p_cc
);
949 static void PacketizerGetCc( decoder_t
*p_dec
, decoder_t
*p_dec_cc
)
951 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
955 /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
956 if( !p_owner
->cc
.b_supported
)
959 assert( p_dec_cc
->pf_get_cc
!= NULL
);
962 p_cc
= p_dec_cc
->pf_get_cc( p_dec_cc
, pb_present
, &i_reorder_depth
);
965 DecoderPlayCc( p_dec
, p_cc
, pb_present
, i_reorder_depth
);
968 static int DecoderQueueCc( decoder_t
*p_videodec
, block_t
*p_cc
,
969 bool p_cc_present
[4], int i_reorder_depth
)
971 decoder_owner_sys_t
*p_owner
= p_videodec
->p_owner
;
973 if( unlikely( p_cc
!= NULL
) )
975 if( p_owner
->cc
.b_supported
&&
976 ( !p_owner
->p_packetizer
|| !p_owner
->p_packetizer
->pf_get_cc
) )
977 DecoderPlayCc( p_videodec
, p_cc
, p_cc_present
, i_reorder_depth
);
979 block_Release( p_cc
);
984 static int DecoderPlayVideo( decoder_t
*p_dec
, picture_t
*p_picture
,
985 unsigned *restrict pi_lost_sum
)
987 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
988 vout_thread_t
*p_vout
= p_owner
->p_vout
;
991 vlc_mutex_lock( &p_owner
->lock
);
992 if( p_owner
->i_preroll_end
> p_picture
->date
)
994 vlc_mutex_unlock( &p_owner
->lock
);
995 picture_Release( p_picture
);
999 prerolled
= p_owner
->i_preroll_end
> INT64_MIN
;
1000 p_owner
->i_preroll_end
= INT64_MIN
;
1001 vlc_mutex_unlock( &p_owner
->lock
);
1003 if( unlikely(prerolled
) )
1005 msg_Dbg( p_dec
, "end of video preroll" );
1008 vout_Flush( p_vout
, VLC_TS_INVALID
+1 );
1011 if( p_picture
->date
<= VLC_TS_INVALID
)
1013 msg_Warn( p_dec
, "non-dated video buffer received" );
1019 vlc_mutex_lock( &p_owner
->lock
);
1021 if( p_owner
->b_waiting
&& !p_owner
->b_first
)
1023 p_owner
->b_has_data
= true;
1024 vlc_cond_signal( &p_owner
->wait_acknowledge
);
1026 bool b_first_after_wait
= p_owner
->b_waiting
&& p_owner
->b_has_data
;
1028 DecoderWaitUnblock( p_dec
);
1030 if( p_owner
->b_waiting
)
1032 assert( p_owner
->b_first
);
1033 msg_Dbg( p_dec
, "Received first picture" );
1034 p_owner
->b_first
= false;
1035 p_picture
->b_force
= true;
1038 const bool b_dated
= p_picture
->date
> VLC_TS_INVALID
;
1039 int i_rate
= INPUT_RATE_DEFAULT
;
1040 DecoderFixTs( p_dec
, &p_picture
->date
, NULL
, NULL
,
1041 &i_rate
, DECODER_BOGUS_VIDEO_DELAY
);
1043 vlc_mutex_unlock( &p_owner
->lock
);
1045 /* FIXME: The *input* FIFO should not be locked here. This will not work
1046 * properly if/when pictures are queued asynchronously. */
1047 vlc_fifo_Lock( p_owner
->p_fifo
);
1048 if( unlikely(p_owner
->paused
) && likely(p_owner
->frames_countdown
> 0) )
1049 p_owner
->frames_countdown
--;
1050 vlc_fifo_Unlock( p_owner
->p_fifo
);
1053 if( p_vout
== NULL
)
1056 if( p_picture
->b_force
|| p_picture
->date
> VLC_TS_INVALID
)
1057 /* FIXME: VLC_TS_INVALID -- verify video_output */
1059 if( i_rate
!= p_owner
->i_last_rate
|| b_first_after_wait
)
1061 /* Be sure to not display old picture after our own */
1062 vout_Flush( p_vout
, p_picture
->date
);
1063 p_owner
->i_last_rate
= i_rate
;
1065 vout_PutPicture( p_vout
, p_picture
);
1070 msg_Warn( p_dec
, "early picture skipped" );
1072 msg_Warn( p_dec
, "non-dated video buffer received" );
1079 picture_Release( p_picture
);
1083 static void DecoderUpdateStatVideo( decoder_owner_sys_t
*p_owner
,
1084 unsigned decoded
, unsigned lost
)
1086 input_thread_t
*p_input
= p_owner
->p_input
;
1087 unsigned displayed
= 0;
1089 /* Update ugly stat */
1090 if( p_input
== NULL
)
1093 if( p_owner
->p_vout
!= NULL
)
1095 unsigned vout_lost
= 0;
1097 vout_GetResetStatistic( p_owner
->p_vout
, &displayed
, &vout_lost
);
1101 vlc_mutex_lock( &input_priv(p_input
)->counters
.counters_lock
);
1102 stats_Update( input_priv(p_input
)->counters
.p_decoded_video
, decoded
, NULL
);
1103 stats_Update( input_priv(p_input
)->counters
.p_lost_pictures
, lost
, NULL
);
1104 stats_Update( input_priv(p_input
)->counters
.p_displayed_pictures
, displayed
, NULL
);
1105 vlc_mutex_unlock( &input_priv(p_input
)->counters
.counters_lock
);
1108 static int DecoderQueueVideo( decoder_t
*p_dec
, picture_t
*p_pic
)
1111 unsigned i_lost
= 0;
1112 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1114 int ret
= DecoderPlayVideo( p_dec
, p_pic
, &i_lost
);
1116 p_owner
->pf_update_stat( p_owner
, 1, i_lost
);
1120 static int DecoderPlayAudio( decoder_t
*p_dec
, block_t
*p_audio
,
1121 unsigned *restrict pi_lost_sum
)
1123 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1126 assert( p_audio
!= NULL
);
1128 vlc_mutex_lock( &p_owner
->lock
);
1129 if( p_owner
->i_preroll_end
> p_audio
->i_pts
)
1131 vlc_mutex_unlock( &p_owner
->lock
);
1132 block_Release( p_audio
);
1136 prerolled
= p_owner
->i_preroll_end
> INT64_MIN
;
1137 p_owner
->i_preroll_end
= INT64_MIN
;
1138 vlc_mutex_unlock( &p_owner
->lock
);
1140 if( unlikely(prerolled
) )
1142 msg_Dbg( p_dec
, "end of audio preroll" );
1144 if( p_owner
->p_aout
)
1145 aout_DecFlush( p_owner
->p_aout
, false );
1149 if( p_audio
->i_pts
<= VLC_TS_INVALID
) // FIXME --VLC_TS_INVALID verify audio_output/*
1151 msg_Warn( p_dec
, "non-dated audio buffer received" );
1153 block_Release( p_audio
);
1158 vlc_mutex_lock( &p_owner
->lock
);
1159 if( p_owner
->b_waiting
)
1161 p_owner
->b_has_data
= true;
1162 vlc_cond_signal( &p_owner
->wait_acknowledge
);
1166 int i_rate
= INPUT_RATE_DEFAULT
;
1168 DecoderWaitUnblock( p_dec
);
1169 DecoderFixTs( p_dec
, &p_audio
->i_pts
, NULL
, &p_audio
->i_length
,
1170 &i_rate
, AOUT_MAX_ADVANCE_TIME
);
1171 vlc_mutex_unlock( &p_owner
->lock
);
1173 audio_output_t
*p_aout
= p_owner
->p_aout
;
1175 if( p_aout
!= NULL
&& p_audio
->i_pts
> VLC_TS_INVALID
1176 && i_rate
>= INPUT_RATE_DEFAULT
/AOUT_MAX_INPUT_RATE
1177 && i_rate
<= INPUT_RATE_DEFAULT
*AOUT_MAX_INPUT_RATE
1178 && !DecoderTimedWait( p_dec
, p_audio
->i_pts
- AOUT_MAX_PREPARE_TIME
) )
1180 int status
= aout_DecPlay( p_aout
, p_audio
, i_rate
);
1181 if( status
== AOUT_DEC_CHANGED
)
1183 /* Only reload the decoder */
1184 RequestReload( p_dec
);
1186 else if( status
== AOUT_DEC_FAILED
)
1188 /* If we reload because the aout failed, we should release it. That
1189 * way, a next call to aout_update_format() won't re-use the
1190 * previous (failing) aout but will try to create a new one. */
1191 atomic_store( &p_owner
->reload
, RELOAD_DECODER_AOUT
);
1196 msg_Dbg( p_dec
, "discarded audio buffer" );
1198 block_Release( p_audio
);
1203 static void DecoderUpdateStatAudio( decoder_owner_sys_t
*p_owner
,
1204 unsigned decoded
, unsigned lost
)
1206 input_thread_t
*p_input
= p_owner
->p_input
;
1207 unsigned played
= 0;
1209 /* Update ugly stat */
1210 if( p_input
== NULL
)
1213 if( p_owner
->p_aout
!= NULL
)
1217 aout_DecGetResetStats( p_owner
->p_aout
, &aout_lost
, &played
);
1221 vlc_mutex_lock( &input_priv(p_input
)->counters
.counters_lock
);
1222 stats_Update( input_priv(p_input
)->counters
.p_lost_abuffers
, lost
, NULL
);
1223 stats_Update( input_priv(p_input
)->counters
.p_played_abuffers
, played
, NULL
);
1224 stats_Update( input_priv(p_input
)->counters
.p_decoded_audio
, decoded
, NULL
);
1225 vlc_mutex_unlock( &input_priv(p_input
)->counters
.counters_lock
);
1228 static int DecoderQueueAudio( decoder_t
*p_dec
, block_t
*p_aout_buf
)
1231 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1233 int ret
= DecoderPlayAudio( p_dec
, p_aout_buf
, &lost
);
1235 p_owner
->pf_update_stat( p_owner
, 1, lost
);
1240 static void DecoderPlaySpu( decoder_t
*p_dec
, subpicture_t
*p_subpic
)
1242 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1243 vout_thread_t
*p_vout
= p_owner
->p_spu_vout
;
1246 if( p_subpic
->i_start
<= VLC_TS_INVALID
)
1248 msg_Warn( p_dec
, "non-dated spu buffer received" );
1249 subpicture_Delete( p_subpic
);
1254 vlc_mutex_lock( &p_owner
->lock
);
1256 if( p_owner
->b_waiting
)
1258 p_owner
->b_has_data
= true;
1259 vlc_cond_signal( &p_owner
->wait_acknowledge
);
1262 DecoderWaitUnblock( p_dec
);
1263 DecoderFixTs( p_dec
, &p_subpic
->i_start
, &p_subpic
->i_stop
, NULL
,
1265 vlc_mutex_unlock( &p_owner
->lock
);
1267 if( p_subpic
->i_start
<= VLC_TS_INVALID
1268 || DecoderTimedWait( p_dec
, p_subpic
->i_start
- SPU_MAX_PREPARE_TIME
) )
1270 subpicture_Delete( p_subpic
);
1274 vout_PutSubpicture( p_vout
, p_subpic
);
1277 static void DecoderUpdateStatSpu( decoder_owner_sys_t
*p_owner
,
1278 unsigned decoded
, unsigned lost
)
1280 (void) p_owner
; (void) decoded
; (void) lost
;
1283 static int DecoderQueueSpu( decoder_t
*p_dec
, subpicture_t
*p_spu
)
1286 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1287 input_thread_t
*p_input
= p_owner
->p_input
;
1289 if( p_input
!= NULL
)
1291 vlc_mutex_lock( &input_priv(p_input
)->counters
.counters_lock
);
1292 stats_Update( input_priv(p_input
)->counters
.p_decoded_sub
, 1, NULL
);
1293 vlc_mutex_unlock( &input_priv(p_input
)->counters
.counters_lock
);
1297 vout_thread_t
*p_vout
= input_resource_HoldVout( p_owner
->p_resource
);
1298 if( p_vout
&& p_owner
->p_spu_vout
== p_vout
)
1300 /* Preroll does not work very well with subtitle */
1301 vlc_mutex_lock( &p_owner
->lock
);
1302 if( p_spu
->i_start
> VLC_TS_INVALID
&&
1303 p_spu
->i_start
< p_owner
->i_preroll_end
&&
1304 ( p_spu
->i_stop
<= VLC_TS_INVALID
|| p_spu
->i_stop
< p_owner
->i_preroll_end
) )
1306 vlc_mutex_unlock( &p_owner
->lock
);
1307 subpicture_Delete( p_spu
);
1311 vlc_mutex_unlock( &p_owner
->lock
);
1312 DecoderPlaySpu( p_dec
, p_spu
);
1318 subpicture_Delete( p_spu
);
1321 vlc_object_release( p_vout
);
1325 static void DecoderProcess( decoder_t
*p_dec
, block_t
*p_block
);
1326 static void DecoderDecode( decoder_t
*p_dec
, block_t
*p_block
)
1328 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1330 int ret
= p_dec
->pf_decode( p_dec
, p_block
);
1333 case VLCDEC_SUCCESS
:
1334 p_owner
->pf_update_stat( p_owner
, 1, 0 );
1336 case VLCDEC_ECRITICAL
:
1337 p_owner
->error
= true;
1340 RequestReload( p_dec
);
1341 if( unlikely( p_block
== NULL
) )
1343 if( !( p_block
->i_flags
& BLOCK_FLAG_CORE_PRIVATE_RELOADED
) )
1345 p_block
->i_flags
|= BLOCK_FLAG_CORE_PRIVATE_RELOADED
;
1346 DecoderProcess( p_dec
, p_block
);
1348 else /* We prefer loosing this block than an infinite recursion */
1349 block_Release( p_block
);
1352 vlc_assert_unreachable();
1359 * \param p_dec the decoder object
1360 * \param p_block the block to decode
1362 static void DecoderProcess( decoder_t
*p_dec
, block_t
*p_block
)
1364 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1366 if( p_owner
->error
)
1369 /* Here, the atomic doesn't prevent to miss a reload request.
1370 * DecoderProcess() can still be called after the decoder module or the
1371 * audio output requested a reload. This will only result in a drop of an
1372 * input block or an output buffer. */
1374 if( ( reload
= atomic_exchange( &p_owner
->reload
, RELOAD_NO_REQUEST
) ) )
1376 msg_Warn( p_dec
, "Reloading the decoder module%s",
1377 reload
== RELOAD_DECODER_AOUT
? " and the audio output" : "" );
1379 if( ReloadDecoder( p_dec
, false, &p_dec
->fmt_in
, reload
) != VLC_SUCCESS
)
1383 bool packetize
= p_owner
->p_packetizer
!= NULL
;
1386 if( p_block
->i_buffer
<= 0 )
1389 vlc_mutex_lock( &p_owner
->lock
);
1390 DecoderUpdatePreroll( &p_owner
->i_preroll_end
, p_block
);
1391 vlc_mutex_unlock( &p_owner
->lock
);
1392 if( unlikely( p_block
->i_flags
& BLOCK_FLAG_CORE_PRIVATE_RELOADED
) )
1394 /* This block has already been packetized */
1400 if( p_owner
->p_sout
!= NULL
)
1402 DecoderProcessSout( p_dec
, p_block
);
1408 block_t
*p_packetized_block
;
1409 block_t
**pp_block
= p_block
? &p_block
: NULL
;
1410 decoder_t
*p_packetizer
= p_owner
->p_packetizer
;
1412 while( (p_packetized_block
=
1413 p_packetizer
->pf_packetize( p_packetizer
, pp_block
) ) )
1415 if( !es_format_IsSimilar( &p_dec
->fmt_in
, &p_packetizer
->fmt_out
) )
1417 msg_Dbg( p_dec
, "restarting module due to input format change");
1419 /* Drain the decoder module */
1420 DecoderDecode( p_dec
, NULL
);
1422 if( ReloadDecoder( p_dec
, false, &p_packetizer
->fmt_out
,
1423 RELOAD_DECODER
) != VLC_SUCCESS
)
1425 block_ChainRelease( p_packetized_block
);
1430 if( p_packetizer
->pf_get_cc
)
1431 PacketizerGetCc( p_dec
, p_packetizer
);
1433 while( p_packetized_block
)
1435 block_t
*p_next
= p_packetized_block
->p_next
;
1436 p_packetized_block
->p_next
= NULL
;
1438 DecoderDecode( p_dec
, p_packetized_block
);
1439 if( p_owner
->error
)
1441 block_ChainRelease( p_next
);
1445 p_packetized_block
= p_next
;
1448 /* Drain the decoder after the packetizer is drained */
1450 DecoderDecode( p_dec
, NULL
);
1453 DecoderDecode( p_dec
, p_block
);
1458 block_Release( p_block
);
1461 static void DecoderProcessFlush( decoder_t
*p_dec
)
1463 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1464 decoder_t
*p_packetizer
= p_owner
->p_packetizer
;
1466 if( p_owner
->error
)
1469 if( p_packetizer
!= NULL
&& p_packetizer
->pf_flush
!= NULL
)
1470 p_packetizer
->pf_flush( p_packetizer
);
1472 if ( p_dec
->pf_flush
!= NULL
)
1473 p_dec
->pf_flush( p_dec
);
1475 /* flush CC sub decoders */
1476 if( p_owner
->cc
.b_supported
)
1478 for( int i
=0; i
<4; i
++ )
1480 decoder_t
*p_subdec
= p_owner
->cc
.pp_decoder
[i
];
1481 if( p_subdec
&& p_subdec
->pf_flush
)
1482 p_subdec
->pf_flush( p_subdec
);
1487 if ( p_owner
->p_sout_input
!= NULL
)
1489 sout_InputFlush( p_owner
->p_sout_input
);
1492 if( p_dec
->fmt_out
.i_cat
== AUDIO_ES
)
1494 if( p_owner
->p_aout
)
1495 aout_DecFlush( p_owner
->p_aout
, false );
1497 else if( p_dec
->fmt_out
.i_cat
== VIDEO_ES
)
1499 if( p_owner
->p_vout
)
1500 vout_Flush( p_owner
->p_vout
, VLC_TS_INVALID
+1 );
1502 else if( p_dec
->fmt_out
.i_cat
== SPU_ES
)
1504 if( p_owner
->p_spu_vout
)
1506 vout_thread_t
*p_vout
= input_resource_HoldVout( p_owner
->p_resource
);
1508 if( p_vout
&& p_owner
->p_spu_vout
== p_vout
)
1509 vout_FlushSubpictureChannel( p_vout
, p_owner
->i_spu_channel
);
1512 vlc_object_release( p_vout
);
1516 vlc_mutex_lock( &p_owner
->lock
);
1517 p_owner
->i_preroll_end
= INT64_MIN
;
1518 vlc_mutex_unlock( &p_owner
->lock
);
1522 * The decoding main loop
1524 * \param p_dec the decoder
1526 static void *DecoderThread( void *p_data
)
1528 decoder_t
*p_dec
= (decoder_t
*)p_data
;
1529 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1530 bool paused
= false;
1532 /* The decoder's main loop */
1533 vlc_fifo_Lock( p_owner
->p_fifo
);
1534 vlc_fifo_CleanupPush( p_owner
->p_fifo
);
1538 if( p_owner
->flushing
)
1539 { /* Flush before/regardless of pause. We do not want to resume just
1540 * for the sake of flushing (glitches could otherwise happen). */
1541 int canc
= vlc_savecancel();
1543 vlc_fifo_Unlock( p_owner
->p_fifo
);
1545 /* Flush the decoder (and the output) */
1546 DecoderProcessFlush( p_dec
);
1548 vlc_fifo_Lock( p_owner
->p_fifo
);
1549 vlc_restorecancel( canc
);
1551 /* Reset flushing after DecoderProcess in case input_DecoderFlush
1552 * is called again. This will avoid a second useless flush (but
1554 p_owner
->flushing
= false;
1559 if( paused
!= p_owner
->paused
)
1560 { /* Update playing/paused status of the output */
1561 int canc
= vlc_savecancel();
1562 mtime_t date
= p_owner
->pause_date
;
1564 paused
= p_owner
->paused
;
1565 vlc_fifo_Unlock( p_owner
->p_fifo
);
1567 /* NOTE: Only the audio and video outputs care about pause. */
1568 msg_Dbg( p_dec
, "toggling %s", paused
? "resume" : "pause" );
1569 if( p_owner
->p_vout
!= NULL
)
1570 vout_ChangePause( p_owner
->p_vout
, paused
, date
);
1571 if( p_owner
->p_aout
!= NULL
)
1572 aout_DecChangePause( p_owner
->p_aout
, paused
, date
);
1574 vlc_restorecancel( canc
);
1575 vlc_fifo_Lock( p_owner
->p_fifo
);
1579 if( p_owner
->paused
&& p_owner
->frames_countdown
== 0 )
1580 { /* Wait for resumption from pause */
1581 p_owner
->b_idle
= true;
1582 vlc_fifo_Wait( p_owner
->p_fifo
);
1583 p_owner
->b_idle
= false;
1587 vlc_cond_signal( &p_owner
->wait_fifo
);
1588 vlc_testcancel(); /* forced expedited cancellation in case of stop */
1590 block_t
*p_block
= vlc_fifo_DequeueUnlocked( p_owner
->p_fifo
);
1591 if( p_block
== NULL
)
1593 if( likely(!p_owner
->b_draining
) )
1594 { /* Wait for a block to decode (or a request to drain) */
1595 p_owner
->b_idle
= true;
1596 vlc_fifo_Wait( p_owner
->p_fifo
);
1597 p_owner
->b_idle
= false;
1600 /* We have emptied the FIFO and there is a pending request to
1601 * drain. Pass p_block = NULL to decoder just once. */
1602 p_owner
->b_draining
= false;
1605 vlc_fifo_Unlock( p_owner
->p_fifo
);
1607 int canc
= vlc_savecancel();
1608 DecoderProcess( p_dec
, p_block
);
1610 if( p_block
== NULL
)
1611 { /* Draining: the decoder is drained and all decoded buffers are
1612 * queued to the output at this point. Now drain the output. */
1613 if( p_owner
->p_aout
!= NULL
)
1614 aout_DecFlush( p_owner
->p_aout
, true );
1616 vlc_restorecancel( canc
);
1618 /* Given that the drained flag is only polled, an atomic variable is
1619 * sufficient. TODO? Wait for draining instead of polling. */
1620 atomic_store( &p_owner
->drained
, (p_block
== NULL
) );
1622 vlc_mutex_lock( &p_owner
->lock
);
1623 vlc_fifo_Lock( p_owner
->p_fifo
);
1624 vlc_cond_signal( &p_owner
->wait_acknowledge
);
1625 vlc_mutex_unlock( &p_owner
->lock
);
1628 vlc_assert_unreachable();
1632 * Create a decoder object
1634 * \param p_input the input thread
1635 * \param p_es the es descriptor
1636 * \param b_packetizer instead of a decoder
1637 * \return the decoder object
1639 static decoder_t
* CreateDecoder( vlc_object_t
*p_parent
,
1640 input_thread_t
*p_input
,
1641 const es_format_t
*fmt
,
1642 input_resource_t
*p_resource
,
1643 sout_instance_t
*p_sout
)
1646 decoder_owner_sys_t
*p_owner
;
1648 p_dec
= vlc_custom_create( p_parent
, sizeof( *p_dec
), "decoder" );
1652 /* Allocate our private structure for the decoder */
1653 p_dec
->p_owner
= p_owner
= malloc( sizeof( decoder_owner_sys_t
) );
1654 if( unlikely(p_owner
== NULL
) )
1656 vlc_object_release( p_dec
);
1659 p_owner
->i_preroll_end
= INT64_MIN
;
1660 p_owner
->i_last_rate
= INPUT_RATE_DEFAULT
;
1661 p_owner
->p_input
= p_input
;
1662 p_owner
->p_resource
= p_resource
;
1663 p_owner
->p_aout
= NULL
;
1664 p_owner
->p_vout
= NULL
;
1665 p_owner
->p_spu_vout
= NULL
;
1666 p_owner
->i_spu_channel
= 0;
1667 p_owner
->i_spu_order
= 0;
1668 p_owner
->p_sout
= p_sout
;
1669 p_owner
->p_sout_input
= NULL
;
1670 p_owner
->p_packetizer
= NULL
;
1672 p_owner
->b_fmt_description
= false;
1673 p_owner
->p_description
= NULL
;
1675 p_owner
->paused
= false;
1676 p_owner
->pause_date
= VLC_TS_INVALID
;
1677 p_owner
->frames_countdown
= 0;
1679 p_owner
->b_waiting
= false;
1680 p_owner
->b_first
= true;
1681 p_owner
->b_has_data
= false;
1683 p_owner
->error
= false;
1685 p_owner
->flushing
= false;
1686 p_owner
->b_draining
= false;
1687 atomic_init( &p_owner
->drained
, false );
1688 atomic_init( &p_owner
->reload
, RELOAD_NO_REQUEST
);
1689 p_owner
->b_idle
= false;
1691 es_format_Init( &p_owner
->fmt
, fmt
->i_cat
, 0 );
1694 p_owner
->p_fifo
= block_FifoNew();
1695 if( unlikely(p_owner
->p_fifo
== NULL
) )
1698 vlc_object_release( p_dec
);
1702 vlc_mutex_init( &p_owner
->lock
);
1703 vlc_cond_init( &p_owner
->wait_request
);
1704 vlc_cond_init( &p_owner
->wait_acknowledge
);
1705 vlc_cond_init( &p_owner
->wait_fifo
);
1706 vlc_cond_init( &p_owner
->wait_timed
);
1708 /* Set buffers allocation callbacks for the decoders */
1709 p_dec
->pf_aout_format_update
= aout_update_format
;
1710 p_dec
->pf_vout_format_update
= vout_update_format
;
1711 p_dec
->pf_vout_buffer_new
= vout_new_buffer
;
1712 p_dec
->pf_spu_buffer_new
= spu_new_buffer
;
1714 p_dec
->pf_get_attachments
= DecoderGetInputAttachments
;
1715 p_dec
->pf_get_display_date
= DecoderGetDisplayDate
;
1716 p_dec
->pf_get_display_rate
= DecoderGetDisplayRate
;
1718 /* Load a packetizer module if the input is not already packetized */
1719 if( p_sout
== NULL
&& !fmt
->b_packetized
)
1721 p_owner
->p_packetizer
=
1722 vlc_custom_create( p_parent
, sizeof( decoder_t
), "packetizer" );
1723 if( p_owner
->p_packetizer
)
1725 if( LoadDecoder( p_owner
->p_packetizer
, true, fmt
) )
1727 vlc_object_release( p_owner
->p_packetizer
);
1728 p_owner
->p_packetizer
= NULL
;
1732 p_owner
->p_packetizer
->fmt_out
.b_packetized
= true;
1733 fmt
= &p_owner
->p_packetizer
->fmt_out
;
1738 /* Find a suitable decoder/packetizer module */
1739 if( LoadDecoder( p_dec
, p_sout
!= NULL
, fmt
) )
1742 switch( p_dec
->fmt_out
.i_cat
)
1745 p_dec
->pf_queue_video
= DecoderQueueVideo
;
1746 p_dec
->pf_queue_cc
= DecoderQueueCc
;
1747 p_owner
->pf_update_stat
= DecoderUpdateStatVideo
;
1750 p_dec
->pf_queue_audio
= DecoderQueueAudio
;
1751 p_owner
->pf_update_stat
= DecoderUpdateStatAudio
;
1754 p_dec
->pf_queue_sub
= DecoderQueueSpu
;
1755 p_owner
->pf_update_stat
= DecoderUpdateStatSpu
;
1758 msg_Err( p_dec
, "unknown ES format" );
1759 UnloadDecoder( p_dec
);
1762 /* Copy ourself the input replay gain */
1763 if( fmt
->i_cat
== AUDIO_ES
)
1765 for( unsigned i
= 0; i
< AUDIO_REPLAY_GAIN_MAX
; i
++ )
1767 if( !p_dec
->fmt_out
.audio_replay_gain
.pb_peak
[i
] )
1769 p_dec
->fmt_out
.audio_replay_gain
.pb_peak
[i
] = fmt
->audio_replay_gain
.pb_peak
[i
];
1770 p_dec
->fmt_out
.audio_replay_gain
.pf_peak
[i
] = fmt
->audio_replay_gain
.pf_peak
[i
];
1772 if( !p_dec
->fmt_out
.audio_replay_gain
.pb_gain
[i
] )
1774 p_dec
->fmt_out
.audio_replay_gain
.pb_gain
[i
] = fmt
->audio_replay_gain
.pb_gain
[i
];
1775 p_dec
->fmt_out
.audio_replay_gain
.pf_gain
[i
] = fmt
->audio_replay_gain
.pf_gain
[i
];
1781 p_owner
->cc
.b_supported
= ( p_sout
== NULL
);
1783 for( unsigned i
= 0; i
< 4; i
++ )
1785 p_owner
->cc
.pb_present
[i
] = false;
1786 p_owner
->cc
.pp_decoder
[i
] = NULL
;
1788 p_owner
->cc
.i_reorder_depth
= 0;
1789 p_owner
->i_ts_delay
= 0;
1794 * Destroys a decoder object
1796 * \param p_dec the decoder object
1799 static void DeleteDecoder( decoder_t
* p_dec
)
1801 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1803 msg_Dbg( p_dec
, "killing decoder fourcc `%4.4s'",
1804 (char*)&p_dec
->fmt_in
.i_codec
);
1806 const bool b_flush_spu
= p_dec
->fmt_out
.i_cat
== SPU_ES
;
1807 UnloadDecoder( p_dec
);
1809 /* Free all packets still in the decoder fifo. */
1810 block_FifoRelease( p_owner
->p_fifo
);
1813 if( p_owner
->p_aout
)
1815 /* TODO: REVISIT gap-less audio */
1816 aout_DecFlush( p_owner
->p_aout
, false );
1817 aout_DecDelete( p_owner
->p_aout
);
1818 input_resource_PutAout( p_owner
->p_resource
, p_owner
->p_aout
);
1819 if( p_owner
->p_input
!= NULL
)
1820 input_SendEventAout( p_owner
->p_input
);
1822 if( p_owner
->p_vout
)
1824 /* Reset the cancel state that was set before joining the decoder
1826 vout_Cancel( p_owner
->p_vout
, false );
1828 input_resource_RequestVout( p_owner
->p_resource
, p_owner
->p_vout
, NULL
,
1830 if( p_owner
->p_input
!= NULL
)
1831 input_SendEventVout( p_owner
->p_input
);
1835 if( p_owner
->p_sout_input
)
1837 sout_InputDelete( p_owner
->p_sout_input
);
1840 es_format_Clean( &p_owner
->fmt
);
1844 vout_thread_t
*p_vout
= input_resource_HoldVout( p_owner
->p_resource
);
1847 if( p_owner
->p_spu_vout
== p_vout
)
1848 vout_FlushSubpictureChannel( p_vout
, p_owner
->i_spu_channel
);
1849 vlc_object_release( p_vout
);
1853 if( p_owner
->p_description
)
1854 vlc_meta_Delete( p_owner
->p_description
);
1856 if( p_owner
->p_packetizer
)
1858 UnloadDecoder( p_owner
->p_packetizer
);
1859 vlc_object_release( p_owner
->p_packetizer
);
1862 vlc_cond_destroy( &p_owner
->wait_timed
);
1863 vlc_cond_destroy( &p_owner
->wait_fifo
);
1864 vlc_cond_destroy( &p_owner
->wait_acknowledge
);
1865 vlc_cond_destroy( &p_owner
->wait_request
);
1866 vlc_mutex_destroy( &p_owner
->lock
);
1868 vlc_object_release( p_dec
);
1874 static void DecoderUnsupportedCodec( decoder_t
*p_dec
, const es_format_t
*fmt
, bool b_decoding
)
1876 if (fmt
->i_codec
!= VLC_CODEC_UNKNOWN
&& fmt
->i_codec
) {
1877 const char *desc
= vlc_fourcc_GetDescription(fmt
->i_cat
, fmt
->i_codec
);
1878 if (!desc
|| !*desc
)
1879 desc
= N_("No description for this codec");
1880 msg_Err( p_dec
, "Codec `%4.4s' (%s) is not supported.", (char*)&fmt
->i_codec
, desc
);
1881 vlc_dialog_display_error( p_dec
, _("Codec not supported"),
1882 _("VLC could not decode the format \"%4.4s\" (%s)"),
1883 (char*)&fmt
->i_codec
, desc
);
1884 } else if( b_decoding
){
1885 msg_Err( p_dec
, "could not identify codec" );
1886 vlc_dialog_display_error( p_dec
, _("Unidentified codec"),
1887 _("VLC could not identify the audio or video codec" ) );
1891 /* TODO: pass p_sout through p_resource? -- Courmisch */
1892 static decoder_t
*decoder_New( vlc_object_t
*p_parent
, input_thread_t
*p_input
,
1893 const es_format_t
*fmt
, input_clock_t
*p_clock
,
1894 input_resource_t
*p_resource
,
1895 sout_instance_t
*p_sout
)
1897 decoder_t
*p_dec
= NULL
;
1898 const char *psz_type
= p_sout
? N_("packetizer") : N_("decoder");
1901 /* Create the decoder configuration structure */
1902 p_dec
= CreateDecoder( p_parent
, p_input
, fmt
, p_resource
, p_sout
);
1905 msg_Err( p_parent
, "could not create %s", psz_type
);
1906 vlc_dialog_display_error( p_parent
, _("Streaming / Transcoding failed"),
1907 _("VLC could not open the %s module."), vlc_gettext( psz_type
) );
1911 if( !p_dec
->p_module
)
1913 DecoderUnsupportedCodec( p_dec
, fmt
, !p_sout
);
1915 DeleteDecoder( p_dec
);
1919 p_dec
->p_owner
->p_clock
= p_clock
;
1920 assert( p_dec
->fmt_out
.i_cat
!= UNKNOWN_ES
);
1922 if( p_dec
->fmt_out
.i_cat
== AUDIO_ES
)
1923 i_priority
= VLC_THREAD_PRIORITY_AUDIO
;
1925 i_priority
= VLC_THREAD_PRIORITY_VIDEO
;
1927 /* Spawn the decoder thread */
1928 if( vlc_clone( &p_dec
->p_owner
->thread
, DecoderThread
, p_dec
, i_priority
) )
1930 msg_Err( p_dec
, "cannot spawn decoder thread" );
1931 DeleteDecoder( p_dec
);
1940 * Spawns a new decoder thread from the input thread
1942 * \param p_input the input thread
1943 * \param p_es the es descriptor
1944 * \return the spawned decoder object
1946 decoder_t
*input_DecoderNew( input_thread_t
*p_input
,
1947 es_format_t
*fmt
, input_clock_t
*p_clock
,
1948 sout_instance_t
*p_sout
)
1950 return decoder_New( VLC_OBJECT(p_input
), p_input
, fmt
, p_clock
,
1951 input_priv(p_input
)->p_resource
, p_sout
);
1955 * Spawn a decoder thread outside of the input thread.
1957 decoder_t
*input_DecoderCreate( vlc_object_t
*p_parent
, const es_format_t
*fmt
,
1958 input_resource_t
*p_resource
)
1960 return decoder_New( p_parent
, NULL
, fmt
, NULL
, p_resource
, NULL
);
1965 * Kills a decoder thread and waits until it's finished
1967 * \param p_input the input thread
1968 * \param p_es the es descriptor
1971 void input_DecoderDelete( decoder_t
*p_dec
)
1973 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
1975 vlc_cancel( p_owner
->thread
);
1977 vlc_fifo_Lock( p_owner
->p_fifo
);
1978 /* Signal DecoderTimedWait */
1979 p_owner
->flushing
= true;
1980 vlc_cond_signal( &p_owner
->wait_timed
);
1981 vlc_fifo_Unlock( p_owner
->p_fifo
);
1983 /* Make sure we aren't waiting/decoding anymore */
1984 vlc_mutex_lock( &p_owner
->lock
);
1985 p_owner
->b_waiting
= false;
1986 vlc_cond_signal( &p_owner
->wait_request
);
1988 /* If the video output is paused or slow, or if the picture pool size was
1989 * under-estimated (e.g. greedy video filter, buggy decoder...), the
1990 * the picture pool may be empty, and the decoder thread or any decoder
1991 * module worker threads may be stuck waiting for free picture buffers.
1993 * This unblocks the thread, allowing the decoder module to join all its
1994 * worker threads (if any) and the decoder thread to terminate. */
1995 if( p_owner
->p_vout
!= NULL
)
1996 vout_Cancel( p_owner
->p_vout
, true );
1997 vlc_mutex_unlock( &p_owner
->lock
);
1999 vlc_join( p_owner
->thread
, NULL
);
2002 if( p_dec
->p_owner
->cc
.b_supported
)
2004 for( int i
= 0; i
< 4; i
++ )
2005 input_DecoderSetCcState( p_dec
, false, i
);
2008 /* Delete decoder */
2009 DeleteDecoder( p_dec
);
2013 * Put a block_t in the decoder's fifo.
2014 * Thread-safe w.r.t. the decoder. May be a cancellation point.
2016 * \param p_dec the decoder object
2017 * \param p_block the data block
2019 void input_DecoderDecode( decoder_t
*p_dec
, block_t
*p_block
, bool b_do_pace
)
2021 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2023 vlc_fifo_Lock( p_owner
->p_fifo
);
2026 /* FIXME: ideally we would check the time amount of data
2027 * in the FIFO instead of its size. */
2028 /* 400 MiB, i.e. ~ 50mb/s for 60s */
2029 if( vlc_fifo_GetBytes( p_owner
->p_fifo
) > 400*1024*1024 )
2031 msg_Warn( p_dec
, "decoder/packetizer fifo full (data not "
2032 "consumed quickly enough), resetting fifo!" );
2033 block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner
->p_fifo
) );
2037 if( !p_owner
->b_waiting
)
2038 { /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
2039 * Locking is not necessary as b_waiting is only read, not written by
2040 * the decoder thread. */
2041 while( vlc_fifo_GetCount( p_owner
->p_fifo
) >= 10 )
2042 vlc_fifo_WaitCond( p_owner
->p_fifo
, &p_owner
->wait_fifo
);
2045 vlc_fifo_QueueUnlocked( p_owner
->p_fifo
, p_block
);
2046 vlc_fifo_Unlock( p_owner
->p_fifo
);
2049 bool input_DecoderIsEmpty( decoder_t
* p_dec
)
2051 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2053 assert( !p_owner
->b_waiting
);
2055 vlc_fifo_Lock( p_owner
->p_fifo
);
2056 if( !vlc_fifo_IsEmpty( p_dec
->p_owner
->p_fifo
) || p_owner
->b_draining
)
2058 vlc_fifo_Unlock( p_owner
->p_fifo
);
2061 vlc_fifo_Unlock( p_owner
->p_fifo
);
2065 vlc_mutex_lock( &p_owner
->lock
);
2067 if( p_owner
->p_sout_input
!= NULL
)
2068 b_empty
= sout_InputIsEmpty( p_owner
->p_sout_input
);
2071 if( p_owner
->fmt
.i_cat
== VIDEO_ES
&& p_owner
->p_vout
!= NULL
)
2072 b_empty
= vout_IsEmpty( p_owner
->p_vout
);
2073 else if( p_owner
->fmt
.i_cat
== AUDIO_ES
)
2074 b_empty
= atomic_load( &p_owner
->drained
);
2076 b_empty
= true; /* TODO subtitles support */
2077 vlc_mutex_unlock( &p_owner
->lock
);
2083 * Signals that there are no further blocks to decode, and requests that the
2084 * decoder drain all pending buffers. This is used to ensure that all
2085 * intermediate buffers empty and no samples get lost at the end of the stream.
2087 * @note The function does not actually wait for draining. It just signals that
2088 * draining should be performed once the decoder has emptied FIFO.
2090 void input_DecoderDrain( decoder_t
*p_dec
)
2092 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2094 vlc_fifo_Lock( p_owner
->p_fifo
);
2095 p_owner
->b_draining
= true;
2096 vlc_fifo_Signal( p_owner
->p_fifo
);
2097 vlc_fifo_Unlock( p_owner
->p_fifo
);
2101 * Requests that the decoder immediately discard all pending buffers.
2102 * This is useful when seeking or when deselecting a stream.
2104 void input_DecoderFlush( decoder_t
*p_dec
)
2106 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2108 vlc_fifo_Lock( p_owner
->p_fifo
);
2110 /* Empty the fifo */
2111 block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner
->p_fifo
) );
2113 /* Don't need to wait for the DecoderThread to flush. Indeed, if called a
2114 * second time, this function will clear the FIFO again before anything was
2115 * dequeued by DecoderThread and there is no need to flush a second time in
2117 p_owner
->flushing
= true;
2119 /* Flushing video decoder when paused: increment frames_countdown in order
2120 * to display one frame */
2121 if( p_owner
->fmt
.i_cat
== VIDEO_ES
&& p_owner
->paused
2122 && p_owner
->frames_countdown
== 0 )
2123 p_owner
->frames_countdown
++;
2125 vlc_fifo_Signal( p_owner
->p_fifo
);
2126 vlc_cond_signal( &p_owner
->wait_timed
);
2128 vlc_fifo_Unlock( p_owner
->p_fifo
);
2131 void input_DecoderIsCcPresent( decoder_t
*p_dec
, bool pb_present
[4] )
2133 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2135 vlc_mutex_lock( &p_owner
->lock
);
2136 for( int i
= 0; i
< 4; i
++ )
2137 pb_present
[i
] = p_owner
->cc
.pb_present
[i
];
2138 vlc_mutex_unlock( &p_owner
->lock
);
2141 int input_DecoderSetCcState( decoder_t
*p_dec
, bool b_decode
, int i_channel
)
2143 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2145 //msg_Warn( p_dec, "input_DecoderSetCcState: %d @%d", b_decode, i_channel );
2147 if( i_channel
< 0 || i_channel
>= 4 || !p_owner
->cc
.pb_present
[i_channel
] )
2148 return VLC_EGENERIC
;
2152 static const vlc_fourcc_t fcc
[4] = {
2161 es_format_Init( &fmt
, SPU_ES
, fcc
[i_channel
] );
2162 fmt
.subs
.cc
.i_reorder_depth
= p_owner
->cc
.i_reorder_depth
;
2163 p_cc
= input_DecoderNew( p_owner
->p_input
, &fmt
,
2164 p_dec
->p_owner
->p_clock
, p_owner
->p_sout
);
2167 msg_Err( p_dec
, "could not create decoder" );
2168 vlc_dialog_display_error( p_dec
,
2169 _("Streaming / Transcoding failed"), "%s",
2170 _("VLC could not open the decoder module.") );
2171 return VLC_EGENERIC
;
2173 else if( !p_cc
->p_module
)
2175 DecoderUnsupportedCodec( p_dec
, &fmt
, true );
2176 input_DecoderDelete(p_cc
);
2177 return VLC_EGENERIC
;
2179 p_cc
->p_owner
->p_clock
= p_owner
->p_clock
;
2181 vlc_mutex_lock( &p_owner
->lock
);
2182 p_owner
->cc
.pp_decoder
[i_channel
] = p_cc
;
2183 vlc_mutex_unlock( &p_owner
->lock
);
2189 vlc_mutex_lock( &p_owner
->lock
);
2190 p_cc
= p_owner
->cc
.pp_decoder
[i_channel
];
2191 p_owner
->cc
.pp_decoder
[i_channel
] = NULL
;
2192 vlc_mutex_unlock( &p_owner
->lock
);
2195 input_DecoderDelete(p_cc
);
2200 int input_DecoderGetCcState( decoder_t
*p_dec
, bool *pb_decode
, int i_channel
)
2202 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2205 if( i_channel
< 0 || i_channel
>= 4 || !p_owner
->cc
.pb_present
[i_channel
] )
2206 return VLC_EGENERIC
;
2208 vlc_mutex_lock( &p_owner
->lock
);
2209 *pb_decode
= p_owner
->cc
.pp_decoder
[i_channel
] != NULL
;
2210 vlc_mutex_unlock( &p_owner
->lock
);
2211 return VLC_EGENERIC
;
2214 void input_DecoderChangePause( decoder_t
*p_dec
, bool b_paused
, mtime_t i_date
)
2216 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2218 /* Normally, p_owner->b_paused != b_paused here. But if a track is added
2219 * while the input is paused (e.g. add sub file), then b_paused is
2220 * (incorrectly) false. FIXME: This is a bug in the decoder owner. */
2221 vlc_fifo_Lock( p_owner
->p_fifo
);
2222 p_owner
->paused
= b_paused
;
2223 p_owner
->pause_date
= i_date
;
2224 p_owner
->frames_countdown
= 0;
2225 vlc_fifo_Signal( p_owner
->p_fifo
);
2226 vlc_fifo_Unlock( p_owner
->p_fifo
);
2229 void input_DecoderChangeDelay( decoder_t
*p_dec
, mtime_t i_delay
)
2231 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2233 vlc_mutex_lock( &p_owner
->lock
);
2234 p_owner
->i_ts_delay
= i_delay
;
2235 vlc_mutex_unlock( &p_owner
->lock
);
2238 void input_DecoderStartWait( decoder_t
*p_dec
)
2240 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2242 assert( !p_owner
->b_waiting
);
2244 vlc_mutex_lock( &p_owner
->lock
);
2245 p_owner
->b_first
= true;
2246 p_owner
->b_has_data
= false;
2247 p_owner
->b_waiting
= true;
2248 vlc_cond_signal( &p_owner
->wait_request
);
2249 vlc_mutex_unlock( &p_owner
->lock
);
2252 void input_DecoderStopWait( decoder_t
*p_dec
)
2254 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2256 assert( p_owner
->b_waiting
);
2258 vlc_mutex_lock( &p_owner
->lock
);
2259 p_owner
->b_waiting
= false;
2260 vlc_cond_signal( &p_owner
->wait_request
);
2261 vlc_mutex_unlock( &p_owner
->lock
);
2264 void input_DecoderWait( decoder_t
*p_dec
)
2266 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2268 assert( p_owner
->b_waiting
);
2270 vlc_mutex_lock( &p_owner
->lock
);
2271 while( !p_owner
->b_has_data
)
2273 /* Don't need to lock p_owner->paused since it's only modified by the
2275 if( p_owner
->paused
)
2277 vlc_fifo_Lock( p_owner
->p_fifo
);
2278 if( p_owner
->b_idle
&& vlc_fifo_IsEmpty( p_owner
->p_fifo
) )
2280 msg_Err( p_dec
, "buffer deadlock prevented" );
2281 vlc_fifo_Unlock( p_owner
->p_fifo
);
2284 vlc_fifo_Unlock( p_owner
->p_fifo
);
2285 vlc_cond_wait( &p_owner
->wait_acknowledge
, &p_owner
->lock
);
2287 vlc_mutex_unlock( &p_owner
->lock
);
2290 void input_DecoderFrameNext( decoder_t
*p_dec
, mtime_t
*pi_duration
)
2292 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2294 assert( p_owner
->paused
);
2297 vlc_fifo_Lock( p_owner
->p_fifo
);
2298 p_owner
->frames_countdown
++;
2299 vlc_fifo_Signal( p_owner
->p_fifo
);
2300 vlc_fifo_Unlock( p_owner
->p_fifo
);
2302 vlc_mutex_lock( &p_owner
->lock
);
2303 if( p_owner
->fmt
.i_cat
== VIDEO_ES
)
2305 if( p_owner
->p_vout
)
2306 vout_NextPicture( p_owner
->p_vout
, pi_duration
);
2308 vlc_mutex_unlock( &p_owner
->lock
);
2311 bool input_DecoderHasFormatChanged( decoder_t
*p_dec
, es_format_t
*p_fmt
, vlc_meta_t
**pp_meta
)
2313 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2316 vlc_mutex_lock( &p_owner
->lock
);
2317 b_changed
= p_owner
->b_fmt_description
;
2321 es_format_Copy( p_fmt
, &p_owner
->fmt
);
2326 if( p_owner
->p_description
)
2328 *pp_meta
= vlc_meta_New();
2330 vlc_meta_Merge( *pp_meta
, p_owner
->p_description
);
2333 p_owner
->b_fmt_description
= false;
2335 vlc_mutex_unlock( &p_owner
->lock
);
2339 size_t input_DecoderGetFifoSize( decoder_t
*p_dec
)
2341 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2343 return block_FifoSize( p_owner
->p_fifo
);
2346 void input_DecoderGetObjects( decoder_t
*p_dec
,
2347 vout_thread_t
**pp_vout
, audio_output_t
**pp_aout
)
2349 decoder_owner_sys_t
*p_owner
= p_dec
->p_owner
;
2351 vlc_mutex_lock( &p_owner
->lock
);
2353 *pp_vout
= p_owner
->p_vout
? vlc_object_hold( p_owner
->p_vout
) : NULL
;
2355 *pp_aout
= p_owner
->p_aout
? vlc_object_hold( p_owner
->p_aout
) : NULL
;
2356 vlc_mutex_unlock( &p_owner
->lock
);