1 /*
2  *  Digital Video Recorder
3  *  Copyright (C) 2008 Andreas Öman
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef DVR_H
20 #define DVR_H
21 
22 #include <regex.h>
23 #include "epg.h"
24 #include "channels.h"
25 #include "subscriptions.h"
26 #include "muxer.h"
27 #include "profile.h"
28 #include "lang_str.h"
29 #include "tvhvfs.h"
30 
31 #define DVR_MAX_DATA_ERRORS     (10000)
32 
33 #define DVR_FILESIZE_UPDATE     (1<<0)
34 #define DVR_FILESIZE_TOTAL      (1<<1)
35 
36 #define DVR_FINISHED_ALL             (1<<0)
37 #define DVR_FINISHED_SUCCESS         (1<<1)
38 #define DVR_FINISHED_FAILED          (1<<2)
39 #define DVR_FINISHED_REMOVED_SUCCESS (1<<3) /* Removed recording, was succesful before */
40 #define DVR_FINISHED_REMOVED_FAILED  (1<<4) /* Removed recording, was failed before */
41 
42 typedef struct dvr_vfs {
43   LIST_ENTRY(dvr_vfs) link;
44   tvh_fsid_t fsid;
45   uint64_t used_size;
46 } dvr_vfs_t;
47 
48 typedef struct dvr_config {
49   idnode_t dvr_id;
50 
51   LIST_ENTRY(dvr_config) config_link;
52   LIST_ENTRY(dvr_config) profile_link;
53 
54   int dvr_enabled;
55   int dvr_valid;
56   char *dvr_config_name;
57   char *dvr_comment;
58   profile_t *dvr_profile;
59   char *dvr_storage;
60   int dvr_clone;
61   uint32_t dvr_rerecord_errors;
62   uint32_t dvr_retention_days;
63   uint32_t dvr_removal_days;
64   uint32_t dvr_autorec_max_count;
65   uint32_t dvr_autorec_max_sched_count;
66   char *dvr_charset;
67   char *dvr_charset_id;
68   char *dvr_preproc;
69   char *dvr_postproc;
70   char *dvr_postremove;
71   uint32_t dvr_warm_time;
72   uint32_t dvr_extra_time_pre;
73   uint32_t dvr_extra_time_post;
74   uint32_t dvr_update_window;
75   int dvr_running;
76   uint32_t dvr_cleanup_threshold_free;
77   uint32_t dvr_cleanup_threshold_used;
78 
79   muxer_config_t dvr_muxcnf;
80 
81   char *dvr_pathname;
82   int dvr_pathname_changed;
83 
84   int dvr_dir_per_day;
85   int dvr_channel_dir;
86   int dvr_channel_in_title;
87   int dvr_omit_title;
88   int dvr_date_in_title;
89   int dvr_time_in_title;
90   int dvr_whitespace_in_title;
91   int dvr_title_dir;
92   int dvr_episode_in_title;
93   int dvr_clean_title;
94   int dvr_tag_files;
95   int dvr_skip_commercials;
96   int dvr_subtitle_in_title;
97   int dvr_windows_compatible_filenames;
98 
99   struct dvr_entry_list dvr_entries;
100   struct dvr_autorec_entry_list dvr_autorec_entries;
101   struct dvr_timerec_entry_list dvr_timerec_entries;
102 
103   idnode_list_head_t dvr_accesses;
104 
105 } dvr_config_t;
106 
107 typedef enum {
108   DVR_PRIO_IMPORTANT   = 0,
109   DVR_PRIO_HIGH        = 1,
110   DVR_PRIO_NORMAL      = 2,
111   DVR_PRIO_LOW         = 3,
112   DVR_PRIO_UNIMPORTANT = 4,
113   DVR_PRIO_NOTSET      = 5,
114 } dvr_prio_t;
115 
116 typedef enum {
117   DVR_SCHEDULED,         /* Scheduled for recording (in the future) */
118   DVR_RECORDING,
119   DVR_COMPLETED,         /* If recording failed, de->de_error is set to
120 			    a string */
121   DVR_NOSTATE,
122   DVR_MISSED_TIME,
123 } dvr_entry_sched_state_t;
124 
125 
126 typedef enum {
127   DVR_RS_PENDING,
128   DVR_RS_WAIT_PROGRAM_START,
129   DVR_RS_RUNNING,
130   DVR_RS_COMMERCIAL,
131   DVR_RS_ERROR,
132   DVR_RS_EPG_WAIT,
133   DVR_RS_FINISHED
134 } dvr_rs_state_t;
135 
136 typedef enum {
137   DVR_RET_MIN_DISABLED  = 0, /* For dvr config minimal retention only */
138   DVR_RET_REM_DVRCONFIG = 0,
139   DVR_RET_REM_1DAY      = 1,
140   DVR_RET_REM_3DAY      = 3,
141   DVR_RET_REM_5DAY      = 5,
142   DVR_RET_REM_1WEEK     = 7,
143   DVR_RET_REM_2WEEK     = 14,
144   DVR_RET_REM_3WEEK     = 21,
145   DVR_RET_REM_1MONTH    = (30+1),
146   DVR_RET_REM_2MONTH    = (60+2),
147   DVR_RET_REM_3MONTH    = (90+2),
148   DVR_RET_REM_6MONTH    = (180+3),
149   DVR_RET_REM_1YEAR     = (365+1),
150   DVR_RET_REM_2YEARS    = (2*365+1),
151   DVR_RET_REM_3YEARS    = (3*365+1),
152   DVR_RET_ONREMOVE      = INT32_MAX-1, /* For retention only */
153   DVR_REM_SPACE         = INT32_MAX-1, /* For removal only */
154   DVR_RET_REM_FOREVER   = INT32_MAX
155 } dvr_retention_removal_t;
156 
157 typedef struct dvr_entry {
158 
159   idnode_t de_id;
160 
161   int de_refcnt;   /* Modification is protected under global_lock */
162   int de_in_unsubscribe;
163 
164 
165   /**
166    * Upon dvr_entry_remove() this fields will be invalidated (and pointers
167    * NULLed)
168    */
169 
170   LIST_ENTRY(dvr_entry) de_global_link;
171 
172   channel_t *de_channel;
173   LIST_ENTRY(dvr_entry) de_channel_link;
174 
175   char *de_channel_name;
176 
177   gtimer_t de_timer;
178   mtimer_t de_deferred_timer;
179 
180   /**
181    * These meta fields will stay valid as long as reference count > 0
182    */
183 
184   dvr_config_t *de_config;
185   LIST_ENTRY(dvr_entry) de_config_link;
186 
187   int de_enabled;
188 
189   time_t de_start;
190   time_t de_stop;
191 
192   time_t de_start_extra;
193   time_t de_stop_extra;
194   time_t de_segment_stop_extra; /* Automatic extra time for segmented prog (from EPG) */
195 
196   time_t de_running_start;
197   time_t de_running_stop;
198   time_t de_running_pause;
199   int    de_running_change;
200 
201   char *de_owner;
202   char *de_creator;
203   char *de_comment;
204   htsmsg_t *de_files; /* List of all used files */
205   char *de_directory; /* Can be set for autorec entries, will override any
206                          directory setting from the configuration */
207   lang_str_t *de_title;      /* Title in UTF-8 (from EPG) */
208   lang_str_t *de_subtitle;   /* Subtitle in UTF-8 (from EPG) */
209   lang_str_t *de_desc;       /* Description in UTF-8 (from EPG) */
210   uint32_t de_content_type;  /* Content type (from EPG) (only code) */
211 
212   uint16_t de_dvb_eid;
213 
214   int de_pri;
215   int de_dont_reschedule;
216   int de_dont_rerecord;
217   uint32_t de_file_removed;
218   uint32_t de_retention;
219   uint32_t de_removal;
220   uint32_t de_playcount;    /* Recording play count */
221   uint32_t de_playposition; /* Recording last played position in seconds */
222 
223   /**
224    * EPG information / links
225    */
226   epg_broadcast_t *de_bcast;
227   char *de_episode;
228 
229   /**
230    * Major State
231    */
232   dvr_entry_sched_state_t de_sched_state;
233 
234   /**
235    * Recording state (onyl valid if de_sched_state == DVR_RECORDING)
236    */
237   dvr_rs_state_t de_rec_state;
238 
239   /**
240    * Number of errors (only to be modified by the recording thread)
241    */
242   uint32_t de_errors;
243 
244   /**
245    * Number of data errors (only to be modified by the recording thread)
246    */
247   uint32_t de_data_errors;
248 
249   /**
250    * Last error, see SM_CODE_ defines
251    */
252   uint32_t de_last_error;
253 
254 
255   /**
256    * Autorec linkage
257    */
258   LIST_ENTRY(dvr_entry) de_autorec_link;
259   struct dvr_autorec_entry *de_autorec;
260 
261   /**
262    * Timerec linkage
263    */
264   struct dvr_timerec_entry *de_timerec;
265 
266   /**
267    * Parent/child
268    */
269   struct dvr_entry *de_parent;
270   struct dvr_entry *de_child;
271 
272   /**
273    * Fields for recording
274    */
275   pthread_t de_thread;
276   int de_thread_shutdown;
277 
278   th_subscription_t *de_s;
279 
280   /**
281    * Stream worker chain
282    */
283   profile_chain_t *de_chain;
284 
285   /**
286    * Entry change notification timer
287    */
288   int64_t de_last_notify;
289 
290   /**
291    * Update notification limit
292    */
293   tvhlog_limit_t de_update_limit;
294 
295 } dvr_entry_t;
296 
297 #define DVR_CH_NAME(e) ((e)->de_channel == NULL ? (e)->de_channel_name : channel_get_name((e)->de_channel))
298 
299 typedef enum {
300   DVR_AUTOREC_RECORD_ALL = 0,
301   DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER = 1,
302   DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE = 2,
303   DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION = 3,
304   DVR_AUTOREC_RECORD_ONCE_PER_MONTH = 12,
305   DVR_AUTOREC_RECORD_ONCE_PER_WEEK = 4,
306   DVR_AUTOREC_RECORD_ONCE_PER_DAY = 5,
307   DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER = 6,
308   DVR_AUTOREC_LRECORD_DIFFERENT_TITLE = 7,
309   DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE = 8,
310   DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION = 9,
311   DVR_AUTOREC_LRECORD_ONCE_PER_MONTH = 13,
312   DVR_AUTOREC_LRECORD_ONCE_PER_WEEK = 10,
313   DVR_AUTOREC_LRECORD_ONCE_PER_DAY = 11,
314   /* last free value == 14 */
315 } dvr_autorec_dedup_t;
316 
317 typedef enum {
318   DVR_AUTOREC_BTYPE_ALL = 0,
319   DVR_AUTOREC_BTYPE_NEW = 1,
320   DVR_AUTOREC_BTYPE_REPEAT = 2
321 } dvr_autorec_btype_t;
322 
323 /**
324  * Autorec entry
325  */
326 typedef struct dvr_autorec_entry {
327   idnode_t dae_id;
328 
329   TAILQ_ENTRY(dvr_autorec_entry) dae_link;
330 
331   char *dae_name;
332   char *dae_directory;
333   dvr_config_t *dae_config;
334   LIST_ENTRY(dvr_autorec_entry) dae_config_link;
335 
336   int dae_enabled;
337   char *dae_owner;
338   char *dae_creator;
339   char *dae_comment;
340 
341   char *dae_title;
342   regex_t dae_title_preg;
343   int dae_fulltext;
344 
345   uint32_t dae_content_type;
346 
347   int dae_start;        /* Minutes from midnight */
348   int dae_start_window; /* Minutes (duration) */
349 
350   uint32_t dae_weekdays;
351 
352   channel_t *dae_channel;
353   LIST_ENTRY(dvr_autorec_entry) dae_channel_link;
354 
355   channel_tag_t *dae_channel_tag;
356   LIST_ENTRY(dvr_autorec_entry) dae_channel_tag_link;
357 
358   int dae_pri;
359 
360   struct dvr_entry_list dae_spawns;
361 
362   epg_brand_t *dae_brand;
363   epg_season_t *dae_season;
364   epg_serieslink_t *dae_serieslink;
365   epg_episode_num_t dae_epnum;
366 
367   int dae_minduration;
368   int dae_maxduration;
369   uint32_t dae_retention;
370   uint32_t dae_removal;
371   uint32_t dae_btype;
372   uint32_t dae_max_count;
373   uint32_t dae_max_sched_count;
374 
375   time_t dae_start_extra;
376   time_t dae_stop_extra;
377 
378   int dae_record;
379 
380 } dvr_autorec_entry_t;
381 
382 TAILQ_HEAD(dvr_autorec_entry_queue, dvr_autorec_entry);
383 
384 extern struct dvr_autorec_entry_queue autorec_entries;
385 
386 /**
387  * Timerec entry
388  */
389 typedef struct dvr_timerec_entry {
390   idnode_t dte_id;
391 
392   TAILQ_ENTRY(dvr_timerec_entry) dte_link;
393 
394   char *dte_name;
395   char *dte_directory;
396   dvr_config_t *dte_config;
397   LIST_ENTRY(dvr_timerec_entry) dte_config_link;
398 
399   int dte_enabled;
400   char *dte_owner;
401   char *dte_creator;
402   char *dte_comment;
403 
404   char *dte_title;
405 
406   int dte_start;  /* Minutes from midnight */
407   int dte_stop;   /* Minutes from midnight */
408 
409   uint32_t dte_weekdays;
410 
411   channel_t *dte_channel;
412   LIST_ENTRY(dvr_timerec_entry) dte_channel_link;
413 
414   int dte_pri;
415 
416   dvr_entry_t *dte_spawn;
417 
418   uint32_t dte_retention;
419   uint32_t dte_removal;
420 } dvr_timerec_entry_t;
421 
422 TAILQ_HEAD(dvr_timerec_entry_queue, dvr_timerec_entry);
423 
424 extern struct dvr_timerec_entry_queue timerec_entries;
425 
426 /**
427  *
428  */
429 
430 extern const idclass_t dvr_config_class;
431 extern const idclass_t dvr_entry_class;
432 extern const idclass_t dvr_autorec_entry_class;
433 extern const idclass_t dvr_timerec_entry_class;
434 
435 extern struct dvr_vfs_list dvrvfs_list;
436 extern struct dvr_config_list dvrconfigs;
437 extern struct dvr_entry_list dvrentries;
438 
439 /**
440  * Prototypes
441  */
442 
dvr_config_is_valid(dvr_config_t * cfg)443 static inline int dvr_config_is_valid(dvr_config_t *cfg)
444   { return cfg->dvr_valid; }
445 
dvr_config_is_default(dvr_config_t * cfg)446 static inline int dvr_config_is_default(dvr_config_t *cfg)
447   { return tvh_str_default(cfg->dvr_config_name, NULL)  == NULL; }
448 
449 dvr_config_t *dvr_config_find_by_name(const char *name);
450 
451 dvr_config_t *dvr_config_find_by_name_default(const char *name);
452 
453 dvr_config_t *dvr_config_find_by_list(htsmsg_t *list, const char *name);
454 
455 dvr_config_t *dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf);
456 
dvr_config_find_by_uuid(const char * uuid)457 static inline dvr_config_t *dvr_config_find_by_uuid(const char *uuid)
458   { return (dvr_config_t*)idnode_find(uuid, &dvr_config_class, NULL); }
459 
460 void dvr_config_delete(const char *name);
461 
462 void dvr_config_changed(dvr_config_t *cfg);
463 
464 void dvr_config_destroy_by_profile(profile_t *pro, int delconf);
465 
dvr_retention_cleanup(uint32_t val)466 static inline uint32_t dvr_retention_cleanup(uint32_t val)
467 {
468   return val > DVR_RET_REM_FOREVER ? DVR_RET_REM_FOREVER : val;
469 }
470 
471 /*
472  *
473  */
474 
475 uint32_t dvr_usage_count(access_t *aa);
476 
dvr_entry_is_editable(dvr_entry_t * de)477 static inline int dvr_entry_is_editable(dvr_entry_t *de)
478   { return de->de_sched_state == DVR_SCHEDULED; }
479 
dvr_entry_is_valid(dvr_entry_t * de)480 static inline int dvr_entry_is_valid(dvr_entry_t *de)
481   { return de->de_refcnt > 0; }
482 
483 char *dvr_entry_get_retention_string ( dvr_entry_t *de );
484 
485 char *dvr_entry_get_removal_string ( dvr_entry_t *de );
486 
487 uint32_t dvr_entry_get_retention_days( dvr_entry_t *de );
488 
489 uint32_t dvr_entry_get_removal_days( dvr_entry_t *de );
490 
491 uint32_t dvr_entry_get_rerecord_errors( dvr_entry_t *de );
492 
493 int dvr_entry_get_epg_running( dvr_entry_t *de );
494 
495 time_t dvr_entry_get_start_time( dvr_entry_t *de, int warm );
496 
497 time_t dvr_entry_get_stop_time( dvr_entry_t *de );
498 
499 time_t dvr_entry_get_extra_time_post( dvr_entry_t *de );
500 
501 time_t dvr_entry_get_extra_time_pre( dvr_entry_t *de );
502 
503 void dvr_entry_init(void);
504 
505 void dvr_entry_done(void);
506 
507 void dvr_entry_destroy_by_config(dvr_config_t *cfg, int delconf);
508 
509 int dvr_entry_set_state(dvr_entry_t *de, dvr_entry_sched_state_t state,
510                         dvr_rs_state_t rec_state, int error_code);
511 
512 const char *dvr_entry_status(dvr_entry_t *de);
513 
514 const char *dvr_entry_schedstatus(dvr_entry_t *de);
515 
516 void dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_entry_t *dae);
517 
518 void dvr_entry_created(dvr_entry_t *de);
519 
520 dvr_entry_t *
521 dvr_entry_clone ( dvr_entry_t *de );
522 
523 dvr_entry_t *
524 dvr_entry_create ( const char *uuid, htsmsg_t *conf, int clone );
525 
526 
527 dvr_entry_t *
528 dvr_entry_create_by_event( int enabled,
529                            const char *dvr_config_uuid,
530                            epg_broadcast_t *e,
531                            time_t start_extra, time_t stop_extra,
532                            const char *owner, const char *creator,
533                            dvr_autorec_entry_t *dae,
534                            dvr_prio_t pri, int retention, int removal,
535                            const char *comment );
536 
537 dvr_entry_t *
538 dvr_entry_create_htsp( int enabled, const char *dvr_config_uuid,
539                        channel_t *ch, time_t start, time_t stop,
540                        time_t start_extra, time_t stop_extra,
541                        const char *title, const char *subtitle,
542                        const char *description,
543                        const char *lang, epg_genre_t *content_type,
544                        const char *owner, const char *creator,
545                        dvr_autorec_entry_t *dae,
546                        dvr_prio_t pri, int retention, int removal,
547                        const char *comment );
548 
549 dvr_entry_t *
550 dvr_entry_update( dvr_entry_t *de, int enabled,
551                   const char *dvr_config_uuid, channel_t *ch,
552                   const char *title, const char *subtitle,
553                   const char *desc, const char *lang,
554                   time_t start, time_t stop,
555                   time_t start_extra, time_t stop_extra,
556                   dvr_prio_t pri, int retention, int removal,
557                   int playcount, int playposition);
558 
559 void dvr_destroy_by_channel(channel_t *ch, int delconf);
560 
561 void dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone);
562 
563 int dvr_rec_subscribe(dvr_entry_t *de);
564 
565 void dvr_rec_unsubscribe(dvr_entry_t *de);
566 
567 void dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new);
568 
569 void dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e);
570 
571 void dvr_event_removed(epg_broadcast_t *e);
572 
573 void dvr_event_updated(epg_broadcast_t *e);
574 
575 void dvr_event_running(epg_broadcast_t *e, epg_source_t esrc, epg_running_t running);
576 
577 dvr_entry_t *dvr_entry_find_by_id(int id);
578 
dvr_entry_find_by_uuid(const char * uuid)579 static inline dvr_entry_t *dvr_entry_find_by_uuid(const char *uuid)
580   { return (dvr_entry_t*)idnode_find(uuid, &dvr_entry_class, NULL); }
581 
582 dvr_entry_t *dvr_entry_find_by_event_fuzzy(epg_broadcast_t *e);
583 
584 const char *dvr_get_filename(dvr_entry_t *de);
585 
586 int64_t dvr_get_filesize(dvr_entry_t *de, int flags);
587 
588 int64_t dvr_entry_claenup(dvr_entry_t *de, int64_t requiredBytes);
589 
590 void dvr_entry_set_rerecord(dvr_entry_t *de, int cmd);
591 
592 void dvr_entry_move(dvr_entry_t *de, int to_failed);
593 
594 dvr_entry_t *dvr_entry_stop(dvr_entry_t *de);
595 
596 dvr_entry_t *dvr_entry_cancel(dvr_entry_t *de, int rerecord);
597 
598 void dvr_entry_dec_ref(dvr_entry_t *de);
599 
600 int dvr_entry_delete(dvr_entry_t *de);
601 
602 void dvr_entry_cancel_delete(dvr_entry_t *de, int rerecord);
603 
604 void dvr_entry_cancel_remove(dvr_entry_t *de, int rerecord);
605 
606 int dvr_entry_file_moved(const char *src, const char *dst);
607 
608 void dvr_entry_destroy(dvr_entry_t *de, int delconf);
609 
610 htsmsg_t *dvr_entry_class_mc_list (void *o, const char *lang);
611 htsmsg_t *dvr_entry_class_pri_list(void *o, const char *lang);
612 htsmsg_t *dvr_entry_class_config_name_list(void *o, const char *lang);
613 htsmsg_t *dvr_entry_class_duration_list(void *o, const char *not_set, int max, int step, const char *lang);
614 htsmsg_t *dvr_entry_class_retention_list ( void *o, const char *lang );
615 htsmsg_t *dvr_entry_class_removal_list ( void *o, const char *lang );
616 
617 int dvr_entry_is_upcoming(dvr_entry_t *entry);
618 int dvr_entry_is_finished(dvr_entry_t *entry, int flags);
619 int dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly);
620 
621 void dvr_entry_changed_notify(dvr_entry_t *de);
622 
623 void dvr_spawn_cmd(dvr_entry_t *de, const char *cmd, const char *filename, int pre);
624 
625 void dvr_vfs_refresh_entry(dvr_entry_t *de);
626 void dvr_vfs_remove_entry(dvr_entry_t *de);
627 int64_t dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata);
628 int64_t dvr_vfs_rec_start_check(dvr_config_t *cfg);
629 
630 void dvr_disk_space_boot(void);
631 void dvr_disk_space_init(void);
632 void dvr_disk_space_done(void);
633 int dvr_get_disk_space(int64_t *bfree, int64_t *bused, int64_t *btotal);
634 
635 /**
636  *
637  */
638 
639 dvr_autorec_entry_t *
640 dvr_autorec_create(const char *uuid, htsmsg_t *conf);
641 
642 dvr_entry_t *
643 dvr_entry_create_(int enabled, const char *config_uuid, epg_broadcast_t *e,
644                   channel_t *ch, time_t start, time_t stop,
645                   time_t start_extra, time_t stop_extra,
646                   const char *title, const char* subtitle, const char *description,
647                   const char *lang, epg_genre_t *content_type,
648                   const char *owner, const char *creator,
649                   dvr_autorec_entry_t *dae, dvr_timerec_entry_t *tae,
650                   dvr_prio_t pri, int retention, int removal, const char *comment);
651 
652 dvr_autorec_entry_t *
653 dvr_autorec_create_htsp(htsmsg_t *conf);
654 
655 void dvr_autorec_update_htsp(dvr_autorec_entry_t *dae, htsmsg_t *conf);
656 
657 dvr_autorec_entry_t *
658 dvr_autorec_add_series_link(const char *dvr_config_name,
659                             epg_broadcast_t *event,
660                             const char *owner, const char *creator,
661                             const char *comment);
662 
663 void dvr_autorec_changed(dvr_autorec_entry_t *dae, int purge);
664 
665 static inline dvr_autorec_entry_t *
dvr_autorec_find_by_uuid(const char * uuid)666 dvr_autorec_find_by_uuid(const char *uuid)
667   { return (dvr_autorec_entry_t*)idnode_find(uuid, &dvr_autorec_entry_class, NULL); }
668 
669 
670 htsmsg_t * dvr_autorec_entry_class_time_list(void *o, const char *null);
671 htsmsg_t * dvr_autorec_entry_class_weekdays_get(uint32_t weekdays);
672 htsmsg_t * dvr_autorec_entry_class_weekdays_list (void *o, const char *list);
673 char * dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char *lang);
674 
675 void dvr_autorec_check_event(epg_broadcast_t *e);
676 void dvr_autorec_check_brand(epg_brand_t *b);
677 void dvr_autorec_check_season(epg_season_t *s);
678 void dvr_autorec_check_serieslink(epg_serieslink_t *s);
679 
680 void autorec_destroy_by_config(dvr_config_t *cfg, int delconf);
681 
682 void autorec_destroy_by_channel(channel_t *ch, int delconf);
683 
684 void autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf);
685 
686 void autorec_destroy_by_id(const char *id, int delconf);
687 
688 void dvr_autorec_init(void);
689 
690 void dvr_autorec_done(void);
691 
692 void dvr_autorec_update(void);
693 
694 static inline int
dvr_autorec_entry_verify(dvr_autorec_entry_t * dae,access_t * a,int readonly)695   dvr_autorec_entry_verify(dvr_autorec_entry_t *dae, access_t *a, int readonly)
696 {
697   if (readonly && !access_verify2(a, ACCESS_ALL_RECORDER))
698     return 0;
699   if (!access_verify2(a, ACCESS_ALL_RW_RECORDER))
700     return 0;
701   if (strcmp(dae->dae_owner ?: "", a->aa_username ?: ""))
702     return -1;
703   return 0;
704 }
705 
706 uint32_t dvr_autorec_get_retention_days( dvr_autorec_entry_t *dae );
707 
708 uint32_t dvr_autorec_get_removal_days( dvr_autorec_entry_t *dae );
709 
710 int dvr_autorec_get_extra_time_post( dvr_autorec_entry_t *dae );
711 
712 int dvr_autorec_get_extra_time_pre( dvr_autorec_entry_t *dae );
713 
714 void dvr_autorec_completed( dvr_autorec_entry_t *dae, int error_code );
715 
716 uint32_t dvr_autorec_get_max_sched_count(dvr_autorec_entry_t *dae);
717 
718 /**
719  *
720  */
721 
722 dvr_timerec_entry_t *
723 dvr_timerec_create(const char *uuid, htsmsg_t *conf);
724 
725 dvr_timerec_entry_t*
726 dvr_timerec_create_htsp(htsmsg_t *conf);
727 
728 void dvr_timerec_update_htsp(dvr_timerec_entry_t *dte, htsmsg_t *conf);
729 
730 static inline dvr_timerec_entry_t *
dvr_timerec_find_by_uuid(const char * uuid)731 dvr_timerec_find_by_uuid(const char *uuid)
732   { return (dvr_timerec_entry_t*)idnode_find(uuid, &dvr_timerec_entry_class, NULL); }
733 
734 
735 void dvr_timerec_check(dvr_timerec_entry_t *dae);
736 
737 void timerec_destroy_by_config(dvr_config_t *cfg, int delconf);
738 
739 void timerec_destroy_by_channel(channel_t *ch, int delconf);
740 
741 void timerec_destroy_by_id(const char *id, int delconf);
742 
743 void dvr_timerec_init(void);
744 
745 void dvr_timerec_done(void);
746 
747 void dvr_timerec_update(void);
748 
dvr_timerec_entry_verify(dvr_timerec_entry_t * dte,access_t * a,int readonly)749 static inline int dvr_timerec_entry_verify
750   (dvr_timerec_entry_t *dte, access_t *a, int readonly)
751 {
752   if (readonly && !access_verify2(a, ACCESS_ALL_RECORDER))
753     return 0;
754   if (!access_verify2(a, ACCESS_ALL_RW_RECORDER))
755     return 0;
756   if (strcmp(dte->dte_owner ?: "", a->aa_username ?: ""))
757     return -1;
758   return 0;
759 }
760 
761 uint32_t dvr_timerec_get_retention_days( dvr_timerec_entry_t *dte );
762 
763 uint32_t dvr_timerec_get_removal_days( dvr_timerec_entry_t *dte );
764 
765 /**
766  *
767  */
768 dvr_prio_t dvr_pri2val(const char *s);
769 
770 const char *dvr_val2pri(dvr_prio_t v);
771 
772 /**
773  * Inotify support
774  */
775 void dvr_inotify_init ( void );
776 void dvr_inotify_done ( void );
777 void dvr_inotify_add  ( dvr_entry_t *de );
778 void dvr_inotify_del  ( dvr_entry_t *de );
779 int  dvr_inotify_count( void );
780 
781 /**
782  * Cutpoints support
783  **/
784 
785 typedef struct dvr_cutpoint {
786   TAILQ_ENTRY(dvr_cutpoint) dc_link;
787   uint64_t dc_start_ms;
788   uint64_t dc_end_ms;
789   enum {
790     DVR_CP_CUT,
791     DVR_CP_MUTE,
792     DVR_CP_SCENE,
793     DVR_CP_COMM
794   } dc_type;
795 } dvr_cutpoint_t;
796 
797 typedef TAILQ_HEAD(,dvr_cutpoint) dvr_cutpoint_list_t;
798 
799 dvr_cutpoint_list_t *dvr_get_cutpoint_list (dvr_entry_t *de);
800 void dvr_cutpoint_list_destroy (dvr_cutpoint_list_t *list);
801 
802 /**
803  *
804  */
805 
806 const char *dvr_entry_sched_state2str(dvr_entry_sched_state_t s);
807 const char *dvr_entry_rs_state2str(dvr_rs_state_t s);
808 
809 void dvr_entry_trace_(const char *file, int line,
810                       dvr_entry_t *de, const char *fmt, ...);
811 
812 void dvr_entry_trace_time2_(const char *file, int line,
813                             dvr_entry_t *de,
814                             const char *t1name, time_t t1,
815                             const char *t2name, time_t t2,
816                             const char *fmt, ...);
817 
818 #define dvr_entry_trace(de, fmt, ...) \
819   do { \
820     if (tvhtrace_enabled()) \
821       dvr_entry_trace_(__FILE__, __LINE__, de, fmt, ##__VA_ARGS__); \
822   } while (0)
823 
824 #define dvr_entry_trace_time1(de, t1name, t1, fmt, ...) \
825   dvr_entry_trace_time2(de, t1name, t1, NULL, 0, fmt, ##__VA_ARGS__)
826 
827 #define dvr_entry_trace_time2(de, t1name, t1, t2name, t2, fmt, ...) \
828   do { \
829     if (tvhtrace_enabled()) \
830       dvr_entry_trace_time2_(__FILE__, __LINE__, de, t1name, t1, \
831                              t2name, t2, fmt, ##__VA_ARGS__); \
832   } while (0)
833 
834 /**
835  *
836  */
837 
838 void dvr_init(void);
839 void dvr_config_init(void);
840 
841 void dvr_done(void);
842 
843 
844 #endif /* DVR_H  */
845