From: Erik Nilsson Date: Tue, 27 Aug 2019 17:44:45 +0000 (+0200) Subject: add FHD quality support X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a98ebc0556ba6724673772d7e41383bcf0ec913;p=thirdparty%2Ftvheadend.git add FHD quality support --- diff --git a/src/channels.c b/src/channels.c index aa811d76a..562065432 100644 --- a/src/channels.c +++ b/src/channels.c @@ -638,6 +638,9 @@ channel_make_fuzzy_name(const char *name) /* Strip trailing 'UHD'. */ if (*ch == 'U' && *(ch+1) == 'H' && *(ch+2) == 'D' && *(ch+3) == 0) break; + /* Strip trailing 'FHD'. */ + if (*ch == 'F' && *(ch+1) == 'H' && *(ch+2) == 'D' && *(ch+3) == 0) + break; if (!isspace(*ch)) { *ch_fuzzy++ = tolower(*ch); @@ -1996,6 +1999,7 @@ channel_has_correct_service_filter(const channel_t *ch, int svf) service = (const service_t*)ilm->ilm_in1; if ((svf == PROFILE_SVF_SD && service_is_sdtv(service)) || (svf == PROFILE_SVF_HD && service_is_hdtv(service)) || + (svf == PROFILE_SVF_FHD && service_is_fhdtv(service)) || (svf == PROFILE_SVF_UHD && service_is_uhdtv(service))) { return 1; } diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 2a474ba1d..ee8bb8130 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -1875,7 +1875,7 @@ dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_ent if (!old_channel) return 1; /* Always prefer a recording that has the correct service profile - * (UHD, HD, SD). Someone mentioned (#1846) that some channels can + * (UHD, FHD, HD, SD). Someone mentioned (#1846) that some channels can * show a recording earlier in the week in SD then later in the week * in HD so this would prefer the later HD recording if the user so * desired. @@ -1890,10 +1890,29 @@ dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_ent return 0; if (!old_has_svf && new_has_svf) return 1; - /* Also try "downgrading", where user asks for UHD, which we don't + /* Also try "downgrading", where user asks for FHD, which we don't * have, but we could give them HD. */ + if (svf == PROFILE_SVF_FHD && !old_has_svf) { + old_has_svf = channel_has_correct_service_filter(old_channel, PROFILE_SVF_HD); + new_has_svf = channel_has_correct_service_filter(new_channel, PROFILE_SVF_HD); + + if (old_has_svf && !new_has_svf) + return 0; + if (!old_has_svf && new_has_svf) + return 1; + } + + /* Also try "downgrading", where user asks for UHD, which we don't + * have, but we could give them FHD, then HD. + */ if (svf == PROFILE_SVF_UHD && !old_has_svf) { + old_has_svf = channel_has_correct_service_filter(old_channel, PROFILE_SVF_FHD); + new_has_svf = channel_has_correct_service_filter(new_channel, PROFILE_SVF_FHD); + + if (!old_has_svf && new_has_svf) + return 1; + old_has_svf = channel_has_correct_service_filter(old_channel, PROFILE_SVF_HD); new_has_svf = channel_has_correct_service_filter(new_channel, PROFILE_SVF_HD); diff --git a/src/epggrab/module/xmltv.c b/src/epggrab/module/xmltv.c index c87d041a0..34ab05bdb 100644 --- a/src/epggrab/module/xmltv.c +++ b/src/epggrab/module/xmltv.c @@ -270,8 +270,10 @@ xmltv_parse_vid_quality if ((str = htsmsg_xml_get_cdata_str(m, "quality"))) { if (strstr(str, "HD")) { hd = 1; - } else if (strstr(str, "UHD")) { + } else if (strstr(str, "FHD")) { hd = 2; + } else if (strstr(str, "UHD")) { + hd = 3; } else if (strstr(str, "480")) { lines = 480; aspect = 150; @@ -284,15 +286,15 @@ xmltv_parse_vid_quality aspect = 178; } else if (strstr(str, "1080")) { lines = 1080; - hd = 1; + hd = 2; aspect = 178; } else if (strstr(str, "1716")) { lines = 1716; - hd = 2; + hd = 3; aspect = 239; } else if (strstr(str, "2160")) { lines = 2160; - hd = 2; + hd = 3; aspect = 178; } } diff --git a/src/profile.c b/src/profile.c index b287610c1..76aa1a8c1 100644 --- a/src/profile.c +++ b/src/profile.c @@ -272,6 +272,7 @@ profile_class_svfilter_list ( void *o, const char *lang ) { N_("None"), PROFILE_SVF_NONE }, { N_("SD: standard definition"), PROFILE_SVF_SD }, { N_("HD: high definition"), PROFILE_SVF_HD }, + { N_("FHD: full high definition"), PROFILE_SVF_FHD }, { N_("UHD: ultra high definition"), PROFILE_SVF_UHD }, }; return strtab2htsmsg(tab, 1, lang); diff --git a/src/profile.h b/src/profile.h index fa7ffbe91..efccb0352 100644 --- a/src/profile.h +++ b/src/profile.h @@ -41,6 +41,7 @@ typedef enum { PROFILE_SVF_NONE = 0, PROFILE_SVF_SD, PROFILE_SVF_HD, + PROFILE_SVF_FHD, PROFILE_SVF_UHD } profile_svfilter_t; diff --git a/src/service.c b/src/service.c index cdcf5b5ea..79b7d93f1 100644 --- a/src/service.c +++ b/src/service.c @@ -148,6 +148,7 @@ service_type_auto_list ( void *o, const char *lang ) { N_("Radio"), ST_RADIO }, { N_("SD TV"), ST_SDTV }, { N_("HD TV"), ST_HDTV }, + { N_("FHD TV"), ST_FHDTV }, { N_("UHD TV"), ST_UHDTV } }; return strtab2htsmsg(tab, 1, lang); @@ -406,6 +407,7 @@ service_find_instance pro->pro_svfilter == PROFILE_SVF_NONE || (pro->pro_svfilter == PROFILE_SVF_SD && service_is_sdtv(s)) || (pro->pro_svfilter == PROFILE_SVF_HD && service_is_hdtv(s)) || + (pro->pro_svfilter == PROFILE_SVF_FHD && service_is_fhdtv(s)) || (pro->pro_svfilter == PROFILE_SVF_UHD && service_is_uhdtv(s))) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) @@ -416,10 +418,9 @@ service_find_instance /* find a valid instance, no error and "user" idle */ TAILQ_FOREACH(si, sil, si_link) if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) break; - /* UHD->HD fallback and SD->HD fallback */ + /* SD->HD->FHD->UHD fallback */ if (si == NULL && pro && - (pro->pro_svfilter == PROFILE_SVF_UHD || - pro->pro_svfilter == PROFILE_SVF_SD)) { + pro->pro_svfilter == PROFILE_SVF_SD) { LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { s = (service_t *)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_hdtv(s)) { @@ -428,6 +429,53 @@ service_find_instance r = r1; } } + LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t *)ilm->ilm_in1; + if (s->s_is_enabled(s, flags) && service_is_fhdtv(s)) { + r1 = s->s_enlist(s, ti, sil, flags, weight); + if (r1 && r == 0) + r = r1; + } + } + LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t *)ilm->ilm_in1; + if (s->s_is_enabled(s, flags) && service_is_uhdtv(s)) { + r1 = s->s_enlist(s, ti, sil, flags, weight); + if (r1 && r == 0) + r = r1; + } + } + /* find a valid instance, no error and "user" idle */ + TAILQ_FOREACH(si, sil, si_link) + if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) break; + } + /* UHD->FHD->HD->SD fallback */ + if (si == NULL && pro && + pro->pro_svfilter == PROFILE_SVF_UHD) { + LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t *)ilm->ilm_in1; + if (s->s_is_enabled(s, flags) && service_is_fhdtv(s)) { + r1 = s->s_enlist(s, ti, sil, flags, weight); + if (r1 && r == 0) + r = r1; + } + } + LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t *)ilm->ilm_in1; + if (s->s_is_enabled(s, flags) && service_is_hdtv(s)) { + r1 = s->s_enlist(s, ti, sil, flags, weight); + if (r1 && r == 0) + r = r1; + } + } + LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t *)ilm->ilm_in1; + if (s->s_is_enabled(s, flags) && service_is_sdtv(s)) { + r1 = s->s_enlist(s, ti, sil, flags, weight); + if (r1 && r == 0) + r = r1; + } + } /* find a valid instance, no error and "user" idle */ TAILQ_FOREACH(si, sil, si_link) if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) break; @@ -840,7 +888,26 @@ service_is_hdtv(const service_t *t) elementary_stream_t *st; TAILQ_FOREACH(st, &t->s_components.set_all, es_link) if (SCT_ISVIDEO(st->es_type) && - st->es_height >= 720 && st->es_height <= 1080) + st->es_height >= 720 && st->es_height < 1080) + return 1; + } + return 0; +} + +int +service_is_fhdtv(const service_t *t) +{ + char s_type; + if(t->s_type_user == ST_UNSET) + s_type = t->s_servicetype; + else + s_type = t->s_type_user; + if (s_type == ST_FHDTV) + return 1; + else if (s_type == ST_NONE) { + elementary_stream_t *st; + TAILQ_FOREACH(st, &t->s_components.set_all, es_link) + if (SCT_ISVIDEO(st->es_type) && st->es_height == 1080) return 1; } return 0; @@ -915,13 +982,14 @@ const char * service_servicetype_txt ( service_t *s ) { static const char *types[] = { - "HDTV", "SDTV", "Radio", "UHDTV", "Other" + "HDTV", "SDTV", "Radio", "FHDTV", "UHDTV", "Other" }; if (service_is_hdtv(s)) return types[0]; if (service_is_sdtv(s)) return types[1]; if (service_is_radio(s)) return types[2]; - if (service_is_uhdtv(s)) return types[3]; - return types[4]; + if (service_is_fhdtv(s)) return types[3]; + if (service_is_uhdtv(s)) return types[4]; + return types[5]; } diff --git a/src/service.h b/src/service.h index 8b940bed2..d4833848f 100644 --- a/src/service.h +++ b/src/service.h @@ -183,6 +183,7 @@ typedef struct service { ST_OTHER, ST_SDTV, ST_HDTV, + ST_FHDTV, ST_UHDTV, ST_RADIO } s_servicetype; @@ -433,10 +434,11 @@ static inline uint16_t service_id16(void *t) int service_is_sdtv(const service_t *t); int service_is_uhdtv(const service_t *t); +int service_is_fhdtv(const service_t *t); int service_is_hdtv(const service_t *t); int service_is_radio(const service_t *t); static inline int service_is_tv( const service_t *s) - { return service_is_hdtv(s) || service_is_sdtv(s) || service_is_uhdtv(s); } + { return service_is_hdtv(s) || service_is_sdtv(s) || service_is_uhdtv(s) || service_is_fhdtv(s); } static inline int service_is_other(const service_t *t) { return !service_is_tv(t) && !service_is_radio(t); } diff --git a/src/service_mapper.c b/src/service_mapper.c index 52c735f15..ee37a54fc 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -230,9 +230,9 @@ service_mapper_process // 4HD\0 len=3, HD at pos 1 (3-2) // 4\0 len=1 if (name[len-2] == 'H' && name[len-1] == 'D') { - /* Ends in HD but does it end in UHD? */ + /* Ends in HD but does it end in UHD/FHD? */ tidy_name = tvh_strdupa(name); - if (len > 3 && name[len-3] == 'U') + if (len > 3 && (name[len-3] == 'U' || name[len-3] == 'F')) tidy_name[len-3] = 0; else tidy_name[len-2] = 0; @@ -300,6 +300,9 @@ service_mapper_process if (service_is_uhdtv(s)) { channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn); channel_tag_map(channel_tag_find_by_name("UHDTV", 1), chn, chn); + } else if (service_is_fhdtv(s)) { + channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn); + channel_tag_map(channel_tag_find_by_name("FHDTV", 1), chn, chn); } else if (service_is_hdtv(s)) { channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn); channel_tag_map(channel_tag_find_by_name("HDTV", 1), chn, chn); diff --git a/src/webui/static/app/epg.js b/src/webui/static/app/epg.js index 06dc71be9..f80624e9c 100644 --- a/src/webui/static/app/epg.js +++ b/src/webui/static/app/epg.js @@ -282,8 +282,10 @@ tvheadend.epgDetails = function(grid, index) { content += '
' + _('Content Type') + ':' + genre.join(', ') + '
'; } var tags = []; - if (event.hd > 1) + if (event.hd > 2) tags.push(_('UHDTV')); + else if (event.hd > 1) + tags.push(_('FHDTV')); else if (event.hd > 0) tags.push(_('HDTV')); if ('new' in event && event.new)