From: Jaroslav Kysela Date: Tue, 30 Aug 2016 07:56:42 +0000 (+0200) Subject: scanfile: do not keep mux data in memory - load them on demand (saves cca 1.5MB) X-Git-Tag: v4.2.1~332 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=63ea351aa32d2389ae8d49140a2a76e222da0e24;p=thirdparty%2Ftvheadend.git scanfile: do not keep mux data in memory - load them on demand (saves cca 1.5MB) --- diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index bf433e622..8672081d1 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -100,6 +100,7 @@ dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) } } } + scanfile_clean(sfn); return; } diff --git a/src/input/mpegts/scanfile.c b/src/input/mpegts/scanfile.c index 9c5cb8dd5..d02d11841 100644 --- a/src/input/mpegts/scanfile.c +++ b/src/input/mpegts/scanfile.c @@ -53,6 +53,8 @@ static scanfile_region_list_t *scanfile_regions_load; static int64_t scanfile_total_load; static memoryinfo_t scanfile_memoryinfo = { .my_name = "Scan files" }; +static void scanfile_done_muxes( scanfile_network_t *net ); + /* ************************************************************************** * Country codes @@ -323,7 +325,8 @@ scanfile_region_create */ static int scanfile_create_network - ( scanfile_network_t **_net, const char *type, const char *name, + ( scanfile_network_t **_net, const char *type, + const char *path, const char *name, dvb_fe_delivery_system_t delsys ) { scanfile_region_t *reg = NULL; @@ -369,9 +372,12 @@ scanfile_create_network } snprintf(buf2, sizeof(buf2), "%s_%s", type, buf); net = calloc(1, sizeof(scanfile_network_t)); - memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*net) + strlen(buf2) + 1 + strlen(buf) + 1); + memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*net) + strlen(buf2) + 1 + strlen(buf) + 1 + + strlen(path) + 1 + strlen(type) + 1); net->sfn_id = strdup(buf2); net->sfn_name = strdup(buf); + net->sfn_path = strdup(path); + net->sfn_type = strdup(type); net->sfn_satpos = opos; LIST_INSERT_SORTED(®->sfr_networks, net, sfn_link, scanfile_network_cmp); @@ -384,7 +390,8 @@ scanfile_create_network */ static int scanfile_load_one - ( scanfile_network_t **net, const char *type, const char *name, const char *line ) + ( scanfile_network_t **net, const char *type, const char *path, + const char *name, const char *line, int test ) { int r = 1; dvb_mux_conf_t *mux = malloc(sizeof(dvb_mux_conf_t)); @@ -408,12 +415,17 @@ scanfile_load_one if (r) { free(mux); } else { - if (*net == NULL && scanfile_create_network(net, type, name, mux->dmc_fe_delsys)) { + if (*net == NULL && + scanfile_create_network(net, type, path, name, mux->dmc_fe_delsys)) { free(mux); return -1; } - memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*mux)); - LIST_INSERT_HEAD(&(*net)->sfn_muxes, mux, dmc_link); + if (!test) { + memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*mux)); + LIST_INSERT_HEAD(&(*net)->sfn_muxes, mux, dmc_link); + } else { + return -1; + } } return 1; } @@ -450,8 +462,9 @@ str_trim(char *s) static int scanfile_load_dvbv5 - ( scanfile_network_t **net, const char *type, const char *name, - char *line, fb_file *fp ) + ( scanfile_network_t **net, const char *type, + const char *path, const char *name, + char *line, fb_file *fp, int test ) { int res = 1, r = 1, i; char buf[256]; @@ -694,10 +707,15 @@ scanfile_load_dvbv5 dvb_mux_conf_str(mux, buf, sizeof(buf)); tvhtrace(LS_SCANFILE, "mux %s", buf); if (*net == NULL) - if (scanfile_create_network(net, type, name, mux->dmc_fe_delsys)) + if (scanfile_create_network(net, type, path, name, mux->dmc_fe_delsys)) return -1; - memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*mux)); - LIST_INSERT_HEAD(&(*net)->sfn_muxes, mux, dmc_link); + if (!test) { + memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*mux)); + LIST_INSERT_HEAD(&(*net)->sfn_muxes, mux, dmc_link); + } else { + free(mux); + res = -2; + } } return res; @@ -706,21 +724,19 @@ scanfile_load_dvbv5 /* * Process a file */ -static void +static scanfile_network_t * scanfile_load_file - ( const char *type, fb_dir *dir, const char *name ) + ( scanfile_network_t *net, const char *type, const char *path, + fb_file *fp, const char *name, int test ) { - fb_file *fp; - scanfile_network_t *net = NULL; char *str, buf[256]; int load = 0; tvhtrace(LS_SCANFILE, "load file %s (processed bytes %"PRId64")", name, scanfile_total_load); - if (scanfile_total_load > SCANFILE_LIMIT) return; - fp = fb_open2(dir, name, 1, 0); - if (!fp) return; + if (!fp) return NULL; + scanfile_total_load += fb_size(fp); if (scanfile_total_load > SCANFILE_LIMIT) goto end; @@ -746,10 +762,10 @@ scanfile_load_file case 'C': case 'T': case 'S': - load = scanfile_load_one(&net, type, name, buf); + load = scanfile_load_one(&net, type, path, name, buf, test); break; case '[': - load = scanfile_load_dvbv5(&net, type, name, buf, fp); + load = scanfile_load_dvbv5(&net, type, path, name, buf, fp, test); break; default: break; @@ -757,6 +773,7 @@ scanfile_load_file } end: fb_close(fp); + return net; } /* @@ -766,11 +783,14 @@ end: */ static void scanfile_load_dir - ( const char *path, const char *type, int lvl ) + ( const char *path, const char *type, int lvl, int test ) { - char p[256]; + char p[PATH_MAX]; fb_dir *dir; fb_dirent *de; + fb_file *fp; + scanfile_network_t *net; + tvhtrace(LS_SCANFILE, "load dir %s", path); if (lvl >= 3) return; @@ -781,9 +801,13 @@ scanfile_load_dir if (*de->name == '.') continue; if (de->type == FB_DIR) { snprintf(p, sizeof(p), "%s/%s", path, de->name); - scanfile_load_dir(p, de->name, lvl+1); + scanfile_load_dir(p, de->name, lvl+1, test); } else if (type) { - scanfile_load_file(type, dir, de->name); + snprintf(p, sizeof(p), "%s/%s", path, de->name); + if (scanfile_total_load > SCANFILE_LIMIT) continue; + fp = fb_open2(dir, de->name, 1, 0); + net = scanfile_load_file(NULL, type, p, fp, de->name, test); + scanfile_done_muxes(net); } } @@ -812,6 +836,22 @@ scanfile_stats(const char *what, scanfile_region_list_t *list) return 0; } +/* + * Destroy the muxes + */ +static void +scanfile_done_muxes( scanfile_network_t *net ) +{ + dvb_mux_conf_t *mux; + if (!net) return; + while ((mux = LIST_FIRST(&net->sfn_muxes)) != NULL) { + memoryinfo_free(&scanfile_memoryinfo, sizeof(*mux)); + LIST_REMOVE(mux, dmc_link); + free(mux); + } +} + + /* * Destroy the region */ @@ -820,22 +860,21 @@ scanfile_done_region( scanfile_region_list_t *list ) { scanfile_region_t *reg; scanfile_network_t *net; - dvb_mux_conf_t *mux; while ((reg = LIST_FIRST(&list->srl_regions)) != NULL) { LIST_REMOVE(reg, sfr_link); while ((net = LIST_FIRST(®->sfr_networks)) != NULL) { LIST_REMOVE(net, sfn_link); - while ((mux = LIST_FIRST(&net->sfn_muxes)) != NULL) { - memoryinfo_free(&scanfile_memoryinfo, sizeof(*mux)); - LIST_REMOVE(mux, dmc_link); - free(mux); - } + scanfile_done_muxes(net); memoryinfo_free(&scanfile_memoryinfo, sizeof(*net) + (net->sfn_id ? strlen(net->sfn_id) + 1 : 0) + - (net->sfn_name ? strlen(net->sfn_name) + 1 : 0)); + (net->sfn_name ? strlen(net->sfn_name) + 1 : 0) + + (net->sfn_path ? strlen(net->sfn_path) + 1 : 0) + + (net->sfn_type ? strlen(net->sfn_type) + 1 : 0)); free((void *)net->sfn_id); free((void *)net->sfn_name); + free((void *)net->sfn_path); + free((void *)net->sfn_type); free(net); } memoryinfo_free(&scanfile_memoryinfo, sizeof(*reg) + @@ -879,7 +918,7 @@ scanfile_init ( const char *muxconf_path, int lock ) scanfile_regions_load[i].srl_alt_type = scanfile_region_types[i][1]; } - scanfile_load_dir(path, NULL, 0); + scanfile_load_dir(path, NULL, 0, 1); for (i = 0; i < REGIONS; i++) { snprintf(buf, sizeof(buf)-1, "%s", scanfile_regions_load[i].srl_type); @@ -949,7 +988,7 @@ scanfile_find_region_list ( const char *type ) } /* - * Find scanfile + * Find scanfile and load muxes */ scanfile_network_t * scanfile_find ( const char *id ) @@ -958,6 +997,7 @@ scanfile_find ( const char *id ) scanfile_region_t *r = NULL; scanfile_network_t *n = NULL; scanfile_region_list_t *l; + fb_file *fp; tmp = strdup(id); /* Type */ @@ -983,9 +1023,25 @@ scanfile_find ( const char *id ) break; free(tmp); + + if (n) { + fp = fb_open(n->sfn_path, 1, 0); + tmp = strrchr(n->sfn_path, '/'); + scanfile_load_file(n, n->sfn_type, n->sfn_path, fp, tmp ?: n->sfn_path, 0); + } + return n; fail: free(tmp); return NULL; } + +/* + * Remove muxes from scanfile + */ +void +scanfile_clean( scanfile_network_t *sfn ) +{ + scanfile_done_muxes(sfn); +} diff --git a/src/input/mpegts/scanfile.h b/src/input/mpegts/scanfile.h index 817d2e15a..ffdcaaa1e 100644 --- a/src/input/mpegts/scanfile.h +++ b/src/input/mpegts/scanfile.h @@ -22,6 +22,8 @@ typedef struct scanfile_network { const char *sfn_id; const char *sfn_name; + const char *sfn_path; + const char *sfn_type; int sfn_satpos; LIST_ENTRY(scanfile_network) sfn_link; LIST_HEAD(,dvb_mux_conf) sfn_muxes; @@ -45,5 +47,6 @@ void scanfile_done ( void ); scanfile_region_list_t *scanfile_find_region_list ( const char *type ); scanfile_network_t *scanfile_find ( const char *id ); +void scanfile_clean( scanfile_network_t *sfn ); #endif /* __DVB_SCANFILES_H__ */