Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
DVR: added 'clone scheduled entry on error' functionality - marked as…
… default
  • Loading branch information
perexg committed Sep 30, 2015
1 parent 252aa8c commit c05a478
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/api/api_dvr.c
Expand Up @@ -170,7 +170,7 @@ api_dvr_entry_create
htsmsg_add_str(m, lang, s1);
htsmsg_add_msg(conf, "subtitle", m);
}
if ((de = dvr_entry_create(NULL, conf)))
if ((de = dvr_entry_create(NULL, conf, 0)))
dvr_entry_save(de);

res = 0;
Expand Down
10 changes: 8 additions & 2 deletions src/dvr/dvr.h
Expand Up @@ -39,6 +39,7 @@ typedef struct dvr_config {
char *dvr_comment;
profile_t *dvr_profile;
char *dvr_storage;
int dvr_clone;
uint32_t dvr_retention_days;
char *dvr_charset;
char *dvr_charset_id;
Expand Down Expand Up @@ -424,7 +425,10 @@ void dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_en
void dvr_entry_created(dvr_entry_t *de);

dvr_entry_t *
dvr_entry_create ( const char *uuid, htsmsg_t *conf );
dvr_entry_clone ( dvr_entry_t *de );

dvr_entry_t *
dvr_entry_create ( const char *uuid, htsmsg_t *conf, int clone );


dvr_entry_t *
Expand Down Expand Up @@ -459,12 +463,14 @@ dvr_entry_update( dvr_entry_t *de, int enabled, channel_t *ch,

void dvr_destroy_by_channel(channel_t *ch, int delconf);

void dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf);
void dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone);

int dvr_rec_subscribe(dvr_entry_t *de);

void dvr_rec_unsubscribe(dvr_entry_t *de);

void dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new);

void dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e);

void dvr_event_updated(epg_broadcast_t *e);
Expand Down
9 changes: 9 additions & 0 deletions src/dvr/dvr_config.c
Expand Up @@ -177,6 +177,7 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf)
cfg->dvr_enabled = 1;
cfg->dvr_config_name = strdup(name);
cfg->dvr_retention_days = 31;
cfg->dvr_clone = 1;
cfg->dvr_tag_files = 1;
cfg->dvr_skip_commercials = 1;
dvr_charset_update(cfg, intlconv_filesystem_charset());
Expand Down Expand Up @@ -812,6 +813,14 @@ const idclass_t dvr_config_class = {
.def.u32 = 31,
.group = 1,
},
{
.type = PT_BOOL,
.id = "clone",
.name = N_("Clone Scheduled Entry On Error"),
.off = offsetof(dvr_config_t, dvr_clone),
.def.u32 = 1,
.group = 1,
},
{
.type = PT_U32,
.id = "pre-extra-time",
Expand Down
99 changes: 72 additions & 27 deletions src/dvr/dvr_db.c
Expand Up @@ -42,6 +42,7 @@ static gtimer_t dvr_dbus_timer;

static void dvr_entry_destroy(dvr_entry_t *de, int delconf);
static void dvr_timer_expire(void *aux);
static void dvr_entry_start_recording(dvr_entry_t *de, int clone);
static void dvr_timer_start_recording(void *aux);
static void dvr_timer_stop_recording(void *aux);

Expand Down Expand Up @@ -474,7 +475,7 @@ dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e)
* Create the event from config
*/
dvr_entry_t *
dvr_entry_create(const char *uuid, htsmsg_t *conf)
dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone)
{
dvr_entry_t *de, *de2;
int64_t start, stop;
Expand Down Expand Up @@ -517,7 +518,7 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)

LIST_INSERT_HEAD(&dvrentries, de, de_global_link);

if (de->de_channel) {
if (de->de_channel && !de->de_dont_reschedule && !clone) {
LIST_FOREACH(de2, &de->de_channel->ch_dvrs, de_channel_link)
if(de2 != de &&
de2->de_config == de->de_config &&
Expand All @@ -536,7 +537,8 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf)
}
}

dvr_entry_set_timer(de);
if (!clone)
dvr_entry_set_timer(de);
htsp_dvr_entry_add(de);

return de;
Expand Down Expand Up @@ -627,7 +629,7 @@ dvr_entry_create_(int enabled, const char *config_uuid, epg_broadcast_t *e,
htsmsg_add_str(conf, "directory", dte->dte_directory ?: "");
}

de = dvr_entry_create(NULL, conf);
de = dvr_entry_create(NULL, conf, 0);

htsmsg_destroy(conf);

Expand Down Expand Up @@ -700,6 +702,37 @@ dvr_entry_create_by_event(int enabled, const char *config_uuid,
comment);
}

/**
* Clone existing DVR entry and stop the previous
*/
dvr_entry_t *
dvr_entry_clone(dvr_entry_t *de)
{
htsmsg_t *conf = htsmsg_create_map();
dvr_entry_t *n;

lock_assert(&global_lock);

idnode_save(&de->de_id, conf);
n = dvr_entry_create(NULL, conf, 1);
htsmsg_destroy(conf);

if (n) {
if(de->de_sched_state == DVR_RECORDING) {
de->de_dont_reschedule = 1;
dvr_stop_recording(de, SM_CODE_SOURCE_RECONFIGURED, 1, 1);
dvr_rec_migrate(de, n);
n->de_start = dispatch_clock;
dvr_entry_start_recording(n, 1);
} else {
dvr_entry_set_timer(n);
}
dvr_entry_save(n);
}

return n == NULL ? de : n;
}

/**
*
*/
Expand Down Expand Up @@ -1196,11 +1229,12 @@ void dvr_event_updated ( epg_broadcast_t *e )
*
*/
void
dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf)
dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone)
{
dvr_rs_state_t rec_state = de->de_rec_state;

dvr_rec_unsubscribe(de);
if (!clone)
dvr_rec_unsubscribe(de);

if (stopcode != SM_CODE_INVALID_TARGET &&
(rec_state == DVR_RS_PENDING ||
Expand Down Expand Up @@ -1229,7 +1263,7 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf)
static void
dvr_timer_stop_recording(void *aux)
{
dvr_stop_recording(aux, SM_CODE_OK, 1);
dvr_stop_recording(aux, SM_CODE_OK, 1, 0);
}


Expand All @@ -1238,28 +1272,16 @@ dvr_timer_stop_recording(void *aux)
*
*/
static void
dvr_timer_start_recording(void *aux)
dvr_entry_start_recording(dvr_entry_t *de, int clone)
{
dvr_entry_t *de = aux;
int r;

if (de->de_channel == NULL || !de->de_channel->ch_enabled) {
dvr_entry_set_state(de, DVR_NOSTATE, DVR_RS_PENDING, de->de_last_error);
return;
}

// if duplicate, then delete it now, don't record!
if (_dvr_duplicate_event(de)) {
dvr_entry_cancel_delete(de);
return;
}

dvr_entry_set_state(de, DVR_RECORDING, DVR_RS_PENDING, SM_CODE_OK);

tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\" recorder starting",
lang_str_get(de->de_title, NULL), DVR_CH_NAME(de));

if ((r = dvr_rec_subscribe(de)) < 0) {
if (!clone && (r = dvr_rec_subscribe(de)) < 0) {
dvr_entry_completed(de, r == -EPERM ? SM_CODE_USER_ACCESS :
(r == -EOVERFLOW ? SM_CODE_USER_LIMIT :
SM_CODE_BAD_SOURCE));
Expand All @@ -1271,6 +1293,29 @@ dvr_timer_start_recording(void *aux)
}


/**
*
*/
static void
dvr_timer_start_recording(void *aux)
{
dvr_entry_t *de = aux;

if (de->de_channel == NULL || !de->de_channel->ch_enabled) {
dvr_entry_set_state(de, DVR_NOSTATE, DVR_RS_PENDING, de->de_last_error);
return;
}

// if duplicate, then delete it now, don't record!
if (_dvr_duplicate_event(de)) {
dvr_entry_cancel_delete(de);
return;
}

dvr_entry_start_recording(de, 0);
}


/**
*
*/
Expand Down Expand Up @@ -1326,7 +1371,7 @@ static void
dvr_entry_purge(dvr_entry_t *de, int delconf)
{
if(de->de_sched_state == DVR_RECORDING)
dvr_stop_recording(de, SM_CODE_SOURCE_DELETED, delconf);
dvr_stop_recording(de, SM_CODE_SOURCE_DELETED, delconf, 0);
}


Expand Down Expand Up @@ -2455,11 +2500,11 @@ dvr_entry_t *
dvr_entry_stop(dvr_entry_t *de)
{
if(de->de_sched_state == DVR_RECORDING) {
dvr_stop_recording(de, SM_CODE_OK, 1);
dvr_stop_recording(de, SM_CODE_OK, 1, 0);
return de;
}

return dvr_entry_cancel(de);
return de;
}

/**
Expand All @@ -2475,7 +2520,7 @@ dvr_entry_cancel(dvr_entry_t *de)

case DVR_RECORDING:
de->de_dont_reschedule = 1;
dvr_stop_recording(de, SM_CODE_ABORTED, 1);
dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0);
return de;

case DVR_COMPLETED:
Expand All @@ -2502,7 +2547,7 @@ dvr_entry_cancel_delete(dvr_entry_t *de)

case DVR_RECORDING:
de->de_dont_reschedule = 1;
dvr_stop_recording(de, SM_CODE_ABORTED, 1);
dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0);
case DVR_COMPLETED:
dvr_entry_delete(de);
break;
Expand Down Expand Up @@ -2530,7 +2575,7 @@ dvr_entry_init(void)
HTSMSG_FOREACH(f, l) {
if((c = htsmsg_get_map_by_field(f)) == NULL)
continue;
(void)dvr_entry_create(f->hmf_name, c);
(void)dvr_entry_create(f->hmf_name, c, 0);
}
htsmsg_destroy(l);
}
Expand Down
32 changes: 26 additions & 6 deletions src/dvr/dvr_rec.c
Expand Up @@ -164,7 +164,7 @@ dvr_rec_unsubscribe(dvr_entry_t *de)
assert(prch != NULL);

streaming_target_deliver(prch->prch_st, streaming_msg_create(SMT_EXIT));

pthread_join(de->de_thread, NULL);

subscription_unsubscribe(de->de_s, 0);
Expand All @@ -175,6 +175,21 @@ dvr_rec_unsubscribe(dvr_entry_t *de)
free(prch);
}

/**
*
*/
void
dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new)
{
lock_assert(&global_lock);

de_new->de_s = de_old->de_s;
de_new->de_chain = de_old->de_chain;
de_new->de_thread = de_old->de_thread;
de_old->de_s = NULL;
de_old->de_chain = NULL;
de_old->de_thread = 0;
}

/**
* Replace various chars with a dash
Expand Down Expand Up @@ -916,17 +931,18 @@ static void *
dvr_thread(void *aux)
{
dvr_entry_t *de = aux;
dvr_config_t *cfg = de->de_config;
profile_chain_t *prch = de->de_chain;
streaming_queue_t *sq = &prch->prch_sq;
streaming_message_t *sm;
th_subscription_t *ts;
th_pkt_t *pkt;
int run = 1;
int started = 0;
int comm_skip = cfg->dvr_skip_commercials;
int run = 1, started = 0, comm_skip;
int commercial = COMMERCIAL_UNKNOWN;

pthread_mutex_lock(&global_lock);
comm_skip = de->de_config->dvr_skip_commercials;
pthread_mutex_unlock(&global_lock);

pthread_mutex_lock(&sq->sq_mutex);

while(run) {
Expand Down Expand Up @@ -1003,6 +1019,10 @@ dvr_thread(void *aux)
// support reconfiguration of the streams.
dvr_thread_epilog(de);
started = 0;
pthread_mutex_lock(&global_lock);
if (de->de_config->dvr_clone)
de = dvr_entry_clone(de);
pthread_mutex_unlock(&global_lock);
}

if(!started) {
Expand All @@ -1011,7 +1031,7 @@ dvr_thread(void *aux)
if(dvr_rec_start(de, sm->sm_data) == 0)
started = 1;
else
dvr_stop_recording(de, SM_CODE_INVALID_TARGET, 1);
dvr_stop_recording(de, SM_CODE_INVALID_TARGET, 1, 0);
pthread_mutex_unlock(&global_lock);
}
break;
Expand Down

1 comment on commit c05a478

@ksooo
Copy link
Contributor

@ksooo ksooo commented on c05a478 Oct 1, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this fix the problem I mentioned here: fa57953#commitcomment-13453451? Or shall I write a ticket for this?

Please sign in to comment.