[vlc-devel] [PATCH 08/11] mediacodec: handle flush or restart outside pf_on_new_block callback

Thomas Guillem thomas at gllm.fr
Wed Aug 26 18:10:05 CEST 2015


---
 modules/codec/omxil/mediacodec.c | 93 +++++++++++++++++++---------------------
 1 file changed, 44 insertions(+), 49 deletions(-)

diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index a8258fe..5f63f38 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -61,11 +61,13 @@ struct csd
     size_t i_size;
 };
 
+#define NEWBLOCK_FLAG_RESTART (0x01)
+#define NEWBLOCK_FLAG_FLUSH (0x02)
 /**
  * Callback called when a new block is processed from DecodeCommon.
  * It returns -1 in case of error, 0 if block should be dropped, 1 otherwise.
  */
-typedef int (*dec_on_new_block_cb)(decoder_t *, block_t *);
+typedef int (*dec_on_new_block_cb)(decoder_t *, block_t *, int *);
 
 /**
  * Callback called when decoder is flushing.
@@ -136,12 +138,12 @@ static int  OpenDecoderJni(vlc_object_t *);
 static int  OpenDecoderNdk(vlc_object_t *);
 static void CloseDecoder(vlc_object_t *);
 
-static int Video_OnNewBlock(decoder_t *, block_t *);
+static int Video_OnNewBlock(decoder_t *, block_t *, int *);
 static int Video_GetOutput(decoder_t *, picture_t **, block_t **, bool *, mtime_t);
 static void Video_OnFlush(decoder_t *);
 static picture_t *DecodeVideo(decoder_t *, block_t **);
 
-static int Audio_OnNewBlock(decoder_t *, block_t *);
+static int Audio_OnNewBlock(decoder_t *, block_t *, int *);
 static int Audio_GetOutput(decoder_t *, picture_t **, block_t **, bool *, mtime_t);
 static void Audio_OnFlush(decoder_t *);
 static block_t *DecodeAudio(decoder_t *, block_t **);
@@ -1110,17 +1112,39 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block,
 
     if (b_new_block)
     {
-        int i_ret;
+        int i_ret, i_flags = 0;
 
         p_sys->b_new_block = false;
-        i_ret = p_sys->pf_on_new_block(p_dec, p_block);
+
+        if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
+        {
+            if (DecodeFlush(p_dec) != VLC_SUCCESS)
+                b_error = true;
+            goto endclean;
+        }
+
+        i_ret = p_sys->pf_on_new_block(p_dec, p_block, &i_flags);
         if (i_ret != 1)
         {
             if (i_ret == -1)
                 b_error = true;
             goto endclean;
         }
+        if (i_flags & NEWBLOCK_FLAG_FLUSH)
+        {
+            if (DecodeFlush(p_dec) != VLC_SUCCESS)
+                goto endclean;
+        }
+
+        if (i_flags & NEWBLOCK_FLAG_RESTART)
+        {
+            StopMediaCodec(p_dec);
+            if (StartMediaCodec(p_dec) != VLC_SUCCESS)
+                goto endclean;
+        }
     }
+    if (!p_sys->api->b_started)
+        goto endclean;
 
     do
     {
@@ -1227,46 +1251,35 @@ endclean:
     return b_error ? -1 : 0;
 }
 
-static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block)
+static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
     bool b_csd_changed = false, b_size_changed = false;
-    bool b_delayed_start = false;
 
     if (p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
         && !p_sys->api->b_support_interlaced)
         return -1;
 
-    if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
-    {
-        if (DecodeFlush(p_dec) != VLC_SUCCESS)
-            return -1;
-        return 0;
-    }
-
     if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
         H264ProcessBlock(p_dec, p_block, &b_csd_changed, &b_size_changed);
     else if (p_dec->fmt_in.i_codec == VLC_CODEC_HEVC)
         HEVCProcessBlock(p_dec, p_block, &b_csd_changed, &b_size_changed);
 
-    if (p_sys->api->b_started && b_csd_changed)
+    if (b_csd_changed)
     {
-        if (b_size_changed)
+        if (b_size_changed || !p_sys->api->b_started)
         {
-            msg_Err(p_dec, "SPS/PPS changed during playback and "
-                    "video size are different. Restart it !");
-            StopMediaCodec(p_dec);
+            if (p_sys->api->b_started)
+                msg_Err(p_dec, "SPS/PPS changed during playback and "
+                        "video size are different. Restart it !");
+            *p_flags |= NEWBLOCK_FLAG_RESTART;
         } else
         {
             msg_Err(p_dec, "SPS/PPS changed during playback. Flush it");
-            if (DecodeFlush(p_dec) != VLC_SUCCESS)
-                return -1;
+            *p_flags |= NEWBLOCK_FLAG_FLUSH;
         }
     }
 
-    if (b_csd_changed)
-        b_delayed_start = true;
-
     /* try delayed opening if there is a new extra data */
     if (!p_sys->api->b_started)
     {
@@ -1274,18 +1287,15 @@ static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block)
         {
         case VLC_CODEC_VC1:
             if (p_dec->fmt_in.i_extra)
-                b_delayed_start = true;
+                *p_flags |= NEWBLOCK_FLAG_RESTART;
         default:
             break;
         }
-        if (b_delayed_start && StartMediaCodec(p_dec) != VLC_SUCCESS)
-            return -1;
-        if (!p_sys->api->b_started)
-            return 0;
     }
 
     timestamp_FifoPut(p_sys->u.video.timestamp_fifo,
                       p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);
+
     return 1;
 }
 
@@ -1323,17 +1333,10 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
     return p_out;
 }
 
-static int Audio_OnNewBlock(decoder_t *p_dec, block_t *p_block)
+static int Audio_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
-    {
-        if (DecodeFlush(p_dec) != VLC_SUCCESS)
-            return -1;
-        return 0;
-    }
-
     /* We've just started the stream, wait for the first PTS. */
     if (!date_Get(&p_sys->u.audio.i_end_date))
     {
@@ -1345,31 +1348,23 @@ static int Audio_OnNewBlock(decoder_t *p_dec, block_t *p_block)
     /* try delayed opening if there is a new extra data */
     if (!p_sys->api->b_started)
     {
-        bool b_delayed_start = false;
-
         switch (p_dec->fmt_in.i_codec)
         {
         case VLC_CODEC_VORBIS:
         case VLC_CODEC_MP4A:
             if (p_dec->fmt_in.i_extra)
-                b_delayed_start = true;
+                *p_flags |= NEWBLOCK_FLAG_RESTART;
         default:
             break;
         }
         if (!p_dec->p_sys->u.audio.i_channels && p_dec->fmt_in.audio.i_channels)
         {
             p_dec->p_sys->u.audio.i_channels = p_dec->fmt_in.audio.i_channels;
-            b_delayed_start = true;
+            *p_flags |= NEWBLOCK_FLAG_RESTART;
         }
 
-        if (b_delayed_start && !p_dec->p_sys->u.audio.i_channels
-         && p_sys->u.audio.b_need_channels)
-            b_delayed_start = false;
-
-        if (b_delayed_start && StartMediaCodec(p_dec) != VLC_SUCCESS)
-            return -1;
-        if (!p_sys->api->b_started)
-            return 0;
+        if (!p_dec->p_sys->u.audio.i_channels && p_sys->u.audio.b_need_channels)
+            *p_flags &= ~NEWBLOCK_FLAG_RESTART;
     }
     return 1;
 }
-- 
2.1.4



More information about the vlc-devel mailing list