version 1.6, 2001/04/25 16:17:05
|
version 1.7, 2001/04/30 15:58:29
|
Line 220 boolean splice_delstream (prog_descr *p,
|
Line 220 boolean splice_delstream (prog_descr *p,
|
return (FALSE); |
return (FALSE); |
} |
} |
|
|
|
void process_finish (void) |
|
{ |
|
warn (LIMP,"Finish",ETSC,6,0,0); |
|
} |
|
|
static int make_patsection (int section, |
static int make_patsection (int section, |
byte *dest) |
byte *dest) |
{ |
{ |
Line 329 static int make_pmtsection (stream_descr
|
Line 334 static int make_pmtsection (stream_descr
|
return (i + TS_TRANSPORTID); |
return (i + TS_TRANSPORTID); |
} |
} |
|
|
void process_finish (void) |
/* Check for generated psi data to-be-sent, select data source. |
|
* If PAT or PMT needs to be rebuild, do so. If PAT or PMT is (partially) |
|
* pending to be transmitted, select that to be packaged next. Otherwise |
|
* select data payload. Set pid, scramble mode and PES paket size. |
|
* Precondition: s!=NULL, !list_empty(s->ctrl), s->streamdata==sd_data. |
|
* Input: stream s, current ctrl fifo out c. |
|
* Output: *pid, *scramble, *size (PES paket ~) for the stream to generate. |
|
*/ |
|
static void procdata_check_psi (int *pid, |
|
byte *scramble, |
|
int *size, |
|
stream_descr *s, |
|
ctrl_buffer *c) |
{ |
{ |
warn (LIMP,"Finish",ETSC,6,0,0); |
|
} |
|
|
|
stream_descr *process_something (stream_descr *s) |
|
{ |
|
byte *d; |
|
int pid; |
|
byte scramble; |
|
ctrl_buffer *c; |
|
int l, f, k; |
|
int privdata; |
|
int adapt_ext_len; |
|
t_msec now; |
t_msec now; |
byte adapt_field_ctrl; |
|
byte adapt_flags1, adapt_flags2; |
|
warn (LDEB,"Splice TS",ETSC,0,0,s->ctrl.out); |
|
if (s->isamap) { |
|
validate_mapref (s); |
|
return (NULL); |
|
} |
|
c = &s->ctrl.ptr[s->ctrl.out]; |
|
if (psi_size > 0) { |
if (psi_size > 0) { |
pid = psi_pid; |
*pid = psi_pid; |
scramble = 0; |
*scramble = 0; |
k = psi_size; |
*size = psi_size; |
} else { |
} else { |
if (unit_start != 0) { |
if (unit_start != 0) { |
now = msec_now (); |
now = msec_now (); |
if ((psi_frequency_changed) |
if ((psi_frequency_changed) |
|| ((psi_frequency_msec > 0) |
|| ((psi_frequency_msec > 0) |
&& ((next_psi_periodic - now) <= 0))) { |
&& ((next_psi_periodic - now) <= 0))) { |
|
int l; |
changed_pat = TRUE; |
changed_pat = TRUE; |
l = progs; |
l = progs; |
while (--l >= 0) { |
while (--l >= 0) { |
Line 383 stream_descr *process_something (stream_
|
Line 381 stream_descr *process_something (stream_
|
pat_section += 1; |
pat_section += 1; |
} |
} |
psi_done = 0; |
psi_done = 0; |
pid = psi_pid; |
*pid = psi_pid; |
scramble = 0; |
*scramble = 0; |
k = psi_size; |
*size = psi_size; |
} else { |
} else { |
|
int l; |
l = s->u.d.progs; |
l = s->u.d.progs; |
while (--l >= 0) { |
while (--l >= 0) { |
if (s->u.d.pdescr[l]->changed) { |
if (s->u.d.pdescr[l]->changed) { |
f = s->u.d.pdescr[l]->streams; |
int i; |
while ((--f >= 0) |
i = s->u.d.pdescr[l]->streams; |
&& (!s->u.d.pdescr[l]->stream[f]->u.d.mention)) { |
while ((--i >= 0) |
|
&& (!s->u.d.pdescr[l]->stream[i]->u.d.mention)) { |
} |
} |
if (f >= 0) { |
if (i >= 0) { |
psi_pid = s->u.d.pdescr[l]->pmt_pid; |
psi_pid = s->u.d.pdescr[l]->pmt_pid; |
conticnt = &s->u.d.pdescr[l]->pmt_conticnt; |
conticnt = &s->u.d.pdescr[l]->pmt_conticnt; |
psi_data[0] = 0; |
psi_data[0] = 0; |
psi_size = make_pmtsection (s,s->u.d.pdescr[l],&psi_data[1]) + 1; |
psi_size = make_pmtsection (s,s->u.d.pdescr[l],&psi_data[1]) + 1; |
psi_done = 0; |
psi_done = 0; |
pid = psi_pid; |
*pid = psi_pid; |
scramble = 0; |
*scramble = 0; |
k = psi_size; |
*size = psi_size; |
break; |
return; |
} |
} |
} |
} |
} |
} |
if (l < 0) { |
s->data.ptr[c->index+PES_STREAM_ID] = s->stream_id; |
s->data.ptr[c->index+PES_STREAM_ID] = s->stream_id; |
conticnt = &s->conticnt; |
conticnt = &s->conticnt; |
*pid = s->u.d.pid; |
pid = s->u.d.pid; |
*scramble = c->scramble; |
scramble = c->scramble; |
*size = c->length; |
k = c->length; |
|
} |
|
} |
} |
} else { |
} else { |
pid = s->u.d.pid; |
*pid = s->u.d.pid; |
scramble = c->scramble; |
*scramble = c->scramble; |
k = c->length; |
*size = c->length; |
} |
|
} |
|
d = output_pushdata (TS_PACKET_SIZE,c->msecpush + s->u.d.delta); |
|
if (d == NULL) { |
|
return (s); |
|
} |
|
if ((s->fdescr->content == ct_transport) |
|
&& (s == ts_file_stream (s->fdescr,TS_UNPARSED_SI))) { |
|
warn (LINF,"Splice Unparsed SI",ETSC,0,5,s->u.d.delta); |
|
memcpy (d,&s->data.ptr[c->index],c->length); |
|
list_incr (s->ctrl.out,s->ctrl,1); |
|
if (list_empty (s->ctrl)) { |
|
s->data.out = s->data.in; |
|
} else { |
|
s->data.out = s->ctrl.ptr[s->ctrl.out].index; |
|
} |
} |
return (NULL); |
|
} |
} |
adapt_ext_len = 1; |
} |
adapt_flags2 = 0; |
|
adapt_flags1 = 0; |
/* Check for adaption field items to be filled in. |
f = TS_PACKET_SIZE - TS_PACKET_HEADSIZE; |
* First assume no adaption field is set and the complete packet except the |
|
* header is available for payload. Then check which adaption fields have |
|
* to be set and decrease the free space accordingly. |
|
* Precondition: s!=NULL, !list_empty(s->ctrl), s->streamdata==sd_data. |
|
* Input: stream s, current ctrl fifo out c. |
|
* Output: *adapt_flags1, *adapt_flags2, *adapt_ext_len. |
|
* Return: number of bytes of free space available for payload. |
|
*/ |
|
static int procdata_adaptfield_flags (byte *adapt_flags1, |
|
byte *adapt_flags2, |
|
int *adapt_ext_len, |
|
stream_descr *s, |
|
ctrl_buffer *c) |
|
{ |
|
int space; |
|
*adapt_ext_len = 1; |
|
*adapt_flags2 = 0; |
|
*adapt_flags1 = 0; |
|
space = TS_PACKET_SIZE - TS_PACKET_HEADSIZE; |
if ((psi_size <= 0) |
if ((psi_size <= 0) |
&& (s->u.d.discontinuity)) { /* o, not for contents, but PCR-disco ? */ |
&& (s->u.d.discontinuity)) { /* o, not for contents, but PCR-disco ? */ |
s->u.d.discontinuity = FALSE; |
s->u.d.discontinuity = FALSE; |
adapt_flags1 |= TS_ADAPT_DISCONTI; |
*adapt_flags1 |= TS_ADAPT_DISCONTI; |
} |
} |
if (0) { |
if (0) { |
adapt_flags1 |= TS_ADAPT_RANDOMAC; |
*adapt_flags1 |= TS_ADAPT_RANDOMAC; |
} |
} |
if (0) { |
if (0) { |
adapt_flags1 |= TS_ADAPT_PRIORITY; |
*adapt_flags1 |= TS_ADAPT_PRIORITY; |
} |
} |
if ((psi_size <= 0) |
if ((psi_size <= 0) |
&& (s->u.d.has_clockref) |
&& (s->u.d.has_clockref) |
&& ((c->pcr.valid) |
&& ((c->pcr.valid) |
|| (s->u.d.next_clockref - (c->msecpush + s->u.d.delta) <= 0))) { |
|| (s->u.d.next_clockref - (c->msecpush + s->u.d.delta) <= 0))) { |
adapt_flags1 |= TS_ADAPT_PCRFLAG; |
*adapt_flags1 |= TS_ADAPT_PCRFLAG; |
f -= 6; |
space -= 6; |
} |
} |
if ((psi_size <= 0) |
if ((psi_size <= 0) |
&& ((c->opcr.valid) |
&& ((c->opcr.valid) |
|| ((!s->u.d.has_opcr) |
|| ((!s->u.d.has_opcr) |
&& (c->pcr.valid)))) { |
&& (c->pcr.valid)))) { |
adapt_flags1 |= TS_ADAPT_OPCRFLAG; |
*adapt_flags1 |= TS_ADAPT_OPCRFLAG; |
f -= 6; |
space -= 6; |
} |
} |
if (0) { |
if (0) { |
adapt_flags1 |= TS_ADAPT_SPLICING; |
*adapt_flags1 |= TS_ADAPT_SPLICING; |
f -= 1; |
space -= 1; |
} |
} |
if (0) { |
if (0) { |
adapt_flags1 |= TS_ADAPT_TPRIVATE; |
int privdata; |
|
*adapt_flags1 |= TS_ADAPT_TPRIVATE; |
privdata = 0; |
privdata = 0; |
f -= (privdata + 1); |
space -= (privdata + 1); |
} |
} |
if (0) { |
if (0) { |
adapt_flags2 |= TS_ADAPT2_LTWFLAG; |
*adapt_flags2 |= TS_ADAPT2_LTWFLAG; |
adapt_ext_len += 2; |
*adapt_ext_len += 2; |
} |
} |
if (0) { |
if (0) { |
adapt_flags2 |= TS_ADAPT2_PIECEWRF; |
*adapt_flags2 |= TS_ADAPT2_PIECEWRF; |
adapt_ext_len += 3; |
*adapt_ext_len += 3; |
} |
} |
if (0) { |
if (0) { |
adapt_flags2 |= TS_ADAPT2_SEAMLESS; |
*adapt_flags2 |= TS_ADAPT2_SEAMLESS; |
adapt_ext_len += 5; |
*adapt_ext_len += 5; |
} |
} |
if (adapt_flags2 != 0) { |
if (*adapt_flags2 != 0) { |
adapt_flags1 |= TS_ADAPT_EXTENSIO; |
*adapt_flags1 |= TS_ADAPT_EXTENSIO; |
f -= adapt_ext_len; |
space -= *adapt_ext_len; |
} |
} |
if (adapt_flags1 != 0) { |
if (*adapt_flags1 != 0) { |
f -= 2; |
space -= 2; |
} |
} |
if (k < f) { |
return (space); |
l = k; |
} |
|
|
|
/* Adjust size of adaption field against size of payload. Set flags. |
|
* Input: *space (number of bytes of free space available for payload), |
|
* *adapt_flags1, size (number of bytes left to be sent). |
|
* Output: *space (corrected in case of padding is done via adaption field), |
|
* *adapt_field_ctrl. |
|
* Return: Number of bytes of payload to be inserted into THIS packet. |
|
*/ |
|
static int procdata_adaptfield_frame (int *space, |
|
byte *adapt_field_ctrl, |
|
byte adapt_flags1, |
|
int size) |
|
{ |
|
int payload; |
|
if (size < *space) { |
|
payload = size; |
if (adapt_flags1 == 0) { |
if (adapt_flags1 == 0) { |
f -= 1; |
*space -= 1; |
if (f > l) { |
if (*space > payload) { |
f -= 1; |
*space -= 1; |
} |
} |
} |
} |
adapt_field_ctrl = TS_AFC_BOTH; |
*adapt_field_ctrl = TS_AFC_BOTH; |
} else { |
} else { |
l = f; |
payload = *space; |
if (f == 0) { |
if (payload == 0) { |
adapt_field_ctrl = TS_AFC_ADAPT; |
*adapt_field_ctrl = TS_AFC_ADAPT; |
} else if (adapt_flags1 == 0) { |
} else if (adapt_flags1 == 0) { |
adapt_field_ctrl = TS_AFC_PAYLD; |
*adapt_field_ctrl = TS_AFC_PAYLD; |
} else { |
} else { |
adapt_field_ctrl = TS_AFC_BOTH; |
*adapt_field_ctrl = TS_AFC_BOTH; |
} |
} |
} |
} |
|
return (payload); |
|
} |
|
|
|
/* Generate packet header. |
|
* Keep track of continuity counter (which is selected in procdata_check_psi). |
|
* Precondition: d!=NULL (data destination). |
|
* Input: pid, scramble, adaption_field_ctrl. |
|
* Return: d (increased by header size). |
|
*/ |
|
static byte *procdata_syn_head (byte *d, |
|
int pid, |
|
byte scramble, |
|
byte adapt_field_ctrl) |
|
{ |
*d++ = TS_SYNC_BYTE; |
*d++ = TS_SYNC_BYTE; |
warn (LSEC,"Splice unitstart",ETSC,0,1,unit_start); |
warn (LSEC,"Splice unitstart",ETSC,7,1,unit_start); |
warn (LSEC,"Splice PID",ETSC,0,2,pid); |
warn (LSEC,"Splice PID",ETSC,7,2,pid); |
*d++ = (0 << 7) /* transport_error_indicator */ |
*d++ = (0 << 7) /* transport_error_indicator */ |
| unit_start |
| unit_start |
| (0 << 5) /* transport_priority */ |
| (0 << 5) /* transport_priority */ |
Line 524 stream_descr *process_something (stream_
|
Line 555 stream_descr *process_something (stream_
|
*d++ = (scramble << 6) |
*d++ = (scramble << 6) |
| adapt_field_ctrl |
| adapt_field_ctrl |
| *conticnt; |
| *conticnt; |
warn (LSEC,"Splice continuity cnt",ETSC,0,3,*conticnt); |
warn (LSEC,"Splice continuity cnt",ETSC,7,3,*conticnt); |
if (adapt_field_ctrl & TS_AFC_PAYLD) { |
if (adapt_field_ctrl & TS_AFC_PAYLD) { |
*conticnt = (*conticnt+1) & 0x0F; |
*conticnt = (*conticnt+1) & 0x0F; |
} |
} |
|
return (d); |
|
} |
|
|
|
/* Generate adpation field. |
|
* This MUST match the calculations in procdata_adaptfield_flags. |
|
* Precondition: s!=NULL. |
|
* Input: s (stream), c (current ctrl fifo out), d (data destination), |
|
* padding (number of padding bytes needed), payload (number of payload bytes |
|
* to insert), adapt_field_ctrl, adapt_flags1, adapt_flags2, adapt_ext_len. |
|
* Return: d (increased by adaption field size). |
|
*/ |
|
static byte *procdata_syn_adaptfield (stream_descr *s, |
|
ctrl_buffer *c, |
|
byte *d, |
|
int padding, |
|
int payload, |
|
byte adapt_field_ctrl, |
|
byte adapt_flags1, |
|
byte adapt_flags2, |
|
int adapt_ext_len) |
|
{ |
if (adapt_field_ctrl & TS_AFC_ADAPT) { |
if (adapt_field_ctrl & TS_AFC_ADAPT) { |
if ((*d++ = (TS_PACKET_SIZE - TS_PACKET_FLAGS1) - l) != 0) { |
if ((*d++ = (TS_PACKET_SIZE - TS_PACKET_FLAGS1) - payload) != 0) { |
*d++ = adapt_flags1; |
*d++ = adapt_flags1; |
if (adapt_flags1 & TS_ADAPT_PCRFLAG) { |
if (adapt_flags1 & TS_ADAPT_PCRFLAG) { |
clockref pcr; |
clockref pcr; |
Line 574 stream_descr *process_something (stream_
|
Line 626 stream_descr *process_something (stream_
|
} |
} |
} |
} |
} |
} |
if (f > l) { |
if (padding > 0) { |
warn (LSEC,"Splice padding",ETSC,0,4,f-l); |
warn (LSEC,"Splice padding",ETSC,8,1,padding); |
memset (d,-1,f-l); |
memset (d,-1,padding); |
d += (f-l); |
d += padding; |
} |
} |
} |
} |
if (l > 0) { |
return (d); |
|
} |
|
|
|
/* Generate payload portion. |
|
* Insert the appropriate payload (either PSI or data), check whether payload |
|
* from this PES packet or section is left. |
|
* Precondition: s!=NULL. |
|
* Input: s (stream), c (current ctrl fifo out), d (data destination), |
|
* payload (number of payload bytes to insert). |
|
* Return: processed stream s, if there is more data from the current PES |
|
* packet to be processed, NULL otherwise. |
|
*/ |
|
static stream_descr *procdata_syn_payload (stream_descr *s, |
|
ctrl_buffer *c, |
|
byte *d, |
|
int payload) |
|
{ |
|
if (payload > 0) { |
if (psi_size > 0) { |
if (psi_size > 0) { |
memcpy (d,&psi_data[psi_done],l); |
memcpy (d,&psi_data[psi_done],payload); |
if (l < psi_size) { |
if (payload < psi_size) { |
warn (LSEC,"Splice PSI Data",ETSC,0,s->stream_id,l); |
warn (LSEC,"Splice PSI Data",ETSC,9,s->stream_id,payload); |
psi_done += l; |
psi_done += payload; |
psi_size -= l; |
psi_size -= payload; |
unit_start = 0; |
unit_start = 0; |
} else { |
} else { |
warn (LINF,"Splice PSI Done",ETSC,0,s->stream_id,l); |
warn (LINF,"Splice PSI Done",ETSC,9,s->stream_id,payload); |
psi_done = psi_size = 0; |
psi_done = psi_size = 0; |
unit_start = TS_UNIT_START; |
unit_start = TS_UNIT_START; |
} |
} |
} else { |
} else { |
memcpy (d,&s->data.ptr[c->index],l); |
memcpy (d,&s->data.ptr[c->index],payload); |
if (l < c->length) { |
if (payload < c->length) { |
warn (LSEC,"Splice Data",ETSC,0,s->stream_id,l); |
warn (LSEC,"Splice Data",ETSC,9,s->stream_id,payload); |
c->length -= l; |
c->length -= payload; |
s->data.out = (c->index += l); |
s->data.out = (c->index += payload); |
unit_start = 0; |
unit_start = 0; |
} else { |
} else { |
warn (LINF,"Splice Done",ETSC,0,s->stream_id,l); |
warn (LINF,"Splice Done",ETSC,9,s->stream_id,payload); |
list_incr (s->ctrl.out,s->ctrl,1); |
list_incr (s->ctrl.out,s->ctrl,1); |
if (list_empty (s->ctrl)) { |
if (list_empty (s->ctrl)) { |
s->data.out = s->data.in; |
s->data.out = s->data.in; |
} else { |
} else { |
s->data.out = s->ctrl.ptr[s->ctrl.out].index; |
s->data.out = s->ctrl.ptr[s->ctrl.out].index; |
} |
} |
s = NULL; |
|
unit_start = TS_UNIT_START; |
unit_start = TS_UNIT_START; |
|
return (NULL); |
} |
} |
} |
} |
} |
} |
return (s); |
return (s); |
} |
} |
|
|
|
/* Process unparsed si data and generate output. |
|
* Take one TS paket, copy it to output stream data buffer. |
|
* Precondition: s!=NULL, !list_empty(s->ctrl), s->streamdata==sd_unparsedsi, |
|
* s->ctrl.ptr[s->ctrl.out].length==TS_PACKET_SIZE, d!=NULL. |
|
*/ |
|
static void proc_unparsedsi (stream_descr *s, |
|
byte *d) |
|
{ |
|
warn (LINF,"Splice Unparsed SI",ETSC,10,0,s->u.usi.delta); |
|
memcpy (d,&s->data.ptr[s->ctrl.ptr[s->ctrl.out].index],TS_PACKET_SIZE); |
|
/* check if == s->ctrl.ptr[s->ctrl.out].length); ? */ |
|
list_incr (s->ctrl.out,s->ctrl,1); |
|
if (list_empty (s->ctrl)) { |
|
s->data.out = s->data.in; |
|
} else { |
|
s->data.out = s->ctrl.ptr[s->ctrl.out].index; |
|
} |
|
} |
|
|
|
stream_descr *process_something (stream_descr *s) |
|
{ |
|
byte *d; |
|
int pid; |
|
byte scramble; |
|
int size; |
|
ctrl_buffer *c; |
|
int payload; |
|
int space; |
|
int adapt_ext_len; |
|
byte adapt_field_ctrl; |
|
byte adapt_flags1, adapt_flags2; |
|
warn (LDEB,"Splice TS",ETSC,0,0,s->ctrl.out); |
|
switch (s->streamdata) { |
|
case sd_data: |
|
c = &s->ctrl.ptr[s->ctrl.out]; |
|
procdata_check_psi (&pid, &scramble, &size, s, c); |
|
d = output_pushdata (TS_PACKET_SIZE,c->msecpush + s->u.d.delta); |
|
if (d == NULL) { |
|
return (s); |
|
} |
|
space = procdata_adaptfield_flags (&adapt_flags1, &adapt_flags2, |
|
&adapt_ext_len, s, c); |
|
payload = procdata_adaptfield_frame (&space, &adapt_field_ctrl, adapt_flags1, size); |
|
d = procdata_syn_head (d, pid, scramble, adapt_field_ctrl); |
|
d = procdata_syn_adaptfield (s, c, d, space-payload, payload, adapt_field_ctrl, |
|
adapt_flags1, adapt_flags2, adapt_ext_len); |
|
return (procdata_syn_payload (s, c, d, payload)); |
|
break; |
|
case sd_map: |
|
validate_mapref (s); |
|
return (NULL); |
|
break; |
|
case sd_unparsedsi: |
|
c = &s->ctrl.ptr[s->ctrl.out]; |
|
d = output_pushdata (TS_PACKET_SIZE,c->msecpush + s->u.usi.delta); |
|
if (d == NULL) { |
|
return (s); |
|
} |
|
proc_unparsedsi (s,d); |
|
return (NULL); |
|
break; |
|
default: |
|
return (NULL); |
|
break; |
|
} |
|
} |
|
|