static void vout_link_picture( decoder_t *, picture_t * );
static void vout_unlink_picture( decoder_t *, picture_t * );
-static subpicture_t *spu_new_buffer( 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
p_decoder->pf_aout_buffer_del( p_decoder, p_buffer );
}
-subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder )
+subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
+ const subpicture_updater_t *p_dyn )
{
- subpicture_t *p_subpicture = p_decoder->pf_spu_buffer_new( p_decoder );
+ subpicture_t *p_subpicture = p_decoder->pf_spu_buffer_new( p_decoder, p_dyn );
if( !p_subpicture )
msg_Warn( p_decoder, "can't get output subpicture" );
return p_subpicture;
}
+
void decoder_DeleteSubpicture( decoder_t *p_decoder, subpicture_t *p_subpicture )
{
p_decoder->pf_spu_buffer_del( p_decoder, p_subpicture );
block_FifoPace( p_owner->p_fifo, 10, SIZE_MAX );
}
#ifdef __arm__
- else if( block_FifoSize( p_owner->p_fifo ) > 50000000 /* 50 MB */ )
+ else if( block_FifoSize( p_owner->p_fifo ) > 50*1024*1024 /* 50 MiB */ )
#else
- else if( block_FifoSize( p_owner->p_fifo ) > 400000000 /* 400 MB, ie ~ 50mb/s for 60s */ )
+ else if( block_FifoSize( p_owner->p_fifo ) > 400*1024*1024 /* 400 MiB, ie ~ 50mb/s for 60s */ )
#endif
{
/* FIXME: ideally we would check the time amount of data
bool input_DecoderIsEmpty( decoder_t * p_dec )
{
- assert( !p_dec->p_owner->b_buffering );
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ assert( !p_owner->b_buffering );
- /* FIXME that's not really true */
- return block_FifoCount( p_dec->p_owner->p_fifo ) <= 0;
+ bool b_empty = block_FifoCount( p_dec->p_owner->p_fifo ) <= 0;
+ if( b_empty )
+ {
+ vlc_mutex_lock( &p_owner->lock );
+ /* TODO audio support */
+ if( p_dec->fmt_out.i_cat == VIDEO_ES && p_owner->p_vout )
+ b_empty = vout_IsEmpty( p_owner->p_vout );
+ vlc_mutex_unlock( &p_owner->lock );
+ }
+ return b_empty;
}
void input_DecoderIsCcPresent( decoder_t *p_dec, bool pb_present[4] )
vlc_mutex_lock( &p_owner->lock );
if( pp_vout )
- *pp_vout = vlc_object_hold( p_owner->p_vout );
+ *pp_vout = p_owner->p_vout ? vlc_object_hold( p_owner->p_vout ) : NULL;
if( pp_aout )
- *pp_aout = vlc_object_hold( p_owner->p_aout );
+ *pp_aout = p_owner->p_aout ? vlc_object_hold( p_owner->p_aout ) : NULL;
vlc_mutex_unlock( &p_owner->lock );
}
{
msg_Warn( p_vout, "non-dated video buffer received" );
*pi_lost_sum += 1;
- vout_DropPicture( p_vout, p_picture );
+ vout_ReleasePicture( p_vout, p_picture );
return;
}
vout_Flush( p_vout, p_picture->date );
p_owner->i_last_rate = i_rate;
}
- vout_DisplayPicture( p_vout, p_picture );
+ vout_PutPicture( p_vout, p_picture );
}
else
{
msg_Warn( p_vout, "non-dated video buffer received" );
*pi_lost_sum += 1;
- vout_DropPicture( p_vout, p_picture );
+ vout_ReleasePicture( p_vout, p_picture );
}
int i_tmp_display;
int i_tmp_lost;
if( p_dec->b_die )
{
/* It prevent freezing VLC in case of broken decoder */
- vout_DropPicture( p_vout, p_pic );
+ vout_ReleasePicture( p_vout, 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_DropPicture( p_vout, p_pic );
+ vout_ReleasePicture( p_vout, p_pic );
continue;
}
vout_thread_t *p_vout = p_owner->p_spu_vout;
/* */
- if( p_subpic->i_start <= VLC_TS_INVALID )
+ if( p_subpic->i_start <= VLC_TS_INVALID && !b_telx )
{
msg_Warn( p_dec, "non-dated spu buffer received" );
subpicture_Delete( p_subpic );
p_owner->buffer.i_count--;
if( p_owner->p_vout )
- vout_DropPicture( p_owner->p_vout, p_picture );
+ {
+ vout_ReleasePicture( p_owner->p_vout, p_picture );
+ }
if( !p_owner->buffer.p_picture )
p_owner->buffer.pp_picture_next = &p_owner->buffer.p_picture;
{
/* Hack to make sure all the the pictures are freed by the decoder
* and that the vout is not paused anymore */
- vout_FixLeaks( p_owner->p_vout, true );
- if( p_owner->b_paused )
- vout_ChangePause( p_owner->p_vout, false, mdate() );
+ vout_Reset( p_owner->p_vout );
/* */
input_resource_RequestVout( p_owner->p_input->p->p_resource, p_owner->p_vout, NULL, true );
p_owner->p_aout_input, p_buffer );
}
-
-int vout_CountPictureAvailable( vout_thread_t *p_vout );
-
static picture_t *vout_new_buffer( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
p_dec->b_error = true;
return NULL;
}
-
- if( p_owner->video.i_rmask )
- p_owner->p_vout->render.i_rmask = p_owner->video.i_rmask;
- if( p_owner->video.i_gmask )
- p_owner->p_vout->render.i_gmask = p_owner->video.i_gmask;
- if( p_owner->video.i_bmask )
- p_owner->p_vout->render.i_bmask = p_owner->video.i_bmask;
}
/* Get a new picture
*/
for( ;; )
{
- picture_t *p_picture;
-
if( p_dec->b_die || p_dec->b_error )
return NULL;
- /* The video filter chain required that there is always 1 free buffer
- * that it will use as temporary one. It will release the temporary
- * buffer once its work is done, so this check is safe even if we don't
- * lock around both count() and create().
- */
- if( vout_CountPictureAvailable( p_owner->p_vout ) >= 2 )
- {
- p_picture = vout_CreatePicture( p_owner->p_vout, 0, 0, 0 );
- if( p_picture )
- return p_picture;
- }
+ picture_t *p_picture = vout_GetPicture( p_owner->p_vout );
+ if( p_picture )
+ return p_picture;
if( DecoderIsFlushing( p_dec ) )
return NULL;
DecoderSignalBuffering( p_dec, true );
/* Check the decoder doesn't leak pictures */
- vout_FixLeaks( p_owner->p_vout, false );
+ vout_FixLeaks( p_owner->p_vout );
/* FIXME add a vout_WaitPictureAvailable (timedwait) */
msleep( VOUT_OUTMEM_SLEEP );
static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
{
- vout_DropPicture( p_dec->p_owner->p_vout, 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_LinkPicture( p_dec->p_owner->p_vout, 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_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );
+ vout_ReleasePicture( p_dec->p_owner->p_vout, p_pic );
}
-static subpicture_t *spu_new_buffer( decoder_t *p_dec )
+static subpicture_t *spu_new_buffer( decoder_t *p_dec,
+ const subpicture_updater_t *p_updater )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
vout_thread_t *p_vout = NULL;
p_owner->p_spu_vout = p_vout;
}
- p_subpic = subpicture_New();
+ p_subpic = subpicture_New( p_updater );
if( p_subpic )
{
p_subpic->i_channel = p_owner->i_spu_channel;