static void epggrab_mod_class_changed(idnode_t *self) { epggrab_module_t *mod = (epggrab_module_t *)self; epggrab_activate_module(mod, mod->enabled); idnode_changed(&epggrab_conf.idnode); }
static htsmsg_t * iptv_service_config_save ( service_t *s, char *filename, size_t fsize ) { mpegts_mux_t *mm = ((mpegts_service_t *)s)->s_dvb_mux; idnode_changed(&mm->mm_id); return NULL; }
/** * find a dvr config by name, return the default config if not found */ dvr_config_t * dvr_config_find_by_name_default(const char *name) { dvr_config_t *cfg; if (dvrdefaultconfig == NULL) dvrdefaultconfig = dvr_config_find_by_name(NULL); if (dvrdefaultconfig == NULL) { cfg = dvr_config_create("", NULL, NULL); assert(cfg); idnode_changed(&cfg->dvr_id); dvrdefaultconfig = cfg; } if (name == NULL || *name == '\0') return dvrdefaultconfig; cfg = dvr_config_find_by_name(name); if (cfg == NULL) { if (name && *name) tvhwarn(LS_DVR, "Configuration '%s' not found, using default", name); cfg = dvrdefaultconfig; } else if (!cfg->dvr_enabled) { tvhwarn(LS_DVR, "Configuration '%s' not enabled, using default", name); cfg = dvrdefaultconfig; } return cfg; }
static void iptv_service_delete ( service_t *s, int delconf ) { mpegts_mux_t *mm = ((mpegts_service_t *)s)->s_dvb_mux; idnode_changed(&mm->mm_id); /* Note - do no pass the delconf flag - another file location */ mpegts_service_delete(s, 0); }
void mpegts_network_scan_timer_cb ( void *p ) { mpegts_network_t *mn = p; mpegts_mux_t *mm, *nxt = NULL; int r; /* Process Q */ for (mm = TAILQ_FIRST(&mn->mn_scan_pend); mm != NULL; mm = nxt) { nxt = TAILQ_NEXT(mm, mm_scan_link); assert(mm->mm_scan_state == MM_SCAN_STATE_PEND || mm->mm_scan_state == MM_SCAN_STATE_ACTIVE); /* Don't try to subscribe already tuned muxes */ if (mm->mm_active) continue; /* Attempt to tune */ r = mpegts_mux_subscribe(mm, NULL, "scan", mm->mm_scan_weight, mm->mm_scan_flags | SUBSCRIPTION_ONESHOT | SUBSCRIPTION_TABLES); /* Started */ if (!r) { assert(mm->mm_scan_state == MM_SCAN_STATE_ACTIVE); continue; } assert(mm->mm_scan_state == MM_SCAN_STATE_PEND); /* No free tuners - stop */ if (r == SM_CODE_NO_FREE_ADAPTER || r == SM_CODE_NO_ADAPTERS) break; /* No valid tuners (subtly different, might be able to tuner a later * mux) */ if (r == SM_CODE_NO_VALID_ADAPTER && mm->mm_is_enabled(mm)) continue; /* Failed */ TAILQ_REMOVE(&mn->mn_scan_pend, mm, mm_scan_link); if (mm->mm_scan_result != MM_SCAN_FAIL) { mm->mm_scan_result = MM_SCAN_FAIL; idnode_changed(&mm->mm_id); } mm->mm_scan_state = MM_SCAN_STATE_IDLE; mm->mm_scan_weight = 0; mpegts_network_scan_notify(mm); } /* Re-arm timer. Really this is just a safety measure as we'd normally * expect the timer to be forcefully triggered on finish of a mux scan */ mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, sec2mono(120)); }
/* Finished */ static inline void mpegts_network_scan_mux_done0 ( mpegts_mux_t *mm, mpegts_mux_scan_result_t result, int weight ) { mpegts_network_t *mn = mm->mm_network; mpegts_mux_scan_state_t state = mm->mm_scan_state; /* prevent double del: */ /* mpegts_mux_stop -> mpegts_network_scan_mux_cancel */ mm->mm_scan_state = MM_SCAN_STATE_IDLE; mpegts_mux_unsubscribe_by_name(mm, "scan"); mm->mm_scan_state = state; if (state == MM_SCAN_STATE_PEND) { if (weight || mn->mn_idlescan) { if (!weight) mm->mm_scan_weight = SUBSCRIPTION_PRIO_SCAN_IDLE; TAILQ_REMOVE(&mn->mn_scan_pend, mm, mm_scan_link); TAILQ_INSERT_SORTED_R(&mn->mn_scan_pend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp); mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, sec2mono(10)); weight = 0; } else { mpegts_network_scan_queue_del(mm); } } else { if (!weight && mn->mn_idlescan) weight = SUBSCRIPTION_PRIO_SCAN_IDLE; mpegts_network_scan_queue_del(mm); } if (result != MM_SCAN_NONE && mm->mm_scan_result != result) { mm->mm_scan_result = result; idnode_changed(&mm->mm_id); } /* Re-enable? */ if (weight > 0) mpegts_network_scan_queue_add(mm, weight, mm->mm_scan_flags, 10); }
static void * dvr_thread(void *aux) { dvr_entry_t *de = aux; dvr_config_t *cfg = de->de_config; profile_chain_t *prch = de->de_chain; streaming_queue_t *sq = &prch->prch_sq; streaming_message_t *sm; th_pkt_t *pkt; int run = 1; int started = 0; int comm_skip = cfg->dvr_skip_commercials; int commercial = COMMERCIAL_UNKNOWN; pthread_mutex_lock(&sq->sq_mutex); while(run) { sm = TAILQ_FIRST(&sq->sq_queue); if(sm == NULL) { pthread_cond_wait(&sq->sq_cond, &sq->sq_mutex); continue; } if (de->de_s && started) { pktbuf_t *pb = NULL; if (sm->sm_type == SMT_PACKET) pb = ((th_pkt_t*)sm->sm_data)->pkt_payload; else if (sm->sm_type == SMT_MPEGTS) pb = sm->sm_data; if (pb) atomic_add(&de->de_s->ths_bytes_out, pktbuf_len(pb)); } TAILQ_REMOVE(&sq->sq_queue, sm, sm_link); pthread_mutex_unlock(&sq->sq_mutex); switch(sm->sm_type) { case SMT_PACKET: pkt = sm->sm_data; if(pkt->pkt_commercial == COMMERCIAL_YES) dvr_rec_set_state(de, DVR_RS_COMMERCIAL, 0); else dvr_rec_set_state(de, DVR_RS_RUNNING, 0); if(pkt->pkt_commercial == COMMERCIAL_YES && comm_skip) break; if(commercial != pkt->pkt_commercial) muxer_add_marker(prch->prch_muxer); commercial = pkt->pkt_commercial; if(started) { muxer_write_pkt(prch->prch_muxer, sm->sm_type, sm->sm_data); sm->sm_data = NULL; } break; case SMT_MPEGTS: if(started) { dvr_rec_set_state(de, DVR_RS_RUNNING, 0); muxer_write_pkt(prch->prch_muxer, sm->sm_type, sm->sm_data); sm->sm_data = NULL; } break; case SMT_START: if(started && muxer_reconfigure(prch->prch_muxer, sm->sm_data) < 0) { tvhlog(LOG_WARNING, "dvr", "Unable to reconfigure \"%s\"", de->de_filename ?: lang_str_get(de->de_title, NULL)); // Try to restart the recording if the muxer doesn't // support reconfiguration of the streams. dvr_thread_epilog(de); started = 0; } if(!started) { pthread_mutex_lock(&global_lock); dvr_rec_set_state(de, DVR_RS_WAIT_PROGRAM_START, 0); if(dvr_rec_start(de, sm->sm_data) == 0) { started = 1; idnode_changed(&de->de_id); htsp_dvr_entry_update(de); } pthread_mutex_unlock(&global_lock); } break; case SMT_STOP: if(sm->sm_code == SM_CODE_SOURCE_RECONFIGURED) { // Subscription is restarting, wait for SMT_START } else if(sm->sm_code == 0) { // Recording is completed de->de_last_error = 0; tvhlog(LOG_INFO, "dvr", "Recording completed: \"%s\"", de->de_filename ?: lang_str_get(de->de_title, NULL)); dvr_thread_epilog(de); started = 0; }else if(de->de_last_error != sm->sm_code) {