]> git.sesse.net Git - vlc/blobdiff - modules/demux/ts.c
Qt: EPGView: includes cleanup
[vlc] / modules / demux / ts.c
index 234a523b3f565c7d673332b4ff6b7a0743a96198..1374791429e54f6687908c85b41bc60a1ba235e8 100644 (file)
@@ -1,25 +1,25 @@
 /*****************************************************************************
  * ts.c: Transport Stream input module for VLC.
  *****************************************************************************
- * Copyright (C) 2004-2005 the VideoLAN team
+ * Copyright (C) 2004-2005 VLC authors and VideoLAN
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Jean-Paul Saman <jpsaman #_at_# m2x.nl>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -62,7 +62,7 @@
 # include <dvbpsi/tot.h>
 
 #undef TS_DEBUG
-static void ts_debug(const char *format, ...)
+VLC_FORMAT(1, 2) static void ts_debug(const char *format, ...)
 {
 #ifdef TS_DEBUG
     va_list ap;
@@ -235,17 +235,23 @@ typedef struct
 
 } ts_psi_t;
 
+typedef enum
+{
+    TS_ES_DATA_PES,
+    TS_ES_DATA_TABLE_SECTION
+} ts_es_data_type_t;
+
 typedef struct
 {
     es_format_t  fmt;
     es_out_id_t *id;
-    int         i_pes_size;
-    int         i_pes_gathered;
-    block_t     *p_pes;
+    ts_es_data_type_t data_type;
+    int         i_data_size;
+    int         i_data_gathered;
+    block_t     *p_data;
     block_t     **pp_last;
 
     es_mpeg4_descriptor_t *p_mpeg4desc;
-    int         b_gather;
 
 } ts_es_t;
 
@@ -348,7 +354,7 @@ static inline int PIDGet( block_t *p )
     return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
 }
 
-static bool GatherPES( 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 block_t* ReadTSPacket( demux_t *p_demux );
 static mtime_t GetPCR( block_t *p_pkt );
@@ -866,7 +872,7 @@ static int Demux( demux_t *p_demux )
             }
             else if( !p_sys->b_udp_out )
             {
-                b_frame = GatherPES( p_demux, p_pid, p_pkt );
+                b_frame = GatherData( p_demux, p_pid, p_pkt );
             }
             else
             {
@@ -1328,7 +1334,8 @@ static void PIDInit( ts_pid_t *pid, bool b_psi, ts_psi_t *p_owner )
             return;
 
         es_format_Init( &pid->es->fmt, UNKNOWN_ES, 0 );
-        pid->es->pp_last = &pid->es->p_pes;
+        pid->es->data_type = TS_ES_DATA_PES;
+        pid->es->pp_last = &pid->es->p_data;
     }
 }
 
@@ -1360,8 +1367,8 @@ static void PIDClean( demux_t *p_demux, ts_pid_t *pid )
             p_sys->i_pmt_es--;
         }
 
-        if( pid->es->p_pes )
-            block_ChainRelease( pid->es->p_pes );
+        if( pid->es->p_data )
+            block_ChainRelease( pid->es->p_data );
 
         es_format_Clean( &pid->es->fmt );
 
@@ -1375,8 +1382,8 @@ static void PIDClean( demux_t *p_demux, ts_pid_t *pid )
                 p_sys->i_pmt_es--;
             }
 
-            if( pid->extra_es[i]->p_pes )
-                block_ChainRelease( pid->extra_es[i]->p_pes );
+            if( pid->extra_es[i]->p_data )
+                block_ChainRelease( pid->extra_es[i]->p_data );
 
             es_format_Clean( &pid->extra_es[i]->fmt );
 
@@ -1392,9 +1399,8 @@ static void PIDClean( demux_t *p_demux, ts_pid_t *pid )
 /****************************************************************************
  * gathering stuff
  ****************************************************************************/
-static void ParsePES( demux_t *p_demux, ts_pid_t *pid )
+static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
 {
-    block_t *p_pes = pid->es->p_pes;
     uint8_t header[34];
     unsigned i_pes_size = 0;
     unsigned i_skip = 0;
@@ -1402,12 +1408,6 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid )
     mtime_t i_pts = -1;
     mtime_t i_length = 0;
 
-    /* remove the pes from pid */
-    pid->es->p_pes = NULL;
-    pid->es->i_pes_size= 0;
-    pid->es->i_pes_gathered= 0;
-    pid->es->pp_last = &pid->es->p_pes;
-
     /* FIXME find real max size */
     /* const int i_max = */ block_ChainExtract( p_pes, header, 34 );
 
@@ -1618,6 +1618,78 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid )
     }
 }
 
+static void ParseTableSection( demux_t *p_demux, ts_pid_t *pid, block_t *p_data )
+{
+    block_t *p_content = block_ChainGather( p_data );
+    mtime_t i_date = -1;
+    for( int i = 0; pid->p_owner && i < pid->p_owner->i_prg; i++ )
+    {
+        if( pid->i_owner_number == pid->p_owner->prg[i]->i_number )
+        {
+            i_date = pid->p_owner->prg[i]->i_pcr_value;
+            if( i_date >= 0 )
+                break;
+        }
+    }
+    if( i_date >= 0 )
+    {
+        if( pid->es->fmt.i_codec == VLC_CODEC_SCTE_27 )
+        {
+            /* We need to extract the truncated pts stored inside the payload */
+            if( p_content->i_buffer > 9 && p_content->p_buffer[0] == 0xc6 )
+            {
+                int i_index = 0;
+                int i_offset = 4;
+                if( p_content->p_buffer[3] & 0x40 )
+                {
+                    i_index = ((p_content->p_buffer[7] & 0x0f) << 8) |
+                              p_content->p_buffer[8];
+                    i_offset = 9;
+                }
+                if( i_index == 0 && p_content->i_buffer > i_offset + 8 )
+                {
+                    bool is_immediate = p_content->p_buffer[i_offset + 3] & 0x40;
+                    if( !is_immediate )
+                    {
+                        mtime_t i_display_in = GetDWBE( &p_content->p_buffer[i_offset + 4] );
+                        if( i_display_in < i_date )
+                            i_date = i_display_in + (1ll << 32);
+                        else
+                            i_date = i_display_in;
+                    }
+
+                }
+            }
+        }
+        p_content->i_dts =
+        p_content->i_pts = VLC_TS_0 + i_date * 100 / 9;
+    }
+    es_out_Send( p_demux->out, pid->es->id, p_content );
+}
+static void ParseData( demux_t *p_demux, ts_pid_t *pid )
+{
+    block_t *p_data = pid->es->p_data;
+
+    /* remove the pes from 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;
+
+    if( pid->es->data_type == TS_ES_DATA_PES )
+    {
+        ParsePES( p_demux, pid, p_data );
+    }
+    else if( pid->es->data_type == TS_ES_DATA_TABLE_SECTION )
+    {
+        ParseTableSection( p_demux, pid, p_data );
+    }
+    else
+    {
+        block_ChainRelease( p_data );
+    }
+}
+
 static block_t* ReadTSPacket( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
@@ -1944,31 +2016,25 @@ static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         return;
 
     mtime_t i_pcr = GetPCR( p_bk );
-    if( i_pcr >= 0 )
-    {
-        if( p_sys->i_pid_ref_pcr == pid->i_pid )
-        {
-            p_sys->i_current_pcr = AdjustPCRWrapAround( p_demux, i_pcr );
-        }
+    if( i_pcr < 0 )
+        return;
 
-        /* Search program and set the PCR */
-        for( int i = 0; i < p_sys->i_pmt; i++ )
-        {
-            for( int i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
+    if( p_sys->i_pid_ref_pcr == pid->i_pid )
+        p_sys->i_current_pcr = AdjustPCRWrapAround( p_demux, i_pcr );
+
+    /* Search program and set the PCR */
+    for( int i = 0; i < p_sys->i_pmt; i++ )
+        for( int i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
+            if( pid->i_pid == p_sys->pmt[i]->psi->prg[i_prg]->i_pid_pcr )
             {
-                if( pid->i_pid == p_sys->pmt[i]->psi->prg[i_prg]->i_pid_pcr )
-                {
-                    p_sys->pmt[i]->psi->prg[i_prg]->i_pcr_value = i_pcr;
-                    es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
-                                    (int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,
-                                    (int64_t)(VLC_TS_0 + i_pcr * 100 / 9) );
-                }
+                p_sys->pmt[i]->psi->prg[i_prg]->i_pcr_value = i_pcr;
+                es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
+                                (int)p_sys->pmt[i]->psi->prg[i_prg]->i_number,
+                                (int64_t)(VLC_TS_0 + i_pcr * 100 / 9) );
             }
-        }
-    }
 }
 
-static bool GatherPES( 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 )
 {
     const uint8_t *p = p_bk->p_buffer;
     const bool b_unit_start = p[1]&0x40;
@@ -1996,8 +2062,8 @@ static bool GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     {
         msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",
                  pid->i_pid );
-        if( pid->es->p_pes ) //&& pid->es->fmt.i_cat == VIDEO_ES )
-            pid->es->p_pes->i_flags |= BLOCK_FLAG_CORRUPTED;
+        if( pid->es->p_data ) //&& pid->es->fmt.i_cat == VIDEO_ES )
+            pid->es->p_data->i_flags |= BLOCK_FLAG_CORRUPTED;
     }
 
     if( p_demux->p_sys->csa )
@@ -2021,11 +2087,11 @@ static bool GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         {
             /* discontinuity indicator found in stream */
             b_discontinuity = (p[5]&0x80) ? true : false;
-            if( b_discontinuity && pid->es->p_pes )
+            if( b_discontinuity && pid->es->p_data )
             {
                 msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
                             pid->i_pid );
-                /* pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY; */
+                /* pid->es->p_data->i_flags |= BLOCK_FLAG_DISCONTINUITY; */
             }
 #if 0
             if( p[5]&0x40 )
@@ -2060,11 +2126,11 @@ static bool GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
                       i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
 
             pid->i_cc = i_cc;
-            if( pid->es->p_pes && pid->es->fmt.i_cat != VIDEO_ES )
+            if( pid->es->p_data && pid->es->fmt.i_cat != VIDEO_ES )
             {
                 /* Small video artifacts are usually better than
                  * dropping full frames */
-                pid->es->p_pes->i_flags |= BLOCK_FLAG_CORRUPTED;
+                pid->es->p_data->i_flags |= BLOCK_FLAG_CORRUPTED;
             }
         }
     }
@@ -2100,32 +2166,55 @@ static bool GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
 
     if( b_unit_start )
     {
-        if( pid->es->p_pes )
+        if( pid->es->data_type == TS_ES_DATA_TABLE_SECTION && p_bk->i_buffer > 0 )
         {
-            ParsePES( p_demux, pid );
+            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;
+        }
+        if( pid->es->p_data )
+        {
+            ParseData( p_demux, pid );
             i_ret = true;
         }
 
         block_ChainLastAppend( &pid->es->pp_last, p_bk );
-        if( p_bk->i_buffer > 6 )
+        if( pid->es->data_type == TS_ES_DATA_PES )
         {
-            pid->es->i_pes_size = GetWBE( &p_bk->p_buffer[4] );
-            if( pid->es->i_pes_size > 0 )
+            if( p_bk->i_buffer > 6 )
             {
-                pid->es->i_pes_size += 6;
+                pid->es->i_data_size = GetWBE( &p_bk->p_buffer[4] );
+                if( pid->es->i_data_size > 0 )
+                {
+                    pid->es->i_data_size += 6;
+                }
             }
         }
-        pid->es->i_pes_gathered += p_bk->i_buffer;
-        if( pid->es->i_pes_size > 0 &&
-            pid->es->i_pes_gathered >= pid->es->i_pes_size )
+        else if( pid->es->data_type == TS_ES_DATA_TABLE_SECTION )
         {
-            ParsePES( p_demux, pid );
+            if( p_bk->i_buffer > 3 && p_bk->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_gathered += p_bk->i_buffer;
+        if( pid->es->i_data_size > 0 &&
+            pid->es->i_data_gathered >= pid->es->i_data_size )
+        {
+            ParseData( p_demux, pid );
             i_ret = true;
         }
     }
     else
     {
-        if( pid->es->p_pes == NULL )
+        if( pid->es->p_data == NULL )
         {
             /* msg_Dbg( p_demux, "broken packet" ); */
             block_Release( p_bk );
@@ -2133,11 +2222,12 @@ static bool GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         else
         {
             block_ChainLastAppend( &pid->es->pp_last, p_bk );
-            pid->es->i_pes_gathered += p_bk->i_buffer;
-            if( pid->es->i_pes_size > 0 &&
-                pid->es->i_pes_gathered >= pid->es->i_pes_size )
+            pid->es->i_data_gathered += p_bk->i_buffer;
+
+            if( pid->es->i_data_size > 0 &&
+                pid->es->i_data_gathered >= pid->es->i_data_size )
             {
-                ParsePES( p_demux, pid );
+                ParseData( p_demux, pid );
                 i_ret = true;
             }
         }
@@ -2167,7 +2257,6 @@ static void PIDFillFormat( ts_es_t *es, int i_stream_type )
         break;
     case 0x10:  /* MPEG4 (video) */
         es_format_Init( fmt, VIDEO_ES, VLC_CODEC_MP4V );
-        es->b_gather = true;
         break;
     case 0x1B:  /* H264 <- check transport syntax/needed descriptor */
         es_format_Init( fmt, VIDEO_ES, VLC_CODEC_H264 );
@@ -2179,8 +2268,9 @@ static void PIDFillFormat( ts_es_t *es, int i_stream_type )
     case 0x81:  /* A52 (audio) */
         es_format_Init( fmt, AUDIO_ES, VLC_CODEC_A52 );
         break;
-    case 0x82:  /* DVD_SPU (sub) */
-        es_format_Init( fmt, SPU_ES, VLC_CODEC_SPU );
+    case 0x82:  /* SCTE-27 (sub) */
+        es_format_Init( fmt, SPU_ES, VLC_CODEC_SCTE_27 );
+        es->data_type = TS_ES_DATA_TABLE_SECTION;
         break;
     case 0x83:  /* LPCM (audio) */
         es_format_Init( fmt, AUDIO_ES, VLC_CODEC_DVD_LPCM );
@@ -2208,7 +2298,6 @@ static void PIDFillFormat( ts_es_t *es, int i_stream_type )
 
     case 0xa0:  /* MSCODEC vlc (video) (fixed later) */
         es_format_Init( fmt, UNKNOWN_ES, 0 );
-        es->b_gather = true;
         break;
 
     case 0x06:  /* PES_PRIVATE  (fixed later) */
@@ -2504,6 +2593,13 @@ static char *EITConvertToUTF8( const unsigned char *psz_instring,
                                size_t i_length,
                                bool b_broken )
 {
+    /* Deal with no longer broken providers (no switch byte
+      but sending ISO_8859-1 instead of ISO_6937) without
+      removing them from the broken providers table
+      (keep the entry for correctly handling recorded TS).
+    */
+    b_broken = b_broken && i_length && *psz_instring > 0x20;
+
     if( b_broken )
         return FromCharset( "ISO_8859-1", psz_instring, i_length );
     return vlc_from_EIT( psz_instring, i_length );
@@ -3095,7 +3191,6 @@ static void PMTSetupEsTeletext( demux_t *p_demux, ts_pid_t *pid,
     }
 #endif
 
-#ifdef _DVBPSI_DR_59_H_
     dvbpsi_descriptor_t *p_dr = PMTEsFindDescriptor( p_es, 0x59 );
     if( p_dr )
     {
@@ -3127,7 +3222,6 @@ static void PMTSetupEsTeletext( demux_t *p_demux, ts_pid_t *pid,
             memcpy( p_dst->p_iso639, p_src->i_iso6392_language_code, 3 );
         }
     }
-#endif
 
     /* */
     es_format_Init( p_fmt, SPU_ES, VLC_CODEC_TELETEXT );
@@ -3178,12 +3272,12 @@ static void PMTSetupEsTeletext( demux_t *p_demux, ts_pid_t *pid,
                 p_es->fmt.psz_description = NULL;
 
                 p_es->id      = NULL;
-                p_es->p_pes   = NULL;
-                p_es->i_pes_size = 0;
-                p_es->i_pes_gathered = 0;
-                p_es->pp_last = &p_es->p_pes;
+                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->data_type = TS_ES_DATA_PES;
                 p_es->p_mpeg4desc = NULL;
-                p_es->b_gather = false;
 
                 TAB_APPEND( pid->i_extra_es, pid->extra_es, p_es );
             }
@@ -3213,7 +3307,6 @@ static void PMTSetupEsDvbSubtitle( demux_t *p_demux, ts_pid_t *pid,
 
     dvbpsi_descriptor_t *p_dr = PMTEsFindDescriptor( p_es, 0x59 );
     int i_page = 0;
-#ifdef _DVBPSI_DR_59_H_
     dvbpsi_subtitling_dr_t *p_sub = dvbpsi_DecodeSubtitlingDr( p_dr );
     for( int i = 0; p_sub && i < p_sub->i_subtitles_number; i++ )
     {
@@ -3222,7 +3315,6 @@ static void PMTSetupEsDvbSubtitle( demux_t *p_demux, ts_pid_t *pid,
             ( i_type >= 0x20 && i_type <= 0x24 ) )
             i_page++;
     }
-#endif
 
     if( !p_demux->p_sys->b_split_es  || i_page <= 0 )
     {
@@ -3242,7 +3334,6 @@ static void PMTSetupEsDvbSubtitle( demux_t *p_demux, ts_pid_t *pid,
     }
     else
     {
-#ifdef _DVBPSI_DR_59_H_
         for( int i = 0; i < p_sub->i_subtitles_number; i++ )
         {
             ts_es_t *p_es;
@@ -3265,12 +3356,12 @@ static void PMTSetupEsDvbSubtitle( demux_t *p_demux, ts_pid_t *pid,
                 p_es->fmt.psz_description = NULL;
 
                 p_es->id      = NULL;
-                p_es->p_pes   = NULL;
-                p_es->i_pes_size = 0;
-                p_es->i_pes_gathered = 0;
-                p_es->pp_last = &p_es->p_pes;
+                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->data_type = TS_ES_DATA_PES;
                 p_es->p_mpeg4desc = NULL;
-                p_es->b_gather = false;
 
                 TAB_APPEND( pid->i_extra_es, pid->extra_es, p_es );
             }
@@ -3302,7 +3393,6 @@ static void PMTSetupEsDvbSubtitle( demux_t *p_demux, ts_pid_t *pid,
             p_es->fmt.subs.dvb.i_id = ( p->i_composition_page_id <<  0 ) |
                                       ( p->i_ancillary_page_id   << 16 );
         }
-#endif
     }
 }
 static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
@@ -3343,7 +3433,6 @@ static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
         /* Subtitle/Teletext/VBI fallbacks */
         dvbpsi_descriptor_t *p_dr = PMTEsFindDescriptor( p_es, 0x59 );
 
-#ifdef _DVBPSI_DR_59_H_
         dvbpsi_subtitling_dr_t *p_sub;
         if( p_dr && ( p_sub = dvbpsi_DecodeSubtitlingDr( p_dr ) ) )
         {
@@ -3378,10 +3467,7 @@ static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
                 }
             }
         }
-#else
-        if( p_fmt->i_cat == UNKNOWN_ES && p_dr )
-            PMTSetupEsDvbSubtitle( p_demux, pid, p_es );
-#endif
+
         if( p_fmt->i_cat == UNKNOWN_ES &&
             ( PMTEsFindDescriptor( p_es, 0x45 ) ||  /* VBI Data descriptor */
               PMTEsFindDescriptor( p_es, 0x46 ) ||  /* VBI Teletext descriptor */
@@ -3392,7 +3478,6 @@ static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
         }
     }
 
-#ifdef _DVBPSI_DR_52_H_
     /* FIXME is it useful ? */
     if( PMTEsFindDescriptor( p_es, 0x52 ) )
     {
@@ -3401,7 +3486,6 @@ static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
 
         msg_Dbg( p_demux, "    * Stream Component Identifier: %d", p_si->i_component_tag );
     }
-#endif
 }
 
 static void PMTSetupEs0xEA( demux_t *p_demux, ts_pid_t *pid,
@@ -3562,7 +3646,7 @@ static char *GetAudioTypeDesc(demux_t *p_demux, int type)
     if (type < 0 || type > 3)
         msg_Dbg( p_demux, "unknown audio type: %d", type);
     else if (type > 0)
-        return strdup(audio_type[type - 1]);
+        return strdup(audio_type[type]);
 
     return NULL;
 }
@@ -3970,16 +4054,17 @@ static void PATCallBack( void *data, dvbpsi_pat_t *p_pat )
         /* Delete PMT pid */
         for( int i = 0; i < i_pmt_rm; i++ )
         {
-            SetPIDFilter( p_demux, pmt_rm[i]->i_pid, false );
+            ts_pid_t *pid = pmt_rm[i];
+            SetPIDFilter( p_demux, pid->i_pid, false );
 
-            for( int i_prg = 0; i_prg < pmt_rm[i]->psi->i_prg; i_prg++ )
+            for( int i_prg = 0; i_prg < pid->psi->i_prg; i_prg++ )
             {
-                const int i_number = pmt_rm[i]->psi->prg[i_prg]->i_number;
+                const int i_number = pid->psi->prg[i_prg]->i_number;
                 es_out_Control( p_demux->out, ES_OUT_DEL_GROUP, i_number );
             }
 
-            PIDClean( p_demux, &p_sys->pid[pmt_rm[i]->i_pid] );
-            TAB_REMOVE( p_sys->i_pmt, p_sys->pmt, pmt_rm[i] );
+            PIDClean( p_demux, &p_sys->pid[pid->i_pid] );
+            TAB_REMOVE( p_sys->i_pmt, p_sys->pmt, pid );
         }
 
         free( pmt_rm );