static int api_dvr_entry_create ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) { dvr_entry_t *de; dvr_config_t *cfg; htsmsg_t *conf; const char *s1; int res = EPERM; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; pthread_mutex_lock(&global_lock); s1 = htsmsg_get_str(conf, "config_name"); cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, s1); if (cfg) { htsmsg_set_str(conf, "config_name", idnode_uuid_as_str(&cfg->dvr_id)); if (perm->aa_representative) htsmsg_set_str(conf, "creator", perm->aa_representative); if ((de = dvr_entry_create(NULL, conf))) dvr_entry_save(de); res = 0; } pthread_mutex_unlock(&global_lock); return res; }
static int api_dvr_entry_create ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) { dvr_entry_t *de; dvr_config_t *cfg; htsmsg_t *conf, *m; char *s, *lang; const char *s1; int res = EPERM; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; pthread_mutex_lock(&global_lock); s1 = htsmsg_get_str(conf, "config_name"); cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, s1); if (cfg) { htsmsg_set_str(conf, "config_name", idnode_uuid_as_str(&cfg->dvr_id)); htsmsg_set_str(conf, "owner", perm->aa_username ?: ""); htsmsg_set_str(conf, "creator", perm->aa_representative ?: ""); lang = access_get_lang(perm, htsmsg_get_str(conf, "lang")); if (lang) { for (s = (char *)lang; *s && *s != ','; s++); *s = '\0'; } else { lang = strdup(lang_code_preferred()); } s1 = htsmsg_get_str(conf, "disp_title"); if (s1 && !htsmsg_get_map(conf, "title")) { m = htsmsg_create_map(); htsmsg_add_str(m, lang, s1); htsmsg_add_msg(conf, "title", m); } s1 = htsmsg_get_str(conf, "disp_subtitle"); if (s1 && !htsmsg_get_map(conf, "subtitle")) { m = htsmsg_create_map(); htsmsg_add_str(m, lang, s1); htsmsg_add_msg(conf, "subtitle", m); } if ((de = dvr_entry_create(NULL, conf))) dvr_entry_save(de); res = 0; free(lang); } pthread_mutex_unlock(&global_lock); return res; }
/** * Unlink - and remove any unstarted */ static void dvr_autorec_purge_spawns(dvr_autorec_entry_t *dae, int del) { dvr_entry_t *de; while((de = LIST_FIRST(&dae->dae_spawns)) != NULL) { LIST_REMOVE(de, de_autorec_link); de->de_autorec = NULL; if (!del) continue; if (de->de_sched_state == DVR_SCHEDULED) dvr_entry_cancel(de); else dvr_entry_save(de); } }
static int api_dvr_entry_create_by_event ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) { dvr_entry_t *de; const char *config_uuid, *comment; epg_broadcast_t *e; htsmsg_t *entries, *entries2 = NULL, *m; htsmsg_field_t *f; const char *s; int count = 0; if (!(entries = htsmsg_get_list(args, "entries"))) { entries = entries2 = api_dvr_entry_create_from_single(args); if (!entries) return EINVAL; } HTSMSG_FOREACH(f, entries) { if (!(m = htsmsg_get_map_by_field(f))) continue; if (!(s = htsmsg_get_str(m, "event_id"))) continue; config_uuid = htsmsg_get_str(m, "config_uuid"); comment = htsmsg_get_str(m, "comment"); pthread_mutex_lock(&global_lock); if ((e = epg_broadcast_find_by_id(strtoll(s, NULL, 10)))) { dvr_config_t *cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, config_uuid); if (cfg) { de = dvr_entry_create_by_event(idnode_uuid_as_str(&cfg->dvr_id), e, 0, 0, perm->aa_username, perm->aa_representative, NULL, DVR_PRIO_NORMAL, 0, comment); if (de) dvr_entry_save(de); } } pthread_mutex_unlock(&global_lock); count++; } htsmsg_destroy(entries2); return !count ? EINVAL : 0; }
static void * dvr_thread(void *aux) { dvr_entry_t *de = aux; dvr_config_t *cfg = dvr_config_find_by_name_default(de->de_config_name); streaming_queue_t *sq = &de->de_sq; streaming_message_t *sm; th_pkt_t *pkt; int run = 1; int started = 0; int comm_skip = (cfg->dvr_flags & 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; } 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(de->de_mux); commercial = pkt->pkt_commercial; if(started) { muxer_write_pkt(de->de_mux, 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(de->de_mux, sm->sm_type, sm->sm_data); sm->sm_data = NULL; } break; case SMT_START: if(started && muxer_reconfigure(de->de_mux, 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; dvr_entry_notify(de); htsp_dvr_entry_update(de); dvr_entry_save(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) {