[vlc-commits] mediacodec: refactor input block queue function

Thomas Guillem git at videolan.org
Wed Mar 29 15:49:45 CEST 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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);



More information about the vlc-commits mailing list