From: tskd08@gmail.com
To: linux-media@vger.kernel.org
Cc: m.chehab@samsung.com
Subject: [PATCH 3/4] v4l-utils/libdvbv5: add support for ISDB-S scanning
Date: Wed, 8 Oct 2014 21:09:40 +0900 [thread overview]
Message-ID: <1412770181-5420-4-git-send-email-tskd08@gmail.com> (raw)
In-Reply-To: <1412770181-5420-1-git-send-email-tskd08@gmail.com>
From: Akihiro Tsukada <tskd08@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 <tskd08@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
next prev parent reply other threads:[~2014-10-08 12:10 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-08 12:09 [PATCH 0/4] v4l-utils:libdvbv5,dvb: add basic support for ISDB-S tskd08
2014-10-08 12:09 ` [PATCH 1/4] v4l-utils/libdvbv5: avoid crash when failed to get a channel name tskd08
2014-10-08 16:05 ` Mauro Carvalho Chehab
2014-10-08 12:09 ` [PATCH 2/4] v4l-utils/libdvbv5: add support for ISDB-S tuning tskd08
2014-10-08 13:57 ` Mauro Carvalho Chehab
2014-10-08 12:09 ` tskd08 [this message]
2014-10-08 15:59 ` [PATCH 3/4] v4l-utils/libdvbv5: add support for ISDB-S scanning Mauro Carvalho Chehab
2014-10-08 12:09 ` [PATCH 4/4] v4l-utils/dvbv5-scan: " tskd08
2014-10-08 16:04 ` Mauro Carvalho Chehab
2014-10-09 18:11 ` Akihiro TSUKADA
2014-10-09 18:35 ` Mauro Carvalho Chehab
2014-10-08 16:22 ` [PATCH 0/4] v4l-utils:libdvbv5,dvb: add basic support for ISDB-S Mauro Carvalho Chehab
2014-10-09 16:41 ` Akihiro TSUKADA
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1412770181-5420-4-git-send-email-tskd08@gmail.com \
--to=tskd08@gmail.com \
--cc=linux-media@vger.kernel.org \
--cc=m.chehab@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.