From: Jaroslav Kysela Date: Fri, 6 Nov 2015 16:04:04 +0000 (+0100) Subject: psip: many fixes for recent changes, leaks, sorting, refcounting X-Git-Tag: v4.2.1~1641 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=117d1dbee5002db1d5f45a2fa150b6346533237d;p=thirdparty%2Ftvheadend.git psip: many fixes for recent changes, leaks, sorting, refcounting --- diff --git a/src/epggrab/module/psip.c b/src/epggrab/module/psip.c index c9159b32b..e5833a75f 100644 --- a/src/epggrab/module/psip.c +++ b/src/epggrab/module/psip.c @@ -134,7 +134,6 @@ psip_update_table(psip_status_t *ps, uint16_t pid, int type) } pt = calloc(1, sizeof(*pt)); TAILQ_INSERT_TAIL(&ps->ps_tables, pt, pt_link); - ps->ps_refcount++; pt->pt_pid = pid; assign: pt->pt_type = type; @@ -162,8 +161,11 @@ psip_activate_table(psip_status_t *ps, psip_table_t *pt) } else { abort(); } + ps->ps_refcount++; + mt->mt_destroy = psip_status_destroy; pt->pt_start = dispatch_clock; - tvhtrace("psip", "table activated - pid 0x%04X", mt->mt_pid); + pt->pt_table = mt; + tvhtrace("psip", "table activated - pid 0x%04X type 0x%04X", mt->mt_pid, pt->pt_type); return mt; } @@ -172,7 +174,8 @@ psip_activate_table(psip_status_t *ps, psip_table_t *pt) static int _reschedule_cmp(const void *_a, const void *_b) { - const psip_table_t *a = _a, *b = _b; + const psip_table_t *a = *(psip_table_t **)_a; + const psip_table_t *b = *(psip_table_t **)_b; int res = 0, va, vb; if (a->pt_table && b->pt_table) res = safecmp(a->pt_start, b->pt_start); @@ -198,8 +201,14 @@ psip_reschedule_tables(psip_status_t *ps) ps->ps_armed = 0; total = 0; - TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) + TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) { total++; + if (pt->pt_start + 10 < dispatch_clock && pt->pt_table) { + tvhtrace("psip", "table late: pid = 0x%04X, type = 0x%04X\n", pt->pt_pid, pt->pt_type); + mpegts_table_destroy(pt->pt_table); + pt->pt_table = NULL; + } + } tables = malloc(total * sizeof(psip_table_t *)); tvhtrace("psip", "reschedule tables, total %d", total); @@ -210,11 +219,16 @@ psip_reschedule_tables(psip_status_t *ps) qsort(tables, total, sizeof(psip_table_t *), _reschedule_cmp); + for (i = 0; i < total; i++) { + pt = tables[i]; + tvhtrace("psip", "sorted: pid = 0x%04X, type = 0x%04X\n", pt->pt_pid, pt->pt_type); + } + for (i = 0; i < total && i < PSIP_EPG_TABLE_LIMIT; i++) { pt = tables[i]; if (pt->pt_table) continue; - pt->pt_table = psip_activate_table(ps, pt); + psip_activate_table(ps, pt); } free(tables); @@ -357,7 +371,7 @@ _psip_eit_callback_channel " stop=%"PRItime_t", ebc=%p", ch ? channel_get_name(ch) : "(null)", eventid, start, stop, ebc); - if (!ebc) continue; + if (!ebc) goto next; save |= save2; pd = psip_find_desc(ps, eventid); @@ -372,6 +386,7 @@ _psip_eit_callback_channel ee = epg_broadcast_get_episode(ebc, 1, &save2); save |= epg_episode_set_title2(ee, title, mod); +next: lang_str_destroy(title); } return save; @@ -448,6 +463,7 @@ _psip_eit_callback /* Begin */ r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7, &st, §, &last, &ver); + if (r == 0) goto complete; if (r != 1) return r; tvhtrace("psip", "0x%04x: EIT tsid %04X (%s), ver %d", mt->mt_pid, tsid, svc->s_dvb_svcname, ver); @@ -479,6 +495,7 @@ _psip_eit_callback done: r = dvb_table_end((mpegts_psi_table_t *)mt, st, sect); +complete: if (!r) psip_complete_table(ps, mt); @@ -521,6 +538,7 @@ _psip_ett_callback /* Begin */ r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7, &st, §, &last, &ver); + if (r == 0) goto complete; if (r != 1) return r; sourceid = ptr[6] << 8 | ptr[7]; @@ -563,6 +581,7 @@ _psip_ett_callback done: r = dvb_table_end((mpegts_psi_table_t *)mt, st, sect); +complete: if (!r) psip_complete_table(ps, mt); return r; diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 3b34de381..5ff9a6841 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -1680,6 +1680,7 @@ atsc_vct_callback LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) if (mm->mm_tsid == tsid && (mm == mm_orig || mpegts_mux_alive(mm))) { /* Find the service */ + save = 0; if (!(s = mpegts_service_find(mm, sid, 0, 1, &save))) continue; diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index f625dbd08..f40f82665 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -154,7 +154,8 @@ mpegts_table_destroy ( mpegts_table_t *mt ) mpegts_mux_t *mm = mt->mt_mux; pthread_mutex_lock(&mm->mm_tables_lock); - mpegts_table_destroy_(mt); + if (!mt->mt_destroyed) + mpegts_table_destroy_(mt); pthread_mutex_unlock(&mm->mm_tables_lock); }