* Add a new stream to a service
*/
elementary_stream_t *
-elementary_stream_create
- (elementary_set_t *set, int pid, streaming_component_type_t type)
+elementary_stream_create_parent
+ (elementary_set_t *set, int pid, int parent_pid, streaming_component_type_t type)
{
elementary_stream_t *st;
- int i = 0;
int idx = 0;
TAILQ_FOREACH(st, &set->set_all, es_link) {
if(st->es_index > idx)
idx = st->es_index;
- i++;
- if(pid != -1 && st->es_pid == pid)
+ if(pid != -1 && st->es_pid == pid) {
+ if (parent_pid >= 0 && st->es_parent_pid != parent_pid)
+ goto create;
return st;
+ }
}
+create:
st = calloc(1, sizeof(elementary_stream_t));
st->es_index = idx + 1;
st->es_service = set->set_service;
st->es_pid = pid;
+ st->es_parent_pid = parent_pid > 0 ? parent_pid : 0;
elementary_stream_make_nicename(st, set->set_nicename);
return NULL;
}
+/**
+ * Find an elementary stream in a service with specific parent pid
+ */
+elementary_stream_t *
+elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid)
+{
+ elementary_stream_t *st;
+
+ TAILQ_FOREACH(st, &set->set_all, es_link) {
+ if(st->es_pid == pid && st->es_parent_pid == parent_pid)
+ return st;
+ }
+ return NULL;
+}
+
/**
* Find a first elementary stream in a service (by type)
*/
void elementary_set_stream_destroy(elementary_set_t *set, elementary_stream_t *es);
void elementary_set_init_filter_streams(elementary_set_t *set);
void elementary_set_filter_build(elementary_set_t *set);
-elementary_stream_t *elementary_stream_create
- (elementary_set_t *set, int pid, streaming_component_type_t type);
+elementary_stream_t *elementary_stream_create_parent
+ (elementary_set_t *set, int pid, int parent_pid, streaming_component_type_t type);
+static inline elementary_stream_t *elementary_stream_create
+ (elementary_set_t *set, int pid, streaming_component_type_t type)
+{ return elementary_stream_create_parent(set, pid, -1, type); }
elementary_stream_t *elementary_stream_find_(elementary_set_t *set, int pid);
elementary_stream_t *elementary_stream_type_find
(elementary_set_t *set, streaming_component_type_t type);
else
return set->set_last_es;
}
+elementary_stream_t *elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid);
elementary_stream_t *elementary_stream_type_modify
(elementary_set_t *set, int pid, streaming_component_type_t type);
void elementary_stream_type_destroy
int page = (ptr[3] & 0x7 ?: 8) * 100 + (ptr[4] >> 4) * 10 + (ptr[4] & 0xf);
int type = ptr[3] >> 3;
- if(type == 2 || type == 5) {
+ if(page > 0 && (type == 2 || type == 5)) {
// 2 = subtitle page, 5 = subtitle page [hearing impaired]
// We put the teletext subtitle driven streams on a list of pids
// higher than normal MPEG TS (0x2000 ++)
int pid = DVB_TELETEXT_BASE + page;
- st = elementary_stream_find(set, pid);
+ st = elementary_stream_find_parent(set, pid, parent_pid);
if (st == NULL || st->es_type != SCT_TEXTSUB) {
r |= PMT_UPDATE_NEW_STREAM;
- st = elementary_stream_create(set, pid, SCT_TEXTSUB);
+ st = elementary_stream_create_parent(set, pid, parent_pid, SCT_TEXTSUB);
}
lang = lang_code_get2((const char*)ptr, 3);
memcpy(st->es_lang, lang, 4);
}
- if(st->es_parent_pid != parent_pid) {
- r |= PMT_UPDATE_PARENT_PID;
- st->es_parent_pid = parent_pid;
- }
-
// Check es_delete_me so we only compute position once per PMT update
if(st->es_position != *position && st->es_delete_me) {
st->es_position = *position;
break;
case DVB_DESC_TELETEXT:
- if(estype == 0x06)
+ if(estype == 0x06) {
hts_stream_type = SCT_TELETEXT;
-
- update |= psi_desc_teletext(set, ptr, dlen, pid, &tt_position);
+ update |= psi_desc_teletext(set, ptr, dlen, pid, &tt_position);
+ }
break;
case DVB_DESC_AC3:
if (update) {
tvhdebug(mt->mt_subsys, "%s: Service \"%s\" PMT (version %d) updated"
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
mt->mt_name,
nicename, version,
update&PMT_UPDATE_PCR ? ", PCR PID changed":"",
update&PMT_UPDATE_NEW_CA_STREAM ? ", New CA stream":"",
update&PMT_UPDATE_NEW_CAID ? ", New CAID":"",
update&PMT_UPDATE_CA_PROVIDER_CHANGE? ", CA provider changed":"",
- update&PMT_UPDATE_PARENT_PID ? ", Parent PID changed":"",
update&PMT_UPDATE_CAID_DELETED ? ", CAID deleted":"",
update&PMT_UPDATE_CAID_PID ? ", CAID PID changed":"",
update&PMT_REORDERED ? ", PIDs reordered":"");
#define PMT_UPDATE_NEW_CA_STREAM (1<<10)
#define PMT_UPDATE_NEW_CAID (1<<11)
#define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<12)
-#define PMT_UPDATE_PARENT_PID (1<<13)
-#define PMT_UPDATE_CAID_DELETED (1<<14)
-#define PMT_UPDATE_CAID_PID (1<<15)
-#define PMT_REORDERED (1<<16)
+#define PMT_UPDATE_CAID_DELETED (1<<13)
+#define PMT_UPDATE_CAID_PID (1<<14)
+#define PMT_REORDERED (1<<15)
uint32_t dvb_psi_parse_pmt
(mpegts_table_t *mt, const char *nicename, elementary_set_t *set,
TAILQ_FOREACH(es, &t->prs_components.set_filter, es_filter_link) {
st = (parser_es_t *)es;
+ if (st->es_type != SCT_TELETEXT) continue;
if (parent->es_pid == st->es_parent_pid &&
ttm->ttm_curpage == st->es_pid - PID_TELETEXT_BASE) {
if (extract_subtitle(t, st, ttm, ttm->ttm_current_pts))
if cc & 0x10:
cc &= 0x0f
if pid in pids_cc and pids_cc[pid] != cc:
- print 'cc err 0x%x != 0x%x for pid %04X (%4d) %d' % (cc, pids_cc[pid], pid, pid, fp.tell())
+ print 'cc err 0x%x != 0x%x for pid %04X (%4d) at %d' % (cc, pids_cc[pid], pid, pid, fp.tell())
if pid not in pids_cc_err:
pids_cc_err[pid] = 1
else: