stream_output: add sout_InputFlush()
[vlc.git] / src / input / decoder.c
blob5be414d4dedad8856dd498ed1d7cd85478fa66e0
1 /*****************************************************************************
2 * decoder.c: Functions for the management of decoders
3 *****************************************************************************
4 * Copyright (C) 1999-2004 VLC authors and VideoLAN
5 * $Id$
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 /*****************************************************************************
27 * Preamble
28 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
34 #include <vlc_common.h>
36 #include <vlc_atomic.h>
37 #include <vlc_block.h>
38 #include <vlc_vout.h>
39 #include <vlc_aout.h>
40 #include <vlc_sout.h>
41 #include <vlc_codec.h>
42 #include <vlc_spu.h>
43 #include <vlc_meta.h>
44 #include <vlc_dialog.h>
45 #include <vlc_modules.h>
47 #include "audio_output/aout_internal.h"
48 #include "stream_output/stream_output.h"
49 #include "input_internal.h"
50 #include "clock.h"
51 #include "decoder.h"
52 #include "event.h"
53 #include "resource.h"
55 #include "../video_output/vout_control.h"
57 struct decoder_owner_sys_t
59 input_thread_t *p_input;
60 input_resource_t*p_resource;
61 input_clock_t *p_clock;
62 int i_last_rate;
64 vout_thread_t *p_spu_vout;
65 int i_spu_channel;
66 int64_t i_spu_order;
68 sout_instance_t *p_sout;
69 sout_packetizer_input_t *p_sout_input;
71 vlc_thread_t thread;
73 /* Some decoders require already packetized data (ie. not truncated) */
74 decoder_t *p_packetizer;
75 bool b_packetizer;
77 /* Current format in use by the output */
78 es_format_t fmt;
80 /* */
81 bool b_fmt_description;
82 vlc_meta_t *p_description;
84 /* fifo */
85 block_fifo_t *p_fifo;
87 /* Lock for communication with decoder thread */
88 vlc_mutex_t lock;
89 vlc_cond_t wait_request;
90 vlc_cond_t wait_acknowledge;
91 vlc_cond_t wait_fifo; /* TODO: merge with wait_acknowledge */
92 vlc_cond_t wait_timed;
94 /* -- These variables need locking on write(only) -- */
95 audio_output_t *p_aout;
97 vout_thread_t *p_vout;
99 /* -- Theses variables need locking on read *and* write -- */
100 /* Preroll */
101 int64_t i_preroll_end;
102 /* Pause */
103 mtime_t pause_date;
104 unsigned frames_countdown;
105 bool paused;
107 /* Waiting */
108 bool b_waiting;
109 bool b_first;
110 bool b_has_data;
112 /* Flushing */
113 bool flushing;
114 bool b_draining;
115 atomic_bool drained;
116 bool b_idle;
118 /* CC */
119 struct
121 bool b_supported;
122 bool pb_present[4];
123 decoder_t *pp_decoder[4];
124 } cc;
126 /* Delay */
127 mtime_t i_ts_delay;
130 /* Pictures which are DECODER_BOGUS_VIDEO_DELAY or more in advance probably have
131 * a bogus PTS and won't be displayed */
132 #define DECODER_BOGUS_VIDEO_DELAY ((mtime_t)(DEFAULT_PTS_DELAY * 30))
134 /* */
135 #define DECODER_SPU_VOUT_WAIT_DURATION ((int)(0.200*CLOCK_FREQ))
138 * Load a decoder module
140 static int LoadDecoder( decoder_t *p_dec, bool b_packetizer,
141 const es_format_t *restrict p_fmt )
143 p_dec->b_frame_drop_allowed = true;
144 p_dec->i_extra_picture_buffers = 0;
146 p_dec->pf_decode_audio = NULL;
147 p_dec->pf_decode_video = NULL;
148 p_dec->pf_decode_sub = NULL;
149 p_dec->pf_get_cc = NULL;
150 p_dec->pf_packetize = NULL;
151 p_dec->pf_flush = NULL;
153 es_format_Copy( &p_dec->fmt_in, p_fmt );
154 es_format_Init( &p_dec->fmt_out, UNKNOWN_ES, 0 );
156 /* Find a suitable decoder/packetizer module */
157 if( !b_packetizer )
158 p_dec->p_module = module_need( p_dec, "decoder", "$codec", false );
159 else
160 p_dec->p_module = module_need( p_dec, "packetizer", "$packetizer", false );
162 if( !p_dec->p_module )
164 es_format_Clean( &p_dec->fmt_in );
165 return -1;
167 else
168 return 0;
172 * Unload a decoder module
174 static void UnloadDecoder( decoder_t *p_dec )
176 if( p_dec->p_module )
178 module_unneed( p_dec, p_dec->p_module );
179 p_dec->p_module = NULL;
182 if( p_dec->p_description )
184 vlc_meta_Delete( p_dec->p_description );
185 p_dec->p_description = NULL;
188 es_format_Clean( &p_dec->fmt_in );
189 es_format_Clean( &p_dec->fmt_out );
190 p_dec->b_error = false;
193 static void DecoderUpdateFormatLocked( decoder_t *p_dec )
195 decoder_owner_sys_t *p_owner = p_dec->p_owner;
197 vlc_assert_locked( &p_owner->lock );
199 es_format_Clean( &p_owner->fmt );
200 es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
202 /* Move p_description */
203 if( p_dec->p_description != NULL )
205 if( p_owner->p_description != NULL )
206 vlc_meta_Delete( p_owner->p_description );
207 p_owner->p_description = p_dec->p_description;
208 p_dec->p_description = NULL;
211 p_owner->b_fmt_description = true;
214 /*****************************************************************************
215 * Buffers allocation callbacks for the decoders
216 *****************************************************************************/
217 static vout_thread_t *aout_request_vout( void *p_private,
218 vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recyle )
220 decoder_t *p_dec = p_private;
221 decoder_owner_sys_t *p_owner = p_dec->p_owner;
222 input_thread_t *p_input = p_owner->p_input;
224 p_vout = input_resource_RequestVout( p_owner->p_resource, p_vout, p_fmt, 1,
225 b_recyle );
226 if( p_input != NULL )
227 input_SendEventVout( p_input );
229 return p_vout;
232 static int aout_update_format( decoder_t *p_dec )
234 decoder_owner_sys_t *p_owner = p_dec->p_owner;
236 if( p_owner->p_aout
237 && !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) )
239 audio_output_t *p_aout = p_owner->p_aout;
241 /* Parameters changed, restart the aout */
242 vlc_mutex_lock( &p_owner->lock );
243 p_owner->p_aout = NULL;
244 vlc_mutex_unlock( &p_owner->lock );
245 aout_DecDelete( p_aout );
247 input_resource_PutAout( p_owner->p_resource, p_aout );
250 if( p_owner->p_aout == NULL )
252 p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
254 audio_sample_format_t format = p_dec->fmt_out.audio;
255 aout_FormatPrepare( &format );
257 const int i_force_dolby = var_InheritInteger( p_dec, "force-dolby-surround" );
258 if( i_force_dolby &&
259 (format.i_original_channels&AOUT_CHAN_PHYSMASK) ==
260 (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
262 if( i_force_dolby == 1 )
264 format.i_original_channels = format.i_original_channels |
265 AOUT_CHAN_DOLBYSTEREO;
267 else /* i_force_dolby == 2 */
269 format.i_original_channels = format.i_original_channels &
270 ~AOUT_CHAN_DOLBYSTEREO;
274 aout_request_vout_t request_vout = {
275 .pf_request_vout = aout_request_vout,
276 .p_private = p_dec,
278 audio_output_t *p_aout;
280 p_aout = input_resource_GetAout( p_owner->p_resource );
281 if( p_aout )
283 if( aout_DecNew( p_aout, &format,
284 &p_dec->fmt_out.audio_replay_gain,
285 &request_vout ) )
287 input_resource_PutAout( p_owner->p_resource, p_aout );
288 p_aout = NULL;
292 vlc_mutex_lock( &p_owner->lock );
293 p_owner->p_aout = p_aout;
295 DecoderUpdateFormatLocked( p_dec );
296 aout_FormatPrepare( &p_owner->fmt.audio );
297 vlc_mutex_unlock( &p_owner->lock );
299 if( p_owner->p_input != NULL )
300 input_SendEventAout( p_owner->p_input );
302 if( p_aout == NULL )
304 msg_Err( p_dec, "failed to create audio output" );
305 p_dec->b_error = true;
306 return -1;
309 p_dec->fmt_out.audio.i_bytes_per_frame =
310 p_owner->fmt.audio.i_bytes_per_frame;
311 p_dec->fmt_out.audio.i_frame_length =
312 p_owner->fmt.audio.i_frame_length;
314 return 0;
317 static int vout_update_format( decoder_t *p_dec )
319 decoder_owner_sys_t *p_owner = p_dec->p_owner;
321 if( p_owner->p_vout == NULL
322 || p_dec->fmt_out.video.i_width != p_owner->fmt.video.i_width
323 || p_dec->fmt_out.video.i_height != p_owner->fmt.video.i_height
324 || p_dec->fmt_out.video.i_visible_width != p_owner->fmt.video.i_visible_width
325 || p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
326 || p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
327 || p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset
328 || p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma
329 || (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
330 (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num ||
331 p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation )
333 vout_thread_t *p_vout;
335 if( !p_dec->fmt_out.video.i_width ||
336 !p_dec->fmt_out.video.i_height )
338 /* Can't create a new vout without display size */
339 return -1;
342 video_format_t fmt = p_dec->fmt_out.video;
343 fmt.i_chroma = p_dec->fmt_out.i_codec;
345 if( vlc_fourcc_IsYUV( fmt.i_chroma ) )
347 const vlc_chroma_description_t *dsc = vlc_fourcc_GetChromaDescription( fmt.i_chroma );
348 for( unsigned int i = 0; dsc && i < dsc->plane_count; i++ )
350 while( fmt.i_width % dsc->p[i].w.den )
351 fmt.i_width++;
352 while( fmt.i_height % dsc->p[i].h.den )
353 fmt.i_height++;
357 if( !fmt.i_visible_width || !fmt.i_visible_height )
359 if( p_dec->fmt_in.video.i_visible_width &&
360 p_dec->fmt_in.video.i_visible_height )
362 fmt.i_visible_width = p_dec->fmt_in.video.i_visible_width;
363 fmt.i_visible_height = p_dec->fmt_in.video.i_visible_height;
364 fmt.i_x_offset = p_dec->fmt_in.video.i_x_offset;
365 fmt.i_y_offset = p_dec->fmt_in.video.i_y_offset;
367 else
369 fmt.i_visible_width = fmt.i_width;
370 fmt.i_visible_height = fmt.i_height;
371 fmt.i_x_offset = 0;
372 fmt.i_y_offset = 0;
376 if( fmt.i_visible_height == 1088 &&
377 var_CreateGetBool( p_dec, "hdtv-fix" ) )
379 fmt.i_visible_height = 1080;
380 if( !(fmt.i_sar_num % 136))
382 fmt.i_sar_num *= 135;
383 fmt.i_sar_den *= 136;
385 msg_Warn( p_dec, "Fixing broken HDTV stream (display_height=1088)");
388 if( !fmt.i_sar_num || !fmt.i_sar_den )
390 fmt.i_sar_num = 1;
391 fmt.i_sar_den = 1;
394 vlc_ureduce( &fmt.i_sar_num, &fmt.i_sar_den,
395 fmt.i_sar_num, fmt.i_sar_den, 50000 );
397 vlc_mutex_lock( &p_owner->lock );
399 p_vout = p_owner->p_vout;
400 p_owner->p_vout = NULL;
401 vlc_mutex_unlock( &p_owner->lock );
403 unsigned dpb_size;
404 switch( p_dec->fmt_in.i_codec )
406 case VLC_CODEC_HEVC:
407 case VLC_CODEC_H264:
408 case VLC_CODEC_DIRAC: /* FIXME valid ? */
409 dpb_size = 18;
410 break;
411 case VLC_CODEC_VP5:
412 case VLC_CODEC_VP6:
413 case VLC_CODEC_VP6F:
414 case VLC_CODEC_VP8:
415 dpb_size = 3;
416 break;
417 default:
418 dpb_size = 2;
419 break;
421 p_vout = input_resource_RequestVout( p_owner->p_resource,
422 p_vout, &fmt,
423 dpb_size +
424 p_dec->i_extra_picture_buffers + 1,
425 true );
426 vlc_mutex_lock( &p_owner->lock );
427 p_owner->p_vout = p_vout;
429 DecoderUpdateFormatLocked( p_dec );
430 p_owner->fmt.video.i_chroma = p_dec->fmt_out.i_codec;
431 vlc_mutex_unlock( &p_owner->lock );
433 if( p_owner->p_input != NULL )
434 input_SendEventVout( p_owner->p_input );
435 if( p_vout == NULL )
437 msg_Err( p_dec, "failed to create video output" );
438 return -1;
441 return 0;
444 static picture_t *vout_new_buffer( decoder_t *p_dec )
446 decoder_owner_sys_t *p_owner = p_dec->p_owner;
448 return vout_GetPicture( p_owner->p_vout );
451 static subpicture_t *spu_new_buffer( decoder_t *p_dec,
452 const subpicture_updater_t *p_updater )
454 decoder_owner_sys_t *p_owner = p_dec->p_owner;
455 vout_thread_t *p_vout = NULL;
456 subpicture_t *p_subpic;
457 int i_attempts = 30;
459 while( i_attempts-- )
461 if( p_dec->b_error )
462 break;
464 p_vout = input_resource_HoldVout( p_owner->p_resource );
465 if( p_vout )
466 break;
468 msleep( DECODER_SPU_VOUT_WAIT_DURATION );
471 if( !p_vout )
473 msg_Warn( p_dec, "no vout found, dropping subpicture" );
474 return NULL;
477 if( p_owner->p_spu_vout != p_vout )
479 p_owner->i_spu_channel = vout_RegisterSubpictureChannel( p_vout );
480 p_owner->i_spu_order = 0;
481 p_owner->p_spu_vout = p_vout;
484 p_subpic = subpicture_New( p_updater );
485 if( p_subpic )
487 p_subpic->i_channel = p_owner->i_spu_channel;
488 p_subpic->i_order = p_owner->i_spu_order++;
489 p_subpic->b_subtitle = true;
492 vlc_object_release( p_vout );
494 return p_subpic;
497 static int DecoderGetInputAttachments( decoder_t *p_dec,
498 input_attachment_t ***ppp_attachment,
499 int *pi_attachment )
501 input_thread_t *p_input = p_dec->p_owner->p_input;
503 if( unlikely(p_input == NULL) )
504 return VLC_ENOOBJ;
505 return input_Control( p_input, INPUT_GET_ATTACHMENTS,
506 ppp_attachment, pi_attachment );
509 static mtime_t DecoderGetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
511 decoder_owner_sys_t *p_owner = p_dec->p_owner;
513 vlc_mutex_lock( &p_owner->lock );
514 if( p_owner->b_waiting )
515 i_ts = VLC_TS_INVALID;
516 vlc_mutex_unlock( &p_owner->lock );
518 if( !p_owner->p_clock || i_ts <= VLC_TS_INVALID )
519 return i_ts;
521 if( input_clock_ConvertTS( VLC_OBJECT(p_dec), p_owner->p_clock, NULL, &i_ts, NULL, INT64_MAX ) ) {
522 msg_Err(p_dec, "Could not get display date for timestamp %"PRId64"", i_ts);
523 return VLC_TS_INVALID;
526 return i_ts;
529 static int DecoderGetDisplayRate( decoder_t *p_dec )
531 decoder_owner_sys_t *p_owner = p_dec->p_owner;
533 if( !p_owner->p_clock )
534 return INPUT_RATE_DEFAULT;
535 return input_clock_GetRate( p_owner->p_clock );
538 /*****************************************************************************
539 * Public functions
540 *****************************************************************************/
541 block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples )
543 if( decoder_UpdateAudioFormat( dec ) )
544 return NULL;
546 size_t length = samples * dec->fmt_out.audio.i_bytes_per_frame
547 / dec->fmt_out.audio.i_frame_length;
548 block_t *block = block_Alloc( length );
549 if( likely(block != NULL) )
551 block->i_nb_samples = samples;
552 block->i_pts = block->i_length = 0;
554 return block;
557 subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
558 const subpicture_updater_t *p_dyn )
560 subpicture_t *p_subpicture = p_decoder->pf_spu_buffer_new( p_decoder, p_dyn );
561 if( !p_subpicture )
562 msg_Warn( p_decoder, "can't get output subpicture" );
563 return p_subpicture;
566 /* decoder_GetInputAttachments:
568 int decoder_GetInputAttachments( decoder_t *p_dec,
569 input_attachment_t ***ppp_attachment,
570 int *pi_attachment )
572 if( !p_dec->pf_get_attachments )
573 return VLC_EGENERIC;
575 return p_dec->pf_get_attachments( p_dec, ppp_attachment, pi_attachment );
577 /* decoder_GetDisplayDate:
579 mtime_t decoder_GetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
581 if( !p_dec->pf_get_display_date )
582 return VLC_TS_INVALID;
584 return p_dec->pf_get_display_date( p_dec, i_ts );
586 /* decoder_GetDisplayRate:
588 int decoder_GetDisplayRate( decoder_t *p_dec )
590 if( !p_dec->pf_get_display_rate )
591 return INPUT_RATE_DEFAULT;
593 return p_dec->pf_get_display_rate( p_dec );
596 void decoder_AbortPictures( decoder_t *p_dec, bool b_abort )
598 decoder_owner_sys_t *p_owner = p_dec->p_owner;
600 vlc_mutex_lock( &p_owner->lock );
601 if( p_owner->p_vout != NULL )
602 vout_Cancel( p_owner->p_vout, b_abort );
603 vlc_mutex_unlock( &p_owner->lock );
606 static void DecoderWaitUnblock( decoder_t *p_dec )
608 decoder_owner_sys_t *p_owner = p_dec->p_owner;
610 vlc_assert_locked( &p_owner->lock );
612 for( ;; )
614 if( !p_owner->b_waiting || !p_owner->b_has_data )
615 break;
616 vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
620 /* DecoderTimedWait: Interruptible wait
621 * Returns VLC_SUCCESS if wait was not interrupted, and VLC_EGENERIC otherwise */
622 static int DecoderTimedWait( decoder_t *p_dec, mtime_t deadline )
624 decoder_owner_sys_t *p_owner = p_dec->p_owner;
626 if (deadline - mdate() <= 0)
627 return VLC_SUCCESS;
629 vlc_fifo_Lock( p_owner->p_fifo );
630 while( !p_owner->flushing
631 && vlc_fifo_TimedWaitCond( p_owner->p_fifo, &p_owner->wait_timed,
632 deadline ) == 0 );
633 int ret = p_owner->flushing ? VLC_EGENERIC : VLC_SUCCESS;
634 vlc_fifo_Unlock( p_owner->p_fifo );
635 return ret;
638 static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
640 if( p->i_flags & (BLOCK_FLAG_PREROLL|BLOCK_FLAG_DISCONTINUITY) )
641 *pi_preroll = INT64_MAX;
642 else if( p->i_dts > VLC_TS_INVALID )
643 *pi_preroll = __MIN( *pi_preroll, p->i_dts );
644 else if( p->i_pts > VLC_TS_INVALID )
645 *pi_preroll = __MIN( *pi_preroll, p->i_pts );
648 static void DecoderFixTs( decoder_t *p_dec, mtime_t *pi_ts0, mtime_t *pi_ts1,
649 mtime_t *pi_duration, int *pi_rate, mtime_t i_ts_bound )
651 decoder_owner_sys_t *p_owner = p_dec->p_owner;
652 input_clock_t *p_clock = p_owner->p_clock;
654 vlc_assert_locked( &p_owner->lock );
656 const mtime_t i_es_delay = p_owner->i_ts_delay;
658 if( !p_clock )
659 return;
661 const bool b_ephemere = pi_ts1 && *pi_ts0 == *pi_ts1;
662 int i_rate;
664 if( *pi_ts0 > VLC_TS_INVALID )
666 *pi_ts0 += i_es_delay;
667 if( pi_ts1 && *pi_ts1 > VLC_TS_INVALID )
668 *pi_ts1 += i_es_delay;
669 if( i_ts_bound != INT64_MAX )
670 i_ts_bound += i_es_delay;
671 if( input_clock_ConvertTS( VLC_OBJECT(p_dec), p_clock, &i_rate, pi_ts0, pi_ts1, i_ts_bound ) ) {
672 if( pi_ts1 != NULL )
673 msg_Err(p_dec, "Could not convert timestamps %"PRId64
674 ", %"PRId64"", *pi_ts0, *pi_ts1);
675 else
676 msg_Err(p_dec, "Could not convert timestamp %"PRId64, *pi_ts0);
677 *pi_ts0 = VLC_TS_INVALID;
680 else
682 i_rate = input_clock_GetRate( p_clock );
685 /* Do not create ephemere data because of rounding errors */
686 if( !b_ephemere && pi_ts1 && *pi_ts0 == *pi_ts1 )
687 *pi_ts1 += 1;
689 if( pi_duration )
690 *pi_duration = ( *pi_duration * i_rate + INPUT_RATE_DEFAULT-1 )
691 / INPUT_RATE_DEFAULT;
693 if( pi_rate )
694 *pi_rate = i_rate;
697 #ifdef ENABLE_SOUT
698 static int DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block )
700 decoder_owner_sys_t *p_owner = p_dec->p_owner;
702 assert( p_owner->p_clock );
703 assert( !p_sout_block->p_next );
705 vlc_mutex_lock( &p_owner->lock );
707 if( p_owner->b_waiting )
709 p_owner->b_has_data = true;
710 vlc_cond_signal( &p_owner->wait_acknowledge );
713 DecoderWaitUnblock( p_dec );
714 DecoderFixTs( p_dec, &p_sout_block->i_dts, &p_sout_block->i_pts,
715 &p_sout_block->i_length, NULL, INT64_MAX );
717 vlc_mutex_unlock( &p_owner->lock );
719 /* FIXME --VLC_TS_INVALID inspect stream_output*/
720 return sout_InputSendBuffer( p_owner->p_sout_input, p_sout_block );
723 /* This function process a block for sout
725 static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block )
727 decoder_owner_sys_t *p_owner = p_dec->p_owner;
728 block_t *p_sout_block;
729 block_t **pp_block = p_block ? &p_block : NULL;
731 while( ( p_sout_block =
732 p_dec->pf_packetize( p_dec, pp_block ) ) )
734 if( p_owner->p_sout_input == NULL )
736 vlc_mutex_lock( &p_owner->lock );
737 DecoderUpdateFormatLocked( p_dec );
738 vlc_mutex_unlock( &p_owner->lock );
740 p_owner->fmt.i_group = p_dec->fmt_in.i_group;
741 p_owner->fmt.i_id = p_dec->fmt_in.i_id;
742 if( p_dec->fmt_in.psz_language )
744 free( p_owner->fmt.psz_language );
745 p_owner->fmt.psz_language =
746 strdup( p_dec->fmt_in.psz_language );
749 p_owner->p_sout_input =
750 sout_InputNew( p_owner->p_sout, &p_owner->fmt );
752 if( p_owner->p_sout_input == NULL )
754 msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
755 (char *)&p_owner->fmt.i_codec );
756 p_dec->b_error = true;
758 block_ChainRelease(p_sout_block);
759 break;
763 while( p_sout_block )
765 block_t *p_next = p_sout_block->p_next;
767 p_sout_block->p_next = NULL;
769 if( DecoderPlaySout( p_dec, p_sout_block ) == VLC_EGENERIC )
771 msg_Err( p_dec, "cannot continue streaming due to errors" );
773 p_dec->b_error = true;
775 /* Cleanup */
776 block_ChainRelease( p_next );
777 return;
780 p_sout_block = p_next;
784 #endif
786 static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
788 decoder_owner_sys_t *p_owner = p_dec->p_owner;
789 block_t *p_cc;
790 bool pb_present[4];
791 bool b_processed = false;
792 int i;
793 int i_cc_decoder;
795 assert( p_dec_cc->pf_get_cc != NULL );
797 /* Do not try retreiving CC if not wanted (sout) or cannot be retreived */
798 if( !p_owner->cc.b_supported )
799 return;
801 p_cc = p_dec_cc->pf_get_cc( p_dec_cc, pb_present );
802 if( !p_cc )
803 return;
805 vlc_mutex_lock( &p_owner->lock );
806 for( i = 0, i_cc_decoder = 0; i < 4; i++ )
808 p_owner->cc.pb_present[i] |= pb_present[i];
809 if( p_owner->cc.pp_decoder[i] )
810 i_cc_decoder++;
813 for( i = 0; i < 4; i++ )
815 if( !p_owner->cc.pp_decoder[i] )
816 continue;
818 block_FifoPut( p_owner->cc.pp_decoder[i]->p_owner->p_fifo,
819 (i_cc_decoder > 1) ? block_Duplicate(p_cc) : p_cc);
821 i_cc_decoder--;
822 b_processed = true;
824 vlc_mutex_unlock( &p_owner->lock );
826 if( !b_processed )
827 block_Release( p_cc );
830 static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
831 int *pi_played_sum, int *pi_lost_sum )
833 decoder_owner_sys_t *p_owner = p_dec->p_owner;
834 vout_thread_t *p_vout = p_owner->p_vout;
836 if( p_picture->date <= VLC_TS_INVALID )
838 msg_Warn( p_dec, "non-dated video buffer received" );
839 *pi_lost_sum += 1;
840 picture_Release( p_picture );
841 return;
844 /* */
845 vlc_mutex_lock( &p_owner->lock );
847 if( p_owner->b_waiting && !p_owner->b_first )
849 p_owner->b_has_data = true;
850 vlc_cond_signal( &p_owner->wait_acknowledge );
852 bool b_first_after_wait = p_owner->b_waiting && p_owner->b_has_data;
854 DecoderWaitUnblock( p_dec );
856 if( p_owner->b_waiting )
858 assert( p_owner->b_first );
859 msg_Dbg( p_dec, "Received first picture" );
860 p_owner->b_first = false;
861 p_picture->b_force = true;
864 const bool b_dated = p_picture->date > VLC_TS_INVALID;
865 int i_rate = INPUT_RATE_DEFAULT;
866 DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
867 &i_rate, DECODER_BOGUS_VIDEO_DELAY );
869 vlc_mutex_unlock( &p_owner->lock );
871 /* FIXME: The *input* FIFO should not be locked here. This will not work
872 * properly if/when pictures are queued asynchronously. */
873 vlc_fifo_Lock( p_owner->p_fifo );
874 if( unlikely(p_owner->paused) && likely(p_owner->frames_countdown > 0) )
875 p_owner->frames_countdown--;
876 vlc_fifo_Unlock( p_owner->p_fifo );
878 /* */
879 if( p_picture->b_force || p_picture->date > VLC_TS_INVALID )
880 /* FIXME: VLC_TS_INVALID -- verify video_output */
882 if( i_rate != p_owner->i_last_rate || b_first_after_wait )
884 /* Be sure to not display old picture after our own */
885 vout_Flush( p_vout, p_picture->date );
886 p_owner->i_last_rate = i_rate;
888 vout_PutPicture( p_vout, p_picture );
890 else
892 if( b_dated )
893 msg_Warn( p_dec, "early picture skipped" );
894 else
895 msg_Warn( p_dec, "non-dated video buffer received" );
897 *pi_lost_sum += 1;
898 picture_Release( p_picture );
900 int i_tmp_display;
901 int i_tmp_lost;
902 vout_GetResetStatistic( p_vout, &i_tmp_display, &i_tmp_lost );
904 *pi_played_sum += i_tmp_display;
905 *pi_lost_sum += i_tmp_lost;
908 static int DecoderPreparePlayVideo( decoder_t *p_dec, picture_t *p_pic )
910 decoder_owner_sys_t *p_owner = p_dec->p_owner;
911 vout_thread_t *p_vout = p_owner->p_vout;
912 bool prerolled;
914 vlc_mutex_lock( &p_owner->lock );
915 if( p_owner->i_preroll_end > p_pic->date )
917 vlc_mutex_unlock( &p_owner->lock );
918 picture_Release( p_pic );
919 return -1;
922 prerolled = p_owner->i_preroll_end > INT64_MIN;
923 p_owner->i_preroll_end = INT64_MIN;
924 vlc_mutex_unlock( &p_owner->lock );
926 if( unlikely(prerolled) )
928 msg_Dbg( p_dec, "end of video preroll" );
930 if( p_vout )
931 vout_Flush( p_vout, VLC_TS_INVALID+1 );
934 if( p_dec->pf_get_cc &&
935 ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
936 DecoderGetCc( p_dec, p_dec );
938 return 0;
941 static void DecoderUpdateStatVideo( decoder_t *p_dec, int i_decoded,
942 int i_lost, int i_displayed )
944 decoder_owner_sys_t *p_owner = p_dec->p_owner;
945 input_thread_t *p_input = p_owner->p_input;
947 /* Update ugly stat */
948 if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_displayed > 0) )
950 vlc_mutex_lock( &p_input->p->counters.counters_lock );
951 stats_Update( p_input->p->counters.p_decoded_video, i_decoded, NULL );
952 stats_Update( p_input->p->counters.p_lost_pictures, i_lost , NULL);
953 stats_Update( p_input->p->counters.p_displayed_pictures,
954 i_displayed, NULL);
955 vlc_mutex_unlock( &p_input->p->counters.counters_lock );
959 static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic )
961 assert( p_pic );
962 int i_lost = 0;
963 int i_displayed = 0;
964 int i_ret;
966 if( ( i_ret = DecoderPreparePlayVideo( p_dec, p_pic ) ) == 0 )
967 DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
969 DecoderUpdateStatVideo( p_dec, 1, i_lost, i_displayed );
970 return i_ret;
973 static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
975 picture_t *p_pic;
976 block_t **pp_block = p_block ? &p_block : NULL;
977 int i_lost = 0;
978 int i_decoded = 0;
979 int i_displayed = 0;
981 while( (p_pic = p_dec->pf_decode_video( p_dec, pp_block ) ) )
983 i_decoded++;
985 if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 )
986 continue;
988 DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
991 DecoderUpdateStatVideo( p_dec, i_decoded, i_lost, i_displayed );
994 /* This function process a video block
996 static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block )
998 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1000 if( p_owner->p_packetizer )
1002 block_t *p_packetized_block;
1003 block_t **pp_block = p_block ? &p_block : NULL;
1004 decoder_t *p_packetizer = p_owner->p_packetizer;
1006 while( (p_packetized_block =
1007 p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
1009 if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
1011 msg_Dbg( p_dec, "restarting module due to input format change");
1013 /* Drain the decoder module */
1014 DecoderDecodeVideo( p_dec, NULL );
1015 /* Restart the decoder module */
1016 UnloadDecoder( p_dec );
1017 if( LoadDecoder( p_dec, false, &p_packetizer->fmt_out ) )
1019 p_dec->b_error = true;
1020 block_ChainRelease( p_packetized_block );
1021 return;
1025 if( p_packetizer->pf_get_cc )
1026 DecoderGetCc( p_dec, p_packetizer );
1028 while( p_packetized_block )
1030 block_t *p_next = p_packetized_block->p_next;
1031 p_packetized_block->p_next = NULL;
1033 DecoderDecodeVideo( p_dec, p_packetized_block );
1035 p_packetized_block = p_next;
1038 /* Drain the decoder after the packetizer is drained */
1039 if( !pp_block )
1040 DecoderDecodeVideo( p_dec, NULL );
1042 else
1044 DecoderDecodeVideo( p_dec, p_block );
1048 static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
1049 int *pi_played_sum, int *pi_lost_sum )
1051 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1053 /* */
1054 if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
1056 msg_Warn( p_dec, "non-dated audio buffer received" );
1057 *pi_lost_sum += 1;
1058 block_Release( p_audio );
1059 return;
1062 /* */
1063 vlc_mutex_lock( &p_owner->lock );
1064 if( p_owner->b_waiting )
1066 p_owner->b_has_data = true;
1067 vlc_cond_signal( &p_owner->wait_acknowledge );
1070 /* */
1071 int i_rate = INPUT_RATE_DEFAULT;
1073 DecoderWaitUnblock( p_dec );
1074 DecoderFixTs( p_dec, &p_audio->i_pts, NULL, &p_audio->i_length,
1075 &i_rate, AOUT_MAX_ADVANCE_TIME );
1076 vlc_mutex_unlock( &p_owner->lock );
1078 audio_output_t *p_aout = p_owner->p_aout;
1080 if( p_aout == NULL || p_audio->i_pts <= VLC_TS_INVALID
1081 || i_rate < INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE
1082 || i_rate > INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE
1083 || DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME ) )
1085 msg_Dbg( p_dec, "discarded audio buffer" );
1086 *pi_lost_sum += 1;
1087 block_Release( p_audio );
1088 return;
1091 if( aout_DecPlay( p_aout, p_audio, i_rate ) == 0 )
1092 *pi_played_sum += 1;
1094 *pi_lost_sum += aout_DecGetResetLost( p_aout );
1097 static int DecoderPreparePlayAudio( decoder_t *p_dec, block_t *p_aout_buf )
1099 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1100 bool prerolled;
1102 vlc_mutex_lock( &p_owner->lock );
1103 if( p_owner->i_preroll_end > p_aout_buf->i_pts )
1105 vlc_mutex_unlock( &p_owner->lock );
1106 block_Release( p_aout_buf );
1107 return -1;
1110 prerolled = p_owner->i_preroll_end > INT64_MIN;
1111 p_owner->i_preroll_end = INT64_MIN;
1112 vlc_mutex_unlock( &p_owner->lock );
1114 if( unlikely(prerolled) )
1116 msg_Dbg( p_dec, "end of audio preroll" );
1118 if( p_owner->p_aout )
1119 aout_DecFlush( p_owner->p_aout, false );
1122 return 0;
1125 static void DecoderUpdateStatAudio( decoder_t *p_dec, int i_decoded,
1126 int i_lost, int i_played )
1128 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1129 input_thread_t *p_input = p_owner->p_input;
1131 /* Update ugly stat */
1132 if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_played > 0) )
1134 vlc_mutex_lock( &p_input->p->counters.counters_lock);
1135 stats_Update( p_input->p->counters.p_lost_abuffers, i_lost, NULL );
1136 stats_Update( p_input->p->counters.p_played_abuffers, i_played, NULL );
1137 stats_Update( p_input->p->counters.p_decoded_audio, i_decoded, NULL );
1138 vlc_mutex_unlock( &p_input->p->counters.counters_lock);
1142 static int DecoderQueueAudio( decoder_t *p_dec, block_t *p_aout_buf )
1144 assert( p_aout_buf );
1145 int i_lost = 0;
1146 int i_played = 0;
1147 int i_ret;
1149 if( ( i_ret = DecoderPreparePlayAudio( p_dec, p_aout_buf ) ) == 0 )
1150 DecoderPlayAudio( p_dec, p_aout_buf, &i_played, &i_lost );
1152 DecoderUpdateStatAudio( p_dec, 1, i_lost, i_played );
1154 return i_ret;
1157 static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
1159 block_t *p_aout_buf;
1160 block_t **pp_block = p_block ? &p_block : NULL;
1161 int i_decoded = 0;
1162 int i_lost = 0;
1163 int i_played = 0;
1165 while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, pp_block ) ) )
1167 i_decoded++;
1169 if( DecoderPreparePlayAudio( p_dec, p_aout_buf ) != 0 )
1170 continue;
1172 DecoderPlayAudio( p_dec, p_aout_buf, &i_played, &i_lost );
1175 DecoderUpdateStatAudio( p_dec, i_decoded, i_lost, i_played );
1178 /* This function process a audio block
1180 static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block )
1182 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1184 if( p_owner->p_packetizer )
1186 block_t *p_packetized_block;
1187 block_t **pp_block = p_block ? &p_block : NULL;
1188 decoder_t *p_packetizer = p_owner->p_packetizer;
1190 while( (p_packetized_block =
1191 p_packetizer->pf_packetize( p_packetizer, pp_block ) ) )
1193 if( !es_format_IsSimilar( &p_dec->fmt_in, &p_packetizer->fmt_out ) )
1195 msg_Dbg( p_dec, "restarting module due to input format change");
1197 /* Drain the decoder module */
1198 DecoderDecodeAudio( p_dec, NULL );
1199 /* Restart the decoder module */
1200 UnloadDecoder( p_dec );
1201 if( LoadDecoder( p_dec, false, &p_packetizer->fmt_out ) )
1203 p_dec->b_error = true;
1204 block_ChainRelease( p_packetized_block );
1205 return;
1209 while( p_packetized_block )
1211 block_t *p_next = p_packetized_block->p_next;
1212 p_packetized_block->p_next = NULL;
1214 DecoderDecodeAudio( p_dec, p_packetized_block );
1216 p_packetized_block = p_next;
1219 /* Drain the decoder after the packetizer is drained */
1220 if( !pp_block )
1221 DecoderDecodeAudio( p_dec, NULL );
1223 else
1225 DecoderDecodeAudio( p_dec, p_block );
1229 static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
1231 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1232 vout_thread_t *p_vout = p_owner->p_spu_vout;
1234 /* */
1235 if( p_subpic->i_start <= VLC_TS_INVALID )
1237 msg_Warn( p_dec, "non-dated spu buffer received" );
1238 subpicture_Delete( p_subpic );
1239 return;
1242 /* */
1243 vlc_mutex_lock( &p_owner->lock );
1245 if( p_owner->b_waiting )
1247 p_owner->b_has_data = true;
1248 vlc_cond_signal( &p_owner->wait_acknowledge );
1251 DecoderWaitUnblock( p_dec );
1252 DecoderFixTs( p_dec, &p_subpic->i_start, &p_subpic->i_stop, NULL,
1253 NULL, INT64_MAX );
1254 vlc_mutex_unlock( &p_owner->lock );
1256 if( p_subpic->i_start <= VLC_TS_INVALID
1257 || DecoderTimedWait( p_dec, p_subpic->i_start - SPU_MAX_PREPARE_TIME ) )
1259 subpicture_Delete( p_subpic );
1260 return;
1263 vout_PutSubpicture( p_vout, p_subpic );
1266 static int DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
1268 assert( p_spu );
1269 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1270 input_thread_t *p_input = p_owner->p_input;
1272 if( p_input != NULL )
1274 vlc_mutex_lock( &p_input->p->counters.counters_lock );
1275 stats_Update( p_input->p->counters.p_decoded_sub, 1, NULL );
1276 vlc_mutex_unlock( &p_input->p->counters.counters_lock );
1279 int i_ret = -1;
1280 vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
1281 if( p_vout && p_owner->p_spu_vout == p_vout )
1283 /* Preroll does not work very well with subtitle */
1284 vlc_mutex_lock( &p_owner->lock );
1285 if( p_spu->i_start > VLC_TS_INVALID &&
1286 p_spu->i_start < p_owner->i_preroll_end &&
1287 ( p_spu->i_stop <= VLC_TS_INVALID || p_spu->i_stop < p_owner->i_preroll_end ) )
1289 vlc_mutex_unlock( &p_owner->lock );
1290 subpicture_Delete( p_spu );
1292 else
1294 vlc_mutex_unlock( &p_owner->lock );
1295 DecoderPlaySpu( p_dec, p_spu );
1296 i_ret = 0;
1299 else
1301 subpicture_Delete( p_spu );
1303 if( p_vout )
1304 vlc_object_release( p_vout );
1305 return i_ret;
1308 /* This function process a subtitle block
1310 static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block )
1312 subpicture_t *p_spu;
1313 block_t **pp_block = p_block ? &p_block : NULL;
1315 while( (p_spu = p_dec->pf_decode_sub( p_dec, pp_block ) ) )
1316 DecoderQueueSpu( p_dec, p_spu );
1320 * Decode a block
1322 * \param p_dec the decoder object
1323 * \param p_block the block to decode
1324 * \return VLC_SUCCESS or an error code
1326 static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
1328 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1330 if( p_dec->b_error )
1332 if( p_block )
1333 block_Release( p_block );
1334 return;
1337 if( p_block && p_block->i_buffer <= 0 )
1339 block_Release( p_block );
1340 return;
1343 if( p_block )
1345 vlc_mutex_lock( &p_owner->lock );
1346 DecoderUpdatePreroll( &p_owner->i_preroll_end, p_block );
1347 vlc_mutex_unlock( &p_owner->lock );
1350 #ifdef ENABLE_SOUT
1351 if( p_owner->p_sout != NULL )
1353 DecoderProcessSout( p_dec, p_block );
1355 else
1356 #endif
1358 if( p_dec->fmt_out.i_cat == AUDIO_ES )
1360 DecoderProcessAudio( p_dec, p_block );
1362 else if( p_dec->fmt_out.i_cat == VIDEO_ES )
1364 DecoderProcessVideo( p_dec, p_block );
1366 else if( p_dec->fmt_out.i_cat == SPU_ES )
1368 DecoderProcessSpu( p_dec, p_block );
1370 else
1372 msg_Err( p_dec, "unknown ES format" );
1373 p_dec->b_error = true;
1378 static void DecoderProcessFlush( decoder_t *p_dec )
1380 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1381 decoder_t *p_packetizer = p_owner->p_packetizer;
1383 if( p_dec->b_error )
1384 return;
1386 if( p_packetizer != NULL && p_packetizer->pf_flush != NULL )
1387 p_packetizer->pf_flush( p_packetizer );
1389 if ( p_dec->pf_flush != NULL )
1390 p_dec->pf_flush( p_dec );
1392 #ifdef ENABLE_SOUT
1393 if ( p_owner->p_sout_input != NULL )
1395 sout_InputFlush( p_owner->p_sout_input );
1397 #endif
1398 if( p_dec->fmt_out.i_cat == AUDIO_ES )
1400 if( p_owner->p_aout )
1401 aout_DecFlush( p_owner->p_aout, false );
1403 else if( p_dec->fmt_out.i_cat == VIDEO_ES )
1405 if( p_owner->p_vout )
1406 vout_Flush( p_owner->p_vout, VLC_TS_INVALID+1 );
1408 else if( p_dec->fmt_out.i_cat == SPU_ES )
1410 if( p_owner->p_spu_vout )
1412 vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
1414 if( p_vout && p_owner->p_spu_vout == p_vout )
1415 vout_FlushSubpictureChannel( p_vout, p_owner->i_spu_channel );
1417 if( p_vout )
1418 vlc_object_release( p_vout );
1422 vlc_mutex_lock( &p_owner->lock );
1423 p_owner->i_preroll_end = INT64_MIN;
1424 vlc_mutex_unlock( &p_owner->lock );
1428 * The decoding main loop
1430 * \param p_dec the decoder
1432 static void *DecoderThread( void *p_data )
1434 decoder_t *p_dec = (decoder_t *)p_data;
1435 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1436 bool paused = false;
1438 /* The decoder's main loop */
1439 vlc_fifo_Lock( p_owner->p_fifo );
1440 vlc_fifo_CleanupPush( p_owner->p_fifo );
1442 for( ;; )
1444 if( p_owner->flushing )
1445 { /* Flush before/regardless of pause. We do not want to resume just
1446 * for the sake of flushing (glitches could otherwise happen). */
1447 int canc = vlc_savecancel();
1449 vlc_fifo_Unlock( p_owner->p_fifo );
1451 /* Flush the decoder (and the output) */
1452 DecoderProcessFlush( p_dec );
1454 vlc_fifo_Lock( p_owner->p_fifo );
1455 vlc_restorecancel( canc );
1457 /* Reset flushing after DecoderProcess in case input_DecoderFlush
1458 * is called again. This will avoid a second useless flush (but
1459 * harmless). */
1460 p_owner->flushing = false;
1462 continue;
1465 if( paused != p_owner->paused )
1466 { /* Update playing/paused status of the output */
1467 int canc = vlc_savecancel();
1468 mtime_t date = p_owner->pause_date;
1470 paused = p_owner->paused;
1471 vlc_fifo_Unlock( p_owner->p_fifo );
1473 /* NOTE: Only the audio and video outputs care about pause. */
1474 msg_Dbg( p_dec, "toggling %s", paused ? "resume" : "pause" );
1475 if( p_owner->p_vout != NULL )
1476 vout_ChangePause( p_owner->p_vout, paused, date );
1477 if( p_owner->p_aout != NULL )
1478 aout_DecChangePause( p_owner->p_aout, paused, date );
1480 vlc_restorecancel( canc );
1481 vlc_fifo_Lock( p_owner->p_fifo );
1482 continue;
1485 if( p_owner->paused && p_owner->frames_countdown == 0 )
1486 { /* Wait for resumption from pause */
1487 p_owner->b_idle = true;
1488 vlc_fifo_Wait( p_owner->p_fifo );
1489 p_owner->b_idle = false;
1490 continue;
1493 vlc_cond_signal( &p_owner->wait_fifo );
1494 vlc_testcancel(); /* forced expedited cancellation in case of stop */
1496 block_t *p_block = vlc_fifo_DequeueUnlocked( p_owner->p_fifo );
1497 if( p_block == NULL )
1499 if( likely(!p_owner->b_draining) )
1500 { /* Wait for a block to decode (or a request to drain) */
1501 p_owner->b_idle = true;
1502 vlc_fifo_Wait( p_owner->p_fifo );
1503 p_owner->b_idle = false;
1504 continue;
1506 /* We have emptied the FIFO and there is a pending request to
1507 * drain. Pass p_block = NULL to decoder just once. */
1508 p_owner->b_draining = false;
1511 vlc_fifo_Unlock( p_owner->p_fifo );
1513 int canc = vlc_savecancel();
1514 DecoderProcess( p_dec, p_block );
1516 if( p_block == NULL )
1517 { /* Draining: the decoder is drained and all decoded buffers are
1518 * queued to the output at this point. Now drain the output. */
1519 if( p_owner->p_aout != NULL )
1520 aout_DecFlush( p_owner->p_aout, true );
1522 vlc_restorecancel( canc );
1524 /* Given that the drained flag is only polled, an atomic variable is
1525 * sufficient. TODO? Wait for draining instead of polling. */
1526 atomic_store( &p_owner->drained, (p_block == NULL) );
1528 vlc_mutex_lock( &p_owner->lock );
1529 vlc_fifo_Lock( p_owner->p_fifo );
1530 vlc_cond_signal( &p_owner->wait_acknowledge );
1531 vlc_mutex_unlock( &p_owner->lock );
1533 vlc_cleanup_pop();
1534 vlc_assert_unreachable();
1538 * Create a decoder object
1540 * \param p_input the input thread
1541 * \param p_es the es descriptor
1542 * \param b_packetizer instead of a decoder
1543 * \return the decoder object
1545 static decoder_t * CreateDecoder( vlc_object_t *p_parent,
1546 input_thread_t *p_input,
1547 const es_format_t *fmt,
1548 input_resource_t *p_resource,
1549 sout_instance_t *p_sout )
1551 decoder_t *p_dec;
1552 decoder_owner_sys_t *p_owner;
1554 p_dec = vlc_custom_create( p_parent, sizeof( *p_dec ), "decoder" );
1555 if( p_dec == NULL )
1556 return NULL;
1558 /* Allocate our private structure for the decoder */
1559 p_dec->p_owner = p_owner = malloc( sizeof( decoder_owner_sys_t ) );
1560 if( unlikely(p_owner == NULL) )
1562 vlc_object_release( p_dec );
1563 return NULL;
1565 p_owner->i_preroll_end = INT64_MIN;
1566 p_owner->i_last_rate = INPUT_RATE_DEFAULT;
1567 p_owner->p_input = p_input;
1568 p_owner->p_resource = p_resource;
1569 p_owner->p_aout = NULL;
1570 p_owner->p_vout = NULL;
1571 p_owner->p_spu_vout = NULL;
1572 p_owner->i_spu_channel = 0;
1573 p_owner->i_spu_order = 0;
1574 p_owner->p_sout = p_sout;
1575 p_owner->p_sout_input = NULL;
1576 p_owner->p_packetizer = NULL;
1578 p_owner->b_fmt_description = false;
1579 p_owner->p_description = NULL;
1581 p_owner->paused = false;
1582 p_owner->pause_date = VLC_TS_INVALID;
1583 p_owner->frames_countdown = 0;
1585 p_owner->b_waiting = false;
1586 p_owner->b_first = true;
1587 p_owner->b_has_data = false;
1589 p_owner->flushing = false;
1590 p_owner->b_draining = false;
1591 atomic_init( &p_owner->drained, false );
1592 p_owner->b_idle = false;
1594 es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
1596 /* decoder fifo */
1597 p_owner->p_fifo = block_FifoNew();
1598 if( unlikely(p_owner->p_fifo == NULL) )
1600 free( p_owner );
1601 vlc_object_release( p_dec );
1602 return NULL;
1605 vlc_mutex_init( &p_owner->lock );
1606 vlc_cond_init( &p_owner->wait_request );
1607 vlc_cond_init( &p_owner->wait_acknowledge );
1608 vlc_cond_init( &p_owner->wait_fifo );
1609 vlc_cond_init( &p_owner->wait_timed );
1611 /* Set buffers allocation callbacks for the decoders */
1612 p_dec->pf_aout_format_update = aout_update_format;
1613 p_dec->pf_vout_format_update = vout_update_format;
1614 p_dec->pf_vout_buffer_new = vout_new_buffer;
1615 p_dec->pf_spu_buffer_new = spu_new_buffer;
1616 /* */
1617 p_dec->pf_get_attachments = DecoderGetInputAttachments;
1618 p_dec->pf_get_display_date = DecoderGetDisplayDate;
1619 p_dec->pf_get_display_rate = DecoderGetDisplayRate;
1620 p_dec->pf_queue_video = DecoderQueueVideo;
1621 p_dec->pf_queue_audio = DecoderQueueAudio;
1622 p_dec->pf_queue_sub = DecoderQueueSpu;
1624 /* Load a packetizer module if the input is not already packetized */
1625 if( p_sout == NULL && !fmt->b_packetized )
1627 p_owner->p_packetizer =
1628 vlc_custom_create( p_parent, sizeof( decoder_t ), "packetizer" );
1629 if( p_owner->p_packetizer )
1631 if( LoadDecoder( p_owner->p_packetizer, true, fmt ) )
1633 vlc_object_release( p_owner->p_packetizer );
1634 p_owner->p_packetizer = NULL;
1636 else
1638 p_owner->p_packetizer->fmt_out.b_packetized = true;
1639 fmt = &p_owner->p_packetizer->fmt_out;
1644 /* Find a suitable decoder/packetizer module */
1645 if( LoadDecoder( p_dec, p_sout != NULL, fmt ) )
1646 return p_dec;
1648 /* Copy ourself the input replay gain */
1649 if( fmt->i_cat == AUDIO_ES )
1651 for( unsigned i = 0; i < AUDIO_REPLAY_GAIN_MAX; i++ )
1653 if( !p_dec->fmt_out.audio_replay_gain.pb_peak[i] )
1655 p_dec->fmt_out.audio_replay_gain.pb_peak[i] = fmt->audio_replay_gain.pb_peak[i];
1656 p_dec->fmt_out.audio_replay_gain.pf_peak[i] = fmt->audio_replay_gain.pf_peak[i];
1658 if( !p_dec->fmt_out.audio_replay_gain.pb_gain[i] )
1660 p_dec->fmt_out.audio_replay_gain.pb_gain[i] = fmt->audio_replay_gain.pb_gain[i];
1661 p_dec->fmt_out.audio_replay_gain.pf_gain[i] = fmt->audio_replay_gain.pf_gain[i];
1666 /* */
1667 p_owner->cc.b_supported = false;
1668 if( p_sout == NULL )
1670 if( p_owner->p_packetizer && p_owner->p_packetizer->pf_get_cc )
1671 p_owner->cc.b_supported = true;
1672 if( p_dec->pf_get_cc )
1673 p_owner->cc.b_supported = true;
1676 for( unsigned i = 0; i < 4; i++ )
1678 p_owner->cc.pb_present[i] = false;
1679 p_owner->cc.pp_decoder[i] = NULL;
1681 p_owner->i_ts_delay = 0;
1682 return p_dec;
1686 * Destroys a decoder object
1688 * \param p_dec the decoder object
1689 * \return nothing
1691 static void DeleteDecoder( decoder_t * p_dec )
1693 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1695 msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %u PES in FIFO",
1696 (char*)&p_dec->fmt_in.i_codec,
1697 (unsigned)block_FifoCount( p_owner->p_fifo ) );
1699 const bool b_flush_spu = p_dec->fmt_out.i_cat == SPU_ES;
1700 UnloadDecoder( p_dec );
1702 /* Free all packets still in the decoder fifo. */
1703 block_FifoRelease( p_owner->p_fifo );
1705 /* Cleanup */
1706 if( p_owner->p_aout )
1708 /* TODO: REVISIT gap-less audio */
1709 aout_DecFlush( p_owner->p_aout, false );
1710 aout_DecDelete( p_owner->p_aout );
1711 input_resource_PutAout( p_owner->p_resource, p_owner->p_aout );
1712 if( p_owner->p_input != NULL )
1713 input_SendEventAout( p_owner->p_input );
1715 if( p_owner->p_vout )
1717 /* Hack to make sure all the the pictures are freed by the decoder
1718 * and that the vout is not paused anymore */
1719 vout_Reset( p_owner->p_vout );
1721 /* */
1722 input_resource_RequestVout( p_owner->p_resource, p_owner->p_vout, NULL,
1723 0, true );
1724 if( p_owner->p_input != NULL )
1725 input_SendEventVout( p_owner->p_input );
1728 #ifdef ENABLE_SOUT
1729 if( p_owner->p_sout_input )
1731 sout_InputDelete( p_owner->p_sout_input );
1733 #endif
1734 es_format_Clean( &p_owner->fmt );
1736 if( b_flush_spu )
1738 vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
1739 if( p_vout )
1741 if( p_owner->p_spu_vout == p_vout )
1742 vout_FlushSubpictureChannel( p_vout, p_owner->i_spu_channel );
1743 vlc_object_release( p_vout );
1747 if( p_owner->p_description )
1748 vlc_meta_Delete( p_owner->p_description );
1750 if( p_owner->p_packetizer )
1752 UnloadDecoder( p_owner->p_packetizer );
1753 vlc_object_release( p_owner->p_packetizer );
1756 vlc_cond_destroy( &p_owner->wait_timed );
1757 vlc_cond_destroy( &p_owner->wait_fifo );
1758 vlc_cond_destroy( &p_owner->wait_acknowledge );
1759 vlc_cond_destroy( &p_owner->wait_request );
1760 vlc_mutex_destroy( &p_owner->lock );
1762 vlc_object_release( p_dec );
1764 free( p_owner );
1767 /* */
1768 static void DecoderUnsupportedCodec( decoder_t *p_dec, const es_format_t *fmt )
1770 if (fmt->i_codec != VLC_FOURCC('u','n','d','f')) {
1771 const char *desc = vlc_fourcc_GetDescription(fmt->i_cat, fmt->i_codec);
1772 if (!desc || !*desc)
1773 desc = N_("No description for this codec");
1774 msg_Err( p_dec, "Codec `%4.4s' (%s) is not supported.", (char*)&fmt->i_codec, desc );
1775 dialog_Fatal( p_dec, _("Codec not supported"),
1776 _("VLC could not decode the format \"%4.4s\" (%s)"),
1777 (char*)&fmt->i_codec, desc );
1778 } else {
1779 msg_Err( p_dec, "could not identify codec" );
1780 dialog_Fatal( p_dec, _("Unidentified codec"),
1781 _("VLC could not identify the audio or video codec" ) );
1785 /* TODO: pass p_sout through p_resource? -- Courmisch */
1786 static decoder_t *decoder_New( vlc_object_t *p_parent, input_thread_t *p_input,
1787 const es_format_t *fmt, input_clock_t *p_clock,
1788 input_resource_t *p_resource,
1789 sout_instance_t *p_sout )
1791 decoder_t *p_dec = NULL;
1792 const char *psz_type = p_sout ? N_("packetizer") : N_("decoder");
1793 int i_priority;
1795 /* Create the decoder configuration structure */
1796 p_dec = CreateDecoder( p_parent, p_input, fmt, p_resource, p_sout );
1797 if( p_dec == NULL )
1799 msg_Err( p_parent, "could not create %s", psz_type );
1800 dialog_Fatal( p_parent, _("Streaming / Transcoding failed"),
1801 _("VLC could not open the %s module."),
1802 vlc_gettext( psz_type ) );
1803 return NULL;
1806 if( !p_dec->p_module )
1808 DecoderUnsupportedCodec( p_dec, fmt );
1810 DeleteDecoder( p_dec );
1811 return NULL;
1814 p_dec->p_owner->p_clock = p_clock;
1815 assert( p_dec->fmt_out.i_cat != UNKNOWN_ES );
1817 if( p_dec->fmt_out.i_cat == AUDIO_ES )
1818 i_priority = VLC_THREAD_PRIORITY_AUDIO;
1819 else
1820 i_priority = VLC_THREAD_PRIORITY_VIDEO;
1822 /* Spawn the decoder thread */
1823 if( vlc_clone( &p_dec->p_owner->thread, DecoderThread, p_dec, i_priority ) )
1825 msg_Err( p_dec, "cannot spawn decoder thread" );
1826 DeleteDecoder( p_dec );
1827 return NULL;
1830 return p_dec;
1835 * Spawns a new decoder thread from the input thread
1837 * \param p_input the input thread
1838 * \param p_es the es descriptor
1839 * \return the spawned decoder object
1841 decoder_t *input_DecoderNew( input_thread_t *p_input,
1842 es_format_t *fmt, input_clock_t *p_clock,
1843 sout_instance_t *p_sout )
1845 return decoder_New( VLC_OBJECT(p_input), p_input, fmt, p_clock,
1846 p_input->p->p_resource, p_sout );
1850 * Spawn a decoder thread outside of the input thread.
1852 decoder_t *input_DecoderCreate( vlc_object_t *p_parent, const es_format_t *fmt,
1853 input_resource_t *p_resource )
1855 return decoder_New( p_parent, NULL, fmt, NULL, p_resource, NULL );
1860 * Kills a decoder thread and waits until it's finished
1862 * \param p_input the input thread
1863 * \param p_es the es descriptor
1864 * \return nothing
1866 void input_DecoderDelete( decoder_t *p_dec )
1868 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1870 vlc_cancel( p_owner->thread );
1872 vlc_fifo_Lock( p_owner->p_fifo );
1873 /* Signal DecoderTimedWait */
1874 p_owner->flushing = true;
1875 vlc_cond_signal( &p_owner->wait_timed );
1876 vlc_fifo_Unlock( p_owner->p_fifo );
1878 /* Make sure we aren't waiting/decoding anymore */
1879 vlc_mutex_lock( &p_owner->lock );
1880 p_owner->b_waiting = false;
1881 vlc_cond_signal( &p_owner->wait_request );
1883 /* If the video output is paused or slow, or if the picture pool size was
1884 * under-estimated (e.g. greedy video filter, buggy decoder...), the
1885 * the picture pool may be empty, and the decoder thread or any decoder
1886 * module worker threads may be stuck waiting for free picture buffers.
1888 * This unblocks the thread, allowing the decoder module to join all its
1889 * worker threads (if any) and the decoder thread to terminate. */
1890 if( p_owner->p_vout != NULL )
1891 vout_Cancel( p_owner->p_vout, true );
1892 vlc_mutex_unlock( &p_owner->lock );
1894 vlc_join( p_owner->thread, NULL );
1896 /* */
1897 if( p_dec->p_owner->cc.b_supported )
1899 int i;
1900 for( i = 0; i < 4; i++ )
1901 input_DecoderSetCcState( p_dec, false, i );
1904 /* Delete decoder */
1905 DeleteDecoder( p_dec );
1909 * Put a block_t in the decoder's fifo.
1910 * Thread-safe w.r.t. the decoder. May be a cancellation point.
1912 * \param p_dec the decoder object
1913 * \param p_block the data block
1915 void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
1917 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1919 vlc_fifo_Lock( p_owner->p_fifo );
1920 if( !b_do_pace )
1922 /* FIXME: ideally we would check the time amount of data
1923 * in the FIFO instead of its size. */
1924 /* 400 MiB, i.e. ~ 50mb/s for 60s */
1925 if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )
1927 msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
1928 "consumed quickly enough), resetting fifo!" );
1929 block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
1932 else
1933 if( !p_owner->b_waiting )
1934 { /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
1935 * Locking is not necessary as b_waiting is only read, not written by
1936 * the decoder thread. */
1937 while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
1938 vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_fifo );
1941 vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
1942 vlc_fifo_Unlock( p_owner->p_fifo );
1945 bool input_DecoderIsEmpty( decoder_t * p_dec )
1947 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1949 assert( !p_owner->b_waiting );
1951 if( block_FifoCount( p_dec->p_owner->p_fifo ) > 0 )
1952 return false;
1954 bool b_empty;
1956 vlc_mutex_lock( &p_owner->lock );
1957 if( p_owner->p_sout_input != NULL )
1958 b_empty = sout_InputIsEmpty( p_owner->p_sout_input );
1959 else if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->p_vout != NULL )
1960 b_empty = vout_IsEmpty( p_owner->p_vout );
1961 else if( p_owner->fmt.i_cat == AUDIO_ES )
1962 b_empty = atomic_load( &p_owner->drained );
1963 else
1964 b_empty = true; /* TODO subtitles support */
1965 vlc_mutex_unlock( &p_owner->lock );
1967 return b_empty;
1971 * Signals that there are no further blocks to decode, and requests that the
1972 * decoder drain all pending buffers. This is used to ensure that all
1973 * intermediate buffers empty and no samples get lost at the end of the stream.
1975 * @note The function does not actually wait for draining. It just signals that
1976 * draining should be performed once the decoder has emptied FIFO.
1978 void input_DecoderDrain( decoder_t *p_dec )
1980 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1982 vlc_fifo_Lock( p_owner->p_fifo );
1983 p_owner->b_draining = true;
1984 vlc_fifo_Signal( p_owner->p_fifo );
1985 vlc_fifo_Unlock( p_owner->p_fifo );
1989 * Requests that the decoder immediately discard all pending buffers.
1990 * This is useful when seeking or when deselecting a stream.
1992 void input_DecoderFlush( decoder_t *p_dec )
1994 decoder_owner_sys_t *p_owner = p_dec->p_owner;
1996 vlc_fifo_Lock( p_owner->p_fifo );
1998 /* Empty the fifo */
1999 block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
2001 /* Don't need to wait for the DecoderThread to flush. Indeed, if called a
2002 * second time, this function will clear the FIFO again before anything was
2003 * dequeued by DecoderThread and there is no need to flush a second time in
2004 * a row. */
2005 p_owner->flushing = true;
2007 /* Flushing video decoder when paused: increment frames_countdown in order
2008 * to display one frame */
2009 if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->paused
2010 && p_owner->frames_countdown == 0 )
2011 p_owner->frames_countdown++;
2013 vlc_fifo_Signal( p_owner->p_fifo );
2014 vlc_cond_signal( &p_owner->wait_timed );
2016 vlc_fifo_Unlock( p_owner->p_fifo );
2019 void input_DecoderIsCcPresent( decoder_t *p_dec, bool pb_present[4] )
2021 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2022 int i;
2024 vlc_mutex_lock( &p_owner->lock );
2025 for( i = 0; i < 4; i++ )
2026 pb_present[i] = p_owner->cc.pb_present[i];
2027 vlc_mutex_unlock( &p_owner->lock );
2030 int input_DecoderSetCcState( decoder_t *p_dec, bool b_decode, int i_channel )
2032 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2034 //msg_Warn( p_dec, "input_DecoderSetCcState: %d @%d", b_decode, i_channel );
2036 if( i_channel < 0 || i_channel >= 4 || !p_owner->cc.pb_present[i_channel] )
2037 return VLC_EGENERIC;
2039 if( b_decode )
2041 static const vlc_fourcc_t fcc[4] = {
2042 VLC_FOURCC('c', 'c', '1', ' '),
2043 VLC_FOURCC('c', 'c', '2', ' '),
2044 VLC_FOURCC('c', 'c', '3', ' '),
2045 VLC_FOURCC('c', 'c', '4', ' '),
2047 decoder_t *p_cc;
2048 es_format_t fmt;
2050 es_format_Init( &fmt, SPU_ES, fcc[i_channel] );
2051 p_cc = input_DecoderNew( p_owner->p_input, &fmt,
2052 p_dec->p_owner->p_clock, p_owner->p_sout );
2053 if( !p_cc )
2055 msg_Err( p_dec, "could not create decoder" );
2056 dialog_Fatal( p_dec, _("Streaming / Transcoding failed"), "%s",
2057 _("VLC could not open the decoder module.") );
2058 return VLC_EGENERIC;
2060 else if( !p_cc->p_module )
2062 DecoderUnsupportedCodec( p_dec, &fmt );
2063 input_DecoderDelete(p_cc);
2064 return VLC_EGENERIC;
2066 p_cc->p_owner->p_clock = p_owner->p_clock;
2068 vlc_mutex_lock( &p_owner->lock );
2069 p_owner->cc.pp_decoder[i_channel] = p_cc;
2070 vlc_mutex_unlock( &p_owner->lock );
2072 else
2074 decoder_t *p_cc;
2076 vlc_mutex_lock( &p_owner->lock );
2077 p_cc = p_owner->cc.pp_decoder[i_channel];
2078 p_owner->cc.pp_decoder[i_channel] = NULL;
2079 vlc_mutex_unlock( &p_owner->lock );
2081 if( p_cc )
2082 input_DecoderDelete(p_cc);
2084 return VLC_SUCCESS;
2087 int input_DecoderGetCcState( decoder_t *p_dec, bool *pb_decode, int i_channel )
2089 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2091 *pb_decode = false;
2092 if( i_channel < 0 || i_channel >= 4 || !p_owner->cc.pb_present[i_channel] )
2093 return VLC_EGENERIC;
2095 vlc_mutex_lock( &p_owner->lock );
2096 *pb_decode = p_owner->cc.pp_decoder[i_channel] != NULL;
2097 vlc_mutex_unlock( &p_owner->lock );
2098 return VLC_EGENERIC;
2101 void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
2103 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2105 /* Normally, p_owner->b_paused != b_paused here. But if a track is added
2106 * while the input is paused (e.g. add sub file), then b_paused is
2107 * (incorrectly) false. FIXME: This is a bug in the decoder owner. */
2108 vlc_fifo_Lock( p_owner->p_fifo );
2109 p_owner->paused = b_paused;
2110 p_owner->pause_date = i_date;
2111 p_owner->frames_countdown = 0;
2112 vlc_fifo_Signal( p_owner->p_fifo );
2113 vlc_fifo_Unlock( p_owner->p_fifo );
2116 void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
2118 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2120 vlc_mutex_lock( &p_owner->lock );
2121 p_owner->i_ts_delay = i_delay;
2122 vlc_mutex_unlock( &p_owner->lock );
2125 void input_DecoderStartWait( decoder_t *p_dec )
2127 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2129 assert( !p_owner->b_waiting );
2131 vlc_mutex_lock( &p_owner->lock );
2132 p_owner->b_first = true;
2133 p_owner->b_has_data = false;
2134 p_owner->b_waiting = true;
2135 vlc_cond_signal( &p_owner->wait_request );
2136 vlc_mutex_unlock( &p_owner->lock );
2139 void input_DecoderStopWait( decoder_t *p_dec )
2141 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2143 assert( p_owner->b_waiting );
2145 vlc_mutex_lock( &p_owner->lock );
2146 p_owner->b_waiting = false;
2147 vlc_cond_signal( &p_owner->wait_request );
2148 vlc_mutex_unlock( &p_owner->lock );
2151 void input_DecoderWait( decoder_t *p_dec )
2153 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2155 assert( p_owner->b_waiting );
2157 vlc_mutex_lock( &p_owner->lock );
2158 while( !p_owner->b_has_data )
2160 /* Don't need to lock p_owner->paused since it's only modified by the
2161 * owner */
2162 if( p_owner->paused )
2163 break;
2164 vlc_fifo_Lock( p_owner->p_fifo );
2165 if( p_owner->b_idle && vlc_fifo_IsEmpty( p_owner->p_fifo ) )
2167 msg_Err( p_dec, "buffer deadlock prevented" );
2168 vlc_fifo_Unlock( p_owner->p_fifo );
2169 break;
2171 vlc_fifo_Unlock( p_owner->p_fifo );
2172 vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
2174 vlc_mutex_unlock( &p_owner->lock );
2177 void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration )
2179 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2181 assert( p_owner->paused );
2182 *pi_duration = 0;
2184 vlc_fifo_Lock( p_owner->p_fifo );
2185 p_owner->frames_countdown++;
2186 vlc_fifo_Signal( p_owner->p_fifo );
2187 vlc_fifo_Unlock( p_owner->p_fifo );
2189 vlc_mutex_lock( &p_owner->lock );
2190 if( p_owner->fmt.i_cat == VIDEO_ES )
2192 if( p_owner->p_vout )
2193 vout_NextPicture( p_owner->p_vout, pi_duration );
2195 vlc_mutex_unlock( &p_owner->lock );
2198 bool input_DecoderHasFormatChanged( decoder_t *p_dec, es_format_t *p_fmt, vlc_meta_t **pp_meta )
2200 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2201 bool b_changed;
2203 vlc_mutex_lock( &p_owner->lock );
2204 b_changed = p_owner->b_fmt_description;
2205 if( b_changed )
2207 if( p_fmt != NULL )
2208 es_format_Copy( p_fmt, &p_owner->fmt );
2210 if( pp_meta )
2212 *pp_meta = NULL;
2213 if( p_owner->p_description )
2215 *pp_meta = vlc_meta_New();
2216 if( *pp_meta )
2217 vlc_meta_Merge( *pp_meta, p_owner->p_description );
2220 p_owner->b_fmt_description = false;
2222 vlc_mutex_unlock( &p_owner->lock );
2223 return b_changed;
2226 size_t input_DecoderGetFifoSize( decoder_t *p_dec )
2228 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2230 return block_FifoSize( p_owner->p_fifo );
2233 void input_DecoderGetObjects( decoder_t *p_dec,
2234 vout_thread_t **pp_vout, audio_output_t **pp_aout )
2236 decoder_owner_sys_t *p_owner = p_dec->p_owner;
2238 vlc_mutex_lock( &p_owner->lock );
2239 if( pp_vout )
2240 *pp_vout = p_owner->p_vout ? vlc_object_hold( p_owner->p_vout ) : NULL;
2241 if( pp_aout )
2242 *pp_aout = p_owner->p_aout ? vlc_object_hold( p_owner->p_aout ) : NULL;
2243 vlc_mutex_unlock( &p_owner->lock );