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>