Rework how content_type is handled internally

This commit is contained in:
Andreas Öman 2010-08-30 09:17:03 +00:00
parent 4322b7b131
commit 2bd91b3110
8 changed files with 61 additions and 131 deletions

View file

@ -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:

View file

@ -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);

View file

@ -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);

View file

@ -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,

101
src/epg.c
View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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)

View file

@ -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();