[dvblast-devel] Allow service and provider names to be set per output.

Georgi Chorbadzhiyski git at videolan.org
Mon Sep 12 12:11:57 CEST 2011


dvblast | branch: master | Georgi Chorbadzhiyski <gf at unixsol.org> | Sun Sep 11 14:38:34 2011 +0300| [5967be13fa30b811082f9d417b5c993a139902e0] | committer: Georgi Chorbadzhiyski

Allow service and provider names to be set per output.

This patch adds two new output options that allow service
name and provider name to be changed per output. The new
output options are /srvname=XXX and /srvprovider=YYY.

If option is not set the values from input stream are used.

Signed-off-by: Georgi Chorbadzhiyski <gf at unixsol.org>

> http://git.videolan.org/gitweb.cgi/dvblast.git/?a=commit;h=5967be13fa30b811082f9d417b5c993a139902e0
---

 NEWS      |    1 +
 README    |    5 ++++
 demux.c   |   69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 dvblast.c |   34 ++++++++++++++++++++++++++++++
 dvblast.h |    4 +++
 util.c    |   17 +++++++++++++++
 6 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 3e59ad7..d5502c9 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,7 @@ Changes between 1.2 and 2.0:
   * Add support for getting PAT/CAT/NIT/SDT tables in dvblastctl
   * Add support for getting PMT table for chosen service in dvblastctl
   * Add support for getting PID information (bps, error counters and more)
+  * Add support for setting service name and provider name per output
 
 Changes between 1.1 and 1.2:
 ----------------------------
diff --git a/README b/README
index c635c4a..9e00ff9 100644
--- a/README
+++ b/README
@@ -147,6 +147,11 @@ Available options include :
  /mtu=XXXX (sets the maximum UDP packet size)
  /ecm or /noecm (pass-through ECM packets or not)
  /emm or /noemm (pass-through EMM packets or not)
+ /srvname=Some_Channel (set service name in SDT)
+ /srvprovider=Some_Provider (set provider name in SDT)
+
+When setting text options like /srvname or /srvprovider, remember
+that the underscore character (_) will be replaced by space ( ).
 
 Several options can be appended, for instance:
 
diff --git a/demux.c b/demux.c
index b661cc0..f8ead1f 100644
--- a/demux.c
+++ b/demux.c
@@ -481,10 +481,19 @@ void demux_Change( output_t *p_output, const output_config_t *p_config )
     bool b_pid_change = false, b_tsid_change = false;
     bool b_dvb_change = !!((p_output->config.i_config ^ p_config->i_config)
                              & OUTPUT_DVB);
+    bool b_service_name_change =
+        (!streq(p_output->config.psz_service_name, p_config->psz_service_name) ||
+         !streq(p_output->config.psz_service_provider, p_config->psz_service_provider));
     int i;
 
     p_output->config.i_config = p_config->i_config;
 
+    /* Change output settings related to service_name and service_provider . */
+    free( p_output->config.psz_service_name );
+    free( p_output->config.psz_service_provider );
+    p_output->config.psz_service_name = xstrdup( p_config->psz_service_name );
+    p_output->config.psz_service_provider = xstrdup( p_config->psz_service_provider );
+
     if ( p_config->i_tsid != -1 && p_output->config.i_tsid != p_config->i_tsid )
     {
         p_output->i_tsid = p_config->i_tsid;
@@ -627,6 +636,9 @@ out_change:
 
         if ( b_pid_change )
             NewPMT( p_output );
+
+        if ( !b_sid_change && b_service_name_change )
+            NewSDT( p_output );
     }
 }
 
@@ -1349,9 +1361,60 @@ static void NewSDT( output_t *p_output )
     sdtn_set_running( p_service, sdtn_get_running(p_current_service) );
     /* Do not set free_ca */
     sdtn_set_desclength( p_service, sdtn_get_desclength(p_current_service) );
-    memcpy( descs_get_desc( sdtn_get_descs(p_service), 0 ),
-            descs_get_desc( sdtn_get_descs(p_current_service), 0 ),
-            sdtn_get_desclength(p_current_service) );
+
+    char *p_new_provider = p_output->config.psz_service_provider;
+    char *p_new_service  = p_output->config.psz_service_name;
+
+    if ( !p_new_provider && !p_new_service ) {
+        /* Copy all descriptors unchanged */
+        memcpy( descs_get_desc( sdtn_get_descs(p_service), 0 ),
+                descs_get_desc( sdtn_get_descs(p_current_service), 0 ),
+                sdtn_get_desclength(p_current_service) );
+    } else {
+        int j = 0, i_total_desc_len = 0;
+        uint8_t *p_desc;
+        uint8_t *p_new_desc = descs_get_desc( sdtn_get_descs(p_service), 0 );
+        while ( (p_desc = descs_get_desc( sdtn_get_descs( p_current_service ), j++ )) != NULL )
+        {
+            /* Regenerate descriptor 48 (service name) */
+            if ( desc_get_tag( p_desc ) == 0x48 && desc48_validate( p_desc ) )
+            {
+                uint8_t i_old_provider_len, i_old_service_len, i_new_desc_len = 0;
+                char *p_new_provider = p_output->config.psz_service_provider;
+                char *p_new_service  = p_output->config.psz_service_name;
+                const uint8_t *p_old_provider = desc48_get_provider( p_desc, &i_old_provider_len );
+                const uint8_t *p_old_service = desc48_get_service( p_desc, &i_old_service_len );
+
+                desc48_init( p_new_desc );
+                desc48_set_type( p_new_desc, desc48_get_type( p_desc ) );
+
+                if ( p_new_provider ) {
+                    desc48_set_provider( p_new_desc, (uint8_t *)p_new_provider, strlen( p_new_provider ) );
+                    i_new_desc_len += strlen( p_new_provider );
+                } else {
+                    desc48_set_provider( p_new_desc, p_old_provider, i_old_provider_len );
+                    i_new_desc_len += i_old_provider_len;
+                }
+
+                if ( p_new_service ) {
+                    desc48_set_service( p_new_desc, (uint8_t *)p_new_service, strlen( p_new_service ) );
+                    i_new_desc_len += strlen( p_new_service );
+                } else {
+                    desc48_set_service( p_new_desc, p_old_service, i_old_service_len );
+                    i_new_desc_len += i_old_service_len;
+                }
+                desc_set_length( p_new_desc, i_new_desc_len );
+                i_total_desc_len += DESC48_HEADER_SIZE + 2 + i_new_desc_len;
+            } else {
+                /* Copy single descriptor */
+                int i_desc_len = DESC_HEADER_SIZE + desc_get_length( p_desc );
+                memcpy( p_new_desc, p_desc, i_desc_len );
+                p_new_desc += i_desc_len;
+                i_total_desc_len += i_desc_len;
+            }
+        }
+        sdtn_set_desclength( p_service, i_total_desc_len );
+    }
 
     p_service = sdt_get_service( p, 1 );
     if ( p_service == NULL )
diff --git a/dvblast.c b/dvblast.c
index ae05598..85c6ad8 100644
--- a/dvblast.c
+++ b/dvblast.c
@@ -128,6 +128,8 @@ void config_Init( output_config_t *p_config )
     memset( p_config, 0, sizeof(output_config_t) );
 
     p_config->psz_displayname = NULL;
+    p_config->psz_service_name = NULL;
+    p_config->psz_service_provider = NULL;
 
     p_config->i_family = AF_UNSPEC;
     p_config->connect_addr.ss_family = AF_UNSPEC;
@@ -140,6 +142,8 @@ void config_Init( output_config_t *p_config )
 void config_Free( output_config_t *p_config )
 {
     free( p_config->psz_displayname );
+    free( p_config->psz_service_name );
+    free( p_config->psz_service_provider );
     free( p_config->pi_pids );
 }
 
@@ -159,6 +163,24 @@ static void config_Defaults( output_config_t *p_config )
     memcpy( p_config->pi_ssrc, pi_ssrc_global, 4 * sizeof(uint8_t) );
 }
 
+static char *config_stropt( char *psz_string )
+{
+    char *ret, *tmp;
+    if ( !psz_string || strlen( psz_string ) == 0 )
+        return NULL;
+    ret = tmp = strdup( psz_string );
+    while (*tmp) {
+        if (*tmp == '_')
+            *tmp = ' ';
+        if (*tmp == '/') {
+            *tmp = '\0';
+            break;
+        }
+        tmp++;
+    }
+    return ret;
+}
+
 bool config_ParseHost( output_config_t *p_config, char *psz_string )
 {
     struct addrinfo *p_ai;
@@ -224,6 +246,18 @@ bool config_ParseHost( output_config_t *p_config, char *psz_string )
             p_config->i_mtu = strtol( ARG_OPTION("mtu="), NULL, 0 );
         else if ( IS_OPTION("ifindex=") )
             p_config->i_if_index_v6 = strtol( ARG_OPTION("ifindex="), NULL, 0 );
+        else if ( IS_OPTION("srvname=")  )
+        {
+            if ( p_config->psz_service_name )
+                free( p_config->psz_service_name );
+            p_config->psz_service_name = config_stropt( ARG_OPTION("srvname=") );
+        }
+        else if ( IS_OPTION("srvprovider=") )
+        {
+            if ( !p_config->psz_service_provider )
+                free( p_config->psz_service_provider );
+            p_config->psz_service_provider = config_stropt( ARG_OPTION("srvprovider=") );
+        }
         else if ( IS_OPTION("ssrc=") )
         {
             in_addr_t i_addr = inet_addr( ARG_OPTION("ssrc=") );
diff --git a/dvblast.h b/dvblast.h
index 6f61a95..4f43fab 100644
--- a/dvblast.h
+++ b/dvblast.h
@@ -92,6 +92,8 @@ typedef struct output_config_t
     uint64_t i_config;
 
     /* output config */
+    char *psz_service_name;
+    char *psz_service_provider;
     uint8_t pi_ssrc[4];
     mtime_t i_output_latency, i_max_retention;
     int i_ttl;
@@ -216,6 +218,8 @@ __attribute__ ((format(printf, 2, 3))) void msg_Dbg( void *_unused, const char *
 __attribute__ ((format(printf, 2, 3))) void msg_Raw( void *_unused, const char *psz_format, ... );
 
 /* */
+bool streq(char *a, char *b);
+char * xstrdup(char *str);
 mtime_t mdate( void );
 void msleep( mtime_t delay );
 void hexDump( uint8_t *p_data, uint32_t i_len );
diff --git a/util.c b/util.c
index 26b8389..23c5686 100644
--- a/util.c
+++ b/util.c
@@ -161,6 +161,23 @@ void msg_Raw( void *_unused, const char *psz_format, ... )
 }
 
 /*****************************************************************************
+ * streq
+ *****************************************************************************/
+inline bool streq(char *a, char *b) {
+    if (!a && b) return false;
+    if (!b && a) return false;
+    if (a == b) return true;
+    return strcmp(a, b) == 0 ? true : false;
+}
+
+/*****************************************************************************
+ * xstrdup
+ *****************************************************************************/
+inline char * xstrdup(char *str) {
+    return str ? strdup(str) : NULL;
+}
+
+/*****************************************************************************
  * mdate
  *****************************************************************************/
 mtime_t mdate( void )



More information about the dvblast-devel mailing list