Commit 7290c2d3 authored by Laurent Aimar's avatar Laurent Aimar Committed by Derk-Jan Hartman

Workaround libmpeg2 DPB bugs (#2883).

It should work as the vout never deletes the pictures used by a decoder.
(cherry picked from commit a3d9fc2e)
Signed-off-by: default avatarDerk-Jan Hartman <hartman@videolan.org>
parent a54f7169
...@@ -111,12 +111,14 @@ static void PutPicture( decoder_t *, picture_t * ); ...@@ -111,12 +111,14 @@ static void PutPicture( decoder_t *, picture_t * );
static void GetAR( decoder_t *p_dec ); static void GetAR( decoder_t *p_dec );
static void Reset( decoder_t *p_dec );
/* */ /* */
static void DpbInit( decoder_t * ); static void DpbInit( decoder_t * );
static void DpbClean( decoder_t * ); static void DpbClean( decoder_t * );
static picture_t *DpbNewPicture( decoder_t * ); static picture_t *DpbNewPicture( decoder_t * );
static void DpbUnlinkPicture( decoder_t *, picture_t * ); static void DpbUnlinkPicture( decoder_t *, picture_t * );
static void DpbDisplayPicture( decoder_t *, picture_t * ); static int DpbDisplayPicture( decoder_t *, picture_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -244,11 +246,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -244,11 +246,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_block = *pp_block; p_block = *pp_block;
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) ) if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
{ Reset( p_dec );
cc_Flush( &p_sys->cc );
mpeg2_reset( p_sys->p_mpeg2dec, p_sys->p_info->sequence != NULL );
DpbClean( p_dec );
}
while( 1 ) while( 1 )
{ {
...@@ -383,7 +381,15 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -383,7 +381,15 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_pic = NULL; p_pic = NULL;
if( !b_skip ) if( !b_skip )
{
p_pic = DpbNewPicture( p_dec ); p_pic = DpbNewPicture( p_dec );
if( !p_pic )
{
Reset( p_dec );
block_Release( p_block );
return NULL;
}
}
if( b_skip || !p_pic ) if( b_skip || !p_pic )
{ {
...@@ -518,17 +524,21 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -518,17 +524,21 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->p_info->display_fbuf->id ) p_sys->p_info->display_fbuf->id )
{ {
p_pic = p_sys->p_info->display_fbuf->id; p_pic = p_sys->p_info->display_fbuf->id;
DpbDisplayPicture( p_dec, p_pic ); if( DpbDisplayPicture( p_dec, p_pic ) )
p_pic = NULL;
decoder_SynchroEnd( p_sys->p_synchro, decoder_SynchroEnd( p_sys->p_synchro,
p_sys->p_info->display_picture->flags & PIC_MASK_CODING_TYPE, p_sys->p_info->display_picture->flags & PIC_MASK_CODING_TYPE,
p_sys->b_garbage_pic ); p_sys->b_garbage_pic );
if( p_pic )
{
p_pic->date = decoder_SynchroDate( p_sys->p_synchro ); p_pic->date = decoder_SynchroDate( p_sys->p_synchro );
if( p_sys->b_garbage_pic ) if( p_sys->b_garbage_pic )
p_pic->date = 0; /* ??? */ p_pic->date = 0; /* ??? */
p_sys->b_garbage_pic = false; p_sys->b_garbage_pic = false;
} }
}
if( p_sys->p_info->discard_fbuf && if( p_sys->p_info->discard_fbuf &&
p_sys->p_info->discard_fbuf->id ) p_sys->p_info->discard_fbuf->id )
...@@ -587,6 +597,18 @@ static void CloseDecoder( vlc_object_t *p_this ) ...@@ -587,6 +597,18 @@ static void CloseDecoder( vlc_object_t *p_this )
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* Reset: reset the decoder state
*****************************************************************************/
static void Reset( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
cc_Flush( &p_sys->cc );
mpeg2_reset( p_sys->p_mpeg2dec, p_sys->p_info->sequence != NULL );
DpbClean( p_dec );
}
/***************************************************************************** /*****************************************************************************
* GetNewPicture: Get a new picture from the vout and set the buf struct * GetNewPicture: Get a new picture from the vout and set the buf struct
*****************************************************************************/ *****************************************************************************/
...@@ -813,6 +835,14 @@ static picture_dpb_t *DpbFindPicture( decoder_t *p_dec, picture_t *p_picture ) ...@@ -813,6 +835,14 @@ static picture_dpb_t *DpbFindPicture( decoder_t *p_dec, picture_t *p_picture )
static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture ) static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture )
{ {
picture_dpb_t *p = DpbFindPicture( p_dec, p_picture ); picture_dpb_t *p = DpbFindPicture( p_dec, p_picture );
/* XXX it is needed to workaround libmpeg2 bugs */
if( !p || !p->b_linked )
{
msg_Err( p_dec, "DpbUnlinkPicture called on an invalid picture" );
return;
}
assert( p && p->b_linked ); assert( p && p->b_linked );
decoder_UnlinkPicture( p_dec, p->p_picture ); decoder_UnlinkPicture( p_dec, p->p_picture );
...@@ -825,12 +855,21 @@ static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture ) ...@@ -825,12 +855,21 @@ static void DpbUnlinkPicture( decoder_t *p_dec, picture_t *p_picture )
/** /**
* Mark the provided picture as displayed. * Mark the provided picture as displayed.
*/ */
static void DpbDisplayPicture( decoder_t *p_dec, picture_t *p_picture ) static int DpbDisplayPicture( decoder_t *p_dec, picture_t *p_picture )
{ {
picture_dpb_t *p = DpbFindPicture( p_dec, p_picture ); picture_dpb_t *p = DpbFindPicture( p_dec, p_picture );
/* XXX it is needed to workaround libmpeg2 bugs */
if( !p || p->b_displayed || !p->b_linked )
{
msg_Err( p_dec, "DpbDisplayPicture called on an invalid picture" );
return VLC_EGENERIC;
}
assert( p && !p->b_displayed && p->b_linked ); assert( p && !p->b_displayed && p->b_linked );
p->b_displayed = true; p->b_displayed = true;
return VLC_SUCCESS;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment