utils/dvb: Add support for parsing zap format
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 29 Dec 2011 16:00:16 +0000 (13:00 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 7 Jan 2012 13:12:13 +0000 (11:12 -0200)
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
utils/dvb/Makefile
utils/dvb/dvb-fe.c
utils/dvb/dvb-file.c
utils/dvb/dvb-file.h
utils/dvb/dvb-zap-format.c [new file with mode: 0644]

index c7dc878f94bd8b59cf4bf7055c4895a06f5b7e55..e090b78eb8e9382899a03a465f23bf8a4ce42a59 100644 (file)
@@ -5,7 +5,8 @@ all: $(TARGETS)
 -include *.d
 
 dvb-fe-tool: dvb-fe-tool.o dvb-fe.o
-dvbzap: dvbzap.o dvb-fe.o util.o dvb-legacy-channel-format.o dvb-file.o
+dvbzap: dvbzap.o dvb-fe.o util.o dvb-file.o \
+               dvb-zap-format.o dvb-legacy-channel-format.o
 
        $(CC) $(LDFLAGS) -o $@ $^
 
index 72d52d00307c25abdf532a3e7bad02a52690806c..88fd3f8ea1e99c5614e361507bf8886993e70c27 100644 (file)
@@ -235,7 +235,7 @@ void dvb_fe_prt_parms(struct dvb_v5_fe_parms *parms)
                const char **attr_name = dvbv5_attr_names[parms->dvb_prop[i].cmd];
                if (attr_name) {
                        int j;
-                       
+
                        for (j = 0; j < parms->dvb_prop[i].u.data; j++) {
                                if (!*attr_name)
                                        break;
@@ -383,7 +383,7 @@ int dvb_fe_set_parms(struct dvb_v5_fe_parms *parms)
                return 0;
        }
        /* DVBv3 call */
-       
+
        dvb_fe_retrieve_parm(parms, DTV_FREQUENCY, &v3_parms.frequency);
        dvb_fe_retrieve_parm(parms, DTV_INVERSION, &v3_parms.inversion);
        switch (parms->current_sys) {
index 43b099db4749e3fb39fc828375f72412accdb185..ca56f47879cdbf2a3fa86005ca1480fca9ca418a 100644 (file)
@@ -28,6 +28,7 @@
  * just one line.
  */
 struct dvb_file *parse_format_oneline(const char *fname, const char *delimiter,
+                                     uint32_t delsys,
                                      const struct parse_struct *formats)
 {
        char *buf = NULL, *p;
@@ -59,17 +60,26 @@ struct dvb_file *parse_format_oneline(const char *fname, const char *delimiter,
                if (!len)
                        break;
                line++;
-               p = strtok(buf, delimiter);
-               if (!p) {
-                       sprintf(err_msg, "unknown delivery system type for %s",
-                               p);
-                       goto error;
-               }
 
-               /* Parse the type of the delivery system */
-               for (i = 0; formats[i].id != NULL; i++) {
-                       if (!strcmp(p, formats[i].id))
-                               break;
+               if (!delsys) {
+                       p = strtok(buf, delimiter);
+                       if (!p) {
+                               sprintf(err_msg, "unknown delivery system type for %s",
+                                       p);
+                               goto error;
+                       }
+
+                       /* Parse the type of the delivery system */
+                       for (i = 0; formats[i].id != NULL; i++) {
+                               if (!strcmp(p, formats[i].id))
+                                       break;
+                       }
+               } else {
+                       /* Seek for the delivery system */
+                       for (i = 0; formats[i].id != NULL; i++) {
+                               if (formats[i].delsys == delsys)
+                                       break;
+                       }
                }
                if (i == ARRAY_SIZE(formats))
                        goto error;
@@ -114,8 +124,25 @@ struct dvb_file *parse_format_oneline(const char *fname, const char *delimiter,
                                long v = atol(p);
                                if (table->mult_factor)
                                        v *= table->mult_factor;
-                               entry->props[entry->n_props].cmd = table->prop;
-                               entry->props[entry->n_props++].u.data = v;
+
+                               switch (table->prop) {
+                               case DTV_VIDEO_PID:
+                                       entry->video_pid = v;
+                                       break;
+                               case DTV_AUDIO_PID:
+                                       entry->audio_pid = v;
+                                       break;
+                               case DTV_SERVICE_PID:
+                                       entry->service_pid = v;
+                                       break;
+                               case DTV_CH_NAME:
+                                       entry->channel = calloc(strlen(p) + 1, 1);
+                                       strcpy(entry->channel, p);
+                                       break;
+                               default:
+                                       entry->props[entry->n_props].cmd = table->prop;
+                                       entry->props[entry->n_props++].u.data = v;
+                               }
                        }
                        if (table->prop == DTV_INVERSION)
                                has_inversion = 1;
index 0b61cb20a43ff043c921fa4f541c90efde094edf..491e0488416253954502ccaeb0122532c52aa42b 100644 (file)
@@ -32,6 +32,8 @@ struct dvb_entry {
        unsigned int n_props;
        struct dvb_entry *next;
        enum polarization pol;
+       uint32_t video_pid, audio_pid, service_pid;
+       char *channel;
 };
 
 struct dvb_file {
@@ -55,21 +57,34 @@ struct parse_struct {
 };
 
 #define PTABLE(a) .table = a, .size=ARRAY_SIZE(a)
+
+/* FAKE DTV codes, for internal usage */
 #define DTV_POLARIZATION        (DTV_MAX_COMMAND + 200)
+#define DTV_VIDEO_PID           (DTV_MAX_COMMAND + 201)
+#define DTV_AUDIO_PID           (DTV_MAX_COMMAND + 202)
+#define DTV_SERVICE_PID         (DTV_MAX_COMMAND + 203)
+#define DTV_CH_NAME             (DTV_MAX_COMMAND + 204)
 
 static inline void dvb_file_free(struct dvb_file *dvb_file)
 {
        struct dvb_entry *entry = dvb_file->first_entry, *next;
        while (entry) {
                next = entry->next;
+               if (entry->channel)
+                       free (entry->channel);
                free (entry);
                entry = next;
        }
        free (dvb_file);
 }
 
-/* From dvb_legacy_channel_format.c */
+/* From dvb-legacy-channel-format.c */
 extern const const struct parse_struct channel_formats[];
 
+/* From dvb-zap-format.c */
+extern const const struct parse_struct zap_formats[];
+
+/* From dvb-file.c */
 struct dvb_file *parse_format_oneline(const char *fname, const char *delimiter,
+                                     uint32_t delsys,
                                      const struct parse_struct *formats);
diff --git a/utils/dvb/dvb-zap-format.c b/utils/dvb/dvb-zap-format.c
new file mode 100644 (file)
index 0000000..415709d
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2011 - Mauro Carvalho Chehab <mchehab@redhat.com>
+ *
+ * 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 the Free Software Foundation version 2
+ * of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dvb-file.h"
+
+/*
+ * Standard channel.conf format for DVB-T, DVB-C, DVB-S and ATSC
+ */
+
+static const char *zap_parse_inversion[] = {
+       [INVERSION_OFF]  = "INVERSION_OFF",
+       [INVERSION_ON]   = "INVERSION_ON",
+       [INVERSION_AUTO] = "INVERSION_AUTO"
+};
+
+static const char *zap_parse_code_rate[] = {
+       [FEC_1_2] =  "FEC_1_2",
+       [FEC_2_3] =  "FEC_2_3",
+       [FEC_3_4] =  "FEC_3_4",
+       [FEC_3_5] =  "FEC_3_5",
+       [FEC_4_5] =  "FEC_4_5",
+       [FEC_5_6] =  "FEC_5_6",
+       [FEC_6_7] =  "FEC_6_7",
+       [FEC_7_8] =  "FEC_7_8",
+       [FEC_8_9] =  "FEC_8_9",
+       [FEC_9_10] = "FEC_9_10",
+       [FEC_AUTO] = "FEC_AUTO",
+       [FEC_NONE] = "FEC_NONE",
+};
+
+static const char *zap_parse_modulation[] = {
+       [QPSK] =     "QPSK",
+       [QAM_16] =   "QAM_16",
+       [QAM_32] =   "QAM_32",
+       [QAM_64] =   "QAM_64",
+       [QAM_128] =  "QAM_128",
+       [QAM_256] =  "QAM_256",
+       [QAM_AUTO] = "QAM_AUTO",
+       [PSK_8] =    "8PSK",
+       [VSB_8] =    "8VSB",
+       [VSB_16] =   "16VSB",
+       [APSK_16] =  "APSK16",
+       [APSK_32] =  "APSK32",
+       [DQPSK] =    "DQPSK",
+};
+
+
+static const char *zap_parse_trans_mode[] = {
+       [TRANSMISSION_MODE_1K] =   "TRANSMISSION_MODE_1K",
+       [TRANSMISSION_MODE_2K] =   "TRANSMISSION_MODE_2K",
+       [TRANSMISSION_MODE_4K] =   "TRANSMISSION_MODE_4K",
+       [TRANSMISSION_MODE_8K] =   "TRANSMISSION_MODE_8K",
+       [TRANSMISSION_MODE_16K] =  "TRANSMISSION_MODE_16K",
+       [TRANSMISSION_MODE_32K] =  "TRANSMISSION_MODE_32K",
+       [TRANSMISSION_MODE_AUTO] = "TRANSMISSION_MODE_AUTO",
+};
+
+static const char *zap_parse_guard_interval[8] = {
+       [GUARD_INTERVAL_1_4] =    "GUARD_INTERVAL_1_4",
+       [GUARD_INTERVAL_1_8] =    "GUARD_INTERVAL_1_8",
+       [GUARD_INTERVAL_1_16] =   "GUARD_INTERVAL_1_16",
+       [GUARD_INTERVAL_1_32] =   "GUARD_INTERVAL_1_32",
+       [GUARD_INTERVAL_1_128] =  "GUARD_INTERVAL_1_128",
+       [GUARD_INTERVAL_19_128] = "GUARD_INTERVAL_19_128",
+       [GUARD_INTERVAL_19_256] = "GUARD_INTERVAL_19_256",
+       [GUARD_INTERVAL_AUTO] =   "GUARD_INTERVAL_AUTO",
+};
+
+static const char *zap_parse_hierarchy[] = {
+       [HIERARCHY_1] =    "HIERARCHY_1",
+       [HIERARCHY_2] =    "HIERARCHY_2",
+       [HIERARCHY_4] =    "HIERARCHY_4",
+       [HIERARCHY_AUTO] = "HIERARCHY_AUTO",
+       [HIERARCHY_NONE] = "HIERARCHY_NONE",
+};
+
+static const char *zap_parse_bandwidth[] = {
+       [BANDWIDTH_1_712_MHZ] = "BANDWIDTH_1.712MHZ",
+       [BANDWIDTH_5_MHZ] =     "BANDWIDTH_5MHZ",
+       [BANDWIDTH_6_MHZ] =     "BANDWIDTH_6MHZ",
+       [BANDWIDTH_7_MHZ] =     "BANDWIDTH_7MHZ",
+       [BANDWIDTH_8_MHZ] =     "BANDWIDTH_8MHZ",
+       [BANDWIDTH_10_MHZ] =    "BANDWIDTH_10MHZ",
+       [BANDWIDTH_AUTO] =      "BANDWIDTH_AUTO",
+};
+
+static const char *zap_parse_polarization[] = {
+       [POLARIZATION_H] = "H",
+       [POLARIZATION_V] = "V",
+       [POLARIZATION_L] = "L",
+       [POLARIZATION_R] = "R",
+};
+
+static const struct parse_table sys_atsc_table[] = {
+       { DTV_CH_NAME, NULL, 0 },
+
+       { DTV_FREQUENCY, NULL, 0 },
+       { DTV_MODULATION, PTABLE(zap_parse_modulation) },
+
+       { DTV_VIDEO_PID, NULL, 0 },
+       { DTV_AUDIO_PID, NULL, 0 },
+       { DTV_SERVICE_PID, NULL, 0 },
+
+};
+
+static const struct parse_table sys_dvbc_table[] = {
+       { DTV_CH_NAME, NULL, 0 },
+
+       { DTV_FREQUENCY, NULL, 0 },
+       { DTV_INVERSION, PTABLE(zap_parse_inversion) },
+       { DTV_SYMBOL_RATE, NULL, 0 },
+       { DTV_INNER_FEC, PTABLE(zap_parse_code_rate) },
+       { DTV_MODULATION, PTABLE(zap_parse_modulation) },
+
+       { DTV_VIDEO_PID, NULL, 0 },
+       { DTV_AUDIO_PID, NULL, 0 },
+       { DTV_SERVICE_PID, NULL, 0 },
+};
+
+/* Note: On DVB-S, frequency and symbol rate are divided by 1000 */
+static const struct parse_table sys_dvbs_table[] = {
+       { DTV_CH_NAME, NULL, 0 },
+
+       { DTV_FREQUENCY, NULL, 0 },
+       { DTV_POLARIZATION, PTABLE(zap_parse_polarization) },
+       { DTV_SYMBOL_RATE, NULL, 0, .mult_factor = 1000 },
+
+       { DTV_VIDEO_PID, NULL, 0 },
+       { DTV_AUDIO_PID, NULL, 0 },
+       { DTV_SERVICE_PID, NULL, 0 },
+
+};
+
+static const struct parse_table sys_dvbt_table[] = {
+       { DTV_CH_NAME, NULL, 0 },
+
+       { DTV_FREQUENCY, NULL, 0 },
+       { DTV_INVERSION, PTABLE(zap_parse_inversion) },
+       { DTV_BANDWIDTH_HZ, PTABLE(zap_parse_bandwidth) },
+       { DTV_CODE_RATE_HP, PTABLE(zap_parse_code_rate) },
+       { DTV_CODE_RATE_LP, PTABLE(zap_parse_code_rate) },
+       { DTV_MODULATION, PTABLE(zap_parse_modulation) },
+       { DTV_TRANSMISSION_MODE, PTABLE(zap_parse_trans_mode) },
+       { DTV_GUARD_INTERVAL, PTABLE(zap_parse_guard_interval) },
+       { DTV_HIERARCHY, PTABLE(zap_parse_hierarchy) },
+
+       { DTV_VIDEO_PID, NULL, 0 },
+       { DTV_AUDIO_PID, NULL, 0 },
+       { DTV_SERVICE_PID, NULL, 0 },
+};
+
+const struct parse_struct zap_formats[] = {
+       {
+               .id             = "A",
+               .delsys         = SYS_ATSC,
+               PTABLE(sys_atsc_table),
+       }, {
+               .id             = "C",
+               .delsys         = SYS_DVBC_ANNEX_A,
+               PTABLE(sys_dvbc_table),
+       }, {
+               .id             = "S",
+               .delsys         = SYS_DVBS,
+               PTABLE(sys_dvbs_table),
+       }, {
+               .id             = "T",
+               .delsys         = SYS_DVBT,
+               PTABLE(sys_dvbt_table),
+       }, {
+               NULL, 0, NULL, 0,
+       }
+};