Changeset 4332

Show
Ignore:
Timestamp:
03/16/10 20:54:45 (6 months ago)
Author:
andoma
Message:
  • Inject entries in DVR schedule as soon as we know about an EPG entry that matches an autorecording rule. Previously Tvheadend would scan the EPG continously and just grab shows as they neared air time. The drawbacks of this approach was that it's a bit hard to understand what is happening. It also makes (more) correct wakeup from suspend hard to do.
Location:
trunk/tvheadend
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • trunk/tvheadend/debian/changelog

    r4274 r4332  
    88    written to disk as Tvheadend tunes to it. This should aid a lot when 
    99    it comes to debugging 
     10 
     11  * Inject entries in DVR schedule as soon as we know about an EPG 
     12    entry that matches an autorecording rule. Previously Tvheadend 
     13    would scan the EPG continously and just grab shows as they neared 
     14    air time.  The drawbacks of this approach was that it's a bit hard 
     15    to understand what is happening. It also makes (more) correct 
     16    wakeup from suspend hard to do. 
    1017 
    1118hts-tvheadend (2.10) hts; urgency=high 
  • trunk/tvheadend/src/dvr/dvr.h

    r4315 r4332  
    2121 
    2222#include <libavformat/avformat.h> 
     23#include <regex.h> 
    2324#include "epg.h" 
    2425#include "channels.h" 
     
    9899   
    99100  /** 
     101   * Autorec linkage 
     102   */ 
     103  LIST_ENTRY(dvr_entry) de_autorec_link; 
     104  struct dvr_autorec_entry *de_autorec; 
     105 
     106  /** 
    100107   * Fields for recording 
    101108   */ 
     
    130137} dvr_entry_t; 
    131138 
     139 
     140/** 
     141 * Autorec entry 
     142 */ 
     143typedef struct dvr_autorec_entry { 
     144  TAILQ_ENTRY(dvr_autorec_entry) dae_link; 
     145  char *dae_id; 
     146 
     147  int dae_enabled; 
     148  char *dae_creator; 
     149  char *dae_comment; 
     150 
     151  char *dae_title; 
     152  regex_t dae_title_preg; 
     153   
     154  epg_content_group_t *dae_ecg; 
     155 
     156  int dae_weekdays; 
     157 
     158  channel_t *dae_channel; 
     159  LIST_ENTRY(dvr_autorec_entry) dae_channel_link; 
     160 
     161  channel_tag_t *dae_channel_tag; 
     162  LIST_ENTRY(dvr_autorec_entry) dae_channel_tag_link; 
     163 
     164  struct dvr_entry_list dae_spawns; 
     165 
     166} dvr_autorec_entry_t; 
     167 
     168 
    132169/** 
    133170 * Prototypes 
    134171 */ 
    135 dvr_entry_t *dvr_entry_create_by_event(event_t *e, const char *creator); 
     172void dvr_entry_create_by_autorec(event_t *e, dvr_autorec_entry_t *dae); 
     173 
     174dvr_entry_t *dvr_entry_create_by_event(event_t *e, const char *creator, 
     175                                       dvr_autorec_entry_t *dae); 
    136176 
    137177dvr_entry_t *dvr_entry_create(channel_t *ch, time_t start, time_t stop,  
    138178                              const char *title, const char *description, 
    139                               const char *creator); 
     179                              const char *creator, dvr_autorec_entry_t *dae); 
    140180 
    141181void dvr_init(void); 
     
    191231                     const char *creator, const char *comment); 
    192232 
    193 void dvr_autorec_check(event_t *e); 
     233void dvr_autorec_check_event(event_t *e); 
    194234 
    195235void autorec_destroy_by_channel(channel_t *ch); 
    196236 
     237dvr_autorec_entry_t *autorec_entry_find(const char *id, int create); 
     238 
    197239#endif /* DVR_H  */ 
  • trunk/tvheadend/src/dvr/dvr_autorec.c

    r4183 r4332  
    2626#include <stdarg.h> 
    2727#include <errno.h> 
    28 #include <regex.h> 
    29  
    3028 
    3129#include "tvhead.h" 
     
    4240struct dvr_autorec_entry_queue autorec_entries; 
    4341 
    44 typedef struct dvr_autorec_entry { 
    45   TAILQ_ENTRY(dvr_autorec_entry) dae_link; 
    46   char *dae_id; 
    47  
    48   int dae_enabled; 
    49   char *dae_creator; 
    50   char *dae_comment; 
    51  
    52   char *dae_title; 
    53   regex_t dae_title_preg; 
    54    
    55   epg_content_group_t *dae_ecg; 
    56  
    57   int dae_weekdays; 
    58  
    59   channel_t *dae_channel; 
    60   LIST_ENTRY(dvr_autorec_entry) dae_channel_link; 
    61  
    62   channel_tag_t *dae_channel_tag; 
    63   LIST_ENTRY(dvr_autorec_entry) dae_channel_tag_link; 
    64  
    65 } dvr_autorec_entry_t; 
    66  
    67 static void dvr_autorec_check_just_enabled(dvr_autorec_entry_t *dae); 
    68  
     42static void dvr_autorec_changed(dvr_autorec_entry_t *dae); 
     43 
     44/** 
     45 * 
     46 */ 
     47static void 
     48dvr_autorec_purge_spawns(dvr_autorec_entry_t *dae) 
     49{ 
     50  dvr_entry_t *de; 
     51 
     52  while((de = LIST_FIRST(&dae->dae_spawns)) != NULL) { 
     53    LIST_REMOVE(de, de_autorec_link); 
     54    de->de_autorec = NULL; 
     55    dvr_entry_cancel(de); 
     56  } 
     57} 
    6958 
    7059 
     
    9988  } 
    10089   
    101   if(dae->dae_title != NULL && e->e_title != NULL && 
    102      regexec(&dae->dae_title_preg, e->e_title, 0, NULL, 0)) 
     90  if(dae->dae_title != NULL) { 
     91    if(e->e_title == NULL || 
     92       regexec(&dae->dae_title_preg, e->e_title, 0, NULL, 0)) 
    10393    return 0; 
     94  } 
    10495 
    10596  if(dae->dae_weekdays != 0x7f) { 
     
    116107 * 
    117108 */ 
    118 static dvr_autorec_entry_t * 
     109dvr_autorec_entry_t * 
    119110autorec_entry_find(const char *id, int create) 
    120111{ 
     
    155146autorec_entry_destroy(dvr_autorec_entry_t *dae) 
    156147{ 
     148  dvr_autorec_purge_spawns(dae); 
     149 
    157150  free(dae->dae_id); 
    158151 
     
    294287    return NULL; 
    295288 
    296   tvh_str_set(&dae->dae_creator, htsmsg_get_str(values, "creator")); 
    297   tvh_str_set(&dae->dae_comment, htsmsg_get_str(values, "comment")); 
     289  printf("autorec_record_update\n"); 
     290  htsmsg_print(values); 
     291 
     292  tvh_str_update(&dae->dae_creator, htsmsg_get_str(values, "creator")); 
     293  tvh_str_update(&dae->dae_comment, htsmsg_get_str(values, "comment")); 
    298294 
    299295  if((s = htsmsg_get_str(values, "channel")) != NULL) { 
     
    341337    dae->dae_enabled = u32; 
    342338 
    343   if(dae->dae_enabled) 
    344     dvr_autorec_check_just_enabled(dae); 
     339  dvr_autorec_changed(dae); 
    345340 
    346341  return autorec_record_build(dae); 
     
    436431  notify_by_msg("autorec", m); 
    437432 
    438   dvr_autorec_check_just_enabled(dae); 
    439 } 
    440  
    441 /** 
    442  * 
    443  */ 
    444 static void 
    445 autorec_schedule(event_t *e, dvr_autorec_entry_t *dae) 
    446 { 
    447   char buf[200]; 
    448  
    449   snprintf(buf, sizeof(buf), "Auto recording by: %s", dae->dae_creator); 
    450   dvr_entry_create_by_event(e, buf); 
     433  dvr_autorec_changed(dae); 
    451434} 
    452435 
     
    456439 */ 
    457440void 
    458 dvr_autorec_check(event_t *e) 
     441dvr_autorec_check_event(event_t *e) 
    459442{ 
    460443  dvr_autorec_entry_t *dae; 
     
    462445  TAILQ_FOREACH(dae, &autorec_entries, dae_link) 
    463446    if(autorec_cmp(dae, e)) 
    464       autorec_schedule(e, dae); 
    465  
    466   if((e = RB_NEXT(e, e_channel_link)) == NULL) 
    467     return; 
    468  
    469   /* Check next event too */ 
    470   TAILQ_FOREACH(dae, &autorec_entries, dae_link) 
    471     if(autorec_cmp(dae, e)) 
    472       autorec_schedule(e, dae); 
     447      dvr_entry_create_by_autorec(e, dae); 
    473448} 
    474449 
     
    477452 */ 
    478453static void 
    479 dvr_autorec_check_just_enabled(dvr_autorec_entry_t *dae) 
     454dvr_autorec_changed(dvr_autorec_entry_t *dae) 
    480455{ 
    481456  channel_t *ch; 
     457  event_t *e; 
     458 
     459  dvr_autorec_purge_spawns(dae); 
    482460 
    483461  RB_FOREACH(ch, &channel_name_tree, ch_name_link) { 
    484     if(ch->ch_epg_current == NULL) 
    485       continue; 
    486  
    487     if(autorec_cmp(dae, ch->ch_epg_current)) 
    488       autorec_schedule(ch->ch_epg_current, dae); 
     462    RB_FOREACH(e, &ch->ch_epg_events, e_channel_link) { 
     463      if(autorec_cmp(dae, e)) 
     464        dvr_entry_create_by_autorec(e, dae); 
     465    } 
    489466  } 
    490467} 
  • trunk/tvheadend/src/dvr/dvr_db.c

    r4315 r4332  
    138138dvr_entry_create(channel_t *ch, time_t start, time_t stop,  
    139139                 const char *title, const char *description, 
    140                  const char *creator) 
     140                 const char *creator, dvr_autorec_entry_t *dae) 
    141141{ 
    142142  dvr_entry_t *de; 
     
    175175  strftime(tbuf, sizeof(tbuf), "%c", &tm); 
    176176 
     177  de->de_autorec = dae; 
     178  LIST_INSERT_HEAD(&dae->dae_spawns, de, de_autorec_link); 
     179 
    177180  tvhlog(LOG_INFO, "dvr", "\"%s\" on \"%s\" starting at %s, " 
    178181         "scheduled for recording by \"%s\"", 
     
    189192 */ 
    190193dvr_entry_t * 
    191 dvr_entry_create_by_event(event_t *e, const char *creator) 
     194dvr_entry_create_by_event(event_t *e, const char *creator,  
     195                          dvr_autorec_entry_t *dae) 
    192196{ 
    193197  if(e->e_channel == NULL || e->e_title == NULL) 
     
    195199 
    196200  return dvr_entry_create(e->e_channel, e->e_start, e->e_stop,  
    197                           e->e_title, e->e_desc, creator); 
     201                          e->e_title, e->e_desc, creator, dae); 
     202} 
     203 
     204 
     205/** 
     206 * 
     207 */ 
     208void 
     209dvr_entry_create_by_autorec(event_t *e, dvr_autorec_entry_t *dae) 
     210{ 
     211  char buf[200]; 
     212 
     213  snprintf(buf, sizeof(buf), "Auto recording by: %s", dae->dae_creator); 
     214  dvr_entry_create_by_event(e, buf, dae); 
    198215} 
    199216 
     
    211228    return; 
    212229  } 
     230 
     231  if(de->de_autorec != NULL) 
     232    LIST_REMOVE(de, de_autorec_link); 
    213233 
    214234  free(de->de_creator); 
     
    302322 
    303323  htsmsg_get_u32(c, "noresched", &de->de_dont_reschedule); 
     324 
     325  s = htsmsg_get_str(c, "autorec"); 
     326  if(s != NULL) { 
     327    dvr_autorec_entry_t *dae = autorec_entry_find(s, 0); 
     328 
     329    if(dae != NULL) { 
     330      de->de_autorec = dae; 
     331      LIST_INSERT_HEAD(&dae->dae_spawns, de, de_autorec_link); 
     332    } 
     333  } 
     334 
    304335  dvr_entry_link(de); 
    305336} 
     
    359390 
    360391  htsmsg_add_u32(m, "noresched", de->de_dont_reschedule); 
     392 
     393  if(de->de_autorec != NULL) 
     394    htsmsg_add_str(m, "autorec", de->de_autorec->dae_id); 
    361395 
    362396  hts_settings_save(m, "dvr/log/%d", de->de_id); 
     
    590624  } 
    591625 
     626  dvr_autorec_init(); 
     627 
    592628  dvr_db_load(); 
    593  
    594   dvr_autorec_init(); 
    595  
    596629} 
    597630 
     
    612645  htsmsg_add_u32(m, "date-in-title",    !!(dvr_flags & DVR_DATE_IN_TITLE)); 
    613646  htsmsg_add_u32(m, "time-in-title",    !!(dvr_flags & DVR_TIME_IN_TITLE)); 
    614   htsmsg_add_u32(m, "whitespace-in-title",    !!(dvr_flags & DVR_WHITESPACE_IN_TITLE)); 
     647  htsmsg_add_u32(m, "whitespace-in-title", !!(dvr_flags & DVR_WHITESPACE_IN_TITLE)); 
    615648  if(dvr_postproc != NULL) 
    616649    htsmsg_add_str(m, "postproc", dvr_postproc); 
  • trunk/tvheadend/src/epg.c

    r4331 r4332  
    5858 
    5959  ch->ch_epg_current = e; 
    60   if(e != NULL) { 
     60  if(e != NULL) 
    6161    gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event, 
    6262                   ch, MAX(e->e_stop, dispatch_clock + 1)); 
    63     dvr_autorec_check(e); 
    64   } 
    6563  htsp_event_update(ch, e); 
    6664} 
     
    114112epg_event_changed(event_t *e) 
    115113{ 
    116   /* nothing atm  */ 
     114  dvr_autorec_check_event(e); 
    117115} 
    118116 
  • trunk/tvheadend/src/htsp.c

    r4205 r4332  
    498498   
    499499  //create the dvr entry 
    500   de = dvr_entry_create_by_event(e, (htsp->htsp_username) ? htsp->htsp_username:"anonymous"); 
     500  de = dvr_entry_create_by_event(e,  
     501                                 htsp->htsp_username ?  
     502                                 htsp->htsp_username : "anonymous", 
     503                                 NULL); 
    501504 
    502505  dvr_status = de != NULL ? de->de_sched_state : DVR_NOSTATE; 
  • trunk/tvheadend/src/webui/extjs.c

    r4315 r4332  
    725725    } 
    726726 
    727     dvr_entry_create_by_event(e, hc->hc_representative); 
     727    dvr_entry_create_by_event(e, hc->hc_representative, NULL); 
    728728 
    729729    out = htsmsg_create_map(); 
     
    778778      stop += 86400; 
    779779 
    780     dvr_entry_create(ch, start, stop, title, NULL, hc->hc_representative); 
     780    dvr_entry_create(ch, start, stop, title, NULL, hc->hc_representative, NULL); 
    781781 
    782782    out = htsmsg_create_map(); 
  • trunk/tvheadend/src/webui/simpleui.c

    r3612 r4332  
    210210 
    211211  if((http_arg_get(&hc->hc_req_args, "rec")) != NULL) { 
    212     de = dvr_entry_create_by_event(e, hc->hc_username ?: "anonymous"); 
     212    de = dvr_entry_create_by_event(e, hc->hc_username ?: "anonymous", NULL); 
    213213  } else if(de != NULL && (http_arg_get(&hc->hc_req_args, "cancel")) != NULL) { 
    214214    de = dvr_entry_cancel(de);