⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splicets.c

📁 mpeg 解复用
💻 C
📖 第 1 页 / 共 2 页
字号:
    byte *y;    y = p->manudescr.refx[i];    if ((y == NULL)     && (s->u.d.mapstream != NULL)) {      y = s->u.d.mapstream->autodescr->refx[i]; /* why this one? */    }    if (y != NULL) {      int yl = y[1];      if (yl != 0) {        yl += 2;        memcpy (d,y,yl);        d += yl;      }    }  }  i = d - dest - (TS_PMT_PILEN+2);  dest[TS_PMT_PILEN] = 0xF0 | (i >> 8);  dest[TS_PMT_PILEN+1] = i;  i = p->streams;  while (--i >= 0) {    t = p->stream[i];    if (t->u.d.mention) {      int x;      byte *e;      *d++ = t->stream_type;      x = t->u.d.pid;      *d++ = 0xE0 | (x >> 8);      *d++ = x;      d += 2;      e = d;      x = NUMBER_DESCR;      while (--x >= 0) {        byte *y;        y = t->manudescr->refx[x];        if (y == NULL) {          y = t->autodescr->refx[x];        }        if (y != NULL) {          int yl = y[1];          if (yl != 0) {            yl += 2;            memcpy (d,y,yl);            d += yl;          }        }      }      x = d - e;      *--e = x;      *--e = 0xF0 | (x >> 8);    }  }  st = p->stump;  while (st != NULL) {    int x;    byte *e;    *d++ = st->stream_type;    x = st->pid;    *d++ = 0xE0 | (x >> 8);    *d++ = x;    d += 2;    e = d;    x = NUMBER_DESCR;    while (--x >= 0) {      byte *y;      y = st->manudescr.refx[x];      if (y != NULL) {        int yl = y[1];        if (yl != 0) {          yl += 2;          memcpy (d,y,yl);          d += yl;        }      }    }    x = d - e;    *--e = x;    *--e = 0xF0 | (x >> 8);    st = st->next;  }  i = d + CRC_SIZE - dest - TS_TRANSPORTID;  dest[TS_SECTIONLEN] = 0xB0 | (i >> 8);  dest[TS_SECTIONLEN+1] = i;  crc32_calc (dest,i + TS_TRANSPORTID - CRC_SIZE,d);  return (i + TS_TRANSPORTID);}/* 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){  t_msec now;  int i, l;  prog_descr *p;  if (psi_size > 0) {    *pid = psi_pid;    *scramble = 0;    *size = psi_size;  } else {    if (unit_start != 0) {      now = msec_now ();      if ((psi_frequency_changed)       || ((psi_frequency_msec > 0)        && ((next_psi_periodic - now) <= 0))) {        unchanged_pat = TRUE;        l = progs;        while (--l >= 0) {          prog[l]->unchanged = TRUE;        }        psi_frequency_changed = FALSE;        next_psi_periodic = now + psi_frequency_msec;      }      if (unchanged_pat || changed_pat) {        psi_pid = TS_PID_PAT;        conticnt = &pat_conticnt;        psi_data[0] = 0;        if ((pat_section == 0)         && (changed_pat)) {          nextpat_version = (nextpat_version+1) & 0x1F;        }        psi_size = make_patsection (pat_section,&psi_data[1]) + 1;        if (pat_section >= last_patsection) {          changed_pat = FALSE;          unchanged_pat = FALSE;          pat_section = 0;        } else {          pat_section += 1;        }        psi_done = 0;        *pid = psi_pid;        *scramble = 0;        *size = psi_size;      } else {        l = s->u.d.progs;        while (--l >= 0) {          p = s->u.d.pdescr[l];          if (p->unchanged || p->changed) {            i = p->streams;            while ((--i >= 0)                && (!p->stream[i]->u.d.mention)) {            }            if (i >= 0) {              psi_pid = p->pmt_pid;              conticnt = &p->pmt_conticnt;              psi_data[0] = 0;              if (p->changed) {                p->pmt_version = (p->pmt_version+1) & 0x1F;              }              psi_size = make_pmtsection (s,p,&psi_data[1]) + 1;              p->changed = FALSE;              p->unchanged = FALSE;              psi_done = 0;              *pid = psi_pid;              *scramble = 0;              *size = psi_size;              return;            }          }        }        s->data.ptr[c->index+PES_STREAM_ID] = s->stream_id;        conticnt = &s->conticnt;        *pid = s->u.d.pid;        *scramble = c->scramble;        *size = c->length;      }    } else {      *pid = s->u.d.pid;      *scramble = c->scramble;      *size = c->length;    }  }}/* Check for adaption field items to be filled in. * 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)   && (s->u.d.discontinuity)) { /* o, not for contents, but PCR-disco ? */    s->u.d.discontinuity = FALSE;    *adapt_flags1 |= TS_ADAPT_DISCONTI;  }  if (0) {    *adapt_flags1 |= TS_ADAPT_RANDOMAC;  }  if (0) {    *adapt_flags1 |= TS_ADAPT_PRIORITY;  }  if ((psi_size <= 0)   && (s->u.d.has_clockref)   && ((c->pcr.valid)    || (s->u.d.next_clockref - (c->msecpush + s->u.d.delta) <= 0))) {    *adapt_flags1 |= TS_ADAPT_PCRFLAG;    space -= 6;  }  if ((psi_size <= 0)   && ((c->opcr.valid)    || ((!s->u.d.has_opcr)     && (c->pcr.valid)))) {    *adapt_flags1 |= TS_ADAPT_OPCRFLAG;    space -= 6;  }  if (0) {    *adapt_flags1 |= TS_ADAPT_SPLICING;    space -= 1;  }  if (0) {    int privdata;    *adapt_flags1 |= TS_ADAPT_TPRIVATE;    privdata = 0;    space -= (privdata + 1);  }  if (0) {    *adapt_flags2 |= TS_ADAPT2_LTWFLAG;    *adapt_ext_len += 2;  }  if (0) {    *adapt_flags2 |= TS_ADAPT2_PIECEWRF;    *adapt_ext_len += 3;  }  if (0) {    *adapt_flags2 |= TS_ADAPT2_SEAMLESS;    *adapt_ext_len += 5;  }  if (*adapt_flags2 != 0) {    *adapt_flags1 |= TS_ADAPT_EXTENSIO;    space -= *adapt_ext_len;  }  if (*adapt_flags1 != 0) {    space -= 2;  }  return (space);}/* 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) {      *space -= 1;      if (*space > payload) {        *space -= 1;      }    }    *adapt_field_ctrl = TS_AFC_BOTH;  } else {    payload = *space;    if (payload == 0) {      *adapt_field_ctrl = TS_AFC_ADAPT;    } else if (adapt_flags1 == 0) {      *adapt_field_ctrl = TS_AFC_PAYLD;    } else {      *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;  warn (LSEC,"Splice unitstart",ETSC,7,1,unit_start);  warn (LSEC,"Splice PID",ETSC,7,2,pid);  *d++ = (0 << 7) /* transport_error_indicator */       | unit_start       | (0 << 5) /* transport_priority */       | (pid >> 8);  *d++ = pid;  *d++ = (scramble << 6)       | adapt_field_ctrl       | *conticnt;  warn (LSEC,"Splice continuity cnt",ETSC,7,3,*conticnt);  if (adapt_field_ctrl & TS_AFC_PAYLD) {    *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 ((*d++ = (TS_PACKET_SIZE - TS_PACKET_FLAGS1) - payload) != 0) {      *d++ = adapt_flags1;      if (adapt_flags1 & TS_ADAPT_PCRFLAG) {        clockref pcr;        msec2cref (&s->u.d.conv, c->msecpush + s->u.d.delta, &pcr);        *d++ = (pcr.base >> 25) | (pcr.ba33 << 7);        *d++ = pcr.base >> 17;        *d++ = pcr.base >> 9;        *d++ = pcr.base >> 1;        *d++ = (pcr.base << 7) | (pcr.ext >> 8) | 0x7E;        *d++ = pcr.ext;        s->u.d.next_clockref =          (c->msecpush + s->u.d.delta) + MAX_MSEC_PCRDIST;        c->pcr.valid = FALSE;      }      if (adapt_flags1 & TS_ADAPT_OPCRFLAG) {        clockref *opcr;        if (c->opcr.valid) {          opcr = &c->opcr;        } else {          opcr = &c->pcr;        }        *d++ = (opcr->base >> 25) | (opcr->ba33 << 7);        *d++ = opcr->base >> 17;        *d++ = opcr->base >> 9;        *d++ = opcr->base >> 1;        *d++ = (opcr->base << 7) | (opcr->ext >> 8) | 0x7E;        *d++ = opcr->ext;        opcr->valid = FALSE;      }      if (adapt_flags1 & TS_ADAPT_SPLICING) {      }      if (adapt_flags1 & TS_ADAPT_TPRIVATE) {      }      if (adapt_flags1 & TS_ADAPT_EXTENSIO) {        *d++ = adapt_ext_len;        *d++ = adapt_flags2 | 0x1F;        if (adapt_flags2 & TS_ADAPT2_LTWFLAG) {        }        if (adapt_flags2 & TS_ADAPT2_PIECEWRF) {        }        if (adapt_flags2 & TS_ADAPT2_SEAMLESS) {        }      }    }    if (padding > 0) {      warn (LSEC,"Splice padding",ETSC,8,1,padding);      memset (d,-1,padding);      d += padding;    }  }  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) {      memcpy (d,&psi_data[psi_done],payload);      if (payload < psi_size) {        warn (LSEC,"Splice PSI Data",ETSC,9,s->stream_id,payload);        psi_done += payload;        psi_size -= payload;        unit_start = 0;      } else {        warn (LINF,"Splice PSI Done",ETSC,9,s->stream_id,payload);        psi_done = psi_size = 0;        unit_start = TS_UNIT_START;      }    } else {      memcpy (d,&s->data.ptr[c->index],payload);      if (payload < c->length) {        warn (LSEC,"Splice Data",ETSC,9,s->stream_id,payload);        c->length -= payload;        s->data.out = (c->index += payload);        unit_start = 0;      } else {        warn (LINF,"Splice Done",ETSC,9,s->stream_id,payload);        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;        }        unit_start = TS_UNIT_START;        return (NULL);      }    }  }  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,s->sourceid,s->streamdata);  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;    input_closefileifunused (s->fdescr);  } 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, TRUE, 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, FALSE, 0);      if (d == NULL) {        return (s);      }      proc_unparsedsi (s,d);      return (NULL);      break;    default:      return (NULL);      break;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -