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

📄 splicets.c

📁 mpeg 解复用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ISO 13818 stream multiplexer * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin * Copyright (C) 2004 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:  Splice TS * Purpose: Generate transport stream. * * This module generates from the available input stream data (as * seperated by the split functions) the complete output stream. * It provides functions to handle programs for the resulting stream, * as these are output format dependent. Further, it accepts PSI data * just in time, validating it not earlier than with the arrival of * the corresponding payload at this stage. */#include "global.h"#include "crc.h"#include "error.h"#include "input.h"#include "output.h"#include "descref.h"#include "splitts.h"#include "pes.h"#include "ts.h"#include "splice.h"#include "splicets.h"const boolean splice_multipleprograms = TRUE;static boolean changed_pat;static boolean unchanged_pat;static int pat_section;static const int last_patsection = 0;static byte nextpat_version;static byte pat_conticnt;static int transportstreamid;static int psi_size;static int psi_done;static byte psi_data [MAX_PSI_SIZE];static byte unit_start;static byte *conticnt;static int psi_pid;static int progs;static prog_descr *prog [MAX_OUTPROG];static int nextpid;static stream_descr *outs [MAX_STRPERTS];static stump_descr *globalstumps;boolean splice_specific_init (void){  progs = 0;  nextpid = 0;  memset (outs,0,sizeof(outs));  changed_pat = TRUE;  pat_section = 0;  nextpat_version = 0;  pat_conticnt = 0;  psi_size = psi_done = 0;  unit_start = TS_UNIT_START;  transportstreamid = 0x4227;  globalstumps = NULL;  return (TRUE);}void splice_settransportstreamid (int tsid){  transportstreamid = tsid;}void splice_setpsifrequency (t_msec freq){  psi_frequency_msec = freq;  psi_frequency_changed = TRUE;}static int findapid (stream_descr *s, int desire){  byte okness = 2;  int h;  if (conservative_pid_assignment   && (desire >= 0)   && (outs[desire] == NULL)   && (input_tssiinafilerange (desire) < 0)) {    return (desire);  }  do {    if ((nextpid < TS_PID_SPLICELO) || (nextpid >= TS_PID_SPLICEHI)) {      warn (LDEB,"Next PID",ETSC,1,okness,nextpid);      if (okness == 0) {        warn (LERR,"No PID found",ETSC,2,1,0);        return (0);      }      okness -= 1;      nextpid = TS_PID_SPLICELO;    } else {      warn (LDEB,"Next PID",ETSC,2,okness,nextpid);      nextpid += 1;    }    if (okness != 0) {      h = input_tssiinafilerange (nextpid);      warn (LDEB,"Next PID",ETSC,3,h,nextpid);      if (h >= 0) {        nextpid = h;      }    } else {      h = -1;    }  } while ((h >= 0)        || (outs[nextpid] != NULL));  outs[nextpid] = s;  warn (LDEB,"Next PID",ETSC,2,2,nextpid);  return (nextpid);}void splice_all_configuration (void){  int i;  if (configuration_must_print) {    i = progs;    fprintf (stderr, configuration_total, i);    while (--i >= 0) {      splice_one_configuration (prog[i]);    }    configuration_was_printed;  }}void splice_addsirange (file_descr *f,    int lower,    int upper){  int i, r;  tssi_descr *tssi;  prog_descr *p;  tssi = malloc (sizeof (tssi_descr));  if (tssi != NULL) {    if (ts_file_stream (f,TS_UNPARSED_SI) == NULL) {      ts_file_stream (f,TS_UNPARSED_SI) = input_openstream (f,              TS_UNPARSED_SI,0,0,sd_unparsedsi,NULL);    }    if (ts_file_stream (f,TS_UNPARSED_SI) != NULL) {      tssi->next = f->u.ts.tssi;      tssi->pid_low = lower;      tssi->pid_high = upper;      f->u.ts.tssi = tssi;      r = upper; /* check for collision against existing PIDs, first sd_data */      while (r >= lower) {        stream_descr *s;        s = outs[r];        if ((s != NULL)         && (s != PMT_STREAM)) {          if (s->streamdata == sd_data) {            i = findapid (s, -1);            if (input_tssiinafilerange (i) >= 0) { /* none free! */              outs[i] = NULL;            } else {              int j;              s->u.d.pid = i;              j = s->u.d.progs;              while (--j >= 0) {                p = s->u.d.pdescr[j];                p->changed = TRUE;                if (p->pcr_pid == r) {                  p->pcr_pid = i;                }              }              configuration_changed = TRUE;              outs[r] = NULL;            }          } else {            warn (LERR,"Bad PID",ETSC,11,s->streamdata,r);          }        }        r -= 1;      }      i = progs; /* ...then sd_map */      while (--i >= 0) {        p = prog[i];        r = p->pmt_pid;        if ((r >= lower)         && (r <= upper)) {          int q;          q = findapid (PMT_STREAM, -1);          if (input_tssiinafilerange (q) >= 0) { /* none free! */            outs[q] = NULL;          } else {            int j;            outs[r] = NULL;            j = i;            while (--j >= 0) {              if (prog[j]->pmt_pid == r) {                prog[j]->pmt_pid = q;              }            }            p->pmt_pid = q;            changed_pat = TRUE;            configuration_changed = TRUE;          }        }      }    } else {      free (tssi);    }  }}void splice_createstump (int programnb,    short pid,    byte styp){  prog_descr *p;  stump_descr **pst;  stump_descr *st;  p = splice_getprog (programnb);  if (p != NULL) {    configuration_changed = TRUE;    p->changed = TRUE;    pst = &(p->stump);  } else {    pst = &globalstumps;  }  st = *pst;  while ((st != NULL)      && ((st->pid != pid)       || (st->program_number != programnb))) {    st = st->next;  }  if (st == NULL) {    st = malloc (sizeof(stump_descr));    st->next = *pst;    st->program_number = programnb;    st->pid = pid;    *pst = st;  }  st->stream_type = styp;  clear_descrdescr (&(st->manudescr));  splice_modifycheckmatch (programnb,p,NULL,st);}stump_descr *splice_getstumps (int programnb,    short pid){  prog_descr *p;  stump_descr **pst;  stump_descr *rl;  rl = NULL;  p = splice_getprog (programnb);  if (p != NULL) {    pst = &(p->stump);  } else {    pst = &globalstumps;  }  while (*pst != NULL) {    stump_descr *st;    st = *pst;    if ((st->program_number == programnb)     && ((pid < 0)      || (pid == st->pid))) {      st = *pst;      *pst = st->next;      st->next = rl;      rl = st;      if (p != NULL) {        configuration_changed = TRUE;        p->changed = TRUE;      }    } else {      pst = &((*pst)->next);    }  }  return (rl);}void splice_modifytargetdescriptor (int programnb,    short sid,    short pid,    int dtag,    int dlength,    byte *data){  int i;  if (programnb < 0) {    i = progs;    while (--i >= 0) {      splice_modifytargetdescrprog (prog[i],          prog[i]->program_number,-1,0,-1,-1,NULL,globalstumps);    }    splice_modifytargetdescrprog (NULL,-1,-1,0,-1,-1,NULL,globalstumps);  } else {    splice_modifytargetdescrprog (splice_getprog (programnb),        programnb,sid,pid,dtag,dlength,data,globalstumps);  }}prog_descr *splice_getprog (int programnb){  int i;  i = progs;  while (--i >= 0) {    if (prog[i]->program_number == programnb) {      return (prog[i]);    }  }  return (NULL);}prog_descr *splice_openprog (int programnb){  prog_descr *p;  int pid;  warn (LIMP,"Open prog",ETSC,1,0,programnb);  p = splice_getprog (programnb);  if (p == NULL) {    if (progs < MAX_OUTPROG) {      if ((pid = findapid (PMT_STREAM, -1)) > 0) {        if ((p = malloc(sizeof(prog_descr))) != NULL) {          p->program_number = programnb;          p->pcr_pid = -1;          p->pmt_pid = pid;          p->pmt_conticnt = 0;          p->pmt_version = 0;          p->changed = TRUE;          p->pat_section = 0; /* more ? */          p->streams = 0;          p->stump = splice_getstumps (programnb,-1);          clear_descrdescr (&p->manudescr);          prog[progs++] = p;          changed_pat = TRUE;          configuration_changed = TRUE;          splice_modifycheckmatch (programnb,p,NULL,NULL);        } else {          outs[pid] = NULL;          warn (LERR,"Open prog",ETSC,1,1,0);        }      }    } else {      warn (LERR,"Max prog open",ETSC,1,2,0);    }  }  return (p);}void splice_closeprog (prog_descr *p){  int i, n;  warn (LIMP,"Close prog",ETSC,3,0,p->program_number);  configuration_changed = TRUE;  while (p->streams > 0) {    unlink_streamprog (p->stream[0],p);  }  releasechain (stump_descr,p->stump);  n = -1;  if (p->pmt_pid >= 0) {    i = progs;    while (--i >= 0) {      if (prog[i]->pmt_pid == p->pmt_pid) {        n += 1;      }    }  }  i = progs;  while (--i >= 0) {    if (prog[i] == p) {      prog[i] = prog[--progs];      if (n == 0) {        outs[p->pmt_pid] = NULL;      }      free (p);      changed_pat = TRUE;      return;    }  }  warn (LERR,"Close lost prog",ETSC,3,1,progs);}int splice_addstream (prog_descr *p,    stream_descr *s,    boolean force_sid){  int pid = 0;  warn (LIMP,"Add stream",ETSC,4,force_sid,s->stream_id);  if (p->streams < MAX_STRPERPRG) {    pid = findapid (s,(s->fdescr->content == ct_transport) ? s->sourceid : -1);    if (pid > 0) {      if (!force_sid) {        s->stream_id = splice_findfreestreamid (p,s->stream_id);      }      p->stream[p->streams++] = s;      p->changed = TRUE;      s->u.d.pid = pid;      configuration_changed = TRUE;      splice_modifycheckmatch (p->program_number,p,s,NULL);    }  }  return (pid);}boolean splice_delstream (prog_descr *p,    stream_descr *s){  int i;  warn (LIMP,"Del stream",ETSC,5,0,s->u.d.pid);  configuration_changed = TRUE;  i = p->streams;  while (--i >= 0) {    if (p->stream[i] == s) {      outs[s->u.d.pid] = NULL;      p->stream[i] = p->stream[--(p->streams)];      p->changed = TRUE;      if (p->pcr_pid == s->u.d.pid) {        p->pcr_pid = -1;      }      s->u.d.pid = 0;      return (TRUE);    }  }  warn (LERR,"Del lost stream",ETSC,5,1,p->streams);  return (FALSE);}void process_finish (void){  warn (LIMP,"Finish",ETSC,6,0,0);}static int make_patsection (int section,    byte *dest){  int i;  byte *d;  prog_descr *p;  d = dest;  *d++ = TS_TABLEID_PAT;  d += 2;  *d++ = transportstreamid >> 8;  *d++ = (byte)transportstreamid;  *d++ = 0xC0 | 0x01 | (nextpat_version << 1);  *d++ = section;  *d++ = last_patsection;  i = progs;  while (--i >= 0) {    p = prog[i];    if (p->pat_section == section) {      int x;      x = p->program_number;      *d++ = (x >> 8);      *d++ = x;      x = p->pmt_pid;      *d++ = 0xE0 | (x >> 8);      *d++ = x;    }  }  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);}static int make_pmtsection (stream_descr *s,    prog_descr *p,    byte *dest){  int i;  byte *d;  stump_descr *st;  stream_descr *t;  d = dest;  *d++ = TS_TABLEID_PMT;  d += 2;  i = p->program_number;  *d++ = (i >> 8);  *d++ = i;  *d++ = 0xC0 | 0x01 | (p->pmt_version << 1);  *d++ = 0;  *d++ = 0;  if (p->pcr_pid < 0) {    stream_descr *pcrs;    pcrs = splice_findpcrstream (p);    if (pcrs == NULL) {      pcrs = s;    }    pcrs->u.d.has_clockref = TRUE;    pcrs->u.d.next_clockref = msec_now () - MAX_MSEC_PCRDIST;    p->pcr_pid = pcrs->u.d.pid;    configuration_changed = TRUE;  }  i = p->pcr_pid;  *d++ = 0xE0 | (i >> 8);  *d++ = i;  d += 2;  i = NUMBER_DESCR;  while (--i >= 0) {

⌨️ 快捷键说明

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