[dvblast-devel] [Git][videolan/dvblast][master] 2 commits: Use DTV_SCRAMBLING_SEQUENCE_INDEX for DVB-S2 multistream
Christophe Massiot (@cmassiot)
gitlab at videolan.org
Sat Nov 1 18:38:28 UTC 2025
Christophe Massiot pushed to branch master at VideoLAN / dvblast
Commits:
746e19af by Christophe Massiot at 2025-10-25T18:31:23+02:00
Use DTV_SCRAMBLING_SEQUENCE_INDEX for DVB-S2 multistream
- - - - -
b276f61a by Christophe Massiot at 2025-11-01T19:37:49+01:00
Add support for DVB-S2 raw BBFrame demuxing.
- - - - -
7 changed files:
- NEWS
- README
- demux.c
- dvb.c
- dvblast.c
- dvblast.h
- output.c
Changes:
=====================================
NEWS
=====================================
@@ -3,6 +3,10 @@ Changes between 3.4 and 3.5:
* Print bitrate status for each service
* Fix passing through the EITp/f without EPG tables (broken in 3.3)
* Add new option --udp-lock-timeout
+ * Use newer linux-dvb API to get signal statistics
+ * Add support for descrambling cards with UDP/RTP input
+ * Use DTV_SCRAMBLING_SEQUENCE_INDEX for DVB-S2 multistream
+ * Add support for DVB-S2 raw BBFrame demuxing
Changes between 3.3 and 3.4:
----------------------------
=====================================
README
=====================================
@@ -309,3 +309,36 @@ unused ones, can be output.
Other options are self-understandable, and are listed in dvblast -h.
+
+Descrambling device support
+===========================
+DVBlast can descramble a UDP or RTP stream using a CAM and a descrambling
+PCIe card. You have to select the device with --sec-number:
+dvblast -D 239.255.0.1:1234 --sec-number 0
+
+
+Raw BBFrame support for Multiple Input Stream
+=============================================
+
+Some DVB-S2 transponders (especially on Eutelsat 5°W) use a feature called
+Multiple Input Stream (MIS) to transmit several TS on the same frequency.
+To retrieve a specific stream, you normally use --multistream-id-pls-mode,
+--multistream-id-pls-code and --multistream-id-is-id and the specific
+stream will be retrieved by the demod.
+
+However some cards (at the moment from Digital Devices brand) have a feature
+allowing to bypass the demod, and do the demultiplexing of DVB-S2 BBframes
+in software, which allows to retrieve all streams with a single tuner/demod,
+and also fixes some compatibility issues on some frequencies. See:
+https://support.digital-devices.eu/index.php?article=194&rated=1
+
+This feature is activated with --bbframe-demux. When this flag is set, you
+have to specify the streams you want instead of the SID in the config file,
+for instance:
+239.255.0.1:1234 1 10
+239.255.0.2:1234 1 7
+
+This will send streams 10 and 7 to the given addresses. The second argument
+and the pids are ignored. The whole TS is transmitted, so if you want to
+demultiplex it, use a second DVBlast instance with the -D input:
+dvblast -D 239.255.0.1:1234
=====================================
demux.c
=====================================
@@ -1,9 +1,9 @@
/*****************************************************************************
* demux.c
*****************************************************************************
- * Copyright (C) 2004, 2008-2011, 2015-2018 VideoLAN
+ * Copyright (C) 2004, 2008-2011, 2015-2018, 2025 VideoLAN
*
- * Authors: Christophe Massiot <massiot at via.ecp.fr>
+ * Authors: Christophe Massiot <cmassiot at upipe.orgq>
* Andy Gatward <a.j.gatward at reading.ac.uk>
* Marian Ďurkovič <md at bts.sk>
*
@@ -49,6 +49,7 @@
#include <bitstream/dvb/si.h>
#include <bitstream/dvb/si_print.h>
#include <bitstream/mpeg/psi_print.h>
+#include <bitstream/dvb/s2.h>
/*****************************************************************************
* Local declarations
@@ -101,11 +102,28 @@ typedef struct sid_t
unsigned long i_packets_passed;
} sid_t;
+struct mis
+{
+ uint8_t i_mis;
+ uint8_t i_matype1;
+ bool b_issy;
+ bool b_npd;
+ uint16_t i_upl;
+
+ uint8_t p_up[TS_SIZE + S2BBDF_ISSY_MAX_SIZE + S2BBDF_NPD_SIZE];
+ uint8_t i_up_size;
+
+ output_t **pp_outputs;
+ int i_nb_outputs;
+};
+
mtime_t i_wallclock = 0;
static ts_pid_t p_pids[MAX_PIDS];
static sid_t **pp_sids = NULL;
static int i_nb_sids = 0;
+static struct mis **pp_miss = NULL;
+static int i_nb_miss = 0;
static PSI_TABLE_DECLARE(pp_current_pat_sections);
static PSI_TABLE_DECLARE(pp_next_pat_sections);
@@ -115,6 +133,11 @@ static PSI_TABLE_DECLARE(pp_current_nit_sections);
static PSI_TABLE_DECLARE(pp_next_nit_sections);
static PSI_TABLE_DECLARE(pp_current_sdt_sections);
static PSI_TABLE_DECLARE(pp_next_sdt_sections);
+
+struct mis *p_current_mis = NULL;
+static uint8_t i_last_bbframe_counter = UINT8_MAX;
+static uint16_t i_current_mis_dfl = 0;
+
static mtime_t i_last_dts = -1;
static int i_demux_fd;
static uint64_t i_nb_packets = 0;
@@ -268,6 +291,39 @@ static inline sid_t *FindSID( uint16_t i_sid )
return NULL;
}
+/*****************************************************************************
+ * FindMis
+ *****************************************************************************/
+static inline struct mis *FindMis( uint8_t i_mis )
+{
+ int i;
+
+ for ( i = 0; i < i_nb_miss; i++ )
+ {
+ struct mis *p_mis = pp_miss[i];
+ if ( p_mis->i_mis == i_mis )
+ return p_mis;
+ }
+ return NULL;
+}
+
+/*****************************************************************************
+ * NewMis
+ *****************************************************************************/
+static inline struct mis *NewMis( uint8_t i_mis )
+{
+ struct mis *p_mis = malloc( sizeof(struct mis) );
+ p_mis->i_mis = i_mis;
+ p_mis->i_matype1 = 0xff; /* impossible value */
+ p_mis->i_up_size = 0;
+ p_mis->pp_outputs = NULL;
+ p_mis->i_nb_outputs = 0;
+ i_nb_miss++;
+ pp_miss = realloc( pp_miss, sizeof(struct mis *) * i_nb_miss );
+ pp_miss[i_nb_miss - 1] = p_mis;
+ return p_mis;
+}
+
/*****************************************************************************
* Print info
*****************************************************************************/
@@ -512,6 +568,14 @@ void demux_Close( void )
}
free( pp_sids );
+ for ( i = 0; i < i_nb_miss; i++ )
+ {
+ struct mis *p_mis = pp_miss[i];
+ free( p_mis->pp_outputs );
+ free( p_mis );
+ }
+ free( pp_miss );
+
#ifdef HAVE_ICONV
if (iconv_handle != (iconv_t)-1) {
iconv_close(iconv_handle);
@@ -636,6 +700,14 @@ static void demux_Handle( block_t *p_ts )
pf_Reset();
}
+ if ( i_mis_is_id == -1 )
+ {
+ /* BBframe mode, only demux 0x80 sections of PID 0x010e */
+ if ( i_pid == S2BBFRAMES_PID )
+ HandlePSIPacket( p_ts->p_ts, p_ts->i_dts );
+ goto demux_out;
+ }
+
if ( i_es_timeout )
{
int i_pes_status = -1;
@@ -774,6 +846,7 @@ static void demux_Handle( block_t *p_ts )
if ( output_dup.config.i_config & OUTPUT_VALID )
output_Put( &output_dup, p_ts );
+demux_out:
if ( b_passthrough )
fwrite(p_ts->p_ts, TS_SIZE, 1, stdout);
@@ -795,6 +868,66 @@ static bool IsIn( const uint16_t *pi_pids, int i_nb_pids, uint16_t i_pid )
void demux_Change( output_t *p_output, const output_config_t *p_config )
{
+ if ( i_mis_is_id == -1 )
+ {
+ /* Special case for MIS demux - sid == mis, ignore pids */
+ uint16_t i_old_mis = p_output->config.i_sid;
+ uint16_t i_mis = p_config->i_sid;
+
+ p_output->config.i_config = p_config->i_config;
+ p_output->config.i_sid = p_config->i_sid;
+
+ if ( i_mis == i_old_mis )
+ return;
+
+ if ( i_old_mis != UINT16_MAX )
+ {
+ struct mis *p_mis = FindMis( i_old_mis );
+ int j;
+ for ( j = 0; j < p_mis->i_nb_outputs; j++ )
+ {
+ if ( p_mis->pp_outputs[j] == p_output )
+ {
+ p_mis->pp_outputs[j] = NULL;
+ break;
+ }
+ }
+ }
+
+ if ( i_mis != UINT16_MAX )
+ {
+ struct mis *p_mis = FindMis( i_mis );
+ int j;
+ if ( p_mis == NULL )
+ {
+ /* Not yet detected but may come later */
+ p_mis = NewMis( i_mis );
+ }
+
+ for ( j = 0; j < p_mis->i_nb_outputs; j++ )
+ if ( p_mis->pp_outputs[j] == p_output )
+ break;
+
+ if ( j == p_mis->i_nb_outputs )
+ {
+ for ( j = 0; j < p_mis->i_nb_outputs; j++ )
+ if ( p_mis->pp_outputs[j] == NULL )
+ break;
+
+ if ( j == p_mis->i_nb_outputs )
+ {
+ p_mis->i_nb_outputs++;
+ p_mis->pp_outputs = realloc( p_mis->pp_outputs,
+ sizeof(output_t *)
+ * p_mis->i_nb_outputs );
+ }
+
+ p_mis->pp_outputs[j] = p_output;
+ }
+ }
+ return;
+ }
+
uint16_t *pi_wanted_pids, *pi_current_pids;
int i_nb_wanted_pids, i_nb_current_pids;
uint16_t i_wanted_pcr_pid, i_current_pcr_pid;
@@ -3120,6 +3253,232 @@ out_eit:
SendEIT( p_sid, i_dts, p_eit );
}
+/*****************************************************************************
+ * HandleBBFrameSection
+ *****************************************************************************/
+static void HandleBBFrameSection( const uint8_t *p_bbframes, mtime_t i_dts )
+{
+ if ( !s2bbframes_validate( p_bbframes ) )
+ {
+ msg_Warn( NULL, "invalid BBFrame section received" );
+ return;
+ }
+
+ uint8_t i_counter = s2bbframes_get_counter( p_bbframes );
+ uint8_t *p_bbframe = s2bbframes_get_bbframe( p_bbframes );
+ uint16_t i_bbframe_size = s2bbframes_get_length( p_bbframes );
+
+ if ( i_counter == S2BBFRAMES_HEADER_COUNTER )
+ {
+ /* Parse new BBFrame header */
+ if ( i_bbframe_size < S2BBH_SIZE )
+ {
+ msg_Warn( NULL, "too short BBFrame section received" );
+ return;
+ }
+ if ( !s2bbh_validate( p_bbframe ) )
+ {
+ msg_Warn( NULL, "invalid BBFrame header received" );
+ return;
+ }
+ if ( s2bbh_get_tsgs( p_bbframe ) != S2BBH_TSGS_TRANSPORT )
+ {
+ msg_Warn( NULL, "unsupported Generic Stream Input" );
+ return;
+ }
+ if ( s2bbh_is_sis( p_bbframe ) )
+ {
+ msg_Warn( NULL, "unsupported Single Input Stream mode" );
+ return;
+ }
+ if ( s2bbh_get_sync( p_bbframe ) != TS_SYNC )
+ {
+ msg_Warn( NULL, "invalid BBFrame sync received" );
+ return;
+ }
+
+ i_last_bbframe_counter = 0;
+ uint8_t i_mis = s2bbh_get_mis( p_bbframe );
+ bool b_ccm = s2bbh_is_ccm( p_bbframe );
+ bool b_issyi = s2bbh_has_issyi( p_bbframe );
+ bool b_npd = s2bbh_has_npd( p_bbframe );
+ uint8_t i_ro = s2bbh_get_ro( p_bbframe );
+ uint16_t i_upl = s2bbh_get_upl( p_bbframe ) / 8;
+ i_current_mis_dfl = s2bbh_get_dfl( p_bbframe ) / 8;
+ uint16_t i_syncd = s2bbh_get_syncd( p_bbframe ) / 8;
+
+ p_current_mis = FindMis( i_mis );
+ if ( p_current_mis == NULL )
+ {
+ p_current_mis = malloc( sizeof(struct mis) );
+ p_current_mis->i_mis = i_mis;
+ p_current_mis->i_matype1 = 0xff; /* impossible value */
+ p_current_mis->i_up_size = 0;
+ p_current_mis->pp_outputs = NULL;
+ p_current_mis->i_nb_outputs = 0;
+ i_nb_miss++;
+ pp_miss = realloc( pp_miss, sizeof(struct mis *) * i_nb_miss );
+ pp_miss[i_nb_miss - 1] = p_current_mis;
+ }
+
+ if ( p_current_mis->i_matype1 != p_bbframe[0] )
+ {
+ switch (i_print_type) {
+ case PRINT_XML:
+ fprintf(print_fh, "<STREAM mis=\"%"PRIu8"\" mode=\"%s\" issyi=\"%s\" npd=\"%s\" ro=\"%s\" />\n",
+ i_mis, b_ccm ? "ccm" : "acm",
+ b_issyi ? "true" : "false",
+ b_npd ? "true" : "false",
+ i_ro == S2BBH_RO_35 ? "0.35" :
+ (i_ro == S2BBH_RO_25 ? "0.25" :
+ (i_ro == S2BBH_RO_20 ? "0.20" : "reserved")));
+ break;
+ case PRINT_TEXT:
+ fprintf(print_fh, "new stream mis %"PRIu8", %s, %sissyi, %snpd, ro %s\n",
+ i_mis, b_ccm ? "ccm" : "acm",
+ b_issyi ? "" : "no ",
+ b_npd ? "" : "no ",
+ i_ro == S2BBH_RO_35 ? "0.35" :
+ (i_ro == S2BBH_RO_25 ? "0.25" :
+ (i_ro == S2BBH_RO_20 ? "0.20" : "reserved")));
+ break;
+ default:
+ break;
+ }
+ p_current_mis->i_matype1 = p_bbframe[0];
+ p_current_mis->b_issy = b_issyi;
+ p_current_mis->b_npd = b_npd;
+ p_current_mis->i_upl = i_upl;
+ }
+
+ if ( i_syncd == UINT16_MAX / 8)
+ {
+ /* BBFrame without UP */
+ return;
+ }
+
+ if ( !p_current_mis->i_nb_outputs )
+ {
+ p_current_mis = NULL;
+ return;
+ }
+
+ p_bbframe += S2BBH_SIZE;
+ i_bbframe_size -= S2BBH_SIZE;
+
+ if ( (i_syncd + 1) % p_current_mis->i_upl !=
+ (p_current_mis->i_upl -
+ p_current_mis->i_up_size) % p_current_mis->i_upl )
+ {
+ msg_Warn( NULL, "fixed a BBframe disalignment (MIS %"PRIu8")",
+ p_current_mis->i_mis );
+ p_current_mis->i_up_size = 0;
+ p_bbframe += i_syncd + 1;
+ i_bbframe_size -= i_syncd + 1;
+ i_current_mis_dfl -= i_syncd + 1;
+ }
+ }
+ else if ( p_current_mis == NULL )
+ {
+ /* Partial frame, abort */
+ return;
+ }
+ else if ( i_last_bbframe_counter + 1 != i_counter )
+ {
+ msg_Warn( NULL, "BBFrame discontinuity on MIS %"PRIu8" expected_counter %u got %u",
+ p_current_mis->i_mis, i_last_bbframe_counter + 1,
+ i_counter );
+ p_current_mis->i_up_size = 0;
+ p_current_mis = NULL;
+ return;
+ }
+ else
+ i_last_bbframe_counter = i_counter;
+
+ if ( i_bbframe_size > i_current_mis_dfl )
+ {
+ /* Remove padding */
+ i_bbframe_size = i_current_mis_dfl;
+ }
+
+ while ( p_current_mis->i_up_size + i_bbframe_size >= p_current_mis->i_upl )
+ {
+ /* Immediately output TS packet to avoid bursting issues */
+ uint16_t i_remainder = p_current_mis->i_upl - p_current_mis->i_up_size;
+ memcpy( p_current_mis->p_up + p_current_mis->i_up_size, p_bbframe,
+ i_remainder );
+ p_bbframe += i_remainder;
+ i_bbframe_size -= i_remainder;
+ i_current_mis_dfl -= i_remainder;
+ p_current_mis->i_up_size = 0;
+
+ block_t *p_ts = block_New();
+ p_ts->i_dts = i_dts;
+ p_ts->p_ts[0] = TS_SYNC;
+ memcpy( p_ts->p_ts + 1, p_current_mis->p_up, TS_SIZE - 1 );
+
+ /* Check CRC (last octet of UP after extra data) */
+ if ( s2bbcrc_check( p_current_mis->p_up, p_current_mis->i_upl - 1 )
+ != p_current_mis->p_up[p_current_mis->i_upl - 1] )
+ ts_set_transporterror( p_ts->p_ts );
+
+ for ( int i = 0; i < p_current_mis->i_nb_outputs; i++ )
+ {
+ output_t *p_output = p_current_mis->pp_outputs[i];
+
+ if ( p_output == NULL ||
+ !(p_output->config.i_config & OUTPUT_VALID) )
+ continue;
+
+ output_Put( p_output, p_ts );
+ }
+
+ p_ts->i_refcount--;
+ if ( !p_ts->i_refcount )
+ block_Delete( p_ts );
+
+ if ( p_current_mis->b_npd )
+ {
+ /* Handle Null Packet Deletion */
+ uint8_t i_null_packets =
+ p_current_mis->p_up[p_current_mis->i_upl - 2];
+ if ( i_null_packets )
+ {
+ block_t *p_ts = block_New();
+ p_ts->i_dts = i_dts;
+ ts_pad( p_ts->p_ts );
+
+ while ( i_null_packets-- )
+ {
+ for ( int i = 0; i < p_current_mis->i_nb_outputs; i++ )
+ {
+ output_t *p_output = p_current_mis->pp_outputs[i];
+
+ if ( p_output == NULL ||
+ !(p_output->config.i_config & OUTPUT_VALID) )
+ continue;
+
+ output_Put( p_output, p_ts );
+ }
+ }
+
+ p_ts->i_refcount--;
+ if ( !p_ts->i_refcount )
+ block_Delete( p_ts );
+ }
+ }
+ }
+
+ /* Copy the rest of the BBFrame to the temporary buffer */
+ if ( i_bbframe_size )
+ {
+ memcpy( p_current_mis->p_up + p_current_mis->i_up_size, p_bbframe,
+ i_bbframe_size );
+ p_current_mis->i_up_size += i_bbframe_size;
+ i_current_mis_dfl -= i_bbframe_size;
+ }
+}
+
/*****************************************************************************
* HandleSection
*****************************************************************************/
@@ -3144,6 +3503,13 @@ static void HandleSection( uint16_t i_pid, uint8_t *p_section, mtime_t i_dts )
return;
}
+ if ( i_mis_is_id == -1 )
+ {
+ HandleBBFrameSection( p_section, i_dts );
+ free( p_section );
+ return;
+ }
+
if ( !psi_get_current( p_section ) )
{
/* Ignore sections which are not in use yet. */
=====================================
dvb.c
=====================================
@@ -1,9 +1,9 @@
/*****************************************************************************
* dvb.c: linux-dvb input for DVBlast
*****************************************************************************
- * Copyright (C) 2008-2010, 2015 VideoLAN
+ * Copyright (C) 2008-2010, 2015, 2025 VideoLAN
*
- * Authors: Christophe Massiot <massiot at via.ecp.fr>
+ * Authors: Christophe Massiot <cmassiot at upipe.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -827,6 +827,23 @@ static fe_rolloff_t GetRollOff(void)
}
}
+static int GetSSI(void)
+{
+ if ( streq(psz_mis_pls_mode, "GOLD") )
+ return i_mis_pls_code;
+
+ /* ROOT mode */
+ uint32_t x, g;
+
+ for ( g = 0, x = 1; g < 0x3ffff; g++ )
+ {
+ if ( i_mis_pls_code == x )
+ return g;
+ x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
+ }
+ return 0xffffffff;
+}
+
static fe_guard_interval_t GetGuard(void)
{
switch ( i_guard )
@@ -1006,19 +1023,21 @@ static struct dtv_properties dvbs_cmdseq = {
#define IDX_DVBS2_PILOT 6
#define IDX_DVBS2_ROLLOFF 7
#define IDX_DVBS2_STREAM_ID 8
+#define IDX_DVBS2_SSI 9
/* Commands 0..5 are the same as dvbs_cmdargs */
/* Commands 6..8 are special for DVB-S2 */
static struct dtv_property dvbs2_cmdargs[] = {
- { .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBS2 },
- { .cmd = DTV_FREQUENCY, .u.data = 0 },
- { .cmd = DTV_MODULATION, .u.data = PSK_8 },
- { .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO },
- { .cmd = DTV_SYMBOL_RATE, .u.data = 27500000 },
- { .cmd = DTV_INNER_FEC, .u.data = FEC_AUTO },
- { .cmd = DTV_PILOT, .u.data = PILOT_AUTO }, /* idx: 6 */
- { .cmd = DTV_ROLLOFF, .u.data = ROLLOFF_AUTO }, /* idx: 7 */
- { .cmd = DTV_STREAM_ID, .u.data = 0 }, /* idx: 8 */
+ { .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBS2 },
+ { .cmd = DTV_FREQUENCY, .u.data = 0 },
+ { .cmd = DTV_MODULATION, .u.data = PSK_8 },
+ { .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO },
+ { .cmd = DTV_SYMBOL_RATE, .u.data = 27500000 },
+ { .cmd = DTV_INNER_FEC, .u.data = FEC_AUTO },
+ { .cmd = DTV_PILOT, .u.data = PILOT_AUTO }, /* idx: 6 */
+ { .cmd = DTV_ROLLOFF, .u.data = ROLLOFF_AUTO }, /* idx: 7 */
+ { .cmd = DTV_STREAM_ID, .u.data = 0 }, /* idx: 8 */
+ { .cmd = DTV_SCRAMBLING_SEQUENCE_INDEX, .u.data = 0 }, /* idx: 9 */
{ .cmd = DTV_TUNE },
};
static struct dtv_properties dvbs2_cmdseq = {
@@ -1394,7 +1413,12 @@ static void FrontendSet( bool b_init )
p->props[MODULATION].u.data = GetModulation();
p->props[IDX_DVBS2_PILOT].u.data = GetPilot();
p->props[IDX_DVBS2_ROLLOFF].u.data = GetRollOff();
- p->props[IDX_DVBS2_STREAM_ID].u.data = i_mis;
+ if ( i_mis_pls_code )
+ {
+ p->props[IDX_DVBS2_STREAM_ID].u.data =
+ i_mis_is_id != -1 ? i_mis_is_id : 0x80000000;
+ p->props[IDX_DVBS2_SSI].u.data = GetSSI();
+ }
}
else
p = &dvbs_cmdseq;
@@ -1404,10 +1428,16 @@ static void FrontendSet( bool b_init )
p->props[FEC_INNER].u.data = GetFECInner(info.caps);
p->props[FREQUENCY].u.data = FrontendDoDiseqc();
- msg_Dbg( NULL, "tuning DVB-S frontend to f=%d srate=%d inversion=%d fec=%d rolloff=%d modulation=%s pilot=%d mis=%d /pls-mode: %s (%d) pls-code: %d is-id: %d /",
- i_frequency, i_srate, i_inversion, i_fec, i_rolloff,
- psz_modulation == NULL ? "legacy" : psz_modulation, i_pilot,
- i_mis, psz_mis_pls_mode, i_mis_pls_mode, i_mis_pls_code, i_mis_is_id );
+ if ( i_mis_is_id == -1 )
+ msg_Dbg( NULL, "tuning DVB-S frontend in BBFrame mode to f=%d srate=%d inversion=%d fec=%d rolloff=%d modulation=%s pilot=%d pls-mode: %s pls-code: %d",
+ i_frequency, i_srate, i_inversion, i_fec, i_rolloff,
+ psz_modulation == NULL ? "legacy" : psz_modulation, i_pilot,
+ psz_mis_pls_mode, i_mis_pls_code );
+ else
+ msg_Dbg( NULL, "tuning DVB-S frontend to f=%d srate=%d inversion=%d fec=%d rolloff=%d modulation=%s pilot=%d pls-mode: %s pls-code: %d is-id: %u",
+ i_frequency, i_srate, i_inversion, i_fec, i_rolloff,
+ psz_modulation == NULL ? "legacy" : psz_modulation, i_pilot,
+ psz_mis_pls_mode, i_mis_pls_code, i_mis_is_id );
break;
case SYS_ATSC:
=====================================
dvblast.c
=====================================
@@ -1,9 +1,9 @@
/*****************************************************************************
* dvblast.c
*****************************************************************************
- * Copyright (C) 2004, 2008-2011, 2015, 2020 VideoLAN
+ * Copyright (C) 2004, 2008-2011, 2015, 2020, 2025 VideoLAN
*
- * Authors: Christophe Massiot <massiot at via.ecp.fr>
+ * Authors: Christophe Massiot <cmassiot at upipe.org>
* Andy Gatward <a.j.gatward at reading.ac.uk>
*
* This program is free software; you can redistribute it and/or modify
@@ -81,9 +81,7 @@ int b_tone = 0;
int i_bandwidth = 8;
char *psz_modulation = NULL;
int i_pilot = -1;
-int i_mis = 0;
char *psz_mis_pls_mode = "ROOT";
-int i_mis_pls_mode = 0;
int i_mis_pls_code = 0;
int i_mis_is_id = 0;
int i_fec_lp = 999;
@@ -159,6 +157,8 @@ void config_Init( output_config_t *p_config )
p_config->i_if_index_v6 = -1;
p_config->i_srcport = 0;
+ if ( i_mis_is_id == -1 )
+ p_config->i_sid = UINT16_MAX; /* sid is mis */
p_config->pi_pids = NULL;
p_config->b_passthrough = false;
p_config->b_do_remap = false;
@@ -634,7 +634,7 @@ void usage()
"[-u] [-w] [-U] [-L <latency>] [-E <retention>] [-d <dest IP>[<:port>][/<opts>]*] [-3] "
"[-z] [-C [-e] [-M <network name>] [-N <network ID>]] [-T] [-j <system charset>] "
"[-W] [-Y] [-l] [-g <logger ident>] [-Z <mrtg file>] [-V] [-h] [-B <provider_name>] "
- "[-1 <mis_id>] [-2 <size>] [-5 <DVBS|DVBS2|DVBC_ANNEX_A|DVBC_ANNEX_B|DVBT|DVBT2|ATSC|ISDBT>] -y <ca_dev_number> "
+ "[-1] [-2 <size>] [-5 <DVBS|DVBS2|DVBC_ANNEX_A|DVBC_ANNEX_B|DVBT|DVBT2|ATSC|ISDBT>] -y <ca_dev_number> "
"[-J <DVB charset>] [-Q <quit timeout>] [-0 pid_mapping] [-x <text|xml>]"
"[-6 <print period>] [-7 <ES timeout>] [-4 <UDP lock timeout>]" );
@@ -667,7 +667,7 @@ void usage()
msg_Raw( NULL, " -P --pilot DVB-S2 Pilot (-1 auto, 0 off, 1 on)" );
msg_Raw( NULL, " -R --rolloff DVB-S2 Rolloff value" );
msg_Raw( NULL, " DVB-S2 35=0.35|25=0.25|20=0.20|0=AUTO (default: 35)" );
- msg_Raw( NULL, " -1 --multistream-id Set stream ID (0-2147483648, default: 0)." );
+ msg_Raw( NULL, " -1 --bbframe-demux use raw BBframes to demultiplex MIS" );
msg_Raw( NULL, " --multistream-id-pls-mode Set multistream PLS mode (ROOT, GOLD, COMBO, default: ROOT)" );
msg_Raw( NULL, " --multistream-id-pls-code Set multistream PLS code (0-262143, default: 0)" );
msg_Raw( NULL, " --multistream-id-is-id Set multistream IS id (0-255, default: 0)" );
@@ -771,7 +771,7 @@ int main( int i_argc, char **pp_argv )
{ "inversion", required_argument, NULL, 'I' },
{ "modulation", required_argument, NULL, 'm' },
{ "pilot", required_argument, NULL, 'P' },
- { "multistream-id", required_argument, NULL, '1' },
+ { "bbframe-demux", no_argument, NULL, '1' },
{ "multistream-id-pls-mode", required_argument, NULL, 0x100001 },
{ "multistream-id-pls-code", required_argument, NULL, 0x100002 },
{ "multistream-id-is-id" , required_argument, NULL, 0x100003 },
@@ -817,7 +817,7 @@ int main( int i_argc, char **pp_argv )
{ 0, 0, 0, 0 }
};
- while ( (c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:5:f:F:R:s:S:k:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:3D:A:lg:zCWYeM:N:j:J:B:x:Q:6:7:4:hVZ:y:0:1:2:9:", long_options, NULL)) != -1 )
+ while ( (c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:5:f:F:R:s:S:k:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:3D:A:lg:zCWYeM:N:j:J:B:x:Q:6:7:4:hVZ:y:0:12:9:", long_options, NULL)) != -1 )
{
switch ( c )
{
@@ -894,9 +894,11 @@ int main( int i_argc, char **pp_argv )
case '5':
psz_delsys = optarg;
break;
+
case '9':
dvb_plp_id = strtol( optarg, NULL, 0 );
break;
+
case 'f':
if (optarg && optarg[0] != '-')
i_frequency = strtol( optarg, NULL, 0 );
@@ -962,34 +964,41 @@ int main( int i_argc, char **pp_argv )
break;
case '1':
- i_mis = strtol( optarg, NULL, 0 );
+ i_mis_is_id = -1;
+ /* intended pass-through */
+
+ case 'u':
+ b_budget_mode = 1;
break;
case 0x100001: // --multistream-id-pls-mode
psz_mis_pls_mode = optarg;
- if ( streq( psz_mis_pls_mode, "ROOT" ) ) {
- i_mis_pls_mode = 0;
- } else if ( streq( psz_mis_pls_mode, "GOLD" ) ) {
- i_mis_pls_mode = 1;
- } else if ( streq( psz_mis_pls_mode, "COMBO" ) ) {
- i_mis_pls_mode = 2;
- } else {
- msg_Err(NULL, "Invalid --multistream-id-pls-mode '%s', valid options are: ROOT GOLD COMBO", optarg);
+ if ( !streq(psz_mis_pls_mode, "ROOT") &&
+ !streq(psz_mis_pls_mode, "GOLD") )
+ {
+ msg_Err(NULL, "Invalid --multistream-id-pls-mode '%s', valid options are: ROOT GOLD", optarg);
exit(1);
}
break;
case 0x100002: // --multistream-id-pls-code
i_mis_pls_code = strtol( optarg, NULL, 0 );
- if ( i_mis_pls_code < 0 || i_mis_pls_code > 262143 ) {
+ if ( i_mis_pls_code < 0 || i_mis_pls_code > 262143 )
+ {
msg_Err(NULL, "ERROR: Invalid --multistream-id-pls-code '%s', valid options are: 0-262143", optarg);
exit(1);
}
break;
case 0x100003: // --multistream-id-is-id
+ if ( i_mis_is_id == -1 )
+ {
+ msg_Err(NULL, "ERROR: --multistream-id-is-id is incompatible with --bbframe-demux");
+ exit(1);
+ }
i_mis_is_id = strtol( optarg, NULL, 0 );
- if ( i_mis_is_id < 0 || i_mis_is_id > 255 ) {
+ if ( i_mis_is_id < 0 || i_mis_is_id > 255 )
+ {
msg_Err(NULL, "ERROR: Invalid --multistream-id-is-id '%s', valid options are: 0-255", optarg);
exit(1);
}
@@ -1015,10 +1024,6 @@ int main( int i_argc, char **pp_argv )
i_hierarchy = strtol( optarg, NULL, 0 );
break;
- case 'u':
- b_budget_mode = 1;
- break;
-
case 'w':
b_select_pmts = !b_select_pmts;
break;
@@ -1234,7 +1239,10 @@ int main( int i_argc, char **pp_argv )
{
case PRINT_XML:
fprintf(print_fh, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
- fprintf(print_fh, "<TS>\n");
+ if ( i_mis_is_id != -1 )
+ fprintf(print_fh, "<TS>\n");
+ else
+ fprintf(print_fh, "<MIS>\n");
break;
default:
break;
@@ -1285,26 +1293,6 @@ int main( int i_argc, char **pp_argv )
srand( time(NULL) * getpid() );
- if ( i_mis_pls_mode || i_mis_pls_code || i_mis_is_id )
- {
- i_mis = calc_multistream_id( i_mis_pls_mode, i_mis_pls_code, i_mis_is_id );
- msg_Info( NULL, "Calculating multistream-id using pls-mode: %s (%d) pls-code: %d is-id: %d. Resulting multistream-id: %d (0x%x)",
- psz_mis_pls_mode, i_mis_pls_mode, i_mis_pls_code, i_mis_is_id, i_mis, i_mis );
- }
- else if ( i_mis )
- {
- i_mis_pls_mode = (i_mis >> 26) & 0x03;
- i_mis_pls_code = (i_mis >> 8) & 0x3ffff;
- i_mis_is_id = i_mis & 0xff;
- psz_mis_pls_mode =
- i_mis_pls_mode == 0 ? "ROOT" :
- i_mis_pls_mode == 1 ? "GOLD" :
- i_mis_pls_mode == 2 ? "COMBO" : "UNKNOWN";
-
- msg_Info( NULL, "Calculated multistream pls-mode: %s (%d) pls-code: %d is-id: %d from multistream-id: %d (0x%x)",
- psz_mis_pls_mode, i_mis_pls_mode, i_mis_pls_code, i_mis_is_id, i_mis, i_mis );
- }
-
demux_Open();
// init the mrtg logfile
@@ -1349,7 +1337,10 @@ int main( int i_argc, char **pp_argv )
switch (i_print_type)
{
case PRINT_XML:
- fprintf(print_fh, "</TS>\n");
+ if ( i_mis_is_id != -1 )
+ fprintf(print_fh, "</TS>\n");
+ else
+ fprintf(print_fh, "</MIS>\n");
break;
default:
break;
=====================================
dvblast.h
=====================================
@@ -1,9 +1,9 @@
/*****************************************************************************
* dvblast.h
*****************************************************************************
- * Copyright (C) 2004, 2008-2011, 2015-2016, 2020 VideoLAN
+ * Copyright (C) 2004, 2008-2011, 2015-2016, 2020,2025 VideoLAN
*
- * Authors: Christophe Massiot <massiot at via.ecp.fr>
+ * Authors: Christophe Massiot <cmassiot at upipe.org>
* Andy Gatward <a.j.gatward at reading.ac.uk>
*
* This program is free software; you can redistribute it and/or modify
@@ -235,13 +235,10 @@ extern int i_inversion;
extern char *psz_modulation;
extern int i_pilot;
-/* Multistream settings */
-extern int i_mis; /* Calculated from the three settings bellow, if they are set */
-extern char *psz_mis_pls_mode; /* ROOT, GOLD, COMBO */
-extern int i_mis_pls_mode; /* ROOT - 0, GOLD - 1, COMBO - 2 */
+/* multistream settings */
+extern char *psz_mis_pls_mode; /* ROOT, GOLD */
extern int i_mis_pls_code; /* 0 .. 262143 */
extern int i_mis_is_id; /* 0 .. 255 */
-#define calc_multistream_id( pls_mode, pls_code, is_id ) ( pls_mode << 26 | pls_code << 8 | is_id )
extern int i_fec_lp;
extern int i_guard;
=====================================
output.c
=====================================
@@ -472,7 +472,7 @@ static void output_Flush( output_t *p_output )
if ( !p_packet->pp_blocks[i_block]->i_refcount )
block_Delete( p_packet->pp_blocks[i_block] );
else if ( b_do_remap || p_output->config.b_do_remap ) {
- /* still referenced so re-instate the orignial pid if remapped */
+ /* still referenced so re-instate the original pid if remapped */
block_t * p_block = p_packet->pp_blocks[i_block];
if (p_block->tmp_pid != UNUSED_PID)
ts_set_pid( p_block->p_ts, p_block->tmp_pid );
@@ -604,10 +604,10 @@ output_t *output_Find( const output_config_t *p_config )
if ( !(p_output->config.i_config & OUTPUT_VALID) ) continue;
if ( p_config->i_family != p_output->config.i_family ||
- memcmp( &p_config->connect_addr, &p_output->config.connect_addr,
- i_sockaddr_len ) ||
- memcmp( &p_config->bind_addr, &p_output->config.bind_addr,
- i_sockaddr_len ) )
+ memcmp( &p_config->connect_addr, &p_output->config.connect_addr,
+ i_sockaddr_len ) ||
+ memcmp( &p_config->bind_addr, &p_output->config.bind_addr,
+ i_sockaddr_len ) )
continue;
if ( p_config->i_family == AF_INET6 &&
View it on GitLab: https://code.videolan.org/videolan/dvblast/-/compare/74b297310be8def45d8c890c19a88fff3b1bbeb9...b276f61a4fc8af671f90b02a62e69175de285041
--
View it on GitLab: https://code.videolan.org/videolan/dvblast/-/compare/74b297310be8def45d8c890c19a88fff3b1bbeb9...b276f61a4fc8af671f90b02a62e69175de285041
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the dvblast-devel
mailing list