Annotation of multiplexer/global.h, revision 1.6
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: #include <asm/types.h>
8: #include <sys/types.h>
9: #include <sys/poll.h>
10: #include <sys/time.h>
11: #include <sys/unistd.h>
12: #include <sys/stat.h>
13: #include <unistd.h>
14: #include <fcntl.h>
15: #include <stdlib.h>
16: #include <string.h>
17: #include <errno.h>
18:
19: /* for a timing and poll profile: */
20: #if 0
21: #define DEBUG_TIMEPOLL
22: #endif
23:
24: #define MAX_MSEC_OUTDELAY 500
25: #define MAX_MSEC_PUSHJTTR (2 * 250)
1.3 oskar 26: #define MAX_MSEC_PCRDIST (100 * 80/100)
1.1 oskar 27:
28: #define MAX_POLLFD (MAX_INFILE+3)
29:
30: #define MAX_DATA_COMB 512
31: #define HIGHWATER_COM 8
32:
1.4 oskar 33: #define MAX_CTRL_OUTB (1 << 11)
34: #define MAX_DATA_OUTB (MAX_CTRL_OUTB << 7)
1.1 oskar 35: #define HIGHWATER_OUT 512
36: #define MAX_WRITE_OUT (128 * 188)
37:
1.4 oskar 38: #define MAX_CTRL_INB (1 << 8)
39: #define MAX_DATA_INBV (MAX_CTRL_INB << 10)
40: #define MAX_DATA_INBA (MAX_CTRL_INB << 9)
41: #define MAX_DATA_INB (MAX_CTRL_INB << 9)
42: #define HIGHWATER_IN (16 * 1024)
43:
44: #define MAX_DATA_RAWB (1 << 18)
45: #define HIGHWATER_RAW (16 * 1024)
46: #define MAX_READ_IN (8 * 1024)
1.1 oskar 47:
48: #define MAX_INSTREAM 64 /* ? */
49: #define MAX_INFILE 8 /* ? */
50:
51: #define MAX_STRPERPS (1<<8)
52: #define MAX_STRPERTS (1<<13)
53:
54: #define MAX_STRPERPRG 42 /* ? */
55: #define MAX_PRGFORSTR 12 /* ? */
56: #define MAX_OUTPROG 16 /* ? */
57:
58: #define MAX_PSI_SIZE 1025
59: #define MAX_PMTSTREAMS (MAX_PSI_SIZE / 4)
60:
61: #define ENDSTR_KILL 0
62: #define ENDSTR_CLOSE 1
63: #define ENDSTR_WAIT 2
64:
65: #define PES_LOWEST_SID (0xBC)
66: #define NUMBER_ELEMD 19
67: #define TS_PACKET_SIZE 188
68:
69: #define CRC_SIZE 4
70:
71: #define boolean __u8
72: #define FALSE 0
73: #define TRUE 1
74:
75: #define byte __u8
1.4 oskar 76: #define t_msec __s32
1.1 oskar 77:
78: typedef struct {
1.4 oskar 79: __u32 base;
80: __u16 ext;
1.3 oskar 81: byte ba33;
1.1 oskar 82: boolean valid;
83: } clockref;
84:
85: typedef struct {
1.4 oskar 86: __u32 base;
87: t_msec msec;
1.3 oskar 88: } conversion_base;
1.1 oskar 89:
90: typedef struct {
91: int index;
92: int length;
93: int sequence;
1.4 oskar 94: t_msec msecread;
95: t_msec msecpush;
1.3 oskar 96: clockref pcr;
1.1 oskar 97: clockref opcr;
1.4 oskar 98: byte scramble;
1.1 oskar 99: } ctrl_buffer;
100:
101: typedef struct {
102: ctrl_buffer *ptr;
103: int in;
104: int out;
105: int mask;
106: } refr_ctrl;
107:
108: typedef struct {
109: byte *ptr;
110: int in;
111: int out;
112: int mask;
113: } refr_data;
114:
115: #define list_empty(refr) ((refr).out == (refr).in)
116:
117: #define list_create(refr,size) \
118: ((((size) & ((size)-1)) || (size < 2)) ? \
119: warn (LERR,"List Create",EGLO,1,1,size), FALSE : \
120: ((refr).ptr = malloc((size) * sizeof(*(refr).ptr))) == NULL ? \
121: warn (LERR,"List Create",EGLO,1,2,size), FALSE : \
122: ((refr).mask = (size)-1, (refr).in = (refr).out = 0, TRUE))
123:
124: #define list_release(refr) \
125: ((refr).mask = 0, free((refr).ptr), (refr).ptr = NULL)
126:
127: #define list_free(refr) \
128: (((refr).out - (refr).in - 1) & (refr).mask)
129:
130: #define list_freeinend(refr) \
131: ((refr).mask + 1 - (refr).in)
132:
133: #define list_size(refr) \
134: (((refr).in - (refr).out) & (refr).mask)
135:
136: #define list_full(refr) \
137: (list_free(refr) == 0)
138:
1.4 oskar 139: #define list_halffull(refr) \
140: (list_size(refr) > ((refr).mask >> 1))
141:
1.1 oskar 142: #define list_incr(var,refr,incr) \
143: ((var) = (((var) + (incr)) & (refr).mask))
144:
145: #define marker_check(data,val,mask) \
146: (((data & mask) != val) ? \
147: warn(LWAR,"Marker bit",EGLO,2,data,mask), TRUE : FALSE)
148:
149: #define marker_bit(data,bit) \
150: marker_check(data,1<<bit,1<<bit)
151:
152: #define mmin(a,b) ((a)<(b)?(a):(b))
153: #define mmax(a,b) ((a)<(b)?(b):(a))
154:
155: #define unionalloc(typ,fld) \
156: (malloc (sizeof(typ)-sizeof(((typ*)0)->u)+sizeof(((typ*)0)->u.fld)))
157:
158: typedef struct {
159: int programnumber;
1.4 oskar 160: short sourceid;
1.1 oskar 161: byte version;
162: byte *elemdnew[NUMBER_ELEMD];
163: } mapreference;
164:
165: typedef struct pmtdescr {
166: struct pmtdescr *next;
167: short pat_section;
168: byte pmt_version;
169: int programnumber;
1.4 oskar 170: short pcr_pid;
171: short pmt_pid;
172: short streams;
1.1 oskar 173: short stream[MAX_PMTSTREAMS];
174: byte streamtype[MAX_PMTSTREAMS];
1.4 oskar 175: short descrlen;
1.1 oskar 176: byte elemdescr[MAX_PSI_SIZE];
177: } pmt_descr;
178:
179: typedef struct {
180: int sprg, tprg, ssid, tsid;
181: } tsauto_descr;
182:
183: typedef enum {
184: ct_none,
185: ct_packetized,
186: ct_program,
187: ct_transport,
188: ct_unknown
189: } content_type;
190:
191: typedef struct {
192: refr_data data;
1.5 oskar 193: int handle;
1.1 oskar 194: char *name;
1.5 oskar 195: int filerefnum;
1.4 oskar 196: int st_mode;
1.1 oskar 197: struct pollfd *ufds;
198: int skipped; /* undesired bytes skipped, total */
199: int payload; /* split payload used total */
200: int total; /* split total (skipped, used, wasted) */
201: int sequence; /* source counter for PES sequence */
1.4 oskar 202: short opendatastreams;
203: short openmapstreams;
1.5 oskar 204: char *append_name;
205: int append_filerefnum;
206: int append_repeatitions;
1.2 oskar 207: int repeatitions;
1.1 oskar 208: int auto_programnb;
1.5 oskar 209: boolean automatic; /* extract'o'use */
210: boolean stopfile;
1.1 oskar 211: content_type content;
212: union {
213: struct {
214: struct streamdescr *stream;
215: } pes;
216: struct {
217: struct {
218: clockref scr;
1.4 oskar 219: __u32 muxrate;
1.1 oskar 220: } ph;
221: struct {
1.4 oskar 222: __u32 ratebound;
223: byte audiobound;
224: byte videobound;
1.1 oskar 225: boolean csps_flag;
226: boolean fixed_flag;
227: boolean system_video_lock_flag;
228: boolean system_audio_lock_flag;
229: boolean packet_rate_restriction_flag;
230: short buffer_bound[MAX_STRPERPS-PES_LOWEST_SID];
231: } sh;
232: /*
233: struct {
234: } dir;
235: */
236: struct streamdescr *stream[MAX_STRPERPS];
237: } ps;
238: struct {
1.4 oskar 239: __u16 transportstreamid;
1.1 oskar 240: byte pat_version;
241: byte newpat_version;
242: pmt_descr *pat;
243: pmt_descr *newpat;
244: int tsautos;
245: tsauto_descr *tsauto;
246: struct streamdescr *stream[MAX_STRPERTS];
247: } ts;
248: } u;
249: } file_descr;
250:
251: typedef struct {
252: int program_number;
1.4 oskar 253: short pcr_pid;
254: short pmt_pid;
1.1 oskar 255: byte pmt_conticnt;
256: byte pmt_version;
257: boolean changed;
1.4 oskar 258: short pat_section;
259: short streams;
1.1 oskar 260: struct streamdescr *stream[MAX_STRPERPRG];
261: } prog_descr;
262:
263: typedef struct streamdescr {
264: refr_ctrl ctrl;
265: refr_data data;
1.4 oskar 266: file_descr *fdescr;
267: short sourceid; /* index into fdescr->u.xx.stream[] */
1.1 oskar 268: byte stream_id; /* elementary stream id, table 2-35, etc */
269: byte stream_type;
270: byte version;
1.4 oskar 271: byte conticnt;
272: byte endaction;
1.1 oskar 273: byte *elemdvld[NUMBER_ELEMD]; /* as valid for out */
274: byte elemdescr[MAX_PSI_SIZE];
275: /*what if a stream is leftupper corner in one prog, but elsewhere in another?*/
276: boolean isamap;
277: union {
278: struct {
279: struct streamdescr *mapstream;
1.4 oskar 280: t_msec next_clockref;
281: t_msec delta;
282: conversion_base conv;
283: t_msec lasttime;
284: short pid; /* splicets: 0010..1FFE, spliceps: ...FF */
1.1 oskar 285: boolean discontinuity;
286: boolean trigger;
287: boolean mention;
288: boolean has_clockref; /* in output */
1.6 ! oskar 289: boolean has_opcr; /* in input */
1.4 oskar 290: short progs;
1.1 oskar 291: prog_descr *pdescr[MAX_PRGFORSTR];
292: } d;
293: struct {
1.4 oskar 294: t_msec msectime;
1.3 oskar 295: conversion_base conv;
1.1 oskar 296: int psi_length;
297: byte psi_data[MAX_PSI_SIZE+TS_PACKET_SIZE];
298: } m;
299: } u;
300: } stream_descr;
301:
302:
303: extern boolean timed_io;
304: extern boolean accept_weird_scr;
1.4 oskar 305: extern t_msec global_delta;
306: extern t_msec psi_frequency_msec;
1.1 oskar 307: extern boolean psi_frequency_changed;
308:
1.4 oskar 309: t_msec msec_now (void);
1.3 oskar 310:
311: void cref2msec (conversion_base *b,
312: clockref c,
1.4 oskar 313: t_msec *m);
1.3 oskar 314:
315: void msec2cref (conversion_base *b,
1.4 oskar 316: t_msec m,
1.3 oskar 317: clockref *c);
1.1 oskar 318:
319: void global_init (void);
320:
321:
322: #ifdef DEBUG_TIMEPOLL
323:
324: #define max_timepoll (1024*1024)
325:
326: typedef struct {
327: struct timeval tv;
1.4 oskar 328: t_msec msec_now;
1.1 oskar 329: int usec;
330: int tmo;
331: int sr, si, so;
332: unsigned char cnt_msecnow;
333: unsigned char nfdso, nfdsi;
334: unsigned char nfdsrevent;
335: unsigned char flags;
336: } timepoll;
337: #define LTP_FLAG_DELTASHIFT 0x80
338: #define LTP_FLAG_OUTPUT 0x40
339: #define LTP_FLAG_INPUT 0x20
340: #define LTP_FLAG_SPLIT 0x10
341: #define LTP_FLAG_PROCESS 0x08
342:
343: extern timepoll logtp [max_timepoll];
344: extern long logtpc;
345: extern timepoll *ltp;
346:
347: #endif
348:
LinuxTV legacy CVS <linuxtv.org/cvs>