Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
DVR: an attempt to add the EPG running state check, fixes #3228
  • Loading branch information
perexg committed Oct 30, 2015
1 parent 77d14ab commit b62e1bd
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 30 deletions.
15 changes: 11 additions & 4 deletions src/dvr/dvr.h
Expand Up @@ -49,6 +49,7 @@ typedef struct dvr_config {
uint32_t dvr_extra_time_pre;
uint32_t dvr_extra_time_post;
uint32_t dvr_update_window;
int dvr_running;

muxer_config_t dvr_muxcnf;

Expand Down Expand Up @@ -111,6 +112,7 @@ typedef enum {
DVR_RS_RUNNING,
DVR_RS_COMMERCIAL,
DVR_RS_ERROR,
DVR_RS_EPG_WAIT,
} dvr_rs_state_t;


Expand Down Expand Up @@ -150,6 +152,9 @@ typedef struct dvr_entry {
time_t de_start_extra;
time_t de_stop_extra;

time_t de_running_start;
time_t de_running_stop;

char *de_owner;
char *de_creator;
char *de_comment;
Expand Down Expand Up @@ -421,13 +426,13 @@ uint32_t dvr_entry_get_removal_days( dvr_entry_t *de );

uint32_t dvr_entry_get_rerecord_errors( dvr_entry_t *de );

int dvr_entry_get_start_time( dvr_entry_t *de );
time_t dvr_entry_get_start_time( dvr_entry_t *de );

int dvr_entry_get_stop_time( dvr_entry_t *de );
time_t dvr_entry_get_stop_time( dvr_entry_t *de );

int dvr_entry_get_extra_time_post( dvr_entry_t *de );
time_t dvr_entry_get_extra_time_post( dvr_entry_t *de );

int dvr_entry_get_extra_time_pre( dvr_entry_t *de );
time_t dvr_entry_get_extra_time_pre( dvr_entry_t *de );

void dvr_entry_init(void);

Expand Down Expand Up @@ -501,6 +506,8 @@ void dvr_event_removed(epg_broadcast_t *e);

void dvr_event_updated(epg_broadcast_t *e);

void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, int running);

dvr_entry_t *dvr_entry_find_by_id(int id);

static inline dvr_entry_t *dvr_entry_find_by_uuid(const char *uuid)
Expand Down
9 changes: 9 additions & 0 deletions src/dvr/dvr_config.c
Expand Up @@ -182,6 +182,7 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf)
cfg->dvr_skip_commercials = 1;
dvr_charset_update(cfg, intlconv_filesystem_charset());
cfg->dvr_update_window = 24 * 3600;
cfg->dvr_running = 1;
cfg->dvr_pathname = strdup("$t$n.$x");

/* Muxer config */
Expand Down Expand Up @@ -862,6 +863,14 @@ const idclass_t dvr_config_class = {
.def.u32 = 24*3600,
.group = 1,
},
{
.type = PT_BOOL,
.id = "epg-running",
.name = N_("Use EPG Running State"),
.off = offsetof(dvr_config_t, dvr_running),
.def.u32 = 1,
.group = 1,
},
{
.type = PT_STR,
.id = "postproc",
Expand Down
77 changes: 72 additions & 5 deletions src/dvr/dvr_db.c
Expand Up @@ -204,20 +204,20 @@ static inline int extra_valid(time_t extra)
return extra != 0 && extra != (time_t)-1;
}

int
time_t
dvr_entry_get_start_time( dvr_entry_t *de )
{
/* Note 30 seconds might not be enough (rotors) */
return de->de_start - (60 * dvr_entry_get_extra_time_pre(de)) - 30;
}

int
time_t
dvr_entry_get_stop_time( dvr_entry_t *de )
{
return de->de_stop + (60 * dvr_entry_get_extra_time_post(de));
}

int
time_t
dvr_entry_get_extra_time_pre( dvr_entry_t *de )
{
time_t extra = de->de_start_extra;
Expand All @@ -233,7 +233,7 @@ dvr_entry_get_extra_time_pre( dvr_entry_t *de )
return extra;
}

int
time_t
dvr_entry_get_extra_time_post( dvr_entry_t *de )
{
time_t extra = de->de_stop_extra;
Expand Down Expand Up @@ -419,6 +419,8 @@ dvr_entry_status(dvr_entry_t *de)
return N_("Commercial break");
case DVR_RS_ERROR:
return streaming_code2txt(de->de_last_error);
case DVR_RS_EPG_WAIT:
return N_("Waiting for EPG running flag");
default:
return N_("Invalid");
}
Expand Down Expand Up @@ -513,7 +515,7 @@ dvr_usage_count(access_t *aa)
return used;
}

static void
void
dvr_entry_set_timer(dvr_entry_t *de)
{
time_t now, start, stop;
Expand All @@ -528,6 +530,12 @@ dvr_entry_set_timer(dvr_entry_t *de)

if (now >= stop || de->de_dont_reschedule) {

/* EPG thinks that the program is running */
if(de->de_running_start > de->de_running_stop) {
stop = dispatch_clock + 10;
goto recording;
}

if(htsmsg_is_empty(de->de_files))
dvr_entry_missed_time(de, de->de_last_error);
else
Expand All @@ -538,6 +546,7 @@ dvr_entry_set_timer(dvr_entry_t *de)

} else if (de->de_sched_state == DVR_RECORDING) {

recording:
gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de, stop);

} else if (de->de_channel && de->de_channel->ch_enabled) {
Expand Down Expand Up @@ -1537,6 +1546,58 @@ void dvr_event_updated(epg_broadcast_t *e)
}
}

/**
* Event running status is updated
*/
void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, int running)
{
dvr_entry_t *de;

if (esrc != EPG_SOURCE_EIT)
return;
de = dvr_entry_find_by_event(e);
if (de == NULL)
return;
if (!de->de_config->dvr_running) {
de->de_running_start = de->de_running_stop = 0;
return;
}
if (running) {
if (!de->de_running_start)
tvhdebug("dvr", "dvr entry %s event %s on %s - EPG marking start",
idnode_uuid_as_sstr(&de->de_id),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
de->de_running_start = dispatch_clock;
if (dvr_entry_get_start_time(de) > dispatch_clock) {
de->de_start = dispatch_clock;
dvr_entry_set_timer(de);
tvhdebug("dvr", "dvr entry %s event %s on %s - EPG start",
idnode_uuid_as_sstr(&de->de_id),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
}
} else {
if (!de->de_running_stop ||
de->de_running_start > de->de_running_stop)
tvhdebug("dvr", "dvr entry %s event %s on %s - EPG marking stop",
idnode_uuid_as_sstr(&de->de_id),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
de->de_running_stop = dispatch_clock;
if (de->de_sched_state == DVR_RECORDING) {
if (dvr_entry_get_stop_time(de) > dispatch_clock) {
de->de_dont_reschedule = 1;
dvr_entry_set_timer(de);
tvhdebug("dvr", "dvr entry %s event %s on %s - EPG stop",
idnode_uuid_as_sstr(&de->de_id),
epg_broadcast_get_title(e, NULL),
channel_get_name(e->channel));
}
}
}
}

/**
*
*/
Expand Down Expand Up @@ -1582,6 +1643,12 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone)
static void
dvr_timer_stop_recording(void *aux)
{
dvr_entry_t *de = aux;
/* EPG thinks that the program is running */
if (de->de_running_start > de->de_running_stop) {
gtimer_arm(&de->de_timer, dvr_timer_stop_recording, de, 10);
return;
}
dvr_stop_recording(aux, SM_CODE_OK, 1, 0);
}

Expand Down
44 changes: 31 additions & 13 deletions src/dvr/dvr_rec.c
Expand Up @@ -1047,8 +1047,9 @@ dvr_thread(void *aux)
streaming_message_t *sm;
th_subscription_t *ts;
th_pkt_t *pkt;
int run = 1, started = 0, comm_skip;
int run = 1, started = 0, comm_skip, epg_running, rs;
int commercial = COMMERCIAL_UNKNOWN;
int64_t packets = 0;
char *postproc;

pthread_mutex_lock(&global_lock);
Expand Down Expand Up @@ -1089,42 +1090,57 @@ dvr_thread(void *aux)
/* we don't want to start new recordings at this point */
if (sm->sm_type == SMT_START && de->de_thread_shutdown)
break;
epg_running = de->de_running_start > de->de_running_stop ||
(de->de_running_start == 0 && de->de_running_stop == 0);
pthread_mutex_unlock(&sq->sq_mutex);

switch(sm->sm_type) {

case SMT_PACKET:
pkt = sm->sm_data;
if(pkt->pkt_commercial == COMMERCIAL_YES)
dvr_rec_set_state(de, DVR_RS_COMMERCIAL, 0);
else
dvr_rec_set_state(de, DVR_RS_RUNNING, 0);

if(pkt->pkt_commercial == COMMERCIAL_YES && comm_skip)
rs = DVR_RS_RUNNING;
if (!epg_running)
rs = DVR_RS_EPG_WAIT;
else if (pkt->pkt_commercial == COMMERCIAL_YES)
rs = DVR_RS_COMMERCIAL;
dvr_rec_set_state(de, rs, 0);

if (rs == DVR_RS_COMMERCIAL && comm_skip)
break;
if (!epg_running)
break;

if(commercial != pkt->pkt_commercial)
if (commercial != pkt->pkt_commercial)
muxer_add_marker(prch->prch_muxer);

commercial = pkt->pkt_commercial;

if(started) {
if (started) {
if (!epg_running && packets)
goto restart;
muxer_write_pkt(prch->prch_muxer, sm->sm_type, sm->sm_data);
sm->sm_data = NULL;
dvr_notify(de);
packets++;
}
break;

case SMT_MPEGTS:
if(started) {
dvr_rec_set_state(de, DVR_RS_RUNNING, 0);
dvr_rec_set_state(de, !epg_running ? DVR_RS_EPG_WAIT : DVR_RS_RUNNING, 0);
if (!epg_running && packets)
goto restart;
muxer_write_pkt(prch->prch_muxer, sm->sm_type, sm->sm_data);
sm->sm_data = NULL;
dvr_notify(de);
packets++;
}
break;

case SMT_START:
restart:
packets = 0;
if(started &&
muxer_reconfigure(prch->prch_muxer, sm->sm_data) < 0) {
tvhlog(LOG_WARNING,
Expand All @@ -1135,10 +1151,12 @@ dvr_thread(void *aux)
// support reconfiguration of the streams.
dvr_thread_epilog(de, postproc);
started = 0;
pthread_mutex_lock(&global_lock);
if (de->de_config->dvr_clone)
de = dvr_entry_clone(de);
pthread_mutex_unlock(&global_lock);
if (epg_running) {
pthread_mutex_lock(&global_lock);
if (de->de_config->dvr_clone)
de = dvr_entry_clone(de);
pthread_mutex_unlock(&global_lock);
}
}

if(!started) {
Expand Down
28 changes: 27 additions & 1 deletion src/epg.c
Expand Up @@ -1417,8 +1417,14 @@ static void _epg_channel_timer_callback ( void *p )
channel_t *ch = (channel_t*)p;

/* Clear now/next */
if ((cur = ch->ch_epg_now))
if ((cur = ch->ch_epg_now)) {
if (cur->running) {
/* running? don't do anything */
gtimer_arm(&ch->ch_epg_timer, _epg_channel_timer_callback, ch, 2);
return;
}
cur->getref(cur);
}
if ((nxt = ch->ch_epg_next))
nxt->getref(nxt);
ch->ch_epg_now = ch->ch_epg_next = NULL;
Expand Down Expand Up @@ -1676,6 +1682,26 @@ epg_broadcast_t *epg_broadcast_find_by_eid ( channel_t *ch, uint16_t eid )
return NULL;
}

void epg_broadcast_notify_running
( epg_broadcast_t *broadcast, epg_source_t esrc, int running )
{
channel_t *ch;
epg_broadcast_t *now;

broadcast->running = !!running;
if (!running) {
broadcast->stop = dispatch_clock - 1;
} else {
ch = broadcast->channel;
now = ch ? ch->ch_epg_now : NULL;
if (broadcast != now && now) {
now->running = 0;
dvr_event_running(ch->ch_epg_now, esrc, 0);
}
}
dvr_event_running(broadcast, esrc, running);
}

int epg_broadcast_set_episode
( epg_broadcast_t *broadcast, epg_episode_t *episode, epggrab_module_t *src )
{
Expand Down
11 changes: 11 additions & 0 deletions src/epg.h
Expand Up @@ -56,6 +56,14 @@ typedef struct epg_serieslink epg_serieslink_t;

extern int epg_in_load;

/*
*
*/
typedef enum {
EPG_SOURCE_NONE = 0,
EPG_SOURCE_EIT = 1,
} epg_source_t;

/* ************************************************************************
* Genres
* ***********************************************************************/
Expand Down Expand Up @@ -436,6 +444,7 @@ struct epg_broadcast
/* Misc flags */
uint8_t is_new; ///< New series / file premiere
uint8_t is_repeat; ///< Repeat screening
uint8_t running; ///< EPG running flag

/* Broadcast level text */
lang_str_t *summary; ///< Summary
Expand All @@ -460,6 +469,8 @@ epg_broadcast_t *epg_broadcast_find_by_id ( uint32_t id );
/* Special */
epg_broadcast_t *epg_broadcast_clone
( struct channel *channel, epg_broadcast_t *src, int *save );
void epg_broadcast_notify_running
( epg_broadcast_t *b, epg_source_t esrc, int running );

/* Mutators */
int epg_broadcast_set_episode
Expand Down

0 comments on commit b62e1bd

Please sign in to comment.