Annotation of multiplexer/global.h, revision 1.12
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:
1.12 ! oskar 24: #define PES_LOWEST_SID (0xBC)
! 25: #define NUMBER_ELEMD 19
! 26: #define TS_PACKET_SIZE 188
! 27:
! 28: #define CRC_SIZE 4
! 29:
1.1 oskar 30: #define MAX_MSEC_OUTDELAY 500
31: #define MAX_MSEC_PUSHJTTR (2 * 250)
1.3 oskar 32: #define MAX_MSEC_PCRDIST (100 * 80/100)
1.1 oskar 33:
1.12 ! oskar 34: #define TRIGGER_MSEC_INPUT 250
! 35: #define TRIGGER_MSEC_OUTPUT 250
1.1 oskar 36:
37: #define MAX_DATA_COMB 512
38: #define HIGHWATER_COM 8
39:
1.12 ! oskar 40: #define MAX_CTRL_OUTB (1 << 16)
1.4 oskar 41: #define MAX_DATA_OUTB (MAX_CTRL_OUTB << 7)
1.1 oskar 42: #define HIGHWATER_OUT 512
1.12 ! oskar 43: #define MAX_WRITE_OUT (44 * TS_PACKET_SIZE)
1.1 oskar 44:
1.12 ! oskar 45: #define MAX_CTRL_INB (1 << 10)
1.4 oskar 46: #define MAX_DATA_INBV (MAX_CTRL_INB << 10)
47: #define MAX_DATA_INBA (MAX_CTRL_INB << 9)
48: #define MAX_DATA_INB (MAX_CTRL_INB << 9)
49: #define HIGHWATER_IN (16 * 1024)
50:
51: #define MAX_DATA_RAWB (1 << 18)
52: #define HIGHWATER_RAW (16 * 1024)
53: #define MAX_READ_IN (8 * 1024)
1.1 oskar 54:
55: #define MAX_INSTREAM 64 /* ? */
56: #define MAX_INFILE 8 /* ? */
57:
58: #define MAX_STRPERPS (1<<8)
59: #define MAX_STRPERTS (1<<13)
60:
61: #define MAX_STRPERPRG 42 /* ? */
62: #define MAX_PRGFORSTR 12 /* ? */
63: #define MAX_OUTPROG 16 /* ? */
64:
65: #define MAX_PSI_SIZE 1025
66: #define MAX_PMTSTREAMS (MAX_PSI_SIZE / 4)
67:
1.12 ! oskar 68: #define MAX_POLLFD (MAX_INFILE+3)
! 69:
1.1 oskar 70: #define ENDSTR_KILL 0
71: #define ENDSTR_CLOSE 1
72: #define ENDSTR_WAIT 2
73:
74: #define boolean __u8
75: #define FALSE 0
76: #define TRUE 1
77:
78: #define byte __u8
1.4 oskar 79: #define t_msec __s32
1.1 oskar 80:
1.7 oskar 81: /* ISO 13818 clock reference 90kHz (33 bit) with 27MHz extension (9 bit).
82: * ba33 holds the high bit of base.
83: */
1.1 oskar 84: typedef struct {
1.4 oskar 85: __u32 base;
86: __u16 ext;
1.3 oskar 87: byte ba33;
1.1 oskar 88: boolean valid;
89: } clockref;
90:
1.7 oskar 91: /* For conversion purposes, this pair of values holds a partial clock
92: * reference and an internal value in milliseconds. This is to eliminate
93: * wrapping faults without producing conversion inaccuracies.
94: */
1.1 oskar 95: typedef struct {
1.4 oskar 96: __u32 base;
97: t_msec msec;
1.3 oskar 98: } conversion_base;
1.1 oskar 99:
1.7 oskar 100: /* On reference to a controlled data buffer, this one holds the control
101: * information, mainly: index into the data buffer, length of the referenced
102: * data block. In a controlled data buffer, a data block is never split to
103: * wrap at the end of the buffer. The other fields are usage dependend.
104: */
1.1 oskar 105: typedef struct {
106: int index;
107: int length;
108: int sequence;
1.4 oskar 109: t_msec msecread;
110: t_msec msecpush;
1.3 oskar 111: clockref pcr;
1.1 oskar 112: clockref opcr;
1.4 oskar 113: byte scramble;
1.1 oskar 114: } ctrl_buffer;
115:
1.7 oskar 116: /* Control buffer */
1.1 oskar 117: typedef struct {
118: ctrl_buffer *ptr;
119: int in;
120: int out;
121: int mask;
122: } refr_ctrl;
123:
1.7 oskar 124: /* Data buffer */
1.1 oskar 125: typedef struct {
126: byte *ptr;
127: int in;
128: int out;
129: int mask;
130: } refr_data;
131:
132:
1.7 oskar 133: /* Create a new buffer, return TRUE on success, FALSE otherwise */
1.1 oskar 134: #define list_create(refr,size) \
135: ((((size) & ((size)-1)) || (size < 2)) ? \
136: warn (LERR,"List Create",EGLO,1,1,size), FALSE : \
137: ((refr).ptr = malloc((size) * sizeof(*(refr).ptr))) == NULL ? \
138: warn (LERR,"List Create",EGLO,1,2,size), FALSE : \
139: ((refr).mask = (size)-1, (refr).in = (refr).out = 0, TRUE))
140:
1.7 oskar 141: /* Release a buffer no longer used */
1.1 oskar 142: #define list_release(refr) \
143: ((refr).mask = 0, free((refr).ptr), (refr).ptr = NULL)
144:
1.12 ! oskar 145: /* Test on buffer emptiness */
! 146: #define list_empty(refr) ((refr).out == (refr).in)
! 147:
1.7 oskar 148: /* Compute number of free elements in buffer */
1.1 oskar 149: #define list_free(refr) \
150: (((refr).out - (refr).in - 1) & (refr).mask)
151:
1.7 oskar 152: /* Compute number of free elements up to the wrapping point, if the
153: latter is included in the free part of the buffer */
1.1 oskar 154: #define list_freeinend(refr) \
155: ((refr).mask + 1 - (refr).in)
156:
1.7 oskar 157: /* Compute number of used elements in buffer (i.e. its current size) */
1.1 oskar 158: #define list_size(refr) \
159: (((refr).in - (refr).out) & (refr).mask)
160:
1.7 oskar 161: /* Test on buffer fullness */
1.1 oskar 162: #define list_full(refr) \
163: (list_free(refr) == 0)
164:
1.12 ! oskar 165: /* Test on buffer partial fullness (as trigger criterium) */
! 166: #define list_partialfull(refr) \
! 167: (list_size(refr) > ((refr).mask * 3/4))
1.4 oskar 168:
1.7 oskar 169: /* Increment an index variable that points in to a buffer by a given value */
1.1 oskar 170: #define list_incr(var,refr,incr) \
171: ((var) = (((var) + (incr)) & (refr).mask))
1.12 ! oskar 172:
1.1 oskar 173:
1.7 oskar 174: /* Check a data byte against a mask */
1.1 oskar 175: #define marker_check(data,val,mask) \
176: (((data & mask) != val) ? \
177: warn(LWAR,"Marker bit",EGLO,2,data,mask), TRUE : FALSE)
178:
1.7 oskar 179: /* Check whether a given bit is set in a data byte */
1.1 oskar 180: #define marker_bit(data,bit) \
181: marker_check(data,1<<bit,1<<bit)
182:
183: #define mmin(a,b) ((a)<(b)?(a):(b))
184: #define mmax(a,b) ((a)<(b)?(b):(a))
185:
1.7 oskar 186: /* Allocate memory for a struct with known union usage */
1.1 oskar 187: #define unionalloc(typ,fld) \
188: (malloc (sizeof(typ)-sizeof(((typ*)0)->u)+sizeof(((typ*)0)->u.fld)))
189:
1.8 oskar 190: /* Release a chained list completely */
191: #define releasechain(typ,root) \
192: { register typ *n, *p = root; \
193: while (p != NULL) { \
194: n = p->next; free (p); p = n; \
195: } }
196:
1.10 oskar 197: /* Supported input file types */
198: typedef enum {
199: ct_packetized, /* packetized elementary stream */
200: ct_program, /* program stream */
201: ct_transport, /* transport stream */
1.11 oskar 202: number_ct
1.10 oskar 203: } content_type;
204:
205: /* stream data types, dependend on buffer contents */
206: typedef enum {
207: sd_data, /* PES packet */
208: sd_map, /* mapreference containing descriptors */
209: sd_unparsedsi, /* TS packet containing raw partial SI sections */
1.11 oskar 210: number_sd
1.10 oskar 211: } streamdata_type;
212:
1.7 oskar 213: /* Reference descriptors as these are parsed from PSI */
1.1 oskar 214: typedef struct {
215: int programnumber;
1.4 oskar 216: short sourceid;
1.1 oskar 217: byte version;
218: byte *elemdnew[NUMBER_ELEMD];
219: } mapreference;
220:
1.7 oskar 221: /* Source TS PMT list */
1.1 oskar 222: typedef struct pmtdescr {
223: struct pmtdescr *next;
224: short pat_section;
225: byte pmt_version;
226: int programnumber;
1.4 oskar 227: short pcr_pid;
228: short pmt_pid;
229: short streams;
1.1 oskar 230: short stream[MAX_PMTSTREAMS];
231: byte streamtype[MAX_PMTSTREAMS];
1.4 oskar 232: short descrlen;
1.1 oskar 233: byte elemdescr[MAX_PSI_SIZE];
234: } pmt_descr;
235:
1.7 oskar 236: /* Automatic stream usage requests as stated via command */
1.8 oskar 237: typedef struct tsautodescr {
238: struct tsautodescr *next;
239: int sprg;
240: int tprg;
241: int ssid; /* ssid<0 when referencing a complete program */
242: int tsid;
1.1 oskar 243: } tsauto_descr;
244:
1.9 oskar 245: /* Declaration of pid ranges as being not-to-be-parsed SI */
246: typedef struct tssidescr {
247: struct tssidescr *next;
248: short pid_low;
249: short pid_high;
250: } tssi_descr;
251:
1.7 oskar 252: /* Source file */
1.1 oskar 253: typedef struct {
254: refr_data data;
1.5 oskar 255: int handle;
1.1 oskar 256: char *name;
1.5 oskar 257: int filerefnum;
1.4 oskar 258: int st_mode;
1.1 oskar 259: struct pollfd *ufds;
260: int skipped; /* undesired bytes skipped, total */
261: int payload; /* split payload used total */
262: int total; /* split total (skipped, used, wasted) */
263: int sequence; /* source counter for PES sequence */
1.11 oskar 264: short openstreams[number_sd];
1.5 oskar 265: char *append_name;
266: int append_filerefnum;
267: int append_repeatitions;
1.2 oskar 268: int repeatitions;
1.1 oskar 269: int auto_programnb;
1.5 oskar 270: boolean automatic; /* extract'o'use */
271: boolean stopfile;
1.1 oskar 272: content_type content;
273: union {
274: struct {
275: struct streamdescr *stream;
276: } pes;
277: struct {
278: struct {
279: clockref scr;
1.4 oskar 280: __u32 muxrate;
1.1 oskar 281: } ph;
282: struct {
1.4 oskar 283: __u32 ratebound;
284: byte audiobound;
285: byte videobound;
1.1 oskar 286: boolean csps_flag;
287: boolean fixed_flag;
288: boolean system_video_lock_flag;
289: boolean system_audio_lock_flag;
290: boolean packet_rate_restriction_flag;
291: short buffer_bound[MAX_STRPERPS-PES_LOWEST_SID];
292: } sh;
293: /*
294: struct {
295: } dir;
296: */
297: struct streamdescr *stream[MAX_STRPERPS];
298: } ps;
299: struct {
1.4 oskar 300: __u16 transportstreamid;
1.1 oskar 301: byte pat_version;
302: byte newpat_version;
303: pmt_descr *pat;
304: pmt_descr *newpat;
305: tsauto_descr *tsauto;
1.9 oskar 306: tssi_descr *tssi;
1.1 oskar 307: struct streamdescr *stream[MAX_STRPERTS];
308: } ts;
309: } u;
310: } file_descr;
311:
1.7 oskar 312: /* Target program */
1.1 oskar 313: typedef struct {
314: int program_number;
1.4 oskar 315: short pcr_pid;
316: short pmt_pid;
1.1 oskar 317: byte pmt_conticnt;
318: byte pmt_version;
319: boolean changed;
1.4 oskar 320: short pat_section;
321: short streams;
1.1 oskar 322: struct streamdescr *stream[MAX_STRPERPRG];
323: } prog_descr;
324:
1.7 oskar 325: /* Single data or map stream */
1.1 oskar 326: typedef struct streamdescr {
327: refr_ctrl ctrl;
328: refr_data data;
1.4 oskar 329: file_descr *fdescr;
330: short sourceid; /* index into fdescr->u.xx.stream[] */
1.1 oskar 331: byte stream_id; /* elementary stream id, table 2-35, etc */
332: byte stream_type;
333: byte version;
1.4 oskar 334: byte conticnt;
335: byte endaction;
1.1 oskar 336: byte *elemdvld[NUMBER_ELEMD]; /* as valid for out */
337: byte elemdescr[MAX_PSI_SIZE];
338: /*what if a stream is leftupper corner in one prog, but elsewhere in another?*/
1.10 oskar 339: streamdata_type streamdata;
1.1 oskar 340: union {
341: struct {
342: struct streamdescr *mapstream;
1.4 oskar 343: t_msec next_clockref;
344: t_msec delta;
345: conversion_base conv;
346: t_msec lasttime;
347: short pid; /* splicets: 0010..1FFE, spliceps: ...FF */
1.1 oskar 348: boolean discontinuity;
349: boolean trigger;
350: boolean mention;
351: boolean has_clockref; /* in output */
1.6 oskar 352: boolean has_opcr; /* in input */
1.4 oskar 353: short progs;
1.1 oskar 354: prog_descr *pdescr[MAX_PRGFORSTR];
355: } d;
356: struct {
1.4 oskar 357: t_msec msectime;
1.3 oskar 358: conversion_base conv;
1.1 oskar 359: int psi_length;
360: byte psi_data[MAX_PSI_SIZE+TS_PACKET_SIZE];
361: } m;
1.10 oskar 362: struct {
363: t_msec delta;
364: } usi;
1.1 oskar 365: } u;
366: } stream_descr;
367:
368:
369: extern boolean timed_io;
370: extern boolean accept_weird_scr;
1.4 oskar 371: extern t_msec global_delta;
372: extern t_msec psi_frequency_msec;
1.1 oskar 373: extern boolean psi_frequency_changed;
374:
1.4 oskar 375: t_msec msec_now (void);
1.3 oskar 376:
377: void cref2msec (conversion_base *b,
378: clockref c,
1.4 oskar 379: t_msec *m);
1.3 oskar 380:
381: void msec2cref (conversion_base *b,
1.4 oskar 382: t_msec m,
1.3 oskar 383: clockref *c);
1.1 oskar 384:
385: void global_init (void);
386:
387:
388: #ifdef DEBUG_TIMEPOLL
389:
390: #define max_timepoll (1024*1024)
391:
392: typedef struct {
393: struct timeval tv;
1.4 oskar 394: t_msec msec_now;
1.1 oskar 395: int usec;
396: int tmo;
397: int sr, si, so;
398: unsigned char cnt_msecnow;
399: unsigned char nfdso, nfdsi;
400: unsigned char nfdsrevent;
401: unsigned char flags;
402: } timepoll;
403: #define LTP_FLAG_DELTASHIFT 0x80
404: #define LTP_FLAG_OUTPUT 0x40
405: #define LTP_FLAG_INPUT 0x20
406: #define LTP_FLAG_SPLIT 0x10
407: #define LTP_FLAG_PROCESS 0x08
408:
409: extern timepoll logtp [max_timepoll];
410: extern long logtpc;
411: extern timepoll *ltp;
412:
413: #endif
414:
LinuxTV legacy CVS <linuxtv.org/cvs>