Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
DVR: Time Based Recorder
  • Loading branch information
perexg committed Sep 15, 2014
1 parent d7b7f72 commit 6de4fb9
Show file tree
Hide file tree
Showing 11 changed files with 937 additions and 92 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -178,6 +178,7 @@ SRCS += src/plumbing/tsfix.c \
SRCS += src/dvr/dvr_db.c \
src/dvr/dvr_rec.c \
src/dvr/dvr_autorec.c \
src/dvr/dvr_timerec.c \
src/dvr/dvr_cutpoints.c \

SRCS += src/webui/webui.c \
Expand Down
10 changes: 10 additions & 0 deletions docs/html/config_dvrtime.html
@@ -0,0 +1,10 @@
<div class="hts-doc-text">

<p>
This tab is used to manipulate with the Digital Video Recorder entries -
the time-based automatic recording.

<p>
A volunteer required to fill this...

</div>
38 changes: 38 additions & 0 deletions src/api/api_dvr.c
Expand Up @@ -330,6 +330,40 @@ api_dvr_autorec_create_by_series
return !count ? EINVAL : 0;
}

static void
api_dvr_timerec_grid
( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args )
{
dvr_timerec_entry_t *dte;

TAILQ_FOREACH(dte, &timerec_entries, dte_link)
idnode_set_add(ins, (idnode_t*)dte, &conf->filter);
}

static int
api_dvr_timerec_create
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
htsmsg_t *conf;
dvr_timerec_entry_t *dte;

if (!(conf = htsmsg_get_map(args, "conf")))
return EINVAL;

if (perm->aa_representative)
htsmsg_set_str(conf, "creator", perm->aa_representative);

pthread_mutex_lock(&global_lock);
dte = dvr_timerec_create(NULL, conf);
if (dte) {
dvr_timerec_save(dte);
dvr_timerec_check(dte);
}
pthread_mutex_unlock(&global_lock);

return 0;
}

void api_dvr_init ( void )
{
static api_hook_t ah[] = {
Expand All @@ -351,6 +385,10 @@ void api_dvr_init ( void )
{ "dvr/autorec/create", ACCESS_RECORDER, api_dvr_autorec_create, NULL },
{ "dvr/autorec/create_by_series", ACCESS_RECORDER, api_dvr_autorec_create_by_series, NULL },

{ "dvr/timerec/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_timerec_entry_class },
{ "dvr/timerec/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_timerec_grid },
{ "dvr/timerec/create", ACCESS_RECORDER, api_dvr_timerec_create, NULL },

{ NULL },
};

Expand Down
18 changes: 18 additions & 0 deletions src/channels.c
Expand Up @@ -197,6 +197,17 @@ channel_class_get_title ( idnode_t *self )
return channel_get_name((channel_t*)self);
}

/* exported for others */
htsmsg_t *
channel_class_get_list(void *o)
{
htsmsg_t *m = htsmsg_create_map();
htsmsg_add_str(m, "type", "api");
htsmsg_add_str(m, "uri", "channel/list");
htsmsg_add_str(m, "event", "channel");
return m;
}

static const void *
channel_class_get_name ( void *p )
{
Expand Down Expand Up @@ -531,6 +542,12 @@ channel_create0
{
lock_assert(&global_lock);

LIST_INIT(&ch->ch_services);
LIST_INIT(&ch->ch_subscriptions);
LIST_INIT(&ch->ch_epggrab);
LIST_INIT(&ch->ch_autorecs);
LIST_INIT(&ch->ch_timerecs);

if (idnode_insert(&ch->ch_id, uuid, idc, IDNODE_SHORT_UUID)) {
if (uuid)
tvherror("channel", "invalid uuid '%s'", uuid);
Expand Down Expand Up @@ -578,6 +595,7 @@ channel_delete ( channel_t *ch, int delconf )

/* DVR */
autorec_destroy_by_channel(ch, delconf);
timerec_destroy_by_channel(ch, delconf);
dvr_destroy_by_channel(ch, delconf);

/* Services */
Expand Down
3 changes: 3 additions & 0 deletions src/channels.h
Expand Up @@ -71,6 +71,7 @@ typedef struct channel
int ch_dvr_extra_time_post;
struct dvr_entry_list ch_dvrs;
struct dvr_autorec_entry_list ch_autorecs;
struct dvr_timerec_entry_list ch_timerecs;

} channel_t;

Expand Down Expand Up @@ -152,6 +153,8 @@ channel_t *channel_find_by_number(int no);

#define channel_find channel_find_by_uuid

htsmsg_t * channel_class_get_list(void *o);

int channel_set_tags_by_list ( channel_t *ch, htsmsg_t *tags );
int channel_set_services_by_list ( channel_t *ch, htsmsg_t *svcs );

Expand Down
97 changes: 89 additions & 8 deletions src/dvr/dvr.h
Expand Up @@ -194,6 +194,11 @@ typedef struct dvr_entry {
LIST_ENTRY(dvr_entry) de_autorec_link;
struct dvr_autorec_entry *de_autorec;

/**
* Timerec linkage
*/
struct dvr_timerec_entry *de_timerec;

/**
* Fields for recording
*/
Expand Down Expand Up @@ -251,7 +256,7 @@ typedef struct dvr_autorec_entry {
channel_tag_t *dae_channel_tag;
LIST_ENTRY(dvr_autorec_entry) dae_channel_tag_link;

dvr_prio_t dae_pri;
int dae_pri;

struct dvr_entry_list dae_spawns;

Expand All @@ -272,13 +277,50 @@ TAILQ_HEAD(dvr_autorec_entry_queue, dvr_autorec_entry);

extern struct dvr_autorec_entry_queue autorec_entries;

/**
* Timerec entry
*/
typedef struct dvr_timerec_entry {
idnode_t dte_id;

TAILQ_ENTRY(dvr_timerec_entry) dte_link;

char *dte_name;
char *dte_config_name;

int dte_enabled;
char *dte_creator;
char *dte_comment;

char *dte_title;

int dte_start; /* Minutes from midnight */
int dte_stop; /* Minutes from midnight */

uint32_t dte_weekdays;

channel_t *dte_channel;
LIST_ENTRY(dvr_timerec_entry) dte_channel_link;

int dte_pri;

dvr_entry_t *dte_spawn;

int dte_retention;
} dvr_timerec_entry_t;

TAILQ_HEAD(dvr_timerec_entry_queue, dvr_timerec_entry);

extern struct dvr_timerec_entry_queue timerec_entries;

/**
*
*/

extern const idclass_t dvr_config_class;
extern const idclass_t dvr_entry_class;
extern const idclass_t dvr_autorec_entry_class;
extern const idclass_t dvr_timerec_entry_class;

/**
* Prototypes
Expand Down Expand Up @@ -366,12 +408,6 @@ void dvr_config_init(void);

void dvr_done(void);

void dvr_autorec_init(void);

void dvr_autorec_done(void);

void dvr_autorec_update(void);

void dvr_destroy_by_channel(channel_t *ch, int delconf);

void dvr_rec_subscribe(dvr_entry_t *de);
Expand Down Expand Up @@ -436,6 +472,16 @@ int dvr_sort_start_ascending(const void *A, const void *B);
dvr_autorec_entry_t *
dvr_autorec_create(const char *uuid, htsmsg_t *conf);

dvr_entry_t *
dvr_entry_create_(const char *config_uuid, epg_broadcast_t *e,
channel_t *ch, time_t start, time_t stop,
time_t start_extra, time_t stop_extra,
const char *title, const char *description,
const char *lang, epg_genre_t *content_type,
const char *creator, dvr_autorec_entry_t *dae,
dvr_timerec_entry_t *tae,
dvr_prio_t pri, int retention);

dvr_autorec_entry_t*
dvr_autorec_create_htsp(const char *dvr_config_name, const char *title,
channel_t *ch, uint32_t aroundTime, uint32_t days,
Expand All @@ -458,18 +504,53 @@ dvr_autorec_find_by_uuid(const char *uuid)
{ return (dvr_autorec_entry_t*)idnode_find(uuid, &dvr_autorec_entry_class); }


htsmsg_t * dvr_autorec_entry_class_time_list(void *o, const char *null);
htsmsg_t * dvr_autorec_entry_class_weekdays_list ( void *o );
char * dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays);

void dvr_autorec_check_event(epg_broadcast_t *e);
void dvr_autorec_check_brand(epg_brand_t *b);
void dvr_autorec_check_season(epg_season_t *s);
void dvr_autorec_check_serieslink(epg_serieslink_t *s);


void autorec_destroy_by_channel(channel_t *ch, int delconf);

void autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf);

void autorec_destroy_by_id(const char *id, int delconf);

void dvr_autorec_init(void);

void dvr_autorec_done(void);

void dvr_autorec_update(void);

/**
*
*/

dvr_timerec_entry_t *
dvr_timerec_create(const char *uuid, htsmsg_t *conf);

static inline dvr_timerec_entry_t *
dvr_timerec_find_by_uuid(const char *uuid)
{ return (dvr_timerec_entry_t*)idnode_find(uuid, &dvr_timerec_entry_class); }


void dvr_timerec_save(dvr_timerec_entry_t *dae);

void dvr_timerec_check(dvr_timerec_entry_t *dae);

void timerec_destroy_by_channel(channel_t *ch, int delconf);

void timerec_destroy_by_id(const char *id, int delconf);

void dvr_timerec_init(void);

void dvr_timerec_done(void);

void dvr_timerec_update(void);

/**
*
*/
Expand Down

0 comments on commit 6de4fb9

Please sign in to comment.