📄 splitts.c
字号:
if (i > b) { i = b; } memcpy (&s->u.m.psi_data[s->u.m.psi_length], &f->data.ptr[f->data.out],i); list_incr (f->data.out,f->data,i); s->u.m.psi_length += i; b -= i; } if (complete) { if (s->u.m.psi_length >= TS_HEADSLEN) { i = ((s->u.m.psi_data[TS_SECTIONLEN] & 0x0F) << 8) + s->u.m.psi_data[TS_SECTIONLEN+1] + TS_HEADSLEN; } else { i = 0; } if (seclen != i) { warn (LWAR,"PSI length wrong",ETST,4,i,seclen); s->u.m.psi_length -= seclen; memmove (&s->u.m.psi_data[0],&s->u.m.psi_data[seclen],s->u.m.psi_length); complete = FALSE; } } if (!complete) { if (s->u.m.psi_length >= TS_HEADSLEN) { seclen = ((s->u.m.psi_data[TS_SECTIONLEN] & 0x0F) << 8) + s->u.m.psi_data[TS_SECTIONLEN+1] + TS_HEADSLEN; if (s->u.m.psi_length >= seclen) { complete = TRUE; } } } while (complete) { if (tableid < 0) { if (marker_check (s->u.m.psi_data[TS_SECTIONLEN],0x00,0x40)) { warn (LWAR,"PSI section syntax ind",ETST,4,5, s->u.m.psi_data[TS_SECTIONLEN]); } } else if (s->u.m.psi_data[TS_TABLE_ID] == tableid) { if (marker_check (s->u.m.psi_data[TS_SECTIONLEN],0x80,0xC0)) { warn (LWAR,"PSI section syntax ind",ETST,4,6, s->u.m.psi_data[TS_SECTIONLEN]); } else { unsigned char a; a = s->u.m.psi_data[TS_VERSIONNB]; if ((i = update_crc_32_block (CRC_INIT_32, &s->u.m.psi_data[0],seclen)) != 0) { warn (LWAR,"PSI CRC error",ETST,4,11,i); } else { i = (s->u.m.psi_data[TS_TRANSPORTID] << 8) + s->u.m.psi_data[TS_TRANSPORTID+1]; switch (tableid) { case TS_TABLEID_PAT: if (seclen <= TS_MAX_SECTLEN) { eval_pat_section (f,s,seclen,i,(a >> 1) & 0x1F,a & 1, s->u.m.psi_data[TS_SECTIONNB],s->u.m.psi_data[TS_LASTSECNB]); } else { warn (LWAR,"PSI data error",ETST,4,8,seclen); } break; case TS_TABLEID_CAT: if ((i == 0xFFFF) && (seclen <= TS_MAX_SECTLEN)) { eval_cat_section (f,s,seclen,(a >> 1) & 0x1F,a & 1, s->u.m.psi_data[TS_SECTIONNB],s->u.m.psi_data[TS_LASTSECNB]); } else { warn (LWAR,"PSI data error",ETST,4,9,seclen); } break; case TS_TABLEID_PMT: if ((s->u.m.psi_data[TS_SECTIONNB] == 0) && (s->u.m.psi_data[TS_LASTSECNB] == 0) && (seclen <= TS_MAX_SECTLEN) && (seclen >= TS_PMTSECT_SIZE)) { eval_pmt_section (f,s,seclen,i,(a >> 1) & 0x1F,a & 1); } else { warn (LWAR,"PSI data error",ETST,4,10,seclen); } break; } } } } else { warn (LWAR,"PSI wrong table id",ETST,4,4,s->u.m.psi_data[TS_TABLE_ID]); } complete = FALSE; s->u.m.psi_length -= seclen; if (s->u.m.psi_length > 0) { if (s->u.m.psi_data[seclen] == TS_TABLEID_STUFFING) { s->u.m.psi_length = 0; } else { memmove (&s->u.m.psi_data[0],&s->u.m.psi_data[seclen], s->u.m.psi_length); if (s->u.m.psi_length >= TS_HEADSLEN) { seclen = ((s->u.m.psi_data[TS_SECTIONLEN] & 0x0F) << 8) + s->u.m.psi_data[TS_SECTIONLEN+1] + TS_HEADSLEN; if (s->u.m.psi_length >= seclen) { complete = TRUE; } } } } } return (TRUE);}/* Check for a single tsauto entry, whether a given pes id matches * For each program in source PAT/PMT check and connect if applicable. * If none matches, but tsauto entry is sprg=unknown, check that sid. * Precondition: f!=NULL. * Return: TRUE, if at least one match, FALSE otherwise. */static boolean split_autostreammatch (file_descr *f, int pid, byte sid, tsauto_descr *a){ int i; boolean match, inpmt; pmt_descr *pmt; match = FALSE; inpmt = FALSE; pmt = f->u.ts.pat; while (pmt != NULL) { i = pmt->streams; while (--i >= 0) { if (pmt->stream[i] == pid) { inpmt = TRUE; if (a == NULL) { warn (LIMP,"Auto T",ETST,13,sid,pmt->programnumber); ts_file_stream (f,pid) = connect_streamprog (f,pmt->programnumber,pid, -sid,guess_streamtype(sid), ts_file_stream (f,pid), ts_file_stream (f,pmt->pmt_pid),TRUE); match = TRUE; i = 0; } else { if (a->sprg > 0) { if (a->sprg == pmt->programnumber) { if (a->ssid < 0) { warn (LIMP,"Auto P",ETST,13,sid,a->tprg); ts_file_stream (f,pid) = connect_streamprog (f,a->tprg,pid, -sid,guess_streamtype(sid), ts_file_stream (f,pid), ts_file_stream (f,pmt->pmt_pid),TRUE); match = TRUE; i = 0; } else if (a->ssid == sid) { warn (LIMP,"Auto S",ETST,13,a->tsid,a->tprg); ts_file_stream (f,pid) = connect_streamprog (f,a->tprg,pid, a->tsid,guess_streamtype(a->tsid<0?-a->tsid:a->tsid), ts_file_stream (f,pid), ts_file_stream (f,pmt->pmt_pid),TRUE); match = TRUE; i = 0; } } } } } } pmt = pmt->next; } if ((!inpmt) /* pid not registered in PAT/PMT -> check for unknown sprg */ && (a != NULL) && (a->sprg == 0) && (a->ssid == sid)) { warn (LIMP,"Auto 0",ETST,9,a->tsid,a->tprg); ts_file_stream (f,pid) = connect_streamprog (f,a->tprg,pid, a->tsid,guess_streamtype(a->tsid<0?-a->tsid:a->tsid), ts_file_stream (f,pid), ts_file_stream (f,0),TRUE); match = TRUE; } return (match);}/* For a packet that does not belong to an active stream, check whether * to open a stream for it automatically. * Precondition: f!=NULL. * Return: TRUE, if a stream was opened now, FALSE otherwise. */static boolean split_autostream (file_descr *f, int pid){ pmt_descr *pmt; boolean r; tsauto_descr *a; tsauto_descr **aa; warn (LDEB,"Auto Stream",ETST,9,0,pid); r = FALSE; if (pusi & TS_UNIT_START) { if ((f->automatic) || (f->u.ts.tsauto != NULL)) { if (paylen >= PES_HDCODE_SIZE) { int x; x = f->data.out; list_incr (x,f->data,TS_PACKET_SIZE - paylen); if (f->data.ptr[x] == 0x00) { list_incr (x,f->data,1); if (f->data.ptr[x] == 0x00) { list_incr (x,f->data,1); if (f->data.ptr[x] == 0x01) { list_incr (x,f->data,1); pmt = f->u.ts.pat; while (pmt != NULL) { if (pmt->pmt_pid == pid) { warn (LWAR,"Auto PMT PID",ETST,9,r,pid); return (r); } pmt = pmt->next; } if (f->automatic) { split_autostreammatch (f,pid,f->data.ptr[x],NULL); r = TRUE; } aa = &f->u.ts.tsauto; a = *aa; while (a != NULL) { if (split_autostreammatch (f,pid,f->data.ptr[x],a)) { r = TRUE; if (a->ssid >= 0) { *aa = a->next; /* delete single entries when matched */ free (a); } else { aa = &((a)->next); } } else { aa = &((a)->next); } a = *aa; } } } } } } } return (r);}/* For a packet that does not belong to an active stream, check whether * it is categorized to be unparsed SI. * Precondition: f!=NULL, f->content==ct_transport. * Return: higher bound of range, if it is unparsed SI, -1 otherwise. */int split_unparsedsi (file_descr *f, int pid){ tssi_descr *tssi; tssi = f->u.ts.tssi; while (tssi != NULL) { warn (LDEB,"Split Chk SI",ETST,12,tssi->pid_low,tssi->pid_high); if ((pid >= tssi->pid_low) && (pid <= tssi->pid_high)) { warn (LDEB,"Split Chk SI",ETST,12,-1,pid); return (tssi->pid_high); } tssi = tssi->next; } warn (LDEB,"Split Chk SI",ETST,12,pid,-1); return (-1);}/* Extract one TS packet of not-to-be-parsed SI. * Precondition: f!=NULL, pid is unparsed_si, * list_size(f->data) >= TS_PACKET_SIZE. * Return: TRUE if something was processed, FALSE if no data/space available */static boolean ts_unparsed_si (file_descr *f){ stream_descr *s; ctrl_buffer *c; s = ts_file_stream (f,TS_UNPARSED_SI); if (s != NULL) { if (!list_full (s->ctrl)) { c = &s->ctrl.ptr[s->ctrl.in]; if (list_free (s->data) >= (2*TS_PACKET_SIZE-1)) { if (TS_PACKET_SIZE > list_freeinend (s->data)) { s->data.in = 0; } c->index = s->data.in; c->length = 0; while (c->length < TS_PACKET_SIZE) { int i; i = MAX_DATA_RAWB - f->data.out; if (i > (TS_PACKET_SIZE - c->length)) { i = TS_PACKET_SIZE - c->length; } memcpy (&s->data.ptr[s->data.in],&f->data.ptr[f->data.out],i); list_incr (s->data.in,s->data,i); list_incr (f->data.out,f->data,i); c->length += i; } f->payload += TS_PACKET_SIZE; c->sequence = f->sequence++; c->scramble = 0; c->msecread = msec_now ();/* c->msecpush not set, because there is no scr/pcr or similar available *//* c->pcr.valid = FALSE; c->opcr.valid = FALSE;*/ list_incr (s->ctrl.in,s->ctrl,1); } else { return (FALSE); } } else { return (FALSE); } } else { list_incr (f->data.out,f->data,TS_PACKET_SIZE); } f->total += TS_PACKET_SIZE; return (TRUE);}/* Check an otherwise unused stream for PCR. * Precondition: f!=NULL */void split_checkpcrpid (file_descr *f, int pid){ pmt_descr *pmt; pmt = f->u.ts.pat; while (pmt != NULL) { if (pmt->pcr_pid == pid) { ts_adaption_field (f,f->data.out, ts_file_stream (f,pmt->pmt_pid),ts_file_stream (f,pmt->pmt_pid)); return;/* only needed, if any of the streams is in use, but then the pcr * evaluation might come too late. therefor eval always. */ } pmt = pmt->next; }}/* Split data from a TS stream. * Precondition: f!=NULL * Return: TRUE, if something was processed, FALSE if not enough data available */boolean split_ts (file_descr *f){ int l, pid; warn (LDEB,"Split TS",ETST,0,0,f); if (ts_skip_to_syncbyte (f)) { l = list_size (f->data); if (l >= TS_PACKET_SIZE) { pid = ts_packet_headinfo (&f->data); if ((pid >= TS_PID_LOWEST) && (pid <= TS_PID_HIGHEST)) { if (ts_file_stream (f,pid) != NULL) { if (ts_file_stream (f,pid)->streamdata == sd_data) { return (ts_data_stream (f,pid)); } else { return (ts_psi_table_section (f,pid,TS_TABLEID_PMT)); } } else { if (split_autostream (f,pid)) { return (ts_data_stream (f,pid)); } if (split_unparsedsi (f,pid) >= 0) { warn (LDEB,"Unparsed SI",ETST,0,2,pid); return (ts_unparsed_si (f)); } split_checkpcrpid (f,pid); warn (LDEB,"Data Packet (ignored)",ETST,0,1,pid); f->total += TS_PACKET_SIZE; list_incr (f->data.out,f->data,TS_PACKET_SIZE); return (TRUE); } } else if (pid == TS_PID_PAT) { return (ts_psi_table_section (f,TS_PID_PAT,TS_TABLEID_PAT));/* } else if (pid == TS_PID_CAT) { return (ts_psi_table_section (f,TS_PID_CAT,TS_TABLEID_CAT));*/ } else if (pid == TS_PID_NULL) { f->total += TS_PACKET_SIZE; list_incr (f->data.out,f->data,TS_PACKET_SIZE); return (TRUE); } else if (split_unparsedsi (f,pid) >= 0) { warn (LDEB,"Unparsed SI",ETST,0,3,pid); return (ts_unparsed_si (f)); } else { /* don't skip 188 here, because it might be an asynchronity */ f->skipped += 1; f->total += 1; list_incr (f->data.out,f->data,1); return (TRUE); } } } return (FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -