Commit 97fb5940 authored by Thomas Guillem's avatar Thomas Guillem
Browse files

mediacodec: refactor input block queue function

parent 9d9e5d29
......@@ -1249,116 +1249,17 @@ static block_t *GetNextBlock(decoder_sys_t *p_sys, block_t *p_block)
return p_block;
}
static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
static int QueueBlockLocked(decoder_t *p_dec, block_t *p_in_block,
bool b_drain)
{
decoder_sys_t *p_sys = p_dec->p_sys;
int i_ret;
block_t *p_block = NULL;
bool b_dequeue_timeout = false;
bool b_draining;
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_aborted)
{
if (p_sys->b_has_format)
goto end;
else
goto reload;
}
if (p_in_block != NULL)
{
b_draining = false;
if (p_in_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
{
DecodeFlushLocked(p_dec);
if (p_sys->b_aborted)
goto end;
if (p_in_block->i_flags & BLOCK_FLAG_CORRUPTED)
goto end;
}
if (p_in_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
&& !(p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED))
{
/* Before Android 21 and depending on the vendor, MediaCodec can
* crash or be in an inconsistent state when decoding interlaced
* videos. See OMXCodec_GetQuirks() for a white list of decoders
* that supported interlaced videos before Android 21. */
msg_Warn(p_dec, "codec doesn't support interlaced videos");
goto reload;
}
/* Parse input block */
if ((i_ret = p_sys->pf_on_new_block(p_dec, &p_in_block)) != 1)
{
if (i_ret != 0)
{
AbortDecoderLocked(p_dec);
msg_Err(p_dec, "pf_on_new_block failed");
}
goto end;
}
}
else
{
/* No input block, decoder is draining */
msg_Err(p_dec, "Decoder is draining");
b_draining = true;
if (!p_sys->b_output_ready)
{
/* Output no ready, no need to drain */
goto end;
}
}
if (p_sys->i_decode_flags & (DECODE_FLASH_FLUSH|DECODE_FLAG_RESTART))
{
msg_Warn(p_dec, "Flushing from DecodeBlock");
const bool b_restart = p_sys->i_decode_flags & DECODE_FLAG_RESTART;
p_sys->i_decode_flags = 0;
/* Flush before restart to unblock OutThread */
DecodeFlushLocked(p_dec);
if (p_sys->b_aborted)
goto end;
if (b_restart)
{
StopMediaCodec(p_dec);
if (p_sys->api.b_direct_rendering
&& UpdateOpaqueVout(p_dec) != VLC_SUCCESS)
{
msg_Err(p_dec, "UpdateOpaqueVout failed");
AbortDecoderLocked(p_dec);
goto end;
}
int i_ret = StartMediaCodec(p_dec);
switch (i_ret)
{
case VLC_SUCCESS:
msg_Warn(p_dec, "Restarted from DecodeBlock");
break;
case VLC_ENOOBJ:
break;
default:
msg_Err(p_dec, "StartMediaCodec failed");
AbortDecoderLocked(p_dec);
goto end;
}
}
}
/* Abort if MediaCodec is not yet started */
if (!p_sys->api.b_started)
goto end;
assert(p_sys->api.b_started);
/* Queue CSD blocks and input blocks */
block_t *p_block = NULL;
while (b_draining || (p_block = GetNextBlock(p_sys, p_in_block)))
while (b_drain || (p_block = GetNextBlock(p_sys, p_in_block)))
{
int i_index;
......@@ -1371,7 +1272,7 @@ 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;
return VLC_EGENERIC;
bool b_config = false;
mtime_t i_ts = 0;
......@@ -1381,7 +1282,7 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
if (i_index >= 0)
{
assert(b_draining || p_block != NULL);
assert(b_drain || p_block != NULL);
if (p_block != NULL)
{
b_config = (p_block->i_flags & BLOCK_FLAG_CSD);
......@@ -1391,7 +1292,6 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
if (!i_ts && p_block->i_dts)
i_ts = p_block->i_dts;
}
else fprintf(stderr, "send CSD\n");
p_buf = p_block->p_buffer;
i_size = p_block->i_buffer;
}
......@@ -1410,17 +1310,15 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
vlc_cond_broadcast(&p_sys->cond);
assert(p_block == p_in_block),
block_Release(p_in_block);
p_in_block = NULL;
}
b_dequeue_timeout = false;
if (b_draining)
if (b_drain)
break;
} else
{
msg_Err(p_dec, "queue_in failed");
AbortDecoderLocked(p_dec);
goto end;
goto error;
}
}
else if (i_index == MC_API_INFO_TRYAGAIN)
......@@ -1442,19 +1340,17 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
else
{
msg_Err(p_dec, "dequeue_in timeout: no input available for 2secs");
AbortDecoderLocked(p_dec);
goto end;
goto error;
}
}
else
{
msg_Err(p_dec, "dequeue_in failed");
AbortDecoderLocked(p_dec);
goto end;
goto error;
}
}
if (b_draining)
if (b_drain)
{
msg_Warn(p_dec, "EOS sent, waiting for OutThread");
......@@ -1467,11 +1363,113 @@ static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
if (!p_sys->b_aborted)
msg_Err(p_dec, "OutThread timed out");
}
vlc_mutex_unlock(&p_sys->lock);
return VLCDEC_SUCCESS;
return VLC_SUCCESS;
error:
AbortDecoderLocked(p_dec);
return VLC_EGENERIC;
}
static int DecodeBlock(decoder_t *p_dec, block_t *p_in_block)
{
decoder_sys_t *p_sys = p_dec->p_sys;
int i_ret;
vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_aborted)
{
if (p_sys->b_has_format)
goto end;
else
goto reload;
}
if (p_in_block == NULL)
{
/* No input block, decoder is draining */
msg_Err(p_dec, "Decoder is draining");
if (p_sys->b_output_ready)
QueueBlockLocked(p_dec, NULL, true);
goto end;
}
if (p_in_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
{
DecodeFlushLocked(p_dec);
if (p_sys->b_aborted)
goto end;
if (p_in_block->i_flags & BLOCK_FLAG_CORRUPTED)
goto end;
}
if (p_in_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
&& !(p_sys->api.i_quirks & MC_API_VIDEO_QUIRKS_SUPPORT_INTERLACED))
{
/* Before Android 21 and depending on the vendor, MediaCodec can
* crash or be in an inconsistent state when decoding interlaced
* videos. See OMXCodec_GetQuirks() for a white list of decoders
* that supported interlaced videos before Android 21. */
msg_Warn(p_dec, "codec doesn't support interlaced videos");
goto reload;
}
/* Parse input block */
if ((i_ret = p_sys->pf_on_new_block(p_dec, &p_in_block)) != 1)
{
if (i_ret != 0)
{
AbortDecoderLocked(p_dec);
msg_Err(p_dec, "pf_on_new_block failed");
}
goto end;
}
if (p_sys->i_decode_flags & (DECODE_FLASH_FLUSH|DECODE_FLAG_RESTART))
{
msg_Warn(p_dec, "Flushing from DecodeBlock");
const bool b_restart = p_sys->i_decode_flags & DECODE_FLAG_RESTART;
p_sys->i_decode_flags = 0;
/* Flush before restart to unblock OutThread */
DecodeFlushLocked(p_dec);
if (p_sys->b_aborted)
goto end;
if (b_restart)
{
StopMediaCodec(p_dec);
if (p_sys->api.b_direct_rendering
&& UpdateOpaqueVout(p_dec) != VLC_SUCCESS)
{
msg_Err(p_dec, "UpdateOpaqueVout failed");
AbortDecoderLocked(p_dec);
goto end;
}
int i_ret = StartMediaCodec(p_dec);
switch (i_ret)
{
case VLC_SUCCESS:
msg_Warn(p_dec, "Restarted from DecodeBlock");
break;
case VLC_ENOOBJ:
break;
default:
msg_Err(p_dec, "StartMediaCodec failed");
AbortDecoderLocked(p_dec);
goto end;
}
}
}
/* Abort if MediaCodec is not yet started */
if (p_sys->api.b_started)
QueueBlockLocked(p_dec, p_in_block, false);
end:
if (p_in_block)
block_Release(p_in_block);
......
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