Commit 0d5eef15 authored by Laurent Aimar's avatar Laurent Aimar

- csa.* : CSA scrambling implementation.

 - demux/ts.c, mux/mpeg/ts.c: added support for CSA (de)scrambling
 (fixed key).
parent e525bf13
...@@ -14,7 +14,8 @@ SOURCES_livedotcom = livedotcom.cpp ...@@ -14,7 +14,8 @@ SOURCES_livedotcom = livedotcom.cpp
SOURCES_demux2 = demux2.c SOURCES_demux2 = demux2.c
SOURCES_nsv = nsv.c SOURCES_nsv = nsv.c
SOURCES_real = real.c SOURCES_real = real.c
SOURCES_ts2 = ts.c SOURCES_ts2 = ts.c ../mux/mpeg/csa.c
SOURCES_ps2 = ps.c ps.h SOURCES_ps2 = ps.c ps.h
SOURCES_dvdnav = dvdnav.c SOURCES_dvdnav = dvdnav.c
SOURCES_mod = mod.c SOURCES_mod = mod.c
SOURCES_pva = pva.c
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ts.c: Transport Stream input module for VLC. * ts.c: Transport Stream input module for VLC.
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 VideoLAN * Copyright (C) 2004 VideoLAN
* $Id: ts.c,v 1.6 2004/01/22 00:02:18 fenrir Exp $ * $Id: ts.c,v 1.7 2004/01/25 02:26:04 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "iso_lang.h" #include "iso_lang.h"
#include "network.h" #include "network.h"
#include "../mux/mpeg/csa.h"
/* Include dvbpsi headers */ /* Include dvbpsi headers */
#ifdef HAVE_DVBPSI_DR_H #ifdef HAVE_DVBPSI_DR_H
# include <dvbpsi/dvbpsi.h> # include <dvbpsi/dvbpsi.h>
...@@ -68,6 +70,7 @@ vlc_module_begin(); ...@@ -68,6 +70,7 @@ vlc_module_begin();
add_bool( "ts-es-id-pid", 0, NULL, "set id of es to pid", "set id of es to pid", VLC_TRUE ); add_bool( "ts-es-id-pid", 0, NULL, "set id of es to pid", "set id of es to pid", VLC_TRUE );
add_string( "ts-out", NULL, NULL, "fast udp streaming", "send TS to specific ip:port by udp (you must know what you are doing)", VLC_TRUE ); add_string( "ts-out", NULL, NULL, "fast udp streaming", "send TS to specific ip:port by udp (you must know what you are doing)", VLC_TRUE );
add_integer( "ts-out-mtu", 1500, NULL, "MTU for out mode", "MTU for out mode", VLC_TRUE ); add_integer( "ts-out-mtu", 1500, NULL, "MTU for out mode", "MTU for out mode", VLC_TRUE );
add_string( "ts-csa-ck", NULL, NULL, "CSA ck", "CSA ck", VLC_TRUE );
set_capability( "demux2", 10 ); set_capability( "demux2", 10 );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
add_shortcut( "ts2" ); add_shortcut( "ts2" );
...@@ -208,6 +211,7 @@ struct demux_sys_t ...@@ -208,6 +211,7 @@ struct demux_sys_t
/* */ /* */
vlc_bool_t b_es_id_pid; vlc_bool_t b_es_id_pid;
csa_t *csa;
vlc_bool_t b_udp_out; vlc_bool_t b_udp_out;
int fd; /* udp socket */ int fd; /* udp socket */
...@@ -285,6 +289,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -285,6 +289,7 @@ static int Open( vlc_object_t *p_this )
} }
p_sys->b_udp_out = VLC_FALSE; p_sys->b_udp_out = VLC_FALSE;
p_sys->i_ts_read = 50; p_sys->i_ts_read = 50;
p_sys->csa = NULL;
/* Init PAT handler */ /* Init PAT handler */
pat = &p_sys->pid[0]; pat = &p_sys->pid[0];
...@@ -405,6 +410,42 @@ static int Open( vlc_object_t *p_this ) ...@@ -405,6 +410,42 @@ static int Open( vlc_object_t *p_this )
free( val.psz_string ); free( val.psz_string );
} }
var_Create( p_demux, "ts-csa-ck", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
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' ) )
{
psz += 2;
}
if( strlen( psz ) != 16 )
{
msg_Warn( p_demux, "invalid csa ck (it must be 16 chars long)" );
}
else
{
uint64_t i_ck = strtoll( psz, NULL, 16 );
uint8_t ck[8];
int i;
for( i = 0; i < 8; i++ )
{
ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
}
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] );
p_sys->csa = csa_New();
csa_SetCW( p_sys->csa, ck, ck );
}
}
if( val.psz_string )
{
free( val.psz_string );
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -461,6 +502,10 @@ static void Close( vlc_object_t *p_this ) ...@@ -461,6 +502,10 @@ static void Close( vlc_object_t *p_this )
net_Close( p_sys->fd ); net_Close( p_sys->fd );
free( p_sys->buffer ); free( p_sys->buffer );
} }
if( p_sys->csa )
{
csa_Delete( p_sys->csa );
}
free( p_sys ); free( p_sys );
} }
...@@ -725,7 +770,7 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid ) ...@@ -725,7 +770,7 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid )
if( header[0] != 0 || header[1] != 0 || header[2] != 1 ) if( header[0] != 0 || header[1] != 0 || header[2] != 1 )
{ {
msg_Err( p_demux, "invalid header [0x%x:%x:%x:%x]", header[0], header[1],header[2],header[3] ); msg_Warn( p_demux, "invalid header [0x%x:%x:%x:%x]", header[0], header[1],header[2],header[3] );
block_ChainRelease( p_pes ); block_ChainRelease( p_pes );
return; return;
} }
...@@ -887,6 +932,11 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) ...@@ -887,6 +932,11 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
msg_Dbg( p_demux, "transport_error_indicator set (pid=0x%x)", pid->i_pid ); msg_Dbg( p_demux, "transport_error_indicator set (pid=0x%x)", pid->i_pid );
} }
if( p_demux->p_sys->csa )
{
csa_Decrypt( p_demux->p_sys->csa, p_bk->p_buffer );
}
if( !b_adaptation ) if( !b_adaptation )
{ {
i_skip = 4; i_skip = 4;
......
...@@ -6,12 +6,16 @@ SOURCES_mux_ps = ps.c \ ...@@ -6,12 +6,16 @@ SOURCES_mux_ps = ps.c \
SOURCES_mux_ts = ts.c \ SOURCES_mux_ts = ts.c \
pes.c \ pes.c \
pes.h \ pes.h \
csa.c \
csa.h \
bits.h \ bits.h \
$(NULL) $(NULL)
SOURCES_mux_ts_dvbpsi = ts.c \ SOURCES_mux_ts_dvbpsi = ts.c \
pes.c \ pes.c \
pes.h \ pes.h \
csa.c \
csa.h \
bits.h \ bits.h \
$(NULL) $(NULL)
This diff is collapsed.
/*****************************************************************************
* csa.h
*****************************************************************************
* Copyright (C) 2004 Laurent Aimar
* $Id: csa.h,v 1.1 2004/01/25 02:26:04 fenrir Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
* 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
* (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.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
typedef struct csa_t csa_t;
#define csa_New E_(__csa_New)
#define csa_Delete E_(__csa_Delete)
#define csa_SetCW E_(__csa_SetCW)
#define csa_Decrypt E_(__csa_decrypt)
#define csa_Encrypt E_(__csa_encrypt)
csa_t *csa_New();
void csa_Delete( csa_t * );
void csa_SetCW( csa_t *, uint8_t o_ck[8], uint8_t e_ck[8] );
void csa_Decrypt( csa_t *, uint8_t *pkt );
void csa_Encrypt( csa_t *, uint8_t *pkt, int b_odd );
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ts.c: MPEG-II TS Muxer * ts.c: MPEG-II TS Muxer
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: ts.c,v 1.41 2003/11/27 22:44:50 massiot Exp $ * $Id: ts.c,v 1.42 2004/01/25 02:26:04 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "codecs.h" #include "codecs.h"
#include "bits.h" #include "bits.h"
#include "pes.h" #include "pes.h"
#include "csa.h"
#if defined MODULE_NAME_IS_mux_ts_dvbpsi #if defined MODULE_NAME_IS_mux_ts_dvbpsi
# ifdef HAVE_DVBPSI_DR_H # ifdef HAVE_DVBPSI_DR_H
...@@ -102,6 +103,7 @@ static int Mux ( sout_mux_t * ); ...@@ -102,6 +103,7 @@ static int Mux ( sout_mux_t * );
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
#define SOUT_BUFFER_FLAGS_PRIVATE_PCR ( 1 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT ) #define SOUT_BUFFER_FLAGS_PRIVATE_PCR ( 1 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT )
#define SOUT_BUFFER_FLAGS_PRIVATE_CSA ( 2 << SOUT_BUFFER_FLAGS_PRIVATE_SHIFT )
typedef struct typedef struct
{ {
int i_depth; int i_depth;
...@@ -212,6 +214,8 @@ struct sout_mux_sys_t ...@@ -212,6 +214,8 @@ struct sout_mux_sys_t
int64_t i_dts_delay; int64_t i_dts_delay;
mtime_t i_pcr; /* last PCR emited */ mtime_t i_pcr; /* last PCR emited */
csa_t *csa;
}; };
...@@ -366,6 +370,36 @@ static int Open( vlc_object_t *p_this ) ...@@ -366,6 +370,36 @@ static int Open( vlc_object_t *p_this )
/* for TS generation */ /* for TS generation */
p_sys->i_pcr = 0; p_sys->i_pcr = 0;
p_sys->csa = NULL;
if( ( val = sout_cfg_find_value( p_mux->p_cfg, "csa-ck" ) ) )
{
/* skip 0x */
if( val[0] == '0' && ( val[1] == 'x' || val[1] == 'X' ) )
{
val += 2;
}
if( strlen( val ) != 16 )
{
msg_Dbg( p_mux, "invalid csa ck (it must be 16 chars long)" );
}
else
{
uint64_t i_ck = strtoll( val, NULL, 16 );
uint8_t ck[8];
int i;
for( i = 0; i < 8; i++ )
{
ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
}
msg_Dbg( p_mux, "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] );
p_sys->csa = csa_New();
csa_SetCW( p_sys->csa, ck, ck );
}
}
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -378,6 +412,10 @@ static void Close( vlc_object_t * p_this ) ...@@ -378,6 +412,10 @@ static void Close( vlc_object_t * p_this )
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
msg_Dbg( p_mux, "Close" ); msg_Dbg( p_mux, "Close" );
if( p_sys->csa )
{
csa_Delete( p_sys->csa );
}
free( p_sys ); free( p_sys );
} }
...@@ -825,6 +863,10 @@ static int Mux( sout_mux_t *p_mux ) ...@@ -825,6 +863,10 @@ static int Mux( sout_mux_t *p_mux )
/* Build the TS packet */ /* Build the TS packet */
p_ts = TSNew( p_mux, p_stream, b_pcr ); p_ts = TSNew( p_mux, p_stream, b_pcr );
if( p_sys->csa )
{
p_ts->i_flags |= SOUT_BUFFER_FLAGS_PRIVATE_CSA;
}
i_packet_pos++; i_packet_pos++;
/* */ /* */
...@@ -846,6 +888,10 @@ static int Mux( sout_mux_t *p_mux ) ...@@ -846,6 +888,10 @@ static int Mux( sout_mux_t *p_mux )
/* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */ /* msg_Dbg( p_mux, "pcr=%lld ms", p_ts->i_dts / 1000 ); */
TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay ); TSSetPCR( p_ts, p_ts->i_dts - p_sys->i_dts_delay );
} }
if( p_ts->i_flags&SOUT_BUFFER_FLAGS_PRIVATE_CSA )
{
csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 );
}
/* latency */ /* latency */
p_ts->i_dts += 3*p_sys->i_caching_delay/2; p_ts->i_dts += 3*p_sys->i_caching_delay/2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment