[vlc-devel] [PATCH] epg: API changes

Francois Cartegnie fcvlcdev at free.fr
Wed Sep 14 18:20:14 CEST 2016


EIT structs and Events and should be referenced by their
unique ID.
First step towards in depth changes to epg_t et epg_event_t.
---
 include/vlc_epg.h            |  51 ++++++++++-----
 include/vlc_plugin.h         |   4 +-
 modules/demux/mpeg/ts_psip.c |  28 +++++++--
 modules/demux/mpeg/ts_si.c   |  36 ++++++++---
 modules/demux/ty.c           |  35 +++++++----
 src/input/es_out_timeshift.c |  14 +----
 src/input/item.c             |  22 +++----
 src/libvlccore.sym           |   6 +-
 src/misc/epg.c               | 146 ++++++++++++++++++++++++++-----------------
 src/video_output/video_epg.c |   8 ++-
 test/src/misc/epg.c          |  26 +++++---
 11 files changed, 241 insertions(+), 135 deletions(-)

diff --git a/include/vlc_epg.h b/include/vlc_epg.h
index c0fd0f5..c4ff661 100644
--- a/include/vlc_epg.h
+++ b/include/vlc_epg.h
@@ -31,8 +31,9 @@
 
 typedef struct
 {
-    int64_t i_start;    /* Interpreted as a value return by time() */
-    int     i_duration;    /* Duration of the event in second */
+    int64_t  i_start;    /* Interpreted as a value return by time() */
+    uint32_t i_duration; /* Duration of the event in second */
+    uint16_t i_id;       /* Unique event id withing the event set */
 
     char    *psz_name;
     char    *psz_short_description;
@@ -44,37 +45,46 @@ typedef struct
 typedef struct
 {
     char            *psz_name;
-    vlc_epg_event_t *p_current; /* Can be null or should be the same than one of pp_event entry */
+    vlc_epg_event_t *p_current;  /* Can be null or should be the same than one of pp_event entry */
+    uint32_t         i_id;       /* Unique identifier for this table / events (partial sets) */
+    uint16_t         i_source_id;/* Channel / Program reference id this epg relates to */
 
-    int             i_event;
+    size_t            i_event;
     vlc_epg_event_t **pp_event;
 } vlc_epg_t;
 
 /**
- * It initializes a vlc_epg_t.
+ * Creates a new vlc_epg_event_t*
  *
- * You must call vlc_epg_Clean to release the associated resource.
+ * You must call vlc_epg_event_Delete to release the associated resources.
+ *
+ * \p i_id is the event unique id
+ * \p i_start start in epoch time
+ * \p i_duration event duration in seconds
  */
-VLC_API void vlc_epg_Init(vlc_epg_t *p_epg, const char *psz_name);
+VLC_API vlc_epg_event_t * vlc_epg_event_New(uint16_t i_id,
+                                            int64_t i_start, uint32_t i_duration);
 
 /**
- * It releases all resources associated to a vlc_epg_t
+ * Releases a vlc_epg_event_t*.
  */
-VLC_API void vlc_epg_Clean(vlc_epg_t *p_epg);
+VLC_API void vlc_epg_event_Delete(vlc_epg_event_t *p_event);
 
 /**
- * It creates and appends a new vlc_epg_event_t to a vlc_epg_t.
+ * Returns a vlc_epg_event_t * duplicated from \p p_src.
  *
- * \see vlc_epg_t for the definitions of the parameters.
  */
-VLC_API void vlc_epg_AddEvent(vlc_epg_t *p_epg, int64_t i_start, int i_duration, const char *psz_name, const char *psz_short_description, const char *psz_description, uint8_t i_rating );
+VLC_API vlc_epg_event_t * vlc_epg_event_Duplicate(const vlc_epg_event_t *p_src);
 
 /**
  * It creates a new vlc_epg_t*
  *
  * You must call vlc_epg_Delete to release the associated resource.
+ *
+ * \p i_id is computed unique id depending on standard (table id, eit number)
+ * \p i_source_id is the associated program number
  */
-VLC_API vlc_epg_t * vlc_epg_New(const char *psz_name) VLC_USED;
+VLC_API vlc_epg_t * vlc_epg_New(uint32_t i_id, uint16_t i_source_id);
 
 /**
  * It releases a vlc_epg_t*.
@@ -82,6 +92,14 @@ VLC_API vlc_epg_t * vlc_epg_New(const char *psz_name) VLC_USED;
 VLC_API void vlc_epg_Delete(vlc_epg_t *p_epg);
 
 /**
+ * It appends a new vlc_epg_event_t to a vlc_epg_t.
+ * Takes ownership of \p p_evt or returns false
+ *
+ * \p p_evt a vlc_epg_event_t * created with vlc_epg_event_New.
+ */
+VLC_API bool vlc_epg_AddEvent(vlc_epg_t *p_epg, vlc_epg_event_t *p_evt);
+
+/**
  * It set the current event of a vlc_epg_t given a start time
  */
 VLC_API void vlc_epg_SetCurrent(vlc_epg_t *p_epg, int64_t i_start);
@@ -89,9 +107,14 @@ VLC_API void vlc_epg_SetCurrent(vlc_epg_t *p_epg, int64_t i_start);
 /**
  * It merges all the event of \p p_src and \p p_dst into \p p_dst.
  *
- * \p p_src is not modified.
  */
 VLC_API void vlc_epg_Merge(vlc_epg_t *p_dst, const vlc_epg_t *p_src);
 
+/**
+ * Returns a duplicated \p p_src and its associated events.
+ *
+ */
+VLC_API vlc_epg_t * vlc_epg_Duplicate(const vlc_epg_t *p_src);
+
 #endif
 
diff --git a/include/vlc_plugin.h b/include/vlc_plugin.h
index 42c3288..bd5c154 100644
--- a/include/vlc_plugin.h
+++ b/include/vlc_plugin.h
@@ -188,8 +188,8 @@ enum vlc_module_properties
 /**
  * Current plugin ABI version
  */
-# define MODULE_SYMBOL 3_0_0b
-# define MODULE_SUFFIX "__3_0_0b"
+# define MODULE_SYMBOL 3_0_0c
+# define MODULE_SUFFIX "__3_0_0c"
 
 /*****************************************************************************
  * Add a few defines. You do not want to read this section. Really.
diff --git a/modules/demux/mpeg/ts_psip.c b/modules/demux/mpeg/ts_psip.c
index a9ee265..9a75bc9 100644
--- a/modules/demux/mpeg/ts_psip.c
+++ b/modules/demux/mpeg/ts_psip.c
@@ -55,6 +55,17 @@
 
 #include <assert.h>
 
+static inline char *grab_notempty( char **ppsz )
+{
+    char *psz_ret = NULL;
+    if( *ppsz && **ppsz )
+    {
+        psz_ret = *ppsz;
+        *ppsz = NULL;
+    }
+    return psz_ret;
+}
+
 /*
  * Decoders activation order due to dependencies,
  * and because callbacks will be fired once per MGT/VCT version
@@ -368,8 +379,15 @@ static time_t ATSC_AddVLCEPGEvent( demux_t *p_demux, ts_psip_context_t *p_basect
         msg_Dbg( p_demux, "EIT Event time %ld +%d %s id 0x%x",
                  i_start, p_evt->i_length_seconds, psz_title, p_evt->i_event_id );
 #endif
-        vlc_epg_AddEvent( p_epg, i_start, p_evt->i_length_seconds,
-                          psz_title, psz_shortdesc_text, psz_longdesc_text, 0 );
+        vlc_epg_event_t *p_epgevt = vlc_epg_event_New( p_evt->i_event_id, i_start, p_evt->i_length_seconds );
+        if( p_epgevt )
+        {
+            p_epgevt->psz_name = grab_notempty( &psz_title );
+            p_epgevt->psz_short_description = grab_notempty( &psz_shortdesc_text );
+            p_epgevt->psz_description = grab_notempty( &psz_longdesc_text );
+            if( !vlc_epg_AddEvent( p_epg, p_epgevt ) )
+                vlc_epg_event_Delete( p_epgevt );
+        }
     }
 
     free( psz_title );
@@ -417,7 +435,8 @@ static void ATSC_EIT_Callback( void *p_pid, dvbpsi_atsc_eit_t* p_eit )
     EIT_DEBUG_TIMESHIFT( i_current_time );
 
 
-    vlc_epg_t *p_epg = vlc_epg_New( NULL );
+    vlc_epg_t *p_epg = vlc_epg_New( p_basectx->i_tabletype - ATSC_TABLE_TYPE_EIT_0,
+                                    i_program_number );
     if( !p_epg )
     {
         dvbpsi_atsc_DeleteEIT( p_eit );
@@ -510,7 +529,8 @@ static void ATSC_ETT_Callback( void *p_pid, dvbpsi_atsc_ett_t *p_ett )
 #ifdef ATSC_DEBUG_EIT
                     msg_Dbg( p_demux, "Should update EIT %x (matched EIT)", p_event->i_event_id );
 #endif
-                    vlc_epg_t *p_epg = vlc_epg_New( NULL );
+                    vlc_epg_t *p_epg = vlc_epg_New( p_basectx->i_tabletype - ATSC_TABLE_TYPE_ETT_0,
+                                                    i_program_number );
                     if( likely(p_epg) )
                     {
                         (void)
diff --git a/modules/demux/mpeg/ts_si.c b/modules/demux/mpeg/ts_si.c
index 66f670d..d175e25 100644
--- a/modules/demux/mpeg/ts_si.c
+++ b/modules/demux/mpeg/ts_si.c
@@ -62,6 +62,17 @@
     } while(0);
 #endif
 
+static inline char *grab_notempty( char **ppsz )
+{
+    char *psz_ret = NULL;
+    if( *ppsz && **ppsz )
+    {
+        psz_ret = *ppsz;
+        *ppsz = NULL;
+    }
+    return psz_ret;
+}
+
 static void SINewTableCallBack( dvbpsi_t *h, uint8_t i_table_id,
                                 uint16_t i_extension, void *p_pid_cbdata );
 
@@ -383,7 +394,7 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit )
              p_eit->i_ts_id, p_eit->i_network_id,
              p_eit->i_segment_last_section_number, p_eit->i_last_table_id );
 
-    p_epg = vlc_epg_New( NULL );
+    p_epg = vlc_epg_New( p_eit->i_table_id, p_eit->i_extension );
     for( p_evt = p_eit->p_first_event; p_evt; p_evt = p_evt->p_next )
     {
         dvbpsi_descriptor_t *p_dr;
@@ -548,14 +559,21 @@ static void EITCallBack( demux_t *p_demux, dvbpsi_eit_t *p_eit )
         /* */
         if( i_start > 0 )
         {
-            vlc_epg_AddEvent( p_epg, i_start, i_duration,
-                              (psz_name && *psz_name) ? psz_name : NULL,
-                              (psz_text && *psz_text) ? psz_text : NULL,
-                              (psz_extra && *psz_extra) ? psz_extra : NULL, i_min_age );
-
-            /* Update "now playing" field */
-            if( b_current_event )
-                vlc_epg_SetCurrent( p_epg, i_start );
+            vlc_epg_event_t *p_epgevt = vlc_epg_event_New( p_evt->i_event_id,
+                                                           i_start, i_duration );
+            if( p_epgevt )
+            {
+                p_epgevt->psz_name = grab_notempty( &psz_name );
+                p_epgevt->psz_short_description = grab_notempty( &psz_text );
+                p_epgevt->psz_description = grab_notempty( &psz_extra );
+                p_epgevt->i_rating = i_min_age;
+                if( !vlc_epg_AddEvent( p_epg, p_epgevt ) )
+                    vlc_epg_event_Delete( p_epgevt );
+
+                /* Update "now playing" field */
+                if( b_current_event )
+                    vlc_epg_SetCurrent( p_epg, i_start );
+            }
         }
 
         free( psz_name );
diff --git a/modules/demux/ty.c b/modules/demux/ty.c
index eecb986..1c66941 100644
--- a/modules/demux/ty.c
+++ b/modules/demux/ty.c
@@ -1430,7 +1430,6 @@ static void DemuxDecodeXds( demux_t *p_demux, uint8_t d1, uint8_t d2 )
     {
         xds_meta_t *m = &p_sys->xds.meta;
         vlc_meta_t *p_meta;
-        vlc_epg_t *p_epg;
 
         /* Channel meta data */
         p_meta = vlc_meta_New();
@@ -1444,20 +1443,32 @@ static void DemuxDecodeXds( demux_t *p_demux, uint8_t d1, uint8_t d2 )
         vlc_meta_Delete( p_meta );
 
         /* Event meta data (current/future) */
-        p_epg = vlc_epg_New( NULL );
         if( m->current.psz_name )
         {
-            vlc_epg_AddEvent( p_epg, 0, 0, m->current.psz_name, NULL, NULL, 0 );
-            //if( m->current.psz_rating )
-            //  TODO but VLC cannot yet handle rating per epg event
-            vlc_epg_SetCurrent( p_epg, 0 );
-        }
-        if( m->future.psz_name )
-        {
+            vlc_epg_t *p_epg = vlc_epg_New( TY_ES_GROUP, TY_ES_GROUP );
+            if ( p_epg )
+            {
+                vlc_epg_event_t *p_evt = vlc_epg_event_New( 0, 0, 0 );
+                if ( p_evt )
+                {
+                    if( m->current.psz_name )
+                        p_evt->psz_name = strdup( m->current.psz_name );
+                    if( !vlc_epg_AddEvent( p_epg, p_evt ) )
+                        vlc_epg_event_Delete( p_evt );
+                }
+                //if( m->current.psz_rating )
+                //  TODO but VLC cannot yet handle rating per epg event
+                vlc_epg_SetCurrent( p_epg, 0 );
+
+                if( m->future.psz_name )
+                {
+                }
+                if( p_epg->i_event > 0 )
+                    es_out_Control( p_demux->out, ES_OUT_SET_GROUP_EPG,
+                                    TY_ES_GROUP, p_epg );
+                vlc_epg_Delete( p_epg );
+            }
         }
-        if( p_epg->i_event > 0 )
-            es_out_Control( p_demux->out, ES_OUT_SET_GROUP_EPG, TY_ES_GROUP, p_epg );
-        vlc_epg_Delete( p_epg );
     }
     p_demux->p_sys->xds.b_meta_changed = false;
 }
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 4420cfc..6914ced 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -1426,21 +1426,9 @@ static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_co
 
         if( b_copy )
         {
-            p_cmd->u.control.u.int_epg.p_epg = vlc_epg_New( p_epg->psz_name );
+            p_cmd->u.control.u.int_epg.p_epg = vlc_epg_Duplicate( p_epg );
             if( !p_cmd->u.control.u.int_epg.p_epg )
                 return VLC_EGENERIC;
-            for( int i = 0; i < p_epg->i_event; i++ )
-            {
-                vlc_epg_event_t *p_evt = p_epg->pp_event[i];
-
-                vlc_epg_AddEvent( p_cmd->u.control.u.int_epg.p_epg,
-                                  p_evt->i_start, p_evt->i_duration,
-                                  p_evt->psz_name,
-                                  p_evt->psz_short_description,
-                                  p_evt->psz_description, 0 );
-            }
-            vlc_epg_SetCurrent( p_cmd->u.control.u.int_epg.p_epg,
-                                p_epg->p_current ? p_epg->p_current->i_start : -1 );
         }
         else
         {
diff --git a/src/input/item.c b/src/input/item.c
index 65ff7b9..e39e34e 100644
--- a/src/input/item.c
+++ b/src/input/item.c
@@ -906,26 +906,24 @@ void input_item_SetEpg( input_item_t *p_item, const vlc_epg_t *p_update )
     vlc_epg_t *p_epg = NULL;
     for( int i = 0; i < p_item->i_epg; i++ )
     {
-        vlc_epg_t *p_tmp = p_item->pp_epg[i];
-
-        if( (p_tmp->psz_name == NULL) != (p_update->psz_name == NULL) )
-            continue;
-        if( p_tmp->psz_name && p_update->psz_name && strcmp(p_tmp->psz_name, p_update->psz_name) )
-            continue;
-
-        p_epg = p_tmp;
-        break;
+        if( p_item->pp_epg[i]->i_source_id == p_update->i_source_id )
+        {
+            p_epg = p_item->pp_epg[i];
+            break;
+        }
     }
 
     /* */
     if( !p_epg )
     {
-        p_epg = vlc_epg_New( p_update->psz_name );
+        p_epg = vlc_epg_Duplicate( p_update );
         if( p_epg )
             TAB_APPEND( p_item->i_epg, p_item->pp_epg, p_epg );
     }
-    if( p_epg )
+    else
+    {
         vlc_epg_Merge( p_epg, p_update );
+    }
 
     vlc_mutex_unlock( &p_item->lock );
 
@@ -940,7 +938,7 @@ void input_item_SetEpg( input_item_t *p_item, const vlc_epg_t *p_update )
     input_item_DelInfo( p_item, psz_epg, NULL );
 
     vlc_mutex_lock( &p_item->lock );
-    for( int i = 0; i < p_epg->i_event; i++ )
+    for( size_t i = 0; i < p_epg->i_event; i++ )
     {
         const vlc_epg_event_t *p_evt = p_epg->pp_event[i];
         time_t t_start = (time_t)p_evt->i_start;
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index cd56a3d..5a7de9e 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -682,10 +682,12 @@ vlc_timer_getoverrun
 vlc_timer_schedule
 vlc_towc
 vlc_ureduce
-vlc_epg_Init
-vlc_epg_Clean
+vlc_epg_event_Delete
+vlc_epg_event_Duplicate
+vlc_epg_event_New
 vlc_epg_New
 vlc_epg_Delete
+vlc_epg_Duplicate
 vlc_epg_AddEvent
 vlc_epg_SetCurrent
 vlc_epg_Merge
diff --git a/src/misc/epg.c b/src/misc/epg.c
index f2cfa98..3c2b354 100644
--- a/src/misc/epg.c
+++ b/src/misc/epg.c
@@ -32,89 +32,100 @@
 #include <vlc_common.h>
 #include <vlc_epg.h>
 
-static void vlc_epg_Event_Delete( vlc_epg_event_t *p_evt )
+static void vlc_epg_event_Clean(vlc_epg_event_t *p_event)
 {
-    free( p_evt->psz_name );
-    free( p_evt->psz_short_description );
-    free( p_evt->psz_description );
-    free( p_evt );
+    free(p_event->psz_description);
+    free(p_event->psz_short_description);
+    free(p_event->psz_name);
 }
 
-static vlc_epg_event_t * vlc_epg_Event_New( int64_t i_start, int i_duration,
-                                            const char *psz_name, const char *psz_short_description,
-                                            const char *psz_description, uint8_t i_rating )
+void vlc_epg_event_Delete(vlc_epg_event_t *p_event)
 {
-    vlc_epg_event_t *p_evt = malloc( sizeof(*p_evt) );
+    vlc_epg_event_Clean(p_event);
+    free(p_event);
+}
+
+static void vlc_epg_event_Init(vlc_epg_event_t *p_event, uint16_t i_id,
+                               int64_t i_start, uint32_t i_duration)
+{
+    memset(p_event, 0, sizeof(*p_event));
+    p_event->i_start = i_start;
+    p_event->i_id = i_id;
+    p_event->i_duration = i_duration;
+}
+
+vlc_epg_event_t * vlc_epg_event_New(uint16_t i_id,
+                                    int64_t i_start, uint32_t i_duration)
+{
+    vlc_epg_event_t *p_event = (vlc_epg_event_t *) malloc(sizeof(*p_event));
+    if(p_event)
+        vlc_epg_event_Init(p_event, i_id, i_start, i_duration);
+
+    return p_event;
+}
+
+vlc_epg_event_t * vlc_epg_event_Duplicate( const vlc_epg_event_t *p_src )
+{
+    vlc_epg_event_t *p_evt = vlc_epg_event_New( p_src->i_id, p_src->i_start,
+                                                p_src->i_duration );
     if( likely(p_evt) )
     {
-        p_evt->i_start = i_start;
-        p_evt->i_duration = i_duration;
-        p_evt->psz_name = psz_name ? strdup( psz_name ) : NULL;
-        p_evt->psz_short_description = psz_short_description ? strdup( psz_short_description ) : NULL;
-        p_evt->psz_description = psz_description ? strdup( psz_description ) : NULL;
-        p_evt->i_rating = i_rating;
+        if( p_src->psz_description )
+            p_evt->psz_description = strdup( p_src->psz_description );
+        if( p_src->psz_name )
+            p_evt->psz_name = strdup( p_src->psz_name );
+        if( p_src->psz_short_description )
+            p_evt->psz_short_description = strdup( p_src->psz_short_description );
+        p_evt->i_rating = p_src->i_rating;
     }
     return p_evt;
 }
 
-static inline vlc_epg_event_t * vlc_epg_Event_Duplicate( const vlc_epg_event_t *p_evt )
+static void vlc_epg_Init( vlc_epg_t *p_epg, uint32_t i_id, uint16_t i_source_id )
 {
-    return vlc_epg_Event_New( p_evt->i_start, p_evt->i_duration,
-                              p_evt->psz_name, p_evt->psz_short_description,
-                              p_evt->psz_description, p_evt->i_rating );
-}
-
-void vlc_epg_Init( vlc_epg_t *p_epg, const char *psz_name )
-{
-    p_epg->psz_name = psz_name ? strdup( psz_name ) : NULL;
+    p_epg->i_id = i_id;
+    p_epg->i_source_id = i_source_id;
+    p_epg->psz_name = NULL;
     p_epg->p_current = NULL;
     TAB_INIT( p_epg->i_event, p_epg->pp_event );
 }
 
-void vlc_epg_Clean( vlc_epg_t *p_epg )
+static void vlc_epg_Clean( vlc_epg_t *p_epg )
 {
-    int i;
+    size_t i;
     for( i = 0; i < p_epg->i_event; i++ )
-        vlc_epg_Event_Delete( p_epg->pp_event[i] );
+        vlc_epg_event_Delete( p_epg->pp_event[i] );
     TAB_CLEAN( p_epg->i_event, p_epg->pp_event );
     free( p_epg->psz_name );
 }
 
-void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration,
-                       const char *psz_name, const char *psz_short_description,
-                       const char *psz_description, uint8_t i_rating )
+bool vlc_epg_AddEvent( vlc_epg_t *p_epg, vlc_epg_event_t *p_evt )
 {
-    vlc_epg_event_t *p_evt = vlc_epg_Event_New( i_start, i_duration,
-                                                psz_name, psz_short_description,
-                                                psz_description, i_rating );
-    if( unlikely(!p_evt) )
-        return;
-
-    int i_pos = -1;
+    ssize_t i_pos = -1;
 
     /* Insertions are supposed in sequential order first */
     if( p_epg->i_event )
     {
-        if( p_epg->pp_event[0]->i_start > i_start )
+        if( p_epg->pp_event[0]->i_start > p_evt->i_start )
         {
             i_pos = 0;
         }
-        else if ( p_epg->pp_event[p_epg->i_event - 1]->i_start >= i_start )
+        else if ( p_epg->pp_event[p_epg->i_event - 1]->i_start >= p_evt->i_start )
         {
             /* Do bisect search lower start time entry */
-            int i_lower = 0;
-            int i_upper = p_epg->i_event - 1;
+            size_t i_lower = 0;
+            size_t i_upper = p_epg->i_event - 1;
 
             while( i_lower < i_upper )
             {
-                int i_split = ( (size_t)i_lower + i_upper ) / 2;
+                size_t i_split = ( i_lower + i_upper ) / 2;
                 vlc_epg_event_t *p_cur = p_epg->pp_event[i_split];
 
-                if( p_cur->i_start < i_start )
+                if( p_cur->i_start < p_evt->i_start )
                 {
                     i_lower = i_split + 1;
                 }
-                else if ( p_cur->i_start >= i_start )
+                else if ( p_cur->i_start >= p_evt->i_start )
                 {
                     i_upper = i_split;
                 }
@@ -125,13 +136,14 @@ void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration,
 
     if( i_pos != -1 )
     {
-        if( p_epg->pp_event[i_pos]->i_start == i_start )/* There can be only one event at same time */
+        /* There can be only one event at same time */
+        if( p_epg->pp_event[i_pos]->i_start == p_evt->i_start )
         {
-            vlc_epg_Event_Delete( p_epg->pp_event[i_pos] );
+            vlc_epg_event_Delete( p_epg->pp_event[i_pos] );
             if( p_epg->p_current == p_epg->pp_event[i_pos] )
                 p_epg->p_current = p_evt;
             p_epg->pp_event[i_pos] = p_evt;
-            return;
+            return true;
         }
         else
         {
@@ -140,13 +152,15 @@ void vlc_epg_AddEvent( vlc_epg_t *p_epg, int64_t i_start, int i_duration,
     }
     else
         TAB_APPEND( p_epg->i_event, p_epg->pp_event, p_evt );
+
+    return true;
 }
 
-vlc_epg_t *vlc_epg_New( const char *psz_name )
+vlc_epg_t *vlc_epg_New( uint32_t i_id, uint16_t i_source_id )
 {
     vlc_epg_t *p_epg = malloc( sizeof(*p_epg) );
     if( p_epg )
-        vlc_epg_Init( p_epg, psz_name );
+        vlc_epg_Init( p_epg, i_id, i_source_id );
     return p_epg;
 }
 
@@ -158,7 +172,7 @@ void vlc_epg_Delete( vlc_epg_t *p_epg )
 
 void vlc_epg_SetCurrent( vlc_epg_t *p_epg, int64_t i_start )
 {
-    int i;
+    size_t i;
     p_epg->p_current = NULL;
     if( i_start < 0 )
         return;
@@ -180,7 +194,7 @@ static void vlc_epg_Prune( vlc_epg_t *p_dst )
     {
         while( p_dst->i_event > 1 && p_dst->pp_event[0] != p_dst->p_current && p_dst->pp_event[1] != p_dst->p_current )
         {
-            vlc_epg_Event_Delete( p_dst->pp_event[0] );
+            vlc_epg_event_Delete( p_dst->pp_event[0] );
             TAB_ERASE( p_dst->i_event, p_dst->pp_event, 0 );
         }
     }
@@ -191,13 +205,13 @@ void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg )
     if( p_src_epg->i_event == 0 )
         return;
 
-    int i_dst=0;
-    int i_src=0;
+    size_t i_dst=0;
+    size_t i_src=0;
     for( ; i_src < p_src_epg->i_event; i_src++ )
     {
         bool b_current = ( p_src_epg->pp_event[i_src] == p_src_epg->p_current );
 
-        vlc_epg_event_t *p_src = vlc_epg_Event_Duplicate( p_src_epg->pp_event[i_src] );
+        vlc_epg_event_t *p_src = vlc_epg_event_Duplicate( p_src_epg->pp_event[i_src] );
         if( unlikely(!p_src) )
             return;
         const int64_t i_src_end = p_src->i_start + p_src->i_duration;
@@ -217,7 +231,7 @@ void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg )
             /* overlap case: appended would contain current's end */
                     ( i_dst_end > p_src->i_start && i_dst_end <= i_src_end ) )
             {
-                vlc_epg_Event_Delete( p_dst );
+                vlc_epg_event_Delete( p_dst );
                 if( p_dst_epg->p_current == p_dst )
                 {
                     b_current |= true;
@@ -239,7 +253,7 @@ void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg )
     /* Remaining/trailing ones */
     for( ; i_src < p_src_epg->i_event; i_src++ )
     {
-        vlc_epg_event_t *p_src = vlc_epg_Event_Duplicate( p_src_epg->pp_event[i_src] );
+        vlc_epg_event_t *p_src = vlc_epg_event_Duplicate( p_src_epg->pp_event[i_src] );
         if( unlikely(!p_src) )
             return;
         TAB_APPEND( p_dst_epg->i_event, p_dst_epg->pp_event, p_src );
@@ -249,3 +263,23 @@ void vlc_epg_Merge( vlc_epg_t *p_dst_epg, const vlc_epg_t *p_src_epg )
 
     vlc_epg_Prune( p_dst_epg );
 }
+
+vlc_epg_t * vlc_epg_Duplicate( const vlc_epg_t *p_src )
+{
+    vlc_epg_t *p_epg = vlc_epg_New( p_src->i_id, p_src->i_source_id );
+    if( p_epg )
+    {
+        p_epg->psz_name = ( p_src->psz_name ) ? strdup( p_src->psz_name ) : NULL;
+        for( size_t i=0; i<p_epg->i_event; i++ )
+        {
+            vlc_epg_event_t *p_dup = vlc_epg_event_Duplicate( p_epg->pp_event[i] );
+            if( p_dup )
+            {
+                if( p_src->p_current == p_epg->pp_event[i] )
+                    p_epg->p_current = p_dup;
+                TAB_APPEND( p_epg->i_event, p_epg->pp_event, p_dup );
+            }
+        }
+    }
+    return p_epg;
+}
diff --git a/src/video_output/video_epg.c b/src/video_output/video_epg.c
index ce149e9..ef2326e 100644
--- a/src/video_output/video_epg.c
+++ b/src/video_output/video_epg.c
@@ -289,8 +289,12 @@ int vout_OSDEpg(vout_thread_t *vout, input_item_t *input)
             if (tmp->p_current &&
                 tmp->p_current->psz_name &&
                 !strcmp(tmp->p_current->psz_name, now_playing)) {
-                epg = vlc_epg_New(tmp->psz_name);
-                vlc_epg_Merge(epg, tmp);
+                 epg = vlc_epg_New(tmp->i_id, tmp->i_source_id);
+                if(epg){
+                    if(tmp->psz_name)
+                        epg->psz_name = strdup(tmp->psz_name);
+                    vlc_epg_Merge(epg, tmp);
+                }
                 break;
             }
         }
diff --git a/test/src/misc/epg.c b/test/src/misc/epg.c
index 96eeb86..63fe760 100644
--- a/test/src/misc/epg.c
+++ b/test/src/misc/epg.c
@@ -59,7 +59,15 @@ static void assert_events( const vlc_epg_t *p_epg, const char *psz_names, int i_
 }
 
 #define EPG_ADD(epg, start, duration, a) \
-    vlc_epg_AddEvent( epg, start, duration, a, NULL, NULL, 0 )
+    do {\
+        vlc_epg_event_t *p_evt = vlc_epg_event_New( start, start, duration );\
+        if( p_evt )\
+        {\
+            p_evt->psz_name = strdup( a );\
+            if( !p_evt->psz_name || !vlc_epg_AddEvent( epg, p_evt ) )\
+                vlc_epg_event_Delete( p_evt );\
+        }\
+    } while( 0 )
 
 int main( void )
 {
@@ -69,7 +77,7 @@ int main( void )
 
     /* Simple insert/current test */
     printf("--test %d\n", i++);
-    vlc_epg_t *p_epg = vlc_epg_New( NULL );
+    vlc_epg_t *p_epg = vlc_epg_New( 0, 0 );
     assert(p_epg);
     EPG_ADD( p_epg,  42, 20, "A" );
     EPG_ADD( p_epg,  62, 20, "B" );
@@ -87,7 +95,7 @@ int main( void )
 
     /* Test reordering / head/tail inserts */
     printf("--test %d\n", i++);
-    p_epg = vlc_epg_New( NULL );
+    p_epg = vlc_epg_New( 0, 0 );
     assert(p_epg);
     EPG_ADD( p_epg,  82, 20, "C" );
     EPG_ADD( p_epg,  62, 20, "B" );
@@ -99,7 +107,7 @@ int main( void )
 
     /* Test reordering/bisect lookup on insert */
     printf("--test %d\n", i++);
-    p_epg = vlc_epg_New( NULL );
+    p_epg = vlc_epg_New( 0, 0 );
     assert(p_epg);
     EPG_ADD( p_epg, 142, 20, "F" );
     EPG_ADD( p_epg, 122, 20, "E" );
@@ -113,7 +121,7 @@ int main( void )
 
     /* Test deduplication and current pointer rebasing on insert */
     printf("--test %d\n", i++);
-    p_epg = vlc_epg_New( NULL );
+    p_epg = vlc_epg_New( 0, 0 );
     assert(p_epg);
     EPG_ADD( p_epg,  62, 20, "E" );
     EPG_ADD( p_epg,  62, 20, "F" );
@@ -130,7 +138,7 @@ int main( void )
 
     /* Test epg merging */
     printf("--test %d\n", i++);
-    p_epg = vlc_epg_New( NULL );
+    p_epg = vlc_epg_New( 0, 0 );
     assert(p_epg);
     EPG_ADD( p_epg, 142, 20, "F" );
     EPG_ADD( p_epg, 122, 20, "E" );
@@ -138,7 +146,7 @@ int main( void )
     EPG_ADD( p_epg,  62, 20, "B" );
     print_order( p_epg );
 
-    vlc_epg_t *p_epg2 = vlc_epg_New( NULL );
+    vlc_epg_t *p_epg2 = vlc_epg_New( 0, 0 );
     assert(p_epg2);
     EPG_ADD( p_epg2, 102, 20, "D" );
     EPG_ADD( p_epg2,  82, 20, "C" );
@@ -156,7 +164,7 @@ int main( void )
 
     /* Test event overlapping */
     printf("--test %d\n", i++);
-    p_epg = vlc_epg_New( NULL );
+    p_epg = vlc_epg_New( 0, 0 );
     assert(p_epg);
     EPG_ADD( p_epg,  42, 20, "A" );
     EPG_ADD( p_epg,  62, 20, "B" );
@@ -165,7 +173,7 @@ int main( void )
     print_order( p_epg );
     vlc_epg_SetCurrent( p_epg, 62 );
 
-    p_epg2 = vlc_epg_New( NULL );
+    p_epg2 = vlc_epg_New( 0, 0 );
     assert(p_epg2);
     EPG_ADD( p_epg2,  41, 30, "E" );
     print_order( p_epg2 );
-- 
2.7.4



More information about the vlc-devel mailing list