Diff for /multiplexer/repeatts.c between versions 1.6 and 1.7

version 1.6, 2003/05/05 11:04:10 version 1.7, 2003/08/14 23:52:38
Line 20 Line 20
 #include <stdio.h>  #include <stdio.h>
 #include "global.h"  #include "global.h"
   
   #define D(x) /* x */
 #define D(x)                   /* x */  
   
 #define MAX_ANOTATE (16 * 256)  #define MAX_ANOTATE (16 * 256)
   
Line 30  static int cmdf, outf, nextf; Line 29  static int cmdf, outf, nextf;
   
 static int combln, comlln;  static int combln, comlln;
 static byte combuf[MAX_DATA_COMB];  static byte combuf[MAX_DATA_COMB];
   static int pollc;
   
 static int dati, dato;  static int dati, dato;
 static byte data[MAX_ANOTATE];  static byte data[MAX_ANOTATE];
   
 static t_msec nextfdelay;  static t_msec nextrdelay, nextfdelay;
   static off_t nextpackets;
 static int    num_packets;  
 static t_msec transmission_time;  
   
 t_msec  t_msec msec_now (void)
 msec_now (void)  
 {  {
   static int       first_call = 1;    
   static long long first_time;  
   static long long now;  
   
   struct timeval tv;  
     
   gettimeofday (&tv, NULL);  
 #if 0  
 #define MSEC_EXPONENT 21  #define MSEC_EXPONENT 21
   static long last;    static long last;
   static int local_delta;    static int local_delta;
   if ((tv.tv_sec & (~((1L << MSEC_EXPONENT) - 1))) != last)    struct timeval tv;
     {    gettimeofday (&tv,NULL);
       last = tv.tv_sec & (~((1L << MSEC_EXPONENT) - 1));    if ((tv.tv_sec & (~((1L << MSEC_EXPONENT) - 1))) != last) {
       local_delta += 1000 * (1L << MSEC_EXPONENT);      last = tv.tv_sec & (~((1L << MSEC_EXPONENT) - 1));
     }      local_delta += 1000 * (1L << MSEC_EXPONENT);
     }
   return ((tv.tv_sec & ((1L << MSEC_EXPONENT) - 1)) * 1000    return ((tv.tv_sec & ((1L << MSEC_EXPONENT) - 1)) * 1000
           + tv.tv_usec / 1000 + local_delta);           + tv.tv_usec / 1000 + local_delta);
 #endif  
   now = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);  
   if (first_call)  
     {  
       first_call = 0;  
       first_time = now;  
     }  
   
   return (t_msec)(now - first_time);  
 }  }
   
 static void  static void command_help (char *command, char *errmsg)
 command_help (char *command)  
 {  {
   fprintf (stderr,     fprintf (stderr, "%s\nUsage:\t%s [OPTIONS...] [<file>]\n"
     "Usage:\t%s [<delay> <time> <file>]\n"    "  -d <delay>\ttime in msec after which the sending shall be repeated\n"
     "\tSend <file> repeated every <delay> msec evenly distributed within\n"    "  -t <time>\ttime in msec until the file shall be sent completely\n"
     "\t<time> msec, Feed a (delay,time,file) tuple to stdin to reset\n"    "  -i\t\taccept from stdin tripels: <delay> <time> <file>\n\n"
     "\tbehaviour, quit program with negative delay, don't repeat with delay=0.\n",    "Send <file> repeated every <delay> msec evenly distributed within <time> msec.\n"
            command);    "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  static boolean line_complete (char **s1,
 line_complete (char **s1, char **s2, char **s3)      char **s2,
       char **s3)
 {  {
   int i;    int i;
   boolean b = FALSE;    boolean b;
   *s3 = NULL;    *s3 = NULL;
   *s2 = NULL;    *s2 = NULL;
   *s1 = NULL;    *s1 = NULL;
   i = 0;    i = 0;
   while (i < combln)    while (i < combln) {
     {      if (combuf[i] == '\n') {
       if (combuf[i] == '\n')        comlln = i;
         {        while (i >= 0) {
           comlln = i;          if (combuf[i] <= ' ') {
           while (i >= 0)            combuf[i] = 0;
             {            b = TRUE;
               if (combuf[i] <= ' ')          } else {
                 {            if (b) {
                   combuf[i] = 0;              *s3 = *s2;
                   b = TRUE;              *s2 = *s1;
                 }              b = FALSE;
               else            }
                 {            *s1 = &combuf[i];
                   if (b)  
                     {  
                       *s3 = *s2;  
                       *s2 = *s1;  
                       b = FALSE;  
                     }  
                   *s1 = &combuf[i];  
                 }  
               i -= 1;  
             }  
           return (TRUE);  
         }          }
       i += 1;          i -= 1;
         }
         return (TRUE);
     }      }
       i += 1;
     }
   return (FALSE);    return (FALSE);
 }  }
   
 static boolean  static boolean is_long (char *s,
 is_long (char *s, long *r)      long *r)
 {  {
   long i;    long i;
   char *e;    char *e;
   if (s == NULL)    if (s == NULL) {
     {      return (FALSE);
       return (FALSE);    }
     }  
   errno = 0;    errno = 0;
   i = strtol (s, &e, 0);    i = strtol (s,&e,0);
   if ((errno != 0) || (*e != 0))    if ((errno != 0)
     {     || (*e != 0)) {
       return (FALSE);      return (FALSE);
     }    }
   *r = i;    *r = i;
   return (TRUE);    return (TRUE);
 }  }
   
 static boolean  static boolean command_do (char *arg1,
 command_do (char *arg1, char *arg2, char *arg3)      char *arg2,
       char *arg3)
 {  {
   long l1, l2;    long l1, l2;
   struct stat stat;    struct stat stat;
 D (fprintf (stderr, "command_do(%s,%s,%s)\n", arg1, arg2, arg3));  D(fprintf(stderr,"command_do(%s,%s,%s)\n",arg1,arg2,arg3));
   if (arg1 != NULL)    if (arg1 != NULL) {
     {      if (is_long (arg1, &l1)) {
       if (is_long (arg1, &l1))        if (l1 < 0) {
         {          quit = TRUE;
           if (l1 < 0)          return (TRUE);
             {        }
               quit = TRUE;        if (arg2 != NULL) {
               return (TRUE);          if (is_long (arg2, &l2)) {
             }            if (l2 >= 0) {
           if (arg2 != NULL)              if ((l1 >= l2) || (l1 == 0)) {
             {                if (arg3 != NULL) {
               if (is_long (arg2, &l2))                  if (nextf >= 0) {
                 {                    close (nextf);
                   if (l2 >= 0)                  }
                     {                  if ((nextf = open (arg3, O_RDONLY)) >= 0) {
                       if ((l1 >= l2) || (l1 == 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 (arg3 != NULL)                      if (S_ISREG (stat.st_mode)) {
                             {                        if ((stat.st_size % TS_PACKET_SIZE) == 0) {
                               if (nextf >= 0)                          nextrdelay = l2;
                                 {                          nextpackets = stat.st_size / TS_PACKET_SIZE;
                                   close (nextf);                          nextfdelay = l1;
                                 }    D(fprintf(stderr,"next opened(%d,%d,%d)\n",nextfdelay,nextrdelay,nextpackets));
                               if ((nextf = open (arg3, O_RDONLY)) >= 0)                          return (TRUE);
                                 {                        } else {
                                   if (fstat (nextf, &stat) == 0)                          fprintf (stderr, "File size not multiple of 188\n");
                                     {                        }
 D (fprintf (stderr, "file %d, mode %07o, name %s, ino %ld, size %ld\n",                      } else {
             nextf, stat.st_mode, arg3, stat.st_ino, stat.st_size));                        fprintf (stderr, "File not regular\n");
                                       if (S_ISREG (stat.st_mode))                      }
                                         {                    } else {
                                           if ((stat.st_size %                      fprintf (stderr, "Cannot stat file\n");
                                                TS_PACKET_SIZE) == 0)                    }
                                             {                    close (nextf);
                                               num_packets = stat.st_size /                    nextf = -1;
                                                 TS_PACKET_SIZE;                  } else {
                                               transmission_time = l2;                    fprintf (stderr, "Cannot open file\n");
                                               nextfdelay = l1;                  }
 D (fprintf (stderr, "next opened(%d, %d, %d)\n",                 } else {
             nextfdelay, num_packets, transmission_time));                  fprintf (stderr, "File name missing\n");
                                               return (TRUE);                }
                                             }              } else {
                                           else                fprintf (stderr, "0<delay<time not allowed\n");
                                             {              }
                                               fprintf (stderr,            } else {
                                                 "File size not multiple of 188\n");              fprintf (stderr, "Time must not be negative\n");
                                             }            }
                                         }          } else {
                                       else            fprintf (stderr, "Time must be numeric\n");
                                         {  
                                           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 {
           fprintf (stderr, "Time missing\n");
         }
       } else {
         fprintf (stderr, "Delay must be numeric\n");
     }      }
   else    } else {
     {      return (TRUE);
       return (TRUE);    }
     }  
   return (FALSE);    return (FALSE);
 }  }
   
 static boolean  static boolean command_init (int cargc,
 command_init (int cargc, char **cargv)      char **cargv)
 {  {
     char *cdelay = NULL;
     char *ctime = NULL;
     char *cfile = NULL;
     int cc = 0;
   nextf = -1;    nextf = -1;
   quit = FALSE;    quit = FALSE;
   combln = 0;    combln = 0;
   dati = dato = 0;    dati = dato = 0;
   if (cargc > 1)    pollc = -1;
     {    while (++cc < cargc) {
       if (!strcmp (cargv[1], "--help"))      if (!strcmp (cargv[cc],"--help")) {
         {        command_help (cargv[0],"");
           command_help (cargv[0]);        return (FALSE);
           return (FALSE);      } else if (!strcmp (cargv[cc],"-i")) {
         }        pollc = 0;
       else      } else if (!strcmp (cargv[cc],"-d")) {
         if (!command_do        if ((cdelay != NULL) || (++cc >= cargc)) {
             (cargv[1], cargc > 2 ? cargv[2] : NULL,          command_help (cargv[0],"must not use -d twice.\n");
              cargc > 3 ? cargv[3] : NULL))          return (FALSE);
         {        }
           command_help (cargv[0]);        cdelay = cargv[cc];
           return (FALSE);      } 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;    cmdf = STDIN_FILENO;
   outf = STDOUT_FILENO;    outf = STDOUT_FILENO;
   return ((cmdf >= 0) && (outf >= 0));    return ((cmdf >= 0) && (outf >= 0));
 }  }
   
 int  int main (int argc,
 main (int argc, char *argv[])      char *argv[])
 {  {
   int polli, pollo, polls;    int polli, pollo, polls;
   int toberead = 0;   /* to make gcc happy */    int toberead;
   int currentf;    int currentf;
   int packet_count = 0;  
   
   boolean dotime;    boolean dotime;
   t_msec rtime;    t_msec rtime, ftime, rdelay, fdelay, now;
   t_msec rtime_base = 0;    struct pollfd ufds [3];
   t_msec ftime;    off_t rpackets, rpartial, rpdone;
   t_msec fdelay = 0;  /* to make gcc happy */    if (command_init (argc,&argv[0])) {
   t_msec now;      currentf = -1;
   struct pollfd ufds[3];      rtime = ftime = msec_now ();
   if (command_init (argc, &argv[0]))      while (!quit) {
     {        now = msec_now ();
       currentf = -1;  D(fprintf(stderr,"now(%d)\n",now));
       rtime = ftime = msec_now ();        if (currentf < 0) {
       while (!quit)          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 ();            now = msec_now ();
           D (fprintf (stderr, "now(%x)\n", now));            if ((ftime-now) < 0) {
           if (currentf < 0)              ftime = now;
             {            }
               toberead = 0;            rtime = ftime;
               fdelay = nextfdelay;          }
               if ((ftime - now) < 0)        }
                 {        if ((pollo >= 0)
                   ftime = now;         && (ufds[pollo].revents & (POLLOUT | POLLHUP | POLLERR))) {
                 }          if (ufds[pollo].revents & POLLOUT) {
               rtime_base = rtime = ftime;            int l;
               packet_count = 0;            if (dati < dato) {
               currentf = nextf;              l = MAX_ANOTATE - dato;
               nextf = -1;            } else {
               D (fprintf (stderr, "next current(%d,%d)\n", currentf, fdelay));              l = dati - dato;
             }            }
           if (currentf >= 0)            l = write (outf, &data[dato], l);
             {            dato = (dato+l) & (MAX_ANOTATE-1);
               if ((rtime - now) <= 0)            if (l == 0) {
                 {              quit = TRUE;
                   if ((((dato - dati - 1) & (MAX_ANOTATE - 1)) - toberead) >            }
                       TS_PACKET_SIZE)          } else {
                     {            quit = TRUE;
                       toberead += TS_PACKET_SIZE;  
   
                       packet_count++;  
                       if (num_packets > 0)  
                         {  
                           rtime = rtime_base +   
                             (t_msec)(((long long)packet_count * transmission_time) /  
                                      num_packets);  
                           D (fprintf (stderr, "%d %d %d %d %d\n",   
                                       rtime, rtime_base, packet_count,   
                                       transmission_time, num_packets));  
                         }  
                           
                       dotime = TRUE;  
                       D (fprintf (stderr, "timer a(%d,%d)\n", toberead, rtime));  
                     }  
                   else  
                     {  
                       rtime_base = rtime = now;  
                       packet_count = 0;  
                       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));  
             }  
           ufds[0].fd = cmdf;  
           ufds[0].events = POLLIN;  
           if (dati != dato)  
             {  
               ufds[1].fd = outf;  
               ufds[1].events = POLLOUT;  
               pollo = 1;  
             }  
           else  
             {  
               pollo = 0;  
             }  
           polls = pollo + 1;  
           if (toberead > 0)  
             {  
               polli = polls++;  
               ufds[polli].fd = currentf;  
               ufds[polli].events = POLLIN;  
             }  
           else  
             {  
               polli = 0;  
             }  
           poll (&ufds[1], polls-1,  
                 dotime ? ((rtime - now) > 0) ? (rtime - now) : 0 : -1);  
           if (ufds[0].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_base = rtime = ftime;  
                   packet_count = 0;  
                 }  
             }  
           if ((pollo != 0)  
               && (ufds[1].revents & (POLLOUT | POLLHUP | POLLERR)))  
             {  
               if (ufds[1].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_SUCCESS);
     }
   return (EXIT_FAILURE);    return (EXIT_FAILURE);
 }  }

Removed from v.1.6  
changed lines
  Added in v.1.7


LinuxTV legacy CVS <linuxtv.org/cvs>