📄 splitts.c
字号:
byte *d; struct { boolean tnew : 1; boolean tpat : 1; } treated[MAX_PMTSTREAMS]; warn (LINF,"Remap",ETST,7,new->descrlen,new->pmt_pid); p = f->u.ts.pat; while ((p != NULL) && (p->programnumber != new->programnumber)) { p = p->next; } warn (LDEB,"Remap 2",ETST,p?p->streams:0,(long)f->u.ts.pat,p); if (p != NULL) { warn (LDEB,"Remap 2a",ETST,p->pmt_version,new->pmt_version,new); if (p->pmt_version == new->pmt_version) { /* check more here, or fall through ? */ p->pat_section = new->pat_section; /* announce presence */ return; } } else { if ((p = malloc (sizeof(pmt_descr))) == NULL) { warn (LERR,"PAT malloc failed",ETST,7,1,sizeof(pmt_descr)); return; } p->next = f->u.ts.pat; p->programnumber = new->programnumber; p->streams = 0; f->u.ts.pat = p; warn (LIMP,"Remap PAT",ETST,7,new->pat_section,new->pmt_pid); } p->pat_section = new->pat_section; p->pmt_version = new->pmt_version; p->pcr_pid = new->pcr_pid; if (ts_file_stream(f,new->pmt_pid) == NULL) { if ((ts_file_stream(f,new->pmt_pid) = input_openstream (f,new->pmt_pid,0,0,sd_map,NULL)) == NULL) { p->pat_section = -1; return; } } p->pmt_pid = new->pmt_pid; memset (&treated[0],0,sizeof(treated)); i = new->streams; while (--i >= 0) { j = p->streams; warn (LDEB,"Remap 3",ETST,0,i,j); while ((--j >= 0) && (p->streamtype[j] != new->streamtype[i]) && (p->stream[j] != new->stream[i])) { } if (j >= 0) { treated[j].tpat = TRUE; treated[i].tnew = TRUE; warn (LIMP,"Remap Match",ETST,7,new->streamtype[i],new->stream[i]); } } i = new->streams; while (--i >= 0) { if (!treated[i].tnew) { j = p->streams; while ((--j >= 0) && (treated[j].tpat) && (p->streamtype[j] != new->streamtype[i])) { } if (j >= 0) { treated[j].tpat = TRUE; warn (LIMP,"Remap Move",ETST,7,p->stream[j],new->stream[i]); warn (LSEC,"Remap Move",ETST,7,p->streamtype[j],new->streamtype[i]); if (ts_file_stream(f,p->stream[j]) != NULL) { k = ts_file_stream(f,p->stream[j])->u.d.progs; while (--k >= 0) { ts_file_stream(f,new->stream[i]) = connect_streamprog ( f,ts_file_stream(f,p->stream[j])->u.d.pdescr[k]->program_number, new->stream[i], ts_file_stream(f,p->stream[j])->stream_id,new->streamtype[i], ts_file_stream(f,new->stream[i]), ts_file_stream(f,new->pmt_pid),FALSE); } if (ts_file_stream(f,new->stream[i]) != NULL) { ts_file_stream(f,new->stream[i])->u.d.trigger = TRUE; } ts_file_stream(f,p->stream[j])->endaction = ENDSTR_KILL; } else { /* was not used -> will not use */ } } else { warn (LIMP,"Remap New",ETST,7,new->streamtype[i],new->stream[i]); } } } j = p->streams; while (--j >= 0) { if (!(treated[j].tpat)) { warn (LIMP,"Remap Close",ETST,7,p->streamtype[j],p->stream[j]); ts_file_stream (f,p->stream[j])->endaction = ENDSTR_KILL; } } p->streams = new->streams; memcpy (p->stream,new->stream,p->streams * sizeof(p->stream[0])); memcpy (p->streamtype,new->streamtype,p->streams * sizeof(p->streamtype[0])); p->descrlen = i = new->descrlen; if (i != 0) { memcpy (p->elemdescr,new->elemdescr,i); d = &p->elemdescr[0]; j = ((d[0] & 0x0F) << 8) + d[1]; i -= (j+2); if (i >= 0) { d += 2; alloc_descriptor (ts_file_stream(f,p->pmt_pid),p->pmt_pid, p->programnumber,p->pmt_version); while (j > 1) { d = put_descriptor_s (d,ts_file_stream(f,p->pmt_pid),&j); } if (j != 0) { warn (LWAR,"PAT descr error",ETST,7,3,j); } else { finish_descriptor (ts_file_stream(f,p->pmt_pid)); while (i >= TS_PMTELEM_SIZE) { k = ((d[1] & 0x1F) << 8) + d[2]; j = ((d[3] & 0x0F) << 8) + d[4]; i -= (j+TS_PMTELEM_SIZE); if (i >= 0) { d += TS_PMTELEM_SIZE; alloc_descriptor (ts_file_stream(f,p->pmt_pid),k, p->programnumber,p->pmt_version); while (j > 1) { d = put_descriptor_s (d,ts_file_stream(f,p->pmt_pid),&j); } if (j != 0) { warn (LWAR,"PAT descr error",ETST,7,5,j); i = -1; } else { finish_descriptor (ts_file_stream(f,p->pmt_pid)); } } } if (i != 0) { warn (LWAR,"PAT descr error",ETST,7,4,i); } } } else { warn (LWAR,"PAT descr error",ETST,7,2,i); } }}/* Unlink stream in an old prgram that will be released. * Mark the corresponding streams to be closed as they cease. * Precondition: f!=NULL, old!=NULL */static void unmap_old_program (file_descr *f, pmt_descr *old){ int i; warn (LIMP,"Unmap",ETST,8,old->descrlen,old->pmt_pid); i = old->streams; while (--i >= 0) { if (ts_file_stream (f,old->stream[i]) != NULL) { warn (LIMP,"Unmap Close",ETST,8,old->streamtype[i],old->stream[i]); ts_file_stream (f,old->stream[i])->endaction = ENDSTR_KILL; } } if (ts_file_stream (f,old->pmt_pid) != NULL) { ts_file_stream (f,old->pmt_pid)->endaction = ENDSTR_CLOSE; }}/* Release old programs that are no longer valid. * Old programs are marked with pat_section < 0. * If f!=NULL, then also unmap all the old programs (used with current pat). * Precondition: pp!=NULL. */static void release_old_progs (file_descr *f, pmt_descr **pp){ pmt_descr *p; p = *pp; while (p != NULL) { if (p->pat_section < 0) { if (f != NULL) { unmap_old_program (f,p); } *pp = p->next; free (p); } else { pp = &p->next; } p = *pp; }}static void eval_pat_section (file_descr *f, stream_descr *s, int seclen, int tsid, int versionnb, boolean curni, int sectionnb, int lastsecnb){ pmt_descr *p; byte *d; int i, l; warn (LINF,"eval PAT",ETST,5,seclen,tsid); if (curni) { if (versionnb != f->u.ts.newpat_version) { f->u.ts.newpat_version = versionnb; p = f->u.ts.newpat; while (p != NULL) { p->pat_section = -1; p = p->next; } } d = &s->u.m.psi_data[TS_SECTIONHEAD]; l = seclen - TS_PATSECT_SIZE; while (l >= TS_PATPROG_SIZE) { i = (d[0] << 8) + d[1]; if (i != 0) { p = f->u.ts.newpat; while ((p != NULL) && (p->programnumber != i)) { p = p->next; } warn (LDEB,"eval PAT 2",ETST,i,(long)f->u.ts.newpat,p); if (p == NULL) { if ((p = malloc (sizeof(pmt_descr))) == NULL) { warn (LERR,"PAT malloc failed",ETST,5,3,sizeof(pmt_descr)); return; } p->next = f->u.ts.newpat; p->pmt_version = 0xFF; p->programnumber = i; p->pcr_pid = 0; p->streams = 0; p->descrlen = 0; f->u.ts.newpat = p; } p->pat_section = sectionnb; p->pmt_pid = ((d[2] & 0x1F) << 8) + d[3]; } d += TS_PATPROG_SIZE; l -= TS_PATPROG_SIZE; } if (l != 0) { warn (LWAR,"PAT data error",ETST,5,2,seclen); } else { if (sectionnb == lastsecnb) { p = f->u.ts.pat; while (p != NULL) { warn (LDEB,"eval PAT 3",ETST,p->pcr_pid,p->pat_section,p); p->pat_section = -1; p = p->next; } release_old_progs (NULL,&f->u.ts.newpat); p = f->u.ts.newpat; while (p != NULL) { remap_new_program (f,p); p = p->next; } release_old_progs (f,&f->u.ts.pat); } } } else { if (versionnb == f->u.ts.pat_version) { warn (LWAR,"Same PAT version w/o cni",ETST,5,1,versionnb); } }}static void eval_cat_section (file_descr *f, stream_descr *s, int seclen, int versionnb, boolean curni, int sectionnb, int lastsecnb){}static void eval_pmt_section (file_descr *f, stream_descr *s, int seclen, int prognb, int versionnb, boolean curni){ pmt_descr *p; int i, epid, esil; byte *d; byte styp; warn (LINF,"eval PMT",ETST,6,seclen,prognb); p = f->u.ts.newpat; while ((p != NULL) && (p->programnumber != prognb)) { p = p->next; } if (curni) { if (p == NULL) { warn (LWAR,"Program not in PAT",ETST,6,1,prognb); } else { p->pmt_version = versionnb; p->pcr_pid = ((s->u.m.psi_data[TS_PMT_PCRPID] & 0x1F) << 8) + s->u.m.psi_data[TS_PMT_PCRPID+1]; p->streams = 0; p->descrlen = seclen-TS_PMT_PILEN-CRC_SIZE; memcpy (&p->elemdescr[0],&s->u.m.psi_data[TS_PMT_PILEN], seclen-TS_PMT_PILEN-CRC_SIZE); i = ((s->u.m.psi_data[TS_PMT_PILEN] & 0x0F) << 8) + s->u.m.psi_data[TS_PMT_PILEN+1]; d = &s->u.m.psi_data[TS_PMTSECTHEAD+i]; i = seclen - i - TS_PMTSECT_SIZE; while (i >= TS_PMTELEM_SIZE) { i -= TS_PMTELEM_SIZE; styp = *d++; epid = (*d++ & 0x1F) << 8; epid = epid | *d++; if ((epid >= TS_PID_LOWEST) && (epid <= TS_PID_HIGHEST)) { p->stream[p->streams] = epid; p->streamtype[p->streams] = styp; p->streams += 1; if ((ts_file_stream(f,epid) != NULL) && (ts_file_stream(f,epid)->streamdata == sd_data) && (ts_file_stream(f,epid)->u.d.mapstream == ts_file_stream(f,0))) { ts_file_stream(f,epid)->u.d.mapstream = s; warn (LIMP,"PMT stream caught",ETST,6,5,epid); } esil = (*d++ & 0x0F) << 8; esil = esil | *d++; d += esil; i -= esil; } else { warn (LWAR,"PMT data error",ETST,6,3,epid); i = -1; } } if (i != 0) { warn (LWAR,"PMT data error",ETST,6,2,i); p->streams = 0; } else { remap_new_program (f,p); release_old_progs (f,&f->u.ts.pat); } } } else { if ((p != NULL) && (versionnb == p->pmt_version)) { warn (LWAR,"PMT next same version",ETST,6,4,versionnb); } }}/* Extract a partial PSI section from a TS packet. * If complete, process its contents (via eval_*_section) * Precondition: f!=NULL * Return: TRUE if something was processed, FALSE if no data/space available */static boolean ts_psi_table_section (file_descr *f, int pid, int tableid){ stream_descr *s; int i, b, adf; int seclen; boolean complete; warn (LDEB,"PSI",ETST,4,pid,tableid); adf = f->data.out; list_incr (f->data.out,f->data,TS_PACKET_SIZE - paylen); s = ts_file_stream (f,pid); if (pusi & TS_UNIT_START) { i = f->data.ptr[f->data.out]; if (i >= paylen) { warn (LWAR,"PSI pointer exceed",ETST,4,1,b); s->u.m.psi_length = 0; list_incr (f->data.out,f->data,paylen); return (TRUE); } if (s->u.m.psi_length == 0) { b = i + 1; complete = FALSE; } else { seclen = s->u.m.psi_length + i; b = 1; complete = TRUE; } } else { if (s->u.m.psi_length == 0) { f->total += TS_PACKET_SIZE; list_incr (f->data.out,f->data,paylen); return (TRUE); } else { b = 0; complete = FALSE; } } list_incr (f->data.out,f->data,b); b = paylen - b; if (s->u.m.psi_length + b > sizeof(s->u.m.psi_data)) { warn (LWAR,"PSI overflow",ETST,4,2,s->u.m.psi_length + b); s->u.m.psi_length = 0; list_incr (f->data.out,f->data,b); return (TRUE); } ts_adaption_field (f,adf,s,s); while (b > 0) { i = MAX_DATA_RAWB - f->data.out;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -