[vlc-commits] [Git][videolan/vlc][master] 3 commits: access: always pass en50221_capmt_info_t as const
Rémi Denis-Courmont (@Courmisch)
gitlab at videolan.org
Tue Feb 20 21:04:15 UTC 2024
Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC
Commits:
6436143c by François Cartegnie at 2024-02-20T20:43:55+00:00
access: always pass en50221_capmt_info_t as const
Will allow caching the struct instead of rebuilding
a new one for each call.
- - - - -
0b14fe9c by François Cartegnie at 2024-02-20T20:43:55+00:00
demux: ts: cache CAPMT info
- - - - -
678d0466 by François Cartegnie at 2024-02-20T20:43:55+00:00
demux: ts: update CAPMT on program selection change
- - - - -
12 changed files:
- modules/access/dtv/access.c
- modules/access/dtv/bdagraph.cpp
- modules/access/dtv/dtv.h
- modules/access/dtv/en50221.c
- modules/access/dtv/en50221.h
- modules/access/dtv/en50221_capmt.h
- modules/access/dtv/linux.c
- modules/demux/mpeg/ts.c
- modules/demux/mpeg/ts_psi.c
- modules/demux/mpeg/ts_psi.h
- modules/demux/mpeg/ts_streams.c
- modules/demux/mpeg/ts_streams_private.h
Changes:
=====================================
modules/access/dtv/access.c
=====================================
@@ -577,7 +577,7 @@ static int Control (stream_t *access, int query, va_list args)
case STREAM_SET_PRIVATE_ID_CA:
{
- en50221_capmt_info_t *pmt = va_arg(args, void *);
+ const en50221_capmt_info_t *pmt = va_arg(args, void *);
if( !dvb_set_ca_pmt (dev, pmt) )
return VLC_EGENERIC;
=====================================
modules/access/dtv/bdagraph.cpp
=====================================
@@ -215,7 +215,7 @@ int dvb_fill_device_caps( dvb_device_t *, dvb_device_caps_t * )
return -1;
}
-bool dvb_set_ca_pmt (dvb_device_t *, en50221_capmt_info_t *)
+bool dvb_set_ca_pmt (dvb_device_t *, const en50221_capmt_info_t *)
{
return false;
}
=====================================
modules/access/dtv/dtv.h
=====================================
@@ -73,7 +73,7 @@ float dvb_get_signal_strength (dvb_device_t *);
float dvb_get_snr (dvb_device_t *);
typedef struct en50221_capmt_info_s en50221_capmt_info_t;
-bool dvb_set_ca_pmt (dvb_device_t *, en50221_capmt_info_t *);
+bool dvb_set_ca_pmt (dvb_device_t *, const en50221_capmt_info_t *);
int dvb_set_inversion (dvb_device_t *, int);
int dvb_tune (dvb_device_t *);
=====================================
modules/access/dtv/en50221.c
=====================================
@@ -2179,10 +2179,11 @@ void en50221_Poll( cam_t * p_cam )
/*****************************************************************************
* en50221_SetCAPMT :
*****************************************************************************/
-int en50221_SetCAPMT( cam_t * p_cam, en50221_capmt_info_t *p_info )
+int en50221_SetCAPMT( cam_t * p_cam, const en50221_capmt_info_t *p_info )
{
bool b_update = false;
bool b_needs_descrambling = CAPMTNeedsDescrambling( p_info );
+ en50221_capmt_info_t *p_oldinfo = NULL;
for ( unsigned i = 0; i < MAX_PROGRAMS; i++ )
{
@@ -2192,34 +2193,37 @@ int en50221_SetCAPMT( cam_t * p_cam, en50221_capmt_info_t *p_info )
{
b_update = true;
+ /* Existing scrambled program went clear now */
if ( !b_needs_descrambling )
{
- en50221_capmt_Delete( p_info );
- p_info = p_cam->pp_selected_programs[i];
+ p_oldinfo = p_cam->pp_selected_programs[i];
p_cam->pp_selected_programs[i] = NULL;
}
+ /* Existing scrambled program has been updated */
else if( p_info != p_cam->pp_selected_programs[i] )
{
en50221_capmt_Delete( p_cam->pp_selected_programs[i] );
- p_cam->pp_selected_programs[i] = p_info;
+ p_cam->pp_selected_programs[i] = en50221_capmt_Duplicate( p_info );
}
break;
}
}
+ /* New selection of scrambled program */
if ( !b_update && b_needs_descrambling )
{
for ( unsigned i = 0; i < MAX_PROGRAMS; i++ )
{
if ( p_cam->pp_selected_programs[i] == NULL )
{
- p_cam->pp_selected_programs[i] = p_info;
+ p_cam->pp_selected_programs[i] = en50221_capmt_Duplicate( p_info );
break;
}
}
}
+ /* Serialization of CAPMT commands to CI */
if ( b_update || b_needs_descrambling )
{
for ( unsigned i = 1; i <= MAX_SESSIONS; i++ )
@@ -2230,17 +2234,15 @@ int en50221_SetCAPMT( cam_t * p_cam, en50221_capmt_info_t *p_info )
if ( b_update && b_needs_descrambling )
CAPMTUpdate( p_cam, i, p_info );
else if ( b_update )
- CAPMTDelete( p_cam, i, p_info );
+ CAPMTDelete( p_cam, i, p_oldinfo );
else
CAPMTAdd( p_cam, i, p_info );
}
}
}
- if ( !b_needs_descrambling )
- {
- en50221_capmt_Delete( p_info );
- }
+ if( p_oldinfo )
+ en50221_capmt_Delete( p_oldinfo );
return VLC_SUCCESS;
}
=====================================
modules/access/dtv/en50221.h
=====================================
@@ -28,7 +28,7 @@ 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 *, en50221_capmt_info_t * );
+int en50221_SetCAPMT( cam_t *, const en50221_capmt_info_t * );
char *en50221_Status( cam_t *, char *req );
void en50221_End( cam_t * );
=====================================
modules/access/dtv/en50221_capmt.h
=====================================
@@ -110,4 +110,40 @@ static inline en50221_capmt_info_t * en50221_capmt_New( uint8_t i_version, uint1
return p_en;
}
+static inline en50221_capmt_info_t * en50221_capmt_Duplicate( const en50221_capmt_info_t *p_src )
+{
+ en50221_capmt_info_t *p_en = en50221_capmt_New( p_src->i_version, p_src->i_program_number );
+ if( !p_en )
+ return NULL;
+ p_en->p_program_descriptors = calloc( p_src->i_program_descriptors, sizeof(uint8_t) );
+ if( !p_en->p_program_descriptors )
+ goto error;
+ memcpy( p_en->p_program_descriptors, p_src->p_program_descriptors, p_src->i_program_descriptors );
+ p_en->i_program_descriptors = p_src->i_program_descriptors;
+
+ p_en->p_es = calloc( p_src->i_es_count, sizeof(en50221_capmt_es_info_t) );
+ if( !p_en->p_es )
+ goto error;
+ memcpy( p_en->p_es, p_src->p_es, p_src->i_es_count );
+ p_en->i_es_count = p_src->i_es_count;
+
+ for( size_t i=0; i<p_en->i_es_count; i++ )
+ {
+ p_en->p_es[i].p_descriptors = malloc( p_src->p_es[i].i_descriptors );
+ if( !p_en->p_es[i].p_descriptors )
+ {
+ p_en->p_es[i].i_descriptors = 0;
+ continue;
+ }
+ memcpy( p_en->p_es[i].p_descriptors, p_src->p_es[i].p_descriptors, p_src->p_es[i].i_descriptors );
+ p_en->p_es[i].i_descriptors = p_src->p_es[i].i_descriptors;
+ }
+
+ return p_en;
+
+error:
+ en50221_capmt_Delete( p_en );
+ return NULL;
+}
+
#endif
=====================================
modules/access/dtv/linux.c
=====================================
@@ -632,7 +632,7 @@ float dvb_get_snr (dvb_device_t *d)
return snr / 65535.;
}
-bool dvb_set_ca_pmt (dvb_device_t *d, en50221_capmt_info_t *p_capmtinfo)
+bool dvb_set_ca_pmt (dvb_device_t *d, const en50221_capmt_info_t *p_capmtinfo)
{
if (d->cam != NULL)
{
=====================================
modules/demux/mpeg/ts.c
=====================================
@@ -845,12 +845,17 @@ void UpdatePESFilters( demux_t *p_demux, bool b_all )
{
ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
+ const bool b_prev_selection = p_pmt->b_selected;
if( (p_sys->b_default_selection && !p_sys->b_access_control) || b_all )
p_pmt->b_selected = true;
else
p_pmt->b_selected = ProgramIsSelected( p_sys, p_pmt->i_number );
+ /* Notify CI for program selection changes */
+ if( b_prev_selection != p_pmt->b_selected )
+ SendCAPMTUpdate( p_demux, p_pmt );
+
if( p_pmt->b_selected )
{
p_pmt_pid->i_flags |= FLAG_FILTERED;
=====================================
modules/demux/mpeg/ts_psi.c
=====================================
@@ -67,6 +67,7 @@ struct ts_psi_context_t
{
dvbpsi_t *p_handle;
void (*pf_detach)(dvbpsi_t *);
+ en50221_capmt_info_t *p_capmt;
};
static void PIDFillFormat( demux_t *, ts_stream_t *p_pes, int i_stream_type, ts_transport_type_t * );
@@ -1841,6 +1842,16 @@ static en50221_capmt_info_t * CreateCAPMTInfo( const dvbpsi_pmt_t *p_pmt )
return p_en;
}
+void SendCAPMTUpdate( demux_t *p_demux, const ts_pmt_t *p_pmt )
+{
+ demux_sys_t *p_sys = p_demux->p_sys;
+ if( !p_pmt->p_ctx->p_capmt )
+ return;
+ if( vlc_stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA,
+ (void *)p_pmt->p_ctx->p_capmt ) != VLC_SUCCESS )
+ msg_Warn( p_demux, "Impos");
+}
+
static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
{
demux_t *p_demux = data;
@@ -1848,6 +1859,7 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
ts_pid_t *pmtpid = NULL;
ts_pmt_t *p_pmt = NULL;
+ bool b_encryption = false;
msg_Dbg( p_demux, "PMTCallBack called for program %d", p_dvbpsipmt->i_program_number );
@@ -1974,6 +1986,8 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
msg_Dbg( p_demux, " - ES descriptor %s 0x%x", psz_desc, p_dr->i_tag );
else
msg_Dbg( p_demux, " - ES descriptor tag 0x%x", p_dr->i_tag );
+
+ b_encryption |= (p_dr->i_tag == 0x09);
}
const bool b_pid_inuse = ( pespid->type == TYPE_STREAM );
@@ -2029,6 +2043,7 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
{
msg_Dbg( p_demux, " - ES descriptor : CA (0x9) SysID 0x%x",
(p_dr->p_data[0] << 8) | p_dr->p_data[1] );
+ b_encryption = true;
}
const bool b_create_es = (p_pes->p_es->fmt.i_cat != UNKNOWN_ES);
@@ -2097,30 +2112,19 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
AddAndCreateES( p_demux, pespid, false );
}
- /* Set CAM descrambling */
- if( ProgramIsSelected( p_sys, p_pmt->i_number ) )
+
+
+ /* Install CAM descrambling */
+ if ( p_sys->standard == TS_STANDARD_ARIB && p_sys->stream == p_demux->s && b_encryption )
{
- en50221_capmt_info_t *p_en = CreateCAPMTInfo( p_dvbpsipmt );
- if( p_en )
+ stream_t *wrapper = ts_stream_wrapper_New( p_demux->s );
+ if( wrapper )
{
- /* DTV/CAM takes ownership of en50221_capmt_info_t on success */
- if( vlc_stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA,
- (void *)p_en ) != VLC_SUCCESS )
+ p_sys->stream = vlc_stream_FilterNew( wrapper, "aribcam" );
+ if( !p_sys->stream )
{
- en50221_capmt_Delete( p_en );
- if ( p_sys->standard == TS_STANDARD_ARIB && p_sys->stream == p_demux->s )
- {
- stream_t *wrapper = ts_stream_wrapper_New( p_demux->s );
- if( wrapper )
- {
- p_sys->stream = vlc_stream_FilterNew( wrapper, "aribcam" );
- if( !p_sys->stream )
- {
- vlc_stream_Delete( wrapper );
- p_sys->stream = p_demux->s;
- }
- }
- }
+ vlc_stream_Delete( wrapper );
+ p_sys->stream = p_demux->s;
}
}
}
@@ -2214,6 +2218,11 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_dvbpsipmt )
p_pmt->i_number, i_cand );
}
+ /* Create CAPMT for this ES */
+ if( p_pmt->p_ctx->p_capmt )
+ en50221_capmt_Delete( p_pmt->p_ctx->p_capmt );
+ p_pmt->p_ctx->p_capmt = CreateCAPMTInfo( p_dvbpsipmt );
+
UpdatePESFilters( p_demux, p_sys->seltype == PROGRAM_ALL );
/* Probe Boundaries */
@@ -2377,6 +2386,8 @@ void ts_psi_context_Delete( ts_psi_context_t *p_ctx )
assert( p_ctx->pf_detach );
p_ctx->pf_detach( p_ctx->p_handle );
}
+ if( p_ctx->p_capmt )
+ en50221_capmt_Delete( p_ctx->p_capmt );
dvbpsi_delete( p_ctx->p_handle );
free( p_ctx );
}
@@ -2394,6 +2405,7 @@ ts_psi_context_t * ts_psi_context_New( demux_t *p_demux )
}
p_ctx->p_handle->p_sys = (void *) p_demux;
p_ctx->pf_detach = NULL;
+ p_ctx->p_capmt = NULL;
}
return p_ctx;
}
=====================================
modules/demux/mpeg/ts_psi.h
=====================================
@@ -38,5 +38,6 @@ bool ts_psi_PAT_Attach( ts_pid_t *, void * );
void ts_psi_Packet_Push( ts_pid_t *, const uint8_t * );
int UserPmt( demux_t *p_demux, const char * );
+void SendCAPMTUpdate( demux_t *, const ts_pmt_t * );
#endif
=====================================
modules/demux/mpeg/ts_streams.c
=====================================
@@ -95,6 +95,7 @@ ts_pmt_t *ts_pmt_New( demux_t *p_demux )
ARRAY_INIT( pmt->e_streams );
+ //pmt->pmtcache = NULL;
pmt->i_version = -1;
pmt->i_number = -1;
pmt->i_pid_pcr = 0x1FFF;
=====================================
modules/demux/mpeg/ts_streams_private.h
=====================================
@@ -77,6 +77,9 @@ struct ts_pmt_t
stime_t i_last_dts;
uint64_t i_last_dts_byte;
+ /* CA */
+ //en50221_capmt_info_t *capmt;
+
/* ARIB specific */
struct
{
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/de4e0e33b11ba3470683138c9f8df5e771bd3092...678d0466d0d625df985166f44659bf83f27f8b02
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/de4e0e33b11ba3470683138c9f8df5e771bd3092...678d0466d0d625df985166f44659bf83f27f8b02
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list