[vlc-commits] packetizer: mpeg4audio: implement draining and handle discontinuities

Francois Cartegnie git at videolan.org
Wed Oct 26 19:07:03 CEST 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Oct 26 14:01:17 2016 +0200| [2616f427bc716668570835919829d6b09e8bdbfa] | committer: Francois Cartegnie

packetizer: mpeg4audio: implement draining and handle discontinuities

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2616f427bc716668570835919829d6b09e8bdbfa
---

 modules/packetizer/mpeg4audio.c | 48 ++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/modules/packetizer/mpeg4audio.c b/modules/packetizer/mpeg4audio.c
index 854caa4..da79a65 100644
--- a/modules/packetizer/mpeg4audio.c
+++ b/modules/packetizer/mpeg4audio.c
@@ -978,25 +978,33 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
     block_t *p_out_buffer;
     uint8_t *p_buf;
 
-    if (!pp_block || !*pp_block)
-        return NULL;
+    block_t *p_block = pp_block ? *pp_block : NULL;
 
-    if ((*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
-        FlushStreamBlock(p_dec);
-        if ((*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED) {
-            block_Release(*pp_block);
+    if(p_block)
+    {
+        if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
+            /* First always drain complete blocks before discontinuity */
+            block_t *p_drain = PacketizeStreamBlock(p_dec, NULL);
+            if(p_drain)
+                return p_drain;
+
+            FlushStreamBlock(p_dec);
+
+            if (p_block->i_flags & BLOCK_FLAG_CORRUPTED) {
+                block_Release(p_block);
+                return NULL;
+            }
+        }
+
+        if (!date_Get(&p_sys->end_date) && p_block->i_pts <= VLC_TS_INVALID) {
+            /* We've just started the stream, wait for the first PTS. */
+            block_Release(p_block);
             return NULL;
         }
-    }
 
-    if (!date_Get(&p_sys->end_date) && (*pp_block)->i_pts <= VLC_TS_INVALID) {
-        /* We've just started the stream, wait for the first PTS. */
-        block_Release(*pp_block);
-        return NULL;
+        block_BytestreamPush(&p_sys->bytestream, p_block);
     }
 
-    block_BytestreamPush(&p_sys->bytestream, *pp_block);
-
     for (;;) switch(p_sys->i_state) {
     case STATE_NOSYNC:
         while (block_PeekBytes(&p_sys->bytestream, p_header, 2) == VLC_SUCCESS) {
@@ -1031,7 +1039,7 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
         if (p_sys->i_pts > VLC_TS_INVALID &&
             p_sys->i_pts != date_Get(&p_sys->end_date))
         {
-            if(date_Get(&p_sys->end_date) != 0)
+            if(date_Get(&p_sys->end_date) != VLC_TS_INVALID)
                 p_sys->b_discontuinity = true;
             date_Set(&p_sys->end_date, p_sys->i_pts);
         }
@@ -1072,8 +1080,6 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
         p_sys->i_state = STATE_NEXT_SYNC;
 
     case STATE_NEXT_SYNC:
-        /* TODO: If p_block == NULL, flush the buffer without checking the
-         * next sync word */
         if (p_sys->bytestream.p_block == NULL) {
             p_sys->i_state = STATE_NOSYNC;
             block_BytestreamFlush(&p_sys->bytestream);
@@ -1083,7 +1089,14 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
         /* Check if next expected frame contains the sync word */
         if (block_PeekOffsetBytes(&p_sys->bytestream, p_sys->i_frame_size
                     + p_sys->i_header_size, p_header, 2) != VLC_SUCCESS)
+        {
+            if(p_block == NULL) /* drain */
+            {
+                p_sys->i_state = STATE_SEND_DATA;
+                break;
+            }
             return NULL; /* Need more data */
+        }
 
         assert((p_sys->i_type == TYPE_ADTS) || (p_sys->i_type == TYPE_LOAS));
         if (((p_sys->i_type == TYPE_ADTS) &&
@@ -1143,7 +1156,8 @@ static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
             p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
 
         /* So p_block doesn't get re-added several times */
-        *pp_block = block_BytestreamPop(&p_sys->bytestream);
+        if( pp_block )
+            *pp_block = block_BytestreamPop(&p_sys->bytestream);
 
         p_sys->i_state = STATE_NOSYNC;
 



More information about the vlc-commits mailing list