From: Mauro Carvalho Chehab Date: Sun, 17 Nov 2013 15:49:44 +0000 (-0200) Subject: libdvbv5: produce dvb data from the new structures X-Git-Tag: v4l-utils-1.2.0~342 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=857fb25f85ae3094f69add36e25bfa55ec761ad9;p=platform%2Fupstream%2Fv4l-utils.git libdvbv5: produce dvb data from the new structures Now that dvb-scan uses the new descriptor structures, convert dvb-file to rely on them to produce the scanned file data. Signed-off-by: Mauro Carvalho Chehab --- diff --git a/lib/include/descriptors/pat.h b/lib/include/descriptors/pat.h index b37ae40..419e342 100644 --- a/lib/include/descriptors/pat.h +++ b/lib/include/descriptors/pat.h @@ -49,7 +49,7 @@ struct dvb_table_pat { #define dvb_pat_program_foreach(_program, _pat) \ struct dvb_table_pat_program *_program; \ - for(int _i = 0; _i < _pat->programs && (_program = _pat->program + _i); _i++) \ + for (int _i = 0; _i < _pat->programs && (_program = _pat->program + _i); _i++) \ struct dvb_v5_fe_parms; diff --git a/lib/include/descriptors/pmt.h b/lib/include/descriptors/pmt.h index 3a585fa..79a6172 100644 --- a/lib/include/descriptors/pmt.h +++ b/lib/include/descriptors/pmt.h @@ -100,7 +100,7 @@ struct dvb_table_pmt { } __attribute__((packed)); #define dvb_pmt_stream_foreach(_stream, _pmt) \ - for( struct dvb_table_pmt_stream *_stream = _pmt->stream; _stream; _stream = _stream->next ) \ + for (struct dvb_table_pmt_stream *_stream = _pmt->stream; _stream; _stream = _stream->next) \ struct dvb_v5_fe_parms; diff --git a/lib/include/descriptors/sdt.h b/lib/include/descriptors/sdt.h index d94c23c..493b853 100644 --- a/lib/include/descriptors/sdt.h +++ b/lib/include/descriptors/sdt.h @@ -57,7 +57,7 @@ struct dvb_table_sdt { } __attribute__((packed)); #define dvb_sdt_service_foreach(_service, _sdt) \ - for( struct dvb_table_sdt_service *_service = _sdt->service; _service; _service = _service->next ) \ + for (struct dvb_table_sdt_service *_service = _sdt->service; _service; _service = _service->next ) \ struct dvb_v5_fe_parms; diff --git a/lib/include/dvb-scan-table-handler.h b/lib/include/dvb-scan-table-handler.h index 81ced1f..cadf03b 100644 --- a/lib/include/dvb-scan-table-handler.h +++ b/lib/include/dvb-scan-table-handler.h @@ -49,33 +49,11 @@ #include "descriptors/desc_atsc_service_location.h" #include "descriptors/desc_hierarchy.h" -struct pmt_table { - uint16_t program_number, pcr_pid; - 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, other_el_pid_len; - uint16_t *video_pid; - uint16_t *audio_pid; - struct el_pid *other_el_pid; -}; - -struct pat_table { - uint16_t ts_id; - unsigned char version; - struct pid_table *pid_table; - unsigned pid_table_len; -}; - struct transport_table { uint16_t tr_id; }; @@ -147,25 +125,24 @@ struct sdt_table { unsigned service_table_len; }; + struct dvb_v5_descriptors_program { - struct dvb_table_pat_program *program; + struct dvb_table_pat_program *pat_pgm; struct dvb_table_pmt *pmt; }; + struct dvb_v5_descriptors { int verbose; uint32_t delivery_system; - struct pat_table pat_table; struct nit_table nit_table; struct sdt_table sdt_table; - /* Used by descriptors to know where to update a PMT/Service/TS */ - unsigned cur_pmt; - unsigned cur_service; - unsigned cur_ts; - /* New data */ + struct dvb_entry *entry; + unsigned num_entry; + struct dvb_table_pat *pat; struct dvb_table_vct *vct; struct dvb_v5_descriptors_program *program; diff --git a/lib/libdvbv5/dvb-file.c b/lib/libdvbv5/dvb-file.c index b5b276b..fe715d5 100644 --- a/lib/libdvbv5/dvb-file.c +++ b/lib/libdvbv5/dvb-file.c @@ -27,6 +27,7 @@ #include "dvb-v5-std.h" #include "dvb-scan.h" #include "dvb-scan-table-handler.h" +#include "dvb-log.h" /* * Generic parse function for all formats each channel is contained into @@ -887,119 +888,205 @@ static int sort_other_el_pid(const void *a_arg, const void *b_arg) return b->pid - a->pid; } + +static void get_pmt_descriptors(struct dvb_entry *entry, + struct dvb_table_pmt *pmt) +{ + int has_ac3 = 0; + int video_len = 0, audio_len = 0, other_len = 0; + + dvb_pmt_stream_foreach(stream, pmt) { + uint16_t pid = stream->elementary_pid; + + switch(stream->type) { + case 0x01: /* ISO/IEC 11172-2 Video */ + case 0x02: /* H.262, ISO/IEC 13818-2 or ISO/IEC 11172-2 video */ + case 0x1b: /* H.264 AVC */ + entry->video_pid = realloc(entry->video_pid, + sizeof(*entry->video_pid) * + (video_len + 1)); + entry->video_pid[video_len] = pid; + video_len++; + break; + case 0x03: /* ISO/IEC 11172-3 Audio */ + case 0x04: /* ISO/IEC 13818-3 Audio */ + case 0x0f: /* ISO/IEC 13818-7 Audio with ADTS (AAC) */ + case 0x11: /* ISO/IEC 14496-3 Audio with the LATM */ + case 0x81: /* user private - in general ATSC Dolby - AC-3 */ + entry->audio_pid = realloc(entry->audio_pid, + sizeof(*entry->audio_pid) * + (audio_len + 1)); + entry->audio_pid[audio_len] = pid; + audio_len++; + break; + case 0x05: /* private sections */ + case 0x06: /* private data */ + /* + * Those can be used by sub-titling, teletext and/or + * DVB AC-3. So, need to seek for the AC-3 descriptors + */ + dvb_desc_find(struct dvb_desc_service, desc, stream, AC_3_descriptor) + has_ac3 = 1; + + dvb_desc_find(struct dvb_desc_service, desc, stream, enhanced_AC_3_descriptor) + has_ac3 = 1; + + if (has_ac3) { + entry->audio_pid = realloc(entry->audio_pid, + sizeof(*entry->audio_pid) * + (audio_len + 1)); + entry->audio_pid[audio_len] = pid; + audio_len++; + } else { + entry->other_el_pid = realloc(entry->other_el_pid, + sizeof(*entry->other_el_pid) * + (other_len + 1)); + entry->other_el_pid[other_len].type = stream->type; + entry->other_el_pid[other_len].pid = pid; + other_len++; + } + break; + default: + entry->other_el_pid = realloc(entry->other_el_pid, + sizeof(*entry->other_el_pid) * + (other_len + 1)); + entry->other_el_pid[other_len].type = stream->type; + entry->other_el_pid[other_len].pid = pid; + other_len++; + break; + } + } + + entry->video_pid_len = video_len; + entry->audio_pid_len = audio_len; + entry->other_el_pid_len = other_len; + + qsort(entry->other_el_pid, entry->other_el_pid_len, + sizeof(*entry->other_el_pid), sort_other_el_pid); +} + +static int get_program_and_store(struct dvb_v5_fe_parms *parms, + struct dvb_file *dvb_file, + struct dvb_v5_descriptors *dvb_scan_handler, + uint16_t service_id, char *channel, + int get_detected, int get_nit) +{ + struct dvb_entry *entry; + int i, j; + + /* Go to the last entry */ + + if (dvb_file->first_entry) { + entry = dvb_file->first_entry; + while (entry && entry->next) + entry = entry->next; + } + + for (i = 0; i < dvb_scan_handler->num_program; i++) { + if (!dvb_scan_handler->program[i].pmt) + continue; + + if (service_id == dvb_scan_handler->program[i].pat_pgm->service_id) + break; + } + + if (service_id != dvb_scan_handler->program[i].pat_pgm->service_id) { + fprintf(stderr, "Service ID %d not found on PMT!\n", + service_id); + return 0; + } + + + /* Create an entry to store the data */ + if (!dvb_file->first_entry) { + dvb_file->first_entry = calloc(sizeof(*entry), 1); + entry = dvb_file->first_entry; + } else { + entry->next = calloc(sizeof(*entry), 1); + entry = entry->next; + } + if (!entry) { + fprintf(stderr, "Not enough memory\n"); + return -1; + } + + /* Initialize data */ + entry->channel = channel; + entry->service_id = service_id; + entry->vchannel = dvb_vchannel(dvb_scan_handler, i); + entry->sat_number = parms->sat_number; + entry->freq_bpf = parms->freq_bpf; + entry->diseqc_wait = parms->diseqc_wait; + if (parms->lnb) + entry->lnb = strdup(parms->lnb->alias); + + /* Get PIDs for each elementary inside the service ID */ + get_pmt_descriptors(entry, dvb_scan_handler->program[i].pmt); + + /* Copy data from parms */ + if (get_detected) { + int rc; + do { + rc = dvb_fe_get_parms(parms); + if (rc == EAGAIN) + usleep(100000); + } while (rc == EAGAIN); + } + for (j = 0; j < parms->n_props; j++) { + entry->props[j].cmd = parms->dvb_prop[j].cmd; + entry->props[j].u.data = parms->dvb_prop[j].u.data; + } + entry->n_props = parms->n_props; + + if (get_nit) + handle_std_specific_parms(entry, dvb_scan_handler); + + return 0; +} + int store_dvb_channel(struct dvb_file **dvb_file, struct dvb_v5_fe_parms *parms, struct dvb_v5_descriptors *dvb_scan_handler, int get_detected, int get_nit) { - struct dvb_entry *entry; - int i, j, has_detected = 1; + int rc; if (!*dvb_file) { *dvb_file = calloc(sizeof(*dvb_file), 1); if (!*dvb_file) { - perror("Allocating memory for dvb_file"); + dvb_perror("Allocating memory for dvb_file"); return -1; } } - /* Go to the last entry */ - entry = (*dvb_file)->first_entry; - while (entry && entry->next) - entry = entry->next; - - for (i = 0; i < dvb_scan_handler->sdt_table.service_table_len; i++) { - struct service_table *service_table = &dvb_scan_handler->sdt_table.service_table[i]; - struct pat_table *pat_table = &dvb_scan_handler->pat_table; - struct pid_table *pid_table = NULL; - - if (!entry) { - (*dvb_file)->first_entry = calloc(sizeof(*entry), 1); - entry = (*dvb_file)->first_entry; - } else { - entry->next = calloc(sizeof(*entry), 1); - entry = entry->next; - } - if (!entry) { - fprintf(stderr, "Not enough memory\n"); - return -1; - } - entry->sat_number = -1; - - if (service_table->service_name) { - entry->channel = calloc(strlen(service_table->service_name) + 1, 1); - strcpy(entry->channel, service_table->service_name); - } else { - asprintf(&entry->channel, "#%d", - service_table->service_id); - } - entry->service_id = service_table->service_id; - - entry->vchannel = dvb_vchannel(dvb_scan_handler, i); - - /*entry->pol = parms->pol;*/ - entry->sat_number = parms->sat_number; - entry->freq_bpf = parms->freq_bpf; - entry->diseqc_wait = parms->diseqc_wait; - if (parms->lnb) - entry->lnb = strdup(parms->lnb->alias); + if (!dvb_scan_handler->sdt) { + dvb_logerr("no SDT table - can't store channels"); + return -1; + } + dvb_sdt_service_foreach(service, dvb_scan_handler->sdt) { + char *channel = NULL; - for (j = 0; j < pat_table->pid_table_len; j++) { - pid_table = &pat_table->pid_table[j]; - if (service_table->service_id == pid_table->service_id) - break; - } - if (j == pat_table->pid_table_len) { - fprintf(stderr, "Service ID %d not found on PMT!\n", - service_table->service_id); - has_detected = 0; - } else has_detected = 1; - - /* - * Video/audio/other pid's can only be filled if the service - * was found. - */ - if (has_detected) { - entry->video_pid = calloc(sizeof(*entry[i].video_pid), - pid_table->video_pid_len); - for (j = 0; j < pid_table->video_pid_len; j++) - entry->video_pid[j] = pid_table->video_pid[j]; - entry->video_pid_len = pid_table->video_pid_len; - - entry->audio_pid = calloc(sizeof(*entry[i].audio_pid), - pid_table->audio_pid_len); - for (j = 0; j < pid_table->audio_pid_len; j++) - 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); + dvb_desc_find(struct dvb_desc_service, desc, service, service_descriptor) { + if (desc->name) { + channel = calloc(strlen(desc->name) + 1, 1); + strcpy(channel, desc->name); + } + dvb_log("Found service %s, provider %s, type %d", + desc->name, desc->provider, desc->service_type); + break; } - /* Copy data from parms */ - if (get_detected) { - int rc; - do { - rc = dvb_fe_get_parms(parms); - if (rc == EAGAIN) - usleep(100000); - } while (rc == EAGAIN); - } - for (j = 0; j < parms->n_props; j++) { - entry->props[j].cmd = parms->dvb_prop[j].cmd; - entry->props[j].u.data = parms->dvb_prop[j].u.data; - } - entry->n_props = parms->n_props; + if (!channel) + asprintf(&channel, "#%d", service->service_id); - if (get_nit) - handle_std_specific_parms(entry, dvb_scan_handler); + rc = get_program_and_store(parms, *dvb_file, dvb_scan_handler, + service->service_id, + channel, get_detected, get_nit); + if (rc < 0) + return rc; } + return 0; } diff --git a/lib/libdvbv5/dvb-scan.c b/lib/libdvbv5/dvb-scan.c index 3d34c3e..99a4596 100644 --- a/lib/libdvbv5/dvb-scan.c +++ b/lib/libdvbv5/dvb-scan.c @@ -310,7 +310,7 @@ struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms, sizeof(*dvb_scan_handler->program)); dvb_pat_program_foreach(program, dvb_scan_handler->pat) { - dvb_scan_handler->program->program = program; + dvb_scan_handler->program[num_pmt].pat_pgm = program; if (!program->service_id) { dvb_log("Program ID %d has service ID 0. discarding", diff --git a/utils/dvb/dvbv5-scan.c b/utils/dvb/dvbv5-scan.c index 1c1adce..dccb907 100644 --- a/utils/dvb/dvbv5-scan.c +++ b/utils/dvb/dvbv5-scan.c @@ -482,19 +482,6 @@ static int run_scan(struct arguments *args, if (!dvb_scan_handler) continue; - for (i = 0; i < dvb_scan_handler->sdt_table.service_table_len; i++) { - struct service_table *service_table = &dvb_scan_handler->sdt_table.service_table[i]; - - entry->vchannel = dvb_vchannel(dvb_scan_handler, i); - printf("Service #%d (%d)", i, - service_table->service_id); - if (service_table->service_name) - printf(" %s", service_table->service_name); - if (entry->vchannel) - printf(" channel %s", entry->vchannel); - printf("\n"); - } - store_dvb_channel(&dvb_file_new, parms, dvb_scan_handler, args->get_detected, args->get_nit);