]> git.sesse.net Git - vlc/commitdiff
* modules/demux/ts.c: New option --ts-capmt-sysid to filter CA descriptors
authorChristophe Massiot <massiot@videolan.org>
Tue, 21 Dec 2004 17:01:40 +0000 (17:01 +0000)
committerChristophe Massiot <massiot@videolan.org>
Tue, 21 Dec 2004 17:01:40 +0000 (17:01 +0000)
  of a given system provider (this is apparently needed for SCM Cryptoworks
  CAM).
* modules/access/dvb/dvb.h: Allow up to 256 demux slots.
* modules/access/dvb/en50221.c: Do not send the CAPMT too often (apparently
  bad for some CAM).

modules/access/dvb/dvb.h
modules/access/dvb/en50221.c
modules/demux/ts.c

index 975a7b954041628af575427dad8da7a8349ee01f..b969a4fe8888a9d2df5c18ed0fb6880df45ca710 100644 (file)
@@ -54,7 +54,7 @@ typedef struct
     void *p_sys;
 } en50221_session_t;
 
-#define MAX_DEMUX 48
+#define MAX_DEMUX 256
 #define MAX_CI_SLOTS 16
 #define MAX_SESSIONS 32
 
@@ -71,7 +71,7 @@ struct access_sys_t
     vlc_bool_t pb_active_slot[MAX_CI_SLOTS];
     vlc_bool_t pb_tc_has_data[MAX_CI_SLOTS];
     en50221_session_t p_sessions[MAX_SESSIONS];
-    mtime_t i_ca_timeout, i_ca_next_event;
+    mtime_t i_ca_timeout, i_ca_next_event, i_ca_next_pmt;
     uint8_t **pp_capmts;
     int i_nb_capmts;
 };
index f2a65c8b15f052aa64f295c90fec1f757e474e4f..0fe49e50318fa92c83224d30a6093a6d91f78e93 100644 (file)
@@ -685,7 +685,7 @@ static void ApplicationInformationHandle( access_t * p_access, int i_session_id,
         uint8_t *d = APDUGetLength( p_apdu, &l );
 
         if ( l < 4 ) break;
-        p_apdu[l + 3] = '\0';
+        p_apdu[l + 4] = '\0';
 
         i_type = *d++;
         i_manufacturer = ((int)d[0] << 8) | d[1];
@@ -744,8 +744,7 @@ static void ConditionalAccessHandle( access_t * p_access, int i_session_id,
                 SPDUSend( p_access, i_session_id, p_sys->pp_capmts[i],
                           i_size + (p - p_sys->pp_capmts[i]) );
             }
-
-            p_sys->i_ca_timeout = 100000;
+            p_sys->i_ca_next_pmt = 0;
         }
         break;
     }
@@ -956,7 +955,7 @@ static int InitSlot( access_t * p_access, int i_slot )
     }
     if ( p_sys->pb_active_slot[i_slot] )
     {
-        p_sys->i_ca_timeout = 1000;
+        p_sys->i_ca_timeout = 100000;
         return VLC_SUCCESS;
     }
 
@@ -1074,6 +1073,30 @@ int E_(en50221_Poll)( access_t * p_access )
         }
     }
 
+    if ( p_sys->i_ca_next_pmt && p_sys->i_ca_next_pmt <= mdate() )
+    {
+        for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
+        {
+            int i;
+
+            if ( p_sys->p_sessions[i_session_id - 1].i_resource_id
+                  != RI_CONDITIONAL_ACCESS_SUPPORT )
+                continue;
+
+            msg_Dbg( p_access, "sending CAPMT on session %d", i_session_id );
+            for ( i = 0; i < p_sys->i_nb_capmts; i++ )
+            {
+                int i_size;
+                uint8_t *p;
+                p = GetLength( &p_sys->pp_capmts[i][3], &i_size );
+                SPDUSend( p_access, i_session_id, p_sys->pp_capmts[i],
+                          i_size + (p - p_sys->pp_capmts[i]) );
+            }
+        }
+
+        p_sys->i_ca_next_pmt = 0;
+    }
+
     return VLC_SUCCESS;
 }
 
@@ -1085,28 +1108,6 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts,
                           int i_nb_capmts )
 {
     access_sys_t *p_sys = p_access->p_sys;
-    int i_session_id;
-
-    for ( i_session_id = 1; i_session_id <= MAX_SESSIONS; i_session_id++ )
-    {
-        int i;
-
-        if ( p_sys->p_sessions[i_session_id - 1].i_resource_id
-              != RI_CONDITIONAL_ACCESS_SUPPORT )
-            continue;
-
-        msg_Dbg( p_access, "sending CAPMT on session %d", i_session_id );
-        for ( i = 0; i < i_nb_capmts; i++ )
-        {
-            int i_size;
-            uint8_t *p;
-            p = GetLength( &pp_capmts[i][3], &i_size );
-            SPDUSend( p_access, i_session_id, pp_capmts[i],
-                      i_size + (p - pp_capmts[i]) );
-        }
-
-        p_sys->i_ca_timeout = 100000;
-    }
 
     if ( p_sys->i_nb_capmts )
     {
@@ -1119,6 +1120,7 @@ int E_(en50221_SetCAPMT)( access_t * p_access, uint8_t **pp_capmts,
     }
     p_sys->pp_capmts = pp_capmts;
     p_sys->i_nb_capmts = i_nb_capmts;
+    p_sys->i_ca_next_pmt = mdate() + 1000000;
 
     return VLC_SUCCESS;
 }
index eefe18589d3fc177103bfd3156b7d2edc49d00e9..4527f3bc7aa53f5c4aca7a9d88a8f7cd0523c735 100644 (file)
@@ -83,6 +83,9 @@ static void Close ( vlc_object_t * );
 #define SILENT_TEXT N_("Silent mode")
 #define SILENT_LONGTEXT N_("do not complain on encrypted PES")
 
+#define CAPMT_SYSID_TEXT N_("CAPMT System ID")
+#define CAPMT_SYSID_LONGTEXT N_("only forward descriptors from this SysID to the CAM")
+
 vlc_module_begin();
     set_description( _("ISO 13818-1 MPEG Transport Stream input - new" ) );
     set_shortname ( _("MPEG-TS") );
@@ -96,6 +99,8 @@ vlc_module_begin();
                  MTUOUT_LONGTEXT, VLC_TRUE );
     add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE );
     add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE );
+    add_integer( "ts-capmt-sysid", 0, NULL, CAPMT_SYSID_TEXT,
+                 CAPMT_SYSID_LONGTEXT, VLC_TRUE );
 
     set_capability( "demux2", 10 );
     set_callbacks( Open, Close );
@@ -270,6 +275,7 @@ struct demux_sys_t
     vlc_bool_t  b_es_id_pid;
     csa_t       *csa;
     vlc_bool_t  b_silent;
+    uint16_t    i_capmt_sysid;
 
     vlc_bool_t  b_udp_out;
     int         fd; /* udp socket */
@@ -572,6 +578,10 @@ static int Open( vlc_object_t *p_this )
     var_Get( p_demux, "ts-silent", &val );
     p_sys->b_silent = val.b_bool;
 
+    var_Create( p_demux, "ts-capmt-sysid", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
+    var_Get( p_demux, "ts-capmt-sysid", &val );
+    p_sys->i_capmt_sysid = val.i_int;
+
     return VLC_SUCCESS;
 }
 
@@ -2033,8 +2043,11 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
         }
         else if( p_dr->i_tag == 0x9 )
         {
-            msg_Dbg( p_demux, " * descriptor : CA (0x9)" );
-            i_cad_length += p_dr->i_length + 2;
+            uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
+                                | p_dr->p_data[1];
+            msg_Dbg( p_demux, " * descriptor : CA (0x9) SysID 0x%x", i_sysid );
+            if ( !p_sys->i_capmt_sysid || p_sys->i_capmt_sysid == i_sysid )
+                i_cad_length += p_dr->i_length + 2;
         }
         else
         {
@@ -2049,7 +2062,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
 
         prg->p_capmt[0] = p_pmt->i_program_number >> 8;
         prg->p_capmt[1] = p_pmt->i_program_number & 0xff;
-        prg->p_capmt[2] = (p_pmt->i_version << 1) | 0x1;
+        prg->p_capmt[2] = ((p_pmt->i_version & 0x1f) << 1) | 0x1;
         prg->p_capmt[3] = (i_cad_length + 1) >> 8;
         prg->p_capmt[4] = (i_cad_length + 1) & 0xff;
         prg->p_capmt[5] = 0x1; /* ok_descrambling */
@@ -2059,10 +2072,15 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
         {
             if( p_dr->i_tag == 0x9 )
             {
-                prg->p_capmt[i] = 0x9;
-                prg->p_capmt[i+1] = p_dr->i_length;
-                memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length );
-                i += p_dr->i_length + 2;
+                uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
+                                    | p_dr->p_data[1];
+                if ( !p_sys->i_capmt_sysid || p_sys->i_capmt_sysid == i_sysid )
+                {
+                    prg->p_capmt[i] = 0x9;
+                    prg->p_capmt[i+1] = p_dr->i_length;
+                    memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length );
+                    i += p_dr->i_length + 2;
+                }
             }
         }
     }
@@ -2449,8 +2467,12 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
         {
             if( p_dr->i_tag == 0x9 )
             {
-                msg_Dbg( p_demux, "   * descriptor : CA (0x9)" );
-                i_cad_length += p_dr->i_length + 2;
+                uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
+                                    | p_dr->p_data[1];
+                msg_Dbg( p_demux, "   * descriptor : CA (0x9) SysID 0x%x",
+                         i_sysid );
+                if ( !p_sys->i_capmt_sysid || p_sys->i_capmt_sysid == i_sysid )
+                    i_cad_length += p_dr->i_length + 2;
             }
             else
             {
@@ -2468,7 +2490,7 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
 
                 prg->p_capmt[0] = p_pmt->i_program_number >> 8;
                 prg->p_capmt[1] = p_pmt->i_program_number & 0xff;
-                prg->p_capmt[2] = (p_pmt->i_version << 1) | 0x1;
+                prg->p_capmt[2] = ((p_pmt->i_version & 0x1f) << 1) | 0x1;
                 prg->p_capmt[3] = 0; /* cad length */
                 prg->p_capmt[4] = 0;
 
@@ -2494,10 +2516,16 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
             {
                 if( p_dr->i_tag == 0x9 )
                 {
-                    prg->p_capmt[i] = 0x9;
-                    prg->p_capmt[i+1] = p_dr->i_length;
-                    memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length );
-                    i += p_dr->i_length + 2;
+                    uint16_t i_sysid = ((uint16_t)p_dr->p_data[0] << 8)
+                                        | p_dr->p_data[1];
+                    if ( !p_sys->i_capmt_sysid
+                           || p_sys->i_capmt_sysid == i_sysid )
+                    {
+                        prg->p_capmt[i] = 0x9;
+                        prg->p_capmt[i+1] = p_dr->i_length;
+                        memcpy( &prg->p_capmt[i+2], p_dr->p_data, p_dr->i_length );
+                        i += p_dr->i_length + 2;
+                    }
                 }
             }
         }
@@ -2697,7 +2725,7 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
                 /* Now select PID at access level */
                 if( p_sys->b_dvb_control )
                 {
-                    if( p_sys->i_dvb_program <= 0 || p_sys->i_dvb_program == p_program->i_number )
+                    if( DVBProgramIsSelected( p_demux, p_program->i_number ) )
                     {
                         if( p_sys->i_dvb_program == 0 )
                             p_sys->i_dvb_program = p_program->i_number;