From 55fb58fb2a140e6597eb885142528e4e43359c3e Mon Sep 17 00:00:00 2001
From: Petri Hintukainen <phintuka@users.sourceforge.net>
Date: Fri, 13 Jun 2014 12:57:28 +0300
Subject: [PATCH 2/3] [WIP] reduce mallocs in mpeg-ts demuxer

---
 modules/demux/ts.c | 226 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 135 insertions(+), 91 deletions(-)

diff --git a/modules/demux/ts.c b/modules/demux/ts.c
index 24d5e99..45e95a3 100644
--- a/modules/demux/ts.c
+++ b/modules/demux/ts.c
@@ -252,7 +252,8 @@ typedef struct
     int         i_data_size;
     int         i_data_gathered;
     block_t     *p_data;
-    block_t     **pp_last;
+    block_t     *p_last;
+    int          i_block_size;
 
     es_mpeg4_descriptor_t *p_mpeg4desc;
 
@@ -291,9 +292,6 @@ struct demux_sys_t
     /* Additional TS packet header size (BluRay TS packets have 4-byte header before sync byte) */
     int         i_packet_header_size;
 
-    /* how many TS packet we read at once */
-    int         i_ts_read;
-
     /* to determine length and time */
     int         i_pid_ref_pcr;
     mtime_t     i_first_pcr;
@@ -358,19 +356,19 @@ static void PSINewTableCallBack( demux_t *, dvbpsi_handle,
 
 static int ChangeKeyCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
 
-static inline int PIDGet( block_t *p )
+static inline int PIDGet( const uint8_t *p_buffer )
 {
-    return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
+    return ( (p_buffer[1]&0x1f)<<8 )|p_buffer[2];
 }
 
-static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk );
+static bool GatherData( demux_t *p_demux, ts_pid_t *pid, uint8_t *p_buffer );
 
-static block_t* ReadTSPacket( demux_t *p_demux );
+static int ReadTSPackets( demux_t *p_demux, uint8_t **pp_buffer, int i_packet );
 static int Seek( demux_t *p_demux, double f_percent );
 static void GetFirstPCR( demux_t *p_demux );
 static void GetLastPCR( demux_t *p_demux );
 static void CheckPCR( demux_t *p_demux );
-static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * );
+static void PCRHandle( demux_t *p_demux, ts_pid_t *, const uint8_t *p );
 
 static void              IODFree( iod_descriptor_t * );
 
@@ -386,6 +384,48 @@ static void SetPrgFilter( demux_t *, int i_prg, bool b_selected );
 #define TS_PACKET_SIZE_MAX 204
 #define TS_TOPFIELD_HEADER 1320
 
+static void EsAppend( ts_es_t *p_es, const uint8_t *p_buffer, int i_buffer)
+{
+#if 1
+    /* append to last block ? */
+    if( p_es->p_last ) {
+        assert( p_es->p_data );
+        if( p_es->i_block_size >= p_es->p_last->i_buffer + i_buffer) {
+            memcpy( p_es->p_last->p_buffer + p_es->p_last->i_buffer, p_buffer, i_buffer );
+            p_es->p_last->i_buffer += i_buffer;
+            return;
+        }
+        //fprintf(stderr, "*** chain, have %d need %d\n", p_es->i_alloc_size, p_es->p_last->i_buffer + i_buffer);
+    }
+
+    /* allocate new block */
+    if( p_es->i_data_size > 188 ) {
+        p_es->i_block_size = p_es->i_data_size;
+    } else if( p_es->i_data_size < 1 ) {
+        p_es->i_block_size = 2*0x10000;
+    } else {
+        p_es->i_block_size = 188;
+    }
+
+    block_t *p_block = block_Alloc( p_es->i_block_size );
+#else
+    block_t *p_block = block_Alloc( 188 );
+#endif
+    if( p_block == NULL )
+        return;
+
+    memcpy( p_block->p_buffer, p_buffer, i_buffer );
+     p_block->i_buffer = i_buffer;
+
+    /* and append it to the chain */
+    if (p_es->p_last) {
+        p_es->p_last->p_next = p_block;
+    } else {
+        p_es->p_data = p_block;
+    }
+    p_es->p_last = p_block;
+}
+
 static int DetectPacketSize( demux_t *p_demux, int *pi_header_size )
 {
     const uint8_t *p_peek;
@@ -602,7 +642,6 @@ static int Open( vlc_object_t *p_this )
     p_sys->pid[8191].b_seen = true;
     p_sys->i_packet_size = i_packet_size;
     p_sys->i_packet_header_size = i_packet_header_size;
-    p_sys->i_ts_read = 50;
     p_sys->csa = NULL;
     p_sys->b_start_record = false;
 
@@ -904,20 +943,21 @@ static int ChangeKeyCallback( vlc_object_t *p_this, char const *psz_cmd,
 /*****************************************************************************
  * Demux:
  *****************************************************************************/
+#define READ_CHUNK_PACKETS 32
 static int Demux( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     bool b_wait_es = p_sys->i_pmt_es <= 0;
 
-    /* We read at most 100 TS packet or until a frame is completed */
-    for( int i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )
+    uint8_t buf[TS_PACKET_SIZE_MAX * READ_CHUNK_PACKETS];
+    uint8_t *p_buffer = buf;
+    int     i_pkt;
+
+    i_pkt = ReadTSPackets( p_demux, &p_buffer, READ_CHUNK_PACKETS );
+
+    for (; i_pkt > 0 && p_buffer[0] == 0x47 ; --i_pkt)
     {
         bool         b_frame = false;
-        block_t     *p_pkt;
-        if( !(p_pkt = ReadTSPacket( p_demux )) )
-        {
-            return 0;
-        }
 
         if( p_sys->b_start_record )
         {
@@ -927,7 +967,7 @@ static int Demux( demux_t *p_demux )
         }
 
         /* Parse the TS packet */
-        ts_pid_t *p_pid = &p_sys->pid[PIDGet( p_pkt )];
+        ts_pid_t *p_pid = &p_sys->pid[PIDGet( p_buffer )];
 
         if( p_pid->b_valid )
         {
@@ -935,21 +975,20 @@ static int Demux( demux_t *p_demux )
             {
                 if( p_pid->i_pid == 0 || ( p_sys->b_dvb_meta && ( p_pid->i_pid == 0x11 || p_pid->i_pid == 0x12 || p_pid->i_pid == 0x14 ) ) )
                 {
-                    dvbpsi_PushPacket( p_pid->psi->handle, p_pkt->p_buffer );
+                    dvbpsi_PushPacket( p_pid->psi->handle, p_buffer );
                 }
                 else
                 {
                     for( int i_prg = 0; i_prg < p_pid->psi->i_prg; i_prg++ )
                     {
                         dvbpsi_PushPacket( p_pid->psi->prg[i_prg]->handle,
-                                           p_pkt->p_buffer );
+                                           p_buffer );
                     }
                 }
-                block_Release( p_pkt );
             }
             else
             {
-                b_frame = GatherData( p_demux, p_pid, p_pkt );
+                b_frame = GatherData( p_demux, p_pid, p_buffer );
             }
         }
         else
@@ -959,13 +998,15 @@ static int Demux( demux_t *p_demux )
                 msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );
             }
             /* We have to handle PCR if present */
-            PCRHandle( p_demux, p_pid, p_pkt );
-            block_Release( p_pkt );
+            PCRHandle( p_demux, p_pid, p_buffer );
         }
         p_pid->b_seen = true;
-
+#if 0
+        // we need to handle all read packets even if frame is ready earlier
         if( b_frame || ( b_wait_es && p_sys->i_pmt_es > 0 ) )
             break;
+#endif
+	p_buffer += p_sys->i_packet_size;
     }
 
     demux_UpdateTitleFromStream( p_demux );
@@ -1440,7 +1481,6 @@ static void PIDInit( ts_pid_t *pid, bool b_psi, ts_psi_t *p_owner )
 
         es_format_Init( &pid->es->fmt, UNKNOWN_ES, 0 );
         pid->es->data_type = TS_ES_DATA_PES;
-        pid->es->pp_last = &pid->es->p_data;
     }
 }
 
@@ -1531,6 +1571,7 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
     mtime_t i_pts = -1;
     mtime_t i_length = 0;
 
+#warning no need to chainExtract anymore, just check amount of data in block
     /* FIXME find real max size */
     /* const int i_max = */ block_ChainExtract( p_pes, header, 34 );
 
@@ -1665,7 +1706,6 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
         if( p_pes->i_buffer <= i_skip )
         {
             block_t *p_next = p_pes->p_next;
-
             i_skip -= p_pes->i_buffer;
             block_Release( p_pes );
             p_pes = p_next;
@@ -1684,8 +1724,6 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 
     if( p_pes )
     {
-        block_t *p_block;
-
         if( i_dts >= 0 )
             p_pes->i_dts = VLC_TS_0 + i_dts * 100 / 9;
 
@@ -1694,9 +1732,11 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 
         p_pes->i_length = i_length * 100 / 9;
 
-        p_block = block_ChainGather( p_pes );
+        block_t *p_block = p_pes; // TODO: redundant
+p_pes = NULL;
         if( pid->es->fmt.i_codec == VLC_CODEC_SUBT )
         {
+            p_block = block_ChainGather( p_block );
             if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
             {
                 p_block->i_buffer = i_pes_size;
@@ -1709,6 +1749,7 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
         }
         else if( pid->es->fmt.i_codec == VLC_CODEC_TELETEXT )
         {
+            p_block = block_ChainGather( p_block );
             if( p_block->i_pts <= VLC_TS_INVALID )
             {
                 /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
@@ -1728,6 +1769,7 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 
         for( int i = 0; i < pid->i_extra_es; i++ )
         {
+            p_block = block_ChainGather( p_block );
             es_out_Send( p_demux->out, pid->extra_es[i]->id,
                          block_Duplicate( p_block ) );
         }
@@ -1735,7 +1777,13 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
         if (!p_sys->b_trust_pcr)
             es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts);
 
-        es_out_Send( p_demux->out, pid->es->id, p_block );
+        while (p_block) {
+          //p_block = block_ChainGather( p_block );
+            block_t *p_next = p_block->p_next;
+            p_block->p_next = NULL;
+            es_out_Send( p_demux->out, pid->es->id, p_block );
+            p_block = p_next;
+        }
     }
     else
     {
@@ -1799,7 +1847,7 @@ static void ParseData( demux_t *p_demux, ts_pid_t *pid )
     pid->es->p_data = NULL;
     pid->es->i_data_size = 0;
     pid->es->i_data_gathered = 0;
-    pid->es->pp_last = &pid->es->p_data;
+    pid->es->p_last = NULL;
 
     if( pid->es->data_type == TS_ES_DATA_PES )
     {
@@ -1815,31 +1863,28 @@ static void ParseData( demux_t *p_demux, ts_pid_t *pid )
     }
 }
 
-static block_t* ReadTSPacket( demux_t *p_demux )
+static int ReadTSPackets( demux_t *p_demux, uint8_t **pp_buffer, int i_packet )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
+    uint8_t *p_buffer = *pp_buffer;
 
-    block_t     *p_pkt;
-
-    /* Get a new TS packet */
-    if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
+    int i_pkt = stream_Read( p_demux->s, p_buffer, p_sys->i_packet_size * i_packet )
+                / p_sys->i_packet_size;
+    if( i_pkt < 1 )
     {
-        msg_Dbg( p_demux, "eof ?" );
-        return NULL;
+        return 0;
     }
 
     /* Skip header (BluRay streams).
      * re-sync logic would do this (by adjusting packet start), but this would result in losing first and last ts packets.
      * First packet is usually PAT, and losing it means losing whole first GOP. This is fatal with still-image based menus.
      */
-    p_pkt->p_buffer += p_sys->i_packet_header_size;
-    p_pkt->i_buffer -= p_sys->i_packet_header_size;
+    *pp_buffer += p_sys->i_packet_header_size;
 
     /* Check sync byte and re-sync if needed */
-    if( p_pkt->p_buffer[0] != 0x47 )
+    if( p_buffer[p_sys->i_packet_header_size] != 0x47 )
     {
         msg_Warn( p_demux, "lost synchro" );
-        block_Release( p_pkt );
         while( vlc_object_alive (p_demux) )
         {
             const uint8_t *p_peek;
@@ -1850,7 +1895,7 @@ static block_t* ReadTSPacket( demux_t *p_demux )
             if( i_peek < p_sys->i_packet_size + 1 )
             {
                 msg_Dbg( p_demux, "eof ?" );
-                return NULL;
+                return 0;
             }
 
             while( i_skip < i_peek - p_sys->i_packet_size )
@@ -1870,13 +1915,16 @@ static block_t* ReadTSPacket( demux_t *p_demux )
                 break;
             }
         }
-        if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
+
+        i_pkt = stream_Read( p_demux->s, p_buffer, p_sys->i_packet_size * i_packet )
+                   / p_sys->i_packet_size;
+        if( i_pkt < 1 )
         {
             msg_Dbg( p_demux, "eof ?" );
-            return NULL;
+            return 0;
         }
     }
-    return p_pkt;
+    return i_pkt;
 }
 
 static mtime_t AdjustPCRWrapAround( demux_t *p_demux, mtime_t i_pcr )
@@ -1900,9 +1948,9 @@ static mtime_t AdjustPCRWrapAround( demux_t *p_demux, mtime_t i_pcr )
     return i_pcr + i_adjust;
 }
 
-static mtime_t GetPCR( block_t *p_pkt )
+static mtime_t GetPCR( const uint8_t *p_buffer )
 {
-    const uint8_t *p = p_pkt->p_buffer;
+    const uint8_t *p = p_buffer;
 
     mtime_t i_pcr = -1;
 
@@ -1939,17 +1987,16 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos )
 
     while( vlc_object_alive( p_demux ) )
     {
-        block_t *p_pkt;
+        uint8_t buf[TS_PACKET_SIZE_MAX], *p_buffer = buf;
 
-        if( !( p_pkt = ReadTSPacket( p_demux ) ) )
+        if( !ReadTSPackets( p_demux, &p_buffer, 1 ) )
         {
             break;
         }
-        if( PIDGet( p_pkt ) == p_sys->i_pid_ref_pcr )
+        if( PIDGet( p_buffer ) == p_sys->i_pid_ref_pcr )
         {
-            i_pcr = GetPCR( p_pkt );
+            i_pcr = GetPCR( p_buffer );
         }
-        block_Release( p_pkt );
         if( i_pcr >= 0 )
             break;
         if( stream_Tell( p_demux->s ) >= i_last_pos )
@@ -2048,20 +2095,19 @@ static void GetFirstPCR( demux_t *p_demux )
 
     while( vlc_object_alive (p_demux) )
     {
-        block_t     *p_pkt;
+        uint8_t buf[TS_PACKET_SIZE_MAX], *p_buffer = buf;
 
-        if( !( p_pkt = ReadTSPacket( p_demux ) ) )
+        if( !ReadTSPackets( p_demux, &p_buffer, 1 ) )
         {
             break;
         }
-        mtime_t i_pcr = GetPCR( p_pkt );
+        mtime_t i_pcr = GetPCR( p_buffer );
         if( i_pcr >= 0 )
         {
-            p_sys->i_pid_ref_pcr = PIDGet( p_pkt );
+            p_sys->i_pid_ref_pcr = PIDGet( p_buffer );
             p_sys->i_first_pcr = i_pcr;
             p_sys->i_current_pcr = i_pcr;
         }
-        block_Release( p_pkt );
         if( p_sys->i_first_pcr >= 0 )
             break;
     }
@@ -2153,14 +2199,14 @@ static void CheckPCR( demux_t *p_demux )
     p_sys->i_current_pcr = i_initial_pcr;
 }
 
-static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
+static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, const uint8_t *p_buffer )
 {
     demux_sys_t   *p_sys = p_demux->p_sys;
 
     if( p_sys->i_pmt_es <= 0 )
         return;
 
-    mtime_t i_pcr = GetPCR( p_bk );
+    mtime_t i_pcr = GetPCR( p_buffer );
     if( i_pcr < 0 )
         return;
 
@@ -2198,9 +2244,9 @@ static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     }
 }
 
-static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
+static bool GatherData( demux_t *p_demux, ts_pid_t *pid, uint8_t *p_buffer )
 {
-    const uint8_t *p = p_bk->p_buffer;
+    const uint8_t *p = p_buffer;
     const bool b_unit_start = p[1]&0x40;
     const bool b_scrambled  = p[3]&0x80;
     const bool b_adaptation = p[3]&0x20;
@@ -2209,6 +2255,7 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     bool       b_discontinuity = false;  /* discontinuity */
 
     /* transport_scrambling_control is ignored */
+    int         i_buffer;
     int         i_skip = 0;
     bool        i_ret  = false;
 
@@ -2220,7 +2267,7 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
 
     /* For now, ignore additional error correction
      * TODO: handle Reed-Solomon 204,188 error correction */
-    p_bk->i_buffer = TS_PACKET_SIZE_188;
+    i_buffer = TS_PACKET_SIZE_188;
 
     if( p[1]&0x80 )
     {
@@ -2233,7 +2280,7 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     if( p_demux->p_sys->csa )
     {
         vlc_mutex_lock( &p_demux->p_sys->csa_lock );
-        csa_Decrypt( p_demux->p_sys->csa, p_bk->p_buffer, p_demux->p_sys->i_csa_pkt_size );
+        csa_Decrypt( p_demux->p_sys->csa, p_buffer, p_demux->p_sys->i_csa_pkt_size );
         vlc_mutex_unlock( &p_demux->p_sys->csa_lock );
     }
 
@@ -2299,11 +2346,10 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         }
     }
 
-    PCRHandle( p_demux, pid, p_bk );
+    PCRHandle( p_demux, pid, p_buffer );
 
     if( i_skip >= 188 || pid->es->id == NULL )
     {
-        block_Release( p_bk );
         return i_ret;
     }
 
@@ -2325,23 +2371,18 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     }
 
     /* We have to gather it */
-    p_bk->p_buffer += i_skip;
-    p_bk->i_buffer -= i_skip;
+    p_buffer += i_skip;
+    i_buffer -= i_skip;
 
     if( b_unit_start )
     {
-        if( pid->es->data_type == TS_ES_DATA_TABLE_SECTION && p_bk->i_buffer > 0 )
+        if( pid->es->data_type == TS_ES_DATA_TABLE_SECTION && i_buffer > 0 )
         {
-            int i_pointer_field = __MIN( p_bk->p_buffer[0], p_bk->i_buffer - 1 );
-            block_t *p = block_Duplicate( p_bk );
-            if( p )
-            {
-                p->i_buffer = i_pointer_field;
-                p->p_buffer++;
-                block_ChainLastAppend( &pid->es->pp_last, p );
-            }
-            p_bk->i_buffer -= 1 + i_pointer_field;
-            p_bk->p_buffer += 1 + i_pointer_field;
+            // TODO - why this branch is here ?
+            int i_pointer_field = __MIN( p_buffer[0], i_buffer - 1 );
+	    EsAppend( pid->es, p_buffer + 1, i_pointer_field );
+            i_buffer -= 1 + i_pointer_field;
+            p_buffer += 1 + i_pointer_field;
         }
         if( pid->es->p_data )
         {
@@ -2349,12 +2390,11 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
             i_ret = true;
         }
 
-        block_ChainLastAppend( &pid->es->pp_last, p_bk );
         if( pid->es->data_type == TS_ES_DATA_PES )
         {
-            if( p_bk->i_buffer > 6 )
+            if( i_buffer > 6 )
             {
-                pid->es->i_data_size = GetWBE( &p_bk->p_buffer[4] );
+                pid->es->i_data_size = GetWBE( &p_buffer[4] );
                 if( pid->es->i_data_size > 0 )
                 {
                     pid->es->i_data_size += 6;
@@ -2363,12 +2403,15 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         }
         else if( pid->es->data_type == TS_ES_DATA_TABLE_SECTION )
         {
-            if( p_bk->i_buffer > 3 && p_bk->p_buffer[0] != 0xff )
+            if( i_buffer > 3 && p_buffer[0] != 0xff )
             {
-                pid->es->i_data_size = 3 + (((p_bk->p_buffer[1] & 0xf) << 8) | p_bk->p_buffer[2]);
+                pid->es->i_data_size = 3 + (((p_buffer[1] & 0xf) << 8) | p_buffer[2]);
             }
         }
-        pid->es->i_data_gathered += p_bk->i_buffer;
+
+        // TODO: simplify, duplicate code
+        EsAppend( pid->es, p_buffer, i_buffer );
+        pid->es->i_data_gathered += i_buffer;
         if( pid->es->i_data_size > 0 &&
             pid->es->i_data_gathered >= pid->es->i_data_size )
         {
@@ -2381,12 +2424,12 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         if( pid->es->p_data == NULL )
         {
             /* msg_Dbg( p_demux, "broken packet" ); */
-            block_Release( p_bk );
         }
         else
         {
-            block_ChainLastAppend( &pid->es->pp_last, p_bk );
-            pid->es->i_data_gathered += p_bk->i_buffer;
+            // TODO: simplify, duplicate code
+            EsAppend( pid->es, p_buffer, i_buffer );
+            pid->es->i_data_gathered += i_buffer;
 
             if( pid->es->i_data_size > 0 &&
                 pid->es->i_data_gathered >= pid->es->i_data_size )
@@ -2491,6 +2534,7 @@ static int  IODDescriptorLength( int *pi_data, uint8_t **pp_data )
 
     } while( i_b&0x80 && *pi_data > 0 );
 
+    // warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if (i_len > *pi_data)
         i_len = *pi_data;
 
@@ -3520,7 +3564,7 @@ static void PMTSetupEsTeletext( demux_t *p_demux, ts_pid_t *pid,
                 p_es->p_data  = NULL;
                 p_es->i_data_size = 0;
                 p_es->i_data_gathered = 0;
-                p_es->pp_last = &p_es->p_data;
+                p_es->p_last  = NULL;
                 p_es->data_type = TS_ES_DATA_PES;
                 p_es->p_mpeg4desc = NULL;
 
@@ -3605,7 +3649,7 @@ static void PMTSetupEsDvbSubtitle( demux_t *p_demux, ts_pid_t *pid,
                 p_es->p_data   = NULL;
                 p_es->i_data_size = 0;
                 p_es->i_data_gathered = 0;
-                p_es->pp_last = &p_es->p_data;
+                p_es->p_last = NULL;
                 p_es->data_type = TS_ES_DATA_PES;
                 p_es->p_mpeg4desc = NULL;
 
-- 
1.9.1

