File:  [DVB] / multiplexer / global.h
Revision 1.4: download - view: text, annotated - select for diffs
Tue Apr 3 21:14:33 2001 UTC (23 years, 2 months ago) by oskar
Branches: MAIN
CVS tags: HEAD
cleaning up.
buffer sizes now depend on split data type (video,audio,other).
new functions to unlink and remove streams from programs.
do not start dispatcher when command line is --help.
new command "crop" to remove program or stream from target.

/*
 * ISO 13818 stream multiplexer
 * Copyright (C) 2001 Convergence Integrated Media GmbH Berlin
 * Author: Oskar Schirmer (oskar@convergence.de)
 */

#include <asm/types.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

/* for a timing and poll profile: */
#if 0
#define DEBUG_TIMEPOLL
#endif

#define MAX_MSEC_OUTDELAY  500
#define MAX_MSEC_PUSHJTTR  (2 * 250)
#define MAX_MSEC_PCRDIST   (100 * 80/100)

#define MAX_POLLFD    (MAX_INFILE+3)

#define MAX_DATA_COMB 512
#define HIGHWATER_COM 8

#define MAX_CTRL_OUTB (1 << 11)
#define MAX_DATA_OUTB (MAX_CTRL_OUTB << 7)
#define HIGHWATER_OUT 512
#define MAX_WRITE_OUT (128 * 188)

#define MAX_CTRL_INB  (1 << 8)
#define MAX_DATA_INBV (MAX_CTRL_INB << 10)
#define MAX_DATA_INBA (MAX_CTRL_INB << 9)
#define MAX_DATA_INB  (MAX_CTRL_INB << 9)
#define HIGHWATER_IN  (16 * 1024)

#define MAX_DATA_RAWB (1 << 18)
#define HIGHWATER_RAW (16 * 1024)
#define MAX_READ_IN   (8 * 1024)

#define MAX_INSTREAM  64 /* ? */
#define MAX_INFILE    8  /* ? */

#define MAX_STRPERPS  (1<<8)
#define MAX_STRPERTS  (1<<13)

#define MAX_STRPERPRG 42 /* ? */
#define MAX_PRGFORSTR 12 /* ? */
#define MAX_OUTPROG   16  /* ? */

#define MAX_PSI_SIZE  1025
#define MAX_PMTSTREAMS (MAX_PSI_SIZE / 4)

#define ENDFILE_CLOSE 0
#define ENDFILE_RESET 1
#define ENDFILE_CHAIN 2

#define ENDSTR_KILL      0
#define ENDSTR_CLOSE     1
#define ENDSTR_WAIT      2

#define PES_LOWEST_SID    (0xBC)
#define NUMBER_ELEMD  19
#define TS_PACKET_SIZE 188

#define CRC_SIZE 4

#define boolean __u8
#define FALSE   0
#define TRUE    1

#define byte __u8
#define t_msec __s32

typedef struct {
  __u32 base;
  __u16 ext;
  byte ba33;
  boolean valid;
} clockref;

typedef struct {
  __u32 base;
  t_msec msec;
} conversion_base;

typedef struct {
  int index;
  int length;
  int sequence;
  t_msec msecread;
  t_msec msecpush;
  clockref pcr;
  clockref opcr;
  byte scramble;
} ctrl_buffer;

typedef struct {
  ctrl_buffer *ptr;
  int in;
  int out;
  int mask;
} refr_ctrl;

typedef struct {
  byte *ptr;
  int in;
  int out;
  int mask;
} refr_data;

#define list_empty(refr) ((refr).out == (refr).in)

#define list_create(refr,size) \
  ((((size) & ((size)-1)) || (size < 2)) ? \
     warn (LERR,"List Create",EGLO,1,1,size), FALSE : \
   ((refr).ptr = malloc((size) * sizeof(*(refr).ptr))) == NULL ? \
     warn (LERR,"List Create",EGLO,1,2,size), FALSE : \
   ((refr).mask = (size)-1, (refr).in = (refr).out = 0, TRUE))

#define list_release(refr) \
  ((refr).mask = 0, free((refr).ptr), (refr).ptr = NULL)

#define list_free(refr) \
  (((refr).out - (refr).in - 1) & (refr).mask)

#define list_freeinend(refr) \
  ((refr).mask + 1 - (refr).in)

#define list_size(refr) \
  (((refr).in - (refr).out) & (refr).mask)

#define list_full(refr) \
  (list_free(refr) == 0)

#define list_halffull(refr) \
  (list_size(refr) > ((refr).mask >> 1))

#define list_incr(var,refr,incr) \
  ((var) = (((var) + (incr)) & (refr).mask))

#define marker_check(data,val,mask) \
  (((data & mask) != val) ? \
    warn(LWAR,"Marker bit",EGLO,2,data,mask), TRUE : FALSE)

#define marker_bit(data,bit) \
  marker_check(data,1<<bit,1<<bit)

#define mmin(a,b) ((a)<(b)?(a):(b))
#define mmax(a,b) ((a)<(b)?(b):(a))

#define unionalloc(typ,fld) \
  (malloc (sizeof(typ)-sizeof(((typ*)0)->u)+sizeof(((typ*)0)->u.fld)))

typedef struct {
  int programnumber;
  short sourceid;
  byte version;
  byte *elemdnew[NUMBER_ELEMD];
} mapreference;

typedef struct pmtdescr {
  struct pmtdescr *next;
  short pat_section;
  byte pmt_version;
  int programnumber;
  short pcr_pid;
  short pmt_pid;
  short streams;
  short stream[MAX_PMTSTREAMS];
  byte streamtype[MAX_PMTSTREAMS];
  short descrlen;
  byte elemdescr[MAX_PSI_SIZE];
} pmt_descr;

typedef struct {
  int sprg, tprg, ssid, tsid;
} tsauto_descr;

typedef enum {
  ct_none,
  ct_packetized,
  ct_program,
  ct_transport,
  ct_unknown
} content_type;

typedef struct {
  refr_data data;
  char *name;
  int handle;
  int st_mode;
  struct pollfd *ufds;
  int skipped; /* undesired bytes skipped, total */
  int payload; /* split payload used total */
  int total; /* split total (skipped, used, wasted) */
  int sequence; /* source counter for PES sequence */
  short opendatastreams;
  short openmapstreams;
  byte endaction;
  boolean automatic; /* extract'o'use */
  int repeatitions;
  int auto_programnb;
  content_type content;
  union {
    struct {
      struct streamdescr *stream;
    } pes;
    struct {
      struct {
        clockref scr;
        __u32 muxrate;
      } ph;
      struct {
        __u32 ratebound;
        byte audiobound;
        byte videobound;
        boolean csps_flag;
        boolean fixed_flag;
        boolean system_video_lock_flag;
        boolean system_audio_lock_flag;
        boolean packet_rate_restriction_flag;
        short buffer_bound[MAX_STRPERPS-PES_LOWEST_SID];
      } sh;
/*
      struct {
      } dir;
*/
      struct streamdescr *stream[MAX_STRPERPS];
    } ps;
    struct {
      __u16 transportstreamid;
      byte pat_version;
      byte newpat_version;
      pmt_descr *pat;
      pmt_descr *newpat;
      int tsautos;
      tsauto_descr *tsauto;
      struct streamdescr *stream[MAX_STRPERTS];
    } ts;
  } u;
} file_descr;

typedef struct {
  int program_number;
  short pcr_pid;
  short pmt_pid;
  byte pmt_conticnt;
  byte pmt_version;
  boolean changed;
  short pat_section;
  short streams;
  struct streamdescr *stream[MAX_STRPERPRG];
} prog_descr;

typedef struct streamdescr {
  refr_ctrl ctrl;
  refr_data data;
  file_descr *fdescr;
  short sourceid; /* index into fdescr->u.xx.stream[] */
  byte stream_id; /* elementary stream id, table 2-35, etc */
  byte stream_type;
  byte version;
  byte conticnt;
  byte endaction;
  byte *elemdvld[NUMBER_ELEMD]; /* as valid for out */
  byte elemdescr[MAX_PSI_SIZE];
/*what if a stream is leftupper corner in one prog, but elsewhere in another?*/
  boolean isamap;
  union {
    struct {
      struct streamdescr *mapstream;
      t_msec next_clockref;
      t_msec delta;
      conversion_base conv;
      t_msec lasttime;
      short pid; /* splicets: 0010..1FFE, spliceps: ...FF */
      boolean discontinuity;
      boolean trigger;
      boolean mention;
      boolean has_clockref; /* in output */
      short progs;
      prog_descr *pdescr[MAX_PRGFORSTR];
    } d;
    struct {
      t_msec msectime;
      conversion_base conv;
      int psi_length;
      byte psi_data[MAX_PSI_SIZE+TS_PACKET_SIZE];
    } m;
  } u;
} stream_descr;


extern boolean timed_io;
extern boolean accept_weird_scr;
extern t_msec global_delta;
extern t_msec psi_frequency_msec;
extern boolean psi_frequency_changed;

t_msec msec_now (void);

void cref2msec (conversion_base *b,
    clockref c,
    t_msec *m);

void msec2cref (conversion_base *b,
    t_msec m,
    clockref *c);

void global_init (void);


#ifdef DEBUG_TIMEPOLL

#define max_timepoll (1024*1024)

typedef struct {
  struct timeval tv;
  t_msec msec_now;
  int usec;
  int tmo;
  int sr, si, so;
  unsigned char cnt_msecnow;
  unsigned char nfdso, nfdsi;
  unsigned char nfdsrevent;
  unsigned char flags;
} timepoll;
#define LTP_FLAG_DELTASHIFT 0x80
#define LTP_FLAG_OUTPUT     0x40
#define LTP_FLAG_INPUT      0x20
#define LTP_FLAG_SPLIT      0x10
#define LTP_FLAG_PROCESS    0x08

extern timepoll logtp [max_timepoll];
extern long logtpc;
extern timepoll *ltp;

#endif


LinuxTV legacy CVS <linuxtv.org/cvs>