[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