Diff for /multiplexer/splicets.c between versions 1.6 and 1.7

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;
     }
   }
   

Removed from v.1.6  
changed lines
  Added in v.1.7


LinuxTV legacy CVS <linuxtv.org/cvs>