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