Annotation of multiplexer/global.h, revision 1.16

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

LinuxTV legacy CVS <linuxtv.org/cvs>