diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index ef75e3ab..c3c6136f 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -503,7 +503,6 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, char extdesc[5000]; char extitem[5000]; char exttext[5000]; - epg_content_type_t *ect; event_t *e; @@ -573,7 +572,6 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, } int changed = 0; - ect = NULL; *title = 0; *desc = 0; while(dllen > 0) { @@ -598,8 +596,7 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, case DVB_DESC_CONTENT: if(dlen >= 2) { /* We only support one content type per event atm. */ - ect = epg_content_type_find_by_dvbcode(*ptr); - changed |= epg_event_set_content_type(e, ect); + changed |= epg_event_set_content_type(e, (*ptr) >> 4); } break; case DVB_DESC_EXT_EVENT: diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 5d08abc2..5b7768fa 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -178,7 +178,7 @@ typedef struct dvr_autorec_entry { char *dae_title; regex_t dae_title_preg; - epg_content_group_t *dae_ecg; + uint8_t dae_content_type; int dae_approx_time; /* Minutes from midnight */ @@ -267,7 +267,7 @@ void dvr_query_sort(dvr_query_result_t *dqr); * */ void dvr_autorec_add(const char *title, const char *channel, - const char *tag, const char *contentgrp, + const char *tag, uint8_t content_type, const char *creator, const char *comment); void dvr_autorec_check_event(event_t *e); diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 73929cf1..eaac0daa 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -71,7 +71,7 @@ autorec_cmp(dvr_autorec_entry_t *dae, event_t *e) if(dae->dae_channel == NULL && dae->dae_channel_tag == NULL && - dae->dae_ecg == NULL && + dae->dae_content_type == 0 && dae->dae_title == NULL) return 0; // Avoid super wildcard match @@ -88,11 +88,9 @@ autorec_cmp(dvr_autorec_entry_t *dae, event_t *e) } - if(dae->dae_ecg != NULL) { - if(e->e_content_type == NULL || - dae->dae_ecg != e->e_content_type->ect_group) - return 0; - } + if(dae->dae_content_type != 0 && + dae->dae_content_type != e->e_content_type) + return 0; if(dae->dae_title != NULL) { if(e->e_title == NULL || @@ -240,8 +238,7 @@ autorec_record_build(dvr_autorec_entry_t *dae) if(dae->dae_channel_tag != NULL) htsmsg_add_str(e, "tag", dae->dae_channel_tag->ct_name); - if(dae->dae_ecg != NULL) - htsmsg_add_str(e, "contentgrp",dae->dae_ecg->ecg_name); + htsmsg_add_u32(e, "contenttype",dae->dae_content_type); htsmsg_add_str(e, "title", dae->dae_title ?: ""); @@ -348,8 +345,7 @@ autorec_record_update(void *opaque, const char *id, htsmsg_t *values, } } - if((s = htsmsg_get_str(values, "contentgrp")) != NULL) - dae->dae_ecg = epg_content_group_find_by_name(s); + dae->dae_content_type = htsmsg_get_u32_or_default(values, "contenttype", 0); if((s = htsmsg_get_str(values, "approx_time")) != NULL) { if(strchr(s, ':') != NULL) { @@ -422,7 +418,7 @@ dvr_autorec_init(void) */ void dvr_autorec_add(const char *title, const char *channel, - const char *tag, const char *cgrp, + const char *tag, uint8_t content_type, const char *creator, const char *comment) { dvr_autorec_entry_t *dae; @@ -452,8 +448,8 @@ dvr_autorec_add(const char *title, const char *channel, dae->dae_channel_tag = ct; } - dae->dae_ecg = cgrp ? epg_content_group_find_by_name(cgrp) : NULL; dae->dae_enabled = 1; + dae->dae_content_type = content_type; m = autorec_record_build(dae); hts_settings_save(m, "%s/%s", "autorec", dae->dae_id); diff --git a/src/dvr/mkmux.c b/src/dvr/mkmux.c index 796e6872..ebf00ef9 100644 --- a/src/dvr/mkmux.c +++ b/src/dvr/mkmux.c @@ -420,6 +420,8 @@ mk_build_metadata(const dvr_entry_t *de) { htsbuf_queue_t *q = htsbuf_queue_alloc(0); + addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", 0, NULL)); + if(de->de_channel != NULL) addtag(q, build_tag_string("TVCHANNEL", de->de_channel->ch_name, 0, NULL)); @@ -427,8 +429,8 @@ mk_build_metadata(const dvr_entry_t *de) addtag(q, build_tag_string("SYNOPSIS", de->de_episode.ee_onscreen, 0, NULL)); - if(de->de_title != NULL) - addtag(q, build_tag_string("SUMMARY", de->de_title, 0, NULL)); + if(de->de_desc != NULL) + addtag(q, build_tag_string("SUMMARY", de->de_desc, 0, NULL)); if(de->de_episode.ee_season) addtag(q, build_tag_int("PART_NUMBER", de->de_episode.ee_season, diff --git a/src/epg.c b/src/epg.c index 38f135ec..6a8778c2 100644 --- a/src/epg.c +++ b/src/epg.c @@ -35,8 +35,6 @@ #define EPG_GLOBAL_HASH_MASK (EPG_GLOBAL_HASH_WIDTH - 1) static struct event_list epg_hash[EPG_GLOBAL_HASH_WIDTH]; -epg_content_group_t *epg_content_groups[16]; - static void epg_expire_event_from_channel(void *opauqe); static void epg_ch_check_current_event(void *aux); @@ -227,17 +225,12 @@ epg_event_set_ext_text(event_t *e, int ext_dn, const char *text) * */ int -epg_event_set_content_type(event_t *e, epg_content_type_t *ect) +epg_event_set_content_type(event_t *e, uint8_t type) { - if(e->e_content_type == ect) + if(e->e_content_type == type) return 0; - if(e->e_content_type != NULL) - LIST_REMOVE(e, e_content_type_link); - - e->e_content_type = ect; - if(ect != NULL) - LIST_INSERT_HEAD(&ect->ect_events, e, e_content_type_link); + e->e_content_type = type; return 1; } @@ -269,9 +262,6 @@ epg_event_set_episode(event_t *e, epg_episode_t *ee) static void epg_event_destroy(event_t *e) { - if(e->e_content_type != NULL) - LIST_REMOVE(e, e_content_type_link); - free(e->e_title); free(e->e_desc); free(e->e_episode.ee_onscreen); @@ -493,77 +483,47 @@ epg_unlink_from_channel(channel_t *ch) /** + * EPG content group * + * Based on the content types defined in EN 300 468 */ static const char *groupnames[16] = { - [0] = "Unclassified", [1] = "Movie / Drama", [2] = "News / Current affairs", [3] = "Show / Games", [4] = "Sports", - [5] = "Children's/Youth", + [5] = "Children's / Youth", [6] = "Music", - [7] = "Art/Culture", - [8] = "Social/Political issues/Economics", - [9] = "Education/Science/Factual topics", + [7] = "Art / Culture", + [8] = "Social / Political issues / Economics", + [9] = "Education / Science / Factual topics", [10] = "Leisure hobbies", [11] = "Special characteristics", }; + /** * */ const char * -epg_content_group_get_name(unsigned int id) +epg_content_group_get_name(uint8_t id) { return id < 16 ? groupnames[id] : NULL; } -/** - * Find a content type - */ -epg_content_type_t * -epg_content_type_find_by_dvbcode(uint8_t dvbcode) -{ - epg_content_group_t *ecg; - epg_content_type_t *ect; - int group = dvbcode >> 4; - int type = dvbcode & 0xf; - char buf[20]; - - ecg = epg_content_groups[group]; - if(ecg == NULL) { - ecg = epg_content_groups[group] = calloc(1, sizeof(epg_content_group_t)); - ecg->ecg_name = groupnames[group]; - } - - ect = ecg->ecg_types[type]; - if(ect == NULL) { - ect = ecg->ecg_types[type] = calloc(1, sizeof(epg_content_type_t)); - ect->ect_group = ecg; - snprintf(buf, sizeof(buf), "type%d", type); - ect->ect_name = strdup(buf); - ect->ect_dvbcode = dvbcode; - } - - return ect; -} - /** * */ -epg_content_group_t * +uint8_t epg_content_group_find_by_name(const char *name) { - epg_content_group_t *ecg; int i; for(i = 0; i < 16; i++) { - ecg = epg_content_groups[i]; - if(ecg != NULL && ecg->ecg_name && !strcmp(name, ecg->ecg_name)) - return ecg; + if(groupnames[i] != NULL && !strcmp(name, groupnames[i])) + return i; } - return NULL; + return 0; } @@ -573,10 +533,6 @@ epg_content_group_find_by_name(const char *name) void epg_init(void) { - int i; - - for(i = 0x0; i < 0x100; i+=16) - epg_content_type_find_by_dvbcode(i); } @@ -611,19 +567,18 @@ eqr_add(epg_query_result_t *eqr, event_t *e, regex_t *preg, time_t now) */ static void epg_query_add_channel(epg_query_result_t *eqr, channel_t *ch, - epg_content_group_t *ecg, regex_t *preg, time_t now) + uint8_t content_type, regex_t *preg, time_t now) { event_t *e; - if(ecg == NULL) { + if(content_type == 0) { RB_FOREACH(e, &ch->ch_epg_events, e_channel_link) eqr_add(eqr, e, preg, now); - return; + } else { + RB_FOREACH(e, &ch->ch_epg_events, e_channel_link) + if(content_type == e->e_content_type) + eqr_add(eqr, e, preg, now); } - - RB_FOREACH(e, &ch->ch_epg_events, e_channel_link) - if(e->e_content_type != NULL && ecg == e->e_content_type->ect_group) - eqr_add(eqr, e, preg, now); } /** @@ -631,7 +586,7 @@ epg_query_add_channel(epg_query_result_t *eqr, channel_t *ch, */ void epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct, - epg_content_group_t *ecg, const char *title) + uint8_t content_type, const char *title) { channel_tag_mapping_t *ctm; time_t now; @@ -650,19 +605,19 @@ epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct, } if(ch != NULL && ct == NULL) { - epg_query_add_channel(eqr, ch, ecg, preg, now); + epg_query_add_channel(eqr, ch, content_type, preg, now); return; } if(ct != NULL) { LIST_FOREACH(ctm, &ct->ct_ctms, ctm_tag_link) if(ch == NULL || ctm->ctm_channel == ch) - epg_query_add_channel(eqr, ctm->ctm_channel, ecg, preg, now); + epg_query_add_channel(eqr, ctm->ctm_channel, content_type, preg, now); return; } RB_FOREACH(ch, &channel_name_tree, ch_name_link) - epg_query_add_channel(eqr, ch, ecg, preg, now); + epg_query_add_channel(eqr, ch, content_type, preg, now); } /** @@ -674,9 +629,9 @@ epg_query(epg_query_result_t *eqr, const char *channel, const char *tag, { channel_t *ch = channel ? channel_find_by_name(channel, 0, 0) : NULL; channel_tag_t *ct = tag ? channel_tag_find_by_name(tag, 0) : NULL; - epg_content_group_t *ecg = contentgroup ? - epg_content_group_find_by_name(contentgroup) : NULL; - epg_query0(eqr, ch, ct, ecg, title); + uint8_t content_type = contentgroup ? + epg_content_group_find_by_name(contentgroup) : 0; + epg_query0(eqr, ch, ct, content_type, title); } /** diff --git a/src/epg.h b/src/epg.h index d07cf1fb..017d7097 100644 --- a/src/epg.h +++ b/src/epg.h @@ -22,24 +22,6 @@ #include "channels.h" -/** - * EPG content group - * - * Based on the content types defined in EN 300 468 - */ - - -typedef struct epg_content_group { - const char *ecg_name; - struct epg_content_type *ecg_types[16]; -} epg_content_group_t; - -typedef struct epg_content_type { - const char *ect_name; - struct event_list ect_events; - epg_content_group_t *ect_group; - uint8_t ect_dvbcode; -} epg_content_type_t; typedef struct epg_episode { @@ -63,8 +45,7 @@ typedef struct event { int e_refcount; uint32_t e_id; - LIST_ENTRY(event) e_content_type_link; - epg_content_type_t *e_content_type; + uint8_t e_content_type; time_t e_start; /* UTC time */ time_t e_stop; /* UTC time */ @@ -113,7 +94,7 @@ int epg_event_set_ext_item(event_t *e, int ext_dn, const char *item) int epg_event_set_ext_text(event_t *e, int ext_dn, const char *text) __attribute__ ((warn_unused_result)); -int epg_event_set_content_type(event_t *e, epg_content_type_t *ect) +int epg_event_set_content_type(event_t *e, uint8_t type) __attribute__ ((warn_unused_result)); int epg_event_set_episode(event_t *e, epg_episode_t *ee) @@ -134,11 +115,9 @@ void epg_unlink_from_channel(channel_t *ch); /** * */ -epg_content_type_t *epg_content_type_find_by_dvbcode(uint8_t dvbcode); +uint8_t epg_content_group_find_by_name(const char *name); -epg_content_group_t *epg_content_group_find_by_name(const char *name); - -const char *epg_content_group_get_name(unsigned int id); +const char *epg_content_group_get_name(uint8_t type); /** * @@ -150,7 +129,7 @@ typedef struct epg_query_result { } epg_query_result_t; void epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct, - epg_content_group_t *ecg, const char *title); + uint8_t type, const char *title); void epg_query(epg_query_result_t *eqr, const char *channel, const char *tag, const char *contentgroup, const char *title); void epg_query_free(epg_query_result_t *eqr); diff --git a/src/htsp.c b/src/htsp.c index 1ac89d94..1a2cba6a 100644 --- a/src/htsp.c +++ b/src/htsp.c @@ -562,10 +562,9 @@ htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in) htsmsg_t *out, *eventIds; const char *query; int c, i; - uint32_t channelid, tagid, epg_content_dvbcode; + uint32_t channelid, tagid, epg_content_dvbcode = 0; channel_t *ch = NULL; channel_tag_t *ct = NULL; - epg_content_type_t *ect = NULL; epg_query_result_t eqr; //only mandatory parameter is the query @@ -578,12 +577,10 @@ htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in) if( !(htsmsg_get_u32(in, "tagId", &tagid)) ) ct = channel_tag_find_by_identifier(tagid); - if( !(htsmsg_get_u32(in, "contentType", &epg_content_dvbcode)) ) - ect = epg_content_type_find_by_dvbcode(epg_content_dvbcode); - + htsmsg_get_u32(in, "contentType", &epg_content_dvbcode); //do the query - epg_query0(&eqr, ch, ct, ect ? ect->ect_group : NULL, query); + epg_query0(&eqr, ch, ct, epg_content_dvbcode, query); c = eqr.eqr_entries; // create reply @@ -626,8 +623,8 @@ htsp_build_event(event_t *e) if(e->e_ext_text != NULL) htsmsg_add_str(out, "ext_text", e->e_ext_text); - if(e->e_content_type != NULL) - htsmsg_add_u32(out, "contentType", e->e_content_type->ect_dvbcode); + if(e->e_content_type) + htsmsg_add_u32(out, "contentType", e->e_content_type); n = RB_NEXT(e, e_channel_link); if(n != NULL) diff --git a/src/webui/extjs.c b/src/webui/extjs.c index b7276d97..686f6f0a 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -643,6 +643,8 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque) end = MIN(start + limit, eqr.eqr_entries); for(i = start; i < end; i++) { + const char *s; + e = eqr.eqr_array[i]; m = htsmsg_create_map(); @@ -676,9 +678,8 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(m, "end", e->e_stop); htsmsg_add_u32(m, "duration", e->e_stop - e->e_start); - if(e->e_content_type != NULL && - e->e_content_type->ect_group->ecg_name != NULL) - htsmsg_add_str(m, "contentgrp", e->e_content_type->ect_group->ecg_name); + if((s = epg_content_group_get_name(e->e_content_type)) != NULL) + htsmsg_add_str(m, "contentgrp", s); dvr_entry_t *de; if((de = dvr_entry_find_by_event(e)) != NULL) @@ -793,11 +794,14 @@ extjs_dvr(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(out, "success", 1); } else if(!strcmp(op, "createAutoRec")) { + const char *cgrp = http_arg_get(&hc->hc_req_args, "contentgrp"); + + dvr_autorec_add(http_arg_get(&hc->hc_req_args, "title"), http_arg_get(&hc->hc_req_args, "channel"), http_arg_get(&hc->hc_req_args, "tag"), - http_arg_get(&hc->hc_req_args, "contentgrp"), + cgrp ? epg_content_group_find_by_name(cgrp) : 0, hc->hc_representative, "Created from EPG query"); out = htsmsg_create_map();