Annotation of multiplexer/global.h, revision 1.4
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 ENDFILE_CLOSE 0
62: #define ENDFILE_RESET 1
63: #define ENDFILE_CHAIN 2
64:
65: #define ENDSTR_KILL 0
66: #define ENDSTR_CLOSE 1
67: #define ENDSTR_WAIT 2
68:
69: #define PES_LOWEST_SID (0xBC)
70: #define NUMBER_ELEMD 19
71: #define TS_PACKET_SIZE 188
72:
73: #define CRC_SIZE 4
74:
75: #define boolean __u8
76: #define FALSE 0
77: #define TRUE 1
78:
79: #define byte __u8
1.4 ! oskar 80: #define t_msec __s32
1.1 oskar 81:
82: typedef struct {
1.4 ! oskar 83: __u32 base;
! 84: __u16 ext;
1.3 oskar 85: byte ba33;
1.1 oskar 86: boolean valid;
87: } clockref;
88:
89: typedef struct {
1.4 ! oskar 90: __u32 base;
! 91: t_msec msec;
1.3 oskar 92: } conversion_base;
1.1 oskar 93:
94: typedef struct {
95: int index;
96: int length;
97: int sequence;
1.4 ! oskar 98: t_msec msecread;
! 99: t_msec msecpush;
1.3 oskar 100: clockref pcr;
1.1 oskar 101: clockref opcr;
1.4 ! oskar 102: byte scramble;
1.1 oskar 103: } ctrl_buffer;
104:
105: typedef struct {
106: ctrl_buffer *ptr;
107: int in;
108: int out;
109: int mask;
110: } refr_ctrl;
111:
112: typedef struct {
113: byte *ptr;
114: int in;
115: int out;
116: int mask;
117: } refr_data;
118:
119: #define list_empty(refr) ((refr).out == (refr).in)
120:
121: #define list_create(refr,size) \
122: ((((size) & ((size)-1)) || (size < 2)) ? \
123: warn (LERR,"List Create",EGLO,1,1,size), FALSE : \
124: ((refr).ptr = malloc((size) * sizeof(*(refr).ptr))) == NULL ? \
125: warn (LERR,"List Create",EGLO,1,2,size), FALSE : \
126: ((refr).mask = (size)-1, (refr).in = (refr).out = 0, TRUE))
127:
128: #define list_release(refr) \
129: ((refr).mask = 0, free((refr).ptr), (refr).ptr = NULL)
130:
131: #define list_free(refr) \
132: (((refr).out - (refr).in - 1) & (refr).mask)
133:
134: #define list_freeinend(refr) \
135: ((refr).mask + 1 - (refr).in)
136:
137: #define list_size(refr) \
138: (((refr).in - (refr).out) & (refr).mask)
139:
140: #define list_full(refr) \
141: (list_free(refr) == 0)
142:
1.4 ! oskar 143: #define list_halffull(refr) \
! 144: (list_size(refr) > ((refr).mask >> 1))
! 145:
1.1 oskar 146: #define list_incr(var,refr,incr) \
147: ((var) = (((var) + (incr)) & (refr).mask))
148:
149: #define marker_check(data,val,mask) \
150: (((data & mask) != val) ? \
151: warn(LWAR,"Marker bit",EGLO,2,data,mask), TRUE : FALSE)
152:
153: #define marker_bit(data,bit) \
154: marker_check(data,1<<bit,1<<bit)
155:
156: #define mmin(a,b) ((a)<(b)?(a):(b))
157: #define mmax(a,b) ((a)<(b)?(b):(a))
158:
159: #define unionalloc(typ,fld) \
160: (malloc (sizeof(typ)-sizeof(((typ*)0)->u)+sizeof(((typ*)0)->u.fld)))
161:
162: typedef struct {
163: int programnumber;
1.4 ! oskar 164: short sourceid;
1.1 oskar 165: byte version;
166: byte *elemdnew[NUMBER_ELEMD];
167: } mapreference;
168:
169: typedef struct pmtdescr {
170: struct pmtdescr *next;
171: short pat_section;
172: byte pmt_version;
173: int programnumber;
1.4 ! oskar 174: short pcr_pid;
! 175: short pmt_pid;
! 176: short streams;
1.1 oskar 177: short stream[MAX_PMTSTREAMS];
178: byte streamtype[MAX_PMTSTREAMS];
1.4 ! oskar 179: short descrlen;
1.1 oskar 180: byte elemdescr[MAX_PSI_SIZE];
181: } pmt_descr;
182:
183: typedef struct {
184: int sprg, tprg, ssid, tsid;
185: } tsauto_descr;
186:
187: typedef enum {
188: ct_none,
189: ct_packetized,
190: ct_program,
191: ct_transport,
192: ct_unknown
193: } content_type;
194:
195: typedef struct {
196: refr_data data;
197: char *name;
198: int handle;
1.4 ! oskar 199: int st_mode;
1.1 oskar 200: struct pollfd *ufds;
201: int skipped; /* undesired bytes skipped, total */
202: int payload; /* split payload used total */
203: int total; /* split total (skipped, used, wasted) */
204: int sequence; /* source counter for PES sequence */
1.4 ! oskar 205: short opendatastreams;
! 206: short openmapstreams;
1.1 oskar 207: byte endaction;
208: boolean automatic; /* extract'o'use */
1.2 oskar 209: int repeatitions;
1.1 oskar 210: int auto_programnb;
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.4 ! oskar 289: short progs;
1.1 oskar 290: prog_descr *pdescr[MAX_PRGFORSTR];
291: } d;
292: struct {
1.4 ! oskar 293: t_msec msectime;
1.3 oskar 294: conversion_base conv;
1.1 oskar 295: int psi_length;
296: byte psi_data[MAX_PSI_SIZE+TS_PACKET_SIZE];
297: } m;
298: } u;
299: } stream_descr;
300:
301:
302: extern boolean timed_io;
303: extern boolean accept_weird_scr;
1.4 ! oskar 304: extern t_msec global_delta;
! 305: extern t_msec psi_frequency_msec;
1.1 oskar 306: extern boolean psi_frequency_changed;
307:
1.4 ! oskar 308: t_msec msec_now (void);
1.3 oskar 309:
310: void cref2msec (conversion_base *b,
311: clockref c,
1.4 ! oskar 312: t_msec *m);
1.3 oskar 313:
314: void msec2cref (conversion_base *b,
1.4 ! oskar 315: t_msec m,
1.3 oskar 316: clockref *c);
1.1 oskar 317:
318: void global_init (void);
319:
320:
321: #ifdef DEBUG_TIMEPOLL
322:
323: #define max_timepoll (1024*1024)
324:
325: typedef struct {
326: struct timeval tv;
1.4 ! oskar 327: t_msec msec_now;
1.1 oskar 328: int usec;
329: int tmo;
330: int sr, si, so;
331: unsigned char cnt_msecnow;
332: unsigned char nfdso, nfdsi;
333: unsigned char nfdsrevent;
334: unsigned char flags;
335: } timepoll;
336: #define LTP_FLAG_DELTASHIFT 0x80
337: #define LTP_FLAG_OUTPUT 0x40
338: #define LTP_FLAG_INPUT 0x20
339: #define LTP_FLAG_SPLIT 0x10
340: #define LTP_FLAG_PROCESS 0x08
341:
342: extern timepoll logtp [max_timepoll];
343: extern long logtpc;
344: extern timepoll *ltp;
345:
346: #endif
347:
LinuxTV legacy CVS <linuxtv.org/cvs>