Commit c4aabc52 authored by Thomas Guillem's avatar Thomas Guillem

decoder: add VLCDEC_RELOAD status

This replaces the decoder_RequestReload() function. The module implementation
that returns this status should not have modified or released the input block
passed in pf_decoder parameter.
parent 21144a3a
......@@ -69,6 +69,7 @@ struct decoder_t
# define VLCDEC_SUCCESS VLC_SUCCESS
# define VLCDEC_ECRITICAL VLC_EGENERIC
# define VLCDEC_RELOAD (-100)
/* This function is called to decode one packetized block.
*
* The module implementation will own the input block (p_block) and should
......@@ -84,6 +85,11 @@ struct decoder_t
* VLCDEC_SUCCESS: pf_decode will be called again
* VLCDEC_ECRITICAL: in case of critical error, pf_decode won't be called
* again.
* VLCDEC_RELOAD: Request that the decoder should be reloaded. The current
* module will be unloaded. Reloading a module may cause a loss of frames.
* When returning this status, the implementation shouldn't release or
* modify the p_block in argument (The same p_block will be feed to the
* next decoder module).
*/
int ( * pf_decode ) ( decoder_t *, block_t *p_block );
......@@ -352,13 +358,6 @@ VLC_API block_t * decoder_NewAudioBuffer( decoder_t *, int i_size ) VLC_USED;
*/
VLC_API subpicture_t * decoder_NewSubpicture( decoder_t *, const subpicture_updater_t * ) VLC_USED;
/*
* Request that the decoder should be reloaded. The current module will be
* unloaded. Reloading a module may cause a loss of frames. There is no
* warranty that pf_decode_* callbacks won't be called again after this call.
*/
VLC_API void decoder_RequestReload( decoder_t * );
/**
* This function gives all input attachments at once.
*
......
......@@ -1362,7 +1362,12 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_aborted)
goto end;
{
if (p_sys->b_has_format)
goto end;
else
goto reload;
}
if (p_in_block != NULL)
{
......@@ -1572,29 +1577,19 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
end:
if (p_in_block)
block_Release(p_in_block);
if (p_sys->b_aborted)
{
if (!p_sys->b_has_format)
{
/* Add an empty variable so that mediacodec won't be loaded again
* for this ES */
if (var_Create(p_dec, "mediacodec-failed", VLC_VAR_VOID)
== VLC_SUCCESS)
decoder_RequestReload(p_dec);
vlc_mutex_unlock(&p_sys->lock);
return VLCDEC_SUCCESS;
}
else
{
vlc_mutex_unlock(&p_sys->lock);
return VLCDEC_ECRITICAL;
}
}
else
{
vlc_mutex_unlock(&p_sys->lock);
return VLCDEC_SUCCESS;
}
/* Too late to reload here, we already modified/released the input block,
* do it next time. */
int ret = p_sys->b_aborted && p_sys->b_has_format ? VLCDEC_ECRITICAL
: VLCDEC_SUCCESS;
vlc_mutex_unlock(&p_sys->lock);
return ret;
reload:
vlc_mutex_unlock(&p_sys->lock);
/* Add an empty variable so that mediacodec won't be loaded again
* for this ES */
var_Create(p_dec, "mediacodec-failed", VLC_VAR_VOID);
return VLCDEC_RELOAD;
}
static int Video_OnNewBlock(decoder_t *p_dec, block_t **pp_block)
......
......@@ -336,7 +336,7 @@ static int StartVideoToolboxSession(decoder_t *p_dec)
return VLC_SUCCESS;
}
static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
static int StartVideoToolbox(decoder_t *p_dec, const block_t *p_block)
{
decoder_sys_t *p_sys = p_dec->p_sys;
OSStatus status;
......@@ -1117,7 +1117,11 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_block)
msg_Err(p_dec, "decoder failure: invalid SPS/PPS");
else if (status == -6661) {
msg_Err(p_dec, "decoder failure: invalid argument");
goto reload;
/* The decoder module will be reloaded next time since we already
* modified the input block */
vlc_mutex_lock(&p_sys->lock);
p_dec->p_sys->b_abort = true;
vlc_mutex_unlock(&p_sys->lock);
} else if (status == -8969 || status == -12909) {
msg_Err(p_dec, "decoder failure: bad data (%i)", (int)status);
StopVideoToolbox(p_dec);
......@@ -1136,14 +1140,10 @@ skip:
return VLCDEC_SUCCESS;
reload:
block_Release(p_block);
/* Add an empty variable so that videotoolbox won't be loaded again for
* this ES */
if (var_Create(p_dec, "videotoolbox-failed", VLC_VAR_VOID) == VLC_SUCCESS)
decoder_RequestReload(p_dec);
else
return VLCDEC_ECRITICAL;
return VLCDEC_SUCCESS;
var_Create(p_dec, "videotoolbox-failed", VLC_VAR_VOID);
return VLCDEC_RELOAD;
}
static int UpdateVideoFormat(decoder_t *p_dec, CVPixelBufferRef imageBuffer)
......
......@@ -148,6 +148,7 @@ struct decoder_owner_sys_t
/* */
#define DECODER_SPU_VOUT_WAIT_DURATION ((int)(0.200*CLOCK_FREQ))
#define BLOCK_FLAG_CORE_PRIVATE_RELOADED (1 << BLOCK_FLAG_CORE_PRIVATE_SHIFT)
/**
* Load a decoder module
......@@ -620,7 +621,7 @@ subpicture_t *decoder_NewSubpicture( decoder_t *p_decoder,
return p_subpicture;
}
void decoder_RequestReload( decoder_t * p_dec )
static void RequestReload( decoder_t * p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
/* Don't override reload if it's RELOAD_DECODER_AOUT */
......@@ -1103,7 +1104,7 @@ static int DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
if( status == AOUT_DEC_CHANGED )
{
/* Only reload the decoder */
decoder_RequestReload( p_dec );
RequestReload( p_dec );
}
else if( status == AOUT_DEC_FAILED )
{
......@@ -1244,7 +1245,7 @@ static int DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
return i_ret;
}
static void DecoderProcess( decoder_t *p_dec, block_t *p_block );
static void DecoderDecode( decoder_t *p_dec, block_t *p_block )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
......@@ -1258,6 +1259,18 @@ static void DecoderDecode( decoder_t *p_dec, block_t *p_block )
case VLCDEC_ECRITICAL:
p_owner->error = true;
break;
case VLCDEC_RELOAD:
RequestReload( p_dec );
if( unlikely( p_block == NULL ) )
break;
if( !( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
{
p_block->i_flags |= BLOCK_FLAG_CORE_PRIVATE_RELOADED;
DecoderProcess( p_dec, p_block );
}
else /* We prefer loosing this block than an infinite recursion */
block_Release( p_block );
break;
default:
vlc_assert_unreachable();
}
......@@ -1307,8 +1320,8 @@ static void DecoderProcess( decoder_t *p_dec, block_t *p_block )
return;
}
#endif
if( p_owner->p_packetizer )
if( p_owner->p_packetizer
&& !unlikely( p_block->i_flags & BLOCK_FLAG_CORE_PRIVATE_RELOADED ) )
{
block_t *p_packetized_block;
block_t **pp_block = p_block ? &p_block : NULL;
......
......@@ -81,7 +81,6 @@ decoder_GetDisplayRate
decoder_GetInputAttachments
decoder_NewAudioBuffer
decoder_NewSubpicture
decoder_RequestReload
decoder_SynchroChoose
decoder_SynchroDate
decoder_SynchroDecode
......
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