mirror of
https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
synced 2023-10-10 17:16:51 +00:00
Initial revision
This commit is contained in:
1
libdvbmpeg/.cvsignore
Normal file
1
libdvbmpeg/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
.depend
|
446
libdvbmpeg/DVB.hh
Normal file
446
libdvbmpeg/DVB.hh
Normal file
@@ -0,0 +1,446 @@
|
||||
#ifndef _DVB_DEV_HH_
|
||||
#define _DVB_DEV_HH_
|
||||
|
||||
extern "C" {
|
||||
#include <asm/errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/un.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define NEWSTRUCT
|
||||
#include <channel.h>
|
||||
}
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
#include <osd.hh>
|
||||
#include <devices.hh>
|
||||
|
||||
#ifndef MAXNAM
|
||||
#define MAXNAM 80
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define FRONT_DVBS 1
|
||||
#define FRONT_DVBC 2
|
||||
#define FRONT_DVBT 3
|
||||
|
||||
#define VTXDIR "/var/vtx"
|
||||
|
||||
#define DEC(N) dec << setw(N) << setfill('0')
|
||||
#define HEX(N) hex << setw(N) << setfill('0')
|
||||
|
||||
#define MAXSECSIZE 4096
|
||||
|
||||
#define NK 10
|
||||
enum {LNB=0,DIS,ROTOR,TRANS,CHAN,BOU,SAT,PICS,SWI,NTW};
|
||||
static const int nums[]={LNB,DIS,ROTOR,TRANS,CHAN,BOU,SAT,PICS,SWI,NTW};
|
||||
static const int maxs[]={ 32, 32, 32, 512,16384,512,100, 50, 10, 100};
|
||||
|
||||
#define MAX_TRANS_CHAN 1024
|
||||
|
||||
enum{DVB_ORIG=0, DVB_NOKIA, DVB_XML, DVB_SATCO};
|
||||
|
||||
typedef struct frontend_stat_s{
|
||||
fe_status_t status;
|
||||
uint16_t snr;
|
||||
uint16_t strength;
|
||||
uint32_t ber;
|
||||
uint32_t u_blocks;
|
||||
} frontend_stat;
|
||||
|
||||
|
||||
extern uint8_t hamtab[256];
|
||||
extern uint8_t invtab[256];
|
||||
|
||||
#define MAX_MAG 8
|
||||
typedef struct mag_struct_ {
|
||||
int valid;
|
||||
int magn;
|
||||
uint8_t flags;
|
||||
uint8_t lang;
|
||||
int pnum,sub;
|
||||
uint8_t pagebuf[25*40];
|
||||
} magazin_t;
|
||||
|
||||
|
||||
class DVB {
|
||||
public:
|
||||
int no_open;
|
||||
int fd_frontend;
|
||||
int fd_demuxa;
|
||||
int fd_demuxv;
|
||||
int fd_demuxpcr;
|
||||
int fd_demuxtt;
|
||||
int fdvb;
|
||||
|
||||
int minor;
|
||||
int adapter;
|
||||
int max_tpid;
|
||||
int max_satid;
|
||||
int max_chanid;
|
||||
|
||||
frontend_stat festat;
|
||||
|
||||
struct dvb_diseqc_master_cmd dcmd;
|
||||
fe_sec_tone_mode_t tone;
|
||||
fe_sec_voltage_t voltage;
|
||||
int burst;
|
||||
struct dmx_pes_filter_params pesFilterParamsV;
|
||||
struct dmx_pes_filter_params pesFilterParamsA;
|
||||
struct dmx_pes_filter_params pesFilterParamsP;
|
||||
struct dmx_pes_filter_params pesFilterParamsTT;
|
||||
struct dvb_frontend_parameters front_param;
|
||||
int front_type;
|
||||
int dvr_enabled;
|
||||
OSD osd;
|
||||
uint32_t transponder_freq;
|
||||
char transponder_pol;
|
||||
uint32_t transponder_srate;
|
||||
|
||||
|
||||
|
||||
fe_status_t status;
|
||||
uint32_t ber, uncorrected_blocks;
|
||||
uint16_t snr, signal;
|
||||
|
||||
|
||||
struct Lnb *lnbs;
|
||||
struct DiSEqC *diseqcs;
|
||||
struct Rotor *rotors;
|
||||
struct Transponder *tps;
|
||||
struct Channel *chans;
|
||||
struct Bouquet *bouqs;
|
||||
struct Sat *sats;
|
||||
struct Picture *pics;
|
||||
struct Switch *swis;
|
||||
struct Network *ntws;
|
||||
int num[NK];
|
||||
int oldsec;
|
||||
int tryit;
|
||||
int oldpol;
|
||||
|
||||
char *vtxdir;
|
||||
magazin_t magazin[MAX_MAG];
|
||||
|
||||
DVB(){
|
||||
no_open = 0;
|
||||
max_tpid = 0;
|
||||
max_satid = 0;
|
||||
max_chanid = 0;
|
||||
minor = 0;
|
||||
|
||||
fd_frontend = -1;
|
||||
fd_demuxa = -1;
|
||||
fd_demuxpcr = -1;
|
||||
fd_demuxv = -1;
|
||||
fd_demuxtt = -1;
|
||||
fdvb = -1;
|
||||
vtxdir = NULL;
|
||||
transponder_freq=0;
|
||||
transponder_pol=0;
|
||||
transponder_srate=0;
|
||||
}
|
||||
|
||||
DVB(int i){
|
||||
if (i >= 0)
|
||||
no_open = 0;
|
||||
else
|
||||
no_open = 1;
|
||||
max_tpid = 0;
|
||||
max_satid = 0;
|
||||
max_chanid = 0;
|
||||
|
||||
fd_frontend = -1;
|
||||
fd_demuxa = -1;
|
||||
fd_demuxpcr = -1;
|
||||
fd_demuxv = -1;
|
||||
fd_demuxtt = -1;
|
||||
fdvb = -1;
|
||||
vtxdir = NULL;
|
||||
transponder_freq=0;
|
||||
transponder_pol=0;
|
||||
transponder_srate=0;
|
||||
|
||||
init("","",i);
|
||||
}
|
||||
|
||||
DVB(char *a, char *b) {
|
||||
max_tpid = 0;
|
||||
max_satid = 0;
|
||||
max_chanid = 0;
|
||||
|
||||
fd_frontend = -1;
|
||||
fd_demuxa = -1;
|
||||
fd_demuxpcr = -1;
|
||||
fd_demuxv = -1;
|
||||
fd_demuxtt = -1;
|
||||
|
||||
fdvb = -1;
|
||||
vtxdir = NULL;
|
||||
init(a,b,0);
|
||||
}
|
||||
|
||||
~DVB();
|
||||
|
||||
void use_osd(int fd = -1){
|
||||
char dvn[32];
|
||||
if (no_open) return;
|
||||
if (fd < 0) fd = 0;
|
||||
sprintf(dvn,OSD_DEV,adapter,fd);
|
||||
fdvb = open(dvn, O_RDWR);
|
||||
|
||||
if (fdvb >= 0){
|
||||
cerr << dvn << " for OSD" << endl;
|
||||
osd.init(fdvb);
|
||||
} else perror("osd");
|
||||
osd.Open(80, 500, 640, 540, 2, 0, 2);
|
||||
osd.SetColor(0, 0, 0, 0, 255);
|
||||
osd.SetColor(1, 240, 240, 240, 255);
|
||||
osd.Show();
|
||||
}
|
||||
|
||||
void set_vtxdir(char *newname){
|
||||
if (!newname) return;
|
||||
if (vtxdir) free(vtxdir);
|
||||
vtxdir = (char *) malloc(sizeof(char)*(strlen(newname)+1));
|
||||
if (vtxdir)
|
||||
strncpy(vtxdir, newname, strlen(newname));
|
||||
}
|
||||
|
||||
void close_osd(){
|
||||
osd.Close(fdvb);
|
||||
close(fdvb);
|
||||
}
|
||||
|
||||
int DVR_enabled(){
|
||||
if (no_open) return -1;
|
||||
return dvr_enabled;
|
||||
}
|
||||
|
||||
void enable_DVR(){
|
||||
if (no_open) return;
|
||||
dvr_enabled = 1;
|
||||
}
|
||||
|
||||
void enable_DVR_other(){
|
||||
if (no_open) return;
|
||||
dvr_enabled = 2;
|
||||
}
|
||||
|
||||
void disable_DVR(){
|
||||
if (no_open) return;
|
||||
dvr_enabled = 0;
|
||||
}
|
||||
|
||||
void init(char *a="/dev/video0", char *b="/dev/vbi0",int adapt=0,
|
||||
int minor = 0);
|
||||
|
||||
|
||||
inline void init(char *a, char *b){
|
||||
if (no_open) return;
|
||||
init(a,b,0,0);
|
||||
}
|
||||
|
||||
int check_frontend();
|
||||
|
||||
void set_apid(ushort apid);
|
||||
void set_vpid(ushort vpid);
|
||||
void set_pcrpid(ushort vpid);
|
||||
void set_ttpid(ushort ttpid);
|
||||
int set_apid_fd(ushort apid, int fd);
|
||||
int set_vpid_fd(ushort vpid, int fd);
|
||||
int set_ttpid_fd(ushort ttpid, int fd);
|
||||
int set_pcrpid_fd(ushort pcrpid, int fd);
|
||||
int set_otherpid_fd(ushort otherpid, int fd);
|
||||
|
||||
|
||||
int set_lnb(int dis);
|
||||
void set_diseqc_nb(int nr);
|
||||
int set_front(void);
|
||||
void get_front(void);
|
||||
|
||||
void scan_pf_eit(int chnr,
|
||||
int (*callback)(uint8_t *data, int l, int pnr,
|
||||
int c_n, uint8_t *t));
|
||||
|
||||
void scan_pf_eit(Channel *chan,
|
||||
int (*callback)(uint8_t *data, int l, int pnr,
|
||||
int c_n, uint8_t *t));
|
||||
void scan_pf_eit(int chnr);
|
||||
|
||||
|
||||
int search_in_TP(Transponder &tp, int show=1, int verbose=0);
|
||||
int search_in_TP(uint16_t tpid, uint16_t satid, int show=1,
|
||||
int verbose=0);
|
||||
int scan_TP(uint16_t tpid, uint16_t satid, int timeout=-1, int verbose=0);
|
||||
|
||||
int GetSection(uint8_t *buf,
|
||||
uint16_t PID, uint8_t TID, uint16_t TIDExt,
|
||||
uint16_t FilterTIDExt,
|
||||
uint8_t secnum, uint8_t &msecnum);
|
||||
int GetSection(uint8_t *buf,
|
||||
uint16_t PID, uint8_t *filter, uint8_t *mask,
|
||||
uint8_t secnum, uint8_t &msecnum);
|
||||
int GetSection(uint8_t *buf, ushort PID, uint8_t sec,
|
||||
uint8_t secnum, uint8_t &msecnum);
|
||||
int SetFilter(uint16_t pid, uint8_t *filter,
|
||||
uint8_t *mask,
|
||||
uint32_t timeout, uint32_t flags);
|
||||
uint16_t SetFilter(uint16_t pid, uint16_t section, uint16_t mode);
|
||||
int CloseFilter(int h);
|
||||
|
||||
|
||||
void bar2(int x, int y, int w, int h, int val, int col1, int col2);
|
||||
|
||||
int SetTP(unsigned int, unsigned int);
|
||||
int scan(void);
|
||||
int scan_all_tps(void);
|
||||
int scan_lnb(struct Lnb &);
|
||||
int scan_cable(Sat &sat);
|
||||
int scan_sat(struct Sat &);
|
||||
int scan_tp(struct Transponder &);
|
||||
|
||||
int AddLNB(int id, int t, uint l1, uint l2, uint sl,
|
||||
int dnr, int dis, int sw);
|
||||
int AddSat(Sat &sat);
|
||||
int AddSat(int satid, unsigned int lnbid, char *name, uint fmin, uint fmax);
|
||||
int AddTP(Transponder &tp);
|
||||
int AddChannel(Channel &chan);
|
||||
int parse_descriptor(Channel *chan, uint8_t *data, int length);
|
||||
int parse_pmt(Channel *chan, uint8_t *data);
|
||||
int parse_pat(Channel *chan, uint8_t *data);
|
||||
|
||||
int check_pids(Channel *chan);
|
||||
void check_all_pids();
|
||||
void scan_sdt(Channel *chan);
|
||||
int scan_sdts(int *chs, int n);
|
||||
|
||||
int channel_num(void) {
|
||||
return num[CHAN];
|
||||
};
|
||||
|
||||
int channel_change(int n) {
|
||||
return 0;
|
||||
};
|
||||
int SetChannel(uint16_t, uint16_t, uint16_t, uint16_t);
|
||||
int SetChannel(Channel *chan, char* apref=NULL, uint16_t *apidp=NULL,
|
||||
uint16_t *vpidp=NULL) ;
|
||||
int SetChannel(int chnr, char *apref=NULL, uint16_t *apidp=NULL,
|
||||
uint16_t *vpidp=NULL);
|
||||
int GetChannel(int chnr, struct channel *);
|
||||
int NumChannel(void) {
|
||||
return num[CHAN];
|
||||
}
|
||||
int tune_it(struct dvb_frontend_parameters *qpsk);
|
||||
void find_satid(Channel &chan);
|
||||
int check_input_format(istream &ins);
|
||||
void read_original(istream &ins);
|
||||
int get_all_progs(uint16_t *progbuf, uint16_t *pnrbuf, int length);
|
||||
uint16_t find_pnr(uint16_t vpid, uint16_t apid);
|
||||
int get_pids(uint16_t prog_pid, uint16_t *vpid, uint16_t *apids,
|
||||
uint16_t *ttpid, uint8_t *apids_name=NULL);
|
||||
void AddECM(Channel *chan, uint8_t *data, int length);
|
||||
int check_ecm(Channel *chan);
|
||||
void add_vtx_line(magazin_t *mag, int line, uint8_t *data, int pnr);
|
||||
|
||||
friend ostream &operator<<(ostream &stream, DVB &x);
|
||||
friend istream &operator>>(istream &stream, DVB &x);
|
||||
|
||||
};
|
||||
|
||||
#define NOKIA_MAX_SAT 4
|
||||
class nokiaconv{
|
||||
public:
|
||||
DVB *dvb;
|
||||
struct lnb_sat_l{
|
||||
int n;
|
||||
int diseqc[NOKIA_MAX_SAT];
|
||||
char sat_names[NOKIA_MAX_SAT][MAXNAM+1];
|
||||
int satid[NOKIA_MAX_SAT];
|
||||
} lnb_sat;
|
||||
|
||||
nokiaconv(DVB *d){
|
||||
dvb = d;
|
||||
}
|
||||
|
||||
friend istream &operator>>(istream &stream, nokiaconv &x);
|
||||
};
|
||||
|
||||
#define XML_MAX_SAT 4
|
||||
class xmlconv{
|
||||
public:
|
||||
DVB *dvb;
|
||||
struct lnb_sat_l{
|
||||
int n;
|
||||
int diseqc[XML_MAX_SAT];
|
||||
char sat_names[XML_MAX_SAT][MAXNAM+1];
|
||||
int satid[XML_MAX_SAT];
|
||||
} lnb_sat;
|
||||
|
||||
xmlconv(DVB *d){
|
||||
dvb = d;
|
||||
}
|
||||
int read_stream(istream &ins, int nchan);
|
||||
int read_desc(istream &ins, int nchan);
|
||||
int read_serv(istream &ins, int ctp, int csat);
|
||||
int read_trans(istream &ins, int satid);
|
||||
int read_sat(istream &ins, int satid = -1);
|
||||
int skip_tag(istream &ins, char *tag);
|
||||
int read_iso639(istream &ins, int nchan, int apids);
|
||||
|
||||
friend istream &operator>>(istream &stream, xmlconv &x);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define SATCO_MAX_SAT 10
|
||||
class satcoconv{
|
||||
public:
|
||||
DVB *dvb;
|
||||
int nlnb;
|
||||
|
||||
satcoconv(DVB *d){
|
||||
dvb = d;
|
||||
}
|
||||
|
||||
friend istream &operator>>(istream &stream, satcoconv &x);
|
||||
};
|
||||
|
||||
void hdump(uint8_t *buf, int n);
|
||||
int get_dvbrc(char *path, DVB &dv, int dev, int len);
|
||||
int set_dvbrc(char *path, DVB &dv, int dev, int len);
|
||||
void dvb2txt(char *out, char *in, int len);
|
||||
int set_sfront(int fdf, uint32_t freq, uint32_t pol, uint32_t sr , int snum, fe_code_rate_t fec);
|
||||
void set_pes_filt(int fd,uint16_t pes_pid);
|
||||
void set_diseqc(int fdf, int snum, fe_sec_voltage_t v, fe_sec_tone_mode_t t);
|
||||
int tune(int fdf, uint32_t freq, uint32_t sr, fe_code_rate_t fec);
|
||||
int set_sfront(int fdf, uint32_t freq, uint32_t pol, uint32_t sr , int snum,
|
||||
fe_code_rate_t fec);
|
||||
|
||||
|
||||
struct in_addr getaddress (const char *name);
|
||||
int tcp_client_connect(const char *hostname, int sckt);
|
||||
int udp_client_connect(const char *filename);
|
||||
void client_send_msg(int fd, uint8_t *msg, int size);
|
||||
int chck_frontend (int fefd, frontend_stat *festat);
|
||||
|
||||
uint8_t deham(uint8_t x, uint8_t y);
|
||||
|
||||
#endif
|
33
libdvbmpeg/Makefile
Normal file
33
libdvbmpeg/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
INCS = -I.
|
||||
CFLAGS = -g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
|
||||
MFLAG = -M
|
||||
OBJS = ctools.o ringbuffy.o remux.o transform.o cpptools.o
|
||||
SRC = $(wildcard *.c)
|
||||
CPPSRC = $(wildcard *.cpp)
|
||||
CSRC = $(wildcard *.cc)
|
||||
|
||||
DESTDIR = /usr/local
|
||||
|
||||
.PHONY: depend clean install uninstall
|
||||
|
||||
clean:
|
||||
- rm -f *.o *~ *.a .depend
|
||||
|
||||
libdvbmpegtools.a: $(OBJS)
|
||||
ar -rcs libdvbmpegtools.a $(OBJS)
|
||||
|
||||
%.o: %.cc
|
||||
$(CXX) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $(INCS) $(DEFINES) $<
|
||||
|
||||
.depend:
|
||||
$(CXX) $(DEFINES) $(MFLAG) $(SRC) $(CSRC) $(CPPSRC) $(INCS)> .depend
|
||||
|
||||
|
||||
|
||||
-include .depend
|
30
libdvbmpeg/OSD.h
Normal file
30
libdvbmpeg/OSD.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _OSD_H_
|
||||
#define _OSD_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
int OSDClose(int dev);
|
||||
int OSDOpen(int dev, int x0, int y0, int x1, int y1, int BitPerPixel, int mix);
|
||||
int OSDShow(int dev);
|
||||
int OSDHide(int dev);
|
||||
int OSDClear(int dev);
|
||||
int OSDFill(int dev, int color);
|
||||
int OSDSetColor(int dev, int color, int r, int g, int b, int op);
|
||||
int OSDText(int dev, int x, int y, int size, int color, const char *text);
|
||||
int OSDSetPalette(int dev, int first, int last, unsigned char *data);
|
||||
int OSDSetTrans(int dev, int trans);
|
||||
int OSDSetPixel(int dev, int x, int y, unsigned int color);
|
||||
int OSDGetPixel(int dev, int x, int y);
|
||||
int OSDSetRow(int dev, int x, int y, int x1, unsigned char *data);
|
||||
int OSDSetBlock(int dev, int x, int y, int x1, int y1, int inc, unsigned char *data);
|
||||
int OSDFillRow(int dev, int x, int y, int x1, int color);
|
||||
int OSDFillBlock(int dev, int x, int y, int x1, int y1, int color);
|
||||
int OSDLine(int dev, int x, int y, int x1, int y1, int color);
|
||||
int OSDQuery(int dev);
|
||||
int OSDSetWindow(int dev, int win);
|
||||
int OSDMoveWindow(int dev, int x, int y);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
58
libdvbmpeg/channel.h
Normal file
58
libdvbmpeg/channel.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef _CHANNEL_H
|
||||
#define _CHANNEL_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct channel {
|
||||
int id;
|
||||
char name[81];
|
||||
int type;
|
||||
ushort pnr;
|
||||
ushort vpid;
|
||||
ushort apids[8];
|
||||
ushort apidnum;
|
||||
ushort ac3pid;
|
||||
ushort pcrpid;
|
||||
|
||||
uint freq;
|
||||
int pol;
|
||||
int qam;
|
||||
uint srate;
|
||||
int fec;
|
||||
};
|
||||
|
||||
#ifdef NEWSTRUCT
|
||||
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/dvb/video.h>
|
||||
#include <linux/dvb/audio.h>
|
||||
|
||||
#define DVR_DEV "/dev/dvb/adapter%d/dvr%d"
|
||||
#define VIDEO_DEV "/dev/dvb/adapter%d/video%d"
|
||||
#define AUDIO_DEV "/dev/dvb/adapter%d/audio%d"
|
||||
#define DEMUX_DEV "/dev/dvb/adapter%d/demux%d"
|
||||
#define FRONT_DEV "/dev/dvb/adapter%d/frontend%d"
|
||||
#define OSD_DEV "/dev/dvb/adapter%d/osd%d"
|
||||
#define CA_DEV "/dev/dvb/adapter%d/ca%d"
|
||||
|
||||
#else
|
||||
|
||||
#include <ost/dmx.h>
|
||||
#include <ost/frontend.h>
|
||||
#include <ost/sec.h>
|
||||
#include <ost/video.h>
|
||||
#include <ost/audio.h>
|
||||
|
||||
#define DVR_DEV "/dev/ost/dvr%d"
|
||||
#define VIDEO_DEV "/dev/ost/video%d"
|
||||
#define AUDIO_DEV "/dev/ost/audio%d"
|
||||
#define DEMUX_DEV "/dev/ost/demux%d"
|
||||
#define FRONT_DEV "/dev/ost/frontend%d"
|
||||
#define OSD_DEV "/dev/ost/osd%d"
|
||||
#define CA_DEV "/dev/ost/ca%d"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
167
libdvbmpeg/ci.hh
Normal file
167
libdvbmpeg/ci.hh
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* ci.hh: Common Interface
|
||||
*
|
||||
* Copyright (C) 2000 Klaus Schmidinger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* The author can be reached at kls@cadsoft.de
|
||||
*
|
||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CI_H
|
||||
#define __CI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#define MAXCASYSTEMIDS 16
|
||||
|
||||
class cMutex {
|
||||
friend class cCondVar;
|
||||
private:
|
||||
pthread_mutex_t mutex;
|
||||
pid_t lockingPid;
|
||||
int locked;
|
||||
public:
|
||||
cMutex(void);
|
||||
~cMutex();
|
||||
void Lock(void);
|
||||
void Unlock(void);
|
||||
};
|
||||
|
||||
class cMutexLock {
|
||||
private:
|
||||
cMutex *mutex;
|
||||
bool locked;
|
||||
public:
|
||||
cMutexLock(cMutex *Mutex = NULL);
|
||||
~cMutexLock();
|
||||
bool Lock(cMutex *Mutex);
|
||||
};
|
||||
|
||||
|
||||
class cCiMMI;
|
||||
|
||||
class cCiMenu {
|
||||
friend class cCiMMI;
|
||||
private:
|
||||
enum { MAX_CIMENU_ENTRIES = 64 }; ///< XXX is there a specified maximum?
|
||||
cCiMMI *mmi;
|
||||
bool selectable;
|
||||
char *titleText;
|
||||
char *subTitleText;
|
||||
char *bottomText;
|
||||
char *entries[MAX_CIMENU_ENTRIES];
|
||||
int numEntries;
|
||||
bool AddEntry(char *s);
|
||||
cCiMenu(cCiMMI *MMI, bool Selectable);
|
||||
public:
|
||||
~cCiMenu();
|
||||
const char *TitleText(void) { return titleText; }
|
||||
const char *SubTitleText(void) { return subTitleText; }
|
||||
const char *BottomText(void) { return bottomText; }
|
||||
const char *Entry(int n) { return n < numEntries ? entries[n] : NULL; }
|
||||
int NumEntries(void) { return numEntries; }
|
||||
bool Selectable(void) { return selectable; }
|
||||
bool Select(int Index);
|
||||
bool Cancel(void);
|
||||
};
|
||||
|
||||
class cCiEnquiry {
|
||||
friend class cCiMMI;
|
||||
private:
|
||||
cCiMMI *mmi;
|
||||
char *text;
|
||||
bool blind;
|
||||
int expectedLength;
|
||||
cCiEnquiry(cCiMMI *MMI);
|
||||
public:
|
||||
~cCiEnquiry();
|
||||
const char *Text(void) { return text; }
|
||||
bool Blind(void) { return blind; }
|
||||
int ExpectedLength(void) { return expectedLength; }
|
||||
bool Reply(const char *s);
|
||||
bool Cancel(void);
|
||||
};
|
||||
|
||||
class cCiCaPmt {
|
||||
friend class cCiConditionalAccessSupport;
|
||||
private:
|
||||
int length;
|
||||
int esInfoLengthPos;
|
||||
uint8_t capmt[2048]; ///< XXX is there a specified maximum?
|
||||
public:
|
||||
cCiCaPmt(int ProgramNumber);
|
||||
void AddPid(int Pid);
|
||||
void AddCaDescriptor(int Length, uint8_t *Data);
|
||||
};
|
||||
|
||||
#define MAX_CI_SESSION 16 //XXX
|
||||
|
||||
class cCiSession;
|
||||
class cCiTransportLayer;
|
||||
class cCiTransportConnection;
|
||||
|
||||
class cCiHandler {
|
||||
private:
|
||||
cMutex mutex;
|
||||
int numSlots;
|
||||
bool newCaSupport;
|
||||
bool hasUserIO;
|
||||
cCiSession *sessions[MAX_CI_SESSION];
|
||||
cCiTransportLayer *tpl;
|
||||
cCiTransportConnection *tc;
|
||||
int ResourceIdToInt(const uint8_t *Data);
|
||||
bool Send(uint8_t Tag, int SessionId, int ResourceId = 0, int Status = -1);
|
||||
cCiSession *GetSessionBySessionId(int SessionId);
|
||||
cCiSession *GetSessionByResourceId(int ResourceId, int Slot);
|
||||
cCiSession *CreateSession(int ResourceId);
|
||||
bool OpenSession(int Length, const uint8_t *Data);
|
||||
bool CloseSession(int SessionId);
|
||||
int CloseAllSessions(int Slot);
|
||||
cCiHandler(int Fd, int NumSlots);
|
||||
public:
|
||||
~cCiHandler();
|
||||
static cCiHandler *CreateCiHandler(const char *FileName);
|
||||
int NumSlots(void) { return numSlots; }
|
||||
bool Process(void);
|
||||
bool HasUserIO(void) { return hasUserIO; }
|
||||
bool EnterMenu(int Slot);
|
||||
cCiMenu *GetMenu(void);
|
||||
cCiEnquiry *GetEnquiry(void);
|
||||
bool SetCaPmt(cCiCaPmt &CaPmt);
|
||||
const unsigned short *GetCaSystemIds(int Slot);
|
||||
bool SetCaPmt(cCiCaPmt &CaPmt, int Slot);
|
||||
bool Reset(int Slot);
|
||||
};
|
||||
|
||||
int tcp_listen(struct sockaddr_in *name,int sckt,unsigned long address=INADDR_ANY);
|
||||
int accept_tcp(int ip_sock,struct sockaddr_in *ip_name);
|
||||
int udp_listen(struct sockaddr_un *name,char const * const filename);
|
||||
int accept_udp(int ip_sock,struct sockaddr_un *ip_name);
|
||||
|
||||
#endif //__CI_H
|
946
libdvbmpeg/cpptools.cc
Normal file
946
libdvbmpeg/cpptools.cc
Normal file
@@ -0,0 +1,946 @@
|
||||
/*
|
||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||
*
|
||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||
* for convergence integrated media GmbH
|
||||
* Copyright (C) 2002 Marcus Metzler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
|
||||
* The author can be reached at mocm@metzlerbros.de
|
||||
*/
|
||||
|
||||
#include "cpptools.hh"
|
||||
|
||||
#define HEX(N) "0x" << hex << setw(2) << setfill('0') \
|
||||
<< int(N) << " " << dec
|
||||
#define HHEX(N,M) "0x" << hex << setw(M) << setfill('0') \
|
||||
<< int(N) << " " << dec
|
||||
#define LHEX(N,M) "0x" << hex << setw(M) << setfill('0') \
|
||||
<< long(N) << " " << dec
|
||||
|
||||
#define MAX_SEARCH 1024 * 1024
|
||||
|
||||
ostream & operator << (ostream & stream, PES_Packet & x){
|
||||
|
||||
if (x.info){
|
||||
cerr << "PES Packet: " ;
|
||||
switch ( x.p.stream_id ) {
|
||||
|
||||
case PROG_STREAM_MAP:
|
||||
cerr << "Program Stream Map";
|
||||
break;
|
||||
case PRIVATE_STREAM2:
|
||||
cerr << "Private Stream 2";
|
||||
break;
|
||||
case PROG_STREAM_DIR:
|
||||
cerr << "Program Stream Directory";
|
||||
break;
|
||||
case ECM_STREAM :
|
||||
cerr << "ECM Stream";
|
||||
break;
|
||||
case EMM_STREAM :
|
||||
cerr << "EMM Stream";
|
||||
break;
|
||||
case PADDING_STREAM :
|
||||
cerr << "Padding Stream";
|
||||
break;
|
||||
case DSM_CC_STREAM :
|
||||
cerr << "DSM Stream";
|
||||
break;
|
||||
case ISO13522_STREAM:
|
||||
cerr << "ISO13522 Stream";
|
||||
break;
|
||||
case PRIVATE_STREAM1:
|
||||
cerr << "Private Stream 1";
|
||||
break;
|
||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
||||
cerr << "Audio Stream " << HEX(x.p.stream_id);
|
||||
break;
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
cerr << "Video Stream " << HEX(x.p.stream_id);
|
||||
break;
|
||||
|
||||
}
|
||||
cerr << " MPEG" << x.p.mpeg << endl;
|
||||
if ( x.p.mpeg == 2 ){
|
||||
cerr << " FLAGS: ";
|
||||
|
||||
if (x.p.flags1 & SCRAMBLE_FLAGS){
|
||||
cerr << " SCRAMBLE(";
|
||||
cerr << ((x.p.flags1 & SCRAMBLE_FLAGS)>>4);
|
||||
cerr << ")";
|
||||
}
|
||||
if (x.p.flags1 & PRIORITY_FLAG)
|
||||
cerr << " PRIORITY";
|
||||
if (x.p.flags1 & DATA_ALIGN_FLAG)
|
||||
cerr << " DATA_ALIGN";
|
||||
if (x.p.flags1 & COPYRIGHT_FLAG)
|
||||
cerr << " COPYRIGHT";
|
||||
if (x.p.flags1 & ORIGINAL_FLAG)
|
||||
cerr << " ORIGINAL";
|
||||
|
||||
if (x.p.flags2 & PTS_DTS_FLAGS){
|
||||
cerr << " PTS_DTS(";
|
||||
cerr << ((x.p.flags2 & PTS_DTS_FLAGS)>>6);
|
||||
cerr << ")";
|
||||
}
|
||||
if (x.p.flags2 & ESCR_FLAG)
|
||||
cerr << " ESCR";
|
||||
if (x.p.flags2 & ES_RATE_FLAG)
|
||||
cerr << " ES_RATE";
|
||||
if (x.p.flags2 & DSM_TRICK_FLAG)
|
||||
cerr << " DSM_TRICK";
|
||||
if (x.p.flags2 & ADD_CPY_FLAG)
|
||||
cerr << " ADD_CPY";
|
||||
if (x.p.flags2 & PES_CRC_FLAG)
|
||||
cerr << " CRC";
|
||||
if (x.p.flags2 & PES_EXT_FLAG)
|
||||
cerr << " EXT";
|
||||
|
||||
cerr << endl;
|
||||
|
||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY)
|
||||
cerr << " PTS: "
|
||||
<< LHEX(ntohl(x.WPTS()),8)
|
||||
<< "(h" << int(x.high_pts()) << ")"
|
||||
<< endl;
|
||||
else if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_DTS){
|
||||
cerr << " PTS: "
|
||||
<< LHEX(ntohl(x.WPTS()),8)
|
||||
<< "(h" << int(x.high_pts()) << ")";
|
||||
cerr << " DTS: "
|
||||
<< LHEX(ntohl(x.WDTS()),8)
|
||||
<< "(h" << int(x.high_dts()) << ")"
|
||||
<< endl;
|
||||
}
|
||||
/*
|
||||
if (x.p.flags2 & ESCR_FLAG)
|
||||
|
||||
|
||||
if (x.p.flags2 & ES_RATE_FLAG)
|
||||
|
||||
|
||||
if (x.p.flags2 & DSM_TRICK_FLAG)
|
||||
|
||||
|
||||
if (x.p.flags2 & ADD_CPY_FLAG)
|
||||
|
||||
|
||||
if (x.p.flags2 & PES_CRC_FLAG)
|
||||
|
||||
|
||||
if (x.p.flags2 & PES_EXT_FLAG){
|
||||
|
||||
if (x.p.priv_flags & PRIVATE_DATA)
|
||||
stream.write(x.p.pes_priv_data,16);
|
||||
|
||||
if (x.p.priv_flags & HEADER_FIELD){
|
||||
stream.write(&x.p.pack_field_length,1);
|
||||
x.p.pack_header = new
|
||||
uint8_t[x.p.pack_field_length];
|
||||
stream.write(x.p.pack_header,
|
||||
x.p.pack_field_length);
|
||||
}
|
||||
|
||||
if ( x.p.priv_flags & PACK_SEQ_CTR){
|
||||
stream.write(&x.p.pck_sqnc_cntr,1);
|
||||
stream.write(&x.p.org_stuff_length,1);
|
||||
}
|
||||
|
||||
if ( x.p.priv_flags & P_STD_BUFFER)
|
||||
stream.write(x.p.p_std,2);
|
||||
|
||||
if ( x.p.priv_flags & PES_EXT_FLAG2){
|
||||
stream.write(&x.p.pes_ext_lngth,1);
|
||||
x.p.pes_ext = new
|
||||
uint8_t[x.p.pes_ext_lngth];
|
||||
stream.write(x.p.pes_ext,
|
||||
x.p.pes_ext_lngth);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY)
|
||||
stream.write(x.p.pts,5);
|
||||
else if ((x.p.flags2 & PTS_DTS_FLAGS) ==
|
||||
PTS_DTS){
|
||||
stream.write(x.p.pts,5);
|
||||
stream.write(x.p.dts,5);
|
||||
}
|
||||
*/
|
||||
}
|
||||
cerr << endl << endl;
|
||||
return stream;
|
||||
}
|
||||
|
||||
int l = x.p.length+x.p.pes_hlength+9;
|
||||
uint8_t buf[l];
|
||||
int length = cwrite_pes(buf,&(x.p),l);
|
||||
stream.write((char *)buf,length);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
static unsigned int find_length(istream & stream){
|
||||
streampos p = 0;
|
||||
streampos start = 0;
|
||||
streampos q = 0;
|
||||
int found = 0;
|
||||
uint8_t sync4[4];
|
||||
|
||||
start = stream.tellg();
|
||||
start -=2;
|
||||
stream.seekg(start);
|
||||
while ( !stream.eof() && !found ){
|
||||
p = stream.tellg();
|
||||
stream.read((char *)&sync4,4);
|
||||
if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
|
||||
switch ( sync4[3] ) {
|
||||
|
||||
case PROG_STREAM_MAP:
|
||||
case PRIVATE_STREAM2:
|
||||
case PROG_STREAM_DIR:
|
||||
case ECM_STREAM :
|
||||
case EMM_STREAM :
|
||||
case PADDING_STREAM :
|
||||
case DSM_CC_STREAM :
|
||||
case ISO13522_STREAM:
|
||||
case PRIVATE_STREAM1:
|
||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
found = 1;
|
||||
break;
|
||||
default:
|
||||
q = stream.tellg();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
q = stream.tellg();
|
||||
stream.seekg(streampos(2)+start);
|
||||
if (found) return (unsigned int)(q-start)-4-2;
|
||||
else return (unsigned int)(q-start)-2;
|
||||
|
||||
}
|
||||
|
||||
istream & operator >> (istream & stream, PES_Packet & x){
|
||||
|
||||
uint8_t sync4[4];
|
||||
int found=0;
|
||||
int done=0;
|
||||
streampos p = 0;
|
||||
|
||||
while (!stream.eof() && !found) {
|
||||
p = stream.tellg();
|
||||
stream.read((char *)&sync4,4);
|
||||
if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) {
|
||||
x.p.stream_id = sync4[3];
|
||||
|
||||
switch ( sync4[3] ) {
|
||||
|
||||
case PROG_STREAM_MAP:
|
||||
case PRIVATE_STREAM2:
|
||||
case PROG_STREAM_DIR:
|
||||
case ECM_STREAM :
|
||||
case EMM_STREAM :
|
||||
found = 1;
|
||||
stream.read((char *)x.p.llength,2);
|
||||
x.setlength();
|
||||
if (!x.p.length){
|
||||
x.p.length = find_length(stream);
|
||||
x.Nlength();
|
||||
}
|
||||
stream.read((char *)x.p.pes_pckt_data,x.p.length);
|
||||
done = 1;
|
||||
break;
|
||||
case PADDING_STREAM :
|
||||
found = 1;
|
||||
stream.read((char *)x.p.llength,2);
|
||||
x.setlength();
|
||||
if (!x.p.length){
|
||||
x.p.length = find_length(stream);
|
||||
x.Nlength();
|
||||
}
|
||||
x.p.padding = x.p.length;
|
||||
stream.read((char *)x.p.pes_pckt_data,x.p.length);
|
||||
done = 1;
|
||||
break;
|
||||
|
||||
case DSM_CC_STREAM :
|
||||
case ISO13522_STREAM:
|
||||
case PRIVATE_STREAM1:
|
||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
stream.read((char *)x.p.llength,2);
|
||||
x.setlength();
|
||||
if (!x.p.length){
|
||||
x.p.length = find_length(stream);
|
||||
x.Nlength();
|
||||
}
|
||||
found = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
stream.seekg(p+streampos(1));
|
||||
break;
|
||||
}
|
||||
} else stream.seekg(p+streampos(1));
|
||||
}
|
||||
|
||||
if ( found && !done) {
|
||||
p = stream.tellg();
|
||||
stream.read((char *)&x.p.flags1,1);
|
||||
if ( (x.p.flags1 & 0xC0) == 0x80 )
|
||||
x.p.mpeg = 2;
|
||||
else
|
||||
x.p.mpeg = 1;
|
||||
if ( x.p.mpeg == 2 ){
|
||||
stream.read((char *)&x.p.flags2,1);
|
||||
stream.read((char *)&x.p.pes_hlength,1);
|
||||
|
||||
if ((int)x.p.length > x.p.pes_hlength+3)
|
||||
x.p.length -=x.p.pes_hlength+3;
|
||||
else
|
||||
return stream;
|
||||
|
||||
uint8_t count = x.p.pes_hlength;
|
||||
|
||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
|
||||
stream.read((char *)x.p.pts,5);
|
||||
count -=5;
|
||||
} else
|
||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_DTS){
|
||||
stream.read((char *)x.p.pts,5);
|
||||
stream.read((char *)x.p.dts,5);
|
||||
count -= 10;
|
||||
}
|
||||
|
||||
if (x.p.flags2 & ESCR_FLAG){
|
||||
stream.read((char *)x.p.escr,6);
|
||||
count -= 6;
|
||||
}
|
||||
|
||||
if (x.p.flags2 & ES_RATE_FLAG){
|
||||
stream.read((char *)x.p.es_rate,3);
|
||||
count -= 6;
|
||||
}
|
||||
|
||||
if (x.p.flags2 & DSM_TRICK_FLAG){
|
||||
stream.read((char *)&x.p.trick,1);
|
||||
count -= 1;
|
||||
}
|
||||
|
||||
if (x.p.flags2 & ADD_CPY_FLAG){
|
||||
stream.read((char *)&x.p.add_cpy,1);
|
||||
count -= 1;
|
||||
}
|
||||
|
||||
if (x.p.flags2 & PES_CRC_FLAG){
|
||||
stream.read((char *)x.p.prev_pes_crc,2);
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if (x.p.flags2 & PES_EXT_FLAG){
|
||||
stream.read((char *)&x.p.priv_flags,1);
|
||||
count -= 1;
|
||||
|
||||
if (x.p.priv_flags & PRIVATE_DATA){
|
||||
stream.read((char *)x.p.pes_priv_data,16);
|
||||
count -= 16;
|
||||
}
|
||||
|
||||
if (x.p.priv_flags & HEADER_FIELD){
|
||||
stream.read((char *)&x.p.pack_field_length,1);
|
||||
x.p.pack_header = new
|
||||
uint8_t[x.p.pack_field_length];
|
||||
stream.read((char *)x.p.pack_header,
|
||||
x.p.pack_field_length);
|
||||
count -= 1+x.p.pack_field_length;
|
||||
}
|
||||
|
||||
if ( x.p.priv_flags & PACK_SEQ_CTR){
|
||||
stream.read((char *)&x.p.pck_sqnc_cntr,1);
|
||||
stream.read((char *)&x.p.org_stuff_length,1);
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if ( x.p.priv_flags & P_STD_BUFFER){
|
||||
stream.read((char *)x.p.p_std,2);
|
||||
count -= 2;
|
||||
}
|
||||
|
||||
if ( x.p.priv_flags & PES_EXT_FLAG2){
|
||||
stream.read((char *)&x.p.pes_ext_lngth,1);
|
||||
x.p.pes_ext = new
|
||||
uint8_t[x.p.pes_ext_lngth];
|
||||
stream.read((char *)x.p.pes_ext,
|
||||
x.p.pes_ext_lngth);
|
||||
count -= 1+x.p.pes_ext_lngth;
|
||||
}
|
||||
}
|
||||
x.p.stuffing = count;
|
||||
uint8_t dummy;
|
||||
for(int i = 0; i< count ;i++)
|
||||
stream.read((char *)&dummy,1);
|
||||
|
||||
} else {
|
||||
uint8_t check;
|
||||
x.p.mpeg1_pad = 1;
|
||||
check = x.p.flags1;
|
||||
while (check == 0xFF){
|
||||
stream.read((char *)&check,1);
|
||||
x.p.mpeg1_pad++;
|
||||
}
|
||||
|
||||
if ( (check & 0xC0) == 0x40){
|
||||
stream.read((char *)&check,1);
|
||||
x.p.mpeg1_pad++;
|
||||
stream.read((char *)&check,1);
|
||||
x.p.mpeg1_pad++;
|
||||
}
|
||||
x.p.flags2 = 0;
|
||||
x.p.length -= x.p.mpeg1_pad;
|
||||
|
||||
stream.seekg(p);
|
||||
if ( (check & 0x30)){
|
||||
x.p.length ++;
|
||||
x.p.mpeg1_pad --;
|
||||
|
||||
if (check == x.p.flags1){
|
||||
x.p.pes_hlength = 0;
|
||||
} else {
|
||||
x.p.mpeg1_headr =
|
||||
new uint8_t[x.p.mpeg1_pad];
|
||||
x.p.pes_hlength = x.p.mpeg1_pad;
|
||||
stream.read((char *)x.p.mpeg1_headr,
|
||||
x.p.mpeg1_pad);
|
||||
}
|
||||
|
||||
x.p.flags2 = (check & 0xF0) << 2;
|
||||
if ((x.p.flags2 & PTS_DTS_FLAGS) == PTS_ONLY){
|
||||
stream.read((char *)x.p.pts,5);
|
||||
x.p.length -= 5;
|
||||
x.p.pes_hlength += 5;
|
||||
}
|
||||
else if ((x.p.flags2 & PTS_DTS_FLAGS) ==
|
||||
PTS_DTS){
|
||||
stream.read((char *)x.p.pts,5);
|
||||
stream.read((char *)x.p.dts,5);
|
||||
x.p.length -= 10;
|
||||
x.p.pes_hlength += 10;
|
||||
}
|
||||
} else {
|
||||
x.p.mpeg1_headr = new uint8_t[x.p.mpeg1_pad];
|
||||
x.p.pes_hlength = x.p.mpeg1_pad;
|
||||
stream.read((char *)x.p.mpeg1_headr,x.p.mpeg1_pad);
|
||||
}
|
||||
}
|
||||
stream.read((char *)x.p.pes_pckt_data,x.p.length);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
ostream & operator << (ostream & stream, TS_Packet & x){
|
||||
|
||||
uint8_t buf[TS_SIZE];
|
||||
int length = cwrite_ts(buf,&(x.p),TS_SIZE);
|
||||
stream.write((char *)buf,length);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
istream & operator >> (istream & stream, TS_Packet & x){
|
||||
uint8_t sync;
|
||||
int found=0;
|
||||
streampos p,q;
|
||||
|
||||
sync=0;
|
||||
while (!stream.eof() && !found) {
|
||||
stream.read((char *)&sync,1);
|
||||
if (sync == 0x47)
|
||||
found = 1;
|
||||
}
|
||||
stream.read((char *)x.p.pid,2);
|
||||
stream.read((char *)&x.p.flags,1);
|
||||
x.p.count = x.p.flags & COUNT_MASK;
|
||||
|
||||
if (!(x.p.flags & ADAPT_FIELD) && (x.p.flags & PAYLOAD)){
|
||||
//no adapt. field only payload
|
||||
stream.read((char *)x.p.data,184);
|
||||
x.p.rest = 184;
|
||||
return stream;
|
||||
}
|
||||
|
||||
if ( x.p.flags & ADAPT_FIELD ) {
|
||||
// adaption field
|
||||
stream.read((char *)&x.p.adapt_length,1);
|
||||
if (x.p.adapt_length){
|
||||
p = stream.tellg();
|
||||
stream.read((char *)&x.p.adapt_flags,1);
|
||||
|
||||
if ( x.p.adapt_flags & PCR_FLAG )
|
||||
stream.read((char *) x.p.pcr,6);
|
||||
|
||||
if ( x.p.adapt_flags & OPCR_FLAG )
|
||||
stream.read((char *) x.p.opcr,6);
|
||||
|
||||
if ( x.p.adapt_flags & SPLICE_FLAG )
|
||||
stream.read((char *) &x.p.splice_count,1);
|
||||
|
||||
if( x.p.adapt_flags & TRANS_PRIV){
|
||||
stream.read((char *)&x.p.priv_dat_len,1);
|
||||
x.p.priv_dat = new uint8_t[x.p.priv_dat_len];
|
||||
stream.read((char *)x.p.priv_dat,x.p.priv_dat_len);
|
||||
}
|
||||
|
||||
if( x.p.adapt_flags & ADAP_EXT_FLAG){
|
||||
stream.read((char *)&x.p.adapt_ext_len,1);
|
||||
stream.read((char *)&x.p.adapt_eflags,1);
|
||||
if( x.p.adapt_eflags & LTW_FLAG)
|
||||
stream.read((char *)x.p.ltw,2);
|
||||
|
||||
if( x.p.adapt_eflags & PIECE_RATE)
|
||||
stream.read((char *)x.p.piece_rate,3);
|
||||
|
||||
if( x.p.adapt_eflags & SEAM_SPLICE)
|
||||
stream.read((char *)x.p.dts,5);
|
||||
}
|
||||
q = stream.tellg();
|
||||
x.p.stuffing = x.p.adapt_length -(q-p);
|
||||
x.p.rest = 183-x.p.adapt_length;
|
||||
stream.seekg(q+streampos(x.p.stuffing));
|
||||
if (x.p.flags & PAYLOAD) // payload
|
||||
stream.read((char *)x.p.data,x.p.rest);
|
||||
else
|
||||
stream.seekg(q+streampos(x.p.rest));
|
||||
} else {
|
||||
x.p.rest = 182;
|
||||
stream.read((char *)x.p.data, 183);
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
ostream & operator << (ostream & stream, PS_Packet & x){
|
||||
|
||||
uint8_t buf[PS_MAX];
|
||||
int length = cwrite_ps(buf,&(x.p),PS_MAX);
|
||||
stream.write((char *)buf,length);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
istream & operator >> (istream & stream, PS_Packet & x){
|
||||
uint8_t headr[4];
|
||||
int found=0;
|
||||
streampos p = 0;
|
||||
streampos q = 0;
|
||||
int count = 0;
|
||||
|
||||
p = stream.tellg();
|
||||
while (!stream.eof() && !found && count < MAX_SEARCH) {
|
||||
stream.read((char *)&headr,4);
|
||||
if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
|
||||
if ( headr[3] == 0xBA )
|
||||
found = 1;
|
||||
else if ( headr[3] == 0xB9 ) break;
|
||||
else stream.seekg(p+streampos(1));
|
||||
count++;
|
||||
}
|
||||
|
||||
if (found){
|
||||
stream.read((char *)x.p.scr,6);
|
||||
if (x.p.scr[0] & 0x40)
|
||||
x.p.mpeg = 2;
|
||||
else
|
||||
x.p.mpeg = 1;
|
||||
|
||||
if (x.p.mpeg == 2){
|
||||
stream.read((char *)x.p.mux_rate,3);
|
||||
stream.read((char *)&x.p.stuff_length,1);
|
||||
p = stream.tellg();
|
||||
stream.seekg(p+streampos(x.p.stuff_length & 3));
|
||||
} else {
|
||||
x.p.mux_rate[0] = x.p.scr[5]; //mpeg1 scr is only 5 bytes
|
||||
stream.read((char *)x.p.mux_rate+1,2);
|
||||
}
|
||||
|
||||
p=stream.tellg();
|
||||
stream.read((char *)headr,4);
|
||||
if (headr[0] == 0x00 && headr[1] == 0x00 &&
|
||||
headr[2] == 0x01 && headr[3] == 0xBB ) {
|
||||
stream.read((char *)x.p.sheader_llength,2);
|
||||
x.setlength();
|
||||
if (x.p.mpeg == 2){
|
||||
stream.read((char *)x.p.rate_bound,3);
|
||||
stream.read((char *)&x.p.audio_bound,1);
|
||||
stream.read((char *)&x.p.video_bound,1);
|
||||
stream.read((char *)&x.p.reserved,1);
|
||||
}
|
||||
stream.read((char *)x.p.data,x.p.sheader_length);
|
||||
} else {
|
||||
stream.seekg(p);
|
||||
x.p.sheader_length = 0;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int done = 0;
|
||||
q = stream.tellg();
|
||||
PES_Packet pes;
|
||||
do {
|
||||
p=stream.tellg();
|
||||
stream.read((char *)headr,4);
|
||||
stream.seekg(p);
|
||||
if ( headr[0] == 0x00 && headr[1] == 0x00
|
||||
&& headr[2] == 0x01 && headr[3] != 0xBA){
|
||||
pes.init();
|
||||
stream >> pes;
|
||||
i++;
|
||||
} else done = 1;
|
||||
} while (!stream.eof() && !done);
|
||||
x.p.npes = i;
|
||||
stream.seekg(q);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
void extract_audio_from_PES(istream &in, ostream &out){
|
||||
PES_Packet pes;
|
||||
|
||||
while(!in.eof()){
|
||||
pes.init();
|
||||
in >> pes ;
|
||||
if (pes.Stream_ID() == 0xC0)
|
||||
out << pes;
|
||||
}
|
||||
}
|
||||
|
||||
void extract_video_from_PES(istream &in, ostream &out){
|
||||
PES_Packet pes;
|
||||
|
||||
while(!in.eof()){
|
||||
pes.init();
|
||||
in >> pes ;
|
||||
if (pes.Stream_ID() == 0xE0)
|
||||
out << pes;
|
||||
}
|
||||
}
|
||||
|
||||
void extract_es_audio_from_PES(istream &in, ostream &out){
|
||||
PES_Packet pes;
|
||||
|
||||
while(!in.eof()){
|
||||
pes.init();
|
||||
in >> pes ;
|
||||
if (pes.Stream_ID() == 0xC0)
|
||||
out.write((char *)pes.Data(),pes.Length());
|
||||
}
|
||||
}
|
||||
|
||||
void extract_es_video_from_PES(istream &in, ostream &out){
|
||||
PES_Packet pes;
|
||||
|
||||
while(!in.eof()){
|
||||
pes.init();
|
||||
in >> pes ;
|
||||
if (pes.Stream_ID() == 0xE0)
|
||||
out.write((char *)pes.Data(),pes.Length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MAX_PID 20
|
||||
int TS_PIDS(istream &in, ostream &out){
|
||||
int pid[MAX_PID];
|
||||
TS_Packet ts;
|
||||
int npid=0;
|
||||
|
||||
for (int i=0 ; i<MAX_PID; i++)
|
||||
pid[i] = -1;
|
||||
while (!in.eof()) {
|
||||
ts.init();
|
||||
in >> ts;
|
||||
int j;
|
||||
int found = 0;
|
||||
for (j=0;j<npid;j++){
|
||||
if ( ts.PID() == pid[j] )
|
||||
found = 1;
|
||||
}
|
||||
if (! found){
|
||||
out << ts.PID() << " ";
|
||||
pid[npid] = ts.PID();
|
||||
npid++;
|
||||
if (npid == MAX_PID) return -1;
|
||||
}
|
||||
}
|
||||
out << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tv_norm(istream &stream){
|
||||
uint8_t headr[4];
|
||||
int found=0;
|
||||
streampos p = 0;
|
||||
streampos q = 0;
|
||||
int hsize,vsize;
|
||||
int form= 0;
|
||||
|
||||
q = stream.tellg();
|
||||
while (!stream.eof() && !found) {
|
||||
p = stream.tellg();
|
||||
stream.read((char *)headr,4);
|
||||
if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
|
||||
if ( headr[3] == 0xB3 ){
|
||||
found = 1;
|
||||
}
|
||||
if (! found) stream.seekg(p+streampos(1));
|
||||
}
|
||||
stream.read((char *)headr,4);
|
||||
|
||||
hsize = (headr[1] &0xF0) >> 4 | headr[0] << 4;
|
||||
vsize = (headr[1] &0x0F) << 8 | headr[2];
|
||||
cerr << "SIZE: " << hsize << "x" << vsize << endl;
|
||||
|
||||
switch(((headr[3]&0xF0) >>4)){
|
||||
case 1:
|
||||
cerr << "ASPECT: 1:1" << endl;
|
||||
break;
|
||||
case 2:
|
||||
cerr << "ASPECT: 4:3" << endl;
|
||||
break;
|
||||
case 3:
|
||||
cerr << "ASPECT: 16:9" << endl;
|
||||
break;
|
||||
case 4:
|
||||
cerr << "ASPECT: 2.21:1" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (int(headr[3]&0x0F)){
|
||||
case 1:
|
||||
cerr << "FRAMERATE: 23.976" << endl;
|
||||
form = pDUNNO;
|
||||
break;
|
||||
case 2:
|
||||
cerr << "FRAMERATE: 24" << endl;
|
||||
form = pDUNNO;
|
||||
break;
|
||||
case 3:
|
||||
cerr << "FRAMERATE: 25" << endl;
|
||||
form = pPAL;
|
||||
break;
|
||||
case 4:
|
||||
cerr << "FRAMERATE: 29.97" << endl;
|
||||
form = pNTSC;
|
||||
break;
|
||||
case 5:
|
||||
cerr << "FRAMERATE: 30" << endl;
|
||||
form = pNTSC;
|
||||
break;
|
||||
case 6:
|
||||
cerr << "FRAMERATE: 50" << endl;
|
||||
form = pPAL;
|
||||
break;
|
||||
case 7:
|
||||
cerr << "FRAMERATE: 59.94" << endl;
|
||||
form = pNTSC;
|
||||
break;
|
||||
case 8:
|
||||
cerr << "FRAMERATE: 60" << endl;
|
||||
form = pNTSC;
|
||||
break;
|
||||
}
|
||||
|
||||
int mpeg = 0;
|
||||
found = 0;
|
||||
while (!stream.eof() && !found) {
|
||||
p = stream.tellg();
|
||||
stream.read((char *)headr,4);
|
||||
if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
|
||||
if ( headr[3] == 0xB5 ){
|
||||
char *profile[] = {"reserved", "High", "Spatially Scalable",
|
||||
"SNR Scalable", "Main", "Simple", "undef",
|
||||
"undef"};
|
||||
char *level[] = {"res", "res", "res", "res",
|
||||
"High","res", "High 1440", "res",
|
||||
"Main","res", "Low", "res",
|
||||
"res", "res", "res", "res"};
|
||||
char *chroma[] = {"res", "4:2:0", "4:2:2", "4:4:4:"};
|
||||
mpeg = 2;
|
||||
stream.read((char *)headr,4);
|
||||
cerr << "PROFILE: " << profile[headr[0] & 0x7] << endl;
|
||||
cerr << "LEVEL: " << level[headr[1]>>4 & 0xF] << endl;
|
||||
cerr << "CHROMA: " << chroma[headr[1]>>1 & 0x3] << endl;
|
||||
found = 1;
|
||||
} else {
|
||||
mpeg = 1;
|
||||
found = 1;
|
||||
}
|
||||
if (! found) stream.seekg(p+streampos(1));
|
||||
}
|
||||
|
||||
stream.seekg(q);
|
||||
return (form | mpeg << 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int stream_type(istream &fin){
|
||||
uint8_t headr[4];
|
||||
streampos p=fin.tellg();
|
||||
|
||||
TS_Packet ts;
|
||||
fin >> ts;
|
||||
fin.read((char *)headr,1);
|
||||
fin.seekg(p);
|
||||
if(fin && headr[0] == 0x47){
|
||||
return TS_STREAM;
|
||||
}
|
||||
|
||||
PS_Packet ps;
|
||||
fin >> ps;
|
||||
PES_Packet pes;
|
||||
for(int j=0;j < ps.NPES();j++){
|
||||
fin >> pes;
|
||||
}
|
||||
fin.read((char *)headr,4);
|
||||
fin.seekg(p);
|
||||
if (fin && headr[0] == 0x00 && headr[1] == 0x00
|
||||
&& headr[2] == 0x01 && headr[3] == 0xBA){
|
||||
return PS_STREAM;
|
||||
}
|
||||
|
||||
fin >> pes;
|
||||
fin.read((char *)!headr,4);
|
||||
fin.seekg(p);
|
||||
if (fin && headr[0] == 0x00 && headr[1] == 0x00
|
||||
&& headr[2] == 0x01 ){
|
||||
int found = 0;
|
||||
switch ( headr[3] ) {
|
||||
|
||||
case PROG_STREAM_MAP:
|
||||
case PRIVATE_STREAM2:
|
||||
case PROG_STREAM_DIR:
|
||||
case ECM_STREAM :
|
||||
case EMM_STREAM :
|
||||
case PADDING_STREAM :
|
||||
case DSM_CC_STREAM :
|
||||
case ISO13522_STREAM:
|
||||
case PRIVATE_STREAM1:
|
||||
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (found){
|
||||
return PES_STREAM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void analyze(istream &fin)
|
||||
{
|
||||
PS_Packet ps;
|
||||
PES_Packet pes;
|
||||
int fc = 0;
|
||||
char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
|
||||
|
||||
while(fin){
|
||||
uint32_t pts;
|
||||
fin >> ps;
|
||||
cerr << "SCR base: " << hex << setw(5)
|
||||
<< setfill('0') \
|
||||
<< ps.SCR_base() << " " << dec
|
||||
<< "ext : " << ps.SCR_ext();
|
||||
|
||||
cerr << " MUX rate: " << ps.MUX()*50*8/1000000.0
|
||||
<< " Mbit/s ";
|
||||
cerr << "RATE bound: " << ps.Rate()*50*8/1000000.0
|
||||
<< " Mbit/s" << endl;
|
||||
cerr << " Audio bound: "
|
||||
<< hex << "0x"
|
||||
<< int(ps.P()->audio_bound);
|
||||
cerr << " Video bound: " << hex << "0x"
|
||||
<< int(ps.P()->video_bound)
|
||||
<< dec
|
||||
<< endl;
|
||||
cerr << endl;
|
||||
|
||||
for (int i=0; i < ps.NPES(); i++){
|
||||
pes.init();
|
||||
fin >> pes;
|
||||
pts2pts((uint8_t *)&pts,pes.PTS());
|
||||
pes.Info() = 1;
|
||||
cerr << pes;
|
||||
|
||||
uint8_t *buf = pes.P()->pes_pckt_data;
|
||||
int c = 0;
|
||||
int l;
|
||||
switch (pes.P()->stream_id){
|
||||
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
||||
l=pes.P()->length;
|
||||
break;
|
||||
default:
|
||||
l = 0;
|
||||
break;
|
||||
}
|
||||
while ( c < l - 6){
|
||||
if (buf[c] == 0x00 &&
|
||||
buf[c+1] == 0x00 &&
|
||||
buf[c+2] == 0x01 &&
|
||||
buf[c+3] == 0xB8) {
|
||||
c += 4;
|
||||
cerr << "TIME hours: "
|
||||
<< int((buf[c]>>2)& 0x1F)
|
||||
<< " minutes: "
|
||||
<< int(((buf[c]<<4)& 0x30)|
|
||||
((buf[c+1]>>4)& 0x0F))
|
||||
<< " seconds: "
|
||||
<< int(((buf[c+1]<<3)& 0x38)|
|
||||
((buf[c+2]>>5)& 0x0F))
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if ( buf[c] == 0x00 &&
|
||||
buf[c+1] == 0x00 &&
|
||||
buf[c+2] == 0x01 &&
|
||||
buf[c+3] == 0x00) {
|
||||
fc++;
|
||||
c += 4;
|
||||
cerr << "picture: "
|
||||
<< fc
|
||||
<< " ("
|
||||
<< frames[((buf[c+1]&0x38) >>3)-1]
|
||||
<< ")" << endl << endl;
|
||||
} else c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
330
libdvbmpeg/cpptools.hh
Normal file
330
libdvbmpeg/cpptools.hh
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||
*
|
||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||
* for convergence integrated media GmbH
|
||||
* Copyright (C) 2002 Marcus Metzler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
|
||||
* The author can be reached at mocm@metzlerbros.de,
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
|
||||
#ifndef _CPPTOOLS_HH_
|
||||
#define _CPPTOOLS_HH_
|
||||
|
||||
#include "ctools.h"
|
||||
|
||||
|
||||
class PES_Packet{
|
||||
int info;
|
||||
pes_packet p;
|
||||
public:
|
||||
PES_Packet(){
|
||||
info = 0;
|
||||
init_pes(&p);
|
||||
}
|
||||
|
||||
~PES_Packet(){
|
||||
if (p.pack_header)
|
||||
delete [] p.pack_header;
|
||||
if (p.pes_ext)
|
||||
delete [] p.pes_ext;
|
||||
if (p.pes_pckt_data)
|
||||
delete [] p.pes_pckt_data;
|
||||
if (p.mpeg1_headr)
|
||||
delete [] p.mpeg1_headr;
|
||||
}
|
||||
|
||||
inline void init(){
|
||||
if (p.pack_header)
|
||||
delete [] p.pack_header;
|
||||
if (p.pes_ext)
|
||||
delete [] p.pes_ext;
|
||||
if (p.pes_pckt_data)
|
||||
delete [] p.pes_pckt_data;
|
||||
if (p.mpeg1_headr)
|
||||
delete [] p.mpeg1_headr;
|
||||
|
||||
info = 0;
|
||||
init_pes(&p);
|
||||
}
|
||||
|
||||
inline pes_packet *P(){
|
||||
return &p;
|
||||
}
|
||||
|
||||
inline void setlength(){
|
||||
setlength_pes(&p);
|
||||
if (p.length)
|
||||
p.pes_pckt_data = new uint8_t[p.length];
|
||||
}
|
||||
|
||||
inline void Nlength(){
|
||||
nlength_pes(&p);
|
||||
p.pes_pckt_data = new uint8_t[p.length];
|
||||
}
|
||||
|
||||
|
||||
inline uint8_t &Stream_ID(){
|
||||
return p.stream_id;
|
||||
}
|
||||
|
||||
inline uint8_t &Flags1(){
|
||||
return p.flags1;
|
||||
}
|
||||
|
||||
inline uint8_t &Flags2(){
|
||||
return p.flags2;
|
||||
}
|
||||
|
||||
inline uint32_t &Length(){
|
||||
return p.length;
|
||||
}
|
||||
|
||||
inline uint8_t &HLength(){
|
||||
return p.pes_hlength;
|
||||
}
|
||||
|
||||
inline uint8_t &Stuffing(){
|
||||
return p.stuffing;
|
||||
}
|
||||
|
||||
inline uint8_t *Data(){
|
||||
return p.pes_pckt_data;
|
||||
}
|
||||
|
||||
inline int has_pts(){
|
||||
return (p.flags2 & PTS_DTS);
|
||||
}
|
||||
|
||||
inline int &MPEG(){
|
||||
return p.mpeg;
|
||||
}
|
||||
inline uint8_t *PTS(){
|
||||
return p.pts;
|
||||
}
|
||||
|
||||
inline uint8_t *DTS(){
|
||||
return p.dts;
|
||||
}
|
||||
|
||||
inline int &Info(){
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline uint8_t high_pts(){
|
||||
if (has_pts())
|
||||
return ((p.pts[0] & 0x08)>>3);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline uint8_t high_dts(){
|
||||
return ((p.dts[0] & 0x08)>>3);
|
||||
}
|
||||
|
||||
inline int WDTS(){
|
||||
int w_dts;
|
||||
w_dts = (int)trans_pts_dts(p.dts);
|
||||
return w_dts;
|
||||
}
|
||||
|
||||
inline int WPTS(){
|
||||
int w_dts;
|
||||
w_dts = (int)trans_pts_dts(p.pts);
|
||||
return w_dts;
|
||||
}
|
||||
|
||||
friend ostream & operator << (ostream & stream, PES_Packet & x);
|
||||
friend istream & operator >> (istream & stream, PES_Packet & x);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class TS_Packet{
|
||||
ts_packet p;
|
||||
int info;
|
||||
|
||||
public:
|
||||
TS_Packet(){
|
||||
init_ts(&p);
|
||||
info = 0;
|
||||
}
|
||||
|
||||
~TS_Packet(){
|
||||
if (p.priv_dat)
|
||||
delete [] p.priv_dat;
|
||||
}
|
||||
|
||||
inline void init(){
|
||||
if (p.priv_dat)
|
||||
delete [] p.priv_dat;
|
||||
|
||||
init_ts(&p);
|
||||
info = 0;
|
||||
}
|
||||
|
||||
inline ts_packet *P(){
|
||||
return &p;
|
||||
}
|
||||
|
||||
inline int &Rest(){
|
||||
return p.rest;
|
||||
}
|
||||
|
||||
inline uint8_t *Data(){
|
||||
return p.data;
|
||||
}
|
||||
|
||||
inline short PID(){
|
||||
return pid_ts(&p);
|
||||
}
|
||||
|
||||
inline uint8_t FLAG1(){
|
||||
return (p.pid[0] & ~PID_MASK_HI);
|
||||
}
|
||||
|
||||
inline int &Info(){
|
||||
return info;
|
||||
}
|
||||
|
||||
friend ostream & operator << (ostream & stream, TS_Packet & x);
|
||||
friend istream & operator >> (istream & stream, TS_Packet & x);
|
||||
};
|
||||
|
||||
|
||||
class PS_Packet{
|
||||
int info;
|
||||
ps_packet p;
|
||||
public:
|
||||
|
||||
PS_Packet(){
|
||||
init_ps(&p);
|
||||
info = 0;
|
||||
}
|
||||
|
||||
~PS_Packet(){
|
||||
if (p.data)
|
||||
delete [] p.data;
|
||||
}
|
||||
|
||||
inline void init(){
|
||||
if (p.data)
|
||||
delete [] p.data;
|
||||
|
||||
init_ps(&p);
|
||||
info = 0;
|
||||
}
|
||||
|
||||
inline ps_packet *P(){
|
||||
return &p;
|
||||
}
|
||||
|
||||
inline int MUX(){
|
||||
return mux_ps(&p);
|
||||
}
|
||||
|
||||
inline int Rate(){
|
||||
return rate_ps(&p);
|
||||
}
|
||||
|
||||
inline void setlength(){
|
||||
setlength_ps(&p);
|
||||
p.data = new uint8_t[p.sheader_length];
|
||||
}
|
||||
|
||||
inline int Stuffing(){
|
||||
return p.stuff_length & PACK_STUFF_MASK;
|
||||
}
|
||||
|
||||
inline int NPES(){
|
||||
return p.npes;
|
||||
}
|
||||
|
||||
inline int &MPEG(){
|
||||
return p.mpeg;
|
||||
}
|
||||
|
||||
inline uint8_t &operator()(int l){
|
||||
return p.data[l];
|
||||
}
|
||||
|
||||
inline char * Data() {
|
||||
return (char *)p.data+p.stuff_length;
|
||||
}
|
||||
|
||||
inline int &SLENGTH(){
|
||||
return p.sheader_length;
|
||||
}
|
||||
|
||||
inline int &Info(){
|
||||
return info;
|
||||
}
|
||||
|
||||
uint32_t SCR_base(){
|
||||
return scr_base_ps(&p);
|
||||
}
|
||||
|
||||
uint16_t SCR_ext(){
|
||||
return scr_ext_ps(&p);
|
||||
}
|
||||
|
||||
friend ostream & operator << (ostream & stream, PS_Packet & x);
|
||||
friend istream & operator >> (istream & stream, PS_Packet & x);
|
||||
};
|
||||
|
||||
|
||||
typedef void (* FILTER)(istream &in, ostream &out);
|
||||
|
||||
typedef struct thread_args_{
|
||||
FILTER function;
|
||||
int *fd;
|
||||
int in;
|
||||
int out;
|
||||
} thread_args;
|
||||
|
||||
|
||||
void extract_audio_from_PES(istream &in, ostream &out);
|
||||
void extract_video_from_PES(istream &in, ostream &out);
|
||||
void extract_es_audio_from_PES(istream &in, ostream &out);
|
||||
void extract_es_video_from_PES(istream &in, ostream &out);
|
||||
int TS_PIDS(istream &in, ostream &out);
|
||||
int ifilter (istream &in, FILTER function);
|
||||
int ofilter (istream &in, FILTER function);
|
||||
int itfilter (int in, FILTER function);
|
||||
int otfilter (istream &in, FILTER function);
|
||||
int stream_type(int fd);
|
||||
int stream_type(istream &stream);
|
||||
int tv_norm(istream &fin);
|
||||
|
||||
void analyze(istream &fin);
|
||||
|
||||
|
||||
#endif //_CPPTOOLS_HH_
|
||||
|
2379
libdvbmpeg/ctools.c
Normal file
2379
libdvbmpeg/ctools.c
Normal file
File diff suppressed because it is too large
Load Diff
404
libdvbmpeg/ctools.h
Normal file
404
libdvbmpeg/ctools.h
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||
*
|
||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||
* for convergence integrated media GmbH
|
||||
* Copyright (C) 2002, 2003 Marcus Metzler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
|
||||
* The author can be reached at mocm@metzlerbros.de
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <libgen.h>
|
||||
#include <stdint.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#include "ringbuffy.h"
|
||||
#include "transform.h"
|
||||
|
||||
#ifndef _CTOOLS_H_
|
||||
#define _CTOOLS_H_
|
||||
|
||||
#define VIDEO_MODE_PAL 0
|
||||
#define VIDEO_MODE_NTSC 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
enum {PS_STREAM, TS_STREAM, PES_STREAM};
|
||||
enum {pDUNNO, pPAL, pNTSC};
|
||||
|
||||
uint64_t trans_pts_dts(uint8_t *pts);
|
||||
|
||||
/*
|
||||
PES
|
||||
*/
|
||||
|
||||
#define PROG_STREAM_MAP 0xBC
|
||||
#ifndef PRIVATE_STREAM1
|
||||
#define PRIVATE_STREAM1 0xBD
|
||||
#endif
|
||||
#define PADDING_STREAM 0xBE
|
||||
#ifndef PRIVATE_STREAM2
|
||||
#define PRIVATE_STREAM2 0xBF
|
||||
#endif
|
||||
#define AUDIO_STREAM_S 0xC0
|
||||
#define AUDIO_STREAM_E 0xDF
|
||||
#define VIDEO_STREAM_S 0xE0
|
||||
#define VIDEO_STREAM_E 0xEF
|
||||
#define ECM_STREAM 0xF0
|
||||
#define EMM_STREAM 0xF1
|
||||
#define DSM_CC_STREAM 0xF2
|
||||
#define ISO13522_STREAM 0xF3
|
||||
#define PROG_STREAM_DIR 0xFF
|
||||
|
||||
#define BUFFYSIZE 10*MAX_PLENGTH
|
||||
#define MAX_PTS 8192
|
||||
#define MAX_FRAME 8192
|
||||
#define MAX_PACK_L 4096
|
||||
#define PS_HEADER_L1 14
|
||||
#define PS_HEADER_L2 (PS_HEADER_L1+18)
|
||||
#define MAX_H_SIZE (PES_H_MIN + PS_HEADER_L1 + 5)
|
||||
#define PES_MIN 7
|
||||
#define PES_H_MIN 9
|
||||
|
||||
//flags1
|
||||
#define FLAGS 0x40
|
||||
#define SCRAMBLE_FLAGS 0x30
|
||||
#define PRIORITY_FLAG 0x08
|
||||
#define DATA_ALIGN_FLAG 0x04
|
||||
#define COPYRIGHT_FLAG 0x02
|
||||
#define ORIGINAL_FLAG 0x01
|
||||
|
||||
//flags2
|
||||
#define PTS_DTS_FLAGS 0xC0
|
||||
#define ESCR_FLAG 0x20
|
||||
#define ES_RATE_FLAG 0x10
|
||||
#define DSM_TRICK_FLAG 0x08
|
||||
#define ADD_CPY_FLAG 0x04
|
||||
#define PES_CRC_FLAG 0x02
|
||||
#define PES_EXT_FLAG 0x01
|
||||
|
||||
//pts_dts flags
|
||||
#define PTS_ONLY 0x80
|
||||
#define PTS_DTS 0xC0
|
||||
|
||||
//private flags
|
||||
#define PRIVATE_DATA 0x80
|
||||
#define HEADER_FIELD 0x40
|
||||
#define PACK_SEQ_CTR 0x20
|
||||
#define P_STD_BUFFER 0x10
|
||||
#define PES_EXT_FLAG2 0x01
|
||||
|
||||
#define MPEG1_2_ID 0x40
|
||||
#define STFF_LNGTH_MASK 0x3F
|
||||
|
||||
|
||||
typedef struct pes_packet_{
|
||||
uint8_t stream_id;
|
||||
uint8_t llength[2];
|
||||
uint32_t length;
|
||||
uint8_t flags1;
|
||||
uint8_t flags2;
|
||||
uint8_t pes_hlength;
|
||||
uint8_t pts[5];
|
||||
uint8_t dts[5];
|
||||
uint8_t escr[6];
|
||||
uint8_t es_rate[3];
|
||||
uint8_t trick;
|
||||
uint8_t add_cpy;
|
||||
uint8_t prev_pes_crc[2];
|
||||
uint8_t priv_flags;
|
||||
uint8_t pes_priv_data[16];
|
||||
uint8_t pack_field_length;
|
||||
uint8_t *pack_header;
|
||||
uint8_t pck_sqnc_cntr;
|
||||
uint8_t org_stuff_length;
|
||||
uint8_t p_std[2];
|
||||
uint8_t pes_ext_lngth;
|
||||
uint8_t *pes_ext;
|
||||
uint8_t *pes_pckt_data;
|
||||
int padding;
|
||||
int mpeg;
|
||||
int mpeg1_pad;
|
||||
uint8_t *mpeg1_headr;
|
||||
uint8_t stuffing;
|
||||
} pes_packet;
|
||||
|
||||
void init_pes(pes_packet *p);
|
||||
void kill_pes(pes_packet *p);
|
||||
void setlength_pes(pes_packet *p);
|
||||
void nlength_pes(pes_packet *p);
|
||||
int cwrite_pes(uint8_t *buf, pes_packet *p, long length);
|
||||
void write_pes(int fd, pes_packet *p);
|
||||
int read_pes(int f, pes_packet *p);
|
||||
void cread_pes(char *buf, pes_packet *p);
|
||||
|
||||
/*
|
||||
Transport Stream
|
||||
*/
|
||||
|
||||
#define TS_SIZE 188
|
||||
#define TRANS_ERROR 0x80
|
||||
#define PAY_START 0x40
|
||||
#define TRANS_PRIO 0x20
|
||||
#define PID_MASK_HI 0x1F
|
||||
//flags
|
||||
#define TRANS_SCRMBL1 0x80
|
||||
#define TRANS_SCRMBL2 0x40
|
||||
#define ADAPT_FIELD 0x20
|
||||
#define PAYLOAD 0x10
|
||||
#define COUNT_MASK 0x0F
|
||||
|
||||
// adaptation flags
|
||||
#define DISCON_IND 0x80
|
||||
#define RAND_ACC_IND 0x40
|
||||
#define ES_PRI_IND 0x20
|
||||
#define PCR_FLAG 0x10
|
||||
#define OPCR_FLAG 0x08
|
||||
#define SPLICE_FLAG 0x04
|
||||
#define TRANS_PRIV 0x02
|
||||
#define ADAP_EXT_FLAG 0x01
|
||||
|
||||
// adaptation extension flags
|
||||
#define LTW_FLAG 0x80
|
||||
#define PIECE_RATE 0x40
|
||||
#define SEAM_SPLICE 0x20
|
||||
|
||||
typedef struct ts_packet_{
|
||||
uint8_t pid[2];
|
||||
uint8_t flags;
|
||||
uint8_t count;
|
||||
uint8_t data[184];
|
||||
uint8_t adapt_length;
|
||||
uint8_t adapt_flags;
|
||||
uint8_t pcr[6];
|
||||
uint8_t opcr[6];
|
||||
uint8_t splice_count;
|
||||
uint8_t priv_dat_len;
|
||||
uint8_t *priv_dat;
|
||||
uint8_t adapt_ext_len;
|
||||
uint8_t adapt_eflags;
|
||||
uint8_t ltw[2];
|
||||
uint8_t piece_rate[3];
|
||||
uint8_t dts[5];
|
||||
int rest;
|
||||
uint8_t stuffing;
|
||||
} ts_packet;
|
||||
|
||||
void init_ts(ts_packet *p);
|
||||
void kill_ts(ts_packet *p);
|
||||
unsigned short pid_ts(ts_packet *p);
|
||||
int cwrite_ts(uint8_t *buf, ts_packet *p, long length);
|
||||
void write_ts(int fd, ts_packet *p);
|
||||
int read_ts(int f, ts_packet *p);
|
||||
void cread_ts (char *buf, ts_packet *p, long length);
|
||||
|
||||
|
||||
/*
|
||||
Program Stream
|
||||
*/
|
||||
|
||||
#define PACK_STUFF_MASK 0x07
|
||||
|
||||
#define FIXED_FLAG 0x02
|
||||
#define CSPS_FLAG 0x01
|
||||
#define SAUDIO_LOCK_FLAG 0x80
|
||||
#define SVIDEO_LOCK_FLAG 0x40
|
||||
|
||||
#define PS_MAX 200
|
||||
|
||||
typedef struct ps_packet_{
|
||||
uint8_t scr[6];
|
||||
uint8_t mux_rate[3];
|
||||
uint8_t stuff_length;
|
||||
uint8_t *data;
|
||||
uint8_t sheader_llength[2];
|
||||
int sheader_length;
|
||||
uint8_t rate_bound[3];
|
||||
uint8_t audio_bound;
|
||||
uint8_t video_bound;
|
||||
uint8_t reserved;
|
||||
int npes;
|
||||
int mpeg;
|
||||
} ps_packet;
|
||||
|
||||
void init_ps(ps_packet *p);
|
||||
void kill_ps(ps_packet *p);
|
||||
void setlength_ps(ps_packet *p);
|
||||
uint32_t scr_base_ps(ps_packet *p);
|
||||
uint16_t scr_ext_ps(ps_packet *p);
|
||||
int mux_ps(ps_packet *p);
|
||||
int rate_ps(ps_packet *p);
|
||||
int cwrite_ps(uint8_t *buf, ps_packet *p, long length);
|
||||
void write_ps(int fd, ps_packet *p);
|
||||
int read_ps (int f, ps_packet *p);
|
||||
void cread_ps (char *buf, ps_packet *p, long length);
|
||||
|
||||
|
||||
|
||||
#define MAX_PLENGTH 0xFFFF
|
||||
|
||||
typedef struct sectionstruct {
|
||||
int id;
|
||||
int length;
|
||||
int found;
|
||||
uint8_t payload[4096+3];
|
||||
} section;
|
||||
|
||||
|
||||
typedef uint32_t tflags;
|
||||
#define MAXFILT 32
|
||||
#define MASKL 16
|
||||
typedef struct trans_struct {
|
||||
int found;
|
||||
uint8_t packet[188];
|
||||
uint16_t pid[MAXFILT];
|
||||
uint8_t mask[MAXFILT*MASKL];
|
||||
uint8_t filt[MAXFILT*MASKL];
|
||||
uint8_t transbuf[MAXFILT*188];
|
||||
int transcount[MAXFILT];
|
||||
section sec[MAXFILT];
|
||||
tflags is_full;
|
||||
tflags pes_start;
|
||||
tflags pes_started;
|
||||
tflags pes;
|
||||
tflags set;
|
||||
} trans;
|
||||
|
||||
|
||||
void init_trans(trans *p);
|
||||
int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask,
|
||||
uint8_t *filt, int pes);
|
||||
|
||||
void clear_trans_filt(trans *p,int filtn);
|
||||
int filt_is_set(trans *p, int filtn);
|
||||
int pes_is_set(trans *p, int filtn);
|
||||
int pes_is_started(trans *p, int filtn);
|
||||
int pes_is_start(trans *p, int filtn);
|
||||
int filt_is_ready(trans *p,int filtn);
|
||||
|
||||
void trans_filt(uint8_t *buf, int count, trans *p);
|
||||
void tfilter(trans *p);
|
||||
void pes_filter(trans *p, int filtn, int off);
|
||||
void sec_filter(trans *p, int filtn, int off);
|
||||
int get_filt_buf(trans *p, int filtn,uint8_t **buf);
|
||||
section *get_filt_sec(trans *p, int filtn);
|
||||
|
||||
|
||||
typedef struct a2pstruct{
|
||||
int type;
|
||||
int fd;
|
||||
int found;
|
||||
int length;
|
||||
int headr;
|
||||
int plength;
|
||||
uint8_t cid;
|
||||
uint8_t flags;
|
||||
uint8_t abuf[MAX_PLENGTH];
|
||||
int alength;
|
||||
uint8_t vbuf[MAX_PLENGTH];
|
||||
int vlength;
|
||||
uint8_t last_av_pts[4];
|
||||
uint8_t av_pts[4];
|
||||
uint8_t scr[4];
|
||||
uint8_t pid0;
|
||||
uint8_t pid1;
|
||||
uint8_t pidv;
|
||||
uint8_t pida;
|
||||
} a2p;
|
||||
|
||||
|
||||
|
||||
void get_pespts(uint8_t *av_pts,uint8_t *pts);
|
||||
void init_a2p(a2p *p);
|
||||
void av_pes_to_pes(uint8_t *buf,int count, a2p *p);
|
||||
int w_pesh(uint8_t id,int length ,uint8_t *pts, uint8_t *obuf);
|
||||
int w_tsh(uint8_t id,int length ,uint8_t *pts, uint8_t *obuf,a2p *p,int startpes);
|
||||
void pts2pts(uint8_t *av_pts, uint8_t *pts);
|
||||
void write_ps_headr(ps_packet *p,uint8_t *pts,int fd);
|
||||
|
||||
typedef struct p2t_s{
|
||||
uint8_t pes[TS_SIZE];
|
||||
uint8_t counter;
|
||||
long int pos;
|
||||
int frags;
|
||||
void (*t_out)(uint8_t const *buf);
|
||||
} p2t_t;
|
||||
|
||||
void twrite(uint8_t const *buf);
|
||||
void init_p2t(p2t_t *p, void (*fkt)(uint8_t const *buf));
|
||||
long int find_pes_header(uint8_t const *buf, long int length, int *frags);
|
||||
void pes_to_ts( uint8_t const *buf, long int length, uint16_t pid, p2t_t *p);
|
||||
void p_to_t( uint8_t const *buf, long int length, uint16_t pid,
|
||||
uint8_t *counter, void (*ts_write)(uint8_t const *));
|
||||
|
||||
|
||||
int write_pes_header(uint8_t id,int length , long PTS,
|
||||
uint8_t *obuf, int stuffing);
|
||||
|
||||
int write_ps_header(uint8_t *buf,
|
||||
uint32_t SCR,
|
||||
long muxr,
|
||||
uint8_t audio_bound,
|
||||
uint8_t fixed,
|
||||
uint8_t CSPS,
|
||||
uint8_t audio_lock,
|
||||
uint8_t video_lock,
|
||||
uint8_t video_bound,
|
||||
uint8_t stream1,
|
||||
uint8_t buffer1_scale,
|
||||
uint32_t buffer1_size,
|
||||
uint8_t stream2,
|
||||
uint8_t buffer2_scale,
|
||||
uint32_t buffer2_size);
|
||||
|
||||
|
||||
int seek_mpg_start(uint8_t *buf, int size);
|
||||
|
||||
|
||||
void split_mpg(char *name, uint64_t size);
|
||||
void cut_mpg(char *name, uint64_t size);
|
||||
int http_open (char *url);
|
||||
ssize_t save_read(int fd, void *buf, size_t count);
|
||||
|
||||
const char * strerrno(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /*_CTOOLS_H_*/
|
310
libdvbmpeg/devices.hh
Normal file
310
libdvbmpeg/devices.hh
Normal file
@@ -0,0 +1,310 @@
|
||||
#ifndef _channel_hh
|
||||
#define _channel_hh
|
||||
|
||||
using namespace std;
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "DVB.hh"
|
||||
|
||||
#define MAXNAM 80
|
||||
#define MAXKEY 15
|
||||
|
||||
const int maxname=80;
|
||||
const int MAXAPIDS=32;
|
||||
const uint32_t UNSET=0xffffffff;
|
||||
const uint16_t NOID=0xffff;
|
||||
const uint16_t NOPID=0xffff;
|
||||
|
||||
class Transponder {
|
||||
public:
|
||||
uint16_t id;
|
||||
uint16_t onid;
|
||||
uint16_t satid;
|
||||
int type;
|
||||
char name[maxname+1];
|
||||
uint32_t freq;
|
||||
int pol;
|
||||
int qam;
|
||||
uint32_t srate;
|
||||
int fec;
|
||||
int band;
|
||||
int hp_rate;
|
||||
int lp_rate;
|
||||
int mod;
|
||||
int transmode;
|
||||
int guard;
|
||||
int hierarchy;
|
||||
|
||||
struct Sat *sat;
|
||||
|
||||
Transponder() {
|
||||
name[0]='\0';
|
||||
id = NOID;
|
||||
onid = NOID;
|
||||
satid = NOID;
|
||||
type = 0;
|
||||
}
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Transponder &x);
|
||||
friend istream &operator>>(istream &stream, Transponder &x);
|
||||
};
|
||||
|
||||
class Sat {
|
||||
public:
|
||||
uint16_t id;
|
||||
char name[maxname+1];
|
||||
unsigned int lnbid;
|
||||
struct Lnb *lnb;
|
||||
unsigned int rotorid;
|
||||
unsigned int fmin;
|
||||
unsigned int fmax;
|
||||
|
||||
Sat() {
|
||||
id=NOID;
|
||||
name[0]='\0';
|
||||
lnb=NULL;
|
||||
rotorid=NOID;
|
||||
lnbid=NOID;
|
||||
fmin=fmax=0;
|
||||
};
|
||||
int set(int sid, char *sname, int slnbid, int srotorid) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Sat &x);
|
||||
friend istream &operator>>(istream &stream, Sat &x);
|
||||
};
|
||||
|
||||
|
||||
class Lnb {
|
||||
public:
|
||||
Sat *sat;
|
||||
uint16_t id;
|
||||
struct DVB *dvbd;
|
||||
char name[maxname+1];
|
||||
int type;
|
||||
unsigned int lof1;
|
||||
unsigned int lof2;
|
||||
unsigned int slof;
|
||||
int diseqcnr;
|
||||
uint16_t diseqcid;
|
||||
uint16_t swiid;
|
||||
|
||||
|
||||
void cpy (const Lnb &olnb){
|
||||
this->id=olnb.id;
|
||||
this->type=olnb.type;
|
||||
this->lof1=olnb.lof1;
|
||||
this->lof2=olnb.lof2;
|
||||
this->slof=olnb.slof;
|
||||
this->diseqcnr=olnb.diseqcnr;
|
||||
this->diseqcid=olnb.diseqcid;
|
||||
this->swiid=olnb.swiid;
|
||||
strncpy(this->name,olnb.name,maxname);
|
||||
}
|
||||
|
||||
void init(int t, uint l1, uint l2, uint sl,
|
||||
int dnr, int disid, int sw) {
|
||||
type=t;
|
||||
lof1=l1;
|
||||
lof2=l2;
|
||||
slof=sl;
|
||||
diseqcnr=dnr;
|
||||
diseqcid=disid;
|
||||
swiid=sw;
|
||||
dvbd=0;
|
||||
name[0]='\0';
|
||||
}
|
||||
|
||||
Lnb () {
|
||||
lof1=lof2=slof=0;
|
||||
swiid=NOID;
|
||||
diseqcid=NOID;
|
||||
diseqcnr=-1;
|
||||
name[0]='\0';
|
||||
}
|
||||
|
||||
Lnb (const Lnb &olnb){
|
||||
cpy(olnb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Lnb &x);
|
||||
friend istream &operator>>(istream &stream, Lnb &x);
|
||||
};
|
||||
|
||||
struct diseqcmsg {
|
||||
int burst;
|
||||
int len;
|
||||
unsigned char msg[8];
|
||||
};
|
||||
|
||||
class DiSEqC {
|
||||
public:
|
||||
uint16_t id;
|
||||
char name[maxname+1];
|
||||
diseqcmsg msgs[4];
|
||||
|
||||
friend ostream &operator<<(ostream &stream, DiSEqC &x);
|
||||
friend istream &operator>>(istream &stream, DiSEqC &x);
|
||||
};
|
||||
|
||||
class Rotor {
|
||||
public:
|
||||
uint16_t id;
|
||||
char name[maxname+1];
|
||||
diseqcmsg msgs[4];
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Rotor &x);
|
||||
friend istream &operator>>(istream &stream, Rotor &x);
|
||||
};
|
||||
|
||||
class Switch {
|
||||
public:
|
||||
uint16_t id;
|
||||
int switchid;
|
||||
char name[maxname+1];
|
||||
diseqcmsg msg;
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Switch &x);
|
||||
friend istream &operator>>(istream &stream, Switch &x);
|
||||
};
|
||||
|
||||
class Network {
|
||||
public:
|
||||
uint16_t id;
|
||||
char name[maxname+1];
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Network &x);
|
||||
friend istream &operator>>(istream &stream, Network &x);
|
||||
};
|
||||
|
||||
class Bouquet {
|
||||
public:
|
||||
uint16_t id;
|
||||
char name[maxname+1];
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Bouquet &x);
|
||||
friend istream &operator>>(istream &stream, Bouquet &x);
|
||||
};
|
||||
|
||||
|
||||
#define MAX_ECM 16
|
||||
#define MAX_ECM_DESC 256
|
||||
typedef struct ecm_struct {
|
||||
int num;
|
||||
uint16_t sysid[MAX_ECM];
|
||||
uint16_t pid[MAX_ECM];
|
||||
uint16_t length[MAX_ECM];
|
||||
uint8_t data[MAX_ECM*MAX_ECM_DESC];
|
||||
} ecm_t;
|
||||
|
||||
|
||||
|
||||
class Channel{
|
||||
public:
|
||||
Channel *next;
|
||||
uint32_t id;
|
||||
char name[maxname+1];
|
||||
int32_t type;
|
||||
int checked;
|
||||
|
||||
uint16_t pnr;
|
||||
uint16_t vpid;
|
||||
uint16_t apids[MAXAPIDS];
|
||||
char apids_name[MAXAPIDS*4];
|
||||
int32_t apidnum;
|
||||
int last_apidn;
|
||||
uint16_t ac3pid;
|
||||
uint16_t ttpid;
|
||||
uint16_t pmtpid;
|
||||
uint16_t pcrpid;
|
||||
uint16_t casystem;
|
||||
uint16_t capid;
|
||||
|
||||
ecm_t ecm;
|
||||
int (*ecm_callback)(Channel *chan);
|
||||
|
||||
int has_eit;
|
||||
int pres_follow;
|
||||
|
||||
uint16_t satid;
|
||||
uint16_t tpid;
|
||||
uint16_t onid;
|
||||
uint16_t bid;
|
||||
int8_t eit_ver_n;
|
||||
int8_t eit_ver_c;
|
||||
|
||||
void clearall(void) {
|
||||
id=UNSET;
|
||||
name[0]='\0';
|
||||
type=0;
|
||||
checked = 0;
|
||||
has_eit = -1;
|
||||
pres_follow = -1;
|
||||
eit_ver_c = -1;
|
||||
eit_ver_n = -1;
|
||||
|
||||
pnr=NOPID;
|
||||
vpid=NOPID;
|
||||
memset(apids, 0, sizeof(uint16_t)*MAXAPIDS);
|
||||
memset(apids_name, 0, sizeof(char)*MAXAPIDS*4);
|
||||
apidnum=0;
|
||||
last_apidn=-1;
|
||||
ac3pid=NOPID;
|
||||
ttpid=NOPID;
|
||||
pmtpid=NOPID;
|
||||
pcrpid=NOPID;
|
||||
capid=NOPID;
|
||||
|
||||
satid=NOID;
|
||||
tpid=NOID;
|
||||
onid=NOID;
|
||||
bid=NOID;
|
||||
ecm_callback = NULL;
|
||||
memset(&ecm,0, sizeof(ecm_t));
|
||||
};
|
||||
|
||||
Channel() {
|
||||
clearall();
|
||||
}
|
||||
|
||||
Channel(int cid, char *nam, int ty, int prognr,
|
||||
int vid, int aid, int tid) {
|
||||
int l=strlen(nam);
|
||||
|
||||
clearall();
|
||||
if (l>maxname){
|
||||
cerr << "" << endl;
|
||||
l=maxname;
|
||||
}
|
||||
strncpy(name, nam, l);
|
||||
name[l]='\0';
|
||||
type=ty;
|
||||
pnr=prognr;
|
||||
vpid=vid;
|
||||
apids[0]=aid;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
~Channel(){
|
||||
cerr <<"Channel " << name << " destroyed" << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
friend ostream &operator<<(ostream &stream, Channel &x);
|
||||
friend istream &operator>>(istream &stream, Channel &x);
|
||||
};
|
||||
|
||||
int findkey(char *name, char *keys[]);
|
||||
void getname(char *name,istream &ins);
|
||||
#endif /*channel.h*/
|
84
libdvbmpeg/osd.hh
Normal file
84
libdvbmpeg/osd.hh
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef _OSD_HH_
|
||||
#define _OSD_HH_
|
||||
|
||||
extern "C" {
|
||||
#include "OSD.h"
|
||||
}
|
||||
struct OSD {
|
||||
int dev;
|
||||
|
||||
void init(int d) {
|
||||
dev=d;
|
||||
}
|
||||
int Open(int x0, int y0, int x1, int y1, int BitPerPixel, int mix, int win) {
|
||||
if (OSDSetWindow(dev, win))
|
||||
return -1;
|
||||
return OSDOpen(dev, x0, y0, x1, y1, BitPerPixel, mix);
|
||||
}
|
||||
int Open(int x0, int y0, int x1, int y1, int BitPerPixel, int mix) {
|
||||
return OSDOpen(dev, x0, y0, x1, y1, BitPerPixel, mix);
|
||||
}
|
||||
int Close(int win) {
|
||||
if (OSDSetWindow(dev, win))
|
||||
return -1;
|
||||
return OSDClose(dev);
|
||||
}
|
||||
int Close(void) {
|
||||
return OSDClose(dev);
|
||||
}
|
||||
int Show(void) {
|
||||
return OSDShow(dev);
|
||||
}
|
||||
int Hide(void) {
|
||||
return OSDHide(dev);
|
||||
}
|
||||
int Clear(void) {
|
||||
return OSDClear(dev);
|
||||
}
|
||||
int Fill(int color) {
|
||||
return OSDFill(dev, color);
|
||||
}
|
||||
int SetColor(int color, int r, int g, int b, int op) {
|
||||
return OSDSetColor(dev, color, r, g, b, op);
|
||||
}
|
||||
int Text(int x, int y, int size, int color, const char *text) {
|
||||
return OSDText(dev, x, y, size, color, text);
|
||||
}
|
||||
int SetPalette(int first, int last, unsigned char *data) {
|
||||
return OSDSetPalette(dev, first, last, data);
|
||||
|
||||
}
|
||||
int SetTrans(int trans) {
|
||||
return OSDSetTrans(dev, trans);
|
||||
|
||||
}
|
||||
int SetPixel(int dev, int x, int y, unsigned int color) {
|
||||
return OSDSetPixel(dev, x, y, color);
|
||||
}
|
||||
int GetPixel(int dev, int x, int y) {
|
||||
return OSDGetPixel(dev, x, y);
|
||||
}
|
||||
int SetRow(int x, int y, int x1, unsigned char *data) {
|
||||
return OSDSetRow(dev, x, y, x1, data);
|
||||
}
|
||||
int SetBlock(int x, int y, int x1, int y1, int inc, unsigned char *data) {
|
||||
return OSDSetBlock(dev, x, y, x1, y1, inc, data);
|
||||
}
|
||||
int FillRow(int x, int y, int x1, int color) {
|
||||
return OSDFillRow(dev, x, y, x1, color);
|
||||
}
|
||||
int FillBlock(int x, int y, int x1, int y1, int color) {
|
||||
return OSDFillBlock(dev, x, y, x1, y1, color);
|
||||
}
|
||||
int Line(int x, int y, int x1, int y1, int color) {
|
||||
return OSDLine(dev, x, y, x1, y1, color);
|
||||
}
|
||||
int Query() {
|
||||
return OSDQuery(dev);
|
||||
}
|
||||
int SetWindow(int win) {
|
||||
return OSDSetWindow(dev, win);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
1215
libdvbmpeg/remux.c
Normal file
1215
libdvbmpeg/remux.c
Normal file
File diff suppressed because it is too large
Load Diff
149
libdvbmpeg/remux.h
Normal file
149
libdvbmpeg/remux.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||
*
|
||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||
* for convergence integrated media GmbH
|
||||
* Copyright (C) 2002 Marcus Metzler
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
|
||||
* The author can be reached at mocm@metzlerbros.de,
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
//#include <libgen.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ringbuffy.h"
|
||||
#include "ctools.h"
|
||||
|
||||
#ifndef _REMUX_H_
|
||||
#define _REMUX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct video_i{
|
||||
uint32_t horizontal_size;
|
||||
uint32_t vertical_size ;
|
||||
uint32_t aspect_ratio ;
|
||||
double framerate ;
|
||||
uint32_t video_format;
|
||||
uint32_t bit_rate ;
|
||||
uint32_t comp_bit_rate ;
|
||||
uint32_t vbv_buffer_size;
|
||||
uint32_t CSPF ;
|
||||
uint32_t off;
|
||||
} VideoInfo;
|
||||
|
||||
typedef struct audio_i{
|
||||
int layer;
|
||||
uint32_t bit_rate;
|
||||
uint32_t frequency;
|
||||
uint32_t mode;
|
||||
uint32_t mode_extension;
|
||||
uint32_t emphasis;
|
||||
uint32_t framesize;
|
||||
uint32_t off;
|
||||
} AudioInfo;
|
||||
|
||||
|
||||
|
||||
typedef
|
||||
struct PTS_list_struct{
|
||||
uint32_t PTS;
|
||||
int pos;
|
||||
uint32_t dts;
|
||||
int spos;
|
||||
} PTS_List;
|
||||
|
||||
typedef
|
||||
struct frame_list_struct{
|
||||
int type;
|
||||
int pos;
|
||||
uint32_t FRAME;
|
||||
uint32_t time;
|
||||
uint32_t pts;
|
||||
uint32_t dts;
|
||||
} FRAME_List;
|
||||
|
||||
typedef
|
||||
struct remux_struct{
|
||||
ringbuffy vid_buffy;
|
||||
ringbuffy aud_buffy;
|
||||
PTS_List vpts_list[MAX_PTS];
|
||||
PTS_List apts_list[MAX_PTS];
|
||||
FRAME_List vframe_list[MAX_FRAME];
|
||||
FRAME_List aframe_list[MAX_FRAME];
|
||||
int vptsn;
|
||||
int aptsn;
|
||||
int vframen;
|
||||
int aframen;
|
||||
long apes;
|
||||
long vpes;
|
||||
uint32_t vframe;
|
||||
uint32_t aframe;
|
||||
uint32_t vcframe;
|
||||
uint32_t acframe;
|
||||
uint32_t vpts;
|
||||
uint32_t vdts;
|
||||
uint32_t apts;
|
||||
uint32_t vpts_old;
|
||||
uint32_t apts_old;
|
||||
uint32_t SCR;
|
||||
uint32_t apts_off;
|
||||
uint32_t vpts_off;
|
||||
uint32_t apts_delay;
|
||||
uint32_t vpts_delay;
|
||||
uint32_t dts_delay;
|
||||
AudioInfo audio_info;
|
||||
VideoInfo video_info;
|
||||
int fin;
|
||||
int fout;
|
||||
long int awrite;
|
||||
long int vwrite;
|
||||
long int aread;
|
||||
long int vread;
|
||||
uint32_t group;
|
||||
uint32_t groupframe;
|
||||
uint32_t muxr;
|
||||
int pack_size;
|
||||
uint32_t time_off;
|
||||
} Remux;
|
||||
|
||||
enum { NONE, I_FRAME, P_FRAME, B_FRAME, D_FRAME };
|
||||
|
||||
void remux(int fin, int fout, int pack_size, int mult);
|
||||
void remux2(int fdin, int fdout);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /*_REMUX_H_*/
|
201
libdvbmpeg/ringbuffy.c
Normal file
201
libdvbmpeg/ringbuffy.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Ringbuffer Implementation for gtvscreen
|
||||
|
||||
Copyright (C) 2000 Marcus Metzler (mocm@metzlerbros.de)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "ringbuffy.h"
|
||||
#include <string.h>
|
||||
|
||||
int ring_init (ringbuffy *rbuf, int size)
|
||||
{
|
||||
if (size > 0){
|
||||
rbuf->size = size;
|
||||
if( !(rbuf->buffy = (char *) malloc(sizeof(char)*size)) ){
|
||||
fprintf(stderr,"Not enough memory for ringbuffy\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Wrong size for ringbuffy\n");
|
||||
return -1;
|
||||
}
|
||||
rbuf->read_pos = 0;
|
||||
rbuf->write_pos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ring_destroy(ringbuffy *rbuf)
|
||||
{
|
||||
free(rbuf->buffy);
|
||||
}
|
||||
|
||||
|
||||
int ring_write(ringbuffy *rbuf, char *data, int count)
|
||||
{
|
||||
|
||||
int diff, free, pos, rest;
|
||||
|
||||
if (count <=0 ) return 0;
|
||||
pos = rbuf->write_pos;
|
||||
rest = rbuf->size - pos;
|
||||
diff = rbuf->read_pos - pos;
|
||||
free = (diff > 0) ? diff-1 : rbuf->size+diff-1;
|
||||
|
||||
if ( free <= 0 ) return FULL_BUFFER;
|
||||
if ( free < count ) count = free;
|
||||
|
||||
if (count >= rest){
|
||||
memcpy (rbuf->buffy+pos, data, rest);
|
||||
if (count - rest)
|
||||
memcpy (rbuf->buffy, data+rest, count - rest);
|
||||
rbuf->write_pos = count - rest;
|
||||
} else {
|
||||
memcpy (rbuf->buffy+pos, data, count);
|
||||
rbuf->write_pos += count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int ring_peek(ringbuffy *rbuf, char *data, int count, long off)
|
||||
{
|
||||
|
||||
int diff, free, pos, rest;
|
||||
|
||||
if (count <=0 ) return 0;
|
||||
pos = rbuf->read_pos+off;
|
||||
rest = rbuf->size - pos ;
|
||||
diff = rbuf->write_pos - pos;
|
||||
free = (diff >= 0) ? diff : rbuf->size+diff;
|
||||
|
||||
if ( free <= 0 ) return FULL_BUFFER;
|
||||
if ( free < count ) count = free;
|
||||
|
||||
if ( count < rest ){
|
||||
memcpy(data, rbuf->buffy+pos, count);
|
||||
} else {
|
||||
memcpy(data, rbuf->buffy+pos, rest);
|
||||
if ( count - rest)
|
||||
memcpy(data+rest, rbuf->buffy, count - rest);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int ring_read(ringbuffy *rbuf, char *data, int count)
|
||||
{
|
||||
|
||||
int diff, free, pos, rest;
|
||||
|
||||
if (count <=0 ) return 0;
|
||||
pos = rbuf->read_pos;
|
||||
rest = rbuf->size - pos;
|
||||
diff = rbuf->write_pos - pos;
|
||||
free = (diff >= 0) ? diff : rbuf->size+diff;
|
||||
|
||||
if ( rest <= 0 ) return 0;
|
||||
if ( free < count ) count = free;
|
||||
|
||||
if ( count < rest ){
|
||||
memcpy(data, rbuf->buffy+pos, count);
|
||||
rbuf->read_pos += count;
|
||||
} else {
|
||||
memcpy(data, rbuf->buffy+pos, rest);
|
||||
if ( count - rest)
|
||||
memcpy(data+rest, rbuf->buffy, count - rest);
|
||||
rbuf->read_pos = count - rest;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ring_write_file(ringbuffy *rbuf, int fd, int count)
|
||||
{
|
||||
|
||||
int diff, free, pos, rest, rr;
|
||||
|
||||
if (count <=0 ) return 0;
|
||||
pos = rbuf->write_pos;
|
||||
rest = rbuf->size - pos;
|
||||
diff = rbuf->read_pos - pos;
|
||||
free = (diff > 0) ? diff-1 : rbuf->size+diff-1;
|
||||
|
||||
if ( rest <= 0 ) return 0;
|
||||
if ( free < count ) count = free;
|
||||
|
||||
if (count >= rest){
|
||||
rr = read (fd, rbuf->buffy+pos, rest);
|
||||
if (rr == rest && count - rest)
|
||||
rr += read (fd, rbuf->buffy, count - rest);
|
||||
if (rr >=0)
|
||||
rbuf->write_pos = (pos + rr) % rbuf->size;
|
||||
} else {
|
||||
rr = read (fd, rbuf->buffy+pos, count);
|
||||
if (rr >=0)
|
||||
rbuf->write_pos += rr;
|
||||
}
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ring_read_file(ringbuffy *rbuf, int fd, int count)
|
||||
{
|
||||
|
||||
int diff, free, pos, rest, rr;
|
||||
|
||||
if (count <=0 ) return 0;
|
||||
pos = rbuf->read_pos;
|
||||
rest = rbuf->size - pos;
|
||||
diff = rbuf->write_pos - pos;
|
||||
free = (diff >= 0) ? diff : rbuf->size+diff;
|
||||
|
||||
if ( free <= 0 ) return FULL_BUFFER;
|
||||
if ( free < count ) count = free;
|
||||
|
||||
if (count >= rest){
|
||||
rr = write (fd, rbuf->buffy+pos, rest);
|
||||
if (rr == rest && count - rest)
|
||||
rr += write (fd, rbuf->buffy, count - rest);
|
||||
if (rr >=0)
|
||||
rbuf->read_pos = (pos + rr) % rbuf->size;
|
||||
} else {
|
||||
rr = write (fd, rbuf->buffy+pos, count);
|
||||
if (rr >=0)
|
||||
rbuf->read_pos += rr;
|
||||
}
|
||||
|
||||
|
||||
return rr;
|
||||
}
|
||||
|
||||
int ring_rest(ringbuffy *rbuf){
|
||||
int diff, free, pos, rest;
|
||||
pos = rbuf->read_pos;
|
||||
rest = rbuf->size - pos;
|
||||
diff = rbuf->write_pos - pos;
|
||||
free = (diff >= 0) ? diff : rbuf->size+diff;
|
||||
|
||||
return free;
|
||||
}
|
52
libdvbmpeg/ringbuffy.h
Normal file
52
libdvbmpeg/ringbuffy.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Ringbuffer Implementation for gtvscreen
|
||||
|
||||
Copyright (C) 2000 Marcus Metzler (mocm@metzlerbros.de)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef RINGBUFFY_H
|
||||
#define RINGBUFFY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define FULL_BUFFER -1000
|
||||
typedef struct ringbuffy{
|
||||
int read_pos;
|
||||
int write_pos;
|
||||
int size;
|
||||
char *buffy;
|
||||
} ringbuffy;
|
||||
|
||||
int ring_init (ringbuffy *rbuf, int size);
|
||||
void ring_destroy(ringbuffy *rbuf);
|
||||
int ring_write(ringbuffy *rbuf, char *data, int count);
|
||||
int ring_read(ringbuffy *rbuf, char *data, int count);
|
||||
int ring_write_file(ringbuffy *rbuf, int fd, int count);
|
||||
int ring_read_file(ringbuffy *rbuf, int fd, int count);
|
||||
int ring_rest(ringbuffy *rbuf);
|
||||
int ring_peek(ringbuffy *rbuf, char *data, int count, long off);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* RINGBUFFY_H */
|
2681
libdvbmpeg/transform.c
Normal file
2681
libdvbmpeg/transform.c
Normal file
File diff suppressed because it is too large
Load Diff
250
libdvbmpeg/transform.h
Normal file
250
libdvbmpeg/transform.h
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||
*
|
||||
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||
* for convergence integrated media GmbH
|
||||
* Copyright (C) 2002 Marcus Metzler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
|
||||
* The author can be reached at mocm@metzlerbros.de,
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _TS_TRANSFORM_H_
|
||||
#define _TS_TRANSFORM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "remux.h"
|
||||
|
||||
#define PROG_STREAM_MAP 0xBC
|
||||
#ifndef PRIVATE_STREAM1
|
||||
#define PRIVATE_STREAM1 0xBD
|
||||
#endif
|
||||
#define PADDING_STREAM 0xBE
|
||||
#ifndef PRIVATE_STREAM2
|
||||
#define PRIVATE_STREAM2 0xBF
|
||||
#endif
|
||||
#define AUDIO_STREAM_S 0xC0
|
||||
#define AUDIO_STREAM_E 0xDF
|
||||
#define VIDEO_STREAM_S 0xE0
|
||||
#define VIDEO_STREAM_E 0xEF
|
||||
#define ECM_STREAM 0xF0
|
||||
#define EMM_STREAM 0xF1
|
||||
#define DSM_CC_STREAM 0xF2
|
||||
#define ISO13522_STREAM 0xF3
|
||||
#define PROG_STREAM_DIR 0xFF
|
||||
|
||||
#define BUFFYSIZE 10*MAX_PLENGTH
|
||||
#define MAX_PTS 8192
|
||||
#define MAX_FRAME 8192
|
||||
#define MAX_PACK_L 4096
|
||||
#define PS_HEADER_L1 14
|
||||
#define PS_HEADER_L2 (PS_HEADER_L1+18)
|
||||
#define MAX_H_SIZE (PES_H_MIN + PS_HEADER_L1 + 5)
|
||||
#define PES_MIN 7
|
||||
#define PES_H_MIN 9
|
||||
|
||||
//flags2
|
||||
#define PTS_DTS_FLAGS 0xC0
|
||||
#define ESCR_FLAG 0x20
|
||||
#define ES_RATE_FLAG 0x10
|
||||
#define DSM_TRICK_FLAG 0x08
|
||||
#define ADD_CPY_FLAG 0x04
|
||||
#define PES_CRC_FLAG 0x02
|
||||
#define PES_EXT_FLAG 0x01
|
||||
|
||||
//pts_dts flags
|
||||
#define PTS_ONLY 0x80
|
||||
#define PTS_DTS 0xC0
|
||||
|
||||
#define TS_SIZE 188
|
||||
#define TRANS_ERROR 0x80
|
||||
#define PAY_START 0x40
|
||||
#define TRANS_PRIO 0x20
|
||||
#define PID_MASK_HI 0x1F
|
||||
//flags
|
||||
#define TRANS_SCRMBL1 0x80
|
||||
#define TRANS_SCRMBL2 0x40
|
||||
#define ADAPT_FIELD 0x20
|
||||
#define PAYLOAD 0x10
|
||||
#define COUNT_MASK 0x0F
|
||||
|
||||
// adaptation flags
|
||||
#define DISCON_IND 0x80
|
||||
#define RAND_ACC_IND 0x40
|
||||
#define ES_PRI_IND 0x20
|
||||
#define PCR_FLAG 0x10
|
||||
#define OPCR_FLAG 0x08
|
||||
#define SPLICE_FLAG 0x04
|
||||
#define TRANS_PRIV 0x02
|
||||
#define ADAP_EXT_FLAG 0x01
|
||||
|
||||
// adaptation extension flags
|
||||
#define LTW_FLAG 0x80
|
||||
#define PIECE_RATE 0x40
|
||||
#define SEAM_SPLICE 0x20
|
||||
|
||||
|
||||
#define MAX_PLENGTH 0xFFFF
|
||||
#define MMAX_PLENGTH (8*MAX_PLENGTH)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define P2P_LENGTH 2048
|
||||
|
||||
enum{NOPES, AUDIO, VIDEO, AC3};
|
||||
|
||||
typedef struct p2pstruct {
|
||||
int found;
|
||||
uint8_t buf[MMAX_PLENGTH];
|
||||
uint8_t cid;
|
||||
uint8_t subid;
|
||||
uint32_t plength;
|
||||
uint8_t plen[2];
|
||||
uint8_t flag1;
|
||||
uint8_t flag2;
|
||||
uint8_t hlength;
|
||||
uint8_t pts[5];
|
||||
int mpeg;
|
||||
uint8_t check;
|
||||
int fd1;
|
||||
int fd2;
|
||||
int es;
|
||||
int filter;
|
||||
int which;
|
||||
int done;
|
||||
int repack;
|
||||
uint16_t bigend_repack;
|
||||
void (*func)(uint8_t *buf, int count, void *p);
|
||||
int startv;
|
||||
int starta;
|
||||
int64_t apts;
|
||||
int64_t vpts;
|
||||
uint16_t pid;
|
||||
uint16_t pida;
|
||||
uint16_t pidv;
|
||||
uint8_t acounter;
|
||||
uint8_t vcounter;
|
||||
uint8_t count0;
|
||||
uint8_t count1;
|
||||
void *data;
|
||||
} p2p;
|
||||
|
||||
|
||||
uint64_t trans_pts_dts(uint8_t *pts);
|
||||
int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start,
|
||||
uint8_t *buf, uint8_t length);
|
||||
uint16_t get_pid(uint8_t *pid);
|
||||
void init_p2p(p2p *p, void (*func)(uint8_t *buf, int count, void *p),
|
||||
int repack);
|
||||
void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p));
|
||||
void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p));
|
||||
void pes_repack(p2p *p);
|
||||
void setup_pes2ts( p2p *p, uint32_t pida, uint32_t pidv,
|
||||
void (*ts_write)(uint8_t *buf, int count, void *p));
|
||||
void kpes_to_ts( p2p *p,uint8_t *buf ,int count );
|
||||
void setup_ts2pes( p2p *pa, p2p *pv, uint32_t pida, uint32_t pidv,
|
||||
void (*pes_write)(uint8_t *buf, int count, void *p));
|
||||
void kts_to_pes( p2p *p, uint8_t *buf);
|
||||
void pes_repack(p2p *p);
|
||||
void extract_from_pes(int fdin, int fdout, uint8_t id, int es);
|
||||
int64_t pes_dmx(int fdin, int fdouta, int fdoutv, int es);
|
||||
void pes_to_ts2( int fdin, int fdout, uint16_t pida, uint16_t pidv);
|
||||
void ts_to_pes( int fdin, uint16_t pida, uint16_t pidv, int pad);
|
||||
int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
|
||||
int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr);
|
||||
int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
|
||||
void filter_audio_from_pes(int fdin, int fdout, uint8_t id,
|
||||
uint8_t subid);
|
||||
|
||||
|
||||
//instant repack
|
||||
|
||||
typedef struct ipack_s {
|
||||
int size;
|
||||
int size_orig;
|
||||
int found;
|
||||
int ps;
|
||||
int has_ai;
|
||||
int has_vi;
|
||||
AudioInfo ai;
|
||||
VideoInfo vi;
|
||||
uint8_t *buf;
|
||||
uint8_t cid;
|
||||
uint32_t plength;
|
||||
uint8_t plen[2];
|
||||
uint8_t flag1;
|
||||
uint8_t flag2;
|
||||
uint8_t hlength;
|
||||
uint8_t pts[5];
|
||||
uint8_t last_pts[5];
|
||||
int mpeg;
|
||||
uint8_t check;
|
||||
int which;
|
||||
int done;
|
||||
void *data;
|
||||
void *data2;
|
||||
void (*func)(uint8_t *buf, int size, void *priv);
|
||||
int count;
|
||||
int start;
|
||||
int fd;
|
||||
int fd1;
|
||||
int fd2;
|
||||
int ffd;
|
||||
int playing;
|
||||
} ipack;
|
||||
|
||||
void instant_repack (uint8_t *buf, int count, ipack *p);
|
||||
void init_ipack(ipack *p, int size,
|
||||
void (*func)(uint8_t *buf, int size, void *priv),
|
||||
int pad);
|
||||
void free_ipack(ipack * p);
|
||||
void send_ipack(ipack *p);
|
||||
void reset_ipack(ipack *p);
|
||||
void ps_pes(ipack *p);
|
||||
// use with ipack structure, repack size and callback func
|
||||
|
||||
int64_t ts_demux(int fd_in, int fdv_out,int fda_out,uint16_t pida,
|
||||
uint16_t pidv, int es);
|
||||
|
||||
void ts2es(int fdin, uint16_t pidv);
|
||||
void ts2es_opt(int fdin, uint16_t pidv, ipack *p, int verb);
|
||||
void insert_pat_pmt( int fdin, int fdout);
|
||||
void change_aspect(int fdin, int fdout, int aspect);
|
||||
|
||||
// SV: all made non-static:
|
||||
void pes_in_ts(p2p *p);
|
||||
|
||||
// SV: moved from .c file:
|
||||
#define IPACKS 2048
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _TS_TRANSFORM_H_*/
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user