Annotation of multiplexer/global.h, revision 1.9

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.7       oskar     192: /* Reference descriptors as these are parsed from PSI */
1.1       oskar     193: typedef struct {
                    194:   int programnumber;
1.4       oskar     195:   short sourceid;
1.1       oskar     196:   byte version;
                    197:   byte *elemdnew[NUMBER_ELEMD];
                    198: } mapreference;
                    199: 
1.7       oskar     200: /* Source TS PMT list */
1.1       oskar     201: typedef struct pmtdescr {
                    202:   struct pmtdescr *next;
                    203:   short pat_section;
                    204:   byte pmt_version;
                    205:   int programnumber;
1.4       oskar     206:   short pcr_pid;
                    207:   short pmt_pid;
                    208:   short streams;
1.1       oskar     209:   short stream[MAX_PMTSTREAMS];
                    210:   byte streamtype[MAX_PMTSTREAMS];
1.4       oskar     211:   short descrlen;
1.1       oskar     212:   byte elemdescr[MAX_PSI_SIZE];
                    213: } pmt_descr;
                    214: 
1.7       oskar     215: /* Automatic stream usage requests as stated via command */
1.8       oskar     216: typedef struct tsautodescr {
                    217:   struct tsautodescr *next;
                    218:   int sprg;
                    219:   int tprg;
                    220:   int ssid; /* ssid<0 when referencing a complete program */
                    221:   int tsid;
1.1       oskar     222: } tsauto_descr;
                    223: 
1.9     ! oskar     224: /* Declaration of pid ranges as being not-to-be-parsed SI */
        !           225: typedef struct tssidescr {
        !           226:   struct tssidescr *next;
        !           227:   short pid_low;
        !           228:   short pid_high;
        !           229: } tssi_descr;
        !           230: 
1.7       oskar     231: /* Supported input file types */
1.1       oskar     232: typedef enum {
                    233:   ct_none,
                    234:   ct_packetized,
                    235:   ct_program,
                    236:   ct_transport,
                    237:   ct_unknown
                    238: } content_type;
                    239: 
1.7       oskar     240: /* Source file */
1.1       oskar     241: typedef struct {
                    242:   refr_data data;
1.5       oskar     243:   int handle;
1.1       oskar     244:   char *name;
1.5       oskar     245:   int filerefnum;
1.4       oskar     246:   int st_mode;
1.1       oskar     247:   struct pollfd *ufds;
                    248:   int skipped; /* undesired bytes skipped, total */
                    249:   int payload; /* split payload used total */
                    250:   int total; /* split total (skipped, used, wasted) */
                    251:   int sequence; /* source counter for PES sequence */
1.4       oskar     252:   short opendatastreams;
                    253:   short openmapstreams;
1.5       oskar     254:   char *append_name;
                    255:   int append_filerefnum;
                    256:   int append_repeatitions;
1.2       oskar     257:   int repeatitions;
1.1       oskar     258:   int auto_programnb;
1.5       oskar     259:   boolean automatic; /* extract'o'use */
                    260:   boolean stopfile;
1.1       oskar     261:   content_type content;
                    262:   union {
                    263:     struct {
                    264:       struct streamdescr *stream;
                    265:     } pes;
                    266:     struct {
                    267:       struct {
                    268:         clockref scr;
1.4       oskar     269:         __u32 muxrate;
1.1       oskar     270:       } ph;
                    271:       struct {
1.4       oskar     272:         __u32 ratebound;
                    273:         byte audiobound;
                    274:         byte videobound;
1.1       oskar     275:         boolean csps_flag;
                    276:         boolean fixed_flag;
                    277:         boolean system_video_lock_flag;
                    278:         boolean system_audio_lock_flag;
                    279:         boolean packet_rate_restriction_flag;
                    280:         short buffer_bound[MAX_STRPERPS-PES_LOWEST_SID];
                    281:       } sh;
                    282: /*
                    283:       struct {
                    284:       } dir;
                    285: */
                    286:       struct streamdescr *stream[MAX_STRPERPS];
                    287:     } ps;
                    288:     struct {
1.4       oskar     289:       __u16 transportstreamid;
1.1       oskar     290:       byte pat_version;
                    291:       byte newpat_version;
                    292:       pmt_descr *pat;
                    293:       pmt_descr *newpat;
                    294:       tsauto_descr *tsauto;
1.9     ! oskar     295:       tssi_descr *tssi;
1.1       oskar     296:       struct streamdescr *stream[MAX_STRPERTS];
                    297:     } ts;
                    298:   } u;
                    299: } file_descr;
                    300: 
1.7       oskar     301: /* Target program */
1.1       oskar     302: typedef struct {
                    303:   int program_number;
1.4       oskar     304:   short pcr_pid;
                    305:   short pmt_pid;
1.1       oskar     306:   byte pmt_conticnt;
                    307:   byte pmt_version;
                    308:   boolean changed;
1.4       oskar     309:   short pat_section;
                    310:   short streams;
1.1       oskar     311:   struct streamdescr *stream[MAX_STRPERPRG];
                    312: } prog_descr;
                    313: 
1.7       oskar     314: /* Single data or map stream */
1.1       oskar     315: typedef struct streamdescr {
                    316:   refr_ctrl ctrl;
                    317:   refr_data data;
1.4       oskar     318:   file_descr *fdescr;
                    319:   short sourceid; /* index into fdescr->u.xx.stream[] */
1.1       oskar     320:   byte stream_id; /* elementary stream id, table 2-35, etc */
                    321:   byte stream_type;
                    322:   byte version;
1.4       oskar     323:   byte conticnt;
                    324:   byte endaction;
1.1       oskar     325:   byte *elemdvld[NUMBER_ELEMD]; /* as valid for out */
                    326:   byte elemdescr[MAX_PSI_SIZE];
                    327: /*what if a stream is leftupper corner in one prog, but elsewhere in another?*/
                    328:   boolean isamap;
                    329:   union {
                    330:     struct {
                    331:       struct streamdescr *mapstream;
1.4       oskar     332:       t_msec next_clockref;
                    333:       t_msec delta;
                    334:       conversion_base conv;
                    335:       t_msec lasttime;
                    336:       short pid; /* splicets: 0010..1FFE, spliceps: ...FF */
1.1       oskar     337:       boolean discontinuity;
                    338:       boolean trigger;
                    339:       boolean mention;
                    340:       boolean has_clockref; /* in output */
1.6       oskar     341:       boolean has_opcr; /* in input */
1.4       oskar     342:       short progs;
1.1       oskar     343:       prog_descr *pdescr[MAX_PRGFORSTR];
                    344:     } d;
                    345:     struct {
1.4       oskar     346:       t_msec msectime;
1.3       oskar     347:       conversion_base conv;
1.1       oskar     348:       int psi_length;
                    349:       byte psi_data[MAX_PSI_SIZE+TS_PACKET_SIZE];
                    350:     } m;
                    351:   } u;
                    352: } stream_descr;
                    353: 
                    354: 
                    355: extern boolean timed_io;
                    356: extern boolean accept_weird_scr;
1.4       oskar     357: extern t_msec global_delta;
                    358: extern t_msec psi_frequency_msec;
1.1       oskar     359: extern boolean psi_frequency_changed;
                    360: 
1.4       oskar     361: t_msec msec_now (void);
1.3       oskar     362: 
                    363: void cref2msec (conversion_base *b,
                    364:     clockref c,
1.4       oskar     365:     t_msec *m);
1.3       oskar     366: 
                    367: void msec2cref (conversion_base *b,
1.4       oskar     368:     t_msec m,
1.3       oskar     369:     clockref *c);
1.1       oskar     370: 
                    371: void global_init (void);
                    372: 
                    373: 
                    374: #ifdef DEBUG_TIMEPOLL
                    375: 
                    376: #define max_timepoll (1024*1024)
                    377: 
                    378: typedef struct {
                    379:   struct timeval tv;
1.4       oskar     380:   t_msec msec_now;
1.1       oskar     381:   int usec;
                    382:   int tmo;
                    383:   int sr, si, so;
                    384:   unsigned char cnt_msecnow;
                    385:   unsigned char nfdso, nfdsi;
                    386:   unsigned char nfdsrevent;
                    387:   unsigned char flags;
                    388: } timepoll;
                    389: #define LTP_FLAG_DELTASHIFT 0x80
                    390: #define LTP_FLAG_OUTPUT     0x40
                    391: #define LTP_FLAG_INPUT      0x20
                    392: #define LTP_FLAG_SPLIT      0x10
                    393: #define LTP_FLAG_PROCESS    0x08
                    394: 
                    395: extern timepoll logtp [max_timepoll];
                    396: extern long logtpc;
                    397: extern timepoll *ltp;
                    398: 
                    399: #endif
                    400: 

LinuxTV legacy CVS <linuxtv.org/cvs>