From c843601360277eda30ccfb30c0ca172ac32892e6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 14 Jan 2012 01:13:38 -0200 Subject: [PATCH] dvb: add support for read/writing the other el PID Instead of just supporting audio and video, add support to write the other PID's to the file, in a generic way. Signed-off-by: Mauro Carvalho Chehab --- utils/dvb/dvb-file.c | 95 ++++++++++++++++++++++++++++++++++++++++++--------- utils/dvb/dvb-file.h | 5 ++- utils/dvb/dvbv5-zap.c | 14 ++++++++ utils/dvb/libscan.c | 51 ++++++--------------------- utils/dvb/libscan.h | 8 ++++- 5 files changed, 114 insertions(+), 59 deletions(-) diff --git a/utils/dvb/dvb-file.c b/utils/dvb/dvb-file.c index ff34e18..7da20a7 100644 --- a/utils/dvb/dvb-file.c +++ b/utils/dvb/dvb-file.c @@ -209,7 +209,7 @@ static const char *pol_name[] = { static int fill_entry(struct dvb_entry *entry, char *key, char *value) { - int i, j, len; + int i, j, len, type = 0, v; int is_video = 0, is_audio = 0, n_prop; uint16_t *pid = NULL; char *p; @@ -269,7 +269,7 @@ static int fill_entry(struct dvb_entry *entry, char *key, char *value) if (!strcasecmp(key, "VIDEO_PID")) is_video = 1; - else if (!strcasecmp(key, "AUDIO_PID")) + else if (!strcasecmp(key, "AUDIO_PID")) is_audio = 1; else if (!strcasecmp(key, "POLARIZATION")) { entry->service_id = atol(value); @@ -280,6 +280,26 @@ static int fill_entry(struct dvb_entry *entry, char *key, char *value) return -2; entry->pol = j; return 0; + } else if (!strncasecmp(key,"PID_", 4)){ + type = strtol(&key[4], NULL, 16); + if (!type) + return 0; + + len = 0; + + p = strtok(value," \t"); + if (!p) + return 0; + while (p) { + entry->other_el_pid = realloc(entry->other_el_pid, + (len + 1) * + sizeof (*entry->other_el_pid)); + entry->other_el_pid[len].type = type; + entry->other_el_pid[len].pid = atol(p); + p = strtok(NULL, " \t\n"); + len++; + } + entry->other_el_pid_len = len; } /* @@ -434,37 +454,58 @@ int write_dvb_file(const char *fname, struct dvb_file *dvb_file) fprintf(fp, "[%s]\n", entry->channel); if (entry->vchannel) fprintf(fp, "\tVCHANNEL = %s\n", entry->vchannel); + } else { + fprintf(fp, "[CHANNEL]\n"); + } + + if (entry->service_id) fprintf(fp, "\tSERVICE_ID = %d\n", entry->service_id); + if (entry->video_pid_len){ fprintf(fp, "\tVIDEO_PID ="); for (i = 0; i < entry->video_pid_len; i++) fprintf(fp, " %d", entry->video_pid[i]); fprintf(fp, "\n"); + } + if (entry->audio_pid_len) { fprintf(fp, "\tAUDIO_PID ="); for (i = 0; i < entry->audio_pid_len; i++) fprintf(fp, " %d", entry->audio_pid[i]); fprintf(fp, "\n"); + } - if (entry->pol != POLARIZATION_OFF) { - fprintf(fp, "\tPOLARIZATION = %s\n", - pol_name[entry->pol]); + if (entry->other_el_pid_len) { + int type = -1; + for (i = 0; i < entry->other_el_pid_len; i++) { + if (type != entry->other_el_pid[i].type) { + type = entry->other_el_pid[i].type; + if (i) + fprintf(fp, "\n"); + fprintf(fp, "\tPID_%02x =", type); + } + fprintf(fp, " %d", entry->other_el_pid[i].pid); } + fprintf(fp, "\n"); + } - if (entry->sat_number >= 0) { - fprintf(fp, "\tSAT_NUMBER = %d\n", - entry->sat_number); - } + if (entry->pol != POLARIZATION_OFF) { + fprintf(fp, "\tPOLARIZATION = %s\n", + pol_name[entry->pol]); + } - if (entry->diseqc_wait > 0) { - fprintf(fp, "\tDISEQC_WAIT = %d\n", - entry->diseqc_wait); - } - if (entry->lnb) - fprintf(fp, "\tLNB = %s\n", entry->lnb); - } else { - fprintf(fp, "[CHANNEL]\n"); + if (entry->sat_number >= 0) { + fprintf(fp, "\tSAT_NUMBER = %d\n", + entry->sat_number); } + + if (entry->diseqc_wait > 0) { + fprintf(fp, "\tDISEQC_WAIT = %d\n", + entry->diseqc_wait); + } + if (entry->lnb) + fprintf(fp, "\tLNB = %s\n", entry->lnb); + for (i = 0; i < entry->n_props; i++) { const char * const *attr_name = dvbv5_attr_names[entry->props[i].cmd]; if (attr_name) { @@ -647,6 +688,18 @@ static void handle_std_specific_parms(struct dvb_entry *entry, } } +static int sort_other_el_pid(const void *a_arg, const void *b_arg) +{ + const struct el_pid *a = a_arg, *b = b_arg; + int r; + + r = b->type - a->type; + if (r) + return r; + + return b->pid - a->pid; +} + int store_dvb_channel(struct dvb_file **dvb_file, struct dvb_v5_fe_parms *parms, struct dvb_descriptors *dvb_desc, @@ -724,6 +777,14 @@ int store_dvb_channel(struct dvb_file **dvb_file, entry->audio_pid[j] = pid_table->audio_pid[j]; entry->audio_pid_len = pid_table->audio_pid_len; + entry->other_el_pid = calloc(sizeof(*entry->other_el_pid), + pid_table->other_el_pid_len); + memcpy(entry->other_el_pid, pid_table->other_el_pid, + pid_table->other_el_pid_len * sizeof(*entry->other_el_pid)); + entry->other_el_pid_len = pid_table->other_el_pid_len; + qsort(entry->other_el_pid, entry->other_el_pid_len, + sizeof(*entry->other_el_pid), sort_other_el_pid); + /* Copy data from parms */ if (get_detected) dvb_fe_get_parms(parms); diff --git a/utils/dvb/dvb-file.h b/utils/dvb/dvb-file.h index 0791288..d439b7c 100644 --- a/utils/dvb/dvb-file.h +++ b/utils/dvb/dvb-file.h @@ -25,7 +25,8 @@ struct dvb_entry { struct dvb_entry *next; uint16_t service_id; uint16_t *video_pid, *audio_pid; - unsigned video_pid_len, audio_pid_len; + struct el_pid *other_el_pid; + unsigned video_pid_len, audio_pid_len, other_el_pid_len; char *channel; char *vchannel; @@ -87,6 +88,8 @@ static inline void dvb_file_free(struct dvb_file *dvb_file) free (entry->video_pid); if (entry->audio_pid) free (entry->audio_pid); + if (entry->other_el_pid) + free (entry->other_el_pid); if (entry->lnb) free (entry->lnb); entry = next; diff --git a/utils/dvb/dvbv5-zap.c b/utils/dvb/dvbv5-zap.c index ec59e55..739362b 100644 --- a/utils/dvb/dvbv5-zap.c +++ b/utils/dvb/dvbv5-zap.c @@ -40,6 +40,7 @@ #include #include "dvb-file.h" #include "dvb-demux.h" +#include "libscan.h" #define CHANNEL_FILE "channels.conf" #define PROGRAM_NAME "dvbv5-scan" @@ -168,6 +169,19 @@ static int parse(struct arguments *args, else *apid = entry->audio_pid[0]; } + if (entry->other_el_pid) { + int i, type = -1; + for (i = 0; i < entry->other_el_pid_len; i++) { + if (type != entry->other_el_pid[i].type) { + type = entry->other_el_pid[i].type; + if (i) + printf("\n"); + printf("service has pid type %02x: ", type); + } + printf(" %d", entry->other_el_pid[i].pid); + } + printf("\n"); + } *sid = entry->service_id; /* First of all, set the delivery system */ diff --git a/utils/dvb/libscan.c b/utils/dvb/libscan.c index b128764..21ec99f 100644 --- a/utils/dvb/libscan.c +++ b/utils/dvb/libscan.c @@ -112,47 +112,16 @@ static void parse_pmt(struct dvb_descriptors *dvb_desc, pid_table->audio_pid[i] = pid; /* Discard audio language descriptors */ break; - case 0x06: - /* - * Used for streaming synchronous and - * asynchronous data for broadcasting - * services. Applied to subtitles and - * superimposed characters. - */ - if (dvb_desc->verbose) - printf("independent PES (type 0x%02x) 0x%04x\n", - buf[0], pid); - break; - case 0x0b: - /* - * Used to transfer general synchronous and - * asynchronous data for broadcasting - * services. Applied to data transmission for - * Download services and multimedia services. - */ - if (dvb_desc->verbose) - printf("data carrousel (type 0x%02x) 0x%04x\n", - buf[0], pid); - break; - case 0x0c: - /* - * Used for synchronous and asynchronous - * message notification to an application on the - * receiver unit from the broadcasting station. - * Used in multimedia services. - */ - if (dvb_desc->verbose) - printf("event message (type 0x%02x) 0x%04x\n", - buf[0], pid); - break; - case 0x0d: - if (dvb_desc->verbose) - printf("data carrousel or event message (type 0x%02x) 0x%04x\n", - buf[0], pid); - break; default: if (dvb_desc->verbose) - printf("other pid (type 0x%02x) 0x%04x\n", buf[0], pid); + printf("pid type 0x02x: 0x%04x\n", pid); + i = pid_table->other_el_pid_len; + pid_table->other_el_pid = realloc(pid_table->other_el_pid, + sizeof(*pid_table->other_el_pid) * + ++pid_table->other_el_pid_len); + + pid_table->other_el_pid[i].type = buf[0]; + pid_table->other_el_pid[i].pid = pid; }; parse_descriptor(PMT, dvb_desc, &buf[5], len); @@ -443,8 +412,10 @@ void free_dvb_ts_tables(struct dvb_descriptors *dvb_desc) for (i = 0; i < pat_table->pid_table_len; i++) { if (pid_table[i].video_pid) free(pid_table[i].video_pid); - if (pid_table[i]. audio_pid) + if (pid_table[i].audio_pid) free(pid_table[i].audio_pid); + if (pid_table[i].other_el_pid) + free(pid_table[i].other_el_pid); } free(pid_table); } diff --git a/utils/dvb/libscan.h b/utils/dvb/libscan.h index cdd52af..7dca751 100644 --- a/utils/dvb/libscan.h +++ b/utils/dvb/libscan.h @@ -8,13 +8,19 @@ struct pmt_table { unsigned char version; }; +struct el_pid { + uint8_t type; + uint16_t pid; +}; + struct pid_table { uint16_t service_id; uint16_t pid; struct pmt_table pmt_table; - unsigned video_pid_len, audio_pid_len; + unsigned video_pid_len, audio_pid_len, other_el_pid_len; uint16_t *video_pid; uint16_t *audio_pid; + struct el_pid *other_el_pid; }; struct pat_table { -- 2.7.4