#include "../video_output/vout_control.h"
static decoder_t *CreateDecoder( vlc_object_t *, input_thread_t *,
- es_format_t *, bool, input_resource_t *,
+ const es_format_t *, bool, input_resource_t *,
sout_instance_t *p_sout );
static void DeleteDecoder( decoder_t * );
static void *DecoderThread( void * );
static void DecoderProcess( decoder_t *, block_t * );
-static void DecoderOutputChangePause( decoder_t *, bool b_paused, mtime_t i_date );
static void DecoderFlush( decoder_t * );
-static void DecoderSignalWait( decoder_t *, bool );
+static void DecoderSignalWait( decoder_t * );
static void DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
/* Buffers allocation callbacks for the decoders */
+static int vout_update_format( decoder_t * );
static picture_t *vout_new_buffer( decoder_t * );
-static void vout_del_buffer( decoder_t *, picture_t * );
-static void vout_link_picture( decoder_t *, picture_t * );
-static void vout_unlink_picture( decoder_t *, picture_t * );
static int aout_update_format( decoder_t * );
static subpicture_t *spu_new_buffer( decoder_t *, const subpicture_updater_t * );
-static void spu_del_buffer( decoder_t *, subpicture_t * );
struct decoder_owner_sys_t
{
bool b_packetizer;
/* Current format in use by the output */
- video_format_t video;
- audio_format_t audio;
- es_format_t sout;
+ es_format_t fmt;
/* */
bool b_fmt_description;
- es_format_t fmt_description;
vlc_meta_t *p_description;
/* fifo */
vout_thread_t *p_vout;
/* -- Theses variables need locking on read *and* write -- */
- bool b_exit;
-
/* Pause */
bool b_paused;
struct
} pause;
/* Waiting */
+ bool b_woken;
bool b_waiting;
bool b_first;
bool b_has_data;
*****************************************************************************/
picture_t *decoder_NewPicture( decoder_t *p_decoder )
{
+ if( decoder_UpdateVideoFormat( p_decoder ) )
+ return NULL;
+
picture_t *p_picture = p_decoder->pf_vout_buffer_new( p_decoder );
if( !p_picture )
msg_Warn( p_decoder, "can't get output picture" );
return p_picture;
}
-void decoder_DeletePicture( decoder_t *p_decoder, picture_t *p_picture )
-{
- p_decoder->pf_vout_buffer_del( p_decoder, p_picture );
-}
-void decoder_LinkPicture( decoder_t *p_decoder, picture_t *p_picture )
-{
- p_decoder->pf_picture_link( p_decoder, p_picture );
-}
-void decoder_UnlinkPicture( decoder_t *p_decoder, picture_t *p_picture )
-{
- p_decoder->pf_picture_unlink( p_decoder, p_picture );
-}
block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples )
{
return p_subpicture;
}
-void decoder_DeleteSubpicture( decoder_t *p_decoder, subpicture_t *p_subpicture )
-{
- p_decoder->pf_spu_buffer_del( p_decoder, p_subpicture );
-}
-
/* decoder_GetInputAttachments:
*/
int decoder_GetInputAttachments( decoder_t *p_dec,
/* TODO: pass p_sout through p_resource? -- Courmisch */
static decoder_t *decoder_New( vlc_object_t *p_parent, input_thread_t *p_input,
- es_format_t *fmt, input_clock_t *p_clock,
+ const es_format_t *fmt, input_clock_t *p_clock,
input_resource_t *p_resource,
sout_instance_t *p_sout )
{
/**
* Spawn a decoder thread outside of the input thread.
*/
-decoder_t *input_DecoderCreate( vlc_object_t *p_parent, es_format_t *fmt,
+decoder_t *input_DecoderCreate( vlc_object_t *p_parent, const es_format_t *fmt,
input_resource_t *p_resource )
{
return decoder_New( p_parent, NULL, fmt, NULL, p_resource, NULL );
/* Make sure we aren't paused/waiting/decoding anymore */
vlc_mutex_lock( &p_owner->lock );
- const bool b_was_paused = p_owner->b_paused;
p_owner->b_paused = false;
p_owner->b_waiting = false;
p_owner->b_flushing = true;
- p_owner->b_exit = true;
vlc_cond_signal( &p_owner->wait_request );
vlc_mutex_unlock( &p_owner->lock );
vlc_join( p_owner->thread, NULL );
- p_owner->b_paused = b_was_paused;
module_unneed( p_dec, p_dec->p_module );
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- if( b_do_pace )
- {
- /* The fifo is not consumed when waiting and so will
- * deadlock vlc.
- * There is no need to lock as b_waiting is never modified
- * inside decoder thread. */
- if( !p_owner->b_waiting )
- block_FifoPace( p_owner->p_fifo, 10, SIZE_MAX );
- }
-#ifdef __arm__
- else if( block_FifoSize( p_owner->p_fifo ) > 50*1024*1024 /* 50 MiB */ )
-#else
- else if( block_FifoSize( p_owner->p_fifo ) > 400*1024*1024 /* 400 MiB, ie ~ 50mb/s for 60s */ )
-#endif
+ vlc_fifo_Lock( p_owner->p_fifo );
+ if( !b_do_pace )
{
/* FIXME: ideally we would check the time amount of data
* in the FIFO instead of its size. */
- msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
- "consumed quickly enough), resetting fifo!" );
- block_FifoEmpty( p_owner->p_fifo );
+ /* 400 MiB, i.e. ~ 50mb/s for 60s */
+ if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )
+ {
+ msg_Warn( p_dec, "decoder/packetizer fifo full (data not "
+ "consumed quickly enough), resetting fifo!" );
+ block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );
+ }
+ }
+ else
+ if( !p_owner->b_waiting )
+ { /* The FIFO is not consumed when waiting, so pacing would deadlock VLC.
+ * Locking is not necessary as b_waiting is only read, not written by
+ * the decoder thread. */
+ while( vlc_fifo_GetCount( p_owner->p_fifo ) >= 10 )
+ vlc_fifo_WaitCond( p_owner->p_fifo, &p_owner->wait_acknowledge );
}
- block_FifoPut( p_owner->p_fifo, p_block );
+ vlc_fifo_QueueUnlocked( p_owner->p_fifo, p_block );
+ vlc_fifo_Unlock( p_owner->p_fifo );
}
bool input_DecoderIsEmpty( decoder_t * p_dec )
{
vlc_mutex_lock( &p_owner->lock );
/* TODO subtitles support */
- if( p_dec->fmt_out.i_cat == VIDEO_ES && p_owner->p_vout )
+ if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->p_vout )
b_empty = vout_IsEmpty( p_owner->p_vout );
- else if( p_dec->fmt_out.i_cat == AUDIO_ES && p_owner->p_aout )
+ else if( p_owner->fmt.i_cat == AUDIO_ES && p_owner->p_aout )
b_empty = aout_DecIsEmpty( p_owner->p_aout );
vlc_mutex_unlock( &p_owner->lock );
}
p_owner->pause.i_ignore = 0;
vlc_cond_signal( &p_owner->wait_request );
- DecoderOutputChangePause( p_dec, b_paused, i_date );
+ /* XXX only audio and video output have to be paused.
+ * - for sout it is useless
+ * - for subs, it is done by the vout
+ */
+ if( p_owner->fmt.i_cat == AUDIO_ES )
+ {
+ if( p_owner->p_aout )
+ aout_DecChangePause( p_owner->p_aout, b_paused, i_date );
+ }
+ else if( p_owner->fmt.i_cat == VIDEO_ES )
+ {
+ if( p_owner->p_vout )
+ vout_ChangePause( p_owner->p_vout, b_paused, i_date );
+ }
}
vlc_mutex_unlock( &p_owner->lock );
}
vlc_mutex_unlock( &p_owner->lock );
}
-void input_DecoderStartWait( decoder_t *p_dec )
+/**
+ * Requests that the decoder immediately discard all pending buffers.
+ * This is useful at end of stream, when seeking or when deselecting a stream.
+ */
+void input_DecoderFlush( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
vlc_mutex_lock( &p_owner->lock );
-
DecoderFlush( p_dec );
+ vlc_mutex_unlock( &p_owner->lock );
+}
+
+void input_DecoderStartWait( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+
+ assert( !p_owner->b_waiting );
+ vlc_mutex_lock( &p_owner->lock );
p_owner->b_first = true;
p_owner->b_has_data = false;
-
p_owner->b_waiting = true;
-
vlc_cond_signal( &p_owner->wait_request );
-
vlc_mutex_unlock( &p_owner->lock );
}
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- vlc_mutex_lock( &p_owner->lock );
+ assert( p_owner->b_waiting );
+ vlc_mutex_lock( &p_owner->lock );
p_owner->b_waiting = false;
-
vlc_cond_signal( &p_owner->wait_request );
-
vlc_mutex_unlock( &p_owner->lock );
}
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- vlc_mutex_lock( &p_owner->lock );
+ assert( p_owner->b_waiting );
- while( p_owner->b_waiting && !p_owner->b_has_data )
+ vlc_mutex_lock( &p_owner->lock );
+ while( !p_owner->b_has_data )
{
- block_FifoWake( p_owner->p_fifo );
+ vlc_fifo_Lock( p_owner->p_fifo );
+ p_owner->b_woken = true;
+ vlc_fifo_Signal( p_owner->p_fifo );
+ vlc_fifo_Unlock( p_owner->p_fifo );
vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
}
-
vlc_mutex_unlock( &p_owner->lock );
}
*pi_duration = 0;
vlc_mutex_lock( &p_owner->lock );
- if( p_dec->fmt_out.i_cat == VIDEO_ES )
+ if( p_owner->fmt.i_cat == VIDEO_ES )
{
if( p_owner->b_paused && p_owner->p_vout )
{
else
{
/* TODO subtitle should not be flushed */
+ p_owner->b_waiting = false;
DecoderFlush( p_dec );
}
vlc_mutex_unlock( &p_owner->lock );
b_changed = p_owner->b_fmt_description;
if( b_changed )
{
- if( p_fmt )
- es_format_Copy( p_fmt, &p_owner->fmt_description );
+ if( p_fmt != NULL )
+ es_format_Copy( p_fmt, &p_owner->fmt );
if( pp_meta )
{
if( !p_owner->p_clock || i_ts <= VLC_TS_INVALID )
return i_ts;
- if( input_clock_ConvertTS( p_owner->p_clock, NULL, &i_ts, NULL, INT64_MAX ) ) {
+ if( input_clock_ConvertTS( VLC_OBJECT(p_dec), p_owner->p_clock, NULL, &i_ts, NULL, INT64_MAX ) ) {
msg_Err(p_dec, "Could not get display date for timestamp %"PRId64"", i_ts);
return VLC_TS_INVALID;
}
*/
static decoder_t * CreateDecoder( vlc_object_t *p_parent,
input_thread_t *p_input,
- es_format_t *fmt, bool b_packetizer,
+ const es_format_t *fmt, bool b_packetizer,
input_resource_t *p_resource,
sout_instance_t *p_sout )
{
p_owner->p_sout_input = NULL;
p_owner->p_packetizer = NULL;
p_owner->b_packetizer = b_packetizer;
+ es_format_Init( &p_owner->fmt, UNKNOWN_ES, 0 );
/* decoder fifo */
+ p_owner->b_woken = false;
p_owner->p_fifo = block_FifoNew();
if( unlikely(p_owner->p_fifo == NULL) )
{
/* Set buffers allocation callbacks for the decoders */
p_dec->pf_aout_format_update = aout_update_format;
+ p_dec->pf_vout_format_update = vout_update_format;
p_dec->pf_vout_buffer_new = vout_new_buffer;
- p_dec->pf_vout_buffer_del = vout_del_buffer;
- p_dec->pf_picture_link = vout_link_picture;
- p_dec->pf_picture_unlink = vout_unlink_picture;
p_dec->pf_spu_buffer_new = spu_new_buffer;
- p_dec->pf_spu_buffer_del = spu_del_buffer;
/* */
p_dec->pf_get_attachments = DecoderGetInputAttachments;
p_dec->pf_get_display_date = DecoderGetDisplayDate;
{
es_format_Clean( &p_owner->p_packetizer->fmt_in );
vlc_object_release( p_owner->p_packetizer );
+ p_owner->p_packetizer = NULL;
}
}
}
vlc_cond_init( &p_owner->wait_acknowledge );
p_owner->b_fmt_description = false;
- es_format_Init( &p_owner->fmt_description, UNKNOWN_ES, 0 );
p_owner->p_description = NULL;
- p_owner->b_exit = false;
-
p_owner->b_paused = false;
p_owner->pause.i_date = VLC_TS_INVALID;
p_owner->pause.i_ignore = 0;
/* The decoder's main loop */
for( ;; )
{
- block_t *p_block = block_FifoGet( p_owner->p_fifo );
+ block_t *p_block;
- /* Make sure there is no cancellation point other than this one^^.
- * If you need one, be sure to push cleanup of p_block. */
- bool end_wait = !p_block || p_block->i_flags & BLOCK_FLAG_CORE_EOS;
- DecoderSignalWait( p_dec, end_wait );
- if (end_wait)
- input_DecoderStopWait( p_dec );
+ vlc_fifo_Lock( p_owner->p_fifo );
+ vlc_fifo_CleanupPush( p_owner->p_fifo );
+
+ while( vlc_fifo_IsEmpty( p_owner->p_fifo ) )
+ {
+ if( p_owner->b_woken )
+ break;
+ vlc_fifo_Wait( p_owner->p_fifo );
+ /* Make sure there is no cancellation point other than this one^^.
+ * If you need one, be sure to push cleanup of p_block. */
+ }
+
+ p_block = vlc_fifo_DequeueUnlocked( p_owner->p_fifo );
+ if( p_block != NULL )
+ vlc_cond_signal( &p_owner->wait_acknowledge );
+
+ p_owner->b_woken = false;
+ vlc_cleanup_run();
+
+ if( p_block == NULL || p_block->i_flags & BLOCK_FLAG_CORE_EOS )
+ DecoderSignalWait( p_dec );
if( p_block )
{
vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
}
-static void DecoderSignalWait( decoder_t *p_dec, bool b_has_data )
+static void DecoderSignalWait( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
if( p_owner->b_waiting )
{
- if( b_has_data )
- p_owner->b_has_data = true;
+ p_owner->b_has_data = true;
vlc_cond_signal( &p_owner->wait_acknowledge );
}
return p_owner->b_flushing;
}
-static void DecoderOutputChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_assert_locked( &p_owner->lock );
-
- /* XXX only audio and video output have to be paused.
- * - for sout it is useless
- * - for subs, it is done by the vout
- */
- if( p_dec->fmt_out.i_cat == AUDIO_ES )
- {
- if( p_owner->p_aout )
- aout_DecChangePause( p_owner->p_aout, b_paused, i_date );
- }
- else if( p_dec->fmt_out.i_cat == VIDEO_ES )
- {
- if( p_owner->p_vout )
- vout_ChangePause( p_owner->p_vout, b_paused, i_date );
- }
-}
static inline void DecoderUpdatePreroll( int64_t *pi_preroll, const block_t *p )
{
if( p->i_flags & (BLOCK_FLAG_PREROLL|BLOCK_FLAG_DISCONTINUITY) )
*pi_ts0 += i_es_delay;
if( pi_ts1 && *pi_ts1 > VLC_TS_INVALID )
*pi_ts1 += i_es_delay;
- if( input_clock_ConvertTS( p_clock, &i_rate, pi_ts0, pi_ts1, i_ts_bound ) ) {
- msg_Err(p_dec, "Could not convert timestamps %"PRId64", %"PRId64"", pi_ts0, pi_ts1);
+ if( input_clock_ConvertTS( VLC_OBJECT(p_dec), p_clock, &i_rate, pi_ts0, pi_ts1, i_ts_bound ) ) {
+ if( pi_ts1 != NULL )
+ msg_Err(p_dec, "Could not convert timestamps %"PRId64
+ ", %"PRId64"", *pi_ts0, *pi_ts1);
+ else
+ msg_Err(p_dec, "Could not convert timestamp %"PRId64, *pi_ts0);
*pi_ts0 = VLC_TS_INVALID;
}
}
*pi_rate = i_rate;
}
-static bool DecoderIsExitRequested( decoder_t *p_dec )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
- vlc_mutex_lock( &p_owner->lock );
- bool b_exit = p_owner->b_exit;
- vlc_mutex_unlock( &p_owner->lock );
-
- return b_exit;
-}
-
/**
* If *pb_reject, it does nothing, otherwise it waits for the given
* deadline or a flush request (in which case it set *pi_reject to true.
do
{
- if( p_owner->b_flushing || p_owner->b_exit )
+ if( p_owner->b_flushing )
{
*pb_reject = true;
break;
}
else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
{
- if( DecoderIsExitRequested( p_dec ) )
+ if( DecoderIsFlushing( p_dec ) )
{
/* It prevent freezing VLC in case of broken decoder */
block_Release( p_aout_buf );
{
msg_Warn( p_dec, "non-dated video buffer received" );
*pi_lost_sum += 1;
- vout_ReleasePicture( p_vout, p_picture );
+ picture_Release( p_picture );
return;
}
msg_Warn( p_dec, "non-dated video buffer received" );
*pi_lost_sum += 1;
- vout_ReleasePicture( p_vout, p_picture );
+ picture_Release( p_picture );
}
int i_tmp_display;
int i_tmp_lost;
while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )
{
vout_thread_t *p_vout = p_owner->p_vout;
- if( DecoderIsExitRequested( p_dec ) )
- {
- /* It prevent freezing VLC in case of broken decoder */
- vout_ReleasePicture( p_vout, p_pic );
+ if( DecoderIsFlushing( p_dec ) )
+ { /* It prevent freezing VLC in case of broken decoder */
+ picture_Release( p_pic );
if( p_block )
block_Release( p_block );
break;
if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end )
{
- vout_ReleasePicture( p_vout, p_pic );
+ picture_Release( p_pic );
continue;
}
while( ( p_sout_block =
p_dec->pf_packetize( p_dec, p_block ? &p_block : NULL ) ) )
{
- if( !p_owner->p_sout_input )
+ if( p_owner->p_sout_input == NULL )
{
- es_format_Copy( &p_owner->sout, &p_dec->fmt_out );
+ assert( !p_owner->b_fmt_description ); // no need for owner lock
+ es_format_Clean( &p_owner->fmt );
+ es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
- p_owner->sout.i_group = p_dec->fmt_in.i_group;
- p_owner->sout.i_id = p_dec->fmt_in.i_id;
+ p_owner->fmt.i_group = p_dec->fmt_in.i_group;
+ p_owner->fmt.i_id = p_dec->fmt_in.i_id;
if( p_dec->fmt_in.psz_language )
{
- free( p_owner->sout.psz_language );
- p_owner->sout.psz_language =
+ free( p_owner->fmt.psz_language );
+ p_owner->fmt.psz_language =
strdup( p_dec->fmt_in.psz_language );
}
p_owner->p_sout_input =
- sout_InputNew( p_owner->p_sout,
- &p_owner->sout );
+ sout_InputNew( p_owner->p_sout, &p_owner->fmt );
if( p_owner->p_sout_input == NULL )
{
msg_Err( p_dec, "cannot create packetizer output (%4.4s)",
- (char *)&p_owner->sout.i_codec );
+ (char *)&p_owner->fmt.i_codec );
p_dec->b_error = true;
block_ChainRelease(p_sout_block);
(unsigned)block_FifoCount( p_owner->p_fifo ) );
/* Free all packets still in the decoder fifo. */
- block_FifoEmpty( p_owner->p_fifo );
block_FifoRelease( p_owner->p_fifo );
/* Cleanup */
if( p_owner->p_sout_input )
{
sout_InputDelete( p_owner->p_sout_input );
- es_format_Clean( &p_owner->sout );
}
#endif
+ es_format_Clean( &p_owner->fmt );
if( p_dec->fmt_out.i_cat == SPU_ES )
{
es_format_Clean( &p_dec->fmt_out );
if( p_dec->p_description )
vlc_meta_Delete( p_dec->p_description );
- es_format_Clean( &p_owner->fmt_description );
if( p_owner->p_description )
vlc_meta_Delete( p_owner->p_description );
p_owner->b_fmt_description = true;
- /* Copy es_format */
- es_format_Clean( &p_owner->fmt_description );
- es_format_Copy( &p_owner->fmt_description, &p_dec->fmt_out );
-
/* Move p_description */
if( p_owner->p_description && p_dec->p_description )
vlc_meta_Delete( p_owner->p_description );
decoder_owner_sys_t *p_owner = p_dec->p_owner;
if( p_owner->p_aout
- && !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->audio) )
+ && !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) )
{
audio_output_t *p_aout = p_owner->p_aout;
if( p_owner->p_aout == NULL )
{
- const int i_force_dolby = var_InheritInteger( p_dec, "force-dolby-surround" );
- audio_sample_format_t format;
- audio_output_t *p_aout;
- aout_request_vout_t request_vout;
-
p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
- p_owner->audio = p_dec->fmt_out.audio;
- aout_FormatPrepare( &p_owner->audio );
- memcpy( &format, &p_owner->audio, sizeof( audio_sample_format_t ) );
+ audio_sample_format_t format = p_dec->fmt_out.audio;
+ aout_FormatPrepare( &format );
+
+ const int i_force_dolby = var_InheritInteger( p_dec, "force-dolby-surround" );
if( i_force_dolby &&
(format.i_original_channels&AOUT_CHAN_PHYSMASK) ==
(AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )
}
}
- request_vout.pf_request_vout = aout_request_vout;
- request_vout.p_private = p_dec;
+ aout_request_vout_t request_vout = {
+ .pf_request_vout = aout_request_vout,
+ .p_private = p_dec,
+ };
+ audio_output_t *p_aout;
- assert( p_owner->p_aout == NULL );
p_aout = input_resource_GetAout( p_owner->p_resource );
if( p_aout )
{
vlc_mutex_lock( &p_owner->lock );
p_owner->p_aout = p_aout;
+
+ es_format_Clean( &p_owner->fmt );
+ es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
+ aout_FormatPrepare( &p_owner->fmt.audio );
+
DecoderUpdateFormatLocked( p_dec );
- if( unlikely(p_owner->b_paused) ) /* fake pause if needed */
+
+ if( unlikely(p_owner->b_paused) && p_aout != NULL )
+ /* fake pause if needed */
aout_DecChangePause( p_aout, true, mdate() );
vlc_mutex_unlock( &p_owner->lock );
}
p_dec->fmt_out.audio.i_bytes_per_frame =
- p_owner->audio.i_bytes_per_frame;
- p_dec->fmt_out.audio.i_frame_length = p_owner->audio.i_frame_length;
+ p_owner->fmt.audio.i_bytes_per_frame;
+ p_dec->fmt_out.audio.i_frame_length =
+ p_owner->fmt.audio.i_frame_length;
}
return 0;
}
-static picture_t *vout_new_buffer( decoder_t *p_dec )
+static int vout_update_format( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
- if( p_owner->p_vout == NULL ||
- p_dec->fmt_out.video.i_width != p_owner->video.i_width ||
- p_dec->fmt_out.video.i_height != p_owner->video.i_height ||
- p_dec->fmt_out.video.i_visible_width != p_owner->video.i_visible_width ||
- p_dec->fmt_out.video.i_visible_height != p_owner->video.i_visible_height ||
- p_dec->fmt_out.video.i_x_offset != p_owner->video.i_x_offset ||
- p_dec->fmt_out.video.i_y_offset != p_owner->video.i_y_offset ||
- p_dec->fmt_out.i_codec != p_owner->video.i_chroma ||
- (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->video.i_sar_den !=
- (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->video.i_sar_num ||
- p_dec->fmt_out.video.orientation != p_owner->video.orientation )
+ if( p_owner->p_vout == NULL
+ || p_dec->fmt_out.video.i_width != p_owner->fmt.video.i_width
+ || p_dec->fmt_out.video.i_height != p_owner->fmt.video.i_height
+ || p_dec->fmt_out.video.i_visible_width != p_owner->fmt.video.i_visible_width
+ || p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
+ || p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
+ || p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset
+ || p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma
+ || (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
+ (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num ||
+ p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation )
{
vout_thread_t *p_vout;
!p_dec->fmt_out.video.i_height )
{
/* Can't create a new vout without display size */
- return NULL;
+ return -1;
}
video_format_t fmt = p_dec->fmt_out.video;
fmt.i_chroma = p_dec->fmt_out.i_codec;
- p_owner->video = fmt;
if( vlc_fourcc_IsYUV( fmt.i_chroma ) )
{
vlc_mutex_lock( &p_owner->lock );
p_owner->p_vout = p_vout;
+ es_format_Clean( &p_owner->fmt );
+ es_format_Copy( &p_owner->fmt, &p_dec->fmt_out );
+ p_owner->fmt.video.i_chroma = p_dec->fmt_out.i_codec;
+
DecoderUpdateFormatLocked( p_dec );
vlc_mutex_unlock( &p_owner->lock );
{
msg_Err( p_dec, "failed to create video output" );
p_dec->b_error = true;
- return NULL;
+ return -1;
}
}
+ return 0;
+}
+
+static picture_t *vout_new_buffer( decoder_t *p_dec )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
- /* Get a new picture
- */
for( ;; )
{
- if( DecoderIsExitRequested( p_dec ) || p_dec->b_error )
+ if( DecoderIsFlushing( p_dec ) || p_dec->b_error )
return NULL;
picture_t *p_picture = vout_GetPicture( p_owner->p_vout );
if( p_picture )
return p_picture;
- if( DecoderIsFlushing( p_dec ) )
- return NULL;
-
/* */
- DecoderSignalWait( p_dec, true );
+ DecoderSignalWait( p_dec );
/* Check the decoder doesn't leak pictures */
vout_FixLeaks( p_owner->p_vout );
}
}
-static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
-{
- vout_ReleasePicture( p_dec->p_owner->p_vout, p_pic );
-}
-
-static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic )
-{
- vout_HoldPicture( p_dec->p_owner->p_vout, p_pic );
-}
-
-static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic )
-{
- vout_ReleasePicture( p_dec->p_owner->p_vout, p_pic );
-}
-
static subpicture_t *spu_new_buffer( decoder_t *p_dec,
const subpicture_updater_t *p_updater )
{
while( i_attempts-- )
{
- if( DecoderIsExitRequested( p_dec ) || p_dec->b_error )
+ if( DecoderIsFlushing( p_dec ) || p_dec->b_error )
break;
p_vout = input_resource_HoldVout( p_owner->p_resource );
return p_subpic;
}
-
-static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic )
-{
- decoder_owner_sys_t *p_owner = p_dec->p_owner;
- vout_thread_t *p_vout = NULL;
-
- p_vout = input_resource_HoldVout( p_owner->p_resource );
- if( !p_vout || p_owner->p_spu_vout != p_vout )
- {
- if( p_vout )
- vlc_object_release( p_vout );
- msg_Warn( p_dec, "no vout found, leaking subpicture" );
- return;
- }
-
- subpicture_Delete( p_subpic );
-
- vlc_object_release( p_vout );
-}