vlc | branch: master | Thomas Guillem <[email protected]> | Mon Mar 27 17:40:58 2017 +0200| [97fb59409f91979ab4478b8bbe5c38408e30456f] | committer: Thomas Guillem
mediacodec: refactor input block queue function > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=97fb59409f91979ab4478b8bbe5c38408e30456f --- modules/codec/omxil/mediacodec.c | 234 +++++++++++++++++++-------------------- 1 file changed, 116 insertions(+), 118 deletions(-) diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c index 05a6dbb..4f81400 100644 --- a/modules/codec/omxil/mediacodec.c +++ b/modules/codec/omxil/mediacodec.c @@ -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); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
