From: Akihiro Tsukada <tsk...@gmail.com>

added NIT scan for ISDB-S,
fixed wrong/too-close frequency of the scanned entries,
when freq_offset/bandwith was not set properly.

ISDB-S/T specific charset conversion is separeted off
as an iconv module, and not implemented in this lib.

Signed-off-by: Akihiro Tsukada <tsk...@gmail.com>
---
 lib/include/libdvbv5/dvb-scan.h |   2 +
 lib/libdvbv5/dvb-fe.c           |   6 +-
 lib/libdvbv5/dvb-file.c         |  21 +++++--
 lib/libdvbv5/dvb-scan.c         | 125 +++++++++++++++++++++++++++++++++++++++-
 lib/libdvbv5/parse_string.c     |  23 ++++++++
 5 files changed, 170 insertions(+), 7 deletions(-)

diff --git a/lib/include/libdvbv5/dvb-scan.h b/lib/include/libdvbv5/dvb-scan.h
index fe50687..e3a0d24 100644
--- a/lib/include/libdvbv5/dvb-scan.h
+++ b/lib/include/libdvbv5/dvb-scan.h
@@ -387,6 +387,8 @@ int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *parms);
 
 int dvb_new_freq_is_needed(struct dvb_entry *entry, struct dvb_entry 
*last_entry,
                           uint32_t freq, enum dvb_sat_polarization pol, int 
shift);
+int dvb_new_ts_is_needed(struct dvb_entry *entry, struct dvb_entry *last_entry,
+                          uint32_t freq, int shift, uint32_t ts_id);
 
 struct dvb_entry *dvb_scan_add_entry(struct dvb_v5_fe_parms *parms,
                                     struct dvb_entry *first_entry,
diff --git a/lib/libdvbv5/dvb-fe.c b/lib/libdvbv5/dvb-fe.c
index f535311..93c0b9b 100644
--- a/lib/libdvbv5/dvb-fe.c
+++ b/lib/libdvbv5/dvb-fe.c
@@ -372,6 +372,8 @@ int dvb_set_sys(struct dvb_v5_fe_parms *p, 
fe_delivery_system_t sys)
        parms->p.current_sys = sys;
        parms->n_props = rc;
 
+       if (sys == SYS_ISDBS /* || sys == SYS_ISDBT */)
+               parms->p.default_charset = "arib-std-b24";
        return 0;
 }
 
@@ -683,8 +685,10 @@ int dvb_fe_set_parms(struct dvb_v5_fe_parms *p)
                        dvb_logdbg("LNA is %s", parms->p.lna ? "ON" : "OFF");
        }
 
-       if (dvb_fe_is_satellite(tmp_parms.p.current_sys))
+       if (dvb_fe_is_satellite(tmp_parms.p.current_sys)) {
                dvb_sat_set_parms(&tmp_parms.p);
+               parms->freq_offset = tmp_parms.freq_offset;
+       }
 
        /* Filter out any user DTV_foo property such as DTV_POLARIZATION */
        tmp_parms.n_props = dvb_copy_fe_props(tmp_parms.dvb_prop,
diff --git a/lib/libdvbv5/dvb-file.c b/lib/libdvbv5/dvb-file.c
index bcb1762..0a0e41a 100644
--- a/lib/libdvbv5/dvb-file.c
+++ b/lib/libdvbv5/dvb-file.c
@@ -1125,12 +1125,25 @@ static int get_program_and_store(struct 
dvb_v5_fe_parms_priv *parms,
                entry->props[j].cmd = parms->dvb_prop[j].cmd;
                entry->props[j].u.data = parms->dvb_prop[j].u.data;
 
-               if ((!channel || !*channel) &&
-                   entry->props[j].cmd == DTV_FREQUENCY)
-                       freq = parms->dvb_prop[j].u.data;
+               if (entry->props[j].cmd == DTV_STREAM_ID &&
+                   entry->props[j].u.data == 0 &&
+                   parms->p.current_sys == SYS_ISDBS)
+                       entry->props[j].u.data = 
dvb_scan_handler->pat->header.id;
+
+               if (entry->props[j].cmd != DTV_FREQUENCY)
+                       continue;
+
+               if (dvb_fe_is_satellite(parms->p.current_sys) &&
+                   entry->props[j].u.data < parms->freq_offset)
+                       entry->props[j].u.data += parms->freq_offset;
+
+               if (!channel || !*channel)
+                       freq = entry->props[j].u.data;
        }
        if (!channel || !*channel) {
-               r = asprintf(&channel, "%.2fMHz#%d", freq/1000000., service_id);
+               r = asprintf(&channel, "%.2f%cHz#%d", freq / 1000000.,
+                       dvb_fe_is_satellite(parms->p.current_sys) ? 'G' : 'M',
+                       service_id);
                if (r < 0)
                        dvb_perror("asprintf");
                if (parms->p.verbose)
diff --git a/lib/libdvbv5/dvb-scan.c b/lib/libdvbv5/dvb-scan.c
index 3b70f5a..470ef61 100644
--- a/lib/libdvbv5/dvb-scan.c
+++ b/lib/libdvbv5/dvb-scan.c
@@ -635,7 +635,7 @@ int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *__p)
                rolloff = 115;
                break;
        case SYS_DVBS:
-       case SYS_ISDBS: /* FIXME: not sure if this rollof is right for ISDB-S */
+       case SYS_ISDBS:
                divisor = 100000;
                rolloff = 135;
                break;
@@ -672,11 +672,14 @@ int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *__p)
                 * purposes of estimating a max frequency shift here.
                 */
                dvb_fe_retrieve_parm(&parms->p, DTV_SYMBOL_RATE, &symbol_rate);
+               if (parms->p.current_sys == SYS_ISDBS)
+                       symbol_rate = 28800;
                bw = (symbol_rate * rolloff) / divisor;
        }
        if (!bw)
                dvb_fe_retrieve_parm(&parms->p, DTV_BANDWIDTH_HZ, &bw);
-
+       if (!bw && parms->p.current_sys == SYS_ISDBT)
+               bw = 6000000;
        /*
         * If the max frequency shift between two frequencies is below
         * than the used bandwidth / 8, it should be the same channel.
@@ -758,6 +761,87 @@ struct dvb_entry *dvb_scan_add_entry(struct 
dvb_v5_fe_parms *__p,
        return NULL;
 }
 
+int dvb_new_ts_is_needed(struct dvb_entry *entry, struct dvb_entry *last_entry,
+                        uint32_t freq, int shift, uint32_t ts_id)
+{
+       int i;
+       uint32_t data;
+
+       for (; entry != last_entry; entry = entry->next) {
+               for (i = 0; i < entry->n_props; i++) {
+                       data = entry->props[i].u.data;
+                       if (entry->props[i].cmd == DTV_STREAM_ID) {
+                               if (data != ts_id)
+                                       break;
+                       }
+                       if (entry->props[i].cmd == DTV_FREQUENCY) {
+                               if (freq < data - shift || freq > data + shift)
+                                       break;
+                       }
+               }
+               if (i == entry->n_props && entry->n_props > 0)
+                       return 0;
+       }
+
+       return 1;
+}
+
+static struct dvb_entry *
+dvb_scan_add_entry_isdbs(struct dvb_v5_fe_parms *__p,
+                        struct dvb_entry *first_entry, struct dvb_entry *entry,
+                        uint32_t freq, uint32_t shift, uint32_t ts_id)
+{
+       struct dvb_v5_fe_parms_priv *parms = (void *)__p;
+       struct dvb_entry *new_entry;
+       int i, n = 2;
+
+       if (!dvb_new_ts_is_needed(first_entry, NULL, freq, shift, ts_id))
+               return NULL;
+
+       /* Clone the current entry into a new entry */
+       new_entry = calloc(sizeof(*new_entry), 1);
+       if (!new_entry) {
+               dvb_perror("not enough memory for a new scanning frequency/TS");
+               return NULL;
+       }
+
+       memcpy(new_entry, entry, sizeof(*entry));
+       if (entry->channel)
+               new_entry->channel = strdup(entry->channel);
+       if (entry->vchannel)
+               new_entry->vchannel = strdup(entry->vchannel);
+       if (entry->location)
+               new_entry->location = strdup(entry->location);
+       if (entry->lnb)
+               new_entry->lnb = strdup(entry->lnb);
+
+       /*
+        * The frequency should change to the new one. Seek for it and
+        * replace its value to the desired one.
+        */
+       for (i = 0; i < new_entry->n_props; i++) {
+               if (new_entry->props[i].cmd == DTV_FREQUENCY) {
+                       new_entry->props[i].u.data = freq;
+                       /* Navigate to the end of the entry list */
+                       while (entry->next) {
+                               entry = entry->next;
+                               n++;
+                       }
+                       dvb_log("New transponder/channel found: #%d: %d",
+                               n, freq);
+                       entry->next = new_entry;
+                       new_entry->next = NULL;
+                       return new_entry;
+               }
+       }
+
+       /* This should never happen */
+       dvb_logerr("BUG: Couldn't add %d to the scan frequency list.", freq);
+       free(new_entry);
+
+       return NULL;
+}
+
 struct update_transponders {
        struct dvb_v5_fe_parms *parms;
        struct dvb_v5_descriptors *dvb_scan_handler;
@@ -987,6 +1071,36 @@ static void add_update_nit_dvbs(struct dvb_table_nit *nit,
                                     SYS_DVBS2);
 }
 
+static void add_update_nit_isdbs(struct dvb_table_nit *nit,
+                                struct dvb_table_nit_transport *tran,
+                                struct dvb_desc *desc,
+                                void *priv)
+{
+       struct update_transponders *tr = priv;
+       struct dvb_entry *new;
+       struct dvb_desc_sat *d = (void *)desc;
+       uint32_t ts_id;
+
+       if (tr->update)
+               return;
+
+        ts_id = tran->transport_id;
+       new = dvb_scan_add_entry_isdbs(tr->parms, tr->first_entry, tr->entry,
+                                      d->frequency, tr->shift, ts_id);
+       if (!new)
+               return;
+
+       /* Set NIT ISDB-S props for the transponder */
+       /* modulation is not defined here but in TMCC. */
+       /* skip setting it since no "AUTO" value in fe_modulation_t */
+       dvb_store_entry_prop(new, DTV_POLARIZATION,
+                            dvbs_polarization[d->polarization]);
+       dvb_store_entry_prop(new, DTV_SYMBOL_RATE,
+                            d->symbol_rate);
+       dvb_store_entry_prop(new, DTV_INNER_FEC,
+                            dvbs_dvbc_dvbs_freq_inner[d->fec]);
+}
+
 
 static void __dvb_add_update_transponders(struct dvb_v5_fe_parms_priv *parms,
                                          struct dvb_v5_descriptors 
*dvb_scan_handler,
@@ -1045,6 +1159,13 @@ static void __dvb_add_update_transponders(struct 
dvb_v5_fe_parms_priv *parms,
                                satellite_delivery_system_descriptor,
                                NULL, add_update_nit_dvbs, &tr);
                return;
+       case SYS_ISDBS:
+               dvb_table_nit_descriptor_handler(
+                               &parms->p, dvb_scan_handler->nit,
+                               satellite_delivery_system_descriptor,
+                               NULL, add_update_nit_isdbs, &tr);
+               return;
+
        default:
                dvb_log("Transponders detection not implemented for this 
standard yet.");
                return;
diff --git a/lib/libdvbv5/parse_string.c b/lib/libdvbv5/parse_string.c
index 3750d04..6a4de2b 100644
--- a/lib/libdvbv5/parse_string.c
+++ b/lib/libdvbv5/parse_string.c
@@ -366,6 +366,22 @@ static void charset_conversion(struct dvb_v5_fe_parms 
*parms, char **dest, const
                                     parms->output_charset);
 }
 
+static void isdb_parse_string(struct dvb_v5_fe_parms *parms, char **dest,
+                             const unsigned char *src, size_t len)
+{
+       int destlen;
+
+       destlen = len * 4;
+       *dest = malloc(destlen + 1);
+       dvb_iconv_to_charset(parms, *dest, destlen, src, len,
+                            "ARIB-STD-B24", parms->output_charset);
+       /* The code had over-sized the space. Fix it. */
+       if (*dest)
+               *dest = realloc(*dest, strlen(*dest) + 1);
+       return;
+}
+
+
 void dvb_parse_string(struct dvb_v5_fe_parms *parms, char **dest, char **emph,
                      const unsigned char *src, size_t len)
 {
@@ -386,6 +402,13 @@ void dvb_parse_string(struct dvb_v5_fe_parms *parms, char 
**dest, char **emph,
        if (!len)
                return;
 
+       /* Strings in ISDB-S/T do not start with a charset identifier, */
+       /*  and can start with a control character. */
+       if (!strcasecmp(type, "ARIB-STD-B24")) {
+               isdb_parse_string(parms, dest, src, len);
+               return;
+       }
+
        if (*src < 0x20) {
                switch (*src) {
                case 0x00:      type = "ISO-6937";              break;
-- 
2.1.2

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to