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

📄 splice.c

📁 mpeg 解复用
💻 C
字号:
/* * 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:  Splice * Purpose: Service functions for specific Splice* modules * * This module provides functions needed for splicing * which are independent from the splice type. */#include "global.h"#include "error.h"#include "splice.h"#include "input.h"#include "pes.h"#include "descref.h"t_msec next_psi_periodic;t_msec psi_frequency_msec;boolean psi_frequency_changed;int configuration_on;boolean configuration_changed;boolean configuration_descr_changed;const char *configuration_total = "Conf: progs: %d\n";static modifydescr_descr *globalmodifydescr;boolean splice_init (void){  psi_frequency_msec = 0;  psi_frequency_changed = FALSE;  configuration_on = 0;  globalmodifydescr = NULL;  return (splice_specific_init ());}/* Connect a stream with a target program. * programnb denotes the program to connect, * stream is the stream to connect, * all further parameters are as with input_openstream. * If stream is NULL, open a stream first. * Add the stream to the programs list of streams and vice versa. * Precondition: f!=NULL * Return: the changed stream on success, the unchanged "stream" otherwise */stream_descr *connect_streamprog (file_descr *f,    int programnb,    int sourceid,    int streamid,    int streamtype,    stream_descr *stream,    stream_descr *mapstream,    boolean mention){  stream_descr *s;  prog_descr *p;  if (stream == NULL) {    s = input_openstream (f,sourceid,streamid<0?-streamid:streamid,            streamtype,sd_data,mapstream);  } else {    if (streamid < 0) {      streamid = -streamid;      warn (LWAR,"Cannot refind sid",ESPC,1,1,streamid);    }    s = stream;  }  if (s != NULL) {    p = splice_openprog (programnb);    if (p != NULL) {      if (input_addprog (s,p)) {        if (splice_addstream (p,s,streamid>=0) > 0) {/*          if (p->pcr_pid < 0) {            if (xxx) {              p->pcr_pid = s->u.d.pid;              s->u.d.has_clockref = TRUE;              s->u.d.next_clockref = msec_now () - MAX_MSEC_PCRDIST;            }          }*/          s->endaction = ENDSTR_WAIT;          s->u.d.mention = mention;          return (s);        }        input_delprog (s,p);      }      if (p->streams <= 0) {        splice_closeprog (p);      }    }    if (stream == NULL) {      input_closestream (s);    }  }  return (stream);}/* Unlink a stream from a target program. * If the stream comes out to be in no program then, close it. *   This function may be used only, if the program in question will either *   be non-empty after the call, or will be closed by the calling function. * Precondition: s!=NULL, p!=NULL */void unlink_streamprog (stream_descr *s,    prog_descr *p){  splice_delstream (p,s);  input_delprog (s,p);  if (s->u.d.progs <= 0) {    file_descr *f;    f = s->fdescr;    input_closestream (s);    input_closefileifunused (f);  }}/* Remove a stream from a target program. * Close stream and/or program, if not contained in another program or stream. * The input file is no longer automatic, because we do manual changes here. * Precondition: s!=NULL, p!=NULL, s is stream in target program p */void remove_streamprog (stream_descr *s,    prog_descr *p){  s->fdescr->automatic = FALSE;  if (p->streams > 1) {    unlink_streamprog (s,p);  } else {    splice_closeprog (p);  }}/* Find the right stream in a program * Precondition: p!=NULL * Return: stream, if found, NULL otherwise */stream_descr *get_streamprog (prog_descr *p,    int streamid){  int i;  i = p->streams;  while (--i >= 0) {    stream_descr *s;    s = p->stream[i];    if (s->stream_id == streamid) {      return (s);    }  }  return (NULL);}/* Find a free stream ID in a program that is equivalent to the given stream id * Precondition: p!=NULL * Return: Free ID, if found; given sid otherwise. */int splice_findfreestreamid (prog_descr *p,    int sid){  int s0, s, n;  s0 = sid;  if ((sid >= PES_CODE_AUDIO)   && (sid < (PES_CODE_AUDIO+PES_NUMB_AUDIO))) {    s = PES_CODE_AUDIO;    n = PES_NUMB_AUDIO;  } else if ((sid >= PES_CODE_VIDEO)   && (sid < (PES_CODE_VIDEO+PES_NUMB_VIDEO))) {    s = PES_CODE_VIDEO;    n = PES_NUMB_VIDEO;  } else {    s = sid;    n = 1;  }  while (--n >= 0) {    int i;    i = p->streams;    while ((--i >= 0)        && (p->stream[i]->stream_id != s0)) {    }    if (i < 0) {      warn (LIMP,"Found SID free",ESPC,2,sid,s0);      return (s0);    }    s0 = s;    s += 1;  }  warn (LIMP,"Found SID",ESPC,2,sid,sid);  return (sid);}/* Check if there is a source pcr stream in a target program * Precondition: p!=NULL * Return: pcr-stream, if found; NULL otherwise. */stream_descr *splice_findpcrstream (prog_descr *p){  int i;  pmt_descr *pmt;  warn (LIMP,"Find PCR Stream",ESPC,3,0,p->program_number);  i = p->streams;  while (--i >= 0) {    if (p->stream[i]->fdescr->content == ct_transport) {      pmt = p->stream[i]->fdescr->u.ts.pat;      while (pmt != NULL) {        if (pmt->pcr_pid == p->stream[i]->sourceid) {          warn (LIMP,"Found PCR Stream",ESPC,3,1,p->stream[i]->sourceid);          return (p->stream[i]);        }        pmt = pmt->next;      }    }  }  return (NULL);}/* Print configuration of descriptors * Precondition: manud!=NULL */static void splice_descr_configuration (descr_descr *manud,    descr_descr *autod){  int i, l;  byte *y;  i = NUMBER_DESCR;  while (--i >= 0) {    y = manud->refx[i];    if (y == NULL) {      if (autod != NULL) {        y = autod->refx[i];      }    } else if (y[1] == 0) {      y = NULL;    }    if (y != NULL) {      l = y[1];      fprintf (stderr, "Conf: descr:%02X len:%d data:", *y++, l);      while (--l >= 0) {        fprintf (stderr, "%02X", *++y);      }      fprintf (stderr, "\n");    }  }}/* Print configuration for one program * Precondition: p!=NULL */void splice_one_configuration (prog_descr *p){  int i, s;  stump_descr *st;  i = p->streams;  s = 0;  st = p->stump;  while (st != NULL) {    s += 1;    st = st->next;  }  fprintf (stderr, "Conf: prog:%04X pmt:%04hX pcr:%04hX streams:%2d",      p->program_number, p->pmt_pid, p->pcr_pid, i+s);  if (s > 0) {    fprintf (stderr, " (%d)", s);  }  fprintf (stderr, "\n");  if (configuration_on > 1) {    splice_descr_configuration (&p->manudescr, NULL); /* Missing auto descr! */  }  while (--i >= 0) {    stream_descr *s;    s = p->stream[i];    fprintf (stderr, "Conf: stream:%04hX type:%02X sid:%02X "      "file:%d source:%04hX num:%2d name:%s\n",      s->u.d.pid, s->stream_type, s->stream_id,      s->fdescr->content, s->sourceid, s->fdescr->filerefnum, s->fdescr->name);    if (configuration_on > 1) {      splice_descr_configuration (s->manudescr, s->autodescr);    }  }  st = p->stump;  while (st != NULL) {    fprintf (stderr, "Conf: stream:%04hX type:%02X\n",      st->pid, st->stream_type);    if (configuration_on > 1) {      splice_descr_configuration (&st->manudescr, NULL);    }    st = st->next;  }}void splice_set_configuration (int on){  configuration_on = on;  configuration_changed = TRUE;}static void splice_modifydescriptor (descr_descr *md,    int dtag,    int dlength,    byte *data,    stream_descr *s){  int i, j;  byte *t, *u;  if (dtag < 0) {    clear_descrdescr (md);  } else {    t = md->refx[dtag];    if ((dlength < 0)     || ((t != NULL)      && (t != &md->null[0]))) {      j = t[1]+2;      i = NUMBER_DESCR;      while (--i >= 0) {        if ((md->refx[i]-t) > 0) {          md->refx[i] -= j;        }      }      memmove (t,&t[j],sizeof(md->data)-(j+(t-&md->data[0])));    }    if (dlength == 0) {      t = &md->null[0];    } else if (dlength < 0) {      t = NULL;    } else {      i = NUMBER_DESCR;      t = &md->data[0];      while (--i >= 0) {        u = md->refx[i];        if (u != NULL) {          u = &u[u[1]+2];          if ((u-t) > 0) {            t = u;          }        }      }      if (t-&md->data[0] < 0) {        warn (LERR,"No space left",ESPC,5,2,t-&md->data[0]);        return;      }      if ((t-&md->data[0]+dlength+2-MAX_PSI_SIZE) > 0) {        warn (LWAR,"No space left",ESPC,5,1,t-&md->data[0]);        return;      }      t[0] = dtag;      t[1] = dlength;      memcpy (&t[2],data,dlength);    }    md->refx[dtag] = t;  }  if (s != NULL) {    i = s->u.d.progs;    while (--i >= 0) {      s->u.d.pdescr[i]->changed = TRUE;    }  }}static void splice_modifydescrlater (int programnb,    short sid,    short pid,    int dtag,    int dlength,    byte *data){  modifydescr_descr *l;  modifydescr_descr **pl;  pl = &globalmodifydescr;  l = *pl;  while (l != NULL) {    if ((programnb < 0) /* delete older matching entries */     || ((programnb == l->programnb)      && ((pid == 0)       || ((pid == l->pid)        && (sid == l->sid)        && ((dtag < 0)         || (dtag == l->dtag)))))) {      *pl = l->next;      free (l);    } else {      pl = &l->next;    }    l = *pl;  }  if ((dtag >= 0)   && (dlength >= 0)) { /* don't save modifiers, that delete */    if ((l = malloc (sizeof(modifydescr_descr))) != NULL) {      l->next = NULL;      l->programnb = programnb;      l->sid = sid;      l->pid = pid;      l->dtag = dtag;      l->dlength = dlength;      if (dlength > 0) {        memcpy (&l->data[0],data,dlength);      }      *pl = l; /* append at end of list */    } else {      warn (LERR,"Malloc fail",ETSC,12,1,programnb);    }  }}/* For a new program and maybe stream or stump, * check presence of applicable descriptors, that have been stored. * All non-NULL parameters must be completely linked into p upon call! * Precondition: p != NULL */void splice_modifycheckmatch (int programnb,    prog_descr *p,    stream_descr *s,    stump_descr *st){  modifydescr_descr *l;  modifydescr_descr **pl;  pl = &globalmodifydescr;  l = *pl;  while (l != NULL) {    if ((programnb == l->programnb)     && (((l->sid < 0)       && (l->pid < 0))      || ((l->pid > 0)       && (((s != NULL)         && (l->pid == s->u.d.pid))        || ((st != NULL)         && (l->pid = st->pid))))      || ((l->sid >= 0)       && (s != NULL)       && (l->sid == s->stream_id)))) {      splice_modifytargetdescrprog (p,programnb,          l->sid,l->pid,l->dtag,l->dlength,&l->data[0],st);      *pl = l->next;      free (l);    } else {      pl = &l->next;    }    l = *pl;  }}/* Modify an entry in a manudescr struct. */void splice_modifytargetdescrprog (prog_descr *p,    int programnb,    short sid,    short pid,    int dtag,    int dlength,    byte *data,    stump_descr *globstump){  int i;  stream_descr *s;  stump_descr *st;  if (sid >= 0) {    if (p != NULL) {      i = p->streams;      while (--i >= 0) {        s = p->stream[i];        if (s->stream_id == sid) {          splice_modifydescriptor (s->manudescr,dtag,dlength,data,s);          configuration_descr_changed = TRUE;          return;        }      }    }    splice_modifydescrlater (programnb,sid,pid,dtag,dlength,data);  } else {    if (pid > 0) {      if (p != NULL) {        i = p->streams;        while (--i >= 0) {          s = p->stream[i];          if (s->u.d.pid == pid) {            splice_modifydescriptor (s->manudescr,dtag,dlength,data,s);            configuration_descr_changed = TRUE;            return;          }        }        st = p->stump;      } else {        st = globstump;      }      while (st != NULL) {        if ((st->pid == pid)         && (st->program_number == programnb)) {          splice_modifydescriptor (&st->manudescr,dtag,dlength,data,NULL);          if (p != NULL) {            p->changed = TRUE;          }          configuration_descr_changed = TRUE;          return;        }        st = st->next;      }      splice_modifydescrlater (programnb,sid,pid,dtag,dlength,data);    } else if (pid < 0) {      if (p != NULL) {        splice_modifydescriptor (&p->manudescr,dtag,dlength,data,NULL);        p->changed = TRUE;        configuration_descr_changed = TRUE;      } else {        splice_modifydescrlater (programnb,sid,pid,dtag,dlength,data);      }    } else {      if (p != NULL) {        i = p->streams;        while (--i >= 0) {          s = p->stream[i];          splice_modifydescriptor (s->manudescr,dtag,dlength,data,s);        }        splice_modifydescriptor (&p->manudescr,dtag,dlength,data,NULL);        configuration_descr_changed = TRUE;        st = p->stump;      } else {        st = globstump;      }      while (st != NULL) {        if (st->program_number == programnb) {          splice_modifydescriptor (&st->manudescr,dtag,dlength,data,NULL);        }        st = st->next;      }      splice_modifydescrlater (programnb,sid,pid,dtag,dlength,data);    }  }}

⌨️ 快捷键说明

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