[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