static void tmdb_insert_movie_cast(void *db, int64_t itemid, htsmsg_t *doc) { char url[300]; char id[64]; htsmsg_field_t *f; const char *s; htsmsg_t *cast = htsmsg_get_list(doc, "cast"); HTSMSG_FOREACH(f, cast) { htsmsg_t *p = htsmsg_get_map_by_field(f); if(p == NULL) continue; s = htsmsg_get_str(p, "profile_path"); if(s) snprintf(url, sizeof(url), "tmdb:image:profile:%s", s); else url[0] = 0; snprintf(id, sizeof(id), "%d", htsmsg_get_u32_or_default(p, "id", 0)); metadb_insert_videocast(db, itemid, htsmsg_get_str(p, "name"), htsmsg_get_str(p, "character"), "Cast", "Actor", htsmsg_get_u32_or_default(p, "order", 0), url[0] ? url : NULL, 0, 0, id); }
static void http_callback(http_req_aux_t *req, void *opaque) { char errbuf[128]; tracker_torrent_t *tt = opaque; torrent_t *to = tt->tt_torrent; htsmsg_t *msg; net_addr_t na; assert(tt->tt_http_req != NULL); tt->tt_http_req = NULL; buf_t *b = http_req_get_result(req); tt->tt_interval = MIN(3600, tt->tt_interval * 2); if(b != NULL) { msg = bencode_deserialize(buf_cstr(b), buf_cstr(b) + buf_size(b), errbuf, sizeof(errbuf), NULL, NULL); if(msg != NULL) { const char *err = htsmsg_get_str(msg, "failure reason"); if(err != NULL) { tracker_trace(tt->tt_tracker, "%s for %s", err, to->to_title); goto done; } const char *trackerid = htsmsg_get_str(msg, "trackerid"); if(trackerid != NULL) mystrset(&tt->tt_trackerid, trackerid); tt->tt_interval = htsmsg_get_u32_or_default(msg, "min interval", htsmsg_get_u32_or_default(msg, "interval", 1800)); htsmsg_t *peers = htsmsg_get_list(msg, "peers"); if(peers != NULL) { htsmsg_field_t *f; HTSMSG_FOREACH(f, peers) { htsmsg_t *sub = htsmsg_get_map_by_field(f); if(sub == NULL) continue; const char *ip = htsmsg_get_str(sub, "ip"); if(ip == NULL) continue; if(net_resolve_numeric(ip, &na)) continue; na.na_port = htsmsg_get_u32_or_default(sub, "port", 0); if(na.na_port == 0) continue; peer_add(to, &na); } }
setting_t * settings_create_bool(prop_t *parent, const char *id, prop_t *title, int initial, htsmsg_t *store, prop_callback_int_t *cb, void *opaque, int flags, prop_courier_t *pc, settings_saver_t *saver, void *saver_opaque) { setting_t *s = setting_create_leaf(parent, title, "bool", "value", flags); prop_sub_t *sub; s->s_id = strdup(id); s->s_callback = cb; s->s_opaque = opaque; if(store != NULL) initial = htsmsg_get_u32_or_default(store, id, initial); prop_set_int(s->s_val, !!initial); if(flags & SETTINGS_INITIAL_UPDATE) settings_int_callback(s, !!initial); sub = prop_subscribe(PROP_SUB_NO_INITIAL_UPDATE, PROP_TAG_CALLBACK_INT, settings_int_callback, s, PROP_TAG_ROOT, s->s_val, PROP_TAG_COURIER, pc, NULL); s->s_sub = sub; s->s_store = store; s->s_saver = saver; s->s_saver_opaque = saver_opaque; return s; }
static prop_t * add_news_locked(const char *id, const char *message, const char *location, const char *caption, const char *action) { prop_t *p, *ret = NULL; prop_t *root = prop_create(prop_get_global(), "news"); if(dismissed_news_out != NULL) { if(htsmsg_get_u32_or_default(dismissed_news_in, id, 0)) { dismis_news(id); } else { p = prop_create_root(id); prop_set(p, "message", PROP_SET_STRING, message); prop_set(p, "id", PROP_SET_STRING, id); prop_set(p, "location", PROP_SET_STRING, location); prop_set(p, "caption", PROP_SET_STRING, caption); prop_set(p, "action", PROP_SET_STRING, action); prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, news_sink, prop_ref_inc(p), PROP_TAG_ROOT, prop_create(p, "eventSink"), PROP_TAG_MUTEX, &news_mutex, NULL); ret = prop_ref_inc(p); if(prop_set_parent(p, root)) prop_destroy(p); } } return ret; }
prop_t * add_news(const char *message, const char *location, const char *caption) { prop_t *p, *ret = NULL; prop_t *root = prop_create(prop_get_global(), "news"); hts_mutex_lock(&news_mutex); if(dismissed_news_out != NULL) { if(htsmsg_get_u32_or_default(dismissed_news_in, message, 0)) { dismis_news(message); } else { p = prop_create_root(NULL); prop_set_string(prop_create(p, "message"), message); prop_set_string(prop_create(p, "location"), location); prop_set_string(prop_create(p, "caption"), caption); prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, news_sink, prop_ref_inc(p), PROP_TAG_ROOT, prop_create(p, "eventSink"), PROP_TAG_MUTEX, &news_mutex, NULL); ret = prop_ref_inc(p); if(prop_set_parent(p, root)) prop_destroy(p); } } hts_mutex_unlock(&news_mutex); return ret; }
HTSMSG_FOREACH(f, crew) { htsmsg_t *p = htsmsg_get_map_by_field(f); if(p == NULL) continue; s = htsmsg_get_str(p, "profile_path"); if(s) snprintf(url, sizeof(url), "tmdb:image:profile:%s", s); else url[0] = 0; snprintf(id, sizeof(id), "%d", htsmsg_get_u32_or_default(p, "id", 0)); metadb_insert_videocast(db, itemid, htsmsg_get_str(p, "name"), NULL, htsmsg_get_str(p, "department"), htsmsg_get_str(p, "job"), o++, url[0] ? url : NULL, 0, 0, id); }
struct pixmap * backend_imageloader(rstr_t *url0, const image_meta_t *im0, const char **vpaths, char *errbuf, size_t errlen, int *cache_control, cancellable_t *c) { const char *url = rstr_get(url0); htsmsg_t *m = NULL; if(im0->im_req_width < -1 || im0->im_req_height < -1) { snprintf(errbuf, errlen, "Invalid dimensions"); return NULL; } image_meta_t im = *im0; if(!strncmp(url, "thumb://", 8)) { url += 8; im.im_want_thumb = 1; } if(!strncmp(url, "imageset:", 9)) { m = htsmsg_json_deserialize(url+9); if(m == NULL) { snprintf(errbuf, errlen, "Invalid JSON"); return NULL; } htsmsg_field_t *f; const char *best = NULL; int best_width = -1; int best_height = -1; HTSMSG_FOREACH(f, m) { htsmsg_t *img = htsmsg_get_map_by_field(f); if(img == NULL) continue; int w = htsmsg_get_u32_or_default(img, "width", 10000); int h = htsmsg_get_u32_or_default(img, "height", 10000); const char *u = htsmsg_get_str(img, "url"); if(!u) continue; if(best != NULL) { if(im.im_req_width != -1) { if(w >= im.im_req_width && (w < best_width || best_width < im.im_req_width)) goto gotone; if(w < im.im_req_width && w > best_width) goto gotone; } else if(im.im_req_height != -1) { if(h >= im.im_req_height && (h < best_height || best_height < im.im_req_height)) goto gotone; if(h < im.im_req_height && h > best_height) goto gotone; } else { if(w > best_width) goto gotone; if(h > best_height) goto gotone; } continue; } gotone: best = u; best_width = w; best_height = h; }
void tvhlogv ( const char *file, int line, int notify, int severity, const char *subsys, const char *fmt, va_list *args ) { int ok, options; size_t l; char buf[1024]; pthread_mutex_lock(&tvhlog_mutex); /* Check for full */ if (tvhlog_queue_full || !tvhlog_run) { pthread_mutex_unlock(&tvhlog_mutex); return; } /* Check debug enabled (and cache config) */ options = tvhlog_options; if (severity >= LOG_DEBUG) { ok = 0; if (severity <= tvhlog_level) { if (tvhlog_trace) { ok = htsmsg_get_u32_or_default(tvhlog_trace, "all", 0); ok = htsmsg_get_u32_or_default(tvhlog_trace, subsys, ok); } if (!ok && severity == LOG_DEBUG && tvhlog_debug) { ok = htsmsg_get_u32_or_default(tvhlog_debug, "all", 0); ok = htsmsg_get_u32_or_default(tvhlog_debug, subsys, ok); } } } else { ok = 1; } /* Ignore */ if (!ok) { pthread_mutex_unlock(&tvhlog_mutex); return; } /* FULL */ if (tvhlog_queue_size == TVHLOG_QUEUE_MAXSIZE) { tvhlog_queue_full = 1; fmt = "log buffer full"; args = NULL; severity = LOG_ERR; } /* Basic message */ l = 0; if (options & TVHLOG_OPT_THREAD) { l += snprintf(buf + l, sizeof(buf) - l, "tid %ld: ", (long)pthread_self()); } l += snprintf(buf + l, sizeof(buf) - l, "%s: ", subsys); if (options & TVHLOG_OPT_FILELINE && severity >= LOG_DEBUG) l += snprintf(buf + l, sizeof(buf) - l, "(%s:%d) ", file, line); if (args) l += vsnprintf(buf + l, sizeof(buf) - l, fmt, *args); else l += snprintf(buf + l, sizeof(buf) - l, "%s", fmt); /* Store */ tvhlog_msg_t *msg = calloc(1, sizeof(tvhlog_msg_t)); gettimeofday(&msg->time, NULL); msg->msg = strdup(buf); msg->severity = severity; msg->notify = notify; #if TVHLOG_THREAD if (tvhlog_run) { TAILQ_INSERT_TAIL(&tvhlog_queue, msg, link); tvhlog_queue_size++; pthread_cond_signal(&tvhlog_cond); } else { #endif FILE *fp = NULL; tvhlog_process(msg, tvhlog_options, &fp, tvhlog_path); if (fp) fclose(fp); #if TVHLOG_THREAD } #endif pthread_mutex_unlock(&tvhlog_mutex); }
static void update_events(htsp_connection_t *hc, prop_t *metadata, int id, int next) { int i; htsmsg_t *m; prop_t *events = prop_create(metadata, "list"); prop_t *current_event = prop_create(metadata, "current"); prop_t *next_event = prop_create(metadata, "next"); char buf[10]; uint32_t u32; int linkstate = 0; if(id == 0) { if(next == 0) { // No events at all prop_destroy_childs(events); return; } id = next; linkstate = 1; } for(i = 0; i < EPG_TAIL; i++) { snprintf(buf, sizeof(buf), "id%d", i); if(id != 0) { m = htsmsg_create_map(); htsmsg_add_str(m, "method", "getEvent"); htsmsg_add_u32(m, "eventId", id); if((m = htsp_reqreply(hc, m)) != NULL) { prop_t *e = prop_create(events, buf); prop_set_string(prop_create(e, "title"), htsmsg_get_str(m, "title")); prop_set_string(prop_create(e, "description"), htsmsg_get_str(m, "description")); if(!htsmsg_get_u32(m, "start", &u32)) prop_set_int(prop_create(e, "start"), u32); if(!htsmsg_get_u32(m, "stop", &u32)) prop_set_int(prop_create(e, "stop"), u32); switch(linkstate) { case 0: prop_link(e, current_event); break; case 1: prop_link(e, next_event); break; } linkstate++; id = htsmsg_get_u32_or_default(m, "nextEventId", 0); continue; } else { id = 0; } } prop_destroy_by_name(events, buf); switch(linkstate) { case 0: prop_unlink(current_event); break; case 1: prop_unlink(next_event); break; } linkstate++; } }
void load_site_news(void) { #if ENABLE_WEBPOPUP struct http_header_list response_headers; buf_t *b; char errbuf[512]; b = fa_load("https://movian.tv/projects/movian/news.json", FA_LOAD_FLAGS(FA_DISABLE_AUTH | FA_COMPRESSION), FA_LOAD_RESPONSE_HEADERS(&response_headers), FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)), NULL); if(b == NULL) { TRACE(TRACE_DEBUG, "News", "Unable to load news -- %s", errbuf); return; } const char *dateheader = http_header_get(&response_headers, "date"); if(dateheader == NULL) { buf_release(b); http_headers_free(&response_headers); return; } dateheader = mystrdupa(dateheader); http_headers_free(&response_headers); htsmsg_t *newsinfo = htsmsg_store_load("sitenews"); time_t no_news_before; if(newsinfo == NULL) newsinfo = htsmsg_create_map(); no_news_before = htsmsg_get_u32_or_default(newsinfo, "nothingbefore", 0); if(no_news_before == 0) { if(http_ctime(&no_news_before, dateheader)) { buf_release(b); htsmsg_release(newsinfo); return; } htsmsg_add_u32(newsinfo, "nothingbefore", no_news_before); htsmsg_store_save(newsinfo, "sitenews"); htsmsg_release(newsinfo); } htsmsg_t *doc = htsmsg_json_deserialize(buf_cstr(b)); buf_release(b); if(doc == NULL) { return; } hts_mutex_lock(&news_mutex); htsmsg_t *news = htsmsg_get_list(doc, "news"); if(news != NULL) { htsmsg_field_t *f; HTSMSG_FOREACH(f, news) { htsmsg_t *entry; if((entry = htsmsg_get_map_by_field(f)) == NULL) continue; const char *title = htsmsg_get_str(entry, "title"); const char *created_on = htsmsg_get_str(entry, "created_on"); int id = htsmsg_get_u32_or_default(entry, "id", 0); if(created_on == NULL || title == NULL || id == 0) continue; time_t t; if(parse_created_on_time(&t, created_on)) continue; if(t < no_news_before) continue; char idstr[64]; snprintf(idstr, sizeof(idstr), "sitenews:%d", id); prop_t *p = add_news_locked(idstr, title, NULL, "Read more", idstr); if(p != NULL) { prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, open_news, p, PROP_TAG_ROOT, prop_create(p, "eventSink"), PROP_TAG_MUTEX, &news_mutex, NULL); } }
static void screenshot_process(void *task) { pixmap_t *pm = task; if(pm == NULL) { screenshot_response(NULL, "Screenshot not supported on this platform"); return; } TRACE(TRACE_DEBUG, "Screenshot", "Processing image %d x %d", pm->pm_width, pm->pm_height); int codecid = AV_CODEC_ID_PNG; if(screenshot_connection) codecid = AV_CODEC_ID_MJPEG; buf_t *b = screenshot_compress(pm, codecid); pixmap_release(pm); if(b == NULL) { screenshot_response(NULL, "Unable to compress image"); return; } if(!screenshot_connection) { char path[512]; char errbuf[512]; snprintf(path, sizeof(path), "%s/screenshot.png", gconf.cache_path); fa_handle_t *fa = fa_open_ex(path, errbuf, sizeof(errbuf), FA_WRITE, NULL); if(fa == NULL) { TRACE(TRACE_ERROR, "SCREENSHOT", "Unable to open %s -- %s", path, errbuf); buf_release(b); return; } fa_write(fa, buf_data(b), buf_len(b)); fa_close(fa); TRACE(TRACE_INFO, "SCREENSHOT", "Written to %s", path); buf_release(b); return; } buf_t *result = NULL; htsbuf_queue_t hq; htsbuf_queue_init(&hq, 0); htsbuf_append(&hq, "image=", 6); htsbuf_append_and_escape_url_len(&hq, buf_cstr(b), buf_len(b)); char errbuf[256]; int ret = http_req("https://api.imgur.com/3/upload", HTTP_FLAGS(FA_CONTENT_ON_ERROR), HTTP_REQUEST_HEADER("Authorization", "Client-ID 7c79b311d4797ed"), HTTP_RESULT_PTR(&result), HTTP_POSTDATA(&hq, "application/x-www-form-urlencoded"), HTTP_ERRBUF(errbuf, sizeof(errbuf)), NULL); if(ret) { screenshot_response(NULL, errbuf); } else { htsmsg_t *response = htsmsg_json_deserialize(buf_cstr(result)); if(response == NULL) { screenshot_response(NULL, "Unable to parse imgur response"); } else { if(htsmsg_get_u32_or_default(response, "success", 0)) { const char *url = htsmsg_get_str_multi(response, "data", "link", NULL); screenshot_response(url, "No link in imgur response"); } else { const char *msg = htsmsg_get_str_multi(response, "data", "error", NULL); if(msg == NULL) { screenshot_response(NULL, "Unkown imgur error"); } else { snprintf(errbuf, sizeof(errbuf), "Imgur error: %s", msg); screenshot_response(NULL, errbuf); } } htsmsg_release(response); } buf_release(result); } buf_release(b); }
static void check_upgrade(int set_news) { char url[1024]; char *result; htsmsg_t *json; char errbuf[1024]; if(inhibit_checks) return; if(upgrade_track == NULL) { prop_set_string(upgrade_error, "No release track specified"); goto err; } prop_set_string(upgrade_status, "checking"); TRACE(TRACE_DEBUG, "Upgrade", "Checking upgrades for %s-%s", upgrade_track, archname); snprintf(url, sizeof(url), "%s/%s-%s.json", ctrlbase, upgrade_track, archname); result = fa_load(url, NULL, NULL, errbuf, sizeof(errbuf), NULL, 0, NULL, NULL); if(result == NULL) { prop_set_string(upgrade_error, errbuf); err: prop_set_string(upgrade_status, "checkError"); return; } json = htsmsg_json_deserialize(result); free(result); if(json == NULL) { prop_set_string(upgrade_error, "Malformed JSON in repository"); goto err; } // Find an artifact for us const char *dlurl = NULL; const char *sha1 = NULL; int dlsize = 0; const char *ver; htsmsg_t *artifacts = htsmsg_get_list(json, "artifacts"); if(artifacts != NULL) { htsmsg_field_t *f; HTSMSG_FOREACH(f, artifacts) { htsmsg_t *a; if((a = htsmsg_get_map_by_field(f)) == NULL) continue; const char *type = htsmsg_get_str(a, "type"); if(type == NULL || strcmp(artifact_type, type)) continue; dlurl = htsmsg_get_str(a, "url"); sha1 = htsmsg_get_str(a, "sha1"); dlsize = htsmsg_get_u32_or_default(a, "size", 0); break; }
void cHTSPDemux::SubscriptionStart(htsmsg_t *m) { htsmsg_t *streams; htsmsg_field_t *f; if((streams = htsmsg_get_list(m, "streams")) == NULL) { XBMC->Log(LOG_ERROR, "%s - malformed message", __FUNCTION__); return; } m_Streams.iStreamCount = 0; HTSMSG_FOREACH(f, streams) { uint32_t index; const char* type; htsmsg_t* sub; if (f->hmf_type != HMF_MAP) continue; sub = &f->hmf_msg; if ((type = htsmsg_get_str(sub, "type")) == NULL) continue; if (htsmsg_get_u32(sub, "index", &index)) continue; const char *language = htsmsg_get_str(sub, "language"); XBMC->Log(LOG_DEBUG, "%s - id: %d, type: %s, language: %s", __FUNCTION__, index, type, language); m_Streams.stream[m_Streams.iStreamCount].iFPSScale = 0; m_Streams.stream[m_Streams.iStreamCount].iFPSRate = 0; m_Streams.stream[m_Streams.iStreamCount].iHeight = 0; m_Streams.stream[m_Streams.iStreamCount].iWidth = 0; m_Streams.stream[m_Streams.iStreamCount].fAspect = 0.0; m_Streams.stream[m_Streams.iStreamCount].iChannels = 0; m_Streams.stream[m_Streams.iStreamCount].iSampleRate = 0; m_Streams.stream[m_Streams.iStreamCount].iBlockAlign = 0; m_Streams.stream[m_Streams.iStreamCount].iBitRate = 0; m_Streams.stream[m_Streams.iStreamCount].iBitsPerSample = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[0] = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[1] = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[2] = 0; m_Streams.stream[m_Streams.iStreamCount].strLanguage[3] = 0; m_Streams.stream[m_Streams.iStreamCount].iIdentifier = -1; if(!strcmp(type, "AC3")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_AC3; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "EAC3")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_EAC3; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "MPEG2AUDIO")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_MP2; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "AAC")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_AUDIO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_AAC; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "MPEG2VIDEO")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_VIDEO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_MPEG2VIDEO; m_Streams.stream[m_Streams.iStreamCount].iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); m_Streams.stream[m_Streams.iStreamCount].iHeight = htsmsg_get_u32_or_default(sub, "height" , 0); m_Streams.iStreamCount++; } else if(!strcmp(type, "H264")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_VIDEO; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_H264; m_Streams.stream[m_Streams.iStreamCount].iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); m_Streams.stream[m_Streams.iStreamCount].iHeight = htsmsg_get_u32_or_default(sub, "height" , 0); m_Streams.iStreamCount++; } else if(!strcmp(type, "DVBSUB")) { uint32_t composition_id = 0, ancillary_id = 0; htsmsg_get_u32(sub, "composition_id", &composition_id); htsmsg_get_u32(sub, "ancillary_id" , &ancillary_id); m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_SUBTITLE; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_DVB_SUBTITLE; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.stream[m_Streams.iStreamCount].iIdentifier = (composition_id & 0xffff) | ((ancillary_id & 0xffff) << 16); m_Streams.iStreamCount++; } else if(!strcmp(type, "TEXTSUB")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_SUBTITLE; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_TEXT; SetLanguageInfo(language, m_Streams.stream[m_Streams.iStreamCount].strLanguage); m_Streams.iStreamCount++; } else if(!strcmp(type, "TELETEXT")) { m_Streams.stream[m_Streams.iStreamCount].iStreamIndex = m_Streams.iStreamCount; m_Streams.stream[m_Streams.iStreamCount].iPhysicalId = index; m_Streams.stream[m_Streams.iStreamCount].iCodecType = CODEC_TYPE_SUBTITLE; m_Streams.stream[m_Streams.iStreamCount].iCodecId = CODEC_ID_DVB_TELETEXT; m_Streams.iStreamCount++; } if (m_Streams.iStreamCount >= PVR_STREAM_MAX_STREAMS) { XBMC->Log(LOG_ERROR, "%s - max amount of streams reached", __FUNCTION__); break; } }