[vlc-commits] demux: ts: fix leak with opus and disambiguate block chains in pes

Francois Cartegnie git at videolan.org
Thu Dec 8 11:59:22 CET 2016


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Dec  8 11:55:00 2016 +0100| [d75c0ce3fa98b6968d4a4b8f841deaeda76e3061] | committer: Francois Cartegnie

demux: ts: fix leak with opus and disambiguate block chains in pes

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

 modules/demux/mpeg/ts.c | 155 +++++++++++++++++++++++++-----------------------
 1 file changed, 82 insertions(+), 73 deletions(-)

diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c
index b8572d8..7fc4917 100644
--- a/modules/demux/mpeg/ts.c
+++ b/modules/demux/mpeg/ts.c
@@ -1219,6 +1219,70 @@ invalid:
     return NULL;
 }
 
+static block_t * ConvertPESBlock( demux_t *p_demux, ts_pes_es_t *p_es,
+                                  size_t i_pes_size, uint8_t i_stream_id,
+                                  block_t *p_block )
+{
+    if(!p_block)
+        return NULL;
+
+    if( p_es->fmt.i_codec == VLC_CODEC_SUBT )
+    {
+        if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
+        {
+            p_block->i_buffer = i_pes_size;
+        }
+        /* Append a \0 */
+        p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
+        if( p_block )
+            p_block->p_buffer[p_block->i_buffer -1] = '\0';
+    }
+    else if( p_es->fmt.i_codec == VLC_CODEC_TELETEXT )
+    {
+        if( p_block->i_pts <= VLC_TS_INVALID )
+        {
+            /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
+             * In this case use the last PCR + 40ms */
+            mtime_t i_pcr = p_es->p_program->pcr.i_current;
+            if( i_pcr > VLC_TS_INVALID )
+                p_block->i_pts = FROM_SCALE(i_pcr) + 40000;
+        }
+    }
+    else if( p_es->fmt.i_codec == VLC_CODEC_ARIB_A ||
+             p_es->fmt.i_codec == VLC_CODEC_ARIB_C )
+    {
+        if( p_block->i_pts <= VLC_TS_INVALID )
+        {
+            if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
+            {
+                p_block->i_buffer = i_pes_size;
+            }
+            /* Append a \0 */
+            p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
+            if( p_block )
+                p_block->p_buffer[p_block->i_buffer -1] = '\0';
+        }
+    }
+    else if( p_es->fmt.i_codec == VLC_CODEC_OPUS)
+    {
+        p_block = Opus_Parse(p_demux, p_block);
+    }
+    else if( p_es->fmt.i_codec == VLC_CODEC_JPEG2000 )
+    {
+        if( unlikely(i_stream_id != 0xBD) )
+        {
+            block_Release( p_block );
+            p_block = NULL;
+        }
+        else
+        {
+            p_block = J2K_Parse( p_demux, p_block, p_es->b_interlaced );
+        }
+    }
+
+    return p_block;
+}
+
 /****************************************************************************
  * gathering stuff
  ****************************************************************************/
@@ -1340,7 +1404,12 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 
     if( p_pes )
     {
-        block_t *p_block;
+        ts_pmt_t *p_pmt = p_es->p_program;
+        if( unlikely(!p_pmt) )
+        {
+            block_ChainRelease( p_pes );
+            return;
+        }
 
         if( i_dts >= 0 )
             p_pes->i_dts = FROM_SCALE(i_dts);
@@ -1350,74 +1419,13 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 
         p_pes->i_length = FROM_SCALE_NZ(i_length);
 
-        p_block = block_ChainGather( p_pes );
-        if( p_es->fmt.i_codec == VLC_CODEC_SUBT )
-        {
-            if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
-            {
-                p_block->i_buffer = i_pes_size;
-            }
-            /* Append a \0 */
-            p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
-            if( !p_block )
-                return;
-            p_block->p_buffer[p_block->i_buffer -1] = '\0';
-        }
-        else if( p_es->fmt.i_codec == VLC_CODEC_TELETEXT )
-        {
-            if( p_block->i_pts <= VLC_TS_INVALID )
-            {
-                /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
-                 * In this case use the last PCR + 40ms */
-                mtime_t i_pcr = p_es->p_program->pcr.i_current;
-                if( i_pcr > VLC_TS_INVALID )
-                    p_block->i_pts = FROM_SCALE(i_pcr) + 40000;
-            }
-        }
-        else if( p_es->fmt.i_codec == VLC_CODEC_ARIB_A ||
-                 p_es->fmt.i_codec == VLC_CODEC_ARIB_C )
-        {
-            if( p_block->i_pts <= VLC_TS_INVALID )
-            {
-                if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
-                {
-                    p_block->i_buffer = i_pes_size;
-                }
-                /* Append a \0 */
-                p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
-                if( !p_block )
-                    return;
-                p_block->p_buffer[p_block->i_buffer -1] = '\0';
-            }
-        }
-        else if( p_es->fmt.i_codec == VLC_CODEC_OPUS)
-        {
-            p_block = Opus_Parse(p_demux, p_block);
-        }
-        else if( p_es->fmt.i_codec == VLC_CODEC_JPEG2000 )
-        {
-            if( unlikely(i_stream_id != 0xBD) )
-            {
-                block_Release( p_block );
-                p_block = NULL;
-            }
-            else
-            {
-                p_block = J2K_Parse( p_demux, p_block, p_es->b_interlaced );
-            }
-            if( !p_block )
-                return;
-        }
+        /* Some codecs might need xform or AU splitting */
+        block_t *p_chain = ConvertPESBlock( p_demux, p_es, i_pes_size, i_stream_id,
+                                            block_ChainGather( p_pes ) );
 
-        ts_pmt_t *p_pmt = p_es->p_program;
-        if( unlikely(!p_pmt) )
-        {
-            block_ChainRelease( p_block );
-            return;
-        }
-
-        while (p_block) {
-            block_t *p_next = p_block->p_next;
+        while ( p_chain ) {
+            block_t *p_block = p_chain;
+            p_chain = p_chain->p_next;
             p_block->p_next = NULL;
 
             if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
@@ -1427,11 +1435,14 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
             {
                 if( pid->u.p_pes->p_prepcr_outqueue )
                 {
+                    /* Rebuild current output chain, appending any prepcr outqueue */
                     block_ChainAppend( &pid->u.p_pes->p_prepcr_outqueue, p_block );
-                    p_block = pid->u.p_pes->p_prepcr_outqueue;
-                    p_next = p_block->p_next;
-                    p_block->p_next = NULL;
+                    if( p_chain )
+                        block_ChainAppend( &pid->u.p_pes->p_prepcr_outqueue, p_chain );
+                    p_chain = pid->u.p_pes->p_prepcr_outqueue;
                     pid->u.p_pes->p_prepcr_outqueue = NULL;
+                    /* Then now output all data */
+                    continue;
                 }
 
                 if ( p_pmt->pcr.b_disable && p_block->i_dts > VLC_TS_INVALID &&
@@ -1562,8 +1573,6 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 
                 block_ChainAppend( &pid->u.p_pes->p_prepcr_outqueue, p_block );
             }
-
-            p_block = p_next;
         }
     }
     else



More information about the vlc-commits mailing list