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

📄 splitts.c

📁 mpeg 解复用
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ISO 13818 stream multiplexer * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin * Author: Oskar Schirmer (schirmer@scara.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* * Module:  Split TS * Purpose: Split a transport stream. * * This module examines a transport stream and collects the packets to * the input stream buffers. PSI data is extracted (and stored in the * files pat structures), descriptors are copied to the corresponding * mapstreams. */#include "global.h"#include "error.h"#include "input.h"#include "splice.h"#include "ts.h"#include "pes.h"#include "descref.h"#include "splitpes.h"#include "splitts.h"#include "crc.h"static byte pusi, afcc, afflg1;static int paylen;/* Skip in input raw data buffer for TS-syncbyte. * Precondition: f!=NULL * Postcondition: if found: f->data.out indicates the syncbyte. * Return: TRUE if found, FALSE otherwise */static boolean ts_skip_to_syncbyte (file_descr *f){  int i, l, k;  boolean r = FALSE;  l = k = list_size (f->data);  i = f->data.out;  while ((l > 0)      && ((f->data.ptr[i] != TS_SYNC_BYTE) || (r = TRUE, FALSE))) {    list_incr (i,f->data,1);    l -= 1;  }  k -= l;  if (k > 0) {    warn (LWAR,"Skipped",ETST,1,1,k);    f->skipped += k;    f->total += k;    list_incr (f->data.out,f->data,k);  }  return (r);}/* Determine the PID of a TS packet and other details. * Procondition: d!=NULL points to a packet. * Postcondition: Set global "Payload Unit Start Indicator", "Adaption Field * Control & Continuity Counter", "Adataption Field Flags 1". * Return: 13 bit PID. */static int ts_packet_headinfo (refr_data *d){  int i, l;  i = d->out;  list_incr (i,*d,TS_PACKET_PID);  l = (pusi = d->ptr[i]) & 0x1F;  list_incr (i,*d,1);  l = (l << 8) | d->ptr[i];  list_incr (i,*d,1);  if (!((afcc = d->ptr[i]) & TS_AFC_BOTH)) {    l = TS_PID_NULL;  } else {    if (afcc & TS_AFC_ADAPT) {      byte aflen;      list_incr (i,*d,1);      if ((aflen = d->ptr[i]) == 0) {        afflg1 = 0x00;      } else {        list_incr (i,*d,1);        afflg1 = d->ptr[i];      }      paylen = TS_PACKET_SIZE - TS_PACKET_FLAGS1 - aflen;    } else {      paylen = TS_PACKET_SIZE - TS_PACKET_HEADSIZE;    }  }  warn (LSEC,"Packet PID",ETST,2,1,l);  warn (LDEB,"Packet PID",ETST,afcc,afflg1,paylen);  return (l);}/* Extract adaption field from a TS packet. * Distribute the information as needed (to s, s->ctrl, etc). * Precondition: f!=NULL, adf indicates a packet in f->data, s!=NULL is the * destined data stream, m!=NULL the map stream, afcc and afflg1 set. */static void ts_adaption_field (file_descr *f,    int adf,    stream_descr *s,    stream_descr *m){  warn (LDEB,"AdaptF",ETST,11,adf,afcc);  if (afcc & TS_AFC_ADAPT) {    list_incr (adf,f->data,TS_PACKET_FLAGS1+1);    if (afflg1 & TS_ADAPT_DISCONTI) {    }    if (afflg1 & TS_ADAPT_RANDOMAC) {    }    if (afflg1 & TS_ADAPT_PRIORITY) {    }    if (afflg1 & TS_ADAPT_PCRFLAG) {      clockref *pcr;      long b;      byte a;      pcr = &s->ctrl.ptr[s->ctrl.in].pcr;      a = f->data.ptr[adf];      list_incr (adf,f->data,1);      pcr->ba33 = (a >> 7) & 1;      b = (a << 8) | f->data.ptr[adf];      list_incr (adf,f->data,1);      b = (b << 8) | f->data.ptr[adf];      list_incr (adf,f->data,1);      b = (b << 8) | f->data.ptr[adf];      list_incr (adf,f->data,1);      a = f->data.ptr[adf];      pcr->base = (b << 1) | ((a >> 7) & 1);      marker_check (a,0x7E,0x7E);      list_incr (adf,f->data,1);      pcr->ext = ((a & 1) << 8) | f->data.ptr[adf];      warn (LINF,"PCR",ETST,10,pcr->ba33,pcr->base);      pcr->valid = TRUE;      list_incr (adf,f->data,1);/* attention ! what if it is not PCR_PID ? xxx */      if (S_ISREG (f->st_mode)) {        cref2msec (&m->u.m.conv, *pcr, &m->u.m.msectime);       } else {        cref2msec (&m->u.m.conv, *pcr, &m->u.m.msectime);       }    }    if (afflg1 & TS_ADAPT_OPCRFLAG) {      clockref *opcr;      long b;      byte a;      opcr = &s->ctrl.ptr[s->ctrl.in].opcr;      a = f->data.ptr[adf];      list_incr (adf,f->data,1);      opcr->ba33 = (a >> 7) & 1;      b = (a << 8) | f->data.ptr[adf];      list_incr (adf,f->data,1);      b = (b << 8) | f->data.ptr[adf];      list_incr (adf,f->data,1);      b = (b << 8) | f->data.ptr[adf];      list_incr (adf,f->data,1);      a = f->data.ptr[adf];      opcr->base = (b << 1) | ((a >> 7) & 1);      marker_check (a,0x7E,0x7E);      list_incr (adf,f->data,1);      opcr->ext = ((a & 1) << 8) | f->data.ptr[adf];      warn (LINF,"OPCR",ETST,10,opcr->ba33,opcr->base);      opcr->valid = TRUE;      s->u.d.has_opcr = TRUE;      list_incr (adf,f->data,1);    }    if (afflg1 & TS_ADAPT_SPLICING) {      list_incr (adf,f->data,1);    }    if (afflg1 & TS_ADAPT_TPRIVATE) {      byte tpdl;      tpdl = f->data.ptr[adf];      list_incr (adf,f->data,tpdl+1);    }    if (afflg1 & TS_ADAPT_EXTENSIO) {      byte afflg2, afel;      afel = f->data.ptr[adf];      list_incr (adf,f->data,1);      afflg2 = f->data.ptr[adf];      list_incr (adf,f->data,1);      if (afflg2 & TS_ADAPT2_LTWFLAG) {        list_incr (adf,f->data,2);      }      if (afflg2 & TS_ADAPT2_PIECEWRF) {        list_incr (adf,f->data,3);      }      if (afflg2 & TS_ADAPT2_SEAMLESS) {        list_incr (adf,f->data,5);      }    }  }}/* Parse one TS packet with given PID. * Depending on the actual state (c->length) and the contents of the packet, * provide the data into the stream and possibly complete a PES package. * c->length keeps the progress of data acquisition, as follows: *  =0: initial, waiting for payload unit start indicator *  <-2, increasing: not yet enough data to evaluate the PES header *  =-2: evaluate the PES packet length field *  =-1: acquiring packet with unspecified length *  >0, decreasing: amount of data still missing *  =0: final, close PES packet, start new one * Precondition: f!=NULL. * Return: TRUE if something was processed, FALSE if no data/space available */static boolean ts_data_stream (file_descr *f,    int pid){  stream_descr *s;  ctrl_buffer *c;  int i, fdo, sdi, adf;  warn (LDEB,"Data Packet",ETST,3,0,pid);  s = ts_file_stream (f,pid);  if (s != NULL) {    if (!list_full (s->ctrl)) {      c = &s->ctrl.ptr[s->ctrl.in];      if (c->length == -1) {        if (pusi & TS_UNIT_START) {          c->length = s->data.in - c->index;          warn (LINF,"Closed unbound packet",ETST,3,5,c->length);          f->payload += c->length;          c->sequence = f->sequence++;          c->scramble = 0;          c->msecread = msec_now ();          c->msecpush = s->u.d.mapstream->u.m.msectime;          list_incr (s->ctrl.in,s->ctrl,1);          c = &s->ctrl.ptr[s->ctrl.in];          c->length = 0;          c->pcr.valid = FALSE;          c->opcr.valid = FALSE;        }      }      if (c->length == 0) {        if (pusi & TS_UNIT_START) {          if (list_free (s->data) >=              (2*(PES_HEADER_SIZE-1+TS_PACKET_SIZE-TS_PACKET_HEADSIZE)-1)) {            if ((PES_HEADER_SIZE-1+TS_PACKET_SIZE-TS_PACKET_HEADSIZE)                > list_freeinend (s->data)) {              s->data.in = 0;            }            c->index = s->data.in;            c->length = -2 - PES_HEADER_SIZE;          } else {            return (FALSE);          }        } else {          f->skipped += TS_PACKET_SIZE;          list_incr (f->data.out,f->data,TS_PACKET_SIZE);          f->total += TS_PACKET_SIZE;          return (TRUE);        }      }      sdi = s->data.in;      fdo = adf = f->data.out;      list_incr (fdo,f->data,TS_PACKET_SIZE - paylen);      if (c->length == -1) {        if (list_freecachedin (s->data,sdi) >= paylen) {          i = list_freeinendcachedin (s->data,sdi);          if (i <= paylen) {            if (list_freecachedin (s->data,sdi) >=                (i + (sdi - c->index) + paylen)) {              sdi -= c->index;              memmove (&s->data.ptr[0],&s->data.ptr[c->index],sdi);              c->index = 0;            } else {              return (FALSE);            }          }          while (paylen > 0) {            i = MAX_DATA_RAWB - fdo;            if (i > paylen) {              i = paylen;            }            memcpy (&s->data.ptr[sdi],&f->data.ptr[fdo],i);            list_incr (sdi,s->data,i);            list_incr (fdo,f->data,i);            paylen -= i;          }        } else {          return (FALSE);        }      }      if (c->length < -2) {        c->length += paylen;        while (paylen > 0) {          i = MAX_DATA_RAWB - fdo;          if (i > paylen) {            i = paylen;          }          memcpy (&s->data.ptr[sdi],&f->data.ptr[fdo],i);          list_incr (sdi,s->data,i);          list_incr (fdo,f->data,i);          paylen -= i;        }        if (c->length > -2) {          c->length = -2;        }      }      if (c->length == -2) {        if ((s->data.ptr[c->index] != 0x00)         || (s->data.ptr[c->index+1] != 0x00)         || (s->data.ptr[c->index+2] != 0x01)) {          warn (LWAR,"Payload not good PES",ETST,3,3,0);          c->length = 0;          return (TRUE);        }        i = (s->data.ptr[c->index+PES_PACKET_LENGTH] << 8)           | s->data.ptr[c->index+PES_PACKET_LENGTH+1];        if (i == 0) {          warn (LSEC,"Payload length 0",ETST,3,4,0);          c->length = -1;        } else {          if (i > list_freeinendcachedin (s->data,c->index) - PES_HEADER_SIZE) {            if (list_freecachedin (s->data,sdi) <                  (2 * (i + PES_HEADER_SIZE) - (sdi - c->index) - 1)) {              return (FALSE);            } else {              sdi -= c->index;              memmove (&s->data.ptr[0],&s->data.ptr[c->index],sdi);              c->index = 0;            }          } else {            if (list_freecachedin (s->data,sdi) <                  (i + PES_HEADER_SIZE - (sdi - c->index))) {              return (FALSE);            }          }          c->length = i + PES_HEADER_SIZE - (sdi - c->index);          if (c->length < 0) {            warn (LWAR,"Too much payload",ETST,3,1,c->length);            c->length = 0;          }        }      }      if ((c->length > 0)       && (paylen > 0)) {        if (paylen > c->length) {          warn (LWAR,"Too much payload",ETST,3,2,c->length);          paylen = c->length;        }        c->length -= paylen;        while (paylen > 0) {          i = MAX_DATA_RAWB - fdo;          if (i > paylen) {            i = paylen;          }          memcpy (&s->data.ptr[sdi],&f->data.ptr[fdo],i);          list_incr (sdi,s->data,i);          list_incr (fdo,f->data,i);          paylen -= i;        }      }      s->data.in = sdi;      f->data.out = fdo;      ts_adaption_field (f,adf,s,s->u.d.mapstream);      if (c->length == 0) {        c->length = s->data.in - c->index;        f->payload += c->length;        c->sequence = f->sequence++;        c->scramble = 0;        c->msecread = msec_now ();        c->msecpush = s->u.d.mapstream->u.m.msectime;        list_incr (s->ctrl.in,s->ctrl,1);        c = &s->ctrl.ptr[s->ctrl.in];        c->length = 0;        c->pcr.valid = FALSE;        c->opcr.valid = FALSE;      }    } else {      return (FALSE);    }  } else {    list_incr (f->data.out,f->data,TS_PACKET_SIZE);  }  f->total += TS_PACKET_SIZE;  return (TRUE);}/* Process changes that arise from a new PMT. * Match the new PMT with the existing PAT/PMT and adjust this to * reflect the changes in the TS. Try to keep PIDs etc stable. * Precondition: f!=NULL, new!=NULL the partial new PMT */static void remap_new_program (file_descr *f,    pmt_descr *new){  pmt_descr* p;  int i, j, k;

⌨️ 快捷键说明

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