dvb: scan: improve scan vals and parsers
authorFrancois Cartegnie <fcvlcdev@free.fr>
Tue, 26 Apr 2016 16:15:17 +0000 (18:15 +0200)
committerFrancois Cartegnie <fcvlcdev@free.fr>
Fri, 20 May 2016 11:20:44 +0000 (13:20 +0200)
parses missing descriptor and scanlist values.
outputs scan results to new format.

modules/access/dvb/access.c
modules/access/dvb/scan.c
modules/access/dvb/scan.h
modules/access/dvb/scan_list.c
modules/access/dvb/scan_list.h

index 8ceabba..a7116d2 100644 (file)
@@ -222,8 +222,8 @@ static int ScanFrontendTuningHandler( scan_t *p_scan, void *p_privdata,
     var_SetInteger( p_access, "dvb-frequency", p_cfg->i_frequency );
     var_SetInteger( p_access, "dvb-bandwidth", p_cfg->i_bandwidth );
 
-    if ( p_cfg->c_polarization )
-        var_SetInteger( p_access, "dvb-voltage", p_cfg->c_polarization == 'H' ? 18 : 13 );
+    if ( p_cfg->polarization != SCAN_POLARIZATION_NONE )
+        var_SetInteger( p_access, "dvb-voltage", p_cfg->polarization == SCAN_POLARIZATION_HORIZONTAL ? 18 : 13 );
 
     if ( p_cfg->i_symbolrate )
         var_SetInteger( p_access, "dvb-srate", p_cfg->i_symbolrate );
index f18c40f..8ac3924 100644 (file)
@@ -111,7 +111,7 @@ struct scan_multiplex_t
 
 typedef struct
 {
-    unsigned i_modulation;
+    scan_modulation_t modulation;
     unsigned i_symbolrate_index;
     unsigned i_index;
 } scan_enumeration_t;
@@ -184,7 +184,16 @@ static unsigned scan_session_GetTablesTimeout( const scan_session_t *p_session )
 static void scan_tuner_config_Init( scan_tuner_config_t *p_cfg, const scan_parameter_t *p_params )
 {
     memset( p_cfg, 0, sizeof(*p_cfg) );
-    p_cfg->i_fec = 9; /* FEC_AUTO */
+    p_cfg->coderate_lp = SCAN_CODERATE_AUTO;
+    p_cfg->coderate_hp = SCAN_CODERATE_AUTO;
+    p_cfg->inner_fec = SCAN_CODERATE_AUTO;
+    switch(p_params->type)
+    {
+        case SCAN_DVB_T: p_cfg->delivery = SCAN_DELIVERY_DVB_T; break;
+        case SCAN_DVB_S: p_cfg->delivery = SCAN_DELIVERY_DVB_S; break;
+        case SCAN_DVB_C: p_cfg->delivery = SCAN_DELIVERY_DVB_C; break;
+        default: p_cfg->delivery = SCAN_DELIVERY_UNKNOWN; break;
+    }
     p_cfg->type = p_params->type;
 }
 
@@ -525,56 +534,24 @@ static int Scan_Next_DVB_SpectrumExhaustive( const scan_parameter_t *p_params, s
     return VLC_SUCCESS;
 }
 
-static int Scan_Next_DVBS( scan_t *p_scan, scan_tuner_config_t *p_cfg, double *pf_pos )
-{
-    if( p_scan->parameter.b_exhaustive )
-        msg_Warn( p_scan->p_obj, "no exhaustive DVB-S scan mode" );
-
-    const scan_list_entry_t *p_entry = p_scan->p_current;
-    if( !p_entry )
-        return VLC_EGENERIC;
-
-    /* setup params for scan */
-    p_cfg->i_symbolrate = p_entry->i_rate / 1000;
-    p_cfg->i_frequency = p_entry->i_freq;
-    p_cfg->i_fec = p_entry->i_fec;
-    p_cfg->c_polarization = ( p_entry->polarization == POLARIZATION_HORIZONTAL ) ? 'H' : 'V';
-
-    p_scan->spectrum.i_index++;
-
-    msg_Dbg( p_scan->p_obj,
-             "transponder [%"PRId64"/%zd]: frequency=%d, symbolrate=%d, fec=%d, polarization=%c",
-             p_scan->spectrum.i_index,
-             p_scan->i_scanlist,
-             p_cfg->i_frequency,
-             p_cfg->i_symbolrate,
-             p_cfg->i_fec,
-             p_cfg->c_polarization );
-
-    p_scan->p_current = p_scan->p_current->p_next;
-    *pf_pos = (double) p_scan->spectrum.i_index / p_scan->i_scanlist;
-
-    return VLC_SUCCESS;
-}
-
 static int Scan_Next_DVBC( const scan_parameter_t *p_params, scan_enumeration_t *p_spectrum,
                            scan_tuner_config_t *p_cfg, double *pf_pos )
 {
     bool b_rotate=true;
     if( !p_params->b_modulation_set )
     {
-        p_spectrum->i_modulation = (p_spectrum->i_modulation >> 1 );
+        p_spectrum->modulation = (p_spectrum->modulation >> 1 );
         /* if we iterated all modulations, move on */
         /* dvb utils dvb-c channels files seems to have only
                QAM64...QAM256, so lets just iterate over those */
-        if( p_spectrum->i_modulation < 64)
+        if( p_spectrum->modulation < SCAN_MODULATION_QAM_64)
         {
-            p_spectrum->i_modulation = 256;
+            p_spectrum->modulation = SCAN_MODULATION_QAM_256;
         } else {
             b_rotate=false;
         }
     }
-    p_cfg->i_modulation = p_spectrum->i_modulation;
+    p_cfg->modulation = p_spectrum->modulation;
 
     if( p_params->i_symbolrate == 0 )
     {
@@ -637,7 +614,7 @@ static int Scan_Next_DVBC( const scan_parameter_t *p_params, scan_enumeration_t
     p_cfg->i_frequency = 10000 * ( frequencies[ p_spectrum->i_index ] );
     *pf_pos = (double)(p_spectrum->i_index * 1000 +
                        p_spectrum->i_symbolrate_index * 100 +
-                       (256 - (p_spectrum->i_modulation >> 4)) )
+                       (256 - (p_spectrum->modulation >> 4)) )
             / (num_frequencies * 1000 + 900 + 16);
 
     if( b_rotate )
@@ -739,8 +716,6 @@ static int Scan_GetNextSpectrumTunerConfig( scan_t *p_scan, scan_tuner_config_t
         case SCAN_DVB_C:
             i_ret = Scan_Next_DVBC( &p_scan->parameter, &p_scan->spectrum, p_cfg, pf_pos );
             break;
-        case SCAN_DVB_S:
-            i_ret = Scan_Next_DVBS( p_scan, p_cfg, pf_pos );
         default:
             break;
     }
@@ -755,25 +730,36 @@ static int Scan_GetNextTunerConfig( scan_t *p_scan, scan_tuner_config_t *p_cfg,
         const scan_list_entry_t *p_entry = p_scan->p_current;
         p_cfg->i_frequency = p_entry->i_freq;
         p_cfg->i_bandwidth = p_entry->i_bw / 1000000;
-        p_scan->p_current = p_scan->p_current->p_next;
-        *pf_pos = (double) p_scan->spectrum.i_index++ / p_scan->i_scanlist;
+        p_cfg->modulation = p_entry->modulation;
+
         switch( p_entry->delivery )
         {
-            case DELIVERY_UNKNOWN:
+            case SCAN_DELIVERY_UNKNOWN:
                 break;
-            case DELIVERY_DVBT:
+            case SCAN_DELIVERY_DVB_T:
+                p_cfg->coderate_hp = p_entry->coderate_hp;
+                p_cfg->coderate_lp = p_entry->coderate_lp;
                 p_cfg->type = SCAN_DVB_T;
                 break;
-            case DELIVERY_DVBS:
+            case SCAN_DELIVERY_DVB_S:
                 p_cfg->type = SCAN_DVB_S;
+                p_cfg->polarization = p_entry->polarization;
+                p_cfg->i_symbolrate = p_entry->i_rate / 1000;
+                p_cfg->inner_fec = p_entry->inner_fec;
                 break;
-            case DELIVERY_DVBC:
+            case SCAN_DELIVERY_DVB_C:
                 p_cfg->type = SCAN_DVB_C;
+                p_cfg->i_symbolrate = p_entry->i_rate / 1000;
+                p_cfg->inner_fec = p_entry->inner_fec;
                 break;
             default:
                 p_cfg->type = SCAN_NONE;
                 break;
         }
+
+        p_scan->p_current = p_scan->p_current->p_next;
+        *pf_pos = (double) p_scan->spectrum.i_index++ / p_scan->i_scanlist;
+
         return VLC_SUCCESS;
     }
 
@@ -1169,6 +1155,33 @@ static void SDTCallBack( scan_session_t *p_session, dvbpsi_sdt_t *p_sdt )
     }
 }
 
+static scan_coderate_t ConvertDelDrInnerFec( uint8_t v )
+{
+    switch(v)
+    {
+        default:
+        case 0x0: return SCAN_CODERATE_AUTO;
+        case 0x1: return SCAN_CODERATE_1_2;
+        case 0x2: return SCAN_CODERATE_2_3;
+        case 0x3: return SCAN_CODERATE_3_4;
+        case 0x4: return SCAN_CODERATE_5_6;
+        case 0x5: return SCAN_CODERATE_7_8;
+        case 0x6: return SCAN_CODERATE_8_9;
+        case 0x7: return SCAN_CODERATE_3_5;
+        case 0x8: return SCAN_CODERATE_4_5;
+        case 0x9: return SCAN_CODERATE_9_10;
+        case 0xF: return SCAN_CODERATE_NONE;
+    }
+}
+
+static scan_coderate_t ConvertDelDrCodeRate( uint8_t v )
+{
+    if( v > 0x04 )
+        return SCAN_CODERATE_AUTO;
+    else
+        return ConvertDelDrInnerFec( v + 1 );
+}
+
 static void ParseNIT( vlc_object_t *p_obj, scan_t *p_scan,
                       const dvbpsi_nit_t *p_nit, const scan_tuner_config_t *p_cfg )
 {
@@ -1205,24 +1218,33 @@ static void ParseNIT( vlc_object_t *p_obj, scan_t *p_scan,
                     tscfg.i_bandwidth =  8 - p_t->i_bandwidth;
                     switch(p_t->i_constellation)
                     {
-                        default:
                         case 0x00:
-                            tscfg.i_modulation = -1;
+                            tscfg.modulation = SCAN_MODULATION_QPSK;
                             break;
                         case 0x01:
-                            tscfg.i_modulation = 16;
+                            tscfg.modulation = SCAN_MODULATION_QAM_16;
                             break;
                         case 0x02:
-                            tscfg.i_modulation = 64;
+                            tscfg.modulation = SCAN_MODULATION_QAM_64;
+                            break;
+                        default:
+                            tscfg.modulation = SCAN_MODULATION_AUTO;
                             break;
                     }
 
+                    tscfg.coderate_hp = ConvertDelDrCodeRate( p_t->i_code_rate_hp_stream );
+                    if( p_t->i_hierarchy_information == 0x0 || p_t->i_hierarchy_information == 0x4 )
+                        tscfg.coderate_lp = SCAN_CODERATE_NONE;
+                    else
+                        tscfg.coderate_lp = ConvertDelDrCodeRate( p_t->i_code_rate_lp_stream );
+
                     msg_Dbg( p_obj, "       * terrestrial delivery system" );
-                    msg_Dbg( p_obj, "           * centre_frequency %u", p_t->i_centre_frequency / 10 );
-                    msg_Dbg( p_obj, "           * bandwidth %u", 8 - p_t->i_bandwidth );
-                    msg_Dbg( p_obj, "           * constellation %d", p_t->i_constellation );
+                    msg_Dbg( p_obj, "           * centre_frequency %u", tscfg.i_frequency );
+                    msg_Dbg( p_obj, "           * bandwidth %u", tscfg.i_bandwidth );
+                    msg_Dbg( p_obj, "           * modulation %s", scan_value_modulation( tscfg.modulation ) );
                     msg_Dbg( p_obj, "           * hierarchy %d", p_t->i_hierarchy_information );
-                    msg_Dbg( p_obj, "           * code_rate hp %d lp %d", p_t->i_code_rate_hp_stream, p_t->i_code_rate_lp_stream );
+                    msg_Dbg( p_obj, "           * code_rate hp %s lp %s", scan_value_coderate( tscfg.coderate_hp ),
+                                                                          scan_value_coderate( tscfg.coderate_hp ) );
                     msg_Dbg( p_obj, "           * guard_interval %d", p_t->i_guard_interval );
                     msg_Dbg( p_obj, "           * transmission_mode %d", p_t->i_transmission_mode );
                     msg_Dbg( p_obj, "           * other_frequency_flag %d", p_t->i_other_frequency_flag );
@@ -1235,12 +1257,47 @@ static void ParseNIT( vlc_object_t *p_obj, scan_t *p_scan,
                 {
                     tscfg.i_frequency =  decode_BCD( p_s->i_frequency ) * 1000;
                     tscfg.i_symbolrate =  decode_BCD( p_s->i_symbol_rate ) * 100;
-                    const char polarizations[] = { 'H', 'V', 'L', 'R' };
-                    tscfg.c_polarization = polarizations[p_s->i_polarization];
+                    if( p_s->i_polarization > SCAN_POLARIZATION_CIRC_RIGHT )
+                        p_s->i_polarization = 0;
+
+                    const scan_polarization_t polarizations[] = {
+                                                  SCAN_POLARIZATION_HORIZONTAL,
+                                                  SCAN_POLARIZATION_VERTICAL,
+                                                  SCAN_POLARIZATION_CIRC_LEFT,
+                                                  SCAN_POLARIZATION_CIRC_RIGHT };
+                    tscfg.polarization = polarizations[p_s->i_polarization];
+
+                    switch(p_s->i_modulation_type)
+                    {
+                        default:
+                        case 0x00:
+                            tscfg.modulation = SCAN_MODULATION_AUTO;
+                            break;
+                        case 0x01:
+                            tscfg.modulation = SCAN_MODULATION_QPSK;
+                            break;
+                        case 0x02:
+                            tscfg.modulation = SCAN_MODULATION_PSK_8;
+                            break;
+                        case 0x03:
+                            tscfg.modulation = SCAN_MODULATION_QAM_16;
+                            break;
+                    }
+
+                    tscfg.delivery = (p_s->i_modulation_system == 0x01) ? SCAN_DELIVERY_DVB_S2
+                                                                        : SCAN_DELIVERY_DVB_S;
+                    tscfg.inner_fec = ConvertDelDrInnerFec( p_s->i_fec_inner );
+
                     msg_Dbg( p_obj, "       * satellite delivery system" );
                     msg_Dbg( p_obj, "           * frequency %u", tscfg.i_frequency );
                     msg_Dbg( p_obj, "           * symbolrate %u", tscfg.i_symbolrate );
-                    msg_Dbg( p_obj, "           * polarization %c", tscfg.c_polarization );
+                    msg_Dbg( p_obj, "           * polarization %c", (char) tscfg.polarization );
+                    msg_Dbg( p_obj, "           * modulation %s", scan_value_modulation( tscfg.modulation ) );
+                    msg_Dbg( p_obj, "           * fec inner %s", scan_value_coderate( tscfg.inner_fec ) );
+                    if( tscfg.delivery == SCAN_DELIVERY_DVB_S2 )
+                    {
+                        msg_Dbg( p_obj, "           * system DVB-S2" );
+                    }
                 }
             }
             else if( p_dsc->i_tag == 0x44 )
@@ -1250,11 +1307,17 @@ static void ParseNIT( vlc_object_t *p_obj, scan_t *p_scan,
                 {
                     tscfg.i_frequency =  decode_BCD( p_t->i_frequency ) * 100;
                     tscfg.i_symbolrate =  decode_BCD( p_t->i_symbol_rate ) * 100;
-                    tscfg.i_modulation = (8 << p_t->i_modulation);
+                    if( p_t->i_modulation <= 0x05 )
+                        tscfg.modulation = p_t->i_modulation;
+                    else
+                        tscfg.modulation = SCAN_MODULATION_AUTO;
+                    tscfg.inner_fec = ConvertDelDrInnerFec( p_t->i_fec_inner );
+
                     msg_Dbg( p_obj, "       * Cable delivery system");
                     msg_Dbg( p_obj, "           * frequency %d", tscfg.i_frequency );
                     msg_Dbg( p_obj, "           * symbolrate %u", tscfg.i_symbolrate );
-                    msg_Dbg( p_obj, "           * modulation %u", tscfg.i_modulation );
+                    msg_Dbg( p_obj, "           * modulation %s", scan_value_modulation( tscfg.modulation ) );
+                    msg_Dbg( p_obj, "           * fec inner %s", scan_value_coderate( tscfg.inner_fec ) );
                 }
             }
             else if( p_dsc->i_tag == 0x5f && p_dsc->i_length > 3 )
@@ -1605,7 +1668,6 @@ const char * scan_service_GetNetworkName( const scan_service_t *s )
         return NULL;
 }
 
-
 char * scan_service_GetUri( const scan_service_t *s )
 {
     char *psz_mrl = NULL;
@@ -1613,24 +1675,24 @@ char * scan_service_GetUri( const scan_service_t *s )
     switch( s->p_mplex->cfg.type )
     {
         case SCAN_DVB_T:
-            i_ret = asprintf( &psz_mrl, "dvb://frequency=%d:bandwidth=%d:modulation=%d",
+            i_ret = asprintf( &psz_mrl, "dvb://frequency=%d:bandwidth=%d:modulation=%s",
                               s->p_mplex->cfg.i_frequency,
                               s->p_mplex->cfg.i_bandwidth,
-                              s->p_mplex->cfg.i_modulation );
+                              scan_value_modulation( s->p_mplex->cfg.modulation ) );
             break;
         case SCAN_DVB_S:
-            i_ret = asprintf( &psz_mrl, "dvb://frequency=%d:srate=%d:voltage=%d:fec=%d",
+            i_ret = asprintf( &psz_mrl, "dvb://frequency=%d:srate=%d:polarization=%c:fec=%s",
                               s->p_mplex->cfg.i_frequency,
                               s->p_mplex->cfg.i_symbolrate,
-                              s->p_mplex->cfg.c_polarization == 'H' ? 18 : 13,
-                              s->p_mplex->cfg.i_fec );
+                              (char) s->p_mplex->cfg.polarization,
+                              scan_value_coderate( s->p_mplex->cfg.inner_fec ) );
             break;
         case SCAN_DVB_C:
-            i_ret = asprintf( &psz_mrl, "dvb://frequency=%d:srate=%d:modulation=%d:fec=%d",
+            i_ret = asprintf( &psz_mrl, "dvb://frequency=%d:srate=%d:modulation=%s:fec=%s",
                               s->p_mplex->cfg.i_frequency,
                               s->p_mplex->cfg.i_symbolrate,
-                              s->p_mplex->cfg.i_modulation,
-                              s->p_mplex->cfg.i_fec );
+                              scan_value_modulation( s->p_mplex->cfg.modulation ),
+                              scan_value_coderate( s->p_mplex->cfg.inner_fec ) );
         default:
             break;
     }
@@ -1687,10 +1749,12 @@ block_t *scan_GetM3U( scan_t *p_scan )
                 psz_type = "Unknown";
                 break;
         }
-        msg_Warn( p_obj, "scan_GetM3U: service number %d type '%s' name '%s' channel %d cypted=%d| network_id %d (nit:%d sdt:%d)| f=%d bw=%d snr=%d modulation=%d",
+        msg_Warn( p_obj, "scan_GetM3U: service number %d type '%s' name '%s' channel %d cypted=%d|"
+                         "network_id %d (nit:%d sdt:%d)| f=%d bw=%d snr=%d modulation=%s",
                   s->i_program, psz_type, s->psz_name, s->i_channel, s->b_crypted,
                   s->p_mplex->i_network_id, s->p_mplex->i_nit_version, s->p_mplex->i_sdt_version,
-                  s->p_mplex->cfg.i_frequency, s->p_mplex->cfg.i_bandwidth, s->p_mplex->i_snr, s->p_mplex->cfg.i_modulation );
+                  s->p_mplex->cfg.i_frequency, s->p_mplex->cfg.i_bandwidth, s->p_mplex->i_snr,
+                  scan_value_modulation( s->p_mplex->cfg.modulation ) );
 
         char *psz_mrl = scan_service_GetUri( s );
         if( psz_mrl == NULL )
@@ -1811,3 +1875,45 @@ static unsigned scan_session_GetTablesTimeout( const scan_session_t *p_session )
 
     return i_time * 2 * 1000;
 }
+
+const char *scan_value_modulation( scan_modulation_t m )
+{
+    switch(m)
+    {
+        case SCAN_MODULATION_QAM_16:     return "16QAM";
+        case SCAN_MODULATION_QAM_32:     return "32QAM";
+        case SCAN_MODULATION_QAM_64:     return "64QAM";
+        case SCAN_MODULATION_QAM_128:    return "128QAM";
+        case SCAN_MODULATION_QAM_256:    return "256QAM";
+        case SCAN_MODULATION_QAM_AUTO:   return "QAM";
+        case SCAN_MODULATION_PSK_8:      return "8PSK";
+        case SCAN_MODULATION_QPSK:       return "QPSK";
+        case SCAN_MODULATION_DQPSK:      return "DQPSK";
+        case SCAN_MODULATION_APSK_16:    return "16APSK";
+        case SCAN_MODULATION_APSK_32:    return "32APSK";
+        case SCAN_MODULATION_VSB_8:      return "8VSB";
+        case SCAN_MODULATION_VSB_16:     return "16VSB";
+        case SCAN_MODULATION_QAM_4NR:
+        case SCAN_MODULATION_AUTO:
+        default:                        return "";
+    }
+}
+
+const char *scan_value_coderate( scan_coderate_t c )
+{
+    switch( c )
+    {
+        case SCAN_CODERATE_NONE: return "0";
+        case SCAN_CODERATE_1_2:  return "1/2";
+        case SCAN_CODERATE_2_3:  return "2/3";
+        case SCAN_CODERATE_3_4:  return "3/4";
+        case SCAN_CODERATE_3_5:  return "3/5";
+        case SCAN_CODERATE_4_5:  return "4/5";
+        case SCAN_CODERATE_5_6:  return "5/6";
+        case SCAN_CODERATE_7_8:  return "7/8";
+        case SCAN_CODERATE_8_9:  return "8/9";
+        case SCAN_CODERATE_9_10: return "9/10";
+        case SCAN_CODERATE_AUTO:
+        default:                 return "";
+    }
+}
index 58d1a87..1782c90 100644 (file)
@@ -29,6 +29,73 @@ typedef enum
     SCAN_DVB_C,
 } scan_type_t;
 
+typedef enum
+{
+    SCAN_DELIVERY_UNKNOWN = 0,
+    SCAN_DELIVERY_DVB_T,
+    SCAN_DELIVERY_DVB_T2,
+    SCAN_DELIVERY_DVB_S,
+    SCAN_DELIVERY_DVB_S2,
+    SCAN_DELIVERY_DVB_C,
+    SCAN_DELIVERY_ISDB_T,
+} scan_delivery_t;
+
+typedef enum
+{
+    SCAN_MODULATION_AUTO       = 0x00,
+    SCAN_MODULATION_QAM_16     = 0x01,
+    SCAN_MODULATION_QAM_32     = 0x02,
+    SCAN_MODULATION_QAM_64     = 0x03,
+    SCAN_MODULATION_QAM_128    = 0x04,
+    SCAN_MODULATION_QAM_256    = 0x05,
+    SCAN_MODULATION_QAM_4NR,
+    SCAN_MODULATION_QAM_AUTO,
+    SCAN_MODULATION_PSK_8,
+    SCAN_MODULATION_QPSK,
+    SCAN_MODULATION_DQPSK,
+    SCAN_MODULATION_APSK_16,
+    SCAN_MODULATION_APSK_32,
+    SCAN_MODULATION_VSB_8,
+    SCAN_MODULATION_VSB_16,
+} scan_modulation_t;
+
+#define make_tuple(a,b) ((a << 16)|b)
+typedef enum
+{
+    SCAN_CODERATE_AUTO = -1,
+    SCAN_CODERATE_NONE = 0,
+    SCAN_CODERATE_1_2  = make_tuple(1,2),
+    SCAN_CODERATE_2_3  = make_tuple(2,3),
+    SCAN_CODERATE_3_4  = make_tuple(3,4),
+    SCAN_CODERATE_3_5  = make_tuple(3,5),
+    SCAN_CODERATE_4_5  = make_tuple(4,5),
+    SCAN_CODERATE_5_6  = make_tuple(5,6),
+    SCAN_CODERATE_7_8  = make_tuple(7,8),
+    SCAN_CODERATE_8_9  = make_tuple(8,9),
+    SCAN_CODERATE_9_10 = make_tuple(9,10),
+} scan_coderate_t;
+
+typedef enum
+{
+    SCAN_POLARIZATION_NONE       = 0,
+    SCAN_POLARIZATION_HORIZONTAL = 'H',
+    SCAN_POLARIZATION_CIRC_LEFT  = 'L',
+    SCAN_POLARIZATION_CIRC_RIGHT = 'R',
+    SCAN_POLARIZATION_VERTICAL   = 'V',
+} scan_polarization_t;
+
+typedef enum
+{
+    SCAN_GUARD_INTERVAL_AUTO   = 0,
+    SCAN_GUARD_INTERVAL_1_4    = make_tuple(1,4),
+    SCAN_GUARD_INTERVAL_1_8    = make_tuple(1,8),
+    SCAN_GUARD_INTERVAL_1_16   = make_tuple(1,16),
+    SCAN_GUARD_INTERVAL_1_32   = make_tuple(1,32),
+    SCAN_GUARD_INTERVAL_1_128  = make_tuple(1,128),
+    SCAN_GUARD_INTERVAL_19_128 = make_tuple(19,128),
+    SCAN_GUARD_INTERVAL_19_256 = make_tuple(19,256),
+} scan_guard_t;
+
 typedef struct
 {
     unsigned i_frequency;
@@ -37,10 +104,15 @@ typedef struct
         unsigned i_bandwidth;
         unsigned i_symbolrate;
     };
-    int i_fec;
-    int i_modulation;
-    char c_polarization;
+
+    scan_modulation_t modulation;
+    scan_coderate_t coderate_lp;
+    scan_coderate_t coderate_hp;
+    scan_coderate_t inner_fec;
+    scan_polarization_t polarization;
+
     scan_type_t type;
+    scan_delivery_t delivery;
 
 } scan_tuner_config_t;
 
@@ -109,3 +181,6 @@ int scan_Run( scan_t *p_scan );
 
 block_t *scan_GetM3U( scan_t *p_scan );
 bool scan_IsCancelled( scan_t *p_scan );
+
+const char *scan_value_modulation(scan_modulation_t);
+const char *scan_value_coderate(scan_coderate_t);
index f6f48df..e09ebb5 100644 (file)
@@ -24,6 +24,7 @@
 #include <vlc_common.h>
 #include <vlc_fs.h>
 
+#include "scan.h"
 #include "scan_list.h"
 
 static scan_list_entry_t * scan_list_entry_New()
@@ -31,8 +32,10 @@ static scan_list_entry_t * scan_list_entry_New()
     scan_list_entry_t *p_entry = calloc(1, sizeof(scan_list_entry_t));
     if( likely(p_entry) )
     {
-        p_entry->i_service = -1;
-        p_entry->i_stream_id = -1;
+        p_entry->coderate_hp = SCAN_CODERATE_AUTO;
+        p_entry->coderate_lp = SCAN_CODERATE_AUTO;
+        p_entry->inner_fec = SCAN_CODERATE_AUTO;
+        p_entry->modulation = SCAN_MODULATION_AUTO;
     }
     return p_entry;
 }
@@ -47,19 +50,17 @@ static bool scan_list_entry_validate( const scan_list_entry_t *p_entry )
 {
     switch( p_entry->delivery )
     {
-        case DELIVERY_DVBS:
-        case DELIVERY_DVBS2:
-            return p_entry->i_freq && p_entry->i_rate && p_entry->i_fec;
+        case SCAN_DELIVERY_DVB_S:
+        case SCAN_DELIVERY_DVB_S2:
+        case SCAN_DELIVERY_DVB_C:
+            return p_entry->i_freq && p_entry->i_rate;
 
-        case DELIVERY_DVBT:
-        case DELIVERY_DVBT2:
-        case DELIVERY_ISDBT:
+        case SCAN_DELIVERY_DVB_T:
+        case SCAN_DELIVERY_DVB_T2:
+        case SCAN_DELIVERY_ISDB_T:
             return p_entry->i_freq && p_entry->i_bw;
 
-        case DELIVERY_DVBC:
-            return p_entry->i_freq && p_entry->i_rate;
-
-        case DELIVERY_UNKNOWN:
+        case SCAN_DELIVERY_UNKNOWN:
         default:
             break;
     }
@@ -79,15 +80,31 @@ static bool scan_list_entry_add( scan_list_entry_t ***ppp_last, scan_list_entry_
     return false;
 }
 
-static void scan_list_parse_fec( scan_list_entry_t *p_entry, const char *psz )
+static int scan_list_parse_fec( const char *psz_fec )
+{
+    if ( psz_fec )
+    {
+        if( !strcmp( "NONE", psz_fec ) )
+            return SCAN_CODERATE_NONE;
+
+        uint16_t a, b;
+        if( 2 == sscanf(psz_fec, "%"SCNu16"/%"SCNu16, &a, &b) )
+            return make_tuple(a, b);
+    }
+
+    return SCAN_CODERATE_AUTO;
+}
+
+static int scan_list_parse_guard( const char *psz_guard )
 {
-    const char *psz_fec_list = "1/22/33/44/55/66/77/88/9";
-    const char *psz_fec = strstr( psz_fec_list, psz );
-    if ( !psz_fec )
-        p_entry->i_fec = 9;    /* FEC_AUTO */
-    else
-        p_entry->i_fec = 1 + ( ( psz_fec - psz_fec_list ) / 3 );
+    if ( psz_guard && strcmp( "AUTO", psz_guard ) )
+    {
+        uint16_t a, b;
+        if( 2 == sscanf(psz_guard, "%"SCNu16"/%"SCNu16, &a, &b) )
+            return make_tuple(a, b);
+    }
 
+    return SCAN_GUARD_INTERVAL_AUTO;
 }
 
 static void scan_token_strip( const char **ppsz, size_t *pi_len )
@@ -145,6 +162,16 @@ static bool scan_list_token_split( const char *psz_line, size_t i_len,
 #define VALUE_EQUALS(token) \
     ((sizeof(token) - 1) == i_valuelen && !strncasecmp( psz_value, token, i_valuelen ))
 
+#define READ_STRINGVAL(variable, parser) { \
+    char *psz_val = strndup(psz_value, i_valuelen);\
+    if( psz_val )\
+    {\
+        variable = parser( psz_val );\
+        free( psz_val );\
+    } }
+
+#define WLEN(string) (sizeof(string) - 1), string
+
 static void scan_list_dvbv5_entry_fill( scan_list_entry_t *p_entry, const char *psz_line, size_t i_len )
 {
     const char *psz_key;
@@ -157,11 +184,7 @@ static void scan_list_dvbv5_entry_fill( scan_list_entry_t *p_entry, const char *
 
     char *psz_end = (char *) &psz_value[i_valuelen];
 
-    if ( KEY_EQUALS("SERVICE_ID") )
-    {
-        p_entry->i_service = strtoll( psz_value, &psz_end, 10 );
-    }
-    else if( KEY_EQUALS("FREQUENCY") )
+    if( KEY_EQUALS("FREQUENCY") )
     {
         p_entry->i_freq = strtoll( psz_value, &psz_end, 10 );
     }
@@ -172,41 +195,77 @@ static void scan_list_dvbv5_entry_fill( scan_list_entry_t *p_entry, const char *
     else if( KEY_EQUALS("DELIVERY_SYSTEM") )
     {
         if( VALUE_EQUALS("DVBT") )
-            p_entry->delivery = DELIVERY_DVBT;
+            p_entry->delivery = SCAN_DELIVERY_DVB_T;
         else if( VALUE_EQUALS("DVBT2") )
-            p_entry->delivery = DELIVERY_DVBT2;
+            p_entry->delivery = SCAN_DELIVERY_DVB_T2;
         else if( VALUE_EQUALS("DVBS") )
-            p_entry->delivery = DELIVERY_DVBS;
+            p_entry->delivery = SCAN_DELIVERY_DVB_S;
         else if( VALUE_EQUALS("DVBS2") )
-            p_entry->delivery = DELIVERY_DVBS2;
+            p_entry->delivery = SCAN_DELIVERY_DVB_S2;
         else if( VALUE_EQUALS("DVBC/ANNEX_A") )
-            p_entry->delivery = DELIVERY_DVBC;
+            p_entry->delivery = SCAN_DELIVERY_DVB_C;
         else if( VALUE_EQUALS("ISDBT") )
-            p_entry->delivery = DELIVERY_ISDBT;
+            p_entry->delivery = SCAN_DELIVERY_ISDB_T;
+    }
+    else if( KEY_EQUALS("MODULATION") )
+    {
+        static const struct
+        {
+            size_t i_len;
+            const char *psz;
+            int val;
+        } map[] = {
+            { WLEN( "APSK/16" ), SCAN_MODULATION_APSK_16 },
+            { WLEN( "APSK/32" ), SCAN_MODULATION_APSK_32 },
+            { WLEN( "DQPSK" ),   SCAN_MODULATION_DQPSK },
+            { WLEN( "PSK/8" ),   SCAN_MODULATION_PSK_8 },
+            { WLEN( "QAM/4_NR" ),SCAN_MODULATION_QAM_4NR },
+            { WLEN( "QAM/16" ),  SCAN_MODULATION_QAM_16 },
+            { WLEN( "QAM/32" ),  SCAN_MODULATION_QAM_32 },
+            { WLEN( "QAM/64" ),  SCAN_MODULATION_QAM_64 },
+            { WLEN( "QAM/128" ), SCAN_MODULATION_QAM_128 },
+            { WLEN( "QAM/256" ), SCAN_MODULATION_QAM_256 },
+            { WLEN( "QAM/AUTO" ),SCAN_MODULATION_QAM_AUTO },
+            { WLEN( "QPSK" ),    SCAN_MODULATION_QPSK },
+            { WLEN( "VSB/8" ),   SCAN_MODULATION_VSB_8 },
+            { WLEN( "VSB/16" ),  SCAN_MODULATION_VSB_16 },
+        };
+        p_entry->modulation = SCAN_MODULATION_AUTO;
+        for(size_t i=0; i<ARRAY_SIZE(map); i++)
+        {
+            if( map[i].i_len == i_valuelen && !strncasecmp( psz_value, map[i].psz, i_valuelen ) )
+            {
+                p_entry->modulation = map[i].val;
+                break;
+            }
+        }
     }
     else if( KEY_EQUALS("POLARIZATION") )
     {
         if( VALUE_EQUALS("VERTICAL") )
-            p_entry->polarization = POLARIZATION_VERTICAL;
+            p_entry->polarization = SCAN_POLARIZATION_VERTICAL;
         else
-            p_entry->polarization = POLARIZATION_HORIZONTAL;
+            p_entry->polarization = SCAN_POLARIZATION_HORIZONTAL;
     }
     else if( KEY_EQUALS("SYMBOL_RATE") )
     {
         p_entry->i_rate = strtoll( psz_value, &psz_end, 10 );
     }
-    else if( KEY_EQUALS("STREAM_ID") )
+    else if( KEY_EQUALS("INNER_FEC") )
     {
-        p_entry->i_stream_id = strtoll( psz_value, &psz_end, 10 );
+        READ_STRINGVAL( p_entry->inner_fec, scan_list_parse_fec );
     }
-    else if( KEY_EQUALS("INNER_FEC") )
+    else if( KEY_EQUALS("CODE_RATE_HP") )
     {
-        char *psz_val = strndup(psz_value, i_valuelen);
-        if( psz_val )
-        {
-            scan_list_parse_fec( p_entry, psz_val );
-            free( psz_val );
-        }
+        READ_STRINGVAL( p_entry->coderate_hp, scan_list_parse_fec );
+    }
+    else if( KEY_EQUALS("CODE_RATE_LP") )
+    {
+        READ_STRINGVAL( p_entry->coderate_lp, scan_list_parse_fec );
+    }
+    else if( KEY_EQUALS("GUARD_INTERVAL") )
+    {
+        READ_STRINGVAL( p_entry->guard_interval, scan_list_parse_guard );
     }
 }
 
@@ -339,15 +398,15 @@ scan_list_entry_t * scan_list_dvbv3_load( vlc_object_t *p_obj, const char *psz_s
 
         if( !strcmp( psz_token, "S" ) )
         {
-            p_entry->delivery = DELIVERY_DVBS;
+            p_entry->delivery = SCAN_DELIVERY_DVB_S;
         }
         else if( !strcmp( psz_token, "S2" ) )
         {
-            p_entry->delivery = DELIVERY_DVBS2;
+            p_entry->delivery = SCAN_DELIVERY_DVB_S2;
         }
 
         /* Parse the delivery format */
-        if( p_entry->delivery == DELIVERY_DVBS || p_entry->delivery == DELIVERY_DVBS2 )
+        if( p_entry->delivery == SCAN_DELIVERY_DVB_S || p_entry->delivery == SCAN_DELIVERY_DVB_S2 )
         {
             /* FREQUENCY */
             if( !(psz_token = strtok_r( NULL, psz_delims, &p_save )) )
@@ -357,8 +416,8 @@ scan_list_entry_t * scan_list_dvbv3_load( vlc_object_t *p_obj, const char *psz_s
             /* POLARIZATION */
             if( !(psz_token = strtok_r( NULL, psz_delims, &p_save )) )
                 continue;
-            p_entry->polarization = !strcasecmp(psz_token, "H") ? POLARIZATION_HORIZONTAL
-                                                                : POLARIZATION_VERTICAL;
+            p_entry->polarization = !strcasecmp(psz_token, "H") ? SCAN_POLARIZATION_HORIZONTAL
+                                                                : SCAN_POLARIZATION_VERTICAL;
 
             /* RATE */
             if( !(psz_token = strtok_r( NULL, psz_delims, &p_save )) )
@@ -368,7 +427,7 @@ scan_list_entry_t * scan_list_dvbv3_load( vlc_object_t *p_obj, const char *psz_s
             /* FEC */
             if( !(psz_token = strtok_r( NULL, psz_delims, &p_save )) )
                 continue;
-            scan_list_parse_fec( p_entry, psz_token );
+            p_entry->inner_fec = scan_list_parse_fec( psz_token );
 
             /* INVERSION */
             if( !(psz_token = strtok_r( NULL, psz_delims, &p_save )) )
@@ -381,7 +440,6 @@ scan_list_entry_t * scan_list_dvbv3_load( vlc_object_t *p_obj, const char *psz_s
             /* STREAM_ID */
             if( !(psz_token = strtok_r( NULL, psz_delims, &p_save )) )
                 continue;
-            p_entry->i_stream_id = atoi( psz_token );
         }
 
     }
index fb541fc..f63a585 100644 (file)
@@ -25,29 +25,18 @@ typedef struct scan_list_entry_t scan_list_entry_t;
 typedef struct scan_list_entry_t
 {
     char *psz_channel;
-    int   i_service;
-    int   i_stream_id;
+
     unsigned i_freq;
     unsigned i_bw;
-
     unsigned i_rate;
-    uint8_t  i_fec;
-    enum
-    {
-        POLARIZATION_VERTICAL = 0,
-        POLARIZATION_HORIZONTAL
-    } polarization;
-
-    enum
-    {
-        DELIVERY_UNKNOWN = 0,
-        DELIVERY_DVBT,
-        DELIVERY_DVBT2,
-        DELIVERY_DVBS,
-        DELIVERY_DVBS2,
-        DELIVERY_DVBC,
-        DELIVERY_ISDBT,
-    } delivery;
+
+    scan_modulation_t modulation;
+    scan_coderate_t   coderate_lp;
+    scan_coderate_t   coderate_hp;
+    scan_coderate_t   inner_fec;
+    scan_guard_t      guard_interval;
+    scan_delivery_t   delivery;
+    scan_polarization_t polarization;
 
     scan_list_entry_t *p_next;