Started work on deleteing epg_channel_t and moving schedule info back into channel_t. This will make working with EIT much simpler, removes a fairly redundant object and will allow me to move epggrab channel mapping into each grabber which will be far more flexible and was what I had originally intended.

This commit is contained in:
Adam Sutton 2012-05-30 11:01:29 +01:00
parent 20097dd255
commit a373a3b4d8
11 changed files with 57 additions and 102 deletions

View file

@ -33,6 +33,7 @@
#include "tvheadend.h"
#include "psi.h"
#include "epg.h"
#include "epggrab.h"
#include "channels.h"
#include "dtable.h"
#include "notify.h"
@ -180,7 +181,7 @@ channel_create(const char *name, int number)
assert(x == NULL);
epg_channel_map_add(ch);
epggrab_channel_add(ch);
htsp_channel_add(ch);
return ch;
@ -247,7 +248,7 @@ channel_load_one(htsmsg_t *c, int id)
channel_set_name(ch, name);
epg_channel_map_add(ch);
epggrab_channel_add(ch);
tvh_str_update(&ch->ch_icon, htsmsg_get_str(c, "icon"));
@ -337,7 +338,7 @@ channel_rename(channel_t *ch, const char *newname)
RB_REMOVE(&channel_name_tree, ch, ch_name_link);
channel_set_name(ch, newname);
epg_channel_map_mod(ch);
epggrab_channel_mod(ch);
LIST_FOREACH(t, &ch->ch_services, s_ch_link)
t->s_config_save(t);
@ -377,7 +378,8 @@ channel_delete(channel_t *ch)
s->ths_channel = NULL;
}
epg_channel_map_rem(ch);
epggrab_channel_rem(ch);
epg_channel_unlink(ch);
hts_settings_remove("channels/%d", ch->ch_id);
@ -478,26 +480,6 @@ channel_set_number(channel_t *ch, int number)
htsp_channel_update(ch);
}
/**
*
*/
void
channel_set_epg_source(channel_t *ch, epg_channel_t *ec)
{
lock_assert(&global_lock);
if(ec == ch->ch_epg_channel)
return;
ch->ch_epg_channel = ec;
if(ec != NULL)
tvh_str_update(&ch->ch_icon, ec->icon);
channel_save(ch);
htsp_channel_update(ch);
}
/**
*
*/

View file

@ -19,6 +19,8 @@
#ifndef CHANNELS_H
#define CHANNELS_H
#include "epg.h"
LIST_HEAD(channel_tag_mapping_list, channel_tag_mapping);
TAILQ_HEAD(channel_tag_queue, channel_tag);
@ -43,8 +45,11 @@ typedef struct channel {
LIST_HEAD(, service) ch_services;
LIST_HEAD(, th_subscription) ch_subscriptions;
struct epg_channel *ch_epg_channel;
LIST_ENTRY(channel) ch_eulink;
/* EPG fields */
epg_object_tree_t ch_epg_schedule;
epg_broadcast_t *ch_epg_now;
epg_broadcast_t *ch_epg_next;
gtimer_t ch_epg_timer;
gtimer_t ch_epg_timer_head;
gtimer_t ch_epg_timer_current;
@ -113,8 +118,6 @@ void channel_delete(channel_t *ch);
void channel_merge(channel_t *dst, channel_t *src);
void channel_set_epg_source(channel_t *ch, struct epg_channel *ec);
void channel_set_epg_postpre_time(channel_t *ch, int pre, int mins);
void channel_set_number(channel_t *ch, int number);

View file

@ -66,7 +66,7 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e)
{
channel_tag_mapping_t *ctm;
if (!e->channel || !e->channel->channel) return 0;
if (!e->channel) return 0;
if(dae->dae_enabled == 0 || dae->dae_weekdays == 0)
return 0;
@ -77,12 +77,12 @@ autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e)
return 0; // Avoid super wildcard match
if(dae->dae_channel != NULL &&
dae->dae_channel != e->channel->channel)
dae->dae_channel != e->channel)
return 0;
if(dae->dae_channel_tag != NULL) {
LIST_FOREACH(ctm, &dae->dae_channel_tag->ct_ctms, ctm_tag_link)
if(ctm->ctm_channel == e->channel->channel)
if(ctm->ctm_channel == e->channel)
break;
if(ctm == NULL)
return 0;

View file

@ -330,11 +330,11 @@ dvr_entry_create_by_event(const char *config_name,
epg_broadcast_t *e, const char *creator,
dvr_autorec_entry_t *dae, dvr_prio_t pri)
{
if(!e->channel || !e->channel->channel || !e->episode->title)
if(!e->channel || !e->episode->title)
return NULL;
return _dvr_entry_create(config_name, e,
e->channel->channel, e->start, e->stop,
e->channel, e->start, e->stop,
e->episode->title,
e->episode->description ? e->episode->description
: e->episode->summary,
@ -724,7 +724,7 @@ dvr_entry_find_by_event(epg_broadcast_t *e)
{
dvr_entry_t *de;
LIST_FOREACH(de, &e->channel->channel->ch_dvrs, de_channel_link)
LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
if(de->de_bcast == e) return de;
return NULL;
}
@ -740,7 +740,7 @@ dvr_entry_find_by_event_fuzzy(epg_broadcast_t *e)
if (e->episode->title == NULL)
return NULL;
LIST_FOREACH(de, &e->channel->channel->ch_dvrs, de_channel_link)
LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link)
if ((abs(de->de_start - e->start) < 600) && (abs(de->de_stop - e->stop) < 600)) {
return de;
}

View file

@ -563,8 +563,8 @@ mk_build_metadata2(const epg_broadcast_t *e)
}
#endif
if(e->channel->channel != NULL)
addtag(q, build_tag_string("TVCHANNEL", e->channel->channel->ch_name, 0, NULL));
if(e->channel != NULL)
addtag(q, build_tag_string("TVCHANNEL", e->channel->ch_name, 0, NULL));
if(ee->title != NULL)
addtag(q, build_tag_string("TITLE", ee->title, 0, NULL));

View file

@ -26,9 +26,14 @@
#ifndef EPG_H
#define EPG_H
#include "channels.h"
#include "settings.h"
/*
* Forward decls
*/
struct channel;
struct channel_tag;
/*
* Map types
*/
@ -37,7 +42,6 @@ RB_HEAD(epg_object_tree, epg_object);
RB_HEAD(epg_brand_tree, epg_brand);
RB_HEAD(epg_season_tree, epg_season);
RB_HEAD(epg_episode_tree, epg_episode);
RB_HEAD(epg_channel_tree, epg_channel);
RB_HEAD(epg_broadcast_tree, epg_broadcast);
/*
@ -48,13 +52,11 @@ typedef struct epg_brand epg_brand_t;
typedef struct epg_season epg_season_t;
typedef struct epg_episode epg_episode_t;
typedef struct epg_broadcast epg_broadcast_t;
typedef struct epg_channel epg_channel_t;
typedef struct epg_object_list epg_object_list_t;
typedef struct epg_object_tree epg_object_tree_t;
typedef struct epg_brand_tree epg_brand_tree_t;
typedef struct epg_season_tree epg_season_tree_t;
typedef struct epg_episode_tree epg_episode_tree_t;
typedef struct epg_channel_tree epg_channel_tree_t;
typedef struct epg_broadcast_tree epg_broadcast_tree_t;
/* ************************************************************************
@ -241,7 +243,6 @@ typedef struct epg_broadcast
{
epg_object_t _; ///< Parent object
uint32_t dvb_id; ///< DVB identifier
time_t start; ///< Start time
time_t stop; ///< End time
@ -262,14 +263,14 @@ typedef struct epg_broadcast
RB_ENTRY(epg_broadcast) elink; ///< Episode link
epg_episode_t *episode; ///< Episode shown
epg_channel_t *channel; ///< Channel being broadcast on
struct channel *channel; ///< Channel being broadcast on
} epg_broadcast_t;
/* Lookup */
epg_broadcast_t *epg_broadcast_find_by_time
( epg_channel_t *ch, time_t start, time_t stop, int create, int *save );
epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, epg_channel_t *ch );
( struct channel *ch, time_t start, time_t stop, int create, int *save );
epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, struct channel *ch );
/* Mutators */
int epg_broadcast_set_episode ( epg_broadcast_t *b, epg_episode_t *e )
@ -287,50 +288,12 @@ epg_broadcast_t *epg_broadcast_deserialize
* Channel - provides mapping from EPG channels to real channels
* ***********************************************************************/
/* Object */
typedef struct epg_channel
{
epg_object_t _; ///< Parent object
char *name; ///< Channel name
char *icon; ///< Channel icon
char **sname; ///< DVB svc names (to map)
int **sid; ///< DVB svc ids (to map)
epg_object_tree_t schedule; ///< List of broadcasts
LIST_ENTRY(epg_channel) umlink; ///< Unmapped channel link
channel_t *channel; ///< Link to real channel
epg_broadcast_t *now; ///< Current broadcast
epg_broadcast_t *next; ///< Next broadcast
gtimer_t expire; ///< Expiration timer
} epg_channel_t;
/* Lookup */
epg_channel_t *epg_channel_find_by_uri
( const char *uri, int create, int *save );
epg_channel_t *epg_channel_find_by_id ( uint64_t id );
/* Mutators */
int epg_channel_set_name ( epg_channel_t *c, const char *n )
__attribute__((warn_unused_result));
int epg_channel_set_icon ( epg_channel_t *c, const char *i )
__attribute__((warn_unused_result));
int epg_channel_set_channel ( epg_channel_t *c, channel_t *ch );
/* Accessors */
epg_broadcast_t *epg_channel_get_broadcast
( epg_channel_t *ch, time_t start, time_t stop, int create, int *save );
( struct channel *ch, time_t start, time_t stop, int create, int *save );
/* Serialization */
htsmsg_t *epg_channel_serialize ( epg_channel_t *b );
epg_channel_t *epg_channel_deserialize ( htsmsg_t *m, int create, int *save );
/* Channel mapping */
void epg_channel_map_add ( channel_t *ch );
void epg_channel_map_rem ( channel_t *ch );
void epg_channel_map_mod ( channel_t *ch );
/* Unlink */
void epg_channel_unlink ( struct channel *ch );
/* ************************************************************************
* Querying
@ -352,8 +315,8 @@ void epg_query_free(epg_query_result_t *eqr);
void epg_query_sort(epg_query_result_t *eqr);
/* Query routines */
void epg_query0(epg_query_result_t *eqr, channel_t *ch, channel_tag_t *ct,
uint8_t type, const char *title);
void epg_query0(epg_query_result_t *eqr, struct channel *ch,
struct channel_tag *ct, 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);

View file

@ -37,6 +37,9 @@ typedef struct epggrab_module
void (*disable) ( void );
htsmsg_t* (*grab) ( const char *opts );
int (*parse) ( htsmsg_t *data, epggrab_stats_t *stats );
void (*ch_add) ( struct channel *ch );
void (*ch_rem) ( struct channel *ch );
void (*ch_mod) ( struct channel *ch );
} epggrab_module_t;
/*
@ -87,4 +90,11 @@ void epggrab_set_simple ( uint32_t interval, epggrab_module_t* mod );
void epggrab_set_advanced ( uint32_t count, epggrab_sched_t* sched );
void epggrab_set_eit ( uint32_t eit );
/*
* Channel handling
*/
void epggrab_channel_add ( struct channel *ch );
void epggrab_channel_rem ( struct channel *ch );
void epggrab_channel_mod ( struct channel *ch );
#endif /* __EPGGRAB_H__ */

View file

@ -310,12 +310,10 @@ htsp_build_channel(channel_t *ch, const char *method)
if(ch->ch_icon != NULL)
htsmsg_add_str(out, "channelIcon", ch->ch_icon);
if (ch->ch_epg_channel) {
now = ch->ch_epg_channel->now;
next = ch->ch_epg_channel->next;
htsmsg_add_u32(out, "eventId", now ? now->_.id : 0);
htsmsg_add_u32(out, "nextEventId", next ? next->_.id : 0);
}
now = ch->ch_epg_now;
next = ch->ch_epg_next;
htsmsg_add_u32(out, "eventId", now ? now->_.id : 0);
htsmsg_add_u32(out, "nextEventId", next ? next->_.id : 0);
LIST_FOREACH(ctm, &ch->ch_ctms, ctm_channel_link) {
ct = ctm->ctm_tag;
@ -757,7 +755,7 @@ htsp_build_event(epg_broadcast_t *e)
out = htsmsg_create_map();
htsmsg_add_u32(out, "eventId", e->_.id);
htsmsg_add_u32(out, "channelId", e->channel->channel->ch_id);
htsmsg_add_u32(out, "channelId", e->channel->ch_id);
htsmsg_add_u32(out, "start", e->start);
htsmsg_add_u32(out, "stop", e->stop);
if(e->episode->title != NULL)
@ -1425,8 +1423,8 @@ htsp_channel_update_current(channel_t *ch)
htsmsg_add_str(m, "method", "channelUpdate");
htsmsg_add_u32(m, "channelId", ch->ch_id);
now = ch->ch_epg_channel->now;
next = ch->ch_epg_channel->next;
now = ch->ch_epg_now;
next = ch->ch_epg_next;
htsmsg_add_u32(m, "eventId", now ? now->_.id : 0);
htsmsg_add_u32(m, "nextEventId", next ? next->_.id : 0);
htsp_async_send(m);

View file

@ -710,7 +710,7 @@ extjs_epg(http_connection_t *hc, const char *remain, void *opaque)
for(i = start; i < end; i++) {
e = eqr.eqr_array[i];
ee = e->episode;
ch = e->channel->channel;
ch = e->channel;
if (!ch||!ee) continue;
m = htsmsg_create_map();
@ -787,7 +787,7 @@ extjs_epgrelated(http_connection_t *hc, const char *remain, void *opaque)
/* Alternative broadcasts */
if (!strcmp(type, "alternative")) {
RB_FOREACH(ebc, &ee->broadcasts, elink) {
ch = ebc->channel->channel;
ch = ebc->channel;
if ( !ch ) continue; // skip something not viewable
if ( ebc == e ) continue; // skip self
count++;

View file

@ -229,9 +229,8 @@ page_einfo(http_connection_t *hc, const char *remain, void *opaque)
days[a.tm_wday], a.tm_mday, a.tm_mon + 1,
a.tm_hour, a.tm_min, b.tm_hour, b.tm_min);
// TODO: use real channel?
htsbuf_qprintf(hq, "<hr><b>\"%s\": \"%s\"</b><br><br>",
e->channel->name, e->episode->title);
e->channel->ch_name, e->episode->title);
dvr_status = de != NULL ? de->de_sched_state : DVR_NOSTATE;

View file

@ -181,7 +181,7 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, th_subscription_t
sm->sm_data = NULL;
epg_broadcast_t *e = NULL;
if(s->ths_channel) e = s->ths_channel->ch_epg_channel->now;
if(s->ths_channel) e = s->ths_channel->ch_epg_now;
if(e && event_id != e->_.id) {
event_id = e->_.id;