[dvblast-devel] [PATCH 1/2] Allow service and provider names to be set per output.
Georgi Chorbadzhiyski
gf at unixsol.org
Sun Sep 11 14:24:27 CEST 2011
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>
---
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 )
--
1.7.5.1
More information about the dvblast-devel
mailing list