Annotation of multiplexer/dispatch.c, revision 1.3

1.1       oskar       1: /*
                      2:  * ISO 13818 stream multiplexer
                      3:  * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin
                      4:  * Author: Oskar Schirmer (oskar@convergence.de)
                      5:  */
                      6: 
                      7: /*
                      8:  * Module:  Dispatch
                      9:  * Purpose: Main dispatching loop.
                     10:  *
                     11:  * The first two buffer stages (raw file data and input stream data)
                     12:  * are filled gready, the following two stages (from input stream to
                     13:  * output data buffer, and further to stdout) are timing controlled.
                     14:  */
                     15: 
                     16: #include "global.h"
                     17: #include "error.h"
                     18: #include "splice.h"
                     19: #include "input.h"
                     20: #include "output.h"
                     21: #include "command.h"
                     22: #include "dispatch.h"
                     23: 
                     24: boolean fatal_error;
                     25: boolean force_quit;
                     26: boolean busy_work;
                     27: 
                     28: boolean dispatch_init (void)
                     29: {
                     30:   fatal_error = FALSE;
                     31:   force_quit = FALSE;
                     32:   busy_work = FALSE;
                     33:   return (TRUE);
                     34: }
                     35: 
1.3     ! oskar      36: /* Dispatch work to the modules as needed.
        !            37:  * Mainly, check a few internal conditions (buffer space,
        !            38:  * data availability), check the corresponding file with
        !            39:  * poll for readiness, then do something at the appropriate
        !            40:  * points to push data forward.
        !            41:  * Data is pushed thru the multiplexer unidirectionally:
        !            42:  * input --> f.rawdata --> s.pesdata --> o.spliceddata --> output
        !            43:  * The main loop continues as long as there is something to do.
        !            44:  * Thereafter, the last two stages may generate a finish and
        !            45:  * another loop tries to pump the buffers out.
        !            46:  */
1.1       oskar      47: void dispatch (void)
                     48: {
                     49:   boolean bi, bo, bs;
                     50:   stream_descr *st;
1.2       oskar      51:   t_msec tmo;
1.1       oskar      52:   unsigned int nfds, onfds, infds;
                     53:   struct pollfd ufds [MAX_POLLFD];
                     54:   warn (LDEB,"Dispatch",EDIS,0,0,0);
                     55:   bs = FALSE;
                     56:   st = input_available ();
                     57:   nfds = 0;
                     58:   command_expected (&nfds, &ufds[0]);
                     59:   onfds = nfds;
                     60:   bo = output_available (&nfds, &ufds[onfds], &tmo);
                     61:   while ((bo
                     62:        || bs
                     63:        || (st != NULL)
                     64:        || input_expected ()
                     65:        || ((tmo >= 0) && (tmo <= MAX_MSEC_OUTDELAY))
                     66:        || busy_work)
                     67:       && (!fatal_error)
                     68:       && (!force_quit)) {
                     69:     infds = nfds;
                     70:     bi = input_acceptable (&nfds, &ufds[infds], &tmo, output_acceptable ());
                     71:     if (bs) {
                     72:       tmo = 0;
                     73:     }
                     74:     warn (LDEB,"Poll",EDIS,0,1,tmo);
                     75: #ifdef DEBUG_TIMEPOLL
                     76:     ltp->tmo = tmo;
                     77: #endif
                     78:     if (!timed_io) {
                     79:       if (tmo > 0) {
                     80:         global_delta += tmo;
                     81:         tmo = 0;
                     82:         warn (LDEB,"Global Delta",EDIS,0,3,global_delta);
                     83: #ifdef DEBUG_TIMEPOLL
                     84:         ltp->flags |= LTP_FLAG_DELTASHIFT;
                     85: #endif
                     86:       }
                     87:     }
                     88: #ifdef DEBUG_TIMEPOLL
                     89:     if (ltp->usec != 0) {
                     90:       struct timeval tv;
                     91:       gettimeofday (&tv,NULL);
                     92:       ltp->usec -= tv.tv_usec;
                     93:     }
                     94:     ltp->nfdso = infds - onfds;
                     95:     ltp->nfdsi = nfds - infds;
                     96:     ltp->flags |=
                     97:       (bo ? LTP_FLAG_OUTPUT : 0) |
                     98:       (bi ? LTP_FLAG_INPUT : 0) |
                     99:       (bs ? LTP_FLAG_SPLIT : 0) |
                    100:       (st != NULL ? LTP_FLAG_PROCESS : 0);
                    101:     ltp->sr = deb_inraw_free (0);
                    102:     ltp->si = deb_instr_free (1);
                    103:     ltp->so = output_free ();
                    104:     ltp->nfdsrevent =
                    105: #endif
                    106:     poll (&ufds[0], nfds, tmo);
                    107: #ifdef DEBUG_TIMEPOLL
                    108:     if (logtpc < (max_timepoll-1)) {
                    109:       struct timeval tv;
                    110:       logtpc += 1;
                    111:       ltp++;
                    112:       gettimeofday (&tv,NULL);
                    113:       ltp->usec = tv.tv_usec;
                    114:     }
                    115: #endif
                    116:     warn (LDEB,"Poll done",EDIS,0,2,nfds);
                    117:     if ((0 < onfds)
                    118:      && (ufds[0].revents & (POLLIN | POLLHUP | POLLERR))) {
                    119:       command_process (ufds[0].revents & POLLIN);
                    120:     }
                    121:     if (bo
                    122:      && (ufds[onfds].revents & (POLLOUT | POLLHUP | POLLERR))) {
                    123:       output_something (ufds[onfds].revents & POLLOUT);
                    124:     }
                    125:     if (bi) {
                    126:       while (infds < nfds) {
                    127:         if (ufds[infds].revents & (POLLIN | POLLHUP | POLLERR)) {
                    128:           input_something (input_filehandle (ufds[infds].fd),
                    129:               ufds[infds].revents & POLLIN);
                    130:           bi = FALSE;
                    131:           bs = TRUE;
                    132:         }
                    133:         infds += 1;
                    134:       }
                    135:       if (!bi) {
                    136:         if (st == NULL) {
                    137:           st = input_available ();
                    138:         }
                    139:       }
                    140:     }
                    141:     if (bs) {
                    142:       bs = split_something ();
                    143:     }
                    144:     if ((st != NULL) && output_acceptable ()) {
                    145:       st = process_something (st);
                    146:       bs = TRUE;
                    147:     }
                    148:     if (st == NULL) {
                    149:       st = input_available ();
                    150:     }
                    151:     nfds = 0;
                    152:     command_expected (&nfds, &ufds[0]);
                    153:     onfds = nfds;
                    154:     bo = output_available (&nfds, &ufds[onfds], &tmo);
                    155:   }
                    156:   process_finish ();
1.2       oskar     157:   output_finish ();
1.1       oskar     158:   while ((output_available (&nfds, &ufds[0], &tmo)
                    159:        || (tmo >= 0))
                    160:       && (!fatal_error)) {
                    161:     output_something (TRUE);
                    162:   }
                    163: #ifdef DEBUG_TIMEPOLL
                    164:   {
                    165:     int i, u, s;
                    166:     i = 0;
                    167:     s = 0;
                    168:     fprintf (stderr,"lines: %8d\n",(int)logtpc);
                    169:     while (i < logtpc) {
                    170:       u = (logtp[i].usec > 0 ? 1000000 : 0) - logtp[i].usec;
                    171:       s += u;
                    172:       fprintf (stderr,
                    173:         "%08d %10d.%06d:%8d (%6d) %c%5d %d %d/%d %c%c%c%c %d (F:%6d,S:%6d,O:%6d)\n",
                    174:         i,
                    175:         (int)logtp[i].tv.tv_sec,
                    176:         (int)logtp[i].tv.tv_usec,
                    177:         logtp[i].msec_now,
                    178:         u,
                    179:         logtp[i].flags & LTP_FLAG_DELTASHIFT ? 'D' : ' ',
                    180:         logtp[i].tmo,
                    181:         logtp[i].cnt_msecnow,
                    182:         logtp[i].nfdsi,
                    183:         logtp[i].nfdso,
                    184:         logtp[i].flags & LTP_FLAG_INPUT ? 'I' : ' ',
                    185:         logtp[i].flags & LTP_FLAG_SPLIT ? 'S' : ' ',
                    186:         logtp[i].flags & LTP_FLAG_PROCESS ? 'P' : ' ',
                    187:         logtp[i].flags & LTP_FLAG_OUTPUT ? 'O' : ' ',
                    188:         logtp[i].nfdsrevent,
                    189:         logtp[i].sr,
                    190:         logtp[i].si,
                    191:         logtp[i].so
                    192:         );
                    193:       i += 1;
                    194:     }
                    195:     fprintf (stderr,"%43d\n",s);
                    196:   }
                    197: #endif
                    198: }
                    199: 

LinuxTV legacy CVS <linuxtv.org/cvs>