From 57b13abd1c37b7f798eef630e614da03007b95a2 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 17 Dec 2006 20:06:53 +0000 Subject: [PATCH] Removal of remuxer --- Makefile | 16 +- libdvbmpeg/DVB.hh | 446 ------- libdvbmpeg/Makefile | 33 - libdvbmpeg/OSD.h | 30 - libdvbmpeg/channel.h | 58 - libdvbmpeg/ci.hh | 167 --- libdvbmpeg/cpptools.cc | 946 -------------- libdvbmpeg/cpptools.hh | 330 ----- libdvbmpeg/ctools.c | 2379 ----------------------------------- libdvbmpeg/ctools.h | 404 ------ libdvbmpeg/devices.hh | 310 ----- libdvbmpeg/osd.hh | 84 -- libdvbmpeg/remux.c | 1215 ------------------ libdvbmpeg/remux.h | 149 --- libdvbmpeg/ringbuffy.c | 200 --- libdvbmpeg/ringbuffy.h | 52 - libdvbmpeg/transform.c | 2681 ---------------------------------------- libdvbmpeg/transform.h | 250 ---- mvpclient.c | 53 + mvpclient.h | 1 + mvpreceiver.c | 90 +- mvpreceiver.h | 11 +- remux/README | 7 - remux/ts2es.c | 87 -- remux/ts2es.h | 21 - remux/ts2ps.c | 114 -- remux/ts2ps.h | 24 - remux/tsremux.c | 215 ---- remux/tsremux.h | 45 - 29 files changed, 64 insertions(+), 10354 deletions(-) delete mode 100644 libdvbmpeg/DVB.hh delete mode 100644 libdvbmpeg/Makefile delete mode 100644 libdvbmpeg/OSD.h delete mode 100644 libdvbmpeg/channel.h delete mode 100644 libdvbmpeg/ci.hh delete mode 100644 libdvbmpeg/cpptools.cc delete mode 100644 libdvbmpeg/cpptools.hh delete mode 100644 libdvbmpeg/ctools.c delete mode 100644 libdvbmpeg/ctools.h delete mode 100644 libdvbmpeg/devices.hh delete mode 100644 libdvbmpeg/osd.hh delete mode 100644 libdvbmpeg/remux.c delete mode 100644 libdvbmpeg/remux.h delete mode 100644 libdvbmpeg/ringbuffy.c delete mode 100644 libdvbmpeg/ringbuffy.h delete mode 100644 libdvbmpeg/transform.c delete mode 100644 libdvbmpeg/transform.h delete mode 100644 remux/README delete mode 100644 remux/ts2es.c delete mode 100644 remux/ts2es.h delete mode 100644 remux/ts2ps.c delete mode 100644 remux/ts2ps.h delete mode 100644 remux/tsremux.c delete mode 100644 remux/tsremux.h diff --git a/Makefile b/Makefile index 5363bad..724d89d 100644 --- a/Makefile +++ b/Makefile @@ -40,21 +40,16 @@ PACKAGE = vdr-$(ARCHIVE) ### Includes and Defines (add further entries here): -INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -Iremux -Ilibdvbmpeg +INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): OBJS = $(PLUGIN).o dsock.o mvpserver.o udpreplier.o bootpd.o tftpd.o mvpclient.o tcp.o \ - remux/ts2ps.o remux/ts2es.o remux/tsremux.o ringbuffer.o \ + ringbuffer.o \ recplayer.o config.o log.o thread.o mvpreceiver.o tftpclient.o - -libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.cc libdvbmpeg/*.h libdvbmpeg/*.hh - make -C ./libdvbmpeg libdvbmpegtools.a - - ### Implicit rules: %.o: %.c @@ -73,8 +68,8 @@ $(DEPFILE): Makefile all: libvdr-$(PLUGIN).so -libvdr-$(PLUGIN).so: $(OBJS) libdvbmpeg/libdvbmpegtools.a - $(CXX) $(CXXFLAGS) -shared $(OBJS) libdvbmpeg/libdvbmpegtools.a -o $@ +libvdr-$(PLUGIN).so: $(OBJS) + $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ @cp $@ $(LIBDIR)/$@.$(APIVERSION) dist: clean @@ -86,5 +81,4 @@ dist: clean @echo Distribution package created as $(PACKAGE).tgz clean: - make -C libdvbmpeg clean - rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ remux/*.o + rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ diff --git a/libdvbmpeg/DVB.hh b/libdvbmpeg/DVB.hh deleted file mode 100644 index e713bee..0000000 --- a/libdvbmpeg/DVB.hh +++ /dev/null @@ -1,446 +0,0 @@ -#ifndef _DVB_DEV_HH_ -#define _DVB_DEV_HH_ - -extern "C" { -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NEWSTRUCT -#include -} - -#include -#include -#include -using namespace std; - -#include -#include - -#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 diff --git a/libdvbmpeg/Makefile b/libdvbmpeg/Makefile deleted file mode 100644 index 9176f80..0000000 --- a/libdvbmpeg/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -INCS = -I. -CFLAGS = -g -fPIC -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_GNU_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 diff --git a/libdvbmpeg/OSD.h b/libdvbmpeg/OSD.h deleted file mode 100644 index 385ac78..0000000 --- a/libdvbmpeg/OSD.h +++ /dev/null @@ -1,30 +0,0 @@ -#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 diff --git a/libdvbmpeg/channel.h b/libdvbmpeg/channel.h deleted file mode 100644 index c4f62b4..0000000 --- a/libdvbmpeg/channel.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _CHANNEL_H -#define _CHANNEL_H - -#include - -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 -#include -#include -#include - -#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 -#include -#include -#include -#include - -#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 diff --git a/libdvbmpeg/ci.hh b/libdvbmpeg/ci.hh deleted file mode 100644 index 77e7684..0000000 --- a/libdvbmpeg/ci.hh +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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 -#include - -#include -#include -#include -#include -#include -#include -#include - -#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 diff --git a/libdvbmpeg/cpptools.cc b/libdvbmpeg/cpptools.cc deleted file mode 100644 index 91808cc..0000000 --- a/libdvbmpeg/cpptools.cc +++ /dev/null @@ -1,946 +0,0 @@ -/* - * 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> ts; - int j; - int found = 0; - for (j=0;j> 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++; - } - } - } -} - - diff --git a/libdvbmpeg/cpptools.hh b/libdvbmpeg/cpptools.hh deleted file mode 100644 index 49ea5de..0000000 --- a/libdvbmpeg/cpptools.hh +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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 -#include -#include -#include -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_ - diff --git a/libdvbmpeg/ctools.c b/libdvbmpeg/ctools.c deleted file mode 100644 index dfd1751..0000000 --- a/libdvbmpeg/ctools.c +++ /dev/null @@ -1,2379 +0,0 @@ -/* - * 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 "ctools.h" - -#define MAX_SEARCH 1024 * 1024 - - -/* - - PES - -*/ - -ssize_t save_read(int fd, void *buf, size_t count) -{ - ssize_t neof = 1; - size_t re = 0; - - while(neof >= 0 && re < count){ - neof = read(fd, buf+re, count - re); - if (neof > 0) re += neof; - else break; - } - - if (neof < 0 && re == 0) return neof; - else return re; -} - -void init_pes(pes_packet *p){ - p->stream_id = 0; - p->llength[0] = 0; - p->llength[1] = 0; - p->length = 0; - p->flags1 = 0x80; - p->flags2 = 0; - p->pes_hlength = 0; - p->trick = 0; - p->add_cpy = 0; - p->priv_flags = 0; - p->pack_field_length = 0; - p->pack_header = (uint8_t *) NULL; - p->pck_sqnc_cntr = 0; - p->org_stuff_length = 0; - p->pes_ext_lngth = 0; - p->pes_ext = (uint8_t *) NULL; - p->pes_pckt_data = (uint8_t *) NULL; - p->padding = 0; - p->mpeg = 2; // DEFAULT MPEG2 - p->mpeg1_pad = 0; - p->mpeg1_headr = NULL; - p->stuffing = 0; -} - -void kill_pes(pes_packet *p){ - if (p->pack_header) - free(p->pack_header); - if (p->pes_ext) - free(p->pes_ext); - if (p->pes_pckt_data) - free(p->pes_pckt_data); - if (p->mpeg1_headr) - free(p->mpeg1_headr); - init_pes(p); -} - -void setlength_pes(pes_packet *p){ - short *ll; - ll = (short *) p->llength; - p->length = ntohs(*ll); -} - -static void setl_pes(pes_packet *p){ - setlength_pes(p); - if (p->length) - p->pes_pckt_data = (uint8_t *)malloc(p->length); -} - -void nlength_pes(pes_packet *p){ - if (p->length <= 0xFFFF){ - short *ll = (short *) p->llength; - short l = p->length; - *ll = htons(l); - } else { - p->llength[0] =0x00; - p->llength[1] =0x00; - } -} - -static void nl_pes(pes_packet *p) -{ - nlength_pes(p); - p->pes_pckt_data = (uint8_t *) malloc(p->length); -} - -void pts2pts(uint8_t *av_pts, uint8_t *pts) -{ - - av_pts[0] = ((pts[0] & 0x06) << 5) | - ((pts[1] & 0xFC) >> 2); - av_pts[1] = ((pts[1] & 0x03) << 6) | - ((pts[2] & 0xFC) >> 2); - av_pts[2] = ((pts[2] & 0x02) << 6) | - ((pts[3] & 0xFE) >> 1); - av_pts[3] = ((pts[3] & 0x01) << 7) | - ((pts[4] & 0xFE) >> 1); - -} - - -int cwrite_pes(uint8_t *buf, pes_packet *p, long length){ - int count,i; - uint8_t dummy; - int more = 0; - uint8_t headr[3] = { 0x00, 0x00 , 0x01}; - - if (length < p->length+p->pes_hlength){ - fprintf(stderr,"Wrong buffer size in cwrite_pes\n"); - exit(1); - } - - - memcpy(buf,headr,3); - count = 3; - buf[count] = p->stream_id; - count++; - - switch ( p->stream_id ) { - - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - buf[count] = p->llength[0]; - count++; - buf[count] = p->llength[1]; - count++; - memcpy(buf+count,p->pes_pckt_data,p->length); - count += p->length; - 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: - buf[count] = p->llength[0]; - count++; - buf[count] = p->llength[1]; - count++; - more = 1; - break; - } - - - if ( more ) { - if ( p->mpeg == 2 ){ - memcpy(buf+count,&p->flags1,1); - count++; - memcpy(buf+count,&p->flags2,1); - count++; - memcpy(buf+count,&p->pes_hlength,1); - count++; - - if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){ - memcpy(buf+count,p->pts,5); - count += 5; - } else - if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){ - memcpy(buf+count,p->pts,5); - count += 5; - memcpy(buf+count,p->dts,5); - count += 5; - } - if (p->flags2 & ESCR_FLAG){ - memcpy(buf+count,p->escr,6); - count += 6; - } - if (p->flags2 & ES_RATE_FLAG){ - memcpy(buf+count,p->es_rate,3); - count += 3; - } - if (p->flags2 & DSM_TRICK_FLAG){ - memcpy(buf+count,&p->trick,1); - count++; - } - if (p->flags2 & ADD_CPY_FLAG){ - memcpy(buf+count,&p->add_cpy,1); - count++; - } - if (p->flags2 & PES_CRC_FLAG){ - memcpy(buf+count,p->prev_pes_crc,2); - count += 2; - } - if (p->flags2 & PES_EXT_FLAG){ - memcpy(buf+count,&p->priv_flags,1); - count++; - - if (p->priv_flags & PRIVATE_DATA){ - memcpy(buf+count,p->pes_priv_data,16); - count += 16; - } - if (p->priv_flags & HEADER_FIELD){ - memcpy(buf+count,&p->pack_field_length, - 1); - count++; - memcpy(buf+count,p->pack_header, - p->pack_field_length); - count += p->pack_field_length; - - } - - if ( p->priv_flags & PACK_SEQ_CTR){ - memcpy(buf+count,&p->pck_sqnc_cntr,1); - count++; - memcpy(buf+count,&p->org_stuff_length, - 1); - count++; - } - - if ( p->priv_flags & P_STD_BUFFER){ - memcpy(buf+count,p->p_std,2); - count += 2; - } - if ( p->priv_flags & PES_EXT_FLAG2){ - memcpy(buf+count,&p->pes_ext_lngth,1); - count++; - memcpy(buf+count,p->pes_ext, - p->pes_ext_lngth); - count += p->pes_ext_lngth; - } - } - dummy = 0xFF; - for (i=0;istuffing;i++) { - memcpy(buf+count,&dummy,1); - count++; - } - } else { - if (p->mpeg1_pad){ - memcpy(buf+count,p->mpeg1_headr,p->mpeg1_pad); - count += p->mpeg1_pad; - } - if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){ - memcpy(buf+count,p->pts,5); - count += 5; - } - else if ((p->flags2 & PTS_DTS_FLAGS) == - PTS_DTS){ - memcpy(buf+count,p->pts,5); - count += 5; - memcpy(buf+count,p->dts,5); - count += 5; - } - } - memcpy(buf+count,p->pes_pckt_data,p->length); - count += p->length; - } - - return count; - -} - -void write_pes(int fd, pes_packet *p){ - long length; - uint8_t *buf; - int l = p->length+p->pes_hlength; - - buf = (uint8_t *) malloc(l); - length = cwrite_pes(buf,p,l); - write(fd,buf,length); - free(buf); -} - -static unsigned int find_length(int f){ - uint64_t p = 0; - uint64_t start = 0; - uint64_t q = 0; - int found = 0; - uint8_t sync4[4]; - int neof = 1; - - start = lseek(f,0,SEEK_CUR); - start -=2; - lseek(f,start,SEEK_SET); - while ( neof > 0 && !found ){ - p = lseek(f,0,SEEK_CUR); - neof = save_read(f,&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 = lseek(f,0,SEEK_CUR); - break; - } - } - } - q = lseek(f,0,SEEK_CUR); - lseek(f,start+2,SEEK_SET); - if (found) return (unsigned int)(q-start)-4-2; - else return (unsigned int)(q-start-2); - -} - - -void cread_pes(char *buf, pes_packet *p){ - - uint8_t count, dummy, check; - int i; - uint64_t po = 0; - int c=0; - - switch ( p->stream_id ) { - - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - memcpy(p->pes_pckt_data,buf+c,p->length); - return; - break; - case PADDING_STREAM : - p->padding = p->length; - memcpy(p->pes_pckt_data,buf+c,p->length); - return; - 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: - break; - default: - return; - break; - } - - po = c; - memcpy(&p->flags1,buf+c,1); - c++; - if ( (p->flags1 & 0xC0) == 0x80 ) p->mpeg = 2; - else p->mpeg = 1; - - if ( p->mpeg == 2 ){ - memcpy(&p->flags2,buf+c,1); - c++; - memcpy(&p->pes_hlength,buf+c,1); - c++; - - p->length -=p->pes_hlength+3; - count = p->pes_hlength; - - if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){ - memcpy(p->pts,buf+c,5); - c += 5; - count -=5; - } else - if ((p->flags2 & PTS_DTS_FLAGS) == PTS_DTS){ - memcpy(p->pts,buf+c,5); - c += 5; - memcpy(p->dts,buf+c,5); - c += 5; - count -= 10; - } - - if (p->flags2 & ESCR_FLAG){ - memcpy(p->escr,buf+c,6); - c += 6; - count -= 6; - } - - if (p->flags2 & ES_RATE_FLAG){ - memcpy(p->es_rate,buf+c,3); - c += 3; - count -= 3; - } - - if (p->flags2 & DSM_TRICK_FLAG){ - memcpy(&p->trick,buf+c,1); - c += 1; - count -= 1; - } - - if (p->flags2 & ADD_CPY_FLAG){ - memcpy(&p->add_cpy,buf+c,1); - c++; - count -= 1; - } - - if (p->flags2 & PES_CRC_FLAG){ - memcpy(p->prev_pes_crc,buf+c,2); - c += 2; - count -= 2; - } - - if (p->flags2 & PES_EXT_FLAG){ - memcpy(&p->priv_flags,buf+c,1); - c++; - count -= 1; - - if (p->priv_flags & PRIVATE_DATA){ - memcpy(p->pes_priv_data,buf+c,16); - c += 16; - count -= 16; - } - - if (p->priv_flags & HEADER_FIELD){ - memcpy(&p->pack_field_length,buf+c,1); - c++; - p->pack_header = (uint8_t *) - malloc(p->pack_field_length); - memcpy(p->pack_header,buf+c, - p->pack_field_length); - c += p->pack_field_length; - count -= 1+p->pack_field_length; - } - - if ( p->priv_flags & PACK_SEQ_CTR){ - memcpy(&p->pck_sqnc_cntr,buf+c,1); - c++; - memcpy(&p->org_stuff_length,buf+c,1); - c++; - count -= 2; - } - - if ( p->priv_flags & P_STD_BUFFER){ - memcpy(p->p_std,buf+c,2); - c += 2; - count -= 2; - } - - if ( p->priv_flags & PES_EXT_FLAG2){ - memcpy(&p->pes_ext_lngth,buf+c,1); - c++; - p->pes_ext = (uint8_t *) - malloc(p->pes_ext_lngth); - memcpy(p->pes_ext,buf+c, - p->pes_ext_lngth); - c += p->pes_ext_lngth; - count -= 1+p->pes_ext_lngth; - } - } - p->stuffing = count; - for(i = 0; i< count ;i++){ - memcpy(&dummy,buf+c,1); - c++; - } - } else { - p->mpeg1_pad = 1; - check = p->flags1; - while (check == 0xFF){ - memcpy(&check,buf+c,1); - c++; - p->mpeg1_pad++; - } - - if ( (check & 0xC0) == 0x40){ - memcpy(&check,buf+c,1); - c++; - p->mpeg1_pad++; - memcpy(&check,buf+c,1); - c++; - p->mpeg1_pad++; - } - p->flags2 = 0; - p->length -= p->mpeg1_pad; - - c = po; - if ( (check & 0x30)){ - p->length ++; - p->mpeg1_pad --; - - if (check == p->flags1){ - p->pes_hlength = 0; - } else { - p->mpeg1_headr = (uint8_t *) - malloc(p->mpeg1_pad); - p->pes_hlength = p->mpeg1_pad; - memcpy(p->mpeg1_headr,buf+c, - p->mpeg1_pad); - c += p->mpeg1_pad; - } - - p->flags2 = (check & 0xF0) << 2; - if ((p->flags2 & PTS_DTS_FLAGS) == PTS_ONLY){ - memcpy(p->pts,buf+c,5); - c += 5; - p->length -= 5; - p->pes_hlength += 5; - } - else if ((p->flags2 & PTS_DTS_FLAGS) == - PTS_DTS){ - memcpy(p->pts,buf+c,5); - c += 5; - memcpy(p->dts,buf+c,5); - c += 5; - p->length -= 10; - p->pes_hlength += 10; - } - } else { - p->mpeg1_headr = (uint8_t *) malloc(p->mpeg1_pad); - p->pes_hlength = p->mpeg1_pad; - memcpy(p->mpeg1_headr,buf+c, - p->mpeg1_pad); - c += p->mpeg1_pad; - } - } - memcpy(p->pes_pckt_data,buf+c,p->length); -} - - -int read_pes(int f, pes_packet *p){ - - uint8_t sync4[4]; - int found=0; - uint64_t po = 0; - int neof = 1; - uint8_t *buf; - - while (neof > 0 && !found) { - po = lseek(f,0,SEEK_CUR); - if (po < 0) return -1; - if ((neof = save_read(f,&sync4,4)) < 4) return -1; - if (sync4[0] == 0x00 && sync4[1] == 0x00 && sync4[2] == 0x01) { - 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 : - 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: - if((neof = save_read(f,p->llength,2)) < 2) - return -1; - setl_pes(p); - if (!p->length){ - p->length = find_length(f); - nl_pes(p); - } - found = 1; - break; - - default: - if (lseek(f,po+1,SEEK_SET) < po+1) return -1; - break; - } - } else if(lseek(f,po+1,SEEK_SET) < po+1) return -1; - } - - if (!found || !p->length) return 0; - - if (p->length >0){ - buf = (uint8_t *) malloc(p->length); - if((neof = save_read(f,buf,p->length))< p->length) return -1; - cread_pes((char *)buf,p); - free(buf); - } else return 0; - - return neof; -} - -/* - - Transport Stream - -*/ - -void init_ts(ts_packet *p){ - p->pid[0] = 0; - p->pid[1] = 0; - p->flags = 0; - p->count = 0; - p->adapt_length = 0; - p->adapt_flags = 0; - p->splice_count = 0; - p->priv_dat_len = 0; - p->priv_dat = NULL; - p->adapt_ext_len = 0; - p->adapt_eflags = 0; - p->rest = 0; - p->stuffing = 0; -} - -void kill_ts(ts_packet *p){ - if (p->priv_dat) - free(p->priv_dat); - init_ts(p); -} - - - -unsigned short pid_ts(ts_packet *p) -{ - return get_pid(p->pid); -} - -int cwrite_ts(uint8_t *buf, ts_packet *p, long length){ - long count,i; - uint8_t sync,dummy; - - sync = 0x47; - memcpy(buf,&sync,1); - count = 1; - memcpy(buf+count,p->pid,2); - count += 2; - memcpy(buf+count,&p->flags,1); - count++; - - - if (! (p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){ - memcpy(buf+count,p->data,184); - count += 184; - } else { - memcpy(buf+count,&p->adapt_length,1); - count++; - memcpy(buf+count,&p->adapt_flags,1); - count++; - - if ( p->adapt_flags & PCR_FLAG ){ - memcpy(buf+count, p->pcr,6); - count += 6; - } - if ( p->adapt_flags & OPCR_FLAG ){ - memcpy(buf+count, p->opcr,6); - count += 6; - } - if ( p->adapt_flags & SPLICE_FLAG ){ - memcpy(buf+count, &p->splice_count,1); - count++; - } - if( p->adapt_flags & TRANS_PRIV){ - memcpy(buf+count,&p->priv_dat_len,1); - count++; - memcpy(buf+count,p->priv_dat,p->priv_dat_len); - count += p->priv_dat_len; - } - - if( p->adapt_flags & ADAP_EXT_FLAG){ - memcpy(buf+count,&p->adapt_ext_len,1); - count++; - memcpy(buf+count,&p->adapt_eflags,1); - count++; - - if( p->adapt_eflags & LTW_FLAG){ - memcpy(buf+count,p->ltw,2); - count += 2; - } - if( p->adapt_eflags & PIECE_RATE){ - memcpy(buf+count,p->piece_rate,3); - count += 3; - } - if( p->adapt_eflags & SEAM_SPLICE){ - memcpy(buf+count,p->dts,5); - count += 5; - } - } - dummy = 0xFF; - for(i=0; i < p->stuffing ; i++){ - memcpy(buf+count,&dummy,1); - count++; - } - if (p->flags & PAYLOAD){ - memcpy(buf+count,p->data,p->rest); - count += p->rest; - } - } - - - return count; -} - -void write_ts(int fd, ts_packet *p){ - long length; - uint8_t buf[TS_SIZE]; - - length = cwrite_ts(buf,p,TS_SIZE); - write(fd,buf,length); -} - -int read_ts (int f, ts_packet *p){ - uint8_t sync; - int found=0; - uint64_t po,q; - int neof = 1; - - sync=0; - while (neof > 0 && !found) { - neof = save_read(f,&sync,1); - if (sync == 0x47) - found = 1; - } - neof = save_read(f,p->pid,2); - neof = save_read(f,&p->flags,1); - p->count = p->flags & COUNT_MASK; - - if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){ - //no adapt. field only payload - neof = save_read(f,p->data,184); - p->rest = 184; - return neof; - } - - if ( p->flags & ADAPT_FIELD ) { - // adaption field - neof = save_read(f,&p->adapt_length,1); - po = lseek(f,0,SEEK_CUR); - neof = save_read(f,&p->adapt_flags,1); - - if ( p->adapt_flags & PCR_FLAG ) - neof = save_read(f, p->pcr,6); - - if ( p->adapt_flags & OPCR_FLAG ) - neof = save_read(f, p->opcr,6); - - if ( p->adapt_flags & SPLICE_FLAG ) - neof = save_read(f, &p->splice_count,1); - - if( p->adapt_flags & TRANS_PRIV){ - neof = save_read(f,&p->priv_dat_len,1); - p->priv_dat = (uint8_t *) malloc(p->priv_dat_len); - neof = save_read(f,p->priv_dat,p->priv_dat_len); - } - - if( p->adapt_flags & ADAP_EXT_FLAG){ - neof = save_read(f,&p->adapt_ext_len,1); - neof = save_read(f,&p->adapt_eflags,1); - if( p->adapt_eflags & LTW_FLAG) - neof = save_read(f,p->ltw,2); - - if( p->adapt_eflags & PIECE_RATE) - neof = save_read(f,p->piece_rate,3); - - if( p->adapt_eflags & SEAM_SPLICE) - neof = save_read(f,p->dts,5); - } - q = lseek(f,0,SEEK_CUR); - p->stuffing = p->adapt_length -(q-po); - p->rest = 183-p->adapt_length; - lseek(f,q+p->stuffing,SEEK_SET); - if (p->flags & PAYLOAD) // payload - neof = save_read(f,p->data,p->rest); - else - lseek(f,q+p->rest,SEEK_SET); - } - return neof; -} - -void cread_ts (char *buf, ts_packet *p, long length){ - uint8_t sync; - int found=0; - uint64_t po,q; - long count=0; - - sync=0; - while (count < length && !found) { - sync=buf[count]; - count++; - if (sync == 0x47) - found = 1; - } - memcpy(p->pid,buf+count,2); - count += 2; - p->flags = buf[count]; - count++; - p->count = p->flags & COUNT_MASK; - - if (!(p->flags & ADAPT_FIELD) && (p->flags & PAYLOAD)){ - //no adapt. field only payload - memcpy(p->data,buf+count,184); - p->rest = 184; - return; - } - - if ( p->flags & ADAPT_FIELD ) { - // adaption field - p->adapt_length = buf[count]; - count++; - po = count; - memcpy(&p->adapt_flags,buf+count,1); - count++; - - if ( p->adapt_flags & PCR_FLAG ){ - memcpy( p->pcr,buf+count,6); - count += 6; - } - if ( p->adapt_flags & OPCR_FLAG ){ - memcpy( p->opcr,buf+count,6); - count += 6; - } - if ( p->adapt_flags & SPLICE_FLAG ){ - memcpy( &p->splice_count,buf+count,1); - count++; - } - if( p->adapt_flags & TRANS_PRIV){ - memcpy(&p->priv_dat_len,buf+count,1); - count++; - p->priv_dat = (uint8_t *) malloc(p->priv_dat_len); - memcpy(p->priv_dat,buf+count,p->priv_dat_len); - count += p->priv_dat_len; - } - - if( p->adapt_flags & ADAP_EXT_FLAG){ - memcpy(&p->adapt_ext_len,buf+count,1); - count++; - memcpy(&p->adapt_eflags,buf+count,1); - count++; - if( p->adapt_eflags & LTW_FLAG){ - memcpy(p->ltw,buf+count,2); - count += 2; - } - if( p->adapt_eflags & PIECE_RATE){ - memcpy(p->piece_rate,buf+count,3); - count += 3; - } - if( p->adapt_eflags & SEAM_SPLICE){ - memcpy(p->dts,buf+count,5); - count += 5; - } - } - q = count; - p->stuffing = p->adapt_length -(q-po); - p->rest = 183-p->adapt_length; - count = q+p->stuffing; - if (p->flags & PAYLOAD){ // payload - memcpy(p->data,buf+count,p->rest); - count += p->rest; - } else - count = q+p->rest; - } -} - - -/* - - Program Stream - -*/ - - -void init_ps(ps_packet *p) -{ - p->stuff_length=0xF8; - p->data = NULL; - p->sheader_length = 0; - p->audio_bound = 0; - p->video_bound = 0; - p->npes = 0; - p->mpeg = 2; -} - -void kill_ps(ps_packet *p) -{ - if (p->data) - free(p->data); - init_ps(p); -} - -void setlength_ps(ps_packet *p) -{ - short *ll; - ll = (short *) p->sheader_llength; - if (p->mpeg == 2) - p->sheader_length = ntohs(*ll) - 6; - else - p->sheader_length = ntohs(*ll); -} - -static void setl_ps(ps_packet *p) -{ - setlength_ps(p); - p->data = (uint8_t *) malloc(p->sheader_length); -} - -int mux_ps(ps_packet *p) -{ - uint32_t mux = 0; - uint8_t *i = (uint8_t *)&mux; - - i[1] = p->mux_rate[0]; - i[2] = p->mux_rate[1]; - i[3] = p->mux_rate[2]; - mux = ntohl(mux); - mux = (mux >>2); - return mux; -} - -int rate_ps(ps_packet *p) -{ - uint32_t rate=0; - uint8_t *i= (uint8_t *) &rate; - - i[1] = p->rate_bound[0] & 0x7F; - i[2] = p->rate_bound[1]; - i[3] = p->rate_bound[2]; - - rate = ntohl(rate); - rate = (rate >> 1); - return rate; -} - - -uint32_t scr_base_ps(ps_packet *p) // only 32 bit!! -{ - uint32_t base = 0; - uint8_t *buf = (uint8_t *)&base; - - buf[0] |= (long int)((p->scr[0] & 0x18) << 3); - buf[0] |= (long int)((p->scr[0] & 0x03) << 4); - buf[0] |= (long int)((p->scr[1] & 0xF0) >> 4); - - buf[1] |= (long int)((p->scr[1] & 0x0F) << 4); - buf[1] |= (long int)((p->scr[2] & 0xF0) >> 4); - - buf[2] |= (long int)((p->scr[2] & 0x08) << 4); - buf[2] |= (long int)((p->scr[2] & 0x03) << 5); - buf[2] |= (long int)((p->scr[3] & 0xF8) >> 3); - - buf[3] |= (long int)((p->scr[3] & 0x07) << 5); - buf[3] |= (long int)((p->scr[4] & 0xF8) >> 3); - - base = ntohl(base); - return base; -} - -uint16_t scr_ext_ps(ps_packet *p) -{ - short ext = 0; - - ext = (short)(p->scr[5] >> 1); - ext += (short) (p->scr[4] & 0x03) * 128; - - return ext; -} - -int cwrite_ps(uint8_t *buf, ps_packet *p, long length) -{ - long count,i; - uint8_t headr1[4] = {0x00, 0x00, 0x01, 0xBA }; - uint8_t headr2[4] = {0x00, 0x00, 0x01, 0xBB }; - uint8_t buffy = 0xFF; - - - memcpy(buf,headr1,4); - count = 4; - if (p->mpeg == 2){ - memcpy(buf+count,p->scr,6); - count += 6; - memcpy(buf+count,p->mux_rate,3); - count += 3; - memcpy(buf+count,&p->stuff_length,1); - count++; - for(i=0; i< (p->stuff_length & 3); i++){ - memcpy(buf+count,&buffy,1); - count++; - } - } else { - memcpy(buf+count,p->scr,5); - count += 5; - memcpy(buf+count,p->mux_rate,3); - count += 3; - } - if (p->sheader_length){ - memcpy(buf+count,headr2,4); - count += 4; - memcpy(buf+count,p->sheader_llength,2); - count += 2; - if ( p->mpeg == 2){ - memcpy(buf+count,p->rate_bound,3); - count += 3; - memcpy(buf+count,&p->audio_bound,1); - count++; - memcpy(buf+count,&p->video_bound,1); - count++; - memcpy(buf+count,&p->reserved,1); - count++; - } - memcpy(buf+count,p->data,p->sheader_length); - count += p->sheader_length; - } - - return count; -} - -void write_ps(int fd, ps_packet *p){ - long length; - uint8_t buf[PS_MAX]; - - length = cwrite_ps(buf,p,PS_MAX); - write(fd,buf,length); -} - -int read_ps (int f, ps_packet *p){ - uint8_t headr[4]; - pes_packet pes; - int i,done; - int found=0; - uint64_t po = 0; - uint64_t q = 0; - long count = 0; - int neof = 1; - - po = lseek(f,0,SEEK_CUR); - while (neof > 0 && !found && count < MAX_SEARCH) { - neof = save_read(f,&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 lseek(f,po+1,SEEK_SET); - } - count++; - } - - if (found){ - neof = save_read(f,p->scr,6); - if (p->scr[0] & 0x40) - p->mpeg = 2; - else - p->mpeg = 1; - - if (p->mpeg == 2){ - neof = save_read(f,p->mux_rate,3); - neof = save_read(f,&p->stuff_length,1); - po = lseek(f,0,SEEK_CUR); - lseek(f,po+(p->stuff_length & 3),SEEK_SET); - } else { - p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes - neof = save_read(f,p->mux_rate+1,2); - } - - po = lseek(f,0,SEEK_CUR); - neof = save_read(f,headr,4); - if (headr[0] == 0x00 && headr[1] == 0x00 && - headr[2] == 0x01 && headr[3] == 0xBB ) { - neof = save_read(f,p->sheader_llength,2); - setl_ps(p); - if (p->mpeg == 2){ - neof = save_read(f,p->rate_bound,3); - neof = save_read(f,&p->audio_bound,1); - neof = save_read(f,&p->video_bound,1); - neof = save_read(f,&p->reserved,1); - } - neof = save_read(f,p->data,p->sheader_length); - } else { - lseek(f,po,SEEK_SET); - p->sheader_length = 0; - } - - i = 0; - done = 0; - q = lseek(f,0,SEEK_CUR); - do { - po = lseek(f,0,SEEK_CUR); - neof = save_read(f,headr,4); - lseek(f,po,SEEK_SET); - if ( headr[0] == 0x00 && headr[1] == 0x00 - && headr[2] == 0x01 && headr[3] != 0xBA){ - init_pes(&pes); - neof = read_pes(f,&pes); - i++; - } else done = 1; - kill_pes(&pes); - } while ( neof > 0 && !done); - p->npes = i; - lseek(f,q,SEEK_SET); - } - return neof; -} - -void cread_ps (char *buf, ps_packet *p, long length){ - uint8_t *headr; - pes_packet pes; - int i,done; - int found=0; - uint64_t po = 0; - uint64_t q = 0; - long count = 0; - long c = 0; - - po = c; - while ( count < length && !found && count < MAX_SEARCH) { - headr = (uint8_t *)buf+c; - c += 4; - if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01){ - if ( headr[3] == 0xBA ) - found = 1; - else - if ( headr[3] == 0xB9 ) break; - else c = po+1; - } - count++; - } - - if (found){ - memcpy(p->scr,buf+c,6); - c += 6; - if (p->scr[0] & 0x40) - p->mpeg = 2; - else - p->mpeg = 1; - - if (p->mpeg == 2){ - memcpy(p->mux_rate,buf+c,3); - c += 3; - memcpy(&p->stuff_length,buf+c,1); - c++; - po = c; - c = po+(p->stuff_length & 3); - } else { - p->mux_rate[0] = p->scr[5]; //mpeg1 scr is only 5 bytes - memcpy(p->mux_rate+1,buf+c,2); - c += 2; - } - - po = c; - headr = (uint8_t *)buf+c; - c += 4; - if (headr[0] == 0x00 && headr[1] == 0x00 && - headr[2] == 0x01 && headr[3] == 0xBB ) { - memcpy(p->sheader_llength,buf+c,2); - c += 2; - setl_ps(p); - if (p->mpeg == 2){ - memcpy(p->rate_bound,buf+c,3); - c += 3; - memcpy(&p->audio_bound,buf+c,1); - c++; - memcpy(&p->video_bound,buf+c,1); - c++; - memcpy(&p->reserved,buf+c,1); - c++; - } - memcpy(p->data,buf+c,p->sheader_length); - c += p->sheader_length; - } else { - c = po; - p->sheader_length = 0; - } - - i = 0; - done = 0; - q = c; - do { - headr = (uint8_t *)buf+c; - if ( headr[0] == 0x00 && headr[1] == 0x00 - && headr[2] == 0x01 && headr[3] != 0xBA){ - init_pes(&pes); - // cread_pes(buf+c,&pes); - i++; - } else done = 1; - kill_pes(&pes); - } while (c < length && !done); - p->npes = i; - c = q; - } -} - - - - - - - -/* - conversion -*/ - -void init_trans(trans *p) -{ - int i; - - p->found = 0; - p->pes = 0; - p->is_full = 0; - p->pes_start = 0; - p->pes_started = 0; - p->set = 0; - - for (i = 0; i < MASKL*MAXFILT ; i++){ - p->mask[i] = 0; - p->filt[i] = 0; - } - for (i = 0; i < MAXFILT ; i++){ - p->sec[i].found = 0; - p->sec[i].length = 0; - } -} - -int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask, uint8_t *filt, int pes) -{ - int i; - int off; - - if ( filtn > MAXFILT-1 || filtn<0 ) return -1; - p->pid[filtn] = pid; - if (pes) p->pes |= (tflags)(1 << filtn); - else { - off = MASKL*filtn; - p->pes &= ~((tflags) (1 << filtn) ); - for (i = 0; i < MASKL ; i++){ - p->mask[off+i] = mask[i]; - p->filt[off+i] = filt[i]; - } - } - p->set |= (tflags) (1 << filtn); - return 0; -} - -void clear_trans_filt(trans *p,int filtn) -{ - int i; - - p->set &= ~((tflags) (1 << filtn) ); - p->pes &= ~((tflags) (1 << filtn) ); - p->is_full &= ~((tflags) (1 << filtn) ); - p->pes_start &= ~((tflags) (1 << filtn) ); - p->pes_started &= ~((tflags) (1 << filtn) ); - - for (i = MASKL*filtn; i < MASKL*(filtn+1) ; i++){ - p->mask[i] = 0; - p->filt[i] = 0; - } - p->sec[filtn].found = 0; - p->sec[filtn].length = 0; -} - -int filt_is_set(trans *p, int filtn) -{ - if (p->set & ((tflags)(1 << filtn))) return 1; - return 0; -} - -int pes_is_set(trans *p, int filtn) -{ - if (p->pes & ((tflags)(1 << filtn))) return 1; - return 0; -} - -int pes_is_started(trans *p, int filtn) -{ - if (p->pes_started & ((tflags)(1 << filtn))) return 1; - return 0; -} - -int pes_is_start(trans *p, int filtn) -{ - if (p->pes_start & ((tflags)(1 << filtn))) return 1; - return 0; -} - -int filt_is_ready(trans *p,int filtn) -{ - if (p->is_full & ((tflags)(1 << filtn))) return 1; - return 0; -} - -void trans_filt(uint8_t *buf, int count, trans *p) -{ - int c=0; - //fprintf(stderr,"trans_filt\n"); - - - while (c < count && p->found <1 ){ - if ( buf[c] == 0x47) p->found = 1; - c++; - p->packet[0] = 0x47; - } - if (c == count) return; - - while( c < count && p->found < 188 && p->found > 0 ){ - p->packet[p->found] = buf[c]; - c++; - p->found++; - } - if (p->found == 188){ - p->found = 0; - tfilter(p); - } - - if (c < count) trans_filt(buf+c,count-c,p); -} - - -void tfilter(trans *p) -{ - int l,c; - int tpid; - uint8_t flag,flags; - uint8_t adapt_length = 0; - uint8_t cpid[2]; - - - // fprintf(stderr,"tfilter\n"); - - cpid[0] = p->packet[1]; - cpid[1] = p->packet[2]; - tpid = get_pid(cpid); - - if ( p->packet[1]&0x80){ - fprintf(stderr,"Error in TS for PID: %d\n", - tpid); - } - - flag = cpid[0]; - flags = p->packet[3]; - - if ( flags & ADAPT_FIELD ) { - // adaption field - adapt_length = p->packet[4]; - } - - c = 5 + adapt_length - (int)(!(flags & ADAPT_FIELD)); - if (flags & PAYLOAD){ - for ( l = 0; l < MAXFILT ; l++){ - if ( filt_is_set(p,l) ) { - if ( p->pid[l] == tpid) { - if ( pes_is_set(p,l) ){ - if (cpid[0] & PAY_START){ - p->pes_started |= - (tflags) - (1 << l); - p->pes_start |= - (tflags) - (1 << l); - } else { - p->pes_start &= ~ - ((tflags) - (1 << l)); - } - pes_filter(p,l,c); - } else { - sec_filter(p,l,c); - } - } - } - } - } -} - - -void pes_filter(trans *p, int filtn, int off) -{ - int count,c; - uint8_t *buf; - - if (filtn < 0 || filtn >= MAXFILT) return; - - count = 188 - off; - c = 188*filtn; - buf = p->packet+off; - if (pes_is_started(p,filtn)){ - p->is_full |= (tflags) (1 << filtn); - memcpy(p->transbuf+c,buf,count); - p->transcount[filtn] = count; - } -} - -section *get_filt_sec(trans *p, int filtn) -{ - section *sec; - - sec = &p->sec[filtn]; - p->is_full &= ~((tflags) (1 << filtn) ); - return sec; -} - -int get_filt_buf(trans *p, int filtn,uint8_t **buf) -{ - *buf = p->transbuf+188*filtn; - p->is_full &= ~((tflags) (1 << filtn) ); - return p->transcount[filtn]; -} - - - - -void sec_filter(trans *p, int filtn, int off) -{ - int i,j; - int error; - int count,c; - uint8_t *buf, *secbuf; - section *sec; - - // fprintf(stderr,"sec_filter\n"); - - if (filtn < 0 || filtn >= MAXFILT) return; - - count = 188 - off; - c = 0; - buf = p->packet+off; - sec = &p->sec[filtn]; - secbuf = sec->payload; - if(!filt_is_ready(p,filtn)){ - p->is_full &= ~((tflags) (1 << filtn) ); - sec->found = 0; - sec->length = 0; - } - - if ( !sec->found ){ - c = buf[c]+1; - if (c >= count) return; - sec->id = buf[c]; - secbuf[0] = buf[c]; - c++; - sec->found++; - sec->length = 0; - } - - while ( c < count && sec->found < 3){ - secbuf[sec->found] = buf[c]; - c++; - sec->found++; - } - if (c == count) return; - - if (!sec->length && sec->found == 3){ - sec->length |= ((secbuf[1] & 0x0F) << 8); - sec->length |= (secbuf[2] & 0xFF); - } - - while ( c < count && sec->found < sec->length+3){ - secbuf[sec->found] = buf[c]; - c++; - sec->found++; - } - - if ( sec->length && sec->found == sec->length+3 ){ - error=0; - for ( i = 0; i < MASKL; i++){ - if (i > 0 ) j=2+i; - else j = 0; - error += (sec->payload[j]&p->mask[MASKL*filtn+i])^ - (p->filt[MASKL*filtn+i]& - p->mask[MASKL*filtn+i]); - } - if (!error){ - p->is_full |= (tflags) (1 << filtn); - } - if (buf[0]+1 < c ) c=count; - } - - if ( c < count ) sec_filter(p, filtn, off); - -} - -#define MULT 1024 - - -void write_ps_headr( ps_packet *p, uint8_t *pts,int fd) -{ - long muxr = 37500; - uint8_t audio_bound = 1; - uint8_t fixed = 0; - uint8_t CSPS = 0; - uint8_t audio_lock = 1; - uint8_t video_lock = 1; - uint8_t video_bound = 1; - uint8_t stream1 = 0XC0; - uint8_t buffer1_scale = 1; - uint32_t buffer1_size = 32; - uint8_t stream2 = 0xE0; - uint8_t buffer2_scale = 1; - uint32_t buffer2_size = 230; - - init_ps(p); - - p->mpeg = 2; -// SCR = 0 - p->scr[0] = 0x44; - p->scr[1] = 0x00; - p->scr[2] = 0x04; - p->scr[3] = 0x00; - p->scr[4] = 0x04; - p->scr[5] = 0x01; - -// SCR = PTS - p->scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03); - p->scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F); - p->scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08) - | ((pts[2] >> 5)&0x03); - p->scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07); - p->scr[4] = 0x04 | ((pts[3] << 3)&0xF8); - p->scr[5] = 0x01; - - p->mux_rate[0] = (uint8_t)(muxr >> 14); - p->mux_rate[1] = (uint8_t)(0xff & (muxr >> 6)); - p->mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2)); - - p->stuff_length = 0xF8; - - p->sheader_llength[0] = 0x00; - p->sheader_llength[1] = 0x0c; - - setl_ps(p); - - p->rate_bound[0] = (uint8_t)(0x80 | (muxr >>15)); - p->rate_bound[1] = (uint8_t)(0xff & (muxr >> 7)); - p->rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1)); - - - p->audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS); - p->video_bound = (uint8_t)((audio_lock << 7)| - (video_lock << 6)|0x20|video_bound); - p->reserved = (uint8_t)(0xFF); - - p->data[0] = stream2; - p->data[1] = (uint8_t) (0xc0 | (buffer2_scale << 5) | - (buffer2_size >> 8)); - p->data[2] = (uint8_t) (buffer2_size & 0xff); - p->data[3] = stream1; - p->data[4] = (uint8_t) (0xc0 | (buffer1_scale << 5) | - (buffer1_size >> 8)); - p->data[5] = (uint8_t) (buffer1_size & 0xff); - - write_ps(fd, p); - kill_ps(p); -} - - - -void twrite(uint8_t const *buf) -{ - int l = TS_SIZE; - int c = 0; - int w; - - - while (l){ - w = write(STDOUT_FILENO,buf+c,l); - if (w>=0){ - l-=w; - c+=w; - } - } -} - -void init_p2t(p2t_t *p, void (*fkt)(uint8_t const *buf)) -{ - memset(p->pes,0,TS_SIZE); - p->counter = 0; - p->pos = 0; - p->frags = 0; - if (fkt) p->t_out = fkt; - else p->t_out = twrite; -} - -void clear_p2t(p2t_t *p) -{ - memset(p->pes,0,TS_SIZE); - p->counter = 0; - p->pos = 0; - p->frags = 0; -} - - -long int find_pes_header(uint8_t const *buf, long int length, int *frags) -{ - int c = 0; - int found = 0; - - *frags = 0; - - while (c < length-3 && !found) { - if (buf[c] == 0x00 && buf[c+1] == 0x00 && - buf[c+2] == 0x01) { - switch ( buf[c+3] ) { - case 0xBA: - 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: - c++; - break; - } - } else c++; - } - if (c == length-3 && !found){ - if (buf[length-1] == 0x00) *frags = 1; - if (buf[length-2] == 0x00 && - buf[length-1] == 0x00) *frags = 2; - if (buf[length-3] == 0x00 && - buf[length-2] == 0x00 && - buf[length-1] == 0x01) *frags = 3; - return -1; - } - - return c; -} - -void pes_to_ts( uint8_t const *buf, long int length, uint16_t pid, p2t_t *p) -{ - int c,c2,l,add; - int check,rest; - - c = 0; - c2 = 0; - if (p->frags){ - check = 0; - switch(p->frags){ - case 1: - if ( buf[c] == 0x00 && buf[c+1] == 0x01 ){ - check = 1; - c += 2; - } - break; - case 2: - if ( buf[c] == 0x01 ){ - check = 1; - c++; - } - break; - case 3: - check = 1; - } - if(check){ - switch ( buf[c] ) { - - 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: - p->pes[0] = 0x00; - p->pes[1] = 0x00; - p->pes[2] = 0x01; - p->pes[3] = buf[c]; - p->pos=4; - memcpy(p->pes+p->pos,buf+c,TS_SIZE-4-p->pos); - c += TS_SIZE-4-p->pos; - p_to_t(p->pes,TS_SIZE-4,pid,&p->counter, - p->t_out); - clear_p2t(p); - break; - - default: - c=0; - break; - } - } - p->frags = 0; - } - - if (p->pos){ - c2 = find_pes_header(buf+c,length-c,&p->frags); - if (c2 >= 0 && c2 < TS_SIZE-4-p->pos){ - l = c2+c; - } else l = TS_SIZE-4-p->pos; - memcpy(p->pes+p->pos,buf,l); - c += l; - p->pos += l; - p_to_t(p->pes,p->pos,pid,&p->counter, - p->t_out); - clear_p2t(p); - } - - add = 0; - while (c < length){ - c2 = find_pes_header(buf+c+add,length-c-add,&p->frags); - if (c2 >= 0) { - c2 += c+add; - if (c2 > c){ - p_to_t(buf+c,c2-c,pid,&p->counter, - p->t_out); - c = c2; - clear_p2t(p); - add = 0; - } else add = 1; - } else { - l = length-c; - rest = l % (TS_SIZE-4); - l -= rest; - p_to_t(buf+c,l,pid,&p->counter, - p->t_out); - memcpy(p->pes,buf+c+l,rest); - p->pos = rest; - c = length; - } - } -} - - - -void p_to_t( uint8_t const *buf, long int length, uint16_t pid, uint8_t *counter, - void (*ts_write)(uint8_t const *)) -{ - - int l, pes_start; - uint8_t obuf[TS_SIZE]; - long int c = 0; - pes_start = 0; - if ( length > 3 && - buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 ) - switch (buf[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: - pes_start = 1; - break; - - default: - break; - } - - while ( c < length ){ - memset(obuf,0,TS_SIZE); - if (length - c >= TS_SIZE-4){ - l = write_ts_header(pid, counter, pes_start - , obuf, TS_SIZE-4); - memcpy(obuf+l, buf+c, TS_SIZE-l); - c += TS_SIZE-l; - } else { - l = write_ts_header(pid, counter, pes_start - , obuf, length-c); - memcpy(obuf+l, buf+c, TS_SIZE-l); - c = length; - } - ts_write(obuf); - pes_start = 0; - } -} - - -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) -{ - ps_packet p; - uint8_t *pts; - long lpts; - init_ps(&p); - - lpts = htonl(SCR); - pts = (uint8_t *) &lpts; - - - p.mpeg = 2; -// SCR = 0 - p.scr[0] = 0x44; - p.scr[1] = 0x00; - p.scr[2] = 0x04; - p.scr[3] = 0x00; - p.scr[4] = 0x04; - p.scr[5] = 0x01; - -// SCR = PTS - p.scr[0] = 0x44 | ((pts[0] >> 3)&0x18) | ((pts[0] >> 4)&0x03); - p.scr[1] = 0x00 | ((pts[0] << 4)&0xF0) | ((pts[1] >> 4)&0x0F); - p.scr[2] = 0x04 | ((pts[1] << 4)&0xF0) | ((pts[2] >> 4)&0x08) - | ((pts[2] >> 5)&0x03); - p.scr[3] = 0x00 | ((pts[2] << 3)&0xF8) | ((pts[3] >> 5)&0x07); - p.scr[4] = 0x04 | ((pts[3] << 3)&0xF8); - p.scr[5] = 0x01; - - p.mux_rate[0] = (uint8_t)(muxr >> 14); - p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6)); - p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2)); - - p.stuff_length = 0xF8; - - if (stream1 && stream2){ - p.sheader_llength[0] = 0x00; - p.sheader_llength[1] = 0x0c; - - setl_ps(&p); - - p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15)); - p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7)); - p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1)); - - - p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS); - p.video_bound = (uint8_t)((audio_lock << 7)| - (video_lock << 6)|0x20|video_bound); - p.reserved = (uint8_t)(0xFF >> 1); - - p.data[0] = stream2; - p.data[1] = (uint8_t) (0xc0 | (buffer2_scale << 5) | - (buffer2_size >> 8)); - p.data[2] = (uint8_t) (buffer2_size & 0xff); - p.data[3] = stream1; - p.data[4] = (uint8_t) (0xc0 | (buffer1_scale << 5) | - (buffer1_size >> 8)); - p.data[5] = (uint8_t) (buffer1_size & 0xff); - - cwrite_ps(buf, &p, PS_HEADER_L2); - kill_ps(&p); - return PS_HEADER_L2; - } else { - cwrite_ps(buf, &p, PS_HEADER_L1); - kill_ps(&p); - return PS_HEADER_L1; - } -} - - - -#define MAX_BASE 80 -#define MAX_PATH 256 -#define MAX_EXT 10 - -int break_up_filename(char *name, char *base_name, char *path, char *ext) -{ - int l,i,sstop,sstart; - - l = strlen(name); - sstop = l; - sstart = -1; - for( i= l-1; i >= 0; i--){ - if (sstop == l && name[i] == '.') sstop = i; - if (sstart<0 && name[i] == '/') sstart = i+1; - } - if (sstart < 0) sstart = 0; - if (sstop-sstart < MAX_BASE){ - strncpy(base_name, name+sstart, sstop-sstart); - base_name[sstop-sstart]=0; - if(sstart > 0){ - if( l - sstop + sstart < MAX_PATH){ - strncpy(path, name, sstart); - path[sstart] = 0; - } else { - fprintf(stderr,"PATH too long\n"); - return -1; - } - - } else { - strcpy(path, "./"); - } - - if(sstop < l){ - if( l - sstop -1 < MAX_EXT){ - strncpy(ext, name+sstop+1, l-sstop-1); - ext[l-sstop-1]=0; - } else { - fprintf(stderr,"Extension too long\n"); - return -1; - } - - } else { - strcpy(ext, ""); - } - - } else { - fprintf(stderr,"Name too long\n"); - return -1; - } -/* - printf("%d %d\n",sstart, sstop); - printf("%s %d\n",name, strlen(name)); - printf("%s %d\n",base_name, strlen(base_name)); - printf("%s %d\n",path,strlen(path)); - printf("%s %d\n",ext,strlen(ext)); -*/ - return 0; -} - - -int seek_mpg_start(uint8_t *buf, int size) -{ - int found = 0; - int c=0; - int seq = 0; - int mpeg = 0; - int mark = 0; - - while ( !seq ){ - while (found != 4){ - switch (found) { - case 0: - if ( buf[c] == 0x00 ) found++; - c++; - break; - case 1: - if ( buf[c] == 0x00 ) found++; - else found = 0; - c++; - break; - case 2: - if ( buf[c] == 0x01 ) found++; - else found = 0; - if ( buf[c] == 0x00 ) found = 2; - c++; - break; - - case 3: - if ( (buf[c] & 0xe0) == 0xe0 ) found++; - else found = 0; - c++; - break; - } - if (c >= size) return -1; - } - - if (found == 4){ - mark = c-4; - c+=2; - if (c >= size) return -1; - - if ( (buf[c] & 0xC0) == 0x80 ){ - mpeg = 2; - c += 2; - if (c >= size) return -1; - c += buf[c]+1; - if (c >= size) return -1; - } else { - mpeg = 1; - while( buf[c] == 0xFF ) { - c++; - if (c >= size) return -1; - } - if ( (buf[c] & 0xC0) == 0x40) c+=2; - if (c >= size) return -1; - if ( (buf[c] & 0x30) ){ - if ( (buf[c] & 0x30) == 0x20) c+=5; - else c+=10; - } else c++; - if (c >= size) return -1; - } - - if ( buf[c] == 0x00 && - buf[c+1] == 0x00 && - buf[c+2] == 0x01 && - buf[c+3] == 0xB3 ) - seq = 1; - } - found = 0; - } - - return size-mark; -} - - -void write_mpg(int fstart, uint64_t length, int fdin, int fdout) -{ -// uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 }; - uint8_t *buf; - uint64_t l=0; - uint64_t count = 0; - struct stat sb; - int buf_size; - - fstat (fdout, &sb); - buf_size = sb.st_blksize; - - buf = (char *) alloca (buf_size + sizeof (int)); - - lseek(fdin, fstart, SEEK_SET); - - while ( count < length && (l = read(fdin,buf,buf_size)) >= 0){ - if (l > 0) count+=l; - write(fdout,buf,l); - printf("written %02.2f%%\r",(100.*count)/length); - } - printf("\n"); - - //write( fdout, mpeg_end, 4); -} - - -#define CHECKBUF (1024*1024) -#define ONE_GIG (1024UL*1024UL*1024UL) -void split_mpg(char *name, uint64_t size) -{ - char base_name[MAX_BASE]; - char path[MAX_PATH]; - char ext[MAX_EXT]; - char new_name[256]; - uint8_t buf[CHECKBUF]; - int fdin; - int fdout; - uint64_t length = 0; - uint64_t last; - int i; - int mark, csize; - struct stat sb; - - if (break_up_filename(name,base_name,path,ext) < 0) exit(1); - - - if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){ - fprintf(stderr,"Can't open %s\n",name); - exit(1); - } - - fstat (fdin, &sb); - - length = sb.st_size; - if ( length < ONE_GIG ) - printf("Filelength = %2.2f MB\n", length/1024./1024.); - else - printf("Filelength = %2.2f GB\n", length/1024./1024./1024.); - - if ( length < size ) length = size; - - printf("Splitting %s into Files with size <= %2.2f MB\n",name, - size/1024./1024.); - - csize = CHECKBUF; - read(fdin, buf, csize); - if ( (mark = seek_mpg_start(buf,csize)) < 0){ - fprintf(stderr,"Couldn't find sequence header\n"); - exit(1); - } - - last = csize-mark; - - for ( i = 0 ; i < length/size; i++){ - csize = CHECKBUF; - - if (csize > length-last) csize = length-last; - lseek(fdin, last+size-csize, SEEK_SET); - read(fdin, buf, csize); - if ( (mark = seek_mpg_start(buf,csize)) < 0){ - fprintf(stderr,"Couldn't find sequence header\n"); - exit(1); - } - - sprintf(new_name,"%s-%03d.%s",base_name,i,ext); - printf("writing %s\n",new_name); - - if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC - |O_LARGEFILE, - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP| - S_IROTH|S_IWOTH)) < 0){ - fprintf(stderr,"Can't open %s\n",new_name); - exit(1); - } - write_mpg(last, size-mark, fdin, fdout); - last = last + size - mark; - } - sprintf(new_name,"%s-%03d.%s",base_name,i,ext); - printf("writing %s\n",new_name); - - if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC - |O_LARGEFILE, - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP| - S_IROTH|S_IWOTH)) < 0){ - fprintf(stderr,"Can't open %s\n",new_name); - exit(1); - } - write_mpg(last, length-last, fdin, fdout); -} - - - - -void cut_mpg(char *name, uint64_t size) -{ - char base_name[MAX_BASE]; - char path[MAX_PATH]; - char ext[MAX_EXT]; - char new_name[256]; - uint8_t buf[CHECKBUF]; - int fdin; - int fdout; - uint64_t length = 0; - uint64_t last; - int mark, csize; - struct stat sb; - - if (break_up_filename(name,base_name,path,ext) < 0) exit(1); - - - if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){ - fprintf(stderr,"Can't open %s\n",name); - exit(1); - } - - fstat (fdin, &sb); - - length = sb.st_size; - if ( length < ONE_GIG ) - printf("Filelength = %2.2f MB\n", length/1024./1024.); - else - printf("Filelength = %2.2f GB\n", length/1024./1024./1024.); - - if ( length < size ) length = size; - - printf("Splitting %s into 2 Files with length %.2f MB and %.2f MB\n", - name, size/1024./1024., (length-size)/1024./1024.); - - csize = CHECKBUF; - read(fdin, buf, csize); - if ( (mark = seek_mpg_start(buf,csize)) < 0){ - fprintf(stderr,"Couldn't find sequence header\n"); - exit(1); - } - - last = csize-mark; - - if (csize > length-last) csize = length-last; - lseek(fdin, last+size-csize, SEEK_SET); - read(fdin, buf, csize); - if ( (mark = seek_mpg_start(buf,csize)) < 0){ - fprintf(stderr,"Couldn't find sequence header\n"); - exit(1); - } - - sprintf(new_name,"%s-1.%s",base_name,ext); - printf("writing %s\n",new_name); - - if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC - |O_LARGEFILE, - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP| - S_IROTH|S_IWOTH)) < 0){ - fprintf(stderr,"Can't open %s\n",new_name); - exit(1); - } - write_mpg(last, size-mark, fdin, fdout); - last = last + size - mark; - - sprintf(new_name,"%s-2.%s",base_name,ext); - printf("writing %s\n",new_name); - - if ( (fdout = open(new_name,O_WRONLY|O_CREAT|O_TRUNC - |O_LARGEFILE, - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP| - S_IROTH|S_IWOTH)) < 0){ - fprintf(stderr,"Can't open %s\n",new_name); - exit(1); - } - write_mpg(last, length-last, fdin, fdout); -} - - - - -void write_all (int fd, uint8_t *data, int length) -{ - int r; - - while (length) { - if ((r = write(fd, data, length)) > 0) { - data += r; - length -= r; - } - } -} - - - -void read_all (int fd, uint8_t *data, int length) -{ - int c = 0; - - while(1) { - if( read(fd, data+c, 1) == 1) { - c++; - if(data[c-1] == '\n') { - data[c] = 0; - break; - } - } - else { - fprintf (stderr, "Error reading socket\n"); - exit(1); - } - } -} - - - -char *url2host (uint8_t *url, char **name, uint32_t *ip, uint32_t *port) -{ - uint8_t *murl; - struct hostent *hoste; - struct in_addr haddr; - int found_ip = 1; - - if (!(strncmp(url, "http://", 7))) - url += 7; - - *name = strdup(url); - if (!(*name)) { - *name = NULL; - return (NULL); - } - - murl = url; - while (*murl && *murl != ':' && *murl != '/') { - if ((*murl < '0' || *murl > '9') && *murl != '.') - found_ip = 0; - murl++; - } - - (*name)[murl - url] = 0; - if (found_ip) { - if ((*ip = inet_addr(*name)) == INADDR_NONE) - return (NULL); - } else { - if (!(hoste = gethostbyname(*name))) - return (NULL); - memcpy (&haddr, hoste->h_addr, sizeof(haddr)); - *ip = haddr.s_addr; - } - - if (!*murl || *murl == '/') { - *port = 80; - return (murl); - } - *port = atoi(++murl); - - while (*murl && *murl != '/') - murl++; - return (murl); -} - -#define ACCEPT "Accept: video/mpeg, video/x-mpegurl, */*\r\n" - -int http_open (char *url) -{ - char purl[1024], *host, req[1024], *sptr; - uint32_t ip; - uint32_t port; - int sock; - int reloc, relocnum = 0; - struct sockaddr_in server; - int mfd; - - strncpy (purl, url, 1023); - purl[1023] = '\0'; - - do { - host = NULL; - strcpy (req, "GET "); - if (!(sptr = url2host(purl, &host, &ip, &port))) { - fprintf (stderr, "Unknown host\n"); - exit (1); - } - strcat (req, sptr); - sprintf (req + strlen(req), - " HTTP/1.0\r\nUser-Agent: %s/%s\r\n", - "whatever", "you want"); - if (host) { - sprintf(req + strlen(req), - "Host: %s:%u\r\n", host, port); - free (host); - } - - strcat (req, ACCEPT); - strcat (req, "\r\n"); - - server.sin_port = htons(port); - server.sin_family = AF_INET; - server.sin_addr.s_addr = ip; - - if ((sock = socket(PF_INET, SOCK_STREAM, 6)) < 0) { - perror ("socket"); - exit (1); - } - - if (connect(sock, (struct sockaddr *)&server, - sizeof(server))) { - perror ("connect"); - exit (1); - } - - write_all (sock, req, strlen(req)); - if (!(mfd = fileno(fdopen(sock, "rb")))) { - perror ("open"); - exit (1); - } - reloc = 0; - purl[0] = '\0'; - read_all (mfd, req, 1023); - if ((sptr = strchr(req, ' '))) { - switch (sptr[1]) { - case '2': - break; - case '3': - reloc = 1; - default: - fprintf (stderr, "HTTP req failed:%s", - sptr+1); - exit (1); - } - } - do { - read_all (mfd,req, 1023); - if (!strncmp(req, "Location:", 9)) - strncpy (purl, req+10, 1023); - } while (req[0] != '\r' && req[0] != '\n'); - } while (reloc && purl[0] && relocnum++ < 3); - if (reloc) { - fprintf (stderr, "Too many HTTP relocations.\n"); - exit (1); - } - - return sock; -} - -extern int errno; -const char * strerrno (void) -{ - return strerror(errno); -} diff --git a/libdvbmpeg/ctools.h b/libdvbmpeg/ctools.h deleted file mode 100644 index a7b0271..0000000 --- a/libdvbmpeg/ctools.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#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_*/ diff --git a/libdvbmpeg/devices.hh b/libdvbmpeg/devices.hh deleted file mode 100644 index 02c62cd..0000000 --- a/libdvbmpeg/devices.hh +++ /dev/null @@ -1,310 +0,0 @@ -#ifndef _channel_hh -#define _channel_hh - -using namespace std; -#include - -#include -#include -#include - -#include -#include -#include - -#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*/ diff --git a/libdvbmpeg/osd.hh b/libdvbmpeg/osd.hh deleted file mode 100644 index 9c6b530..0000000 --- a/libdvbmpeg/osd.hh +++ /dev/null @@ -1,84 +0,0 @@ -#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 diff --git a/libdvbmpeg/remux.c b/libdvbmpeg/remux.c deleted file mode 100644 index 6f8a44f..0000000 --- a/libdvbmpeg/remux.c +++ /dev/null @@ -1,1215 +0,0 @@ -/* - * 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 "remux.h" - -unsigned int bitrates[3][16] = -{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, - {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, - {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; - -uint32_t freq[4] = {441, 480, 320, 0}; -static uint32_t samples[4] = { 384, 1152, 0, 0}; -char *frames[3] = {"I-Frame","P-Frame","B-Frame"}; - - -void copy_ptslm(PTS_List *a, PTS_List *b) -{ - a->pos = b->pos; - a->PTS = b->PTS; - a->dts = b->dts; - a->spos = b->spos; -} - -void clear_ptslm(PTS_List *a) -{ - a->pos = 0; - a->PTS = 0; - a->dts = 0; - a->spos = 0; -} - -void init_ptsl(PTS_List *ptsl) -{ - int i; - for (i=0;i< MAX_PTS;i++){ - clear_ptslm(&ptsl[i]); - } -} - -int del_pts(PTS_List *ptsl, int pos, int nr) -{ - int i; - int del = 0; - - for( i = 0; i < nr-1; i++){ - if(pos > ptsl[i].pos && pos >= ptsl[i+1].pos) del++; - } - - if(del) - for( i = 0; i < nr-del; i++){ - copy_ptslm(&ptsl[i], &ptsl[i+del]); - } - - return nr-del; -} - -int del_ptss(PTS_List *ptsl, int pts, int *nb) -{ - int i; - int del = 0; - int sum = 0; - int nr = *nb; - - for( i = 0; i < nr; i++){ - if(pts > ptsl[i].PTS){ - del++; - sum += ptsl[i].pos; - } - } - - if(del) - for( i = 0; i < nr-del; i++){ - copy_ptslm(&ptsl[i], &ptsl[i+del]); - } - - *nb = nr-del; - return sum; -} - -int add_pts(PTS_List *ptsl, uint32_t pts, int pos, int spos, int nr, uint32_t dts) -{ - int i; - - for ( i=0;i < nr; i++) if (spos && ptsl[i].pos == pos) return nr; - if (nr == MAX_PTS) { - nr = del_pts(ptsl, ptsl[1].pos+1, nr); - } else nr++; - i = nr-1; - - ptsl[i].pos = pos; - ptsl[i].spos = spos; - ptsl[i].PTS = pts; - ptsl[i].dts = dts; - return nr; -} - -void add_vpts(Remux *rem, uint8_t *pts) -{ - uint32_t PTS = trans_pts_dts(pts); - rem->vptsn = add_pts(rem->vpts_list, PTS, rem->vwrite, rem->awrite, - rem->vptsn, PTS); -} - -void add_apts(Remux *rem, uint8_t *pts) -{ - uint32_t PTS = trans_pts_dts(pts); - rem->aptsn = add_pts(rem->apts_list, PTS, rem->awrite, rem->vwrite, - rem->aptsn, PTS); -} - -void del_vpts(Remux *rem) -{ - rem->vptsn = del_pts(rem->vpts_list, rem->vread, rem->vptsn); -} - -void del_apts(Remux *rem) -{ - rem->aptsn = del_pts(rem->apts_list, rem->aread, rem->aptsn); -} - - -void copy_framelm(FRAME_List *a, FRAME_List *b) -{ - a->type = b->type; - a->pos = b->pos; - a->FRAME = b->FRAME; - a->time = b->time; - a->pts = b->pts; - a->dts = b->dts; -} - -void clear_framelm(FRAME_List *a) -{ - a->type = 0; - a->pos = 0; - a->FRAME = 0; - a->time = 0; - a->pts = 0; - a->dts = 0; -} - -void init_framel(FRAME_List *framel) -{ - int i; - for (i=0;i< MAX_FRAME;i++){ - clear_framelm(&framel[i]); - } -} - -int del_frame(FRAME_List *framel, int pos, int nr) -{ - int i; - int del = 0; - - for( i = 0; i < nr-1; i++){ - if(pos > framel[i].pos && pos >= framel[i+1].pos) del++; - } - - if(del) - for( i = 0; i < nr-del; i++){ - copy_framelm(&framel[i], &framel[i+del]); - } - - return nr-del; -} - -int add_frame(FRAME_List *framel, uint32_t frame, int pos, int type, int nr, - uint32_t time, uint32_t pts, uint32_t dts) -{ - int i; - - if (nr == MAX_FRAME) { - nr = del_frame(framel, framel[1].pos+1, nr); - } else nr++; - i = nr-1; - - framel[i].type = type; - framel[i].pos = pos; - framel[i].FRAME = frame; - framel[i].time = time; - framel[i].pts = pts; - framel[i].dts = dts; - return nr; -} - -void add_vframe(Remux *rem, uint32_t frame, long int pos, int type, int time, - uint32_t pts, uint32_t dts) -{ - rem->vframen = add_frame(rem->vframe_list, frame, pos, type, - rem->vframen, time, pts, dts); -} - -void add_aframe(Remux *rem, uint32_t frame, long int pos, uint32_t pts) -{ - rem->aframen = add_frame(rem->aframe_list, frame, pos, 0, - rem->aframen, 0, pts, pts); -} - -void del_vframe(Remux *rem) -{ - rem->vframen = del_frame(rem->vframe_list, rem->vread, rem->vframen); -} - -void del_aframe(Remux *rem) -{ - rem->aframen = del_frame(rem->aframe_list, rem->aread, rem->aframen); -} - - -void printpts(uint32_t pts) -{ - fprintf(stderr,"%2d:%02d:%02d.%03d", - (int)(pts/90000.)/3600, - ((int)(pts/90000.)%3600)/60, - ((int)(pts/90000.)%3600)%60, - (((int)(pts/90.)%3600000)%60000)%1000 - ); -} - - -void find_vframes( Remux *rem, uint8_t *buf, int l) -{ - int c = 0; - int type; - uint32_t time = 0; - int hour; - int min; - int sec; - uint64_t pts=0; - uint64_t dts=0; - uint32_t tempref = 0; - - while ( c < l - 6){ - if (buf[c] == 0x00 && - buf[c+1] == 0x00 && - buf[c+2] == 0x01 && - buf[c+3] == 0xB8) { - c += 4; - hour = (int)((buf[c]>>2)& 0x1F); - min = (int)(((buf[c]<<4)& 0x30)| - ((buf[c+1]>>4)& 0x0F)); - sec = (int)(((buf[c+1]<<3)& 0x38)| - ((buf[c+2]>>5)& 0x07)); - - time = 3600*hour + 60*min + sec; - if ( rem->time_off){ - time = (uint32_t)((uint64_t)time - rem->time_off); - hour = time/3600; - min = (time%3600)/60; - sec = (time%3600)%60; - /* - buf[c] |= (hour & 0x1F) << 2; - buf[c] |= (min & 0x30) >> 4; - buf[c+1] |= (min & 0x0F) << 4; - buf[c+1] |= (sec & 0x38) >> 3; - buf[c+2] |= (sec & 0x07) >> 5;*/ - } - rem->group++; - rem->groupframe = 0; - } - if ( buf[c] == 0x00 && - buf[c+1] == 0x00 && - buf[c+2] == 0x01 && - buf[c+3] == 0x00) { - c += 4; - tempref = (buf[c+1]>>6) & 0x03; - tempref |= buf[c] << 2; - - type = ((buf[c+1]&0x38) >>3); - if ( rem->video_info.framerate){ - pts = ((uint64_t)rem->vframe + tempref + 1 - - rem->groupframe ) * 90000ULL - /rem->video_info.framerate - + rem->vpts_off; - dts = (uint64_t)rem->vframe * 90000ULL/ - rem->video_info.framerate - + rem->vpts_off; - - -fprintf(stderr,"MYPTS:"); -printpts((uint32_t)pts-rem->vpts_off); - fprintf(stderr," REALPTS:"); - printpts(rem->vpts_list[rem->vptsn-1].PTS-rem->vpts_off); - fprintf(stderr," DIFF:"); - printpts(pts-(uint64_t)rem->vpts_list[rem->vptsn-1].PTS); -// fprintf(stderr," DIST: %4d",-rem->vpts_list[rem->vptsn-1].pos+(rem->vwrite+c-4)); - //fprintf(stderr," ERR: %3f",(double)(-rem->vpts_list[rem->vptsn-1].PTS+pts)/(rem->vframe+1)); - fprintf(stderr,"\r"); - - - - rem->vptsn = add_pts(rem->vpts_list,(uint32_t)pts - ,rem->vwrite+c-4, - rem->awrite, - rem->vptsn, - (uint32_t)dts); - - - - } - rem->vframe++; - rem->groupframe++; - add_vframe( rem, rem->vframe, rem->vwrite+c, type, - time, pts, dts); - } else c++; - } -} - -void find_aframes( Remux *rem, uint8_t *buf, int l) -{ - int c = 0; - uint64_t pts = 0; - int sam; - uint32_t fr; - - - while ( c < l - 2){ - if ( buf[c] == 0xFF && - (buf[c+1] & 0xF8) == 0xF8) { - c += 2; - if ( rem->audio_info.layer >= 0){ - sam = samples[3-rem->audio_info.layer]; - fr = freq[rem->audio_info.frequency] ; - - pts = ( (uint64_t)rem->aframe * sam * 900ULL)/fr - + rem->apts_off; - - -fprintf(stderr,"MYPTS:"); -printpts((uint32_t)pts-rem->apts_off); - fprintf(stderr," REALPTS:"); - printpts(rem->apts_list[rem->aptsn-1].PTS-rem->apts_off); - fprintf(stderr," DIFF:"); - printpts((uint32_t)((uint64_t)rem->apts_list[rem->aptsn-1].PTS-pts)); -// fprintf(stderr," DIST: %4d",-rem->apts_list[rem->aptsn-1].pos+(rem->awrite+c-2)); - fprintf(stderr,"\r"); - - rem->aptsn = add_pts(rem->apts_list,(uint32_t)pts - ,rem->awrite+c-2, - rem->vwrite, - rem->aptsn, - (uint32_t)pts); - } - - rem->aframe++; - add_aframe( rem, rem->aframe, rem->awrite+c, pts); - - } else c++; - } -} - -int refill_buffy(Remux *rem) -{ - pes_packet pes; - int count = 0; - int acount, vcount; - ringbuffy *vbuf = &rem->vid_buffy; - ringbuffy *abuf = &rem->aud_buffy; - int fin = rem->fin; - - acount = abuf->size-ring_rest(abuf); - vcount = vbuf->size-ring_rest(vbuf); - - - while ( acount > MAX_PLENGTH && vcount > MAX_PLENGTH && count < 10){ - int neof; - count++; - init_pes(&pes); - if ((neof = read_pes(fin,&pes)) <= 0) return -1; - switch(pes.stream_id){ - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - rem->apes++; - if( rem->audio_info.layer < 0 && - (pes.flags2 & PTS_DTS) ) - add_apts(rem, pes.pts); - find_aframes( rem, pes.pes_pckt_data, pes.length); - ring_write(abuf,(char *)pes.pes_pckt_data,pes.length); - rem->awrite += pes.length; - break; - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - rem->vpes++; - if( !rem->video_info.framerate && - (pes.flags2 & PTS_DTS) ) - add_vpts(rem, pes.pts); - - find_vframes( rem, pes.pes_pckt_data, pes.length); - - ring_write(vbuf,(char *)pes.pes_pckt_data,pes.length); - rem->vwrite += pes.length; - break; - } - acount = abuf->size-ring_rest(abuf); - vcount = vbuf->size-ring_rest(vbuf); - kill_pes(&pes); - } - if (count < 10) return 0; - return 1; -} - -int vring_read( Remux *rem, uint8_t *buf, int l) -{ - int c = 0; - int r = 0; - - if (ring_rest(&rem->vid_buffy) <= l) - r = refill_buffy(rem); - if (r) return -1; - - c = ring_read(&rem->vid_buffy, (char *) buf, l); - rem->vread += c; - del_vpts(rem); - del_vframe(rem); - return c; -} - -int aring_read( Remux *rem, uint8_t *buf, int l) -{ - int c = 0; - int r = 0; - - if (ring_rest(&rem->aud_buffy) <= l) - r = refill_buffy(rem); - if (r) return -1; - - c = ring_read(&rem->aud_buffy, (char *)buf, l); - rem->aread += c; - del_apts(rem); - del_aframe(rem); - return c; -} - -int vring_peek( Remux *rem, uint8_t *buf, int l, long off) -{ - int c = 0; - - if (ring_rest(&rem->vid_buffy) <= l) - refill_buffy(rem); - - c = ring_peek(&rem->vid_buffy, (char *) buf, l, off); - return c; -} - -int aring_peek( Remux *rem, uint8_t *buf, int l, long off) -{ - int c = 0; - - if (ring_rest(&rem->aud_buffy) <= l) - refill_buffy(rem); - - c = ring_peek(&rem->aud_buffy, (char *)buf, l, off); - return c; -} - - -int get_video_info(Remux *rem) -{ - uint8_t buf[12]; - uint8_t *headr; - int found = 0; - int sw; - long off = 0; - int form = -1; - ringbuffy *vid_buffy = &rem->vid_buffy; - VideoInfo *vi = &rem->video_info; - - while (found < 4 && ring_rest(vid_buffy)){ - uint8_t b[3]; - - vring_peek( rem, b, 4, 0); - if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 - && b[3] == 0xb3) found = 4; - else { - off++; - vring_read( rem, b, 1); - } - } - rem->vframe = rem->vframen-1; - - if (! found) return -1; - buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x01; buf[3] = 0xb3; - headr = buf+4; - if(vring_peek(rem, buf, 12, 0) < 12) return -1; - - vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); - vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); - - sw = (int)((headr[3]&0xF0) >> 4) ; - - switch( sw ){ - case 1: - fprintf(stderr,"Videostream: ASPECT: 1:1"); - vi->aspect_ratio = 100; - break; - case 2: - fprintf(stderr,"Videostream: ASPECT: 4:3"); - vi->aspect_ratio = 133; - break; - case 3: - fprintf(stderr,"Videostream: ASPECT: 16:9"); - vi->aspect_ratio = 177; - break; - case 4: - fprintf(stderr,"Videostream: ASPECT: 2.21:1"); - vi->aspect_ratio = 221; - break; - - case 5 ... 15: - fprintf(stderr,"Videostream: ASPECT: reserved"); - vi->aspect_ratio = 0; - break; - - default: - vi->aspect_ratio = 0; - return -1; - } - - fprintf(stderr," Size = %dx%d",vi->horizontal_size,vi->vertical_size); - - sw = (int)(headr[3]&0x0F); - - switch ( sw ) { - case 1: - fprintf(stderr," FRate: 23.976 fps"); - vi->framerate = 24000/1001.; - form = -1; - break; - case 2: - fprintf(stderr," FRate: 24 fps"); - vi->framerate = 24; - form = -1; - break; - case 3: - fprintf(stderr," FRate: 25 fps"); - vi->framerate = 25; - form = VIDEO_MODE_PAL; - break; - case 4: - fprintf(stderr," FRate: 29.97 fps"); - vi->framerate = 30000/1001.; - form = VIDEO_MODE_NTSC; - break; - case 5: - fprintf(stderr," FRate: 30 fps"); - vi->framerate = 30; - form = VIDEO_MODE_NTSC; - break; - case 6: - fprintf(stderr," FRate: 50 fps"); - vi->framerate = 50; - form = VIDEO_MODE_PAL; - break; - case 7: - fprintf(stderr," FRate: 60 fps"); - vi->framerate = 60; - form = VIDEO_MODE_NTSC; - break; - } - - rem->dts_delay = (int)(7.0/vi->framerate/2.0*90000); - - vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) - | ((headr[5] << 2) & 0x000003FCUL) | - (((headr[6] & 0xC0) >> 6) & 0x00000003UL)); - - fprintf(stderr," BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.); - - fprintf(stderr,"\n"); - vi->video_format = form; - - /* - marker_bit (&video_bs, 1); - vi->vbv_buffer_size = getbits (&video_bs, 10); - vi->CSPF = get1bit (&video_bs); - */ - return form; -} - - -int get_audio_info( Remux *rem) -{ - uint8_t *headr; - uint8_t buf[3]; - long off = 0; - int found = 0; - ringbuffy *aud_buffy = &rem->aud_buffy; - AudioInfo *ai = &rem->audio_info; - - while(!ring_rest(aud_buffy) && !refill_buffy(rem)); - while (found < 2 && ring_rest(aud_buffy)){ - uint8_t b[2]; - refill_buffy(rem); - aring_peek( rem, b, 2, 0); - - if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) - found = 2; - else { - off++; - aring_read( rem, b, 1); - } - } - - if (!found) return -1; - rem->aframe = rem->aframen-1; - - if (aring_peek(rem, buf, 3, 0) < 1) return -1; - headr = buf+2; - - ai->layer = (buf[1] & 0x06) >> 1; - - fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer); - - - ai->bit_rate = bitrates[(3-ai->layer)][(headr[0] >> 4 )]*1000; - - if (ai->bit_rate == 0) - fprintf (stderr," Bit rate: free"); - else if (ai->bit_rate == 0xf) - fprintf (stderr," BRate: reserved"); - else - fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000); - - - ai->frequency = (headr[0] & 0x0c ) >> 2; - if (ai->frequency == 3) - fprintf (stderr, " Freq: reserved\n"); - else - fprintf (stderr," Freq: %2.1f kHz\n", - freq[ai->frequency]/10.); - - return 0; -} - - - -void init_remux(Remux *rem, int fin, int fout, int mult) -{ - rem->video_info.framerate = 0; - rem->audio_info.layer = -1; - rem->fin = fin; - rem->fout = fout; - ring_init(&rem->vid_buffy, 40*BUFFYSIZE*mult); - ring_init(&rem->aud_buffy, BUFFYSIZE*mult); - init_ptsl(rem->vpts_list); - init_ptsl(rem->apts_list); - init_framel(rem->vframe_list); - init_framel(rem->aframe_list); - - rem->vptsn = 0; - rem->aptsn = 0; - rem->vframen = 0; - rem->aframen = 0; - rem->vframe = 0; - rem->aframe = 0; - rem->vcframe = 0; - rem->acframe = 0; - rem->vpts = 0; - rem->vdts = 0; - rem->apts_off = 0; - rem->vpts_off = 0; - rem->apts_delay= 0; - rem->vpts_delay= 0; - rem->dts_delay = 0; - rem->apts = 0; - rem->vpes = 0; - rem->apes = 0; - rem->vpts_old = 0; - rem->apts_old = 0; - rem->SCR = 0; - rem->vwrite = 0; - rem->awrite = 0; - rem->vread = 0; - rem->aread = 0; - rem->group = 0; - rem->groupframe= 0; - rem->pack_size = 0; - rem->muxr = 0; - rem->time_off = 0; -} - -uint32_t bytes2pts(int bytes, int rate) -{ - if (bytes < 0xFFFFFFFFUL/720000UL) - return (uint32_t)(bytes*720000UL/rate); - else - return (uint32_t)(bytes/rate*720000UL); -} - -long pts2bytes( uint32_t pts, int rate) -{ - if (pts < 0xEFFFFFFFUL/rate) - return (pts*rate/720000); - else - return (pts* (rate/720000)); -} - -int write_audio_pes( Remux *rem, uint8_t *buf, int *alength) -{ - int add; - int pos = 0; - int p = 0; - uint32_t pts = 0; - int stuff = 0; - int length = *alength; - - if (!length) return 0; - p = PS_HEADER_L1+PES_H_MIN; - - if (rem->apts_old != rem->apts){ - pts = (uint32_t)((uint64_t)rem->apts + rem->apts_delay - rem->apts_off); - p += 5; - } - if ( length+p >= rem->pack_size){ - length = rem->pack_size; - } else { - if (rem->pack_size-length-p <= PES_MIN){ - stuff = rem->pack_size - length; - length = rem->pack_size; - } else - length = length+p; - } - pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0); - - pos += write_pes_header( 0xC0, length-pos, pts, buf+pos, stuff); - add = aring_read( rem, buf+pos, length-pos); - *alength = add; - if (add < 0) return -1; - pos += add; - rem->apts_old = rem->apts; - rem->apts = rem->apts_list[0].PTS; - - if (pos+PES_MIN < rem->pack_size){ - pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0, - buf+pos, 0); - pos = rem->pack_size; - } - if (pos != rem->pack_size) { - fprintf(stderr,"apos: %d\n",pos); - exit(1); - } - - return pos; -} - -int write_video_pes( Remux *rem, uint8_t *buf, int *vlength) -{ - int add; - int pos = 0; - int p = 0; - uint32_t pts = 0; - uint32_t dts = 0; - int stuff = 0; - int length = *vlength; - long diff = 0; - - if (! length) return 0; - p = PS_HEADER_L1+PES_H_MIN; - - if (rem->vpts_old != rem->vpts){ - pts = (uint32_t)((uint64_t)rem->vpts + rem->vpts_delay - rem->vpts_off); - p += 5; - } - if ( length+p >= rem->pack_size){ - length = rem->pack_size; - } else { - if (rem->pack_size - length - p <= PES_MIN){ - stuff = rem->pack_size - length; - length = rem->pack_size; - } else - length = length+p; - } - - pos = write_ps_header(buf,rem->SCR,rem->muxr, 1, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0); - - pos += write_pes_header( 0xE0, length-pos, pts, buf+pos, stuff); - add = vring_read( rem, buf+pos, length-pos); - *vlength = add; - if (add < 0) return -1; - pos += add; - rem->vpts_old = rem->vpts; - dts = rem->vdts; - rem->vpts = rem->vpts_list[0].PTS; - rem->vdts = rem->vpts_list[0].dts; - if ( diff > 0) rem->SCR += diff; - if (pos+PES_MIN < rem->pack_size){ - // fprintf(stderr,"vstuffing: %d \n",rem->pack_size-pos); - pos += write_pes_header( PADDING_STREAM, rem->pack_size-pos, 0, - buf+pos, 0); - pos = rem->pack_size; - } - return pos; -} - -void print_info( Remux *rem , int ret) -{ - int newtime = 0; - static int time = 0; - int i = 0; - - while(! newtime && i < rem->vframen) { - if( (newtime = rem->vframe_list[i].time)) break; - i++; - } - if (newtime) time = newtime; - - fprintf(stderr,"SCR:"); - printpts(rem->SCR); - fprintf(stderr," VDTS:"); - printpts((uint32_t)((uint64_t)rem->vdts - rem->vpts_off + rem->vpts_delay)); - fprintf(stderr," APTS:"); - printpts((uint32_t)((uint64_t)rem->apts - rem->apts_off + rem->apts_delay)); - fprintf(stderr," TIME:%2d:", time/3600); - fprintf(stderr,"%02d:", (time%3600)/60); - fprintf(stderr,"%02d", (time%3600)%60); - if (ret) fprintf(stderr,"\n"); - else fprintf(stderr,"\r"); -} - -void remux(int fin, int fout, int pack_size, int mult) -{ - Remux rem; - long ptsdiff; - uint8_t buf[MAX_PACK_L]; - long pos = 0; - int r = 0; - int i, r1, r2; - long packets = 0; - uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 }; - uint32_t SCR_inc = 0; - int data_size; - long vbuf, abuf; - long vbuf_max, abuf_max; - PTS_List abufl[MAX_PTS]; - PTS_List vbufl[MAX_PTS]; - int abufn = 0; - int vbufn = 0; - uint64_t pts_d = 0; - int ok_audio; - int ok_video; - uint32_t apos = 0; - uint32_t vpos = 0; - int vpack_size = 0; - int apack_size = 0; - - init_ptsl(abufl); - init_ptsl(vbufl); - - if (mult < 0 || mult >1000){ - fprintf(stderr,"Multipler too large\n"); - exit(1); - } - init_remux(&rem, fin, fout, mult); - rem.pack_size = pack_size; - data_size = pack_size - MAX_H_SIZE; - fprintf(stderr,"pack_size: %d header_size: %d data size: %d\n", - pack_size, MAX_H_SIZE, data_size); - refill_buffy(&rem); - fprintf(stderr,"Package size: %d\n",pack_size); - - if ( get_video_info(&rem) < 0 ){ - fprintf(stderr,"ERROR: Can't find valid video stream\n"); - exit(1); - } - - i = 0; - while(! rem.time_off && i < rem.vframen) { - if( (rem.time_off = rem.vframe_list[i].time)) break; - i++; - } - - if ( get_audio_info(&rem) < 0 ){ - fprintf(stderr,"ERROR: Can't find valid audio stream\n"); - exit(1); - } - - rem.vpts = rem.vpts_list[0].PTS; - rem.vdts = rem.vpts; - rem.vpts_off = rem.vpts; - fprintf(stderr,"Video start PTS = %fs \n",rem.vpts_off/90000.); - rem.apts = rem.apts_list[0].PTS; - rem.apts_off = rem.apts; - ptsdiff = rem.vpts - rem.apts; - if (ptsdiff > 0) rem.vpts_off -= ptsdiff; - else rem.apts_off -= -ptsdiff; - fprintf(stderr,"Audio start PTS = %fs\n",rem.apts_off/90000.); - fprintf(stderr,"Difference Video - Audio = %fs\n",ptsdiff/90000.); - fprintf(stderr,"Time offset = %ds\n",rem.time_off); - - rem.muxr = (rem.video_info.bit_rate + - rem.audio_info.bit_rate)/400; - fprintf(stderr,"MUXRATE: %.2f Mb/sec\n",rem.muxr/2500.); - SCR_inc = 1800 * pack_size / rem.muxr; - - r = 0; - while ( rem.vptsn < 2 && !r) r = refill_buffy(&rem); - r = 0; - while ( rem.aptsn < 2 && !r) r = refill_buffy(&rem); - - //rem.vpts_delay = (uint32_t)(2*90000ULL* (uint64_t)pack_size/rem.muxr); - rem.vpts_delay = rem.dts_delay; - rem.apts_delay = rem.vpts_delay; - - vbuf_max = 29440; - abuf_max = 4096; - vbuf = 0; - abuf = 0; - pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, - 0xC0, 0, 32, 0xE0, 1, 230); - pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, buf+pos,0); - pos = rem.pack_size; - write( fout, buf, pos); - - apos = rem.aread; - vpos = rem.vread; - print_info( &rem, 1 ); - - while( ring_rest(&rem.aud_buffy) && ring_rest(&rem.vid_buffy) ){ - uint32_t next_apts; - uint32_t next_vdts; - int asize, vsize; - - r1 = 0; - r2 = 0; - while ( rem.aframen < 2 && !r1) - r1 = refill_buffy(&rem); - while ( rem.vframen < 2 && !r2) - r2 = refill_buffy(&rem); - if (r1 && r2) break; - - if ( !r1 && apos <= rem.aread) - apos = rem.aframe_list[1].pos; - if ( !r2 && vpos <= rem.vread) - vpos = rem.vframe_list[1].pos; - apack_size = apos - rem.aread; - vpack_size = vpos - rem.vread; - - - next_vdts = (uint32_t)((uint64_t)rem.vdts + rem.vpts_delay - - rem.vpts_off) ; - ok_video = ( rem.SCR < next_vdts); - - next_apts = (uint32_t)((uint64_t)rem.apts + rem.apts_delay - - rem.apts_off) ; - ok_audio = ( rem.SCR < next_apts); - - asize = (apack_size > data_size ? data_size: apack_size); - vsize = (vpack_size > data_size ? data_size: vpack_size); - - fprintf(stderr,"vframen: %d aframen: %d v_ok: %d a_ok: %d v_buf: %d a_buf: %d vpacks: %d apacks: %d\n",rem.vframen,rem.aframen, ok_video, ok_audio, (int)vbuf,(int)abuf,vsize, asize); - - - if( vbuf+vsize < vbuf_max && vsize && ok_audio ){ - fprintf(stderr,"1 "); - pos = write_video_pes( &rem, buf, &vpack_size); - write( fout, buf, pos); - vbuf += vpack_size; - vbufn = add_pts( vbufl, rem.vdts, vpack_size, - 0, vbufn, 0); - packets++; - } else if ( abuf+asize < abuf_max && asize && - ok_video ){ - fprintf(stderr,"2 "); - pos = write_audio_pes( &rem, buf, &apack_size); - write( fout, buf, pos); - abuf += apack_size; - abufn = add_pts( abufl, rem.apts, apack_size, - 0, abufn, 0); - packets++; - } else if ( abuf+asize < abuf_max && asize && - !ok_audio){ - fprintf(stderr,"3 "); - pos = write_audio_pes( &rem, buf, &apack_size); - write( fout, buf, pos); - abuf += apack_size; - abufn = add_pts( abufl, rem.apts, apack_size, - 0, abufn, 0); - packets++; - } else if (vbuf+vsize < vbuf_max && vsize && - !ok_video){ - fprintf(stderr,"4 "); - pos = write_video_pes( &rem, buf, &vpack_size); - write( fout, buf, pos); - vbuf += vpack_size; - vbufn = add_pts( vbufl, rem.vdts, vpack_size, - 0, vbufn, 0); - packets++; - } else { - fprintf(stderr,"5 "); - pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, - 1, 1, 1, 0, 0, 0, 0, 0, 0); - - pos += write_pes_header( PADDING_STREAM, pack_size-pos, - 0, buf+pos, 0); - write( fout, buf, pos); - } - - - //fprintf(stderr,"vbufn: %d abufn: %d ", vbufn,abufn); - //fprintf(stderr,"vbuf: %5d abuf: %4d\n", vbuf,abuf); - - if (rem.SCR > rem.vdts+rem.vpts_off -rem.vpts_delay) - rem.SCR = rem.vdts-rem.vpts_off; - rem.SCR = (uint32_t)((uint64_t) rem.SCR + SCR_inc); - - if ( rem.apts_off + rem.SCR < rem.apts_delay ) pts_d = 0; - else pts_d = (uint64_t) rem.SCR + rem.apts_off - rem.apts_delay; - abuf -= del_ptss( abufl, (uint32_t) pts_d, &abufn); - - if ( rem.vpts_off + rem.SCR < rem.vpts_delay ) pts_d = 0; - else pts_d = (uint64_t) rem.SCR + rem.vpts_off - rem.vpts_delay; - vbuf -= del_ptss( vbufl, (uint32_t) pts_d, &vbufn); - - print_info( &rem, 1); - //fprintf(stderr,"vbufn: %d abufn: %d ", vbufn,abufn); - //fprintf(stderr,"vbuf: %5d abuf: %4d\n\n", vbuf,abuf); - - - } - pos = write_ps_header(buf,rem.SCR,rem.muxr, 1, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0); - - pos += write_pes_header( PADDING_STREAM, pack_size-pos-4, 0, - buf+pos, 0); - pos = rem.pack_size-4; - write( fout, buf, pos); - - write( fout, mpeg_end, 4); - fprintf(stderr,"\ndone\n"); -} - - -typedef -struct pes_buffer_s{ - ringbuffy pes_buffy; - uint8_t type; - PTS_List pts_list[MAX_PTS]; - FRAME_List frame_list[MAX_FRAME]; - int pes_size; - uint64_t written; - uint64_t read; -} PESBuffer; - - -void init_PESBuffer(PESBuffer *pbuf, int pes_size, int buf_size, uint8_t type) -{ - init_framel( pbuf->frame_list); - init_ptsl( pbuf->pts_list); - ring_init( &pbuf->pes_buffy, buf_size); - pbuf->pes_size = pes_size; - pbuf->type = type; - pbuf->written = 0; - pbuf->read = 0; -} - - -#define MAX_PBUF 4 - -typedef -struct remux_s{ - PESBuffer pbuf_list[MAX_PBUF]; - int num_pbuf; -} REMUX; - - -void init_REMUX(REMUX *rem) -{ - rem->num_pbuf = 0; -} - - - -#define REPACK 2048 -#define ABUF_SIZE REPACK*1024 -#define VBUF_SIZE REPACK*10240 - -void remux_main(uint8_t *buf, int count, void *pr) -{ - int i, b; - int bufsize = 0; - p2p *p = (p2p *) pr; - PESBuffer *pbuf; - REMUX *rem = (REMUX *) p->data; - uint8_t type = buf[3]; - int *npbuf = &(rem->num_pbuf); - - switch ( type ){ - case PRIVATE_STREAM1: - bufsize = ABUF_SIZE; - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - if (!bufsize) bufsize = VBUF_SIZE; - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - if (!bufsize) bufsize = ABUF_SIZE; - b = -1; - for ( i = 0; i < *npbuf; i++){ - if ( type == rem->pbuf_list[i].type ){ - b = i; - break; - } - } - if (b < 0){ - if ( *npbuf < MAX_PBUF ){ - init_PESBuffer(&rem->pbuf_list[*npbuf], - p->repack+6, bufsize, type); - b = *npbuf; - (*npbuf)++; - } else { - fprintf(stderr,"Not enough PES buffers\n"); - exit(1); - } - } - break; - default: - return; - } - - pbuf = &(rem->pbuf_list[b]); - if (ring_write(&(pbuf->pes_buffy),(char *)buf,count) != count){ - fprintf(stderr,"buffer overflow type 0x%2x\n",type); - exit(1); - } else { - pbuf->written += count; - if ((p->flag2 & PTS_DTS_FLAGS)){ - uint32_t PTS = trans_pts_dts(p->pts); - add_pts(pbuf->pts_list, PTS, pbuf->written, - pbuf->written, 0, 0); - } - p->flag2 = 0; - } - -} - -void output_mux(p2p *p) -{ - int i, filling; - PESBuffer *pbuf; - ringbuffy *pes_buffy; - REMUX *rem = (REMUX *) p->data; - int repack = p->repack; - int npbuf = rem->num_pbuf; - - for ( i = 0; i < npbuf; i++){ - pbuf = &(rem->pbuf_list[i]); - pes_buffy = &pbuf->pes_buffy; - filling = pes_buffy->size - ring_rest(pes_buffy); - if (filling/(2 *repack)){ - pbuf->read += ring_read_file(pes_buffy, p->fd1, - (filling/repack)*repack); - } - } -} - - - -#define SIZE 32768 - -void remux2(int fdin, int fdout) -{ - p2p p; - int count = 1; - uint8_t buf[SIZE]; - uint64_t length = 0; - uint64_t l = 0; - int verb = 0; - REMUX rem; - - init_p2p(&p, remux_main, REPACK); - p.fd1 = fdout; - p.data = (void *) &rem; - - - if (fdin != STDIN_FILENO) verb = 1; - - if (verb) { - length = lseek(fdin, 0, SEEK_END); - lseek(fdin,0,SEEK_SET); - } - - while (count > 0){ - count = read(fdin,buf,SIZE); - l += count; - if (verb) - fprintf(stderr,"Writing %2.2f %%\r", - 100.*l/length); - - get_pes(buf,count,&p,pes_repack); - output_mux(&p); - } - -} diff --git a/libdvbmpeg/remux.h b/libdvbmpeg/remux.h deleted file mode 100644 index 76c128b..0000000 --- a/libdvbmpeg/remux.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include - -#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_*/ diff --git a/libdvbmpeg/ringbuffy.c b/libdvbmpeg/ringbuffy.c deleted file mode 100644 index 8451009..0000000 --- a/libdvbmpeg/ringbuffy.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - 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" - -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; -} diff --git a/libdvbmpeg/ringbuffy.h b/libdvbmpeg/ringbuffy.h deleted file mode 100644 index 16011d7..0000000 --- a/libdvbmpeg/ringbuffy.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - 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 -#include -#include - -#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 */ diff --git a/libdvbmpeg/transform.c b/libdvbmpeg/transform.c deleted file mode 100644 index c53f1fb..0000000 --- a/libdvbmpeg/transform.c +++ /dev/null @@ -1,2681 +0,0 @@ -/* - * 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 marcus@convergence.de, - - * the project's page is at http://linuxtv.org/dvb/ - */ - - -#include "transform.h" -#include -#include -#include "ctools.h" - -static uint8_t tspid0[TS_SIZE] = { - 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xb0, 0x11, - 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0xe0, - 0x10, 0x00, 0x01, 0xe4, 0x00, 0x2a, 0xd6, 0x1a, - 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - -static uint8_t tspid1[TS_SIZE] = { - 0x47, 0x44, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x1c, - 0x00, 0x01, 0xcb, 0x00, 0x00, 0xe0, 0xa0, 0xf0, - 0x05, 0x48, 0x03, 0x01, 0x00, 0x00, 0x02, 0xe0, - 0xa0, 0xf0, 0x00, 0x03, 0xe0, 0x50, 0xf0, 0x00, - 0xae, 0xea, 0x4e, 0x48, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - -// CRC32 lookup table for polynomial 0x04c11db7 -static const uint32_t crc_table[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, - 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - -static uint32_t -calc_crc32 (const uint8_t *sec, uint8_t len) -{ - int i; - uint32_t crc = 0xffffffff; - - for (i = 0; i < len; i++) - crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *sec++) & 0xff]; - - return crc; -} - - -uint64_t trans_pts_dts(uint8_t *pts) -{ - uint64_t wts; - - wts = ((uint64_t)((pts[0] & 0x0E) << 5) | - ((pts[1] & 0xFC) >> 2)) << 24; - wts |= (((pts[1] & 0x03) << 6) | - ((pts[2] & 0xFC) >> 2)) << 16; - wts |= (((pts[2] & 0x02) << 6) | - ((pts[3] & 0xFE) >> 1)) << 8; - wts |= (((pts[3] & 0x01) << 7) | - ((pts[4] & 0xFE) >> 1)); - return wts; -} - - -void get_pespts(uint8_t *av_pts,uint8_t *pts) -{ - - pts[0] = 0x21 | - ((av_pts[0] & 0xC0) >>5); - pts[1] = ((av_pts[0] & 0x3F) << 2) | - ((av_pts[1] & 0xC0) >> 6); - pts[2] = 0x01 | ((av_pts[1] & 0x3F) << 2) | - ((av_pts[2] & 0x80) >> 6); - pts[3] = ((av_pts[2] & 0x7F) << 1) | - ((av_pts[3] & 0x80) >> 7); - pts[4] = 0x01 | ((av_pts[3] & 0x7F) << 1); -} - -uint16_t get_pid(uint8_t *pid) -{ - uint16_t pp = 0; - - pp = (pid[0] & PID_MASK_HI)<<8; - pp |= pid[1]; - - return pp; -} - -int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start, - uint8_t *buf, uint8_t length) -{ - int i; - int c = 0; - int fill; - uint8_t tshead[4] = { 0x47, 0x00, 0x00, 0x10}; - - - fill = TS_SIZE-4-length; - if (pes_start) tshead[1] = 0x40; - if (fill) tshead[3] = 0x30; - tshead[1] |= (uint8_t)((pid & 0x1F00) >> 8); - tshead[2] |= (uint8_t)(pid & 0x00FF); - tshead[3] |= ((*counter)++ & 0x0F) ; - memcpy(buf,tshead,4); - c+=4; - - - if (fill){ - buf[4] = fill-1; - c++; - if (fill >1){ - buf[5] = 0x00; - c++; - } - for ( i = 6; i < fill+4; i++){ - buf[i] = 0xFF; - c++; - } - } - - return c; -} - - -int write_pes_header(uint8_t id,int length , long PTS, uint8_t *obuf, - int stuffing) -{ - uint8_t le[2]; - uint8_t dummy[3]; - uint8_t *pts; - uint8_t ppts[5]; - long lpts; - int c; - uint8_t headr[3] = {0x00, 0x00, 0x01}; - - lpts = htonl(PTS); - pts = (uint8_t *) &lpts; - - get_pespts(pts,ppts); - - c = 0; - memcpy(obuf+c,headr,3); - c += 3; - memcpy(obuf+c,&id,1); - c++; - - le[0] = 0; - le[1] = 0; - length -= 6+stuffing; - - le[0] |= ((uint8_t)(length >> 8) & 0xFF); - le[1] |= ((uint8_t)(length) & 0xFF); - memcpy(obuf+c,le,2); - c += 2; - - if (id == PADDING_STREAM){ - memset(obuf+c,0xff,length); - c+= length; - return c; - } - - dummy[0] = 0x80; - dummy[1] = 0; - dummy[2] = 0; - if (PTS){ - dummy[1] |= PTS_ONLY; - dummy[2] = 5+stuffing; - } - memcpy(obuf+c,dummy,3); - c += 3; - memset(obuf+c,0xFF,stuffing); - - if (PTS){ - memcpy(obuf+c,ppts,5); - c += 5; - } - - return c; -} - - -void init_p2p(p2p *p, void (*func)(uint8_t *buf, int count, void *p), - int repack){ - p->found = 0; - p->cid = 0; - p->mpeg = 0; - memset(p->buf,0,MMAX_PLENGTH); - p->done = 0; - p->fd1 = -1; - p->func = func; - p->bigend_repack = 0; - p->repack = 0; - if ( repack < MAX_PLENGTH && repack > 265 ){ - p->repack = repack-6; - p->bigend_repack = (uint16_t)htons((short) - ((repack-6) & 0xFFFF)); - } else { - fprintf(stderr, "Repack size %d is out of range\n",repack); - exit(1); - } -} - - - -void pes_repack(p2p *p) -{ - int count = 0; - int repack = p->repack; - int rest = p->plength; - uint8_t buf[MAX_PLENGTH]; - int bfill = 0; - int diff; - uint16_t length; - - if (rest < 0) { - fprintf(stderr,"Error in repack\n"); - return; - } - - if (!repack){ - fprintf(stderr,"forgot to set repack size\n"); - return; - } - - if (p->plength == repack){ - memcpy(p->buf+4,(char *)&p->bigend_repack,2); - p->func(p->buf, repack+6, p); - return; - } - - buf[0] = 0x00; - buf[1] = 0x00; - buf[2] = 0x01; - buf[3] = p->cid; - memcpy(buf+4,(char *)&p->bigend_repack,2); - memset(buf+6,0,MAX_PLENGTH-6); - - if (p->mpeg == 2){ - - if ( rest > repack){ - memcpy(p->buf+4,(char *)&p->bigend_repack,2); - p->func(p->buf, repack+6, p); - count += repack+6; - rest -= repack; - } else { - memcpy(buf,p->buf,9+p->hlength); - bfill = p->hlength; - count += 9+p->hlength; - rest -= p->hlength+3; - } - - while (rest >= repack-3){ - memset(buf+6,0,MAX_PLENGTH-6); - buf[6] = 0x80; - buf[7] = 0x00; - buf[8] = 0x00; - memcpy(buf+9,p->buf+count,repack-3); - rest -= repack-3; - count += repack-3; - p->func(buf, repack+6, p); - } - - if (rest){ - diff = repack - 3 - rest - bfill; - if (!bfill){ - buf[6] = 0x80; - buf[7] = 0x00; - buf[8] = 0x00; - } - - if ( diff < PES_MIN){ - length = rest+ diff + bfill+3; - buf[4] = (uint8_t)((length & 0xFF00) >> 8); - buf[5] = (uint8_t)(length & 0x00FF); - buf[8] = (uint8_t)(bfill+diff); - memset(buf+9+bfill,0xFF,diff); - memcpy(buf+9+bfill+diff,p->buf+count,rest); - } else { - length = rest+ bfill+3; - buf[4] = (uint8_t)((length & 0xFF00) >> 8); - buf[5] = (uint8_t)(length & 0x00FF); - memcpy(buf+9+bfill,p->buf+count,rest); - bfill += rest+9; - write_pes_header( PADDING_STREAM, diff, 0, - buf+bfill, 0); - } - p->func(buf, repack+6, p); - } - } - - if (p->mpeg == 1){ - - if ( rest > repack){ - memcpy(p->buf+4,(char *)&p->bigend_repack,2); - p->func(p->buf, repack+6, p); - count += repack+6; - rest -= repack; - } else { - memcpy(buf,p->buf,6+p->hlength); - bfill = p->hlength; - count += 6; - rest -= p->hlength; - } - - while (rest >= repack-1){ - memset(buf+6,0,MAX_PLENGTH-6); - buf[6] = 0x0F; - memcpy(buf+7,p->buf+count,repack-1); - rest -= repack-1; - count += repack-1; - p->func(buf, repack+6, p); - } - - - if (rest){ - diff = repack - 1 - rest - bfill; - - if ( diff < PES_MIN){ - length = rest+ diff + bfill+1; - buf[4] = (uint8_t)((length & 0xFF00) >> 8); - buf[5] = (uint8_t)(length & 0x00FF); - memset(buf+6,0xFF,diff); - if (!bfill){ - buf[6+diff] = 0x0F; - } - memcpy(buf+7+diff,p->buf+count,rest+bfill); - } else { - length = rest+ bfill+1; - buf[4] = (uint8_t)((length & 0xFF00) >> 8); - buf[5] = (uint8_t)(length & 0x00FF); - if (!bfill){ - buf[6] = 0x0F; - memcpy(buf+7,p->buf+count,rest); - bfill = rest+7; - } else { - memcpy(buf+6,p->buf+count,rest+bfill); - bfill += rest+6; - } - write_pes_header( PADDING_STREAM, diff, 0, - buf+bfill, 0); - } - p->func(buf, repack+6, p); - } - } -} - - - - - - - - -int filter_pes (uint8_t *buf, int count, p2p *p, int (*func)(p2p *p)) -{ - - int l; - unsigned short *pl; - int c=0; - int ret = 1; - - uint8_t headr[3] = { 0x00, 0x00, 0x01} ; - - while (c < count && (p->mpeg == 0 || - (p->mpeg == 1 && p->found < 7) || - (p->mpeg == 2 && p->found < 9)) - && (p->found < 5 || !p->done)){ - switch ( p->found ){ - case 0: - case 1: - if (buf[c] == 0x00) p->found++; - else { - if (p->fd1 >= 0) - write(p->fd1,buf+c,1); - p->found = 0; - } - c++; - break; - case 2: - if (buf[c] == 0x01) p->found++; - else if (buf[c] == 0){ - p->found = 2; - } else { - if (p->fd1 >= 0) - write(p->fd1,buf+c,1); - p->found = 0; - } - c++; - break; - case 3: - p->cid = 0; - switch (buf[c]){ - 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: - if (p->fd1 >= 0) - write(p->fd1,buf+c,1); - p->done = 1; - case PRIVATE_STREAM1: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - p->found++; - p->cid = buf[c]; - c++; - break; - default: - if (p->fd1 >= 0) - write(p->fd1,buf+c,1); - p->found = 0; - break; - } - break; - - - case 4: - if (count-c > 1){ - pl = (unsigned short *) (buf+c); - p->plength = ntohs(*pl); - p->plen[0] = buf[c]; - c++; - p->plen[1] = buf[c]; - c++; - p->found+=2; - } else { - p->plen[0] = buf[c]; - p->found++; - return 1; - } - break; - case 5: - p->plen[1] = buf[c]; - c++; - pl = (unsigned short *) p->plen; - p->plength = ntohs(*pl); - p->found++; - break; - - - case 6: - if (!p->done){ - p->flag1 = buf[c]; - c++; - p->found++; - if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; - else { - p->hlength = 0; - p->which = 0; - p->mpeg = 1; - p->flag2 = 0; - } - } - break; - - case 7: - if ( !p->done && p->mpeg == 2){ - p->flag2 = buf[c]; - c++; - p->found++; - } - break; - - case 8: - if ( !p->done && p->mpeg == 2){ - p->hlength = buf[c]; - c++; - p->found++; - } - break; - - default: - - break; - } - } - - if (!p->plength) p->plength = MMAX_PLENGTH-6; - - - if ( p->done || ((p->mpeg == 2 && p->found >= 9) || - (p->mpeg == 1 && p->found >= 7)) ){ - switch (p->cid){ - - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case PRIVATE_STREAM1: - - memcpy(p->buf, headr, 3); - p->buf[3] = p->cid; - memcpy(p->buf+4,p->plen,2); - - if (p->mpeg == 2 && p->found == 9){ - p->buf[6] = p->flag1; - p->buf[7] = p->flag2; - p->buf[8] = p->hlength; - } - - if (p->mpeg == 1 && p->found == 7){ - p->buf[6] = p->flag1; - } - - - if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && - p->found < 14){ - while (c < count && p->found < 14){ - p->pts[p->found-9] = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - } - if (c == count) return 1; - } - - if (p->mpeg == 1 && p->which < 2000){ - - if (p->found == 7) { - p->check = p->flag1; - p->hlength = 1; - } - - while (!p->which && c < count && - p->check == 0xFF){ - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - } - - if ( c == count) return 1; - - if ( (p->check & 0xC0) == 0x40 && !p->which){ - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - - p->which = 1; - if ( c == count) return 1; - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - p->which = 2; - if ( c == count) return 1; - } - - if (p->which == 1){ - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - p->which = 2; - if ( c == count) return 1; - } - - if ( (p->check & 0x30) && p->check != 0xFF){ - p->flag2 = (p->check & 0xF0) << 2; - p->pts[0] = p->check; - p->which = 3; - } - - if ( c == count) return 1; - if (p->which > 2){ - if ((p->flag2 & PTS_DTS_FLAGS) - == PTS_ONLY){ - while (c < count && - p->which < 7){ - p->pts[p->which-2] = - buf[c]; - p->buf[p->found] = - buf[c]; - c++; - p->found++; - p->which++; - p->hlength++; - } - if ( c == count) return 1; - } else if ((p->flag2 & PTS_DTS_FLAGS) - == PTS_DTS){ - while (c < count && - p->which< 12){ - if (p->which< 7) - p->pts[p->which - -2] = - buf[c]; - p->buf[p->found] = - buf[c]; - c++; - p->found++; - p->which++; - p->hlength++; - } - if ( c == count) return 1; - } - p->which = 2000; - } - - } - - while (c < count && p->found < p->plength+6){ - l = count -c; - if (l+p->found > p->plength+6) - l = p->plength+6-p->found; - memcpy(p->buf+p->found, buf+c, l); - p->found += l; - c += l; - } - if(p->found == p->plength+6){ - if (func(p)){ - if (p->fd1 >= 0){ - write(p->fd1,p->buf, - p->plength+6); - } - } else ret = 0; - } - break; - } - - - if ( p->done ){ - if( p->found + count - c < p->plength+6){ - p->found += count-c; - c = count; - } else { - c += p->plength+6 - p->found; - p->found = p->plength+6; - } - } - - if (p->plength && p->found == p->plength+6) { - p->found = 0; - p->done = 0; - p->plength = 0; - memset(p->buf, 0, MAX_PLENGTH); - if (c < count) - return filter_pes(buf+c, count-c, p, func); - } - } - return ret; -} - - -#define SIZE 4096 - - -int audio_pes_filt(p2p *p) -{ - uint8_t off; - - switch(p->cid){ - case PRIVATE_STREAM1: - if ( p->cid == p->filter) { - off = 9+p->buf[8]; - if (p->buf[off] == p->subid){ - return 1; - } - } - break; - - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - if ( p->cid == p->filter) - return 1; - break; - - default: - return 1; - break; - } - return 0; -} - - -void filter_audio_from_pes(int fdin, int fdout, uint8_t id, uint8_t subid) -{ - p2p p; - int count = 1; - uint8_t buf[2048]; - - init_p2p(&p, NULL, 2048); - p.fd1 = -1; - p.filter = id; - p.subid = subid; - - while (count > 0){ - count = read(fdin,buf,2048); - if(filter_pes(buf,count,&p,audio_pes_filt)) - write(fdout,buf,2048); - } -} - - -void pes_filt(p2p *p) -{ - int factor = p->mpeg-1; - - if ( p->cid == p->filter) { - if (p->es) - write(p->fd1,p->buf+p->hlength+6+3*factor, - p->plength-p->hlength-3*factor); - else - write(p->fd1,p->buf,p->plength+6); - } -} - -void extract_from_pes(int fdin, int fdout, uint8_t id, int es) -{ - p2p p; - int count = 1; - uint8_t buf[SIZE]; - - init_p2p(&p, NULL, 2048); - p.fd1 = fdout; - p.filter = id; - p.es = es; - - while (count > 0){ - count = read(fdin,buf,SIZE); - get_pes(buf,count,&p,pes_filt); - } -} - - -void pes_dfilt(p2p *p) -{ - int factor = p->mpeg-1; - int fd =0; - int head=0; - int type = NOPES; - int streamid; - int c = 6+p->hlength+3*factor; - - - switch ( p->cid ) { - case PRIVATE_STREAM1: - streamid = p->buf[c]; - head = 4; - if ((streamid & 0xF8) == 0x80+p->es-1){ - fd = p->fd1; - type = AC3; - } - break; - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - fd = p->fd1; - type = AUDIO; - break; - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - fd = p->fd2; - type = VIDEO; - break; - } - - if (p->es && !p->startv && type == VIDEO){ - int found = 0; - - if ( p->flag2 & PTS_DTS ) - p->vpts = trans_pts_dts(p->pts); - else return; - - while ( !found && c+3 < p->plength+6 ){ - if ( p->buf[c] == 0x00 && - p->buf[c+1] == 0x00 && - p->buf[c+2] == 0x01 && - p->buf[c+3] == 0xb3) - found = 1; - else c++; - } - if (found){ - p->startv = 1; - write(fd, p->buf+c, p->plength+6-c); - } - fd = 0; - } - - - if ( p->es && !p->starta && type == AUDIO){ - int found = 0; - if ( p->flag2 & PTS_DTS ) - p->apts = trans_pts_dts(p->pts); - else return; - - if (p->startv) - while ( !found && c+1 < p->plength+6){ - if ( p->buf[c] == 0xFF && - (p->buf[c+1] & 0xF8) == 0xF8) - found = 1; - else c++; - } - if (found){ - p->starta = 1; - write(fd, p->buf+c, p->plength+6-c); - } - fd = 0; - } - - if ( p->es && !p->starta && type == AC3){ - if ( p->flag2 & PTS_DTS ) - p->apts = trans_pts_dts(p->pts); - else return; - - if (p->startv){ - c+= ((p->buf[c+2] << 8)| p->buf[c+3]); - p->starta = 1; - write(fd, p->buf+c, p->plength+6-c); - } - fd = 0; - } - - - if (fd){ - if (p->es) - write(fd,p->buf+p->hlength+6+3*factor+head, - p->plength-p->hlength-3*factor-head); - else - write(fd,p->buf,p->plength+6); - } -} - -int64_t pes_dmx( int fdin, int fdouta, int fdoutv, int es) -{ - p2p p; - int count = 1; - uint8_t buf[SIZE]; - uint64_t length = 0; - uint64_t l = 0; - int verb = 0; - int percent, oldPercent = -1; - - init_p2p(&p, NULL, 2048); - p.fd1 = fdouta; - p.fd2 = fdoutv; - p.es = es; - p.startv = 0; - p.starta = 0; - p.apts=-1; - p.vpts=-1; - - if (fdin != STDIN_FILENO) verb = 1; - - if (verb) { - length = lseek(fdin, 0, SEEK_END); - lseek(fdin,0,SEEK_SET); - } - - while (count > 0){ - count = read(fdin,buf,SIZE); - l += count; - if (verb){ - percent = 100 * l / length; - - if (percent != oldPercent) { - fprintf(stderr, "Demuxing %d %%\r", percent); - oldPercent = percent; - } - } - get_pes(buf,count,&p,pes_dfilt); - } - - return (int64_t)p.vpts - (int64_t)p.apts; - -} - - -/* SV: made non-static */ -void pes_in_ts(p2p *p) -{ - int l, pes_start; - uint8_t obuf[TS_SIZE]; - long int c = 0; - int length = p->plength+6; - uint16_t pid; - uint8_t *counter; - pes_start = 1; - switch ( p->cid ) { - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - pid = p->pida; - counter = &p->acounter; - break; - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - pid = p->pidv; - counter = &p->acounter; - - tspid0[3] |= (p->count0++) - & 0x0F ; - tspid1[3] |= (p->count1++) - & 0x0F ; - - tspid1[24] = p->pidv; - tspid1[23] |= (p->pidv >> 8) & 0x3F; - tspid1[29] = p->pida; - tspid1[28] |= (p->pida >> 8) & 0x3F; - - p->func(tspid0,188,p); - p->func(tspid1,188,p); - break; - default: - return; - } - - while ( c < length ){ - memset(obuf,0,TS_SIZE); - if (length - c >= TS_SIZE-4){ - l = write_ts_header(pid, counter, pes_start - , obuf, TS_SIZE-4); - memcpy(obuf+l, p->buf+c, TS_SIZE-l); - c += TS_SIZE-l; - } else { - l = write_ts_header(pid, counter, pes_start - , obuf, length-c); - memcpy(obuf+l, p->buf+c, TS_SIZE-l); - c = length; - } - p->func(obuf,188,p); - pes_start = 0; - } -} - -static -void write_out(uint8_t *buf, int count,void *p) -{ - write(STDOUT_FILENO, buf, count); -} - - -void pes_to_ts2( int fdin, int fdout, uint16_t pida, uint16_t pidv) -{ - p2p p; - int count = 1; - uint8_t buf[SIZE]; - uint64_t length = 0; - uint64_t l = 0; - int verb = 0; - - init_p2p(&p, NULL, 2048); - p.fd1 = fdout; - p.pida = pida; - p.pidv = pidv; - p.acounter = 0; - p.vcounter = 0; - p.count1 = 0; - p.count0 = 0; - p.func = write_out; - - if (fdin != STDIN_FILENO) verb = 1; - - if (verb) { - length = lseek(fdin, 0, SEEK_END); - lseek(fdin,0,SEEK_SET); - } - - while (count > 0){ - count = read(fdin,buf,SIZE); - l += count; - if (verb) - fprintf(stderr,"Writing TS %2.2f %%\r", - 100.*l/length); - - get_pes(buf,count,&p,pes_in_ts); - } - -} - - -#define IN_SIZE TS_SIZE*10 -void find_avpids(int fd, uint16_t *vpid, uint16_t *apid) -{ - uint8_t buf[IN_SIZE]; - int count; - int i; - int off =0; - - while ( *apid == 0 || *vpid == 0){ - count = read(fd, buf, IN_SIZE); - for (i = 0; i < count-7; i++){ - if (buf[i] == 0x47){ - if (buf[i+1] & 0x40){ - off = 0; - if ( buf[3+i] & 0x20)//adapt field? - off = buf[4+i] + 1; - switch(buf[i+7+off]){ - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - *vpid = get_pid(buf+i+1); - break; - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - *apid = get_pid(buf+i+1); - break; - } - } - i += 187; - } - if (*apid != 0 && *vpid != 0) break; - } - } -} - -void find_bavpids(uint8_t *buf, int count, uint16_t *vpid, uint16_t *apid) -{ - int i; - int founda = 0; - int foundb = 0; - int off = 0; - - *vpid = 0; - *apid = 0; - for (i = 0; i < count-7; i++){ - if (buf[i] == 0x47){ - if ((buf[i+1] & 0xF0) == 0x40){ - off = 0; - if ( buf[3+i] & 0x20) // adaptation field? - off = buf[4+i] + 1; - - if (buf[off+i+4] == 0x00 && - buf[off+i+5] == 0x00 && - buf[off+i+6] == 0x01){ - switch(buf[off+i+7]){ - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - *vpid = get_pid(buf+i+1); - foundb=1; - break; - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - *apid = get_pid(buf+i+1); - founda=1; - break; - } - } - } - i += 187; - } - if (founda && foundb) break; - } -} - - -void ts_to_pes( int fdin, uint16_t pida, uint16_t pidv, int ps) -{ - - uint8_t buf[IN_SIZE]; - uint8_t mbuf[TS_SIZE]; - int i; - int count = 1; - uint16_t pid; - uint16_t dummy; - ipack pa, pv; - ipack *p; - - if (fdin != STDIN_FILENO && (!pida || !pidv)) - find_avpids(fdin, &pidv, &pida); - - init_ipack(&pa, IPACKS,write_out, ps); - init_ipack(&pv, IPACKS,write_out, ps); - - if ((count = save_read(fdin,mbuf,TS_SIZE))<0) - perror("reading"); - - for ( i = 0; i < 188 ; i++){ - if ( mbuf[i] == 0x47 ) break; - } - if ( i == 188){ - fprintf(stderr,"Not a TS\n"); - return; - } else { - memcpy(buf,mbuf+i,TS_SIZE-i); - if ((count = save_read(fdin,mbuf,i))<0) - perror("reading"); - memcpy(buf+TS_SIZE-i,mbuf,i); - i = 188; - } - count = 1; - while (count > 0){ - if ((count = save_read(fdin,buf+i,IN_SIZE-i)+i)<0) - perror("reading"); - - - if (!pidv){ - find_bavpids(buf+i, IN_SIZE-i, &pidv, &dummy); - if (pidv) fprintf(stderr, "vpid %d (0x%02x)\n", - pidv,pidv); - } - - if (!pida){ - find_bavpids(buf+i, IN_SIZE-i, &dummy, &pida); - if (pida) fprintf(stderr, "apid %d (0x%02x)\n", - pida,pida); - } - - - for( i = 0; i < count; i+= TS_SIZE){ - uint8_t off = 0; - - if ( count - i < TS_SIZE) break; - - pid = get_pid(buf+i+1); - if (!(buf[3+i]&0x10)) // no payload? - continue; - if ( buf[1+i]&0x80){ - fprintf(stderr,"Error in TS for PID: %d\n", - pid); - } - if (pid == pidv){ - p = &pv; - } else { - if (pid == pida){ - p = &pa; - } else continue; - } - - if ( buf[1+i]&0x40) { - if (p->plength == MMAX_PLENGTH-6){ - p->plength = p->found-6; - p->found = 0; - send_ipack(p); - reset_ipack(p); - } - } - - if ( buf[3+i] & 0x20) { // adaptation field? - off = buf[4+i] + 1; - } - - instant_repack(buf+4+off+i, TS_SIZE-4-off, p); - } - i = 0; - - } - -} - - -#define INN_SIZE 2*IN_SIZE -void insert_pat_pmt( int fdin, int fdout) -{ - - uint8_t buf[INN_SIZE]; - uint8_t mbuf[TS_SIZE]; - int i; - int count = 1; - uint16_t pida = 0; - uint16_t pidv = 0; - int written,c; - uint8_t c0 = 0; - uint8_t c1 = 0; - uint8_t pmt_len; - uint32_t crc32; - - - find_avpids(fdin, &pidv, &pida); - - count = save_read(fdin,mbuf,TS_SIZE); - for ( i = 0; i < 188 ; i++){ - if ( mbuf[i] == 0x47 ) break; - } - if ( i == 188){ - fprintf(stderr,"Not a TS\n"); - return; - } else { - memcpy(buf,mbuf+i,TS_SIZE-i); - count = save_read(fdin,mbuf,i); - memcpy(buf+TS_SIZE-i,mbuf,i); - i = 188; - } - - count = 1; - /* length is not correct, but we only create a very small - * PMT, so it doesn't matter :-) - */ - pmt_len = tspid1[7] + 3; - while (count > 0){ - tspid1[24] = pidv; - tspid1[23] |= (pidv >> 8) & 0x3F; - tspid1[29] = pida; - tspid1[28] |= (pida >> 8) & 0x3F; - crc32 = calc_crc32 (&tspid1[5], pmt_len - 4); - tspid1[5 + pmt_len - 4] = (crc32 & 0xff000000) >> 24; - tspid1[5 + pmt_len - 3] = (crc32 & 0x00ff0000) >> 16; - tspid1[5 + pmt_len - 2] = (crc32 & 0x0000ff00) >> 8; - tspid1[5 + pmt_len - 1] = (crc32 & 0x000000ff) >> 0; - - write(fdout,tspid0,188); - write(fdout,tspid1,188); - - count = save_read(fdin,buf+i,INN_SIZE-i); - - written = 0; - while (written < IN_SIZE){ - c = write(fdout,buf,INN_SIZE); - if (c>0) written += c; - } - tspid0[3] &= 0xF0 ; - tspid0[3] |= (c0++)& 0x0F ; - - tspid1[3] &= 0xF0 ; - tspid1[3] |= (c1++)& 0x0F ; - - i=0; - } - -} - -void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p)) -{ - - int l; - unsigned short *pl; - int c=0; - - uint8_t headr[3] = { 0x00, 0x00, 0x01} ; - - while (c < count && (p->mpeg == 0 || - (p->mpeg == 1 && p->found < 7) || - (p->mpeg == 2 && p->found < 9)) - && (p->found < 5 || !p->done)){ - switch ( p->found ){ - case 0: - case 1: - if (buf[c] == 0x00) p->found++; - else p->found = 0; - c++; - break; - case 2: - if (buf[c] == 0x01) p->found++; - else if (buf[c] == 0){ - p->found = 2; - } else p->found = 0; - c++; - break; - case 3: - p->cid = 0; - switch (buf[c]){ - 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: - p->done = 1; - case PRIVATE_STREAM1: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - p->found++; - p->cid = buf[c]; - c++; - break; - default: - p->found = 0; - break; - } - break; - - - case 4: - if (count-c > 1){ - pl = (unsigned short *) (buf+c); - p->plength = ntohs(*pl); - p->plen[0] = buf[c]; - c++; - p->plen[1] = buf[c]; - c++; - p->found+=2; - } else { - p->plen[0] = buf[c]; - p->found++; - return; - } - break; - case 5: - p->plen[1] = buf[c]; - c++; - pl = (unsigned short *) p->plen; - p->plength = ntohs(*pl); - p->found++; - break; - - - case 6: - if (!p->done){ - p->flag1 = buf[c]; - c++; - p->found++; - if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; - else { - p->hlength = 0; - p->which = 0; - p->mpeg = 1; - p->flag2 = 0; - } - } - break; - - case 7: - if ( !p->done && p->mpeg == 2){ - p->flag2 = buf[c]; - c++; - p->found++; - } - break; - - case 8: - if ( !p->done && p->mpeg == 2){ - p->hlength = buf[c]; - c++; - p->found++; - } - break; - - default: - - break; - } - } - - if (!p->plength) p->plength = MMAX_PLENGTH-6; - - - if ( p->done || ((p->mpeg == 2 && p->found >= 9) || - (p->mpeg == 1 && p->found >= 7)) ){ - switch (p->cid){ - - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case PRIVATE_STREAM1: - - memcpy(p->buf, headr, 3); - p->buf[3] = p->cid; - memcpy(p->buf+4,p->plen,2); - - if (p->mpeg == 2 && p->found == 9){ - p->buf[6] = p->flag1; - p->buf[7] = p->flag2; - p->buf[8] = p->hlength; - } - - if (p->mpeg == 1 && p->found == 7){ - p->buf[6] = p->flag1; - } - - - if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && - p->found < 14){ - while (c < count && p->found < 14){ - p->pts[p->found-9] = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - } - if (c == count) return; - } - - if (p->mpeg == 1 && p->which < 2000){ - - if (p->found == 7) { - p->check = p->flag1; - p->hlength = 1; - } - - while (!p->which && c < count && - p->check == 0xFF){ - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - } - - if ( c == count) return; - - if ( (p->check & 0xC0) == 0x40 && !p->which){ - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - - p->which = 1; - if ( c == count) return; - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - p->which = 2; - if ( c == count) return; - } - - if (p->which == 1){ - p->check = buf[c]; - p->buf[p->found] = buf[c]; - c++; - p->found++; - p->hlength++; - p->which = 2; - if ( c == count) return; - } - - if ( (p->check & 0x30) && p->check != 0xFF){ - p->flag2 = (p->check & 0xF0) << 2; - p->pts[0] = p->check; - p->which = 3; - } - - if ( c == count) return; - if (p->which > 2){ - if ((p->flag2 & PTS_DTS_FLAGS) - == PTS_ONLY){ - while (c < count && - p->which < 7){ - p->pts[p->which-2] = - buf[c]; - p->buf[p->found] = - buf[c]; - c++; - p->found++; - p->which++; - p->hlength++; - } - if ( c == count) return; - } else if ((p->flag2 & PTS_DTS_FLAGS) - == PTS_DTS){ - while (c < count && - p->which< 12){ - if (p->which< 7) - p->pts[p->which - -2] = - buf[c]; - p->buf[p->found] = - buf[c]; - c++; - p->found++; - p->which++; - p->hlength++; - } - if ( c == count) return; - } - p->which = 2000; - } - - } - - while (c < count && p->found < p->plength+6){ - l = count -c; - if (l+p->found > p->plength+6) - l = p->plength+6-p->found; - memcpy(p->buf+p->found, buf+c, l); - p->found += l; - c += l; - } - if(p->found == p->plength+6) - func(p); - - break; - } - - - if ( p->done ){ - if( p->found + count - c < p->plength+6){ - p->found += count-c; - c = count; - } else { - c += p->plength+6 - p->found; - p->found = p->plength+6; - } - } - - if (p->plength && p->found == p->plength+6) { - p->found = 0; - p->done = 0; - p->plength = 0; - memset(p->buf, 0, MAX_PLENGTH); - if (c < count) - get_pes(buf+c, count-c, p, func); - } - } - return; -} - - - - -void setup_pes2ts( p2p *p, uint32_t pida, uint32_t pidv, - void (*ts_write)(uint8_t *buf, int count, void *p)) -{ - init_p2p( p, ts_write, 2048); - p->pida = pida; - p->pidv = pidv; - p->acounter = 0; - p->vcounter = 0; - p->count1 = 0; - p->count0 = 0; -} - -void kpes_to_ts( p2p *p,uint8_t *buf ,int count ) -{ - get_pes(buf,count, p,pes_in_ts); -} - - -void setup_ts2pes( p2p *pa, p2p *pv, uint32_t pida, uint32_t pidv, - void (*pes_write)(uint8_t *buf, int count, void *p)) -{ - init_p2p( pa, pes_write, 2048); - init_p2p( pv, pes_write, 2048); - pa->pid = pida; - pv->pid = pidv; -} - -void kts_to_pes( p2p *p, uint8_t *buf) // don't need count (=188) -{ - uint8_t off = 0; - uint16_t pid = 0; - - if (!(buf[3]&PAYLOAD)) // no payload? - return; - - pid = get_pid(buf+1); - - if (pid != p->pid) return; - if ( buf[1]&0x80){ - fprintf(stderr,"Error in TS for PID: %d\n", - pid); - } - - if ( buf[1]&PAY_START) { - if (p->plength == MMAX_PLENGTH-6){ - p->plength = p->found-6; - p->found = 0; - pes_repack(p); - } - } - - if ( buf[3] & ADAPT_FIELD) { // adaptation field? - off = buf[4] + 1; - if (off+4 > 187) return; - } - - get_pes(buf+4+off, TS_SIZE-4-off, p , pes_repack); -} - - - - -// instant repack - - -void reset_ipack(ipack *p) -{ - p->found = 0; - p->cid = 0; - p->plength = 0; - p->flag1 = 0; - p->flag2 = 0; - p->hlength = 0; - p->mpeg = 0; - p->check = 0; - p->which = 0; - p->done = 0; - p->count = 0; - p->size = p->size_orig; -} - -void init_ipack(ipack *p, int size, - void (*func)(uint8_t *buf, int size, void *priv), int ps) -{ - if ( !(p->buf = malloc(size)) ){ - fprintf(stderr,"Couldn't allocate memory for ipack\n"); - exit(1); - } - p->ps = ps; - p->size_orig = size; - p->func = func; - reset_ipack(p); - p->has_ai = 0; - p->has_vi = 0; - p->start = 0; -} - -void free_ipack(ipack * p) -{ - if (p->buf) free(p->buf); -} - - - -int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr) -{ - uint8_t *headr; - int found = 0; - int sw; - int form = -1; - int c = 0; - - while (found < 4 && c+4 < count){ - uint8_t *b; - - b = mbuf+c; - if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 - && b[3] == 0xb3) found = 4; - else { - c++; - } - } - - if (! found) return -1; - c += 4; - if (c+12 >= count) return -1; - headr = mbuf+c; - - vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); - vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); - - sw = (int)((headr[3]&0xF0) >> 4) ; - - switch( sw ){ - case 1: - if (pr) - fprintf(stderr,"Videostream: ASPECT: 1:1"); - vi->aspect_ratio = 100; - break; - case 2: - if (pr) - fprintf(stderr,"Videostream: ASPECT: 4:3"); - vi->aspect_ratio = 133; - break; - case 3: - if (pr) - fprintf(stderr,"Videostream: ASPECT: 16:9"); - vi->aspect_ratio = 177; - break; - case 4: - if (pr) - fprintf(stderr,"Videostream: ASPECT: 2.21:1"); - vi->aspect_ratio = 221; - break; - - case 5 ... 15: - if (pr) - fprintf(stderr,"Videostream: ASPECT: reserved"); - vi->aspect_ratio = 0; - break; - - default: - vi->aspect_ratio = 0; - return -1; - } - - if (pr) - fprintf(stderr," Size = %dx%d",vi->horizontal_size, - vi->vertical_size); - - sw = (int)(headr[3]&0x0F); - - switch ( sw ) { - case 1: - if (pr) - fprintf(stderr," FRate: 23.976 fps"); - vi->framerate = 24000/1001.; - form = -1; - break; - case 2: - if (pr) - fprintf(stderr," FRate: 24 fps"); - vi->framerate = 24; - form = -1; - break; - case 3: - if (pr) - fprintf(stderr," FRate: 25 fps"); - vi->framerate = 25; - form = VIDEO_MODE_PAL; - break; - case 4: - if (pr) - fprintf(stderr," FRate: 29.97 fps"); - vi->framerate = 30000/1001.; - form = VIDEO_MODE_NTSC; - break; - case 5: - if (pr) - fprintf(stderr," FRate: 30 fps"); - vi->framerate = 30; - form = VIDEO_MODE_NTSC; - break; - case 6: - if (pr) - fprintf(stderr," FRate: 50 fps"); - vi->framerate = 50; - form = VIDEO_MODE_PAL; - break; - case 7: - if (pr) - fprintf(stderr," FRate: 60 fps"); - vi->framerate = 60; - form = VIDEO_MODE_NTSC; - break; - } - - vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) - | ((headr[5] << 2) & 0x000003FCUL) | - (((headr[6] & 0xC0) >> 6) & 0x00000003UL)); - - if (pr){ - fprintf(stderr," BRate: %.2f Mbit/s",(vi->bit_rate)/1000000.); - fprintf(stderr,"\n"); - } - vi->video_format = form; - - vi->off = c-4; - return c-4; -} - -extern unsigned int bitrates[3][16]; -extern uint32_t freq[4]; - -int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr) -{ - uint8_t *headr; - int found = 0; - int c = 0; - int fr =0; - - while (!found && c < count){ - uint8_t *b = mbuf+c; - - if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) - found = 1; - else { - c++; - } - } - - if (!found) return -1; - - if (c+3 >= count) return -1; - headr = mbuf+c; - - ai->layer = (headr[1] & 0x06) >> 1; - - if (pr) - fprintf(stderr,"Audiostream: Layer: %d", 4-ai->layer); - - - ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; - - if (pr){ - if (ai->bit_rate == 0) - fprintf (stderr," Bit rate: free"); - else if (ai->bit_rate == 0xf) - fprintf (stderr," BRate: reserved"); - else - fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000); - } - - fr = (headr[2] & 0x0c ) >> 2; - ai->frequency = freq[fr]*100; - - if (pr){ - if (ai->frequency == 3) - fprintf (stderr, " Freq: reserved\n"); - else - fprintf (stderr," Freq: %2.1f kHz\n", - ai->frequency/1000.); - } - ai->off = c; - return c; -} - -unsigned int ac3_bitrates[32] = - {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, - 0,0,0,0,0,0,0,0,0,0,0,0,0}; - -uint32_t ac3_freq[4] = {480, 441, 320, 0}; -uint32_t ac3_frames[3][32] = - {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, - 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, - 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, - 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - -int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr) -{ - uint8_t *headr; - int found = 0; - int c = 0; - uint8_t frame; - int fr = 0; - - while ( !found && c < count){ - uint8_t *b = mbuf+c; - if ( b[0] == 0x0b && b[1] == 0x77 ) - found = 1; - else { - c++; - } - } - - - if (!found){ - return -1; - } - ai->off = c; - - if (c+5 >= count) return -1; - - ai->layer = 0; // 0 for AC3 - headr = mbuf+c+2; - - frame = (headr[2]&0x3f); - ai->bit_rate = ac3_bitrates[frame>>1]*1000; - - if (pr) fprintf (stderr," BRate: %d kb/s", ai->bit_rate/1000); - - fr = (headr[2] & 0xc0 ) >> 6; - ai->frequency = freq[fr]*100; - if (pr) fprintf (stderr," Freq: %d Hz\n", ai->frequency); - - ai->framesize = ac3_frames[fr][frame >> 1]; - if ((frame & 1) && (fr == 1)) ai->framesize++; - ai->framesize = ai->framesize << 1; - if (pr) fprintf (stderr," Framesize %d\n", ai->framesize); - - return c; -} - - -void ps_pes(ipack *p) -{ - int check; - uint8_t pbuf[PS_HEADER_L2]; - static int muxr = 0; - static int ai = 0; - static int vi = 0; - static int start = 0; - static uint32_t SCR = 0; - - if (p->mpeg == 2){ - switch(p->buf[3]){ - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - if (!p->has_vi){ - if(get_vinfo(p->buf, p->count, &p->vi,1) >=0) { - p->has_vi = 1; - vi = p->vi.bit_rate; - } - } - break; - - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - if (!p->has_ai){ - if(get_ainfo(p->buf, p->count, &p->ai,1) >=0) { - p->has_ai = 1; - ai = p->ai.bit_rate; - } - } - break; - } - - if (p->has_vi && vi && !muxr){ - muxr = (vi+ai)/400; - } - - if ( start && muxr && (p->buf[7] & PTS_ONLY) && (p->has_ai || - p->buf[9+p->buf[8]+4] == 0xb3)){ - SCR = trans_pts_dts(p->pts)-3600; - - check = write_ps_header(pbuf, - SCR, - muxr, 1, 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, 0); - - p->func(pbuf, check , p->data); - } - - if (muxr && !start && vi){ - SCR = trans_pts_dts(p->pts)-3600; - check = write_ps_header(pbuf, - SCR, - muxr, 1, 0, 0, 1, 1, 1, - 0xC0, 0, 64, 0xE0, 1, 460); - start = 1; - p->func(pbuf, check , p->data); - } - - if (start) - p->func(p->buf, p->count, p->data); - } -} - -void send_ipack(ipack *p) -{ - int streamid=0; - int off; - int ac3_off = 0; - AudioInfo ai; - int nframes= 0; - int f=0; - - if (p->count < 10) return; - p->buf[3] = p->cid; - p->buf[4] = (uint8_t)(((p->count-6) & 0xFF00) >> 8); - p->buf[5] = (uint8_t)((p->count-6) & 0x00FF); - - - if (p->cid == PRIVATE_STREAM1){ - - off = 9+p->buf[8]; - streamid = p->buf[off]; - if ((streamid & 0xF8) == 0x80){ - ai.off = 0; - ac3_off = ((p->buf[off+2] << 8)| p->buf[off+3]); - if (ac3_off < p->count) - f=get_ac3info(p->buf+off+3+ac3_off, - p->count-ac3_off, &ai,0); - if ( !f ){ - nframes = (p->count-off-3-ac3_off)/ - ai.framesize + 1; - p->buf[off+1] = nframes; - p->buf[off+2] = (ac3_off >> 8)& 0xFF; - p->buf[off+3] = (ac3_off)& 0xFF; - - ac3_off += nframes * ai.framesize - p->count; - } - } - } - - if (p->ps) ps_pes(p); - else p->func(p->buf, p->count, p->data); - - switch ( p->mpeg ){ - case 2: - - p->buf[6] = 0x80; - p->buf[7] = 0x00; - p->buf[8] = 0x00; - p->count = 9; - - if (p->cid == PRIVATE_STREAM1 && (streamid & 0xF8)==0x80 ){ - p->count += 4; - p->buf[9] = streamid; - p->buf[10] = 0; - p->buf[11] = (ac3_off >> 8)& 0xFF; - p->buf[12] = (ac3_off)& 0xFF; - } - - break; - case 1: - p->buf[6] = 0x0F; - p->count = 7; - break; - } - -} - - -static void write_ipack(ipack *p, uint8_t *data, int count) -{ - AudioInfo ai; - uint8_t headr[3] = { 0x00, 0x00, 0x01} ; - int diff =0; - - if (p->count < 6){ - if (trans_pts_dts(p->pts) > trans_pts_dts(p->last_pts)) - memcpy(p->last_pts, p->pts, 5); - p->count = 0; - memcpy(p->buf+p->count, headr, 3); - p->count += 6; - } - if ( p->size == p->size_orig && p->plength && - (diff = 6+p->plength - p->found + p->count +count) > p->size && - diff < 3*p->size/2){ - - p->size = diff/2; -// fprintf(stderr,"size: %d \n",p->size); - } - - if (p->cid == PRIVATE_STREAM1 && p->count == p->hlength+9){ - if ((data[0] & 0xF8) != 0x80){ - int ac3_off; - - ac3_off = get_ac3info(data, count, &ai,0); - if (ac3_off>=0 && ai.framesize){ - p->buf[p->count] = 0x80; - p->buf[p->count+1] = (p->size - p->count - - 4 - ac3_off)/ - ai.framesize + 1; - p->buf[p->count+2] = (ac3_off >> 8)& 0xFF; - p->buf[p->count+3] = (ac3_off)& 0xFF; - p->count+=4; - - } - } - } - - if (p->count + count < p->size){ - memcpy(p->buf+p->count, data, count); - p->count += count; - } else { - int rest = p->size - p->count; - if (rest < 0) rest = 0; - memcpy(p->buf+p->count, data, rest); - p->count += rest; -// fprintf(stderr,"count: %d \n",p->count); - send_ipack(p); - if (count - rest > 0) - write_ipack(p, data+rest, count-rest); - } -} - -void instant_repack (uint8_t *buf, int count, ipack *p) -{ - - int l; - unsigned short *pl; - int c=0; - - while (c < count && (p->mpeg == 0 || - (p->mpeg == 1 && p->found < 7) || - (p->mpeg == 2 && p->found < 9)) - && (p->found < 5 || !p->done)){ - switch ( p->found ){ - case 0: - case 1: - if (buf[c] == 0x00) p->found++; - else p->found = 0; - c++; - break; - case 2: - if (buf[c] == 0x01) p->found++; - else if (buf[c] == 0){ - p->found = 2; - } else p->found = 0; - c++; - break; - case 3: - p->cid = 0; - switch (buf[c]){ - 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: - p->done = 1; - case PRIVATE_STREAM1: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - p->found++; - p->cid = buf[c]; - c++; - break; - default: - p->found = 0; - break; - } - break; - - - case 4: - if (count-c > 1){ - pl = (unsigned short *) (buf+c); - p->plength = ntohs(*pl); - p->plen[0] = buf[c]; - c++; - p->plen[1] = buf[c]; - c++; - p->found+=2; - } else { - p->plen[0] = buf[c]; - p->found++; - return; - } - break; - case 5: - p->plen[1] = buf[c]; - c++; - pl = (unsigned short *) p->plen; - p->plength = ntohs(*pl); - p->found++; - break; - - - case 6: - if (!p->done){ - p->flag1 = buf[c]; - c++; - p->found++; - if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; - else { - p->hlength = 0; - p->which = 0; - p->mpeg = 1; - p->flag2 = 0; - } - } - break; - - case 7: - if ( !p->done && p->mpeg == 2){ - p->flag2 = buf[c]; - c++; - p->found++; - } - break; - - case 8: - if ( !p->done && p->mpeg == 2){ - p->hlength = buf[c]; - c++; - p->found++; - } - break; - - default: - - break; - } - } - - - if (c == count) return; - - if (!p->plength) p->plength = MMAX_PLENGTH-6; - - - if ( p->done || ((p->mpeg == 2 && p->found >= 9) || - (p->mpeg == 1 && p->found >= 7)) ){ - switch (p->cid){ - - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case PRIVATE_STREAM1: - - if (p->mpeg == 2 && p->found == 9){ - write_ipack(p, &p->flag1, 1); - write_ipack(p, &p->flag2, 1); - write_ipack(p, &p->hlength, 1); - } - - if (p->mpeg == 1 && p->found == 7){ - write_ipack(p, &p->flag1, 1); - } - - - if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && - p->found < 14){ - while (c < count && p->found < 14){ - p->pts[p->found-9] = buf[c]; - write_ipack(p, buf+c, 1); - c++; - p->found++; - } - if (c == count) return; - } - - if (p->mpeg == 1 && p->which < 2000){ - - if (p->found == 7) { - p->check = p->flag1; - p->hlength = 1; - } - - while (!p->which && c < count && - p->check == 0xFF){ - p->check = buf[c]; - write_ipack(p, buf+c, 1); - c++; - p->found++; - p->hlength++; - } - - if ( c == count) return; - - if ( (p->check & 0xC0) == 0x40 && !p->which){ - p->check = buf[c]; - write_ipack(p, buf+c, 1); - c++; - p->found++; - p->hlength++; - - p->which = 1; - if ( c == count) return; - p->check = buf[c]; - write_ipack(p, buf+c, 1); - c++; - p->found++; - p->hlength++; - p->which = 2; - if ( c == count) return; - } - - if (p->which == 1){ - p->check = buf[c]; - write_ipack(p, buf+c, 1); - c++; - p->found++; - p->hlength++; - p->which = 2; - if ( c == count) return; - } - - if ( (p->check & 0x30) && p->check != 0xFF){ - p->flag2 = (p->check & 0xF0) << 2; - p->pts[0] = p->check; - p->which = 3; - } - - if ( c == count) return; - if (p->which > 2){ - if ((p->flag2 & PTS_DTS_FLAGS) - == PTS_ONLY){ - while (c < count && - p->which < 7){ - p->pts[p->which-2] = - buf[c]; - write_ipack(p,buf+c,1); - c++; - p->found++; - p->which++; - p->hlength++; - } - if ( c == count) return; - } else if ((p->flag2 & PTS_DTS_FLAGS) - == PTS_DTS){ - while (c < count && - p->which< 12){ - if (p->which< 7) - p->pts[p->which - -2] = - buf[c]; - write_ipack(p,buf+c,1); - c++; - p->found++; - p->which++; - p->hlength++; - } - if ( c == count) return; - } - p->which = 2000; - } - - } - - while (c < count && p->found < p->plength+6){ - l = count -c; - if (l+p->found > p->plength+6) - l = p->plength+6-p->found; - write_ipack(p, buf+c, l); - p->found += l; - c += l; - } - - break; - } - - - if ( p->done ){ - if( p->found + count - c < p->plength+6){ - p->found += count-c; - c = count; - } else { - c += p->plength+6 - p->found; - p->found = p->plength+6; - } - } - - if (p->plength && p->found == p->plength+6) { - send_ipack(p); - reset_ipack(p); - if (c < count) - instant_repack(buf+c, count-c, p); - } - } - return; -} - -void write_out_es(uint8_t *buf, int count,void *priv) -{ - ipack *p = (ipack *) priv; - uint8_t payl = buf[8]+9+p->start-1; - - write(p->fd, buf+payl, count-payl); - p->start = 1; -} - -void write_out_pes(uint8_t *buf, int count,void *priv) -{ - ipack *p = (ipack *) priv; - write(p->fd, buf, count); -} - - - -int64_t ts_demux(int fdin, int fdv_out,int fda_out,uint16_t pida, - uint16_t pidv, int es) -{ - uint8_t buf[IN_SIZE]; - uint8_t mbuf[TS_SIZE]; - int i; - int count = 1; - uint16_t pid; - ipack pa, pv; - ipack *p; - uint8_t *sb; - int64_t apts=0; - int64_t vpts=0; - int verb = 0; - uint64_t length =0; - uint64_t l=0; - int perc =0; - int last_perc =0; - - if (fdin != STDIN_FILENO) verb = 1; - - if (verb) { - length = lseek(fdin, 0, SEEK_END); - lseek(fdin,0,SEEK_SET); - } - - if (!pida || !pidv) - find_avpids(fdin, &pidv, &pida); - - if (es){ - init_ipack(&pa, IPACKS,write_out_es, 0); - init_ipack(&pv, IPACKS,write_out_es, 0); - } else { - init_ipack(&pa, IPACKS,write_out_pes, 0); - init_ipack(&pv, IPACKS,write_out_pes, 0); - } - pa.fd = fda_out; - pv.fd = fdv_out; - pa.data = (void *)&pa; - pv.data = (void *)&pv; - - count = save_read(fdin,mbuf,TS_SIZE); - if (count) l+=count; - for ( i = 0; i < 188 ; i++){ - if ( mbuf[i] == 0x47 ) break; - } - if ( i == 188){ - fprintf(stderr,"Not a TS\n"); - return 0; - } else { - memcpy(buf,mbuf+i,TS_SIZE-i); - count = save_read(fdin,mbuf,i); - if (count) l+=count; - memcpy(buf+TS_SIZE-i,mbuf,i); - i = 188; - } - - count = 1; - while (count > 0){ - count = save_read(fdin,buf+i,IN_SIZE-i)+i; - if (count) l+=count; - if (verb && perc >last_perc){ - perc = (100*l)/length; - fprintf(stderr,"Reading TS %d %%\r",perc); - last_perc = perc; - } - - for( i = 0; i < count; i+= TS_SIZE){ - uint8_t off = 0; - - if ( count - i < TS_SIZE) break; - - pid = get_pid(buf+i+1); - if (!(buf[3+i]&0x10)) // no payload? - continue; - if ( buf[1+i]&0x80){ - fprintf(stderr,"Error in TS for PID: %d\n", - pid); - } - if (pid == pidv){ - p = &pv; - } else { - if (pid == pida){ - p = &pa; - } else continue; - } - - if ( buf[3+i] & 0x20) { // adaptation field? - off = buf[4+i] + 1; - } - - if ( buf[1+i]&0x40) { - if (p->plength == MMAX_PLENGTH-6){ - p->plength = p->found-6; - p->found = 0; - send_ipack(p); - reset_ipack(p); - } - sb = buf+4+off+i; - if( es && - !p->start && (sb[7] & PTS_DTS_FLAGS)){ - uint8_t *pay = sb+sb[8]+9; - int l = TS_SIZE - 13 - off - sb[8]; - if ( pid == pidv && - (p->start = - get_vinfo( pay, l,&p->vi,1)+1) >0 - ){ - vpts = trans_pts_dts(sb+9); - printf("vpts : %fs\n", - vpts/90000.); - } - if ( pid == pida && es==1 && - (p->start = - get_ainfo( pay, l,&p->ai,1)+1) >0 - ){ - apts = trans_pts_dts(sb+9); - printf("apts : %fs\n", - apts/90000.); - } - if ( pid == pida && es==2 && - (p->start = - get_ac3info( pay, l,&p->ai,1)+1) >0 - ){ - apts = trans_pts_dts(sb+9); - printf("apts : %fs\n", - apts/90000.); - } - } - } - - if (p->start) - instant_repack(buf+4+off+i, TS_SIZE-4-off, p); - } - i = 0; - - } - - return (vpts-apts); -} - -void ts2es_opt(int fdin, uint16_t pidv, ipack *p, int verb) -{ - uint8_t buf[IN_SIZE]; - uint8_t mbuf[TS_SIZE]; - int i; - int count = 1; - uint64_t length =0; - uint64_t l=0; - int perc =0; - int last_perc =0; - uint16_t pid; - - if (verb) { - length = lseek(fdin, 0, SEEK_END); - lseek(fdin,0,SEEK_SET); - } - - count = save_read(fdin,mbuf,TS_SIZE); - if (count) l+=count; - for ( i = 0; i < 188 ; i++){ - if ( mbuf[i] == 0x47 ) break; - } - if ( i == 188){ - fprintf(stderr,"Not a TS\n"); - return; - } else { - memcpy(buf,mbuf+i,TS_SIZE-i); - count = save_read(fdin,mbuf,i); - if (count) l+=count; - memcpy(buf+TS_SIZE-i,mbuf,i); - i = 188; - } - - count = 1; - while (count > 0){ - count = save_read(fdin,buf+i,IN_SIZE-i)+i; - if (count) l+=count; - if (verb && perc >last_perc){ - perc = (100*l)/length; - fprintf(stderr,"Reading TS %d %%\r",perc); - last_perc = perc; - } - - for( i = 0; i < count; i+= TS_SIZE){ - uint8_t off = 0; - - if ( count - i < TS_SIZE) break; - - pid = get_pid(buf+i+1); - if (!(buf[3+i]&0x10)) // no payload? - continue; - if ( buf[1+i]&0x80){ - fprintf(stderr,"Error in TS for PID: %d\n", - pid); - } - if (pid != pidv){ - continue; - } - - if ( buf[3+i] & 0x20) { // adaptation field? - off = buf[4+i] + 1; - } - - if ( buf[1+i]&0x40) { - if (p->plength == MMAX_PLENGTH-6){ - p->plength = p->found-6; - p->found = 0; - send_ipack(p); - reset_ipack(p); - } - } - - instant_repack(buf+4+off+i, TS_SIZE-4-off, p); - } - i = 0; - - } -} - -void ts2es(int fdin, uint16_t pidv) -{ - ipack p; - int verb = 0; - - init_ipack(&p, IPACKS,write_out_es, 0); - p.fd = STDOUT_FILENO; - p.data = (void *)&p; - - if (fdin != STDIN_FILENO) verb = 1; - - ts2es_opt(fdin, pidv, &p, verb); -} - - -void change_aspect(int fdin, int fdout, int aspect) -{ - ps_packet ps; - pes_packet pes; - int neof,i; - - do { - init_ps(&ps); - neof = read_ps(fdin,&ps); - write_ps(fdout,&ps); - for (i = 0; i < ps.npes; i++){ - uint8_t *buf; - int c = 0; - int l; - - init_pes(&pes); - read_pes(fdin, &pes); - - buf = pes.pes_pckt_data; - - switch (pes.stream_id){ - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - l=pes.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] == 0xB3) { - c += 4; - buf[c+3] &= 0x0f; - buf[c+3] |= aspect; - } - else c++; - } - write_pes(fdout,&pes); - } - } while( neof > 0 ); -} diff --git a/libdvbmpeg/transform.h b/libdvbmpeg/transform.h deleted file mode 100644 index ad32706..0000000 --- a/libdvbmpeg/transform.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * 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 -#include -#include -#include -#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_*/ - - - diff --git a/mvpclient.c b/mvpclient.c index a4c3dac..181eda9 100644 --- a/mvpclient.c +++ b/mvpclient.c @@ -249,6 +249,9 @@ void MVPClient::run2() case 21: result = processGetMarks(data, packetLength); break; + case 22: + result = processGetChannelPids(data, packetLength); + break; } free(buffer); @@ -593,6 +596,56 @@ int MVPClient::processGetChannelsList(UCHAR* data, int length) return 1; } +int MVPClient::processGetChannelPids(UCHAR* data, int length) +{ + ULONG channelNumber = ntohl(*(ULONG*)data); + + cChannel* channel = channelFromNumber(channelNumber); + if (!channel) + { + sendULONG(0); + return 1; + } + + ULONG numApids = 0; + ULONG spaceRequired = 12; // 4 for length field, 4 for vpid, 4 for number of apids + // Work out space required and number of Apids + for (const int *Apid = channel->Apids(); *Apid; Apid++) + { + spaceRequired += 4 + strlen(channel->Alang(numApids)) + 1; // 4 for pid, length of string + \0 + numApids++; + } + + // Format of response + // vpid + // number of apids + // { + // apid + // lang string + // } + + UCHAR* sendBuffer = new UCHAR[spaceRequired]; + ULONG point = 0; + *(ULONG*)&sendBuffer[point] = htonl(spaceRequired - 4); point += 4; // take off first 4 bytes + *(ULONG*)&sendBuffer[point] = htonl(channel->Vpid()); point += 4; + *(ULONG*)&sendBuffer[point] = htonl(numApids); point += 4; + + for (ULONG i = 0; i < numApids; i++) + { + *(ULONG*)&sendBuffer[point] = htonl(channel->Apid(i)); point += 4; + strcpy((char*)&sendBuffer[point], channel->Alang(i)); point += strlen(channel->Alang(i)) + 1; + } + + printf("About to send getchannelpids response. length = %u\n", spaceRequired); + tcp.dump(sendBuffer, spaceRequired); + + tcp.sendPacket(sendBuffer, spaceRequired); + delete[] sendBuffer; + log->log("Client", Log::DEBUG, "Written channels pids"); + + return 1; +} + int MVPClient::processStartStreamingChannel(UCHAR* data, int length) { log->log("Client", Log::DEBUG, "length = %i", length); diff --git a/mvpclient.h b/mvpclient.h index 063e272..296f795 100644 --- a/mvpclient.h +++ b/mvpclient.h @@ -83,6 +83,7 @@ class MVPClient int processGetIFrame(UCHAR* data, int length); int processGetRecInfo(UCHAR* data, int length); int processGetMarks(UCHAR* data, int length); + int processGetChannelPids(UCHAR* data, int length); int processReScanRecording(UCHAR* data, int length); // FIXME obselete diff --git a/mvpreceiver.c b/mvpreceiver.c index ee29272..f11308b 100755 --- a/mvpreceiver.c +++ b/mvpreceiver.c @@ -32,44 +32,12 @@ MVPReceiver::MVPReceiver(cChannel* channel, cDevice* device) logger = Log::getInstance(); vdrActivated = false; inittedOK = 0; - remuxer = NULL; - unprocessed = NULL; - // Init - - // Get the remuxer for audio or video - -#if VDRVERSNUM < 10300 -// if ((channel->Vpid() == 0) || (channel->Vpid() == 1) || (channel->Vpid() == 0x1FFF)) -// { -// remuxer = new cTS2ESRemux(channel->Apid1()); -// logger->log("MVPReceiver", Log::DEBUG, "Created new < 1.3 TS->ES"); -// } -// else -// { - remuxer = new cTS2PSRemux(channel->Vpid(), channel->Apid1(), 0, 0, 0, 0); - logger->log("MVPReceiver", Log::DEBUG, "Created new < 1.3 TS->PS"); -// } -#else -// if ((channel->Vpid() == 0) || (channel->Vpid() == 1) || (channel->Vpid() == 0x1FFF)) -// { -// remuxer = new cTS2ESRemux(channel->Apid(0)); -// logger->log("MVPReceiver", Log::DEBUG, "Created new > 1.3 TS->ES"); -// } -// else -// { - remuxer = new cTS2PSRemux(channel->Vpid(), channel->Apid(0), 0, 0, 0, 0); - logger->log("MVPReceiver", Log::DEBUG, "Created new > 1.3 TS->PS"); -// } -#endif - - unprocessed = new cRingBufferLinear(1000000, TS_SIZE * 2, false); + logger->log("MVPReceiver", Log::DEBUG, "Channel has VPID %i APID %i", channel->Vpid(), channel->Apid(0)); if (!processed.init(1000000)) return; pthread_mutex_init(&processedRingLock, NULL); - if (!threadStart()) return; - // OK inittedOK = 1; @@ -85,9 +53,6 @@ int MVPReceiver::init() MVPReceiver::~MVPReceiver() { Detach(); - if (threadIsActive()) threadCancel(); - if (unprocessed) delete unprocessed; - if (remuxer) delete remuxer; } void MVPReceiver::Activate(bool on) @@ -104,56 +69,9 @@ bool MVPReceiver::isVdrActivated() void MVPReceiver::Receive(UCHAR* data, int length) { - static int receiveCount = 0; - -// int p = unprocessed->Put(data, length); -// if (p != length) printf("Buffer overrun\n"); - - unprocessed->Put(data, length); - - if (++receiveCount == 15) - { - threadSignal(); - receiveCount = 0; - } -} - -void MVPReceiver::threadMethod() -{ - int amountGot; - UCHAR* dataGot; - - int remuxTook; - UCHAR* remuxedData; - int outputSize; - - while(1) - { - threadWaitForSignal(); - - while(1) - { - dataGot = unprocessed->Get(amountGot); - if (dataGot && (amountGot > 0)) - { - outputSize = 0; - remuxTook = amountGot; - remuxedData = remuxer->Process(dataGot, remuxTook, outputSize); - unprocessed->Del(remuxTook); - - pthread_mutex_lock(&processedRingLock); - processed.put(remuxedData, outputSize); - pthread_mutex_unlock(&processedRingLock); - -// logger->log("MVPReceiver", Log::DEBUG, "Got from unprocessed: %i, Got from remux: %p %i, consumed: %i", -// amountGot, remuxedData, outputSize, remuxTook); - } - else - { - break; - } - } - } + pthread_mutex_lock(&processedRingLock); + processed.put(data, length); + pthread_mutex_unlock(&processedRingLock); } unsigned long MVPReceiver::getBlock(unsigned char* buffer, unsigned long amount) diff --git a/mvpreceiver.h b/mvpreceiver.h index 2606877..f6cb63e 100755 --- a/mvpreceiver.h +++ b/mvpreceiver.h @@ -24,17 +24,12 @@ #include #include #include -#include - -#include "tsremux.h" -#include "ts2es.h" -#include "ts2ps.h" #include "log.h" #include "thread.h" #include "ringbuffer.h" -class MVPReceiver : public cReceiver, public Thread +class MVPReceiver : public cReceiver { public: static MVPReceiver* create(cChannel*, int priority); @@ -45,14 +40,10 @@ class MVPReceiver : public cReceiver, public Thread private: MVPReceiver(cChannel* channel, cDevice* device); - void threadMethod(); Log* logger; bool vdrActivated; int inittedOK; - cTSRemux* remuxer; - cRingBufferLinear* unprocessed; // A VDR ring buffer used for the unprocessed data - // it doesn't delete until told and does its own locking Ringbuffer processed; // A simpler deleting ringbuffer for processed data pthread_mutex_t processedRingLock; // needs outside locking diff --git a/remux/README b/remux/README deleted file mode 100644 index 0ee66d8..0000000 --- a/remux/README +++ /dev/null @@ -1,7 +0,0 @@ -These remux files are taken from the mediamvp plugin for VDR, -which takes them from the streamdev plugin for VDR. - -So these files are written by, and Copyright, Sascha Volkenandt. -I think. - - diff --git a/remux/ts2es.c b/remux/ts2es.c deleted file mode 100644 index 68b41f0..0000000 --- a/remux/ts2es.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "ts2es.h" - -// from VDR's remux.c -#define MAXNONUSEFULDATA (10*1024*1024) - -class cTS2ES: public ipack { - friend void PutES(uint8_t *Buffer, int Size, void *Data); - -private: - uint8_t *m_ResultBuffer; - int *m_ResultCount; - -public: - cTS2ES(uint8_t *ResultBuffer, int *ResultCount); - ~cTS2ES(); - - void PutTSPacket(const uint8_t *Buffer); -}; - -void PutES(uint8_t *Buffer, int Size, void *Data) { - cTS2ES *This = (cTS2ES*)Data; - uint8_t payl = Buffer[8] + 9 + This->start - 1; - int count = Size - payl; - - if (*This->m_ResultCount + count > RESULTBUFFERSIZE) { - esyslog("ERROR: result buffer overflow (%d + %d > %d)", - *This->m_ResultCount, count, RESULTBUFFERSIZE); - count = RESULTBUFFERSIZE - *This->m_ResultCount; - } - memcpy(This->m_ResultBuffer + *This->m_ResultCount, Buffer + payl, count); - *This->m_ResultCount += count; - This->start = 1; -} - -cTS2ES::cTS2ES(uint8_t *ResultBuffer, int *ResultCount) { - m_ResultBuffer = ResultBuffer; - m_ResultCount = ResultCount; - - init_ipack(this, IPACKS, PutES, 0); - data = (void*)this; -} - -cTS2ES::~cTS2ES() { -} - -void cTS2ES::PutTSPacket(const uint8_t *Buffer) { - if (!Buffer) - return; - - if (Buffer[1] & 0x80) { // ts error - // TODO - } - - if (Buffer[1] & 0x40) { // payload start - if (plength == MMAX_PLENGTH - 6) { - plength = found - 6; - found = 0; - send_ipack(this); - reset_ipack(this); - } - } - - uint8_t off = 0; - - if (Buffer[3] & 0x20) { // adaptation field? - off = Buffer[4] + 1; - if (off + 4 > TS_SIZE - 1) - return; - } - - instant_repack((uint8_t*)(Buffer + 4 + off), TS_SIZE - 4 - off, this); -} - -cTS2ESRemux::cTS2ESRemux(int Pid): - cTSRemux(false) { - m_Pid = Pid; - m_Remux = new cTS2ES(m_ResultBuffer, &m_ResultCount); -} - -cTS2ESRemux::~cTS2ESRemux() { - delete m_Remux; -} - -void cTS2ESRemux::PutTSPacket(int Pid, const uint8_t *Data) { - if (Pid == m_Pid) m_Remux->PutTSPacket(Data); -} - diff --git a/remux/ts2es.h b/remux/ts2es.h deleted file mode 100644 index 52e9918..0000000 --- a/remux/ts2es.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef VDR_STREAMDEV_TS2ESREMUX_H -#define VDR_STREAMDEV_TS2ESREMUX_H - -#include "tsremux.h" - -class cTS2ES; - -class cTS2ESRemux: public cTSRemux { -private: - int m_Pid; - cTS2ES *m_Remux; - -protected: - virtual void PutTSPacket(int Pid, const uint8_t *Data); - -public: - cTS2ESRemux(int Pid); - virtual ~cTS2ESRemux(); -}; - -#endif // VDR_STREAMDEV_TS2ESREMUX_H diff --git a/remux/ts2ps.c b/remux/ts2ps.c deleted file mode 100644 index f7f0f99..0000000 --- a/remux/ts2ps.c +++ /dev/null @@ -1,114 +0,0 @@ -#include "ts2ps.h" - -class cTS2PS { - friend void PutPES(uint8_t *Buffer, int Size, void *Data); - -private: - ipack m_Ipack; - uint8_t *m_ResultBuffer; - int *m_ResultCount; - -public: - cTS2PS(uint8_t *ResultBuffer, int *ResultCount, uint8_t AudioCid = 0x00, - bool PS = false); - ~cTS2PS(); - - void PutTSPacket(const uint8_t *Buffer); -}; - -void PutPES(uint8_t *Buffer, int Size, void *Data) { - cTS2PS *This = (cTS2PS*)Data; - if (Size <= 0 || !Buffer || !This ) { - esyslog("ERROR: negative size or null pointers"); - return; - } - if (*This->m_ResultCount + Size > RESULTBUFFERSIZE) { - esyslog("ERROR: result buffer overflow (%d + %d > %d)", - *This->m_ResultCount, Size, RESULTBUFFERSIZE); - Size = RESULTBUFFERSIZE - *This->m_ResultCount; - } - memcpy(This->m_ResultBuffer + *This->m_ResultCount, Buffer, Size); - *This->m_ResultCount += Size; -} - -cTS2PS::cTS2PS(uint8_t *ResultBuffer, int *ResultCount, uint8_t AudioCid, - bool PS) { - m_ResultBuffer = ResultBuffer; - m_ResultCount = ResultCount; - - init_ipack(&m_Ipack, IPACKS, PutPES, PS); - m_Ipack.cid = AudioCid; - m_Ipack.data = (void*)this; -} - -cTS2PS::~cTS2PS() { -} - -void cTS2PS::PutTSPacket(const uint8_t *Buffer) { - if (!Buffer) - return; - - if (Buffer[1] & 0x80) { // ts error - // TODO - } - - if (Buffer[1] & 0x40) { // payload start - if (m_Ipack.plength == MMAX_PLENGTH - 6 && m_Ipack.found > 6) { - m_Ipack.plength = m_Ipack.found - 6; - m_Ipack.found = 0; - send_ipack(&m_Ipack); - reset_ipack(&m_Ipack); - } - } - - uint8_t off = 0; - - if (Buffer[3] & 0x20) { // adaptation field? - off = Buffer[4] + 1; - if (off + 4 > TS_SIZE - 1) - return; - } - - instant_repack((uint8_t*)(Buffer + 4 + off), TS_SIZE - 4 - off, &m_Ipack); -} - -cTS2PSRemux::cTS2PSRemux(int VPid, int APid1, int APid2, int DPid1, - int DPid2, bool PS) -{ - m_VPid = VPid; - m_APid1 = APid1; - m_APid2 = APid2; - m_DPid1 = DPid1; - m_DPid2 = DPid2; - - if (!m_VPid) m_Sync = 0; // CJT - - m_VRemux = VPid ? new cTS2PS(m_ResultBuffer, &m_ResultCount, 0x00, PS) - : NULL; // CJT edit to allow 0 APid - m_ARemux1 = new cTS2PS(m_ResultBuffer, &m_ResultCount, 0xC0, PS); - m_ARemux2 = APid2 ? new cTS2PS(m_ResultBuffer, &m_ResultCount, 0xC1, PS) - : NULL; - m_DRemux1 = DPid1 ? new cTS2PS(m_ResultBuffer, &m_ResultCount, 0x00, PS) - : NULL; - //XXX don't yet know how to tell apart primary and secondary DD data... - m_DRemux2 = /*XXX m_DPid2 ? new cTS2PS(m_ResultBuffer, &m_ResultCount, - 0x00, PS) : XXX*/ NULL; -} - -cTS2PSRemux::~cTS2PSRemux() { - if (m_DRemux2) delete m_DRemux2; - if (m_DRemux1) delete m_DRemux1; - if (m_VRemux) delete m_VRemux; // CJT - if (m_ARemux2) delete m_ARemux2; - delete m_ARemux1; -// delete m_VRemux; -} - -void cTS2PSRemux::PutTSPacket(int Pid, const uint8_t *Data) { - if (Pid == m_VPid && m_VRemux /* CJT */ ) m_VRemux->PutTSPacket(Data); - else if (Pid == m_APid1) m_ARemux1->PutTSPacket(Data); - else if (Pid == m_APid2 && m_ARemux2) m_ARemux2->PutTSPacket(Data); - else if (Pid == m_DPid1 && m_DRemux1) m_DRemux1->PutTSPacket(Data); - else if (Pid == m_DPid2 && m_DRemux2) m_DRemux2->PutTSPacket(Data); -} - diff --git a/remux/ts2ps.h b/remux/ts2ps.h deleted file mode 100644 index add96aa..0000000 --- a/remux/ts2ps.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef VDR_STREAMDEV_TS2PESREMUX_H -#define VDR_STREAMDEV_TS2PESREMUX_H - -#include "tsremux.h" - -#include "../log.h" - -class cTS2PS; - -class cTS2PSRemux: public cTSRemux { -private: - int m_VPid, m_APid1, m_APid2, m_DPid1, m_DPid2; - cTS2PS *m_VRemux, *m_ARemux1, *m_ARemux2, *m_DRemux1, *m_DRemux2; - -protected: - virtual void PutTSPacket(int Pid, const uint8_t *Data); - -public: - cTS2PSRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, - bool PS = false); - virtual ~cTS2PSRemux(); -}; - -#endif // VDR_STREAMDEV_TS2PESREMUX_H diff --git a/remux/tsremux.c b/remux/tsremux.c deleted file mode 100644 index 490c250..0000000 --- a/remux/tsremux.c +++ /dev/null @@ -1,215 +0,0 @@ -#include "tsremux.h" - -// from VDR's remux.c -#define MAXNONUSEFULDATA (10*1024*1024) -#define SC_PICTURE 0x00 // "picture header" -#define VIDEO_STREAM_S 0xE0 - -cTSRemux::cTSRemux(bool Sync) { - memset(m_PROTECTION1, 0x20, PROTECTIONSIZE); - m_ResultCount = 0; - m_ResultDelivered = 0; - m_Synced = false; - m_Skipped = 0; - m_Sync = Sync; -} - -cTSRemux::~cTSRemux(void) { -} - -uchar *cTSRemux::Process(const uchar *Data, int &Count, int &Result) -{ - // Remove any previously delivered data from the result buffer: - if (m_ResultDelivered) - { - if (m_ResultDelivered < m_ResultCount) - memmove(m_ResultBuffer, m_ResultBuffer + m_ResultDelivered, m_ResultCount - m_ResultDelivered); - - m_ResultCount -= m_ResultDelivered; - m_ResultDelivered = 0; - } - - int used = 0; - - // Make sure we are looking at a TS packet: - while (Count > TS_SIZE) - { - if (Data[0] == 0x47 && Data[TS_SIZE] == 0x47) break; - Data++; - Count--; - used++; - } - - if (used) esyslog("ERROR: skipped %d byte to sync on TS packet", used); - - // Convert incoming TS data - for (int i = 0; i < Count; i += TS_SIZE) - { - if (Count - i < TS_SIZE) break; - if (Data[i] != 0x47) break; - - int pid = get_pid((uint8_t*)(Data + i + 1)); - if (Data[i + 3] & 0x10) - { - // got payload - PutTSPacket(pid, Data + i); - } - /*if (pid == m_VPid) m_VRemux->ConvertTSPacket(Data + i); - else if (pid == m_APid1) m_ARemux1->ConvertTSPacket(Data + i); - else if (pid == m_APid2 && m_ARemux2) m_ARemux2->ConvertTSPacket(Data + i); - else if (pid == m_DPid1 && m_DRemux1) m_DRemux1->ConvertTSPacket(Data + i); - else if (pid == m_DPid2 && m_DRemux2) m_DRemux2->ConvertTSPacket(Data + i);*/ - used += TS_SIZE; - if (m_ResultCount > (int)sizeof(m_ResultBuffer) / 2) - break; - -#if 0 - if (memcmp(m_PROTECTION1, m_PROTECTION1+(PROTECTIONSIZE/2), PROTECTIONSIZE/2)) { - int ow_from = -1; // counted from _end_ of protection buffer - int ow_to = -1; // counted from _end_ of protection buffer - for (int pi=0; pi= 0) { - if (m_Skipped > MAXNONUSEFULDATA) { - esyslog("ERROR: no useful data seen within %d byte of video stream", m_Skipped); - m_Skipped = -1; - //if (exitOnFailure) - //cThread::EmergencyExit(true); - } - else - m_Skipped += Count; - } - - // Check for frame borders: - - if (m_ResultCount >= MINVIDEODATA) { - for (int i = 0; i < m_ResultCount; i++) { - if (m_ResultBuffer[i] == 0 && m_ResultBuffer[i + 1] == 0 && m_ResultBuffer[i + 2] == 1) { - switch (m_ResultBuffer[i + 3]) { - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - { - uchar pt = NO_PICTURE; - int l = ScanVideoPacket(m_ResultBuffer, m_ResultCount, i, pt); - if (l < 0) - return NULL; // no useful data found, wait for more - if (pt != NO_PICTURE) { - if (pt < I_FRAME || B_FRAME < pt) - esyslog("ERROR: unknown picture type '%d'", pt); - else if (!m_Synced) { - if (pt == I_FRAME) { - m_ResultDelivered = i; // will drop everything before this position - SetBrokenLink(m_ResultBuffer + i, l); - m_Synced = true; - } - else { - m_ResultDelivered = i + l; // will drop everything before and including this packet - return NULL; - } - } - } - if (m_Synced) { - Result = l; - uchar *p = m_ResultBuffer + m_ResultDelivered; - m_ResultDelivered += l; - return p; - } - else { - m_ResultDelivered = i + l; // will drop everything before and including this packet - return NULL; - } - } - break; - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - { - int l = GetPacketLength(m_ResultBuffer, m_ResultCount, i); - if (l < 0) - return NULL; // no useful data found, wait for more - - /* This shouldn't be happening - why does it for some channels? */ - if ( l > m_ResultCount ) - return NULL; - if (m_Synced) { - Result = l; - uchar *p = m_ResultBuffer + m_ResultDelivered; - m_ResultDelivered += l; - return p; - } - else { - m_ResultDelivered = i + l; // will drop everything before and including this packet - return NULL; - } - } - break; - } - } - } - } - return NULL; // no useful data found, wait for more -} - -int cTSRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType) { - // Scans the video packet starting at Offset and returns its length. - // If the return value is -1 the packet was not completely in the buffer. - - int Length = GetPacketLength(Data, Count, Offset); - if (Length > 0 && Offset + Length <= Count) { - int i = Offset + 8; // the minimum length of the video packet header - i += Data[i] + 1; // possible additional header bytes - for (; i < Offset + Length; i++) { - if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1) { - switch (Data[i + 3]) { - case SC_PICTURE: PictureType = (Data[i + 5] >> 3) & 0x07; - return Length; - } - } - } - PictureType = NO_PICTURE; - return Length; - } - return -1; -} - -int cTSRemux::GetPacketLength(const uchar *Data, int Count, int Offset) { - // Returns the entire length of the packet starting at offset, or -1 in case of error. - return (Offset + 5 < Count) ? (Data[Offset + 4] << 8) + Data[Offset + 5] + 6 : -1; -} - -void cTSRemux::SetBrokenLink(uchar *Data, int Length) { - if (Length > 9 && Data[0] == 0 && Data[1] == 0 && Data[2] == 1 && (Data[3] & VIDEO_STREAM_S) == VIDEO_STREAM_S) { - for (int i = Data[8] + 9; i < Length - 7; i++) { // +9 to skip video packet header - if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1 && Data[i + 3] == 0xB8) { - if (!(Data[i + 7] & 0x40)) // set flag only if GOP is not closed - Data[i + 7] |= 0x20; - return; - } - } - dsyslog("SetBrokenLink: no GOP header found in video packet"); - } - else - dsyslog("SetBrokenLink: no video packet in frame"); -} diff --git a/remux/tsremux.h b/remux/tsremux.h deleted file mode 100644 index a4255f2..0000000 --- a/remux/tsremux.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef VDR_STREAMDEV_TSREMUX_H -#define VDR_STREAMDEV_TSREMUX_H - -#include "transform.h" -#include - -#include "../log.h" - -#define IPACKS 2048 - -#define PROTECTIONSIZE 32768 - -#ifndef RESULTBUFFERSIZE -#define RESULTBUFFERSIZE KILOBYTE(256) -#endif -#ifndef MINVIDEODATA -#define MINVIDEODATA (16*1024) -#endif - -class cTSRemux { -protected: - uchar m_PROTECTION1[PROTECTIONSIZE]; // something sometimes overwrites vtbl without this buffer - uchar m_ResultBuffer[RESULTBUFFERSIZE]; - int m_ResultCount; - int m_ResultDelivered; - int m_Synced; - int m_Skipped; - - int GetPacketLength(const uchar *Data, int Count, int Offset); - int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); - - virtual void PutTSPacket(int Pid, const uint8_t *Data) = 0; - -public: - int m_Sync;// CJT moved from protected - - cTSRemux(bool Sync = true); - virtual ~cTSRemux(); - - virtual uchar *Process(const uchar *Data, int &Count, int &Result); - - static void SetBrokenLink(uchar *Data, int Length); -}; - -#endif // VDR_STREAMDEV_TSREMUX_H -- 2.39.2