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