]> git.sesse.net Git - vlc/blobdiff - modules/demux/ts.c
Cosmetics.
[vlc] / modules / demux / ts.c
index 8a450e7ebbe8cc013c9eaa412da01e4371f18c65..a6b0fe9bac6457325b71ba7ffe480b937b8456a8 100644 (file)
@@ -30,7 +30,8 @@
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
 
 #include <ctype.h>
 
@@ -39,7 +40,7 @@
 #include <vlc_meta.h>
 #include <vlc_epg.h>
 
-#include "iso_lang.h"
+#include <vlc_iso_lang.h>
 #include <vlc_network.h>
 #include <vlc_charset.h>
 
  *  - ...
  */
 
+/*****************************************************************************
+ * Callback prototypes
+ *****************************************************************************/
+static int ChangeKeyCallback    ( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -112,6 +118,10 @@ static void Close ( vlc_object_t * );
 #define CSA_TEXT N_("CSA ck")
 #define CSA_LONGTEXT N_("Control word for the CSA encryption algorithm")
 
+#define CSA2_TEXT N_("Second CSA Key")
+#define CSA2_LONGTEXT N_("The even CSA encryption key. This must be a " \
+  "16 char string (8 hexadecimal bytes).")
+
 #define SILENT_TEXT N_("Silent mode")
 #define SILENT_LONGTEXT N_("Do not complain on encrypted PES.")
 
@@ -137,7 +147,7 @@ static void Close ( vlc_object_t * );
     "Specify the size of the buffer here and not the number of packets." )
 
 vlc_module_begin();
-    set_description( _("MPEG Transport Stream demuxer") );
+    set_description( N_("MPEG Transport Stream demuxer") );
     set_shortname ( "MPEG-TS" );
     set_category( CAT_INPUT );
     set_subcategory( SUBCAT_INPUT_DEMUX );
@@ -148,6 +158,7 @@ vlc_module_begin();
     add_integer( "ts-out-mtu", 1400, NULL, MTUOUT_TEXT,
                  MTUOUT_LONGTEXT, true );
     add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, true );
+    add_string( "ts-csa2-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, true );
     add_integer( "ts-csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, true );
     add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, true );
 
@@ -310,6 +321,8 @@ typedef struct
 
 struct demux_sys_t
 {
+    vlc_mutex_t     csa_lock;
+
     /* TS packet size (188, 192, 204) */
     int         i_packet_size;
 
@@ -538,6 +551,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_ENOMEM;
     memset( p_sys, 0, sizeof( demux_sys_t ) );
     p_sys->i_packet_size = i_packet_size;
+    vlc_mutex_init( &p_sys->csa_lock );
 
     /* Fill dump mode fields */
     p_sys->i_write = 0;
@@ -772,57 +786,54 @@ static int Open( vlc_object_t *p_this )
     }
     free( val.psz_string );
 
-    var_Create( p_demux, "ts-csa-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
+    var_Create( p_demux, "ts-csa-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND );
     var_Get( p_demux, "ts-csa-ck", &val );
     if( val.psz_string && *val.psz_string )
     {
-        char *psz = val.psz_string;
-        if( psz[0] == '0' && ( psz[1] == 'x' || psz[1] == 'X' ) )
+        int i_res;
+        vlc_value_t csa2;
+
+        p_sys->csa = csa_New();
+
+        var_Create( p_demux, "ts-csa2-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT | VLC_VAR_ISCOMMAND);
+        var_Get( p_demux, "ts-csa2-ck", &csa2 );
+        i_res = csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, val.psz_string, true );
+        if( i_res == VLC_SUCCESS && csa2.psz_string && *csa2.psz_string )
         {
-            psz += 2;
+            if( csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, csa2.psz_string, false ) != VLC_SUCCESS )
+            {
+                csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, val.psz_string, false );
+            }
         }
-        if( strlen( psz ) != 16 )
+        else if ( i_res == VLC_SUCCESS )
         {
-            msg_Warn( p_demux, "invalid csa ck (it must be 16 chars long)" );
+            csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, val.psz_string, false );
         }
         else
         {
-#ifndef UNDER_CE
-            uint64_t i_ck = strtoull( psz, NULL, 16 );
-#else
-            uint64_t i_ck = strtoll( psz, NULL, 16 );
-#endif
-            uint8_t ck[8];
-            int     i;
-            for( i = 0; i < 8; i++ )
-            {
-                ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
-            }
-#ifndef TS_NO_CSA_CK_MSG
-            msg_Dbg( p_demux, "using CSA scrambling with "
-                     "ck=%x:%x:%x:%x:%x:%x:%x:%x",
-                     ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
-#endif
-            p_sys->csa = csa_New();
+            csa_Delete( p_sys->csa );
+            p_sys->csa = NULL;
+        }
 
-            if( p_sys->csa )
-            {
-                vlc_value_t pkt_val;
+        if( p_sys->csa )
+        {
+            vlc_value_t pkt_val;
 
-                csa_SetCW( p_sys->csa, ck, ck );
+            var_AddCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, (void *)1 );
+            var_AddCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );
 
-                var_Create( p_demux, "ts-csa-pkt", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
-                var_Get( p_demux, "ts-csa-pkt", &pkt_val );
-                if( pkt_val.i_int < 4 || pkt_val.i_int > 188 )
-                {
-                    msg_Err( p_demux, "wrong packet size %d specified.", pkt_val.i_int );
-                    msg_Warn( p_demux, "using default packet size of 188 bytes" );
-                    p_sys->i_csa_pkt_size = 188;
-                }
-                else p_sys->i_csa_pkt_size = pkt_val.i_int;
-                msg_Dbg( p_demux, "decrypting %d bytes of packet", p_sys->i_csa_pkt_size );
+            var_Create( p_demux, "ts-csa-pkt", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
+            var_Get( p_demux, "ts-csa-pkt", &pkt_val );
+            if( pkt_val.i_int < 4 || pkt_val.i_int > 188 )
+            {
+                msg_Err( p_demux, "wrong packet size %d specified.", pkt_val.i_int );
+                msg_Warn( p_demux, "using default packet size of 188 bytes" );
+                p_sys->i_csa_pkt_size = 188;
             }
+            else p_sys->i_csa_pkt_size = pkt_val.i_int;
+            msg_Dbg( p_demux, "decrypting %d bytes of packet", p_sys->i_csa_pkt_size );
         }
+        free( csa2.psz_string );
     }
     free( val.psz_string );
 
@@ -894,10 +905,15 @@ static void Close( vlc_object_t *p_this )
         net_Close( p_sys->fd );
         free( p_sys->buffer );
     }
+    vlc_mutex_lock( &p_sys->csa_lock );
     if( p_sys->csa )
     {
+        var_DelCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, NULL );
+        var_DelCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );
         csa_Delete( p_sys->csa );
+        p_sys->csa = NULL;
     }
+    vlc_mutex_unlock( &p_sys->csa_lock );
 
     if( p_sys->i_pmt ) free( p_sys->pmt );
 
@@ -911,7 +927,7 @@ static void Close( vlc_object_t *p_this )
     /* If in dump mode, then close the file */
     if( p_sys->b_file_out )
     {
-        msg_Info( p_demux ,"closing %s ("I64Fd" Kbytes dumped)",
+        msg_Info( p_demux ,"closing %s (%"PRId64" Kbytes dumped)",
                   p_sys->psz_file, p_sys->i_write / 1024 );
 
         if( p_sys->p_file != stdout )
@@ -926,9 +942,32 @@ static void Close( vlc_object_t *p_this )
     free( p_sys->psz_file );
     p_sys->psz_file = NULL;
 
+    vlc_mutex_destroy( &p_sys->csa_lock );
     free( p_sys );
 }
 
+/*****************************************************************************
+ * ChangeKeyCallback: called when changing the odd encryption key on the fly.
+ *****************************************************************************/
+static int ChangeKeyCallback( vlc_object_t *p_this, char const *psz_cmd,
+                           vlc_value_t oldval, vlc_value_t newval,
+                           void *p_data )
+{
+    VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
+    demux_t     *p_demux = (demux_t*)p_this;
+    demux_sys_t *p_sys = p_demux->p_sys;
+    int         i_tmp = (intptr_t)p_data;
+
+    vlc_mutex_lock( &p_sys->csa_lock );
+    if ( i_tmp )
+        i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, true );
+    else
+        i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, false );
+
+    vlc_mutex_unlock( &p_sys->csa_lock );
+    return i_tmp;
+}
+
 /*****************************************************************************
  * DemuxFile:
  *****************************************************************************/
@@ -1018,7 +1057,11 @@ static int DemuxFile( demux_t *p_demux )
 
         /* Test if user wants to decrypt it first */
         if( p_sys->csa )
+        {
+            vlc_mutex_lock( &p_sys->csa_lock );
             csa_Decrypt( p_demux->p_sys->csa, &p_buffer[i_pos], p_demux->p_sys->i_csa_pkt_size );
+            vlc_mutex_unlock( &p_sys->csa_lock );
+        }
 
         i_pos += p_sys->i_packet_size;
     }
@@ -1190,9 +1233,9 @@ static int DVBEventInformation( demux_t *p_demux, int64_t *pi_time, int64_t *pi_
         if( p_sys->i_dvb_start <= t && t < p_sys->i_dvb_start + p_sys->i_dvb_length )
         {
             if( pi_length )
-                *pi_length = p_sys->i_dvb_length * I64C(1000000);
+                *pi_length = p_sys->i_dvb_length * INT64_C(1000000);
             if( pi_time )
-                *pi_time   = (t - p_sys->i_dvb_start) * I64C(1000000);
+                *pi_time   = (t - p_sys->i_dvb_start) * INT64_C(1000000);
             return VLC_SUCCESS;
         }
     }
@@ -1255,7 +1298,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             pi64 = (int64_t*)va_arg( args, int64_t * );
             if( p_sys->i_mux_rate > 0 )
             {
-                *pi64 = I64C(1000000) * ( stream_Size( p_demux->s ) / 50 ) /
+                *pi64 = INT64_C(1000000) * ( stream_Size( p_demux->s ) / 50 ) /
                         p_sys->i_mux_rate;
                 return VLC_SUCCESS;
             }
@@ -1810,7 +1853,9 @@ static bool GatherPES( 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 );
+        vlc_mutex_unlock( &p_demux->p_sys->csa_lock );
     }
 
     if( !b_adaptation )
@@ -3236,7 +3281,8 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
                     pid->es->fmt.i_cat = SPU_ES;
                     pid->es->fmt.i_codec = VLC_FOURCC( 't', 'e', 'l', 'x' );
                     pid->es->fmt.i_extra = p_dr->i_length;
-                    pid->es->fmt.p_extra = malloc( p_dr->i_length );
+                    pid->es->fmt.p_extra = p_dr->i_length ?
+                        malloc( p_dr->i_length ) : NULL;
                     if( pid->es->fmt.p_extra )
                         memcpy( pid->es->fmt.p_extra, p_dr->p_data,
                                 p_dr->i_length );