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

📄 repeatts.c

📁 mpeg 解复用
💻 C
字号:
/* * ISO 13818 stream multiplexer / additional repeater tool * 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:  Repeater * Purpose: Additional tool to repeat and pipe an input stream. * * This tool accepts a (time1,time2,filename) tuple via stdin, * opens the filename, assuming it contains a ISO 13818 Transport Stream, * and sends it packet-wise to stdout timed in such a way, that * all pakets are sent equally distributed within time2 msec. * As long as no further tuple is provided, after time1 msec the same * file is sent over and over again. */#include <stdio.h>#include "global.h"#define D(x) /* x */#define MAX_ANOTATE (16 * 256)static boolean quit;static int cmdf, outf, nextf;static int combln, comlln;static byte combuf[MAX_DATA_COMB];static int pollc;static int dati, dato;static byte data[MAX_ANOTATE];static t_msec nextrdelay, nextfdelay;static off_t nextpackets;t_msec msec_now (void){#define MSEC_EXPONENT 21  static long last;  static int local_delta;  struct timeval tv;  gettimeofday (&tv,NULL);  if ((tv.tv_sec & (~((1L << MSEC_EXPONENT) - 1))) != last) {    last = tv.tv_sec & (~((1L << MSEC_EXPONENT) - 1));    local_delta += 1000 * (1L << MSEC_EXPONENT);  }  return ((tv.tv_sec & ((1L << MSEC_EXPONENT) - 1)) * 1000         + tv.tv_usec / 1000 + local_delta);}static void command_help (char *command, char *errmsg){  fprintf (stderr, "%s\nUsage:\t%s [OPTIONS...] [<file>]\n"  "  -d <delay>\ttime in msec after which the sending shall be repeated\n"  "  -t <time>\ttime in msec until the file shall be sent completely\n"  "  -i\t\taccept from stdin tripels: <delay> <time> <file>\n\n"  "Send <file> repeated every <delay> msec evenly distributed within <time> msec.\n"  "When omitted, <time> defaults to <delay>. When <delay> is omitted, the file is\n"  "sent only once, and <time> must be given. When <file> is ommitted, only -i must\n"  "be given, to allow commands be enter through stdin.\n",     errmsg, command);}static boolean line_complete (char **s1,    char **s2,    char **s3){  int i;  boolean b;  *s3 = NULL;  *s2 = NULL;  *s1 = NULL;  i = 0;  while (i < combln) {    if (combuf[i] == '\n') {      comlln = i;      while (i >= 0) {        if (combuf[i] <= ' ') {          combuf[i] = 0;          b = TRUE;        } else {          if (b) {            *s3 = *s2;            *s2 = *s1;            b = FALSE;          }          *s1 = &combuf[i];        }        i -= 1;      }      return (TRUE);    }    i += 1;  }  return (FALSE);}static boolean is_long (char *s,    long *r){  long i;  char *e;  if (s == NULL) {    return (FALSE);  }  errno = 0;  i = strtol (s,&e,0);  if ((errno != 0)   || (*e != 0)) {    return (FALSE);  }  *r = i;  return (TRUE);}static boolean command_do (char *arg1,    char *arg2,    char *arg3){  long l1, l2;  struct stat stat;D(fprintf(stderr,"command_do(%s,%s,%s)\n",arg1,arg2,arg3));  if (arg1 != NULL) {    if (is_long (arg1, &l1)) {      if (l1 < 0) {        quit = TRUE;        return (TRUE);      }      if (arg2 != NULL) {        if (is_long (arg2, &l2)) {          if (l2 >= 0) {            if ((l1 >= l2) || (l1 == 0)) {              if (arg3 != NULL) {                if (nextf >= 0) {                  close (nextf);                }                if ((nextf = open (arg3, O_RDONLY)) >= 0) {                  if (fstat (nextf, &stat) == 0) {  D(fprintf(stderr,"file %d, mode %07o, name %s, ino %ld, size %ld\n",nextf,stat.st_mode,arg3,stat.st_ino,stat.st_size));                    if (S_ISREG (stat.st_mode)) {                      if ((stat.st_size % TS_PACKET_SIZE) == 0) {                        nextrdelay = l2;                        nextpackets = stat.st_size / TS_PACKET_SIZE;                        nextfdelay = l1;  D(fprintf(stderr,"next opened(%d,%d,%d)\n",nextfdelay,nextrdelay,nextpackets));                        return (TRUE);                      } else {                        fprintf (stderr, "File size not multiple of 188\n");                      }                    } else {                      fprintf (stderr, "File not regular\n");                    }                  } else {                    fprintf (stderr, "Cannot stat file\n");                  }                  close (nextf);                  nextf = -1;                } else {                  fprintf (stderr, "Cannot open file\n");                }              } else {                fprintf (stderr, "File name missing\n");              }            } else {              fprintf (stderr, "0<delay<time not allowed\n");            }          } else {            fprintf (stderr, "Time must not be negative\n");          }        } else {          fprintf (stderr, "Time must be numeric\n");        }      } else {        fprintf (stderr, "Time missing\n");      }    } else {      fprintf (stderr, "Delay must be numeric\n");    }  } else {    return (TRUE);  }  return (FALSE);}static boolean command_init (int cargc,    char **cargv){  char *cdelay = NULL;  char *ctime = NULL;  char *cfile = NULL;  int cc = 0;  nextf = -1;  quit = FALSE;  combln = 0;  dati = dato = 0;  pollc = -1;  while (++cc < cargc) {    if (!strcmp (cargv[cc],"--help")) {      command_help (cargv[0],"");      return (FALSE);    } else if (!strcmp (cargv[cc],"-i")) {      pollc = 0;    } else if (!strcmp (cargv[cc],"-d")) {      if ((cdelay != NULL) || (++cc >= cargc)) {        command_help (cargv[0],"must not use -d twice.\n");        return (FALSE);      }      cdelay = cargv[cc];    } else if (!strcmp (cargv[cc],"-t")) {      if ((ctime != NULL) || (++cc >= cargc)) {        command_help (cargv[0],"must not use -t twice.\n");        return (FALSE);      }      ctime = cargv[cc];    } else {      if (cfile != NULL) {        command_help (cargv[0],"too many parameters.\n");        return (FALSE);      }      cfile = cargv[cc];    }  }  if (cfile != NULL) {    if (!command_do (cdelay ? cdelay : "0", ctime ? ctime : cdelay, cfile)) {      command_help (cargv[0],"");      return (FALSE);    }  } else if ((ctime != NULL) || (cdelay != NULL) || (pollc <= 0)) {    command_help (cargv[0],"only -i must be given when started with no file.\n");    return (FALSE);  }  cmdf = STDIN_FILENO;  outf = STDOUT_FILENO;  return ((cmdf >= 0) && (outf >= 0));}int main (int argc,    char *argv[]){  int polli, pollo, polls;  int toberead;  int currentf;  boolean dotime;  t_msec rtime, ftime, rdelay, fdelay, now;  struct pollfd ufds [3];  off_t rpackets, rpartial, rpdone;  if (command_init (argc,&argv[0])) {    currentf = -1;    rtime = ftime = msec_now ();    while (!quit) {      now = msec_now ();D(fprintf(stderr,"now(%d)\n",now));      if (currentf < 0) {        toberead = 0;        if (nextpackets > 0) {          rpackets = nextpackets;          rdelay = nextrdelay / nextpackets;          rpartial = nextrdelay % nextpackets;        } else {          rpackets = 1;          rdelay = 0;          rpartial = 0;        }        rpdone = 0;        fdelay = nextfdelay;        if ((ftime-now) < 0) {          ftime = now;        }        rtime = ftime;        currentf = nextf;        nextf = -1;D(fprintf(stderr,"next current(%d,%d,%d)\n",currentf,fdelay,rdelay));      }      if (currentf >= 0) {        if ((rtime - now) <= 0) {          if ((((dato-dati-1) & (MAX_ANOTATE-1)) - toberead) > TS_PACKET_SIZE) {            toberead += TS_PACKET_SIZE;            rtime += rdelay;            rpdone += rpartial;            if (rpdone >= rpackets) {              rpdone -= rpackets; /* equaly distribute the rounded msecs by */              rtime += 1;      /* counting them in an rpackets modulo-space */            }            dotime = TRUE;D(fprintf(stderr,"timer a(%d,%d,%d)\n",toberead,rtime,rpdone));          } else {            rtime = now;            dotime = FALSE;D(fprintf(stderr,"timer b(%d,%d)\n",toberead,rtime));          }        } else {          dotime = TRUE;D(fprintf(stderr,"timer c(%d,%d)\n",toberead,rtime));        }      } else {        dotime = FALSE;D(fprintf(stderr,"timer c(%d,%d)\n",toberead,rtime));      }      polls = pollc+1;      if (pollc >= 0) {        ufds[pollc].fd = cmdf;        ufds[pollc].events = POLLIN;      }      if (dati != dato) {        pollo = polls++;        ufds[pollo].fd = outf;        ufds[pollo].events = POLLOUT;      } else {        pollo = -1;      }      if (toberead > 0) {        polli = polls++;        ufds[polli].fd = currentf;        ufds[polli].events = POLLIN;      } else {        polli = -1;      }      poll (&ufds[0], polls, dotime ? ((rtime-now) > 0) ? (rtime-now) : 0 : -1);      if ((pollc >= 0)       && (ufds[pollc].revents & POLLIN)) {        char *s1, *s2, *s3;        if (combln >= MAX_DATA_COMB-HIGHWATER_COM) {          combln -= HIGHWATER_COM;          memmove (&combuf[0], &combuf[HIGHWATER_COM], combln);        }        combln += read (cmdf, &combuf[combln], MAX_DATA_COMB-combln);        while (line_complete (&s1, &s2, &s3)) {          command_do (s1, s2, s3);          combln -= comlln;          memmove (&combuf[0], &combuf[comlln], combln);        }      }      if ((polli >= 0)       && (ufds[polli].revents & (POLLIN | POLLHUP | POLLERR))) {        int l;        if (ufds[polli].revents & POLLIN) {          l = toberead;          if (l > (MAX_ANOTATE - dati)) {            l = MAX_ANOTATE - dati;          }          l = read (currentf, &data[dati], l);          dati = (dati+l) & (MAX_ANOTATE-1);          toberead -= l;        } else {          l = 0;        }        if (l == 0) {          if ((nextf >= 0)           || (fdelay == 0)) {            close (currentf);            currentf = -1;          } else {            lseek (currentf,0,SEEK_SET);            toberead = ((toberead-1) / TS_PACKET_SIZE) * TS_PACKET_SIZE;          }          ftime += fdelay;          now = msec_now ();          if ((ftime-now) < 0) {            ftime = now;          }          rtime = ftime;        }      }      if ((pollo >= 0)       && (ufds[pollo].revents & (POLLOUT | POLLHUP | POLLERR))) {        if (ufds[pollo].revents & POLLOUT) {          int l;          if (dati < dato) {            l = MAX_ANOTATE - dato;          } else {            l = dati - dato;          }          l = write (outf, &data[dato], l);          dato = (dato+l) & (MAX_ANOTATE-1);          if (l == 0) {            quit = TRUE;          }        } else {          quit = TRUE;        }      }    }    return (EXIT_SUCCESS);  }  return (EXIT_FAILURE);}

⌨️ 快捷键说明

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