예제 #1
0
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);
}
예제 #2
0
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;
}
예제 #3
0
파일: dvr_config.c 프로젝트: blka/tvheadend
/**
 * 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;
}
예제 #4
0
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);
}
예제 #5
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));
}
예제 #6
0
/* 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);
}
예제 #7
0
파일: dvr_rec.c 프로젝트: JPP1/tvheadend
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) {