Annotation of multiplexer/dispatch.c, revision 1.10

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

LinuxTV legacy CVS <linuxtv.org/cvs>