Add support for destroying channels

This commit is contained in:
Andreas Öman 2008-05-03 06:00:07 +00:00
parent 2b00dcf2a9
commit d517f22827
30 changed files with 330 additions and 220 deletions

View file

@ -37,7 +37,7 @@
static void
ajax_channelgroupmenu_content(tcp_queue_t *tq, int current)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
tcp_qprintf(tq, "<ul class=\"menubar\">");
@ -107,17 +107,16 @@ ajax_output_event(tcp_queue_t *tq, event_t *e, int flags, int color)
static void
ajax_list_events(tcp_queue_t *tq, th_channel_t *ch, int lines)
ajax_list_events(tcp_queue_t *tq, channel_t *ch, int lines)
{
event_t *e;
int i;
e = epg_event_find_current_or_upcoming(ch);
for(i = 0; i < 3 && e != NULL; i++) {
ajax_output_event(tq, e, 0, !(i & 1));
e = TAILQ_NEXT(e, e_link);
e = TAILQ_NEXT(e, e_channel_link);
}
}
@ -133,8 +132,8 @@ ajax_channel_tab(http_connection_t *hc, http_reply_t *hr,
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
th_channel_group_t *tcg;
channel_t *ch;
channel_group_t *tcg;
char dispname[20];
struct sockaddr_in *si;

View file

@ -34,7 +34,7 @@
* Render a channel group widget
*/
static void
ajax_chgroup_build(tcp_queue_t *tq, th_channel_group_t *tcg)
ajax_chgroup_build(tcp_queue_t *tq, channel_group_t *tcg)
{
tcp_qprintf(tq, "<li id=\"chgrp_%d\">", tcg->tcg_tag);
@ -76,7 +76,7 @@ static int
ajax_chgroup_updateorder(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
tcp_queue_t *tq = &hr->hr_tq;
http_arg_t *ra;
@ -106,7 +106,7 @@ static int
ajax_chgroup_add(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
tcp_queue_t *tq = &hr->hr_tq;
const char *name;
@ -146,7 +146,7 @@ static int
ajax_chgroup_del(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
tcp_queue_t *tq = &hr->hr_tq;
const char *id;
@ -172,7 +172,7 @@ int
ajax_config_channels_tab(http_connection_t *hc, http_reply_t *hr)
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_group_t *tcg;
channel_group_t *tcg;
tcp_qprintf(tq, "<div style=\"float: left; width: 30%\">");
@ -244,8 +244,8 @@ ajax_chgroup_editor(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
th_channel_group_t *tcg, *tcg2;
channel_t *ch;
channel_group_t *tcg, *tcg2;
int rowcol = 1;
int disprows;
@ -401,7 +401,7 @@ ajax_cheditor(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
channel_t *ch;
th_transport_t *t;
const char *s;
int i;
@ -490,8 +490,8 @@ ajax_changegroup(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
th_channel_group_t *tcg;
channel_t *ch;
channel_group_t *tcg;
http_arg_t *ra;
const char *s;
const char *curgrp;
@ -531,7 +531,7 @@ static int
ajax_chsetcomdetect(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
th_channel_t *ch;
channel_t *ch;
const char *s;
if(remain == NULL || (ch = channel_by_tag(atoi(remain))) == NULL)
@ -556,7 +556,7 @@ ajax_chrename(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
channel_t *ch;
const char *s;
if(remain == NULL || (ch = channel_by_tag(atoi(remain))) == NULL)
@ -594,8 +594,8 @@ ajax_chdelete(http_connection_t *hc, http_reply_t *hr,
const char *remain, void *opaque)
{
tcp_queue_t *tq = &hr->hr_tq;
th_channel_t *ch;
th_channel_group_t *tcg;
channel_t *ch;
channel_group_t *tcg;
if(remain == NULL || (ch = channel_by_tag(atoi(remain))) == NULL)
return HTTP_STATUS_BAD_REQUEST;

View file

@ -113,8 +113,8 @@ static void
xmltv_grabber_chlist(tcp_queue_t *tq, xmltv_grabber_t *xg)
{
xmltv_channel_t *xc;
th_channel_group_t *tcg;
th_channel_t *ch;
channel_group_t *tcg;
channel_t *ch;
tcp_qprintf(tq,
"<div style=\"overflow: auto; height: 450px\">");
@ -274,7 +274,7 @@ ajax_xmltvgrabberchmap(http_connection_t *hc, http_reply_t *hr,
xmltv_channel_t *xc;
const char *xmltvname;
const char *chname;
th_channel_t *ch;
channel_t *ch;
// tcp_queue_t *tq = &hr->hr_tq;
if(remain == NULL || (xg = xmltv_grabber_find(remain)) == NULL)

View file

@ -40,7 +40,7 @@
#include "epg.h"
#include "channels.h"
struct autorec_head autorecs;
struct autorec_queue autorecs;
static int ar_id_ceil;
static void autorec_save_entry(autorec_t *ar);
@ -60,14 +60,17 @@ autorec_init(void)
static int
autorec_cmp(autorec_t *ar, event_t *e)
{
if(ar->ar_ch != NULL && ar->ar_ch != e->e_ch)
if(ar->ar_channel != NULL &&
ar->ar_channel != e->e_channel)
return 0;
if(ar->ar_tcg != NULL && ar->ar_tcg != e->e_ch->ch_group)
if(ar->ar_channel_group != NULL &&
ar->ar_channel_group != e->e_channel->ch_group)
return 0;
if(ar->ar_ecg != NULL) {
if(e->e_content_type == NULL || ar->ar_ecg != e->e_content_type->ect_group)
if(e->e_content_type == NULL ||
ar->ar_ecg != e->e_content_type->ect_group)
return 0;
}
@ -98,7 +101,7 @@ static void
autorec_check_new_ar(autorec_t *ar)
{
event_t *e;
th_channel_t *ch;
channel_t *ch;
LIST_FOREACH(ch, &channels, ch_global_link) {
e = ch->ch_epg_cur_event;
@ -108,7 +111,7 @@ autorec_check_new_ar(autorec_t *ar)
if(autorec_cmp(ar, e))
autorec_tag(ar, e);
e = TAILQ_NEXT(e, e_link);
e = TAILQ_NEXT(e, e_channel_link);
if(e == NULL)
continue;
@ -143,8 +146,8 @@ autorec_check_new_event(event_t *e)
*/
static autorec_t *
autorec_create0(const char *name, int prio, const char *title,
epg_content_group_t *ecg, th_channel_group_t *tcg,
th_channel_t *ch, int id, const char *creator)
epg_content_group_t *ecg, channel_group_t *tcg,
channel_t *ch, int id, const char *creator)
{
autorec_t *ar = calloc(1, sizeof(autorec_t));
@ -158,8 +161,13 @@ autorec_create0(const char *name, int prio, const char *title,
ar->ar_name = strdup(name);
ar->ar_rec_prio = prio;
ar->ar_ecg = ecg;
ar->ar_tcg = tcg;
ar->ar_ch = ch;
ar->ar_channel_group = tcg;
LIST_INSERT_HEAD(&tcg->tcg_autorecs, ar, ar_channel_group_link);
ar->ar_channel = ch;
LIST_INSERT_HEAD(&ch->ch_autorecs, ar, ar_channel_link);
ar->ar_creator = strdup(creator);
ar->ar_id = id;
@ -186,6 +194,9 @@ autorec_destroy(autorec_t *ar)
free((void *)ar->ar_creator);
free((void *)ar->ar_name);
LIST_REMOVE(ar, ar_channel_group_link);
LIST_REMOVE(ar, ar_channel_link);
TAILQ_REMOVE(&autorecs, ar, ar_link);
free(ar);
}
@ -196,8 +207,8 @@ autorec_destroy(autorec_t *ar)
*/
int
autorec_create(const char *name, int prio, const char *title,
epg_content_group_t *ecg, th_channel_group_t *tcg,
th_channel_t *ch, const char *creator)
epg_content_group_t *ecg, channel_group_t *tcg,
channel_t *ch, const char *creator)
{
autorec_t *ar;
@ -252,11 +263,11 @@ autorec_save_entry(autorec_t *ar)
if(ar->ar_ecg != NULL)
fprintf(fp, "event_content_group = %s\n", ar->ar_ecg->ecg_name);
if(ar->ar_tcg != NULL)
fprintf(fp, "channel_group = %s\n", ar->ar_tcg->tcg_name);
if(ar->ar_channel_group != NULL)
fprintf(fp, "channel_group = %s\n", ar->ar_channel_group->tcg_name);
if(ar->ar_ch != NULL)
fprintf(fp, "channel = %s\n", ar->ar_ch->ch_name);
if(ar->ar_channel != NULL)
fprintf(fp, "channel = %s\n", ar->ar_channel->ch_name);
fclose(fp);
}
@ -319,3 +330,16 @@ autorec_load(void)
}
closedir(dir);
}
/**
*
*/
void
autorec_destroy_by_channel(channel_t *ch)
{
autorec_t *ar;
while((ar = LIST_FIRST(&ch->ch_autorecs)) != NULL)
autorec_destroy(ar);
}

View file

@ -21,9 +21,9 @@
#include <regex.h>
TAILQ_HEAD(autorec_head, autorec);
TAILQ_HEAD(autorec_queue, autorec);
extern struct autorec_head autorecs;
extern struct autorec_queue autorecs;
typedef struct autorec {
TAILQ_ENTRY(autorec) ar_link;
@ -38,8 +38,12 @@ typedef struct autorec {
regex_t ar_title_preg;
epg_content_group_t *ar_ecg;
th_channel_group_t *ar_tcg;
th_channel_t *ar_ch;
channel_group_t *ar_channel_group;
LIST_ENTRY(autorec) ar_channel_group_link;
channel_t *ar_channel;
LIST_ENTRY(autorec) ar_channel_link;
} autorec_t;
@ -47,11 +51,13 @@ typedef struct autorec {
void autorec_init(void);
int autorec_create(const char *name, int prio, const char *title,
epg_content_group_t *ecg, th_channel_group_t *tcg,
th_channel_t *ch, const char *creator);
epg_content_group_t *ecg, channel_group_t *tcg,
channel_t *ch, const char *creator);
void autorec_check_new_event(event_t *e);
void autorec_delete_by_id(int id);
void autorec_destroy_by_channel(channel_t *ch);
#endif /* AUTOREC_H */

View file

@ -89,7 +89,7 @@ static void init_picture(avgen_t *avg, int w, int h);
void
avgen_init(void)
{
th_channel_t *ch;
channel_t *ch;
th_transport_t *t;
if(avcodec_find_encoder(CODEC_ID_MPEG2VIDEO) == NULL)

View file

@ -38,13 +38,16 @@
#include "psi.h"
#include "channels.h"
#include "transports.h"
#include "epg.h"
#include "pvr.h"
#include "autorec.h"
struct th_channel_list channels;
struct channel_list channels;
int nchannels;
struct th_channel_group_queue all_channel_groups;
struct channel_group_queue all_channel_groups;
th_channel_group_t *defgroup;
channel_group_t *defgroup;
void scanner_init(void);
@ -82,7 +85,7 @@ chcmp(const char *s1, const char *s2)
*
*/
static int
channelcmp(th_channel_t *a, th_channel_t *b)
channelcmp(channel_t *a, channel_t *b)
{
return chcmp(a->ch_name, b->ch_name);
}
@ -91,10 +94,10 @@ channelcmp(th_channel_t *a, th_channel_t *b)
/**
*
*/
th_channel_group_t *
channel_group_t *
channel_group_find(const char *name, int create)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
if(!strcmp(name, tcg->tcg_name))
@ -103,7 +106,7 @@ channel_group_find(const char *name, int create)
if(!create)
return NULL;
tcg = calloc(1, sizeof(th_channel_group_t));
tcg = calloc(1, sizeof(channel_group_t));
tcg->tcg_name = strdup(name);
tcg->tcg_tag = tag_get();
@ -122,7 +125,7 @@ channel_group_find(const char *name, int create)
*
*/
void
channel_set_group(th_channel_t *ch, th_channel_group_t *tcg)
channel_set_group(channel_t *ch, channel_group_t *tcg)
{
if(ch->ch_group != NULL)
TAILQ_REMOVE(&ch->ch_group->tcg_channels, ch, ch_group_link);
@ -138,9 +141,9 @@ channel_set_group(th_channel_t *ch, th_channel_group_t *tcg)
*
*/
void
channel_group_destroy(th_channel_group_t *tcg)
channel_group_destroy(channel_group_t *tcg)
{
th_channel_t *ch;
channel_t *ch;
if(defgroup == tcg)
return;
@ -160,7 +163,7 @@ channel_group_destroy(th_channel_group_t *tcg)
*
*/
static void
channel_set_name(th_channel_t *ch, const char *name)
channel_set_name(channel_t *ch, const char *name)
{
const char *n2;
int l, i;
@ -193,10 +196,10 @@ channel_set_name(th_channel_t *ch, const char *name)
/**
*
*/
th_channel_t *
channel_find(const char *name, int create, th_channel_group_t *tcg)
channel_t *
channel_find(const char *name, int create, channel_group_t *tcg)
{
th_channel_t *ch;
channel_t *ch;
LIST_FOREACH(ch, &channels, ch_global_link)
if(!strcasecmp(name, ch->ch_name))
@ -205,7 +208,7 @@ channel_find(const char *name, int create, th_channel_group_t *tcg)
if(create == 0)
return NULL;
ch = calloc(1, sizeof(th_channel_t));
ch = calloc(1, sizeof(channel_t));
ch->ch_index = nchannels;
TAILQ_INIT(&ch->ch_epg_events);
@ -267,8 +270,8 @@ channels_load(void)
DIR *dir;
struct dirent *d;
const char *name, *grp, *x;
th_channel_t *ch;
th_channel_group_t *tcg;
channel_t *ch;
channel_group_t *tcg;
int v;
TAILQ_INIT(&all_channel_groups);
@ -345,10 +348,10 @@ channels_load(void)
/**
* The index stuff should go away
*/
th_channel_t *
channel_t *
channel_by_index(uint32_t index)
{
th_channel_t *ch;
channel_t *ch;
LIST_FOREACH(ch, &channels, ch_global_link)
if(ch->ch_index == index)
@ -362,10 +365,10 @@ channel_by_index(uint32_t index)
/**
*
*/
th_channel_t *
channel_t *
channel_by_tag(uint32_t tag)
{
th_channel_t *ch;
channel_t *ch;
LIST_FOREACH(ch, &channels, ch_global_link)
if(ch->ch_tag == tag)
@ -379,10 +382,10 @@ channel_by_tag(uint32_t tag)
/**
*
*/
th_channel_group_t *
channel_group_t *
channel_group_by_tag(uint32_t tag)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
if(tcg->tcg_tag == tag)
@ -404,7 +407,7 @@ void
channel_group_settings_write(void)
{
FILE *fp;
th_channel_group_t *tcg;
channel_group_t *tcg;
char buf[400];
snprintf(buf, sizeof(buf), "%s/channel-group-settings.cfg", settings_dir);
@ -426,7 +429,7 @@ channel_group_settings_write(void)
* Write out a config file for a channel
*/
void
channel_settings_write(th_channel_t *ch)
channel_settings_write(channel_t *ch)
{
FILE *fp;
char buf[400];
@ -448,7 +451,7 @@ channel_settings_write(th_channel_t *ch)
* Rename a channel and all tied transports
*/
int
channel_rename(th_channel_t *ch, const char *newname)
channel_rename(channel_t *ch, const char *newname)
{
th_transport_t *t;
@ -472,12 +475,36 @@ channel_rename(th_channel_t *ch, const char *newname)
* Delete channel
*/
void
channel_delete(th_channel_t *ch)
channel_delete(channel_t *ch)
{
th_transport_t *t;
th_subscription_t *s;
char buf[400];
while((t = LIST_FIRST(&ch->ch_transports)) != NULL)
pvr_destroy_by_channel(ch);
while((t = LIST_FIRST(&ch->ch_transports)) != NULL) {
transport_unmap_channel(t);
t->tht_config_change(t);
}
printf("Deleted channel %s\n", ch->ch_name);
while((s = LIST_FIRST(&ch->ch_subscriptions)) != NULL) {
LIST_REMOVE(s, ths_channel_link);
s->ths_channel = NULL;
}
epg_destroy_by_channel(ch);
autorec_destroy_by_channel(ch);
free((void *)ch->ch_name);
free((void *)ch->ch_sname);
free(ch->ch_icon);
TAILQ_REMOVE(&ch->ch_group->tcg_channels, ch, ch_group_link);
LIST_REMOVE(ch, ch_global_link);
free(ch);
snprintf(buf, sizeof(buf), "%s/channels/%s", settings_dir, ch->ch_sname);
unlink(buf);
}

View file

@ -21,35 +21,34 @@
void channels_load(void);
th_channel_t *channel_by_index(uint32_t id);
channel_t *channel_by_index(uint32_t id);
th_channel_t *channel_by_tag(uint32_t tag);
channel_t *channel_by_tag(uint32_t tag);
int id_by_channel(th_channel_t *ch);
int id_by_channel(channel_t *ch);
int channel_get_channels(void);
void channel_unsubscribe(th_subscription_t *s);
th_channel_t *channel_find(const char *name, int create,
th_channel_group_t *tcg);
channel_t *channel_find(const char *name, int create, channel_group_t *tcg);
th_channel_group_t *channel_group_find(const char *name, int create);
channel_group_t *channel_group_find(const char *name, int create);
th_channel_group_t *channel_group_by_tag(uint32_t tag);
channel_group_t *channel_group_by_tag(uint32_t tag);
void channel_group_destroy(th_channel_group_t *tcg);
void channel_group_destroy(channel_group_t *tcg);
void channel_set_group(th_channel_t *ch, th_channel_group_t *tcg);
void channel_set_group(channel_t *ch, channel_group_t *tcg);
void channel_set_teletext_rundown(th_channel_t *ch, int v);
void channel_set_teletext_rundown(channel_t *ch, int v);
void channel_group_settings_write(void);
void channel_settings_write(th_channel_t *ch);
void channel_settings_write(channel_t *ch);
int channel_rename(th_channel_t *ch, const char *newname);
int channel_rename(channel_t *ch, const char *newname);
void channel_delete(th_channel_t *ch);
void channel_delete(channel_t *ch);
#endif /* CHANNELS_H */

View file

@ -201,7 +201,7 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
uint8_t tableid, void *opaque)
{
th_transport_t *t;
th_channel_t *ch;
channel_t *ch;
th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
uint16_t serviceid;

83
epg.c
View file

@ -69,14 +69,14 @@ epg_event_find_by_time0(struct event_queue *q, time_t start)
{
event_t *e;
TAILQ_FOREACH(e, q, e_link)
TAILQ_FOREACH(e, q, e_channel_link)
if(start >= e->e_start && start < e->e_start + e->e_duration)
break;
return e;
}
event_t *
epg_event_find_by_time(th_channel_t *ch, time_t start)
epg_event_find_by_time(channel_t *ch, time_t start)
{
return epg_event_find_by_time0(&ch->ch_epg_events, start);
}
@ -96,7 +96,7 @@ epg_event_find_by_tag(uint32_t tag)
event_t *
epg_event_get_current(th_channel_t *ch)
epg_event_get_current(channel_t *ch)
{
event_t *e;
@ -111,11 +111,11 @@ epg_event_get_current(th_channel_t *ch)
}
event_t *
epg_event_find_current_or_upcoming(th_channel_t *ch)
epg_event_find_current_or_upcoming(channel_t *ch)
{
event_t *e;
TAILQ_FOREACH(e, &ch->ch_epg_events, e_link)
TAILQ_FOREACH(e, &ch->ch_epg_events, e_channel_link)
if(e->e_start + e->e_duration > dispatch_clock)
break;
return e;
@ -139,7 +139,7 @@ epg_event_build(struct event_queue *head, time_t start, int duration)
if(duration < 1 || start + duration < now - EPG_MAX_AGE)
return NULL;
TAILQ_FOREACH(e, head, e_link)
TAILQ_FOREACH(e, head, e_channel_link)
if(start == e->e_start && duration == e->e_duration)
return e;
@ -147,7 +147,7 @@ epg_event_build(struct event_queue *head, time_t start, int duration)
e->e_duration = duration;
e->e_start = start;
TAILQ_INSERT_SORTED(head, e, e_link, startcmp);
TAILQ_INSERT_SORTED(head, e, e_channel_link, startcmp);
return e;
}
@ -168,14 +168,14 @@ epg_event_free(event_t *e)
static void
epg_event_destroy(th_channel_t *ch, event_t *e)
epg_event_destroy(channel_t *ch, event_t *e)
{
// printf("epg: flushed event %s\n", e->e_title);
if(ch->ch_epg_cur_event == e)
ch->ch_epg_cur_event = NULL;
TAILQ_REMOVE(&ch->ch_epg_events, e, e_link);
TAILQ_REMOVE(&ch->ch_epg_events, e, e_channel_link);
LIST_REMOVE(e, e_hash_link);
epg_event_free(e);
@ -205,14 +205,14 @@ event_time_txt(time_t start, int duration, char *out, int outlen)
static int
check_overlap0(th_channel_t *ch, event_t *a)
check_overlap0(channel_t *ch, event_t *a)
{
char atime[100];
char btime[100];
event_t *b;
int overshot;
b = TAILQ_NEXT(a, e_link);
b = TAILQ_NEXT(a, e_channel_link);
if(b == NULL)
return 0;
@ -245,11 +245,11 @@ check_overlap0(th_channel_t *ch, event_t *a)
}
static int
check_overlap(th_channel_t *ch, event_t *e)
check_overlap(channel_t *ch, event_t *e)
{
event_t *p;
p = TAILQ_PREV(e, event_queue, e_link);
p = TAILQ_PREV(e, event_queue, e_channel_link);
if(p != NULL) {
if(check_overlap0(ch, p))
return 1;
@ -262,7 +262,7 @@ check_overlap(th_channel_t *ch, event_t *e)
static void
epg_event_create(th_channel_t *ch, time_t start, int duration,
epg_event_create(channel_t *ch, time_t start, int duration,
const char *title, const char *desc, int source,
uint16_t id, epg_content_type_t *ect)
{
@ -275,7 +275,7 @@ epg_event_create(th_channel_t *ch, time_t start, int duration,
if(duration < 1 || start + duration < now - EPG_MAX_AGE)
return;
TAILQ_FOREACH(e, &ch->ch_epg_events, e_link) {
TAILQ_FOREACH(e, &ch->ch_epg_events, e_channel_link) {
if(start == e->e_start && duration == e->e_duration)
break;
@ -288,9 +288,9 @@ epg_event_create(th_channel_t *ch, time_t start, int duration,
e = calloc(1, sizeof(event_t));
e->e_start = start;
TAILQ_INSERT_SORTED(&ch->ch_epg_events, e, e_link, startcmp);
TAILQ_INSERT_SORTED(&ch->ch_epg_events, e, e_channel_link, startcmp);
e->e_ch = ch;
e->e_channel = ch;
e->e_event_id = id;
e->e_duration = duration;
@ -325,13 +325,13 @@ epg_event_create(th_channel_t *ch, time_t start, int duration,
void
epg_update_event_by_id(th_channel_t *ch, uint16_t event_id,
epg_update_event_by_id(channel_t *ch, uint16_t event_id,
time_t start, int duration, const char *title,
const char *desc, epg_content_type_t *ect)
{
event_t *e;
TAILQ_FOREACH(e, &ch->ch_epg_events, e_link)
TAILQ_FOREACH(e, &ch->ch_epg_events, e_channel_link)
if(e->e_event_id == event_id)
break;
@ -346,11 +346,11 @@ epg_update_event_by_id(th_channel_t *ch, uint16_t event_id,
event_time_txt(e->e_start, e->e_duration, before, sizeof(before));
event_time_txt(start, duration, after, sizeof(after));
TAILQ_REMOVE(&ch->ch_epg_events, e, e_link);
TAILQ_REMOVE(&ch->ch_epg_events, e, e_channel_link);
e->e_duration = duration;
e->e_start = start;
TAILQ_INSERT_SORTED(&ch->ch_epg_events, e, e_link, startcmp);
TAILQ_INSERT_SORTED(&ch->ch_epg_events, e, e_channel_link, startcmp);
if(check_overlap(ch, e))
return; /* event was destroyed, return at once */
@ -369,7 +369,7 @@ epg_update_event_by_id(th_channel_t *ch, uint16_t event_id,
static void
epg_set_current_event(th_channel_t *ch, event_t *e)
epg_set_current_event(channel_t *ch, event_t *e)
{
if(e == ch->ch_epg_cur_event)
return;
@ -385,7 +385,7 @@ epg_set_current_event(th_channel_t *ch, event_t *e)
/* Let autorecorder check this event */
autorec_check_new_event(e);
e = TAILQ_NEXT(e, e_link);
e = TAILQ_NEXT(e, e_channel_link);
/* .. and next one, to make better scheduling */
if(e != NULL)
@ -393,7 +393,7 @@ epg_set_current_event(th_channel_t *ch, event_t *e)
}
static void
epg_locate_current_event(th_channel_t *ch, time_t now)
epg_locate_current_event(channel_t *ch, time_t now)
{
event_t *e;
e = epg_event_find_by_time(ch, now);
@ -405,7 +405,7 @@ epg_locate_current_event(th_channel_t *ch, time_t now)
static void
epg_channel_maintain(void *aux, int64_t clk)
{
th_channel_t *ch;
channel_t *ch;
event_t *e, *cur;
time_t now;
@ -432,7 +432,7 @@ epg_channel_maintain(void *aux, int64_t clk)
if(now >= e->e_start && now < e->e_start + e->e_duration)
continue;
e = TAILQ_NEXT(e, e_link);
e = TAILQ_NEXT(e, e_channel_link);
if(e != NULL && now >= e->e_start && now < e->e_start + e->e_duration) {
epg_set_current_event(ch, e);
continue;
@ -443,12 +443,24 @@ epg_channel_maintain(void *aux, int64_t clk)
}
/*
/**
*
*/
void
epg_transfer_events(th_channel_t *ch, struct event_queue *src,
epg_destroy_by_channel(channel_t *ch)
{
event_t *e;
while((e = TAILQ_FIRST(&ch->ch_epg_events)) != NULL)
epg_event_destroy(ch, e);
}
/**
*
*/
void
epg_transfer_events(channel_t *ch, struct event_queue *src,
const char *srcname, char *icon)
{
event_t *e;
@ -460,7 +472,7 @@ epg_transfer_events(th_channel_t *ch, struct event_queue *src,
channel_settings_write(ch);
}
TAILQ_FOREACH(e, src, e_link) {
TAILQ_FOREACH(e, src, e_channel_link) {
epg_event_create(ch, e->e_start, e->e_duration, e->e_title,
e->e_desc, EVENT_SRC_XMLTV, 0,
@ -537,11 +549,12 @@ epg_content_group_find_by_name(const char *name)
* XXX: Optimize if we know channel, group, etc
*/
int
epg_search(struct event_list *h, const char *title, epg_content_group_t *s_ecg,
th_channel_group_t *s_tcg, th_channel_t *s_ch)
epg_search(struct event_list *h, const char *title,
epg_content_group_t *s_ecg,
channel_group_t *s_tcg, channel_t *s_ch)
{
th_channel_group_t *dis;
th_channel_t *ch;
channel_group_t *dis;
channel_t *ch;
event_t *e;
int num = 0;
regex_t preg;
@ -565,7 +578,7 @@ epg_search(struct event_list *h, const char *title, epg_content_group_t *s_ecg,
if(s_tcg != NULL && s_tcg != ch->ch_group)
continue;
TAILQ_FOREACH(e, &ch->ch_epg_events, e_link) {
TAILQ_FOREACH(e, &ch->ch_epg_events, e_channel_link) {
if(e->e_start + e->e_duration < dispatch_clock)
continue; /* old */

16
epg.h
View file

@ -25,11 +25,11 @@ void epg_init(void);
event_t *epg_event_find_by_time0(struct event_queue *q, time_t start);
event_t *epg_event_find_by_time(th_channel_t *ch, time_t start);
event_t *epg_event_find_by_time(channel_t *ch, time_t start);
event_t *epg_event_find_by_tag(uint32_t id);
event_t *epg_event_get_current(th_channel_t *ch);
event_t *epg_event_get_current(channel_t *ch);
event_t *epg_event_build(struct event_queue *head, time_t start, int duration);
@ -39,23 +39,25 @@ void epg_event_set_title(event_t *e, const char *title);
void epg_event_set_desc(event_t *e, const char *desc);
void epg_update_event_by_id(th_channel_t *ch, uint16_t event_id,
void epg_update_event_by_id(channel_t *ch, uint16_t event_id,
time_t start, int duration, const char *title,
const char *desc, epg_content_type_t *ect);
void epg_transfer_events(th_channel_t *ch, struct event_queue *src,
void epg_transfer_events(channel_t *ch, struct event_queue *src,
const char *srcname, char *icon);
void event_time_txt(time_t start, int duration, char *out, int outlen);
event_t *epg_event_find_current_or_upcoming(th_channel_t *ch);
event_t *epg_event_find_current_or_upcoming(channel_t *ch);
epg_content_type_t *epg_content_type_find_by_dvbcode(uint8_t dvbcode);
epg_content_group_t *epg_content_group_find_by_name(const char *name);
int epg_search(struct event_list *h, const char *title,
epg_content_group_t *s_ecg, th_channel_group_t *s_tcg,
th_channel_t *s_ch);
epg_content_group_t *s_ecg, channel_group_t *s_tcg,
channel_t *s_ch);
void epg_destroy_by_channel(channel_t *ch);
#endif /* EPG_H */

View file

@ -220,7 +220,7 @@ xmltv_flush_events(xmltv_grabber_t *xg)
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {
while((e = TAILQ_FIRST(&xc->xc_events)) != NULL) {
TAILQ_REMOVE(&xc->xc_events, e, e_link);
TAILQ_REMOVE(&xc->xc_events, e, e_channel_link);
epg_event_free(e);
}
}
@ -232,10 +232,10 @@ xmltv_flush_events(xmltv_grabber_t *xg)
/*
*
*/
static th_channel_t *
static channel_t *
xmltv_resolve_by_events(xmltv_channel_t *xc)
{
th_channel_t *ch;
channel_t *ch;
event_t *ec, *ex;
time_t now;
int cnt, i;
@ -263,8 +263,8 @@ xmltv_resolve_by_events(xmltv_channel_t *xc)
if(ec->e_start != ex->e_start || ec->e_duration != ex->e_duration)
break;
ec = TAILQ_NEXT(ec, e_link);
ex = TAILQ_NEXT(ex, e_link);
ec = TAILQ_NEXT(ec, e_channel_link);
ex = TAILQ_NEXT(ex, e_channel_link);
cnt++;
}
}
@ -280,7 +280,7 @@ static void
xmltv_transfer_events(xmltv_grabber_t *xg)
{
xmltv_channel_t *xc;
th_channel_t *ch;
channel_t *ch;
int how;
TAILQ_FOREACH(xc, &xg->xg_channels, xc_link) {

View file

@ -82,7 +82,7 @@ file_input_init(void)
config_entry_t *ce;
th_transport_t *t;
th_stream_t *st;
th_channel_t *ch;
channel_t *ch;
TAILQ_FOREACH(ce, &config_list, ce_link) {
if(ce->ce_type != CFG_SUB || strcasecmp("streamedfile", ce->ce_key))

View file

@ -96,7 +96,7 @@ client_output_ts(void *opaque, th_subscription_t *s,
sin.sin_addr = c->c_ipaddr;
hdr[0] = HTSTV_TRANSPORT_STREAM;
hdr[1] = s->ths_channel->ch_index;
hdr[1] = s->ths_u32;
vec[0].iov_base = hdr;
vec[0].iov_len = 2;
@ -122,7 +122,7 @@ client_output_ts(void *opaque, th_subscription_t *s,
static int
cr_channel_info(client_t *c, char **argv, int argc)
{
th_channel_t *ch;
channel_t *ch;
if(argc < 1)
return 1;
@ -158,7 +158,7 @@ cr_channel_unsubscribe(client_t *c, char **argv, int argc)
chindex = atoi(argv[0]);
LIST_FOREACH(s, &c->c_subscriptions, ths_subscriber_link) {
if(s->ths_channel->ch_index == chindex)
if(s->ths_u32 == chindex)
break;
}
@ -202,7 +202,7 @@ client_subscription_callback(struct th_subscription *s,
static int
cr_channel_subscribe(client_t *c, char **argv, int argc)
{
th_channel_t *ch;
channel_t *ch;
th_subscription_t *s;
unsigned int chindex, weight;
char tmp[100];
@ -216,7 +216,7 @@ cr_channel_subscribe(client_t *c, char **argv, int argc)
weight = argc > 1 ? atoi(argv[1]) : 100;
LIST_FOREACH(s, &c->c_subscriptions, ths_subscriber_link) {
if(s->ths_channel->ch_index == chindex) {
if(s->ths_u32 == chindex) {
subscription_set_weight(s, weight);
return 0;
}
@ -234,6 +234,7 @@ cr_channel_subscribe(client_t *c, char **argv, int argc)
if(s == NULL)
return 1;
s->ths_u32 = ch->ch_index;
LIST_INSERT_HEAD(&c->c_subscriptions, s, ths_subscriber_link);
return 0;
}
@ -246,7 +247,7 @@ cr_channel_subscribe(client_t *c, char **argv, int argc)
static int
cr_channels_list(client_t *c, char **argv, int argc)
{
th_channel_t *ch;
channel_t *ch;
LIST_FOREACH(ch, &channels, ch_global_link) {
if(ch->ch_group == NULL)
@ -288,7 +289,7 @@ cr_event_info(client_t *c, char **argv, int argc)
{
event_t *e = NULL, *x;
uint32_t tag, prev, next;
th_channel_t *ch;
channel_t *ch;
pvr_rec_t *pvrr;
if(argc < 2)
@ -308,10 +309,10 @@ cr_event_info(client_t *c, char **argv, int argc)
}
tag = e->e_tag;
x = TAILQ_PREV(e, event_queue, e_link);
x = TAILQ_PREV(e, event_queue, e_channel_link);
prev = x != NULL ? x->e_tag : 0;
x = TAILQ_NEXT(e, e_link);
x = TAILQ_NEXT(e, e_channel_link);
next = x != NULL ? x->e_tag : 0;
pvrr = pvr_get_by_entry(e);
@ -369,7 +370,7 @@ cr_event_record(client_t *c, char **argv, int argc)
static int
cr_channel_record(client_t *c, char **argv, int argc)
{
th_channel_t *ch;
channel_t *ch;
int duration;
if(argc < 2)

8
htsp.c
View file

@ -71,7 +71,7 @@ htsp_send_msg(htsp_t *htsp, htsmsg_t *m, int media)
* build a channel message
*/
static htsmsg_t *
htsp_build_channel_msg(th_channel_t *ch, const char *method)
htsp_build_channel_msg(channel_t *ch, const char *method)
{
htsmsg_t *msg = htsmsg_create();
event_t *e;
@ -99,8 +99,8 @@ static void
htsp_send_all_channels(htsp_t *htsp)
{
htsmsg_t *msg;
th_channel_group_t *tcg;
th_channel_t *ch;
channel_group_t *tcg;
channel_t *ch;
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
if(tcg->tcg_hidden)
@ -125,7 +125,7 @@ htsp_send_all_channels(htsp_t *htsp)
*
*/
void
htsp_async_channel_update(th_channel_t *ch)
htsp_async_channel_update(channel_t *ch)
{
htsp_t *htsp;
htsmsg_t *msg;

2
htsp.h
View file

@ -44,6 +44,6 @@ void htsp_start(int port);
int htsp_send_msg(htsp_t *htsp, htsmsg_t *m, int media);
void htsp_async_channel_update(th_channel_t *ch);
void htsp_async_channel_update(channel_t *ch);
#endif /* HTSP_H_ */

View file

@ -19,9 +19,9 @@
#ifndef HTSP_MUXER_H_
#define HTSP_MUXER_H_
void htsp_muxer_subscribe(htsp_t *htsp, th_channel_t *ch, int weight);
void htsp_muxer_subscribe(htsp_t *htsp, channel_t *ch, int weight);
void htsp_muxer_unsubscribe(htsp_t *htsp, th_channel_t *ch);
void htsp_muxer_unsubscribe(htsp_t *htsp, channel_t *ch);
void htsp_muxer_cleanup(htsp_t *htsp);

View file

@ -122,7 +122,7 @@ static void
output_multicast_load(struct config_head *head)
{
const char *name, *s, *b;
th_channel_t *ch;
channel_t *ch;
output_multicast_t *om;
int ttl = 32;
struct sockaddr_in sin;

38
pvr.c
View file

@ -79,11 +79,11 @@ pvr_rec_t *
pvr_get_by_entry(event_t *e)
{
pvr_rec_t *pvrr;
channel_t *ch = e->e_channel;
LIST_FOREACH(pvrr, &pvrr_global_list, pvrr_global_link) {
LIST_FOREACH(pvrr, &ch->ch_pvrrs, pvrr_channel_link) {
if(pvrr->pvrr_start >= e->e_start &&
pvrr->pvrr_stop <= e->e_start + e->e_duration &&
pvrr->pvrr_channel == e->e_ch) {
pvrr->pvrr_stop <= e->e_start + e->e_duration) {
return pvrr;
}
}
@ -148,6 +148,7 @@ pvr_free(pvr_rec_t *pvrr)
{
dtimer_disarm(&pvrr->pvrr_timer);
LIST_REMOVE(pvrr, pvrr_global_link);
LIST_REMOVE(pvrr, pvrr_channel_link);
free(pvrr->pvrr_title);
free(pvrr->pvrr_desc);
free(pvrr->pvrr_creator);
@ -189,6 +190,22 @@ pvr_clear(pvr_rec_t *pvrr)
return 0;
}
/**
* Destroy all PVRs based on the given channel
*/
void
pvr_destroy_by_channel(channel_t *ch)
{
pvr_rec_t *pvrr;
while((pvrr = LIST_FIRST(&ch->ch_pvrrs)) != NULL) {
if(pvrr->pvrr_status == HTSTV_PVR_STATUS_RECORDING)
pvr_abort(pvrr);
pvr_clear(pvrr);
pvr_free(pvrr);
}
}
/**
@ -252,7 +269,7 @@ pvr_clear_all_completed(void)
pvr_rec_t *
pvr_schedule_by_event(event_t *e, const char *creator)
{
th_channel_t *ch = e->e_ch;
channel_t *ch = e->e_channel;
time_t start = e->e_start;
time_t stop = e->e_start + e->e_duration;
time_t now;
@ -265,19 +282,18 @@ pvr_schedule_by_event(event_t *e, const char *creator)
/* Try to see if we already have a scheduled or active recording */
LIST_FOREACH(pvrr, &pvrr_global_list, pvrr_global_link) {
if(pvrr->pvrr_channel == ch && pvrr->pvrr_start == start &&
pvrr->pvrr_stop == stop)
LIST_FOREACH(pvrr, &ch->ch_pvrrs, pvrr_channel_link)
if(pvrr->pvrr_start == start && pvrr->pvrr_stop == stop)
break;
}
if(pvrr != NULL)
return NULL; /* Already exists */
pvrr = calloc(1, sizeof(pvr_rec_t));
pvrr->pvrr_status = HTSTV_PVR_STATUS_SCHEDULED;
pvrr->pvrr_channel = ch;
LIST_INSERT_HEAD(&ch->ch_pvrrs, pvrr, pvrr_channel_link);
pvrr->pvrr_start = start;
pvrr->pvrr_stop = stop;
pvrr->pvrr_title = e->e_title ? strdup(e->e_title) : NULL;
@ -295,7 +311,7 @@ pvr_schedule_by_event(event_t *e, const char *creator)
* Record based on a channel
*/
pvr_rec_t *
pvr_schedule_by_channel_and_time(th_channel_t *ch, int duration,
pvr_schedule_by_channel_and_time(channel_t *ch, int duration,
const char *creator)
{
time_t now = dispatch_clock;
@ -306,6 +322,8 @@ pvr_schedule_by_channel_and_time(th_channel_t *ch, int duration,
pvrr = calloc(1, sizeof(pvr_rec_t));
pvrr->pvrr_status = HTSTV_PVR_STATUS_SCHEDULED;
pvrr->pvrr_channel = ch;
LIST_INSERT_HEAD(&ch->ch_pvrrs, pvrr, pvrr_channel_link);
pvrr->pvrr_start = start;
pvrr->pvrr_stop = stop;
pvrr->pvrr_title = strdup("Manual recording");

8
pvr.h
View file

@ -34,7 +34,9 @@ typedef struct pvr_rec {
LIST_ENTRY(pvr_rec) pvrr_global_link;
int pvrr_id; /* on-disk database id (filename) */
th_channel_t *pvrr_channel;
channel_t *pvrr_channel;
LIST_ENTRY(pvr_rec) pvrr_channel_link;
time_t pvrr_start;
time_t pvrr_stop;
@ -91,7 +93,9 @@ pvr_rec_t *pvr_get_by_entry(event_t *e);
pvr_rec_t *pvr_schedule_by_event(event_t *e, const char *creator);
pvr_rec_t *pvr_schedule_by_channel_and_time(th_channel_t *ch, int duration,
pvr_rec_t *pvr_schedule_by_channel_and_time(channel_t *ch, int duration,
const char *creator);
void pvr_destroy_by_channel(channel_t *ch);
#endif /* PVR_H */

10
rpc.c
View file

@ -43,7 +43,7 @@
* Build a channel information message
*/
static htsmsg_t *
rpc_build_channel_msg(th_channel_t *ch)
rpc_build_channel_msg(channel_t *ch)
{
htsmsg_t *m;
@ -125,7 +125,7 @@ static htsmsg_t *
rpc_channels_list(rpc_session_t *ses, htsmsg_t *in, void *opaque)
{
htsmsg_t *out;
th_channel_t *ch;
channel_t *ch;
out = htsmsg_create();
htsmsg_add_u32(out, "seq", ses->rs_seq);
@ -143,7 +143,7 @@ static htsmsg_t *
rpc_event_info(rpc_session_t *ses, htsmsg_t *in, void *opaque)
{
htsmsg_t *out;
th_channel_t *ch;
channel_t *ch;
uint32_t u32;
const char *s, *errtxt = NULL;
event_t *e = NULL, *x;
@ -177,10 +177,10 @@ rpc_event_info(rpc_session_t *ses, htsmsg_t *in, void *opaque)
htsmsg_add_str(out, "_error", errtxt);
} else {
tag = e->e_tag;
x = TAILQ_PREV(e, event_queue, e_link);
x = TAILQ_PREV(e, event_queue, e_channel_link);
prev = x != NULL ? x->e_tag : 0;
x = TAILQ_NEXT(e, e_link);
x = TAILQ_NEXT(e, e_channel_link);
next = x != NULL ? x->e_tag : 0;
htsmsg_add_u32(out, "start", e->e_start);

22
rtsp.c
View file

@ -88,10 +88,10 @@ typedef struct rtsp_session {
* Resolve an URL into a channel
*/
static th_channel_t *
static channel_t *
rtsp_channel_by_url(char *url)
{
th_channel_t *ch;
channel_t *ch;
char *c;
c = strrchr(url, '/');
@ -140,7 +140,7 @@ rtsp_subscription_callback(struct th_subscription *s,
* Create an RTSP session
*/
static rtsp_session_t *
rtsp_session_create(th_channel_t *ch, struct sockaddr_in *dst)
rtsp_session_create(channel_t *ch, struct sockaddr_in *dst)
{
rtsp_session_t *rs;
uint32_t id;
@ -275,7 +275,7 @@ rtsp_get_session(http_connection_t *hc)
char *ses;
int sesid;
rtsp_session_t *rs;
th_channel_t *ch;
channel_t *ch;
if((ch = rtsp_channel_by_url(hc->hc_url)) == NULL) {
rtsp_reply_error(hc, RTSP_STATUS_SERVICE, "URL does not resolve");
@ -329,8 +329,9 @@ rtsp_cmd_play(http_connection_t *hc)
ts_muxer_play(rs->rs_muxer, start);
syslog(LOG_INFO, "rtsp: %s: Starting playback of %s",
tcp_logname(&hc->hc_tcp_session), rs->rs_s->ths_channel->ch_name);
if(rs->rs_s->ths_channel != NULL)
syslog(LOG_INFO, "rtsp: %s: Starting playback of %s",
tcp_logname(&hc->hc_tcp_session), rs->rs_s->ths_channel->ch_name);
http_printf(hc,
"RTSP/1.0 200 OK\r\n"
@ -365,8 +366,9 @@ rtsp_cmd_pause(http_connection_t *hc)
ts_muxer_pause(rs->rs_muxer);
syslog(LOG_INFO, "rtsp: %s: Pausing playback of %s",
tcp_logname(&hc->hc_tcp_session), rs->rs_s->ths_channel->ch_name);
if(rs->rs_s->ths_channel != NULL)
syslog(LOG_INFO, "rtsp: %s: Pausing playback of %s",
tcp_logname(&hc->hc_tcp_session), rs->rs_s->ths_channel->ch_name);
http_printf(hc,
"RTSP/1.0 200 OK\r\n"
@ -394,7 +396,7 @@ rtsp_cmd_setup(http_connection_t *hc)
int nt, i, np, j, navp, nports, ismulticast;
int client_ports[2];
rtsp_session_t *rs;
th_channel_t *ch;
channel_t *ch;
struct sockaddr_in dst;
if((ch = rtsp_channel_by_url(hc->hc_url)) == NULL) {
@ -487,7 +489,7 @@ static void
rtsp_cmd_describe(http_connection_t *hc)
{
char sdpreply[1000];
th_channel_t *ch;
channel_t *ch;
char *c;
if((ch = rtsp_channel_by_url(hc->hc_url)) == NULL) {

View file

@ -62,6 +62,9 @@ subscription_reschedule(void)
if(s->ths_transport != NULL)
continue; /* Got a transport, we're happy */
if(s->ths_channel == NULL)
continue; /* stale entry, channel has been destroyed */
t = transport_find(s->ths_channel, s->ths_weight);
if(t == NULL)
@ -96,7 +99,9 @@ subscription_unsubscribe(th_subscription_t *s)
{
th_transport_t *t = s->ths_transport;
LIST_REMOVE(s, ths_global_link);
LIST_REMOVE(s, ths_channel_link);
if(s->ths_channel != NULL)
LIST_REMOVE(s, ths_channel_link);
if(t != NULL) {
subscription_stop(s);
@ -121,7 +126,7 @@ subscription_sort(th_subscription_t *a, th_subscription_t *b)
th_subscription_t *
subscription_create(th_channel_t *ch, unsigned int weight, const char *name,
subscription_create(channel_t *ch, unsigned int weight, const char *name,
subscription_callback_t *cb, void *opaque)
{
th_subscription_t *s;

View file

@ -23,7 +23,7 @@ void subscription_unsubscribe(th_subscription_t *s);
void subscription_set_weight(th_subscription_t *s, unsigned int weight);
th_subscription_t *subscription_create(th_channel_t *ch, unsigned int weight,
th_subscription_t *subscription_create(channel_t *ch, unsigned int weight,
const char *name,
subscription_callback_t *cb,
void *opaque);

View file

@ -32,7 +32,7 @@
#include "tvhead.h"
#include "teletext.h"
static void teletext_rundown(th_transport_t *t, th_channel_t *ch,
static void teletext_rundown(th_transport_t *t, channel_t *ch,
tt_page_t *ttp);
#define bitreverse(b) \
@ -180,7 +180,7 @@ tt_decode_line(th_transport_t *t, uint8_t *buf)
uint8_t mpag, line, s12, s34, c;
int page, magidx, i;
tt_mag_t *mag;
th_channel_t *ch = t->tht_channel;
channel_t *ch = t->tht_channel;
tt_decoder_t *ttd = &ch->ch_tt;
tt_page_t *ttp;
@ -318,7 +318,7 @@ tt_time_to_len(const char *buf)
*/
static void
teletext_rundown(th_transport_t *t, th_channel_t *ch, tt_page_t *ttp)
teletext_rundown(th_transport_t *t, channel_t *ch, tt_page_t *ttp)
{
char r[50];
int i;

View file

@ -274,7 +274,7 @@ transportcmp(const void *A, const void *B)
*
*/
th_transport_t *
transport_find(th_channel_t *ch, unsigned int weight)
transport_find(channel_t *ch, unsigned int weight)
{
th_transport_t *t, **vec;
int cnt = 0, i;
@ -526,7 +526,7 @@ transport_add_stream(th_transport_t *t, int pid, tv_streamtype_t type)
void
transport_map_channel(th_transport_t *t)
{
th_channel_t *ch = channel_find(t->tht_servicename, 1, NULL);
channel_t *ch = channel_find(t->tht_servicename, 1, NULL);
assert(t->tht_channel == NULL);

View file

@ -36,7 +36,7 @@ void transport_map_channel(th_transport_t *t);
void transport_unmap_channel(th_transport_t *t);
th_transport_t *transport_find(th_channel_t *ch, unsigned int weight);
th_transport_t *transport_find(channel_t *ch, unsigned int weight);
th_stream_t *transport_add_stream(th_transport_t *t, int pid,
tv_streamtype_t type);

View file

@ -69,9 +69,9 @@ typedef struct dtimer {
*/
LIST_HEAD(th_subscription_list, th_subscription);
LIST_HEAD(th_channel_list, th_channel);
TAILQ_HEAD(th_channel_queue, th_channel);
TAILQ_HEAD(th_channel_group_queue, th_channel_group);
LIST_HEAD(channel_list, channel);
TAILQ_HEAD(channel_queue, channel);
TAILQ_HEAD(channel_group_queue, channel_group);
TAILQ_HEAD(th_dvb_adapter_queue, th_dvb_adapter);
LIST_HEAD(th_v4l_adapter_list, th_v4l_adapter);
LIST_HEAD(event_list, event);
@ -90,12 +90,13 @@ LIST_HEAD(th_muxstream_list, th_muxstream);
LIST_HEAD(th_descrambler_list, th_descrambler);
TAILQ_HEAD(th_refpkt_queue, th_refpkt);
TAILQ_HEAD(th_muxpkt_queue, th_muxpkt);
LIST_HEAD(autorec_list, autorec);
extern time_t dispatch_clock;
extern int startupcounter;
extern struct th_transport_list all_transports;
extern struct th_channel_list channels;
extern struct th_channel_group_queue all_channel_groups;
extern struct channel_list channels;
extern struct channel_group_queue all_channel_groups;
extern struct pvr_rec_list pvrr_global_list;
extern struct th_subscription_list subscriptions;
@ -418,7 +419,7 @@ typedef struct th_transport {
LIST_ENTRY(th_transport) tht_active_link;
LIST_ENTRY(th_transport) tht_channel_link;
struct th_channel *tht_channel;
struct channel *tht_channel;
LIST_HEAD(, th_subscription) tht_subscriptions;
@ -743,27 +744,29 @@ typedef struct tt_decoder {
/**
* Channel groups
*/
typedef struct th_channel_group {
TAILQ_ENTRY(th_channel_group) tcg_global_link;
typedef struct channel_group {
TAILQ_ENTRY(channel_group) tcg_global_link;
const char *tcg_name;
struct th_channel_queue tcg_channels;
struct channel_queue tcg_channels;
int tcg_tag;
int tcg_cant_delete_me;
int tcg_hidden;
} th_channel_group_t;
struct autorec_list tcg_autorecs;
} channel_group_t;
/*
* Channel definition
*/
typedef struct th_channel {
typedef struct channel {
LIST_ENTRY(th_channel) ch_global_link;
LIST_ENTRY(channel) ch_global_link;
TAILQ_ENTRY(th_channel) ch_group_link;
th_channel_group_t *ch_group;
TAILQ_ENTRY(channel) ch_group_link;
channel_group_t *ch_group;
LIST_HEAD(, th_transport) ch_transports;
LIST_HEAD(, th_subscription) ch_subscriptions;
@ -787,7 +790,11 @@ typedef struct th_channel {
struct event *ch_epg_cur_event;
char *ch_icon;
} th_channel_t;
struct pvr_rec_list ch_pvrrs;
struct autorec_list ch_autorecs;
} channel_t;
/*
@ -823,7 +830,9 @@ typedef struct th_subscription {
int ths_weight;
LIST_ENTRY(th_subscription) ths_channel_link;
struct th_channel *ths_channel;
struct channel *ths_channel; /* May be NULL if channel has been
destroyed during the
subscription */
LIST_ENTRY(th_subscription) ths_transport_link;
struct th_transport *ths_transport; /* if NULL, ths_transport_link
@ -838,6 +847,7 @@ typedef struct th_subscription {
subscription_callback_t *ths_callback;
void *ths_opaque;
uint32_t ths_u32;
subscription_raw_input_t *ths_raw_input;
@ -869,7 +879,9 @@ typedef struct epg_content_type {
* EPG event
*/
typedef struct event {
TAILQ_ENTRY(event) e_link;
channel_t *e_channel;
TAILQ_ENTRY(event) e_channel_link;
LIST_ENTRY(event) e_hash_link;
LIST_ENTRY(event) e_tmp_link;
@ -886,8 +898,6 @@ typedef struct event {
uint32_t e_tag;
th_channel_t *e_ch;
int e_source; /* higer is better, and we never downgrade */
#define EVENT_SRC_XMLTV 1
@ -904,7 +914,7 @@ extern const char *settings_dir;
FILE *settings_open_for_write(const char *name);
FILE *settings_open_for_read(const char *name);
extern const char *sys_warning;
extern th_channel_group_t *defgroup;
extern channel_group_t *defgroup;
static inline unsigned int tvh_strhash(const char *s, unsigned int mod)
{

View file

@ -297,7 +297,7 @@ page_einfo(http_connection_t *hc, http_reply_t *hr,
a.tm_hour, a.tm_min, b.tm_hour, b.tm_min);
tcp_qprintf(tq, "<hr><b>\"%s\": \"%s\"</b><br><br>",
e->e_ch->ch_name, e->e_title);
e->e_channel->ch_name, e->e_title);
pvrstatus = pvrr != NULL ? pvrr->pvrr_status : HTSTV_PVR_STATUS_NONE;

14
xbmsp.c
View file

@ -218,10 +218,10 @@ xbmsp_dir_add_entry(xbmsp_dirhandle_t *xdh, const char *name,
/**
*
*/
static th_channel_group_t *
static channel_group_t *
xbmsp_cur_channel_group(xbmsp_t *xbmsp)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
TAILQ_FOREACH(tcg, &all_channel_groups, tcg_global_link) {
if(tcg->tcg_hidden)
@ -240,8 +240,8 @@ xbmsp_cur_channel_group(xbmsp_t *xbmsp)
static int
xbmsp_dir_populate(xbmsp_t *xbmsp, xbmsp_dirhandle_t *xdh, const char *filter)
{
th_channel_group_t *tcg;
th_channel_t *ch;
channel_group_t *tcg;
channel_t *ch;
char name[100];
if(xbmsp->xbmsp_wd[0] == 0) {
@ -346,7 +346,7 @@ xbmsp_cdroot(xbmsp_t *xbmsp)
static const char *
xbmsp_cddown(xbmsp_t *xbmsp, const char *dir)
{
th_channel_group_t *tcg;
channel_group_t *tcg;
if(xbmsp->xbmsp_wd[0] == 0) {
/* root dir */
@ -772,8 +772,8 @@ static int
xbmsp_input_file_open(xbmsp_t *xbmsp, uint32_t msgid, uint8_t *buf, int len)
{
char *fname = NULL, *tr;
th_channel_group_t *tcg;
th_channel_t *ch;
channel_group_t *tcg;
channel_t *ch;
xbmsp_subscrption_t *xs;
if((fname = xbmsp_extract_string(xbmsp, &buf, &len)) == NULL) {