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>