char *dvr_file_postfix;
uint32_t dvr_retention_days;
int dvr_flags;
+int dvr_extra_time_pre;
+int dvr_extra_time_post;
char *dvr_postproc;
static int de_tally;
time(&now);
- preamble = de->de_start - 30;
+ preamble = de->de_start - (60 * de->de_start_extra) - 30;
if(now >= de->de_stop || de->de_dont_reschedule) {
de->de_sched_state = DVR_COMPLETED;
dvr_entry_t *de;
char tbuf[30];
struct tm tm;
+ time_t t;
if(e->e_channel == NULL || e->e_title == NULL)
return NULL;
de->de_start = e->e_start;
de->de_stop = e->e_stop;
-
+ de->de_start_extra = dvr_extra_time_pre;
+ de->de_stop_extra = dvr_extra_time_post;
de->de_creator = strdup(creator);
de->de_title = strdup(e->e_title);
de->de_desc = e->e_desc ? strdup(e->e_desc) : NULL;
dvr_entry_link(de);
- localtime_r(&de->de_start, &tm);
+ t = de->de_start - de->de_start_extra;
+ localtime_r(&t, &tm);
strftime(tbuf, sizeof(tbuf), "%c", &tm);
tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\" starting at %s, "
const char *s, *title, *creator;
channel_t *ch;
uint32_t start, stop;
+ int d;
if(htsmsg_get_u32(c, "start", &start))
return;
de->de_creator = strdup(creator);
de->de_title = strdup(title);
+
+
+ if(htsmsg_get_s32(c, "start_extra", &d))
+ de->de_start_extra = dvr_extra_time_pre;
+ else
+ de->de_start_extra = d;
+
+ if(htsmsg_get_s32(c, "stop_extra", &d))
+ de->de_stop_extra = dvr_extra_time_post;
+ else
+ de->de_stop_extra = d;
+
tvh_str_set(&de->de_desc, htsmsg_get_str(c, "description"));
tvh_str_set(&de->de_filename, htsmsg_get_str(c, "filename"));
tvh_str_set(&de->de_error, htsmsg_get_str(c, "error"));
htsmsg_add_str(m, "channel", de->de_channel->ch_name);
htsmsg_add_u32(m, "start", de->de_start);
htsmsg_add_u32(m, "stop", de->de_stop);
+
+ htsmsg_add_s32(m, "start_extra", de->de_start_extra);
+ htsmsg_add_s32(m, "stop_extra", de->de_stop_extra);
htsmsg_add_str(m, "creator", de->de_creator);
dvr_rec_subscribe(de);
- gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de, de->de_stop);
+ gtimer_arm_abs(&de->de_timer, dvr_timer_stop_recording, de,
+ de->de_stop + (60 * de->de_stop_extra));
}
/* Override settings with config */
if((m = hts_settings_load("dvr/config")) != NULL) {
+
+ htsmsg_get_s32(m, "pre-extra-time", &dvr_extra_time_pre);
+ htsmsg_get_s32(m, "post-extra-time", &dvr_extra_time_post);
htsmsg_get_u32(m, "retention-days", &dvr_retention_days);
tvh_str_set(&dvr_storage, htsmsg_get_str(m, "storage"));
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_str(m, "storage", dvr_storage);
htsmsg_add_u32(m, "retention-days", dvr_retention_days);
+ htsmsg_add_u32(m, "pre-extra-time", dvr_extra_time_pre);
+ htsmsg_add_u32(m, "post-extra-time", dvr_extra_time_post);
htsmsg_add_u32(m, "day-dir", !!(dvr_flags & DVR_DIR_PER_DAY));
htsmsg_add_u32(m, "channel-dir", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
htsmsg_add_u32(m, "channel-in-title", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
}
+/**
+ *
+ */
+void
+dvr_extra_time_pre_set(int d)
+{
+ if(dvr_extra_time_pre == d)
+ return;
+ dvr_extra_time_pre = d;
+ dvr_save();
+}
+
+
+/**
+ *
+ */
+void
+dvr_extra_time_post_set(int d)
+{
+ if(dvr_extra_time_post == d)
+ return;
+ dvr_extra_time_post = d;
+ dvr_save();
+}
+
+
/**
*
*/
switch(sm->sm_type) {
case SMT_PACKET:
- if(dispatch_clock > de->de_start)
+ if(dispatch_clock > de->de_start - (60 * de->de_start_extra))
dvr_thread_new_pkt(de, sm->sm_data);
pkt_ref_dec(sm->sm_data);
break;
/**
*
*/
-static void dvr_spawn_postproc(dvr_entry_t *de)
+static void
+dvr_spawn_postproc(dvr_entry_t *de)
{
char *fmap[256];
char **args;
}
fbasename = strdup(de->de_filename);
- snprintf(start, sizeof(start), "%ld", de->de_start);
- snprintf(stop, sizeof(stop), "%ld", de->de_stop);
+ snprintf(start, sizeof(start), "%ld", de->de_start - de->de_start_extra);
+ snprintf(stop, sizeof(stop), "%ld", de->de_stop + de->de_stop_extra);
memset(fmap, 0, sizeof(fmap));
fmap['f'] = de->de_filename; /* full path to recoding */
if(dvr_postproc != NULL)
htsmsg_add_str(r, "postproc", dvr_postproc);
htsmsg_add_u32(r, "retention", dvr_retention_days);
+ htsmsg_add_u32(r, "preExtraTime", dvr_extra_time_pre);
+ htsmsg_add_u32(r, "postExtraTime", dvr_extra_time_post);
htsmsg_add_u32(r, "dayDirs", !!(dvr_flags & DVR_DIR_PER_DAY));
htsmsg_add_u32(r, "channelDirs", !!(dvr_flags & DVR_DIR_PER_CHANNEL));
htsmsg_add_u32(r, "channelInTitle", !!(dvr_flags & DVR_CHANNEL_IN_TITLE));
if((s = http_arg_get(&hc->hc_req_args, "retention")) != NULL)
dvr_retention_set(atoi(s));
+ if((s = http_arg_get(&hc->hc_req_args, "preExtraTime")) != NULL)
+ dvr_extra_time_pre_set(atoi(s));
+
+ if((s = http_arg_get(&hc->hc_req_args, "postExtraTime")) != NULL)
+ dvr_extra_time_post_set(atoi(s));
+
if(http_arg_get(&hc->hc_req_args, "dayDirs") != NULL)
flags |= DVR_DIR_PER_DAY;
if(http_arg_get(&hc->hc_req_args, "channelDirs") != NULL)
root: 'dvrSettings'
}, ['storage','postproc','retention','dayDirs',
'channelDirs','channelInTitle',
- 'dateInTitle','timeInTitle']);
+ 'dateInTitle','timeInTitle',
+ 'preExtraTime', 'postExtraTime']);
var confpanel = new Ext.FormPanel({
title:'Digital Video Recorder',
bodyStyle:'padding:15px',
anchor: '100% 50%',
labelAlign: 'right',
- labelWidth: 200,
+ labelWidth: 250,
waitMsgTarget: true,
reader: confreader,
defaultType: 'textfield',
minValue: 1,
fieldLabel: 'DVR Log retention time (days)',
name: 'retention'
+ }), new Ext.form.NumberField({
+ allowDecimals: false,
+ fieldLabel: 'Extra time before recordings (minutes)',
+ name: 'preExtraTime'
+ }), new Ext.form.NumberField({
+ allowDecimals: false,
+ fieldLabel: 'Extra time after recordings (minutes)',
+ name: 'postExtraTime'
}), new Ext.form.Checkbox({
fieldLabel: 'Make subdirectories per day',
name: 'dayDirs'