[vlc-devel] [PATCH 2/2] demux/ts: access/dtv: pass private CA using capmt struct

Francois Cartegnie fcvlcdev at free.fr
Wed Mar 30 17:55:21 CEST 2016


Removes access dependency on libdvbpsi and avoids
taking ownership of ts's dvbpsi pmt structs.

Refactors descriptors copy/filtering. Fixes some const/signedness.
---
 modules/access/Makefile.am   |  10 +-
 modules/access/dtv/access.c  |   5 +-
 modules/access/dtv/dtv.h     |   6 +-
 modules/access/dtv/en50221.c | 257 +++++++++++++++++--------------------------
 modules/access/dtv/en50221.h |   4 +-
 modules/access/dtv/linux.c   |  20 +---
 modules/demux/Makefile.am    |   1 +
 modules/demux/mpeg/ts_psi.c  |  55 +++++++--
 8 files changed, 166 insertions(+), 192 deletions(-)

diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am
index fa23bd8..77ca351 100644
--- a/modules/access/Makefile.am
+++ b/modules/access/Makefile.am
@@ -311,13 +311,11 @@ libdtv_plugin_la_SOURCES = \
 libdtv_plugin_la_CFLAGS = $(AM_CFLAGS)
 
 if HAVE_LINUX_DVB
-libdtv_plugin_la_SOURCES += access/dtv/linux.c
+libdtv_plugin_la_SOURCES += access/dtv/linux.c \
+                            access/dtv/en50221.c \
+                            access/dtv/en50221.h \
+                            access/dtv/en50221_capmt.h
 libdtv_plugin_la_CFLAGS += -DHAVE_LINUX_DVB
-if HAVE_DVBPSI
-libdtv_plugin_la_SOURCES += access/dtv/en50221.c access/dtv/en50221.h mux/mpeg/dvbpsi_compat.h
-libdtv_plugin_la_CFLAGS += -DHAVE_DVBPSI $(DVBPSI_CFLAGS)
-libdtv_plugin_la_LIBADD = $(DVBPSI_LIBS)
-endif
 access_LTLIBRARIES += libdtv_plugin.la
 endif
 
diff --git a/modules/access/dtv/access.c b/modules/access/dtv/access.c
index a370536..bfd0da7 100644
--- a/modules/access/dtv/access.c
+++ b/modules/access/dtv/access.c
@@ -576,15 +576,14 @@ static int Control (access_t *access, int query, va_list args)
             break;
         }
 
-#ifdef HAVE_DVBPSI
         case ACCESS_SET_PRIVATE_ID_CA:
         {
-            struct dvbpsi_pmt_s *pmt = va_arg (args, struct dvbpsi_pmt_s *);
+            en50221_capmt_info_t *pmt = va_arg (args, en50221_capmt_info_t *);
 
             dvb_set_ca_pmt (dev, pmt);
             break;
         }
-#endif
+
         case ACCESS_GET_PRIVATE_ID_STATE:
         {
             unsigned pid = va_arg (args, int);
diff --git a/modules/access/dtv/dtv.h b/modules/access/dtv/dtv.h
index b940bf1..aecd5d7 100644
--- a/modules/access/dtv/dtv.h
+++ b/modules/access/dtv/dtv.h
@@ -56,10 +56,8 @@ unsigned dvb_enum_systems (dvb_device_t *);
 float dvb_get_signal_strength (dvb_device_t *);
 float dvb_get_snr (dvb_device_t *);
 
-#ifdef HAVE_DVBPSI
-struct dvbpsi_pmt_s;
-void dvb_set_ca_pmt (dvb_device_t *, struct dvbpsi_pmt_s *);
-#endif
+typedef struct en50221_capmt_info_s en50221_capmt_info_t;
+void dvb_set_ca_pmt (dvb_device_t *, en50221_capmt_info_t *);
 
 int dvb_set_inversion (dvb_device_t *, int);
 int dvb_tune (dvb_device_t *);
diff --git a/modules/access/dtv/en50221.c b/modules/access/dtv/en50221.c
index 6ecd641..69cefa2 100644
--- a/modules/access/dtv/en50221.c
+++ b/modules/access/dtv/en50221.c
@@ -41,16 +41,6 @@
 /* DVB Card Drivers */
 #include <linux/dvb/ca.h>
 
-/* Include dvbpsi headers */
-# include <dvbpsi/dvbpsi.h>
-# include <dvbpsi/descriptor.h>
-# include <dvbpsi/pat.h>
-# include <dvbpsi/pmt.h>
-# include <dvbpsi/dr.h>
-# include <dvbpsi/psi.h>
-# include <dvbpsi/demux.h>
-# include <dvbpsi/sdt.h>
-
 #undef ENABLE_HTTPD
 #ifdef ENABLE_HTTPD
 #   include <vlc_httpd.h>
@@ -58,8 +48,7 @@
 
 #include "../demux/dvb-text.h"
 #include "dtv/en50221.h"
-
-#include "../mux/mpeg/dvbpsi_compat.h"
+#include "dtv/en50221_capmt.h"
 
 typedef struct en50221_session_t
 {
@@ -139,7 +128,7 @@ struct cam
     bool pb_slot_mmi_undisplayed[MAX_CI_SLOTS];
     en50221_session_t p_sessions[MAX_SESSIONS];
 
-    dvbpsi_pmt_t *pp_selected_programs[MAX_PROGRAMS];
+    en50221_capmt_info_t *pp_selected_programs[MAX_PROGRAMS];
     int i_selected_programs;
 };
 
@@ -816,7 +805,7 @@ static uint8_t *APDUGetLength( uint8_t *p_apdu, int *pi_size )
  * APDUSend
  *****************************************************************************/
 static int APDUSend( cam_t * p_cam, int i_session_id, int i_tag,
-                     uint8_t *p_data, int i_size )
+                     uint8_t *p_data, size_t i_size )
 {
     uint8_t *p_apdu = xmalloc( i_size + 12 );
     uint8_t *p = p_apdu;
@@ -1046,7 +1035,7 @@ typedef struct
     uint16_t pi_system_ids[MAX_CASYSTEM_IDS + 1];
 } system_ids_t;
 
-static bool CheckSystemID( system_ids_t *p_ids, uint16_t i_id )
+static bool CheckSystemID( const system_ids_t *p_ids, uint16_t i_id )
 {
     int i = 0;
     if( !p_ids ) return true;      /* dummy session for high-level CI intf */
@@ -1064,29 +1053,15 @@ static bool CheckSystemID( system_ids_t *p_ids, uint16_t i_id )
 /*****************************************************************************
  * CAPMTNeedsDescrambling
  *****************************************************************************/
-static bool CAPMTNeedsDescrambling( dvbpsi_pmt_t *p_pmt )
+static bool CAPMTNeedsDescrambling( const en50221_capmt_info_t *p_info )
 {
-    dvbpsi_descriptor_t *p_dr;
-    dvbpsi_pmt_es_t *p_es;
+    if( p_info->p_program_descriptors )
+        return true;
 
-    for( p_dr = p_pmt->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
+    for( size_t i=0; i<p_info->i_es_count; i++ )
     {
-        if( p_dr->i_tag == 0x9 )
-        {
+        if( p_info->p_es[i].p_descriptors )
             return true;
-        }
-    }
- 
-    for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
-    {
-        for( p_dr = p_es->p_first_descriptor; p_dr != NULL;
-             p_dr = p_dr->p_next )
-        {
-            if( p_dr->i_tag == 0x9 )
-            {
-                return true;
-            }
-        }
     }
 
     return false;
@@ -1095,29 +1070,36 @@ static bool CAPMTNeedsDescrambling( dvbpsi_pmt_t *p_pmt )
 /*****************************************************************************
  * CAPMTBuild
  *****************************************************************************/
-static int GetCADSize( system_ids_t *p_ids, dvbpsi_descriptor_t *p_dr )
+static size_t CopyDescriptors( const uint8_t *p_drdata, size_t i_drdata,
+                               const system_ids_t *p_ids, uint8_t *p_dest )
 {
-    int i_cad_size = 0;
-
-    while ( p_dr != NULL )
+    size_t i_total = 0;
+    while( i_drdata > 0 )
     {
-        if( p_dr->i_tag == 0x9 )
+        assert( p_drdata[0] == 0x09 );
+        uint8_t i_dr_len = p_drdata[1];
+        uint16_t i_sysid = GetWBE( &p_drdata[2] );
+        if( CheckSystemID( p_ids, i_sysid ) )
         {
-            uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
-                                    | p_dr->p_data[1];
-            if ( CheckSystemID( p_ids, i_sysid ) )
-                i_cad_size += p_dr->i_length + 2;
+            if( p_dest ) /* if p_dest is NULL, just count required space */
+                memcpy( &p_dest[i_total], p_drdata, (size_t) i_dr_len + 2 );
+            i_total += i_dr_len + 2;
         }
-        p_dr = p_dr->p_next;
+        i_drdata = i_drdata - i_dr_len - 2;
+        p_drdata += i_dr_len + 2;
     }
+    return i_total;
+}
 
-    return i_cad_size;
+static size_t GetCADSize( const system_ids_t *p_ids,
+                          const uint8_t *p_drdata, size_t i_drdata )
+{
+    return CopyDescriptors( p_drdata, i_drdata, p_ids, NULL );
 }
 
-static uint8_t *CAPMTHeader( system_ids_t *p_ids, uint8_t i_list_mgt,
-                             uint16_t i_program_number, uint8_t i_version,
-                             int i_size, dvbpsi_descriptor_t *p_dr,
-                             uint8_t i_cmd )
+static uint8_t *CAPMTHeader( const en50221_capmt_info_t *p_info,
+                             const system_ids_t *p_ids, uint8_t i_list_mgt,
+                             size_t i_size, uint8_t i_cmd )
 {
     uint8_t *p_data;
 
@@ -1127,36 +1109,19 @@ static uint8_t *CAPMTHeader( system_ids_t *p_ids, uint8_t i_list_mgt,
         p_data = xmalloc( 6 );
 
     p_data[0] = i_list_mgt;
-    p_data[1] = i_program_number >> 8;
-    p_data[2] = i_program_number & 0xff;
-    p_data[3] = ((i_version & 0x1f) << 1) | 0x1;
+    p_data[1] = p_info->i_program_number >> 8;
+    p_data[2] = p_info->i_program_number & 0xff;
+    p_data[3] = ((p_info->i_version & 0x1f) << 1) | 0x1;
 
     if ( i_size )
     {
-        int i;
-
         p_data[4] = (i_size + 1) >> 8;
         p_data[5] = (i_size + 1) & 0xff;
         p_data[6] = i_cmd;
-        i = 7;
 
-        while ( p_dr != NULL )
-        {
-            if( p_dr->i_tag == 0x9 )
-            {
-                uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
-                                    | p_dr->p_data[1];
-                if ( CheckSystemID( p_ids, i_sysid ) )
-                {
-                    p_data[i] = 0x9;
-                    p_data[i + 1] = p_dr->i_length;
-                    memcpy( &p_data[i + 2], p_dr->p_data, p_dr->i_length );
-//                    p_data[i+4] &= 0x1f;
-                    i += p_dr->i_length + 2;
-                }
-            }
-            p_dr = p_dr->p_next;
-        }
+        CopyDescriptors( p_info->p_program_descriptors,
+                         p_info->i_program_descriptors,
+                         p_ids, &p_data[7] );
     }
     else
     {
@@ -1167,101 +1132,87 @@ static uint8_t *CAPMTHeader( system_ids_t *p_ids, uint8_t i_list_mgt,
     return p_data;
 }
 
-static uint8_t *CAPMTES( system_ids_t *p_ids, uint8_t *p_capmt,
-                         int i_capmt_size, uint8_t i_type, uint16_t i_pid,
-                         int i_size, dvbpsi_descriptor_t *p_dr,
-                         uint8_t i_cmd )
+static uint8_t *CAPMTES( const en50221_capmt_es_info_t *p_es,
+                         const system_ids_t *p_ids,
+                         size_t i_capmt_size, size_t i_size,
+                         uint8_t i_cmd, uint8_t *p_capmt )
 {
     uint8_t *p_data;
-    int i;
- 
+
     if ( i_size )
         p_data = xrealloc( p_capmt, i_capmt_size + 6 + i_size );
     else
         p_data = xrealloc( p_capmt, i_capmt_size + 5 );
 
-    i = i_capmt_size;
+    uint8_t *p_dest = &p_data[ i_capmt_size ];
 
-    p_data[i] = i_type;
-    p_data[i + 1] = i_pid >> 8;
-    p_data[i + 2] = i_pid & 0xff;
+    p_dest[0] = p_es->i_stream_type;
+    p_dest[1] = p_es->i_es_pid >> 8;
+    p_dest[2] = p_es->i_es_pid & 0xff;
 
     if ( i_size )
     {
-        p_data[i + 3] = (i_size + 1) >> 8;
-        p_data[i + 4] = (i_size + 1) & 0xff;
-        p_data[i + 5] = i_cmd;
-        i += 6;
+        p_dest[3] = (i_size + 1) >> 8;
+        p_dest[4] = (i_size + 1) & 0xff;
+        p_dest[5] = i_cmd;
 
-        while ( p_dr != NULL )
-        {
-            if( p_dr->i_tag == 0x9 )
-            {
-                uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
-                                    | p_dr->p_data[1];
-                if ( CheckSystemID( p_ids, i_sysid ) )
-                {
-                    p_data[i] = 0x9;
-                    p_data[i + 1] = p_dr->i_length;
-                    memcpy( &p_data[i + 2], p_dr->p_data, p_dr->i_length );
-                    i += p_dr->i_length + 2;
-                }
-            }
-            p_dr = p_dr->p_next;
-        }
+        CopyDescriptors( p_es->p_descriptors,
+                         p_es->i_descriptors,
+                         p_ids, &p_dest[6] );
     }
     else
     {
-        p_data[i + 3] = 0;
-        p_data[i + 4] = 0;
+        p_dest[3] = 0;
+        p_dest[4] = 0;
     }
 
     return p_data;
 }
 
 static uint8_t *CAPMTBuild( cam_t * p_cam, int i_session_id,
-                            dvbpsi_pmt_t *p_pmt, uint8_t i_list_mgt,
-                            uint8_t i_cmd, int *restrict pi_capmt_size )
+                            const en50221_capmt_info_t *p_info,
+                            uint8_t i_list_mgt,
+                            uint8_t i_cmd, size_t *restrict pi_capmt_size )
 {
     system_ids_t *p_ids =
         (system_ids_t *)p_cam->p_sessions[i_session_id - 1].p_sys;
-    dvbpsi_pmt_es_t *p_es;
-    int i_cad_size, i_cad_program_size;
+    size_t i_cad_size, i_cad_program_size;
     uint8_t *p_capmt;
 
-    i_cad_size = i_cad_program_size =
-            GetCADSize( p_ids, p_pmt->p_first_descriptor );
-    for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
+    i_cad_size = i_cad_program_size = GetCADSize( p_ids,
+                                                  p_info->p_program_descriptors,
+                                                  p_info->i_program_descriptors );
+    for( size_t i=0; i < p_info->i_es_count; i++ )
     {
-        i_cad_size += GetCADSize( p_ids, p_es->p_first_descriptor );
+        const en50221_capmt_es_info_t *p_es = &p_info->p_es[i];
+        i_cad_size += GetCADSize( p_ids, p_es->p_descriptors, p_es->i_descriptors );
     }
 
     if ( !i_cad_size )
     {
         msg_Warn( p_cam->obj,
                   "no compatible scrambling system for SID %d on session %d",
-                  p_pmt->i_program_number, i_session_id );
+                  p_info->i_program_number, i_session_id );
         return NULL;
     }
 
-    p_capmt = CAPMTHeader( p_ids, i_list_mgt, p_pmt->i_program_number,
-                           p_pmt->i_version, i_cad_program_size,
-                           p_pmt->p_first_descriptor, i_cmd );
+    p_capmt = CAPMTHeader( p_info, p_ids, i_list_mgt,
+                           i_cad_program_size, i_cmd );
 
     if ( i_cad_program_size )
         *pi_capmt_size = 7 + i_cad_program_size;
     else
         *pi_capmt_size = 6;
 
-    for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
+    for( size_t i=0; i < p_info->i_es_count; i++ )
     {
-        i_cad_size = GetCADSize( p_ids, p_es->p_first_descriptor );
+        const en50221_capmt_es_info_t *p_es = &p_info->p_es[i];
+        i_cad_size = GetCADSize( p_ids, p_es->p_descriptors, p_es->i_descriptors );
 
         if ( i_cad_size || i_cad_program_size )
         {
-            p_capmt = CAPMTES( p_ids, p_capmt, *pi_capmt_size, p_es->i_type,
-                               p_es->i_pid, i_cad_size,
-                               p_es->p_first_descriptor, i_cmd );
+            p_capmt = CAPMTES( p_es, p_ids, *pi_capmt_size, i_cad_size,
+                               i_cmd, p_capmt );
             if ( i_cad_size )
                 *pi_capmt_size += 6 + i_cad_size;
             else
@@ -1276,15 +1227,15 @@ static uint8_t *CAPMTBuild( cam_t * p_cam, int i_session_id,
  * CAPMTFirst
  *****************************************************************************/
 static void CAPMTFirst( cam_t * p_cam, int i_session_id,
-                        dvbpsi_pmt_t *p_pmt )
+                        const en50221_capmt_info_t *p_info )
 {
     uint8_t *p_capmt;
-    int i_capmt_size;
+    size_t i_capmt_size;
 
     msg_Dbg( p_cam->obj, "adding first CAPMT for SID %d on session %d",
-             p_pmt->i_program_number, i_session_id );
+             p_info->i_program_number, i_session_id );
 
-    p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
+    p_capmt = CAPMTBuild( p_cam, i_session_id, p_info,
                           0x3 /* only */, 0x1 /* ok_descrambling */,
                           &i_capmt_size );
     if( p_capmt != NULL )
@@ -1298,21 +1249,21 @@ static void CAPMTFirst( cam_t * p_cam, int i_session_id,
  * CAPMTAdd
  *****************************************************************************/
 static void CAPMTAdd( cam_t * p_cam, int i_session_id,
-                      dvbpsi_pmt_t *p_pmt )
+                      const en50221_capmt_info_t *p_info )
 {
     uint8_t *p_capmt;
-    int i_capmt_size;
+    size_t i_capmt_size;
 
     if( p_cam->i_selected_programs >= CAM_PROG_MAX )
     {
         msg_Warn( p_cam->obj, "Not adding CAPMT for SID %d, too many programs",
-                  p_pmt->i_program_number );
+                  p_info->i_program_number );
         return;
     }
     p_cam->i_selected_programs++;
     if( p_cam->i_selected_programs == 1 )
     {
-        CAPMTFirst( p_cam, i_session_id, p_pmt );
+        CAPMTFirst( p_cam, i_session_id, p_info );
         return;
     }
  
@@ -1321,9 +1272,9 @@ static void CAPMTAdd( cam_t * p_cam, int i_session_id,
 #endif
  
     msg_Dbg( p_cam->obj, "adding CAPMT for SID %d on session %d",
-             p_pmt->i_program_number, i_session_id );
+             p_info->i_program_number, i_session_id );
 
-    p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
+    p_capmt = CAPMTBuild( p_cam, i_session_id, p_info,
                           0x4 /* add */, 0x1 /* ok_descrambling */,
                           &i_capmt_size );
     if( p_capmt != NULL )
@@ -1337,15 +1288,15 @@ static void CAPMTAdd( cam_t * p_cam, int i_session_id,
  * CAPMTUpdate
  *****************************************************************************/
 static void CAPMTUpdate( cam_t * p_cam, int i_session_id,
-                         dvbpsi_pmt_t *p_pmt )
+                         const en50221_capmt_info_t *p_info )
 {
     uint8_t *p_capmt;
-    int i_capmt_size;
+    size_t i_capmt_size;
 
     msg_Dbg( p_cam->obj, "updating CAPMT for SID %d on session %d",
-             p_pmt->i_program_number, i_session_id );
+             p_info->i_program_number, i_session_id );
 
-    p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
+    p_capmt = CAPMTBuild( p_cam, i_session_id, p_info,
                           0x5 /* update */, 0x1 /* ok_descrambling */,
                           &i_capmt_size );
     if( p_capmt != NULL )
@@ -1359,16 +1310,16 @@ static void CAPMTUpdate( cam_t * p_cam, int i_session_id,
  * CAPMTDelete
  *****************************************************************************/
 static void CAPMTDelete( cam_t * p_cam, int i_session_id,
-                         dvbpsi_pmt_t *p_pmt )
+                         const en50221_capmt_info_t *p_info )
 {
     uint8_t *p_capmt;
-    int i_capmt_size;
+    size_t i_capmt_size;
 
     p_cam->i_selected_programs--;
     msg_Dbg( p_cam->obj, "deleting CAPMT for SID %d on session %d",
-             p_pmt->i_program_number, i_session_id );
+             p_info->i_program_number, i_session_id );
 
-    p_capmt = CAPMTBuild( p_cam, i_session_id, p_pmt,
+    p_capmt = CAPMTBuild( p_cam, i_session_id, p_info,
                           0x5 /* update */, 0x4 /* not selected */,
                           &i_capmt_size );
     if( p_capmt != NULL )
@@ -2225,29 +2176,29 @@ void en50221_Poll( cam_t * p_cam )
 /*****************************************************************************
  * en50221_SetCAPMT :
  *****************************************************************************/
-int en50221_SetCAPMT( cam_t * p_cam, dvbpsi_pmt_t *p_pmt )
+int en50221_SetCAPMT( cam_t * p_cam, en50221_capmt_info_t *p_info )
 {
     bool b_update = false;
-    bool b_needs_descrambling = CAPMTNeedsDescrambling( p_pmt );
+    bool b_needs_descrambling = CAPMTNeedsDescrambling( p_info );
 
     for ( unsigned i = 0; i < MAX_PROGRAMS; i++ )
     {
         if ( p_cam->pp_selected_programs[i] != NULL
               && p_cam->pp_selected_programs[i]->i_program_number
-                  == p_pmt->i_program_number )
+                  == p_info->i_program_number )
         {
             b_update = true;
 
             if ( !b_needs_descrambling )
             {
-                dvbpsi_pmt_delete( p_pmt );
-                p_pmt = p_cam->pp_selected_programs[i];
+                en50221_capmt_Delete( p_info );
+                p_info = p_cam->pp_selected_programs[i];
                 p_cam->pp_selected_programs[i] = NULL;
             }
-            else if( p_pmt != p_cam->pp_selected_programs[i] )
+            else if( p_info != p_cam->pp_selected_programs[i] )
             {
-                dvbpsi_pmt_delete( p_cam->pp_selected_programs[i] );
-                p_cam->pp_selected_programs[i] = p_pmt;
+                en50221_capmt_Delete( p_cam->pp_selected_programs[i] );
+                p_cam->pp_selected_programs[i] = p_info;
             }
 
             break;
@@ -2260,7 +2211,7 @@ int en50221_SetCAPMT( cam_t * p_cam, dvbpsi_pmt_t *p_pmt )
         {
             if ( p_cam->pp_selected_programs[i] == NULL )
             {
-                p_cam->pp_selected_programs[i] = p_pmt;
+                p_cam->pp_selected_programs[i] = p_info;
                 break;
             }
         }
@@ -2274,18 +2225,18 @@ int en50221_SetCAPMT( cam_t * p_cam, dvbpsi_pmt_t *p_pmt )
                     == RI_CONDITIONAL_ACCESS_SUPPORT )
             {
                 if ( b_update && b_needs_descrambling )
-                    CAPMTUpdate( p_cam, i, p_pmt );
+                    CAPMTUpdate( p_cam, i, p_info );
                 else if ( b_update )
-                    CAPMTDelete( p_cam, i, p_pmt );
+                    CAPMTDelete( p_cam, i, p_info );
                 else
-                    CAPMTAdd( p_cam, i, p_pmt );
+                    CAPMTAdd( p_cam, i, p_info );
             }
         }
     }
 
     if ( !b_needs_descrambling )
     {
-        dvbpsi_pmt_delete( p_pmt );
+        en50221_capmt_Delete( p_info );
     }
 
     return VLC_SUCCESS;
@@ -2661,7 +2612,7 @@ void en50221_End( cam_t * p_cam )
     {
         if( p_cam->pp_selected_programs[i] != NULL )
         {
-            dvbpsi_pmt_delete( p_cam->pp_selected_programs[i] );
+            en50221_capmt_Delete( p_cam->pp_selected_programs[i] );
         }
     }
 
diff --git a/modules/access/dtv/en50221.h b/modules/access/dtv/en50221.h
index 096eee0..cf2e9db 100644
--- a/modules/access/dtv/en50221.h
+++ b/modules/access/dtv/en50221.h
@@ -24,11 +24,11 @@
  *****************************************************************************/
 
 typedef struct cam cam_t;
-struct dvbpsi_pmt_s;
+typedef struct en50221_capmt_info_s en50221_capmt_info_t;
 
 cam_t *en50221_Init( vlc_object_t *, int fd );
 void en50221_Poll( cam_t * );
-int en50221_SetCAPMT( cam_t *, struct dvbpsi_pmt_s * );
+int en50221_SetCAPMT( cam_t *, en50221_capmt_info_t * );
 char *en50221_Status( cam_t *, char *req );
 void en50221_End( cam_t * );
 
diff --git a/modules/access/dtv/linux.c b/modules/access/dtv/linux.c
index db139c8..892734f 100644
--- a/modules/access/dtv/linux.c
+++ b/modules/access/dtv/linux.c
@@ -39,9 +39,7 @@
 #include <linux/dvb/dmx.h>
 
 #include "dtv/dtv.h"
-#ifdef HAVE_DVBPSI
-# include "dtv/en50221.h"
-#endif
+#include "dtv/en50221.h"
 
 #ifndef O_SEARCH
 # define O_SEARCH O_RDONLY
@@ -158,9 +156,7 @@ struct dvb_device
         uint16_t pid;
     } pids[MAX_PIDS];
 #endif
-#ifdef HAVE_DVBPSI
     cam_t *cam;
-#endif
     uint8_t device;
     bool budget;
     //size_t buffer_size;
@@ -207,9 +203,7 @@ dvb_device_t *dvb_open (vlc_object_t *obj)
         return NULL;
     }
     d->frontend = -1;
-#ifdef HAVE_DVBPSI
     d->cam = NULL;
-#endif
     d->budget = var_InheritBool (obj, "dvb-budget-mode");
 
 #ifndef USE_DMX
@@ -262,7 +256,6 @@ dvb_device_t *dvb_open (vlc_object_t *obj)
 #endif
     }
 
-#ifdef HAVE_DVBPSI
     int ca = dvb_open_node (d, "ca", O_RDWR);
     if (ca != -1)
     {
@@ -273,7 +266,6 @@ dvb_device_t *dvb_open (vlc_object_t *obj)
     else
         msg_Dbg (obj, "conditional access module not available: %s",
                  vlc_strerror_c(errno));
-#endif
     return d;
 
 error:
@@ -291,10 +283,8 @@ void dvb_close (dvb_device_t *d)
                 close (d->pids[i].fd);
     }
 #endif
-#ifdef HAVE_DVBPSI
     if (d->cam != NULL)
         en50221_End (d->cam);
-#endif
     if (d->frontend != -1)
         close (d->frontend);
     close (d->demux);
@@ -328,10 +318,8 @@ ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len)
     struct pollfd ufd[2];
     int n;
 
-#ifdef HAVE_DVBPSI
     if (d->cam != NULL)
         en50221_Poll (d->cam);
-#endif
 
     ufd[0].fd = d->demux;
     ufd[0].events = POLLIN;
@@ -642,13 +630,11 @@ float dvb_get_snr (dvb_device_t *d)
     return snr / 65535.;
 }
 
-#ifdef HAVE_DVBPSI
-void dvb_set_ca_pmt (dvb_device_t *d, struct dvbpsi_pmt_s *pmt)
+void dvb_set_ca_pmt (dvb_device_t *d, en50221_capmt_info_t *p_capmtinfo)
 {
     if (d->cam != NULL)
-        en50221_SetCAPMT (d->cam, pmt);
+        en50221_SetCAPMT (d->cam, p_capmtinfo);
 }
-#endif
 
 static int dvb_vset_props (dvb_device_t *d, size_t n, va_list ap)
 {
diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index 2562377..981c1f3 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -254,6 +254,7 @@ libts_plugin_la_SOURCES = demux/mpeg/ts.c demux/mpeg/ts.h \
 	mux/mpeg/streams.h \
         mux/mpeg/tables.c mux/mpeg/tables.h \
 	mux/mpeg/tsutil.c mux/mpeg/tsutil.h \
+        access/dtv/en50221_capmt.h \
         codec/scte18.h \
         codec/atsc_a65.c codec/atsc_a65.h \
 	codec/opus_header.c
diff --git a/modules/demux/mpeg/ts_psi.c b/modules/demux/mpeg/ts_psi.c
index 19a4af1..7b739ab 100644
--- a/modules/demux/mpeg/ts_psi.c
+++ b/modules/demux/mpeg/ts_psi.c
@@ -52,6 +52,8 @@
 #include "ts_psip.h"
 #include "ts_psi_eit.h"
 
+#include "../access/dtv/en50221_capmt.h"
+
 #include <assert.h>
 
 static void PIDFillFormat( demux_t *, ts_pes_t *p_pes, int i_stream_type, ts_transport_type_t * );
@@ -1364,6 +1366,40 @@ static void FillPESFromDvbpsiES( demux_t *p_demux,
         p_pes->p_es->fmt.i_id = p_dvbpsies->i_pid;
 }
 
+static en50221_capmt_info_t * CreateCAPMTInfo( const dvbpsi_pmt_t *p_pmt )
+{
+    en50221_capmt_info_t *p_en = en50221_capmt_New( p_pmt->i_version,
+                                                    p_pmt->i_program_number );
+    if( unlikely(p_en == NULL) )
+        return p_en;
+
+    for( const dvbpsi_descriptor_t *p_dr = p_pmt->p_first_descriptor;
+                                           p_dr; p_dr = p_dr->p_next )
+    {
+        if( p_dr->i_tag == 0x09 )
+            en50221_capmt_AddCADescriptor( p_en, p_dr->p_data, p_dr->i_length );
+    }
+
+    for( const dvbpsi_pmt_es_t *p_es = p_pmt->p_first_es;
+                                       p_es; p_es = p_es->p_next )
+    {
+        en50221_capmt_es_info_t *p_enes = en50221_capmt_EsAdd( p_en,
+                                                               p_es->i_type,
+                                                               p_es->i_pid );
+        if( likely(p_enes) )
+        {
+            for( const dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
+                                                   p_dr; p_dr = p_dr->p_next )
+            {
+                if( p_dr->i_tag == 0x09 )
+                    en50221_capmt_AddESCADescriptor( p_enes, p_dr->p_data, p_dr->i_length );
+            }
+        }
+    }
+
+    return p_en;
+}
+
 static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
 {
     demux_t      *p_demux = data;
@@ -1606,18 +1642,21 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
     /* Set CAM descrambling */
     if( ProgramIsSelected( p_sys, p_pmt->i_number ) )
     {
-        /* DTV/CAM takes ownership of p_dvbpsipmt on success */
-        if( stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA, p_dvbpsipmt ) != VLC_SUCCESS )
+        en50221_capmt_info_t *p_en = CreateCAPMTInfo( p_dvbpsipmt );
+        if( p_en )
         {
-            if ( p_sys->standard == TS_STANDARD_ARIB && !p_sys->arib.b25stream )
+            /* DTV/CAM takes ownership of en50221_capmt_info_t on success */
+            if( stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA, p_en ) != VLC_SUCCESS )
             {
-                p_sys->arib.b25stream = stream_FilterNew( p_demux->s, "aribcam" );
-                p_sys->stream = ( p_sys->arib.b25stream ) ? p_sys->arib.b25stream : p_demux->s;
+                en50221_capmt_Delete( p_en );
+                if ( p_sys->standard == TS_STANDARD_ARIB && !p_sys->arib.b25stream )
+                {
+                    p_sys->arib.b25stream = stream_FilterNew( p_demux->s, "aribcam" );
+                    p_sys->stream = ( p_sys->arib.b25stream ) ? p_sys->arib.b25stream : p_demux->s;
+                }
             }
-            dvbpsi_pmt_delete( p_dvbpsipmt );
         }
     }
-    else dvbpsi_pmt_delete( p_dvbpsipmt );
 
      /* Add arbitrary PID from here */
     if ( p_sys->standard == TS_STANDARD_ATSC )
@@ -1718,6 +1757,8 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
         ProbeStart( p_demux, p_pmt->i_number );
         ProbeEnd( p_demux, p_pmt->i_number );
     }
+
+    dvbpsi_pmt_delete( p_dvbpsipmt );
 }
 
 int UserPmt( demux_t *p_demux, const char *psz_fmt )
-- 
2.5.5



More information about the vlc-devel mailing list