summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Regel <andreas.regel@powarman.de>2004-01-28 19:11:00 +0100
committerAndreas Regel <andreas.regel@powarman.de>2004-01-28 19:11:00 +0100
commit64fe6b70d0a5b34a80ff458fbf1664018d5c0182 (patch)
tree4fe036adaf90fef0d0dc910b84dbc11269e40008
parent310f5b2a62343d0c9b7624c09efe35828785ef26 (diff)
downloadvdr-plugin-osdpip-0.0.3.tar.gz
vdr-plugin-osdpip-0.0.3.tar.bz2
Release version 0.0.3v0.0.3
- new TS->ES remuxer: now using VDR's cRemux for TS->PES and some own code for PES->ES - now using libavcodec from ffmpeg instead of mpeg2dec - frames to decode configurable (I-frames, I-/P-frames, all frames) - frame dropping configurable - added new color depths: - 128 shades greyscale - 128 colors with variable palette using Wu's quantizer (patch needed) - changed osd size setting to 6 configurable values
-rw-r--r--HISTORY12
-rw-r--r--Makefile17
-rw-r--r--README52
-rw-r--r--TODO6
-rw-r--r--config.c80
-rw-r--r--config.h20
-rw-r--r--i18n.c6
-rw-r--r--i18n.h6
-rw-r--r--libdvbmpeg/.cvsignore1
-rw-r--r--libdvbmpeg/DVB.hh446
-rw-r--r--libdvbmpeg/Makefile33
-rw-r--r--libdvbmpeg/OSD.h30
-rw-r--r--libdvbmpeg/channel.h58
-rw-r--r--libdvbmpeg/ci.hh167
-rw-r--r--libdvbmpeg/cpptools.cc946
-rw-r--r--libdvbmpeg/cpptools.hh330
-rw-r--r--libdvbmpeg/ctools.c2379
-rw-r--r--libdvbmpeg/ctools.h404
-rw-r--r--libdvbmpeg/devices.hh310
-rw-r--r--libdvbmpeg/osd.hh84
-rw-r--r--libdvbmpeg/remux.c1215
-rw-r--r--libdvbmpeg/remux.h149
-rw-r--r--libdvbmpeg/ringbuffy.c200
-rw-r--r--libdvbmpeg/ringbuffy.h52
-rw-r--r--libdvbmpeg/transform.c2681
-rw-r--r--libdvbmpeg/transform.h250
-rw-r--r--osd.c417
-rw-r--r--osd.h45
-rw-r--r--osdpip.c20
-rw-r--r--patches/vdr-1.2.6.diff77
-rw-r--r--patches/vdr-1.2.6_256.diff75
-rw-r--r--pes.c35
-rw-r--r--pes.h31
-rw-r--r--quantize.c511
-rw-r--r--quantize.h96
-rw-r--r--receiver.c39
-rw-r--r--receiver.h15
-rw-r--r--remux/ts2es.c87
-rw-r--r--remux/ts2es.h21
-rw-r--r--remux/ts2ps.c104
-rw-r--r--remux/ts2ps.h22
-rw-r--r--remux/tsremux.c185
-rw-r--r--remux/tsremux.h30
43 files changed, 1349 insertions, 10395 deletions
diff --git a/HISTORY b/HISTORY
index fc113f1..defe59b 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,18 @@
VDR Plugin 'osdpip' Revision History
------------------------------------
+2004-01-28: Version 0.0.3 (written by Andreas Regel)
+
+- new TS->ES remuxer: now using VDR's cRemux for TS->PES and some own code
+ for PES->ES
+- now using libavcodec from ffmpeg instead of mpeg2dec
+- frames to decode configurable (I-frames, I-/P-frames, all frames)
+- frame dropping configurable
+- added new color depths:
+ - 128 shades greyscale
+ - 128 colors with variable palette using Wu's quantizer (patch needed)
+- changed osd size setting to 6 configurable values
+
2004-01-03: Version 0.0.2
- Added setup menu
diff --git a/Makefile b/Makefile
index 74a085f..7d0906a 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
### The directory environment:
DVBDIR = ../../../../DVB
+FFMDIR = ../../../../ffmpeg
VDRDIR = ../../..
LIBDIR = ../../lib
TMPDIR = /tmp
@@ -40,18 +41,17 @@ PACKAGE = vdr-$(ARCHIVE)
### Includes and Defines (add further entries here):
-INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -I.
-LIBS = -lmpeg2 -lmpeg2convert
+INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -I. -I$(FFMDIR)/libavcodec
+LIBS = -L$(FFMDIR)/libavcodec -lavcodec
DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o osd.o receiver.o config.o i18n.o \
- \
- remux/tsremux.o remux/ts2ps.o remux/ts2es.o
+OBJS = $(PLUGIN).o osd.o receiver.o config.o i18n.o pes.o quantize.o
-libdvbmpeg/libdvbmpegtools.a: libdvbmpeg/*.c libdvbmpeg/*.cc libdvbmpeg/*.h libdvbmpeg/*.hh
- make -C ./libdvbmpeg libdvbmpegtools.a
+ifdef FFMPEG_STATIC
+ DEFINES += -DHAVE_FFMPEG_STATIC
+endif
### Implicit rules:
@@ -71,7 +71,7 @@ $(DEPFILE): Makefile
all: libvdr-$(PLUGIN).so
-libvdr-$(PLUGIN).so: $(OBJS) libdvbmpeg/libdvbmpegtools.a
+libvdr-$(PLUGIN).so: $(OBJS)
$(CXX) $(CXXFLAGS) -shared -o $@ $^ $(LIBS)
@cp $@ $(LIBDIR)/$@.$(VDRVERSION)
@@ -85,4 +85,3 @@ dist: clean
clean:
@-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
- make -C libdvbmpeg clean
diff --git a/README b/README
index eae6037..a8e2095 100644
--- a/README
+++ b/README
@@ -1,6 +1,7 @@
This is a "plugin" for the Video Disk Recorder (VDR).
Written by: Sascha Volkenandt <sascha@akv-soft.de>
+ Andreas Regel <andreas.regel@powarman.de>
Project's homepage: http://www.magoa.net/linux/index.php?view=osdpip
@@ -11,9 +12,7 @@ See the file COPYING for license information.
Requirements:
-- libmpeg2 (http://libmpeg2.sourceforge.net) version 0.4.0 (OLDER VERSIONS
- DON'T WORK)
-
+- libavcodec from ffmpeg (http://ffmpeg.sourceforge.net) version 0.4.8
Description:
@@ -21,21 +20,29 @@ OSD Picture-in-Picture is a PlugIn that displays the current channel in a
small box on the screen (default upper right corner). You can switch up and
down now, watching the progress of the previous channel in the box. Quality is
not too good yet, and only I-Frames are displayed.
-From 0.0.2 on, the plugin supports two modes: grayscaled and 256 colored. If
-you want 256 colors, you'll need to upgrade your VDR to support a 256 color OSD
-with the provided patching instruction. You can choose the color depth in the
-setup menu. If you didn't patch VDR appropriately, you'll only be able to choose
-grayscaled mode.
-Also by 0.0.2, the plugin has the possibility to choose the PiP size (in the
-setup menu in factors of 1/x) and position (by moving it around using number
-keys) as well as crop dimensions.
-
-ATTENTION: To use PiP size factor 2 in 256 color mode, you need to set all crop
-values to >50 pixels.
+The plugin supports four modes:
+ - greyscaled (16 shades of grey)
+ - greyscaled (128 shades of grey)
+ - 256 colors with fixed palette
+ - 128 colors with variable palette
+The first mode works with an ordinary vdr installation. If you want to use the
+other modes, you'll need to upgrade your VDR to support a 256 color OSD
+with the provided patching instruction. The variable palette mode needs more
+extensive changes to VDR's source code using the provided patch that gives the
+plugin more control over the OSD's palette. You can choose the color depth in
+the setup menu. If you didn't patch VDR appropriately, you'll only be able to
+choose greyscaled mode.
+The plugin has the possibility to choose the PiP size (in the setup menu from
+predefined sizes) and position (by moving it around using number keys) as well
+as crop dimensions.
ATTENTION: To have the position saved, you have to enter the plugin's setup menu
and hit the ok button.
+From 0.0.3 on the plugin lets you choose the MPEG frames to decode and display
+(in the setup menu). For slower machines it is further possible to set an
+additional frame dropping.
+
Installation:
@@ -48,6 +55,14 @@ tar xvfz vdr-osdpip-0.0.1.tgz
ln -s osdpip-0.0.1 osdpip
cd ../..
+If you have ffmpeg installed, make plugins should do just fine now, but if you
+have it next to your vdr folder (e.g. as the DXR3 plugin needs it), you have
+to compile with make FFMPEG_STATIC=1 plugins. Ffmpeg must then be present in a
+folder (or symlink) called "ffmpeg".
+
+NOTE: The next step is not needed if you use the variable color patch provided
+below that!
+
Now, you have to call your favourite editor to open osdbase.h and jump to line
number 16. I don't provide a patch here because some patches already touch that
area. Well this one's easy, though. Just increase the number of colors in this
@@ -55,6 +70,15 @@ line to 256. If you don't want 256 color support, you can skip this part.
#define MAXNUMCOLORS 256
+If you want variable palette color mode you will have to further modify VDR's
+source code using a patch from patches subdirectory. I provide two versions of
+the patch: vdr-1.2.6.diff for a plain VDR installation and vdr-1.2.6_256.diff
+for a version that already has 256 color support.
+
+To apply this patch call
+ patch -p1 < PLUGINS/src/osdpip/patches/vdr-1.2.6.diff
+from VDR's source code directory.
+
Now, you have to re-build VDR and Plugins.
make [options, if necessary] vdr
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..8486f6b
--- /dev/null
+++ b/TODO
@@ -0,0 +1,6 @@
+- Show some info when switching channels in an extra OSD window
+ (this is a bit tricky when a 256-color OSD window is on screen,
+ but possible)
+- improve fixed palette color quantization
+- localization
+
diff --git a/config.c b/config.c
index 647a5a3..86ceb87 100644
--- a/config.c
+++ b/config.c
@@ -1,26 +1,68 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#include "config.h"
-int ColorDepths = (MAXNUMCOLORS == 256 ? 2 : 1);
#if MAXNUMCOLORS < 256
-# warning WARNING: YOU WILL NOT BE ABLE TO USE RGB PIP
+# warning WARNING: YOU WILL NOT BE ABLE TO USE 256 COLOR PIP
+#endif
+
+#ifndef VDR_OSDPIP_PATCHED
+# warning WARNING: YOU WILL NOT BE ABLE TO USE VARIABLE COLOR PIP
+#endif
+
+#if MAXNUMCOLORS < 256
+const int kColorDepths = 1;
+#else
+# ifndef VDR_OSDPIP_PATCHED
+const int kColorDepths = 3;
+# else
+const int kColorDepths = 4;
+# endif
#endif
+const int kSizes = 6;
+const int kFrameModes = 3;
+
const char *ColorDepthItems[] = {
- "Greyscale",
- "256 colors"
+ "Greyscale (16)",
+ "Greyscale (128)",
+ "Color (256, fixed)",
+ "Color (128, variable)"
+};
+
+const char *SizeItems[] = {
+ "120x96",
+ "160x128",
+ "200x160",
+ "240x192",
+ "280x224",
+ "320x256"
+};
+
+const char *FrameModeItems[] = {
+ "I-Frames",
+ "I-, P-Frames",
+ "I-, P-, B-Frames"
};
cOsdPipSetup OsdPipSetup;
cOsdPipSetup::cOsdPipSetup(void) {
- XPosition = 20;
- YPosition = 20;
+ XPosition = 50;
+ YPosition = 50;
CropLeft = 5;
CropRight = 5;
CropTop = 5;
CropBottom = 5;
- ZoomFactor = 3;
- ColorDepth = (MAXNUMCOLORS == 256 ? 1 : 0);
+ ColorDepth = kDepthGrey16;
+ Size = 2;
+ FrameMode = kFrameModeI;
+ FrameDrop = 0;
+ SwapFfmpeg = 1;
}
bool cOsdPipSetup::SetupParse(const char *Name, const char *Value) {
@@ -30,8 +72,11 @@ bool cOsdPipSetup::SetupParse(const char *Name, const char *Value) {
else if (strcmp(Name, "CropRight") == 0) CropRight = atoi(Value);
else if (strcmp(Name, "CropTop") == 0) CropTop = atoi(Value);
else if (strcmp(Name, "CropBottom") == 0) CropBottom = atoi(Value);
- else if (strcmp(Name, "ZoomFactor") == 0) ZoomFactor = atoi(Value);
else if (strcmp(Name, "ColorDepth") == 0) ColorDepth = atoi(Value);
+ else if (strcmp(Name, "Size") == 0) Size = atoi(Value);
+ else if (strcmp(Name, "FrameMode") == 0) FrameMode = atoi(Value);
+ else if (strcmp(Name, "FrameDrop") == 0) FrameDrop = atoi(Value);
+ else if (strcmp(Name, "SwapFfmpeg") == 0) SwapFfmpeg = atoi(Value);
else return false;
return true;
}
@@ -46,10 +91,14 @@ cOsdPipSetupPage::cOsdPipSetupPage(void) {
80));
Add(new cMenuEditIntItem(tr("Crop at bottom"), &m_NewOsdPipSetup.CropBottom,
0, 80));
- Add(new cMenuEditIntItem(tr("Zoom factor"), &m_NewOsdPipSetup.ZoomFactor, 2,
- 4));
- Add(new cMenuEditStraItem(tr("Colordepth"), &m_NewOsdPipSetup.ColorDepth,
- ColorDepths, ColorDepthItems));
+ Add(new cMenuEditStraItem(tr("Color depth"),
+ &m_NewOsdPipSetup.ColorDepth, kColorDepths, ColorDepthItems));
+ Add(new cMenuEditStraItem(tr("Size"),
+ &m_NewOsdPipSetup.Size, kSizes, SizeItems));
+ Add(new cMenuEditStraItem(tr("Frames to display"),
+ &m_NewOsdPipSetup.FrameMode, kFrameModes, FrameModeItems));
+ Add(new cMenuEditIntItem(tr("Drop frames"), &m_NewOsdPipSetup.FrameDrop, 0, 2));
+ Add(new cMenuEditBoolItem(tr("Swap FFMPEG output"), &m_NewOsdPipSetup.SwapFfmpeg));
}
cOsdPipSetupPage::~cOsdPipSetupPage() {
@@ -64,6 +113,9 @@ void cOsdPipSetupPage::Store(void) {
SetupStore("CropRight", OsdPipSetup.CropRight);
SetupStore("CropTop", OsdPipSetup.CropTop);
SetupStore("CropBottom", OsdPipSetup.CropBottom);
- SetupStore("ZoomFactor", OsdPipSetup.ZoomFactor);
SetupStore("ColorDepth", OsdPipSetup.ColorDepth);
+ SetupStore("Size", OsdPipSetup.Size);
+ SetupStore("FrameMode", OsdPipSetup.FrameMode);
+ SetupStore("FrameDrop", OsdPipSetup.FrameDrop);
+ SetupStore("SwapFfmpeg", OsdPipSetup.SwapFfmpeg);
}
diff --git a/config.h b/config.h
index 6141ab8..d7f645d 100644
--- a/config.h
+++ b/config.h
@@ -1,8 +1,23 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#ifndef VDR_OSDPIP_SETUP_H
#define VDR_OSDPIP_SETUP_H
#include <vdr/plugin.h>
+const int kDepthGrey16 = 0;
+const int kDepthGrey128 = 1;
+const int kDepthColor256fix = 2;
+const int kDepthColor128var = 3;
+
+const int kFrameModeI = 0;
+const int kFrameModeIP = 1;
+const int kFrameModeIPB = 2;
+
struct cOsdPipSetup {
cOsdPipSetup(void);
@@ -14,8 +29,11 @@ struct cOsdPipSetup {
int CropRight;
int CropTop;
int CropBottom;
- int ZoomFactor;
int ColorDepth;
+ int Size;
+ int FrameMode;
+ int FrameDrop;
+ int SwapFfmpeg;
};
extern cOsdPipSetup OsdPipSetup;
diff --git a/i18n.c b/i18n.c
index eebefe0..77ffe4b 100644
--- a/i18n.c
+++ b/i18n.c
@@ -1,3 +1,9 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#include "i18n.h"
const tI18nPhrase Phrases[] = {
diff --git a/i18n.h b/i18n.h
index a2b2d71..7ed5d79 100644
--- a/i18n.h
+++ b/i18n.h
@@ -1,3 +1,9 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#ifndef VDR_OSDPIP_I18N_H
#define VDR_OSDPIP_I18N_H
diff --git a/libdvbmpeg/.cvsignore b/libdvbmpeg/.cvsignore
deleted file mode 100644
index 4671378..0000000
--- a/libdvbmpeg/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-.depend
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 <asm/errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <time.h>
-#include <unistd.h>
-
-#define NEWSTRUCT
-#include <channel.h>
-}
-
-#include <sstream>
-#include <iostream>
-#include <iomanip>
-using namespace std;
-
-#include <osd.hh>
-#include <devices.hh>
-
-#ifndef MAXNAM
-#define MAXNAM 80
-#endif
-
-
-
-#define FRONT_DVBS 1
-#define FRONT_DVBC 2
-#define FRONT_DVBT 3
-
-#define VTXDIR "/var/vtx"
-
-#define DEC(N) dec << setw(N) << setfill('0')
-#define HEX(N) hex << setw(N) << setfill('0')
-
-#define MAXSECSIZE 4096
-
-#define NK 10
-enum {LNB=0,DIS,ROTOR,TRANS,CHAN,BOU,SAT,PICS,SWI,NTW};
-static const int nums[]={LNB,DIS,ROTOR,TRANS,CHAN,BOU,SAT,PICS,SWI,NTW};
-static const int maxs[]={ 32, 32, 32, 512,16384,512,100, 50, 10, 100};
-
-#define MAX_TRANS_CHAN 1024
-
-enum{DVB_ORIG=0, DVB_NOKIA, DVB_XML, DVB_SATCO};
-
-typedef struct frontend_stat_s{
- fe_status_t status;
- uint16_t snr;
- uint16_t strength;
- uint32_t ber;
- uint32_t u_blocks;
-} frontend_stat;
-
-
-extern uint8_t hamtab[256];
-extern uint8_t invtab[256];
-
-#define MAX_MAG 8
-typedef struct mag_struct_ {
- int valid;
- int magn;
- uint8_t flags;
- uint8_t lang;
- int pnum,sub;
- uint8_t pagebuf[25*40];
-} magazin_t;
-
-
-class DVB {
-public:
- int no_open;
- int fd_frontend;
- int fd_demuxa;
- int fd_demuxv;
- int fd_demuxpcr;
- int fd_demuxtt;
- int fdvb;
-
- int minor;
- int adapter;
- int max_tpid;
- int max_satid;
- int max_chanid;
-
- frontend_stat festat;
-
- struct dvb_diseqc_master_cmd dcmd;
- fe_sec_tone_mode_t tone;
- fe_sec_voltage_t voltage;
- int burst;
- struct dmx_pes_filter_params pesFilterParamsV;
- struct dmx_pes_filter_params pesFilterParamsA;
- struct dmx_pes_filter_params pesFilterParamsP;
- struct dmx_pes_filter_params pesFilterParamsTT;
- struct dvb_frontend_parameters front_param;
- int front_type;
- int dvr_enabled;
- OSD osd;
- uint32_t transponder_freq;
- char transponder_pol;
- uint32_t transponder_srate;
-
-
-
- fe_status_t status;
- uint32_t ber, uncorrected_blocks;
- uint16_t snr, signal;
-
-
- struct Lnb *lnbs;
- struct DiSEqC *diseqcs;
- struct Rotor *rotors;
- struct Transponder *tps;
- struct Channel *chans;
- struct Bouquet *bouqs;
- struct Sat *sats;
- struct Picture *pics;
- struct Switch *swis;
- struct Network *ntws;
- int num[NK];
- int oldsec;
- int tryit;
- int oldpol;
-
- char *vtxdir;
- magazin_t magazin[MAX_MAG];
-
- DVB(){
- no_open = 0;
- max_tpid = 0;
- max_satid = 0;
- max_chanid = 0;
- minor = 0;
-
- fd_frontend = -1;
- fd_demuxa = -1;
- fd_demuxpcr = -1;
- fd_demuxv = -1;
- fd_demuxtt = -1;
- fdvb = -1;
- vtxdir = NULL;
- transponder_freq=0;
- transponder_pol=0;
- transponder_srate=0;
- }
-
- DVB(int i){
- if (i >= 0)
- no_open = 0;
- else
- no_open = 1;
- max_tpid = 0;
- max_satid = 0;
- max_chanid = 0;
-
- fd_frontend = -1;
- fd_demuxa = -1;
- fd_demuxpcr = -1;
- fd_demuxv = -1;
- fd_demuxtt = -1;
- fdvb = -1;
- vtxdir = NULL;
- transponder_freq=0;
- transponder_pol=0;
- transponder_srate=0;
-
- init("","",i);
- }
-
- DVB(char *a, char *b) {
- max_tpid = 0;
- max_satid = 0;
- max_chanid = 0;
-
- fd_frontend = -1;
- fd_demuxa = -1;
- fd_demuxpcr = -1;
- fd_demuxv = -1;
- fd_demuxtt = -1;
-
- fdvb = -1;
- vtxdir = NULL;
- init(a,b,0);
- }
-
- ~DVB();
-
- void use_osd(int fd = -1){
- char dvn[32];
- if (no_open) return;
- if (fd < 0) fd = 0;
- sprintf(dvn,OSD_DEV,adapter,fd);
- fdvb = open(dvn, O_RDWR);
-
- if (fdvb >= 0){
- cerr << dvn << " for OSD" << endl;
- osd.init(fdvb);
- } else perror("osd");
- osd.Open(80, 500, 640, 540, 2, 0, 2);
- osd.SetColor(0, 0, 0, 0, 255);
- osd.SetColor(1, 240, 240, 240, 255);
- osd.Show();
- }
-
- void set_vtxdir(char *newname){
- if (!newname) return;
- if (vtxdir) free(vtxdir);
- vtxdir = (char *) malloc(sizeof(char)*(strlen(newname)+1));
- if (vtxdir)
- strncpy(vtxdir, newname, strlen(newname));
- }
-
- void close_osd(){
- osd.Close(fdvb);
- close(fdvb);
- }
-
- int DVR_enabled(){
- if (no_open) return -1;
- return dvr_enabled;
- }
-
- void enable_DVR(){
- if (no_open) return;
- dvr_enabled = 1;
- }
-
- void enable_DVR_other(){
- if (no_open) return;
- dvr_enabled = 2;
- }
-
- void disable_DVR(){
- if (no_open) return;
- dvr_enabled = 0;
- }
-
- void init(char *a="/dev/video0", char *b="/dev/vbi0",int adapt=0,
- int minor = 0);
-
-
- inline void init(char *a, char *b){
- if (no_open) return;
- init(a,b,0,0);
- }
-
- int check_frontend();
-
- void set_apid(ushort apid);
- void set_vpid(ushort vpid);
- void set_pcrpid(ushort vpid);
- void set_ttpid(ushort ttpid);
- int set_apid_fd(ushort apid, int fd);
- int set_vpid_fd(ushort vpid, int fd);
- int set_ttpid_fd(ushort ttpid, int fd);
- int set_pcrpid_fd(ushort pcrpid, int fd);
- int set_otherpid_fd(ushort otherpid, int fd);
-
-
- int set_lnb(int dis);
- void set_diseqc_nb(int nr);
- int set_front(void);
- void get_front(void);
-
- void scan_pf_eit(int chnr,
- int (*callback)(uint8_t *data, int l, int pnr,
- int c_n, uint8_t *t));
-
- void scan_pf_eit(Channel *chan,
- int (*callback)(uint8_t *data, int l, int pnr,
- int c_n, uint8_t *t));
- void scan_pf_eit(int chnr);
-
-
- int search_in_TP(Transponder &tp, int show=1, int verbose=0);
- int search_in_TP(uint16_t tpid, uint16_t satid, int show=1,
- int verbose=0);
- int scan_TP(uint16_t tpid, uint16_t satid, int timeout=-1, int verbose=0);
-
- int GetSection(uint8_t *buf,
- uint16_t PID, uint8_t TID, uint16_t TIDExt,
- uint16_t FilterTIDExt,
- uint8_t secnum, uint8_t &msecnum);
- int GetSection(uint8_t *buf,
- uint16_t PID, uint8_t *filter, uint8_t *mask,
- uint8_t secnum, uint8_t &msecnum);
- int GetSection(uint8_t *buf, ushort PID, uint8_t sec,
- uint8_t secnum, uint8_t &msecnum);
- int SetFilter(uint16_t pid, uint8_t *filter,
- uint8_t *mask,
- uint32_t timeout, uint32_t flags);
- uint16_t SetFilter(uint16_t pid, uint16_t section, uint16_t mode);
- int CloseFilter(int h);
-
-
- void bar2(int x, int y, int w, int h, int val, int col1, int col2);
-
- int SetTP(unsigned int, unsigned int);
- int scan(void);
- int scan_all_tps(void);
- int scan_lnb(struct Lnb &);
- int scan_cable(Sat &sat);
- int scan_sat(struct Sat &);
- int scan_tp(struct Transponder &);
-
- int AddLNB(int id, int t, uint l1, uint l2, uint sl,
- int dnr, int dis, int sw);
- int AddSat(Sat &sat);
- int AddSat(int satid, unsigned int lnbid, char *name, uint fmin, uint fmax);
- int AddTP(Transponder &tp);
- int AddChannel(Channel &chan);
- int parse_descriptor(Channel *chan, uint8_t *data, int length);
- int parse_pmt(Channel *chan, uint8_t *data);
- int parse_pat(Channel *chan, uint8_t *data);
-
- int check_pids(Channel *chan);
- void check_all_pids();
- void scan_sdt(Channel *chan);
- int scan_sdts(int *chs, int n);
-
- int channel_num(void) {
- return num[CHAN];
- };
-
- int channel_change(int n) {
- return 0;
- };
- int SetChannel(uint16_t, uint16_t, uint16_t, uint16_t);
- int SetChannel(Channel *chan, char* apref=NULL, uint16_t *apidp=NULL,
- uint16_t *vpidp=NULL) ;
- int SetChannel(int chnr, char *apref=NULL, uint16_t *apidp=NULL,
- uint16_t *vpidp=NULL);
- int GetChannel(int chnr, struct channel *);
- int NumChannel(void) {
- return num[CHAN];
- }
- int tune_it(struct dvb_frontend_parameters *qpsk);
- void find_satid(Channel &chan);
- int check_input_format(istream &ins);
- void read_original(istream &ins);
- int get_all_progs(uint16_t *progbuf, uint16_t *pnrbuf, int length);
- uint16_t find_pnr(uint16_t vpid, uint16_t apid);
- int get_pids(uint16_t prog_pid, uint16_t *vpid, uint16_t *apids,
- uint16_t *ttpid, uint8_t *apids_name=NULL);
- void AddECM(Channel *chan, uint8_t *data, int length);
- int check_ecm(Channel *chan);
- void add_vtx_line(magazin_t *mag, int line, uint8_t *data, int pnr);
-
- friend ostream &operator<<(ostream &stream, DVB &x);
- friend istream &operator>>(istream &stream, DVB &x);
-
-};
-
-#define NOKIA_MAX_SAT 4
-class nokiaconv{
-public:
- DVB *dvb;
- struct lnb_sat_l{
- int n;
- int diseqc[NOKIA_MAX_SAT];
- char sat_names[NOKIA_MAX_SAT][MAXNAM+1];
- int satid[NOKIA_MAX_SAT];
- } lnb_sat;
-
- nokiaconv(DVB *d){
- dvb = d;
- }
-
- friend istream &operator>>(istream &stream, nokiaconv &x);
-};
-
-#define XML_MAX_SAT 4
-class xmlconv{
-public:
- DVB *dvb;
- struct lnb_sat_l{
- int n;
- int diseqc[XML_MAX_SAT];
- char sat_names[XML_MAX_SAT][MAXNAM+1];
- int satid[XML_MAX_SAT];
- } lnb_sat;
-
- xmlconv(DVB *d){
- dvb = d;
- }
- int read_stream(istream &ins, int nchan);
- int read_desc(istream &ins, int nchan);
- int read_serv(istream &ins, int ctp, int csat);
- int read_trans(istream &ins, int satid);
- int read_sat(istream &ins, int satid = -1);
- int skip_tag(istream &ins, char *tag);
- int read_iso639(istream &ins, int nchan, int apids);
-
- friend istream &operator>>(istream &stream, xmlconv &x);
-};
-
-
-
-#define SATCO_MAX_SAT 10
-class satcoconv{
-public:
- DVB *dvb;
- int nlnb;
-
- satcoconv(DVB *d){
- dvb = d;
- }
-
- friend istream &operator>>(istream &stream, satcoconv &x);
-};
-
-void hdump(uint8_t *buf, int n);
-int get_dvbrc(char *path, DVB &dv, int dev, int len);
-int set_dvbrc(char *path, DVB &dv, int dev, int len);
-void dvb2txt(char *out, char *in, int len);
-int set_sfront(int fdf, uint32_t freq, uint32_t pol, uint32_t sr , int snum, fe_code_rate_t fec);
-void set_pes_filt(int fd,uint16_t pes_pid);
-void set_diseqc(int fdf, int snum, fe_sec_voltage_t v, fe_sec_tone_mode_t t);
-int tune(int fdf, uint32_t freq, uint32_t sr, fe_code_rate_t fec);
-int set_sfront(int fdf, uint32_t freq, uint32_t pol, uint32_t sr , int snum,
- fe_code_rate_t fec);
-
-
-struct in_addr getaddress (const char *name);
-int tcp_client_connect(const char *hostname, int sckt);
-int udp_client_connect(const char *filename);
-void client_send_msg(int fd, uint8_t *msg, int size);
-int chck_frontend (int fefd, frontend_stat *festat);
-
-uint8_t deham(uint8_t x, uint8_t y);
-
-#endif
diff --git a/libdvbmpeg/Makefile b/libdvbmpeg/Makefile
deleted file mode 100644
index a56cb6b..0000000
--- a/libdvbmpeg/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-INCS = -I.
-CFLAGS = -g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
-MFLAG = -M
-OBJS = ctools.o ringbuffy.o remux.o transform.o cpptools.o
-SRC = $(wildcard *.c)
-CPPSRC = $(wildcard *.cpp)
-CSRC = $(wildcard *.cc)
-
-DESTDIR = /usr/local
-
-.PHONY: depend clean install uninstall
-
-clean:
- - rm -f *.o *~ *.a .depend
-
-libdvbmpegtools.a: $(OBJS)
- ar -rcs libdvbmpegtools.a $(OBJS)
-
-%.o: %.cc
- $(CXX) -c $(CFLAGS) $(INCS) $(DEFINES) $<
-
-%.o: %.cpp
- $(CXX) -c $(CFLAGS) $(INCS) $(DEFINES) $<
-
-%.o: %.c
- $(CC) -c $(CFLAGS) $(INCS) $(DEFINES) $<
-
-.depend:
- $(CXX) $(DEFINES) $(MFLAG) $(SRC) $(CSRC) $(CPPSRC) $(INCS)> .depend
-
-
-
--include .depend
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 <sys/types.h>
-
-struct channel {
- int id;
- char name[81];
- int type;
- ushort pnr;
- ushort vpid;
- ushort apids[8];
- ushort apidnum;
- ushort ac3pid;
- ushort pcrpid;
-
- uint freq;
- int pol;
- int qam;
- uint srate;
- int fec;
-};
-
-#ifdef NEWSTRUCT
-
-#include <linux/dvb/dmx.h>
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
-
-#define DVR_DEV "/dev/dvb/adapter%d/dvr%d"
-#define VIDEO_DEV "/dev/dvb/adapter%d/video%d"
-#define AUDIO_DEV "/dev/dvb/adapter%d/audio%d"
-#define DEMUX_DEV "/dev/dvb/adapter%d/demux%d"
-#define FRONT_DEV "/dev/dvb/adapter%d/frontend%d"
-#define OSD_DEV "/dev/dvb/adapter%d/osd%d"
-#define CA_DEV "/dev/dvb/adapter%d/ca%d"
-
-#else
-
-#include <ost/dmx.h>
-#include <ost/frontend.h>
-#include <ost/sec.h>
-#include <ost/video.h>
-#include <ost/audio.h>
-
-#define DVR_DEV "/dev/ost/dvr%d"
-#define VIDEO_DEV "/dev/ost/video%d"
-#define AUDIO_DEV "/dev/ost/audio%d"
-#define DEMUX_DEV "/dev/ost/demux%d"
-#define FRONT_DEV "/dev/ost/frontend%d"
-#define OSD_DEV "/dev/ost/osd%d"
-#define CA_DEV "/dev/ost/ca%d"
-
-#endif
-
-
-#endif
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 <stdint.h>
-#include <stdio.h>
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-
-#define MAXCASYSTEMIDS 16
-
-class cMutex {
- friend class cCondVar;
-private:
- pthread_mutex_t mutex;
- pid_t lockingPid;
- int locked;
-public:
- cMutex(void);
- ~cMutex();
- void Lock(void);
- void Unlock(void);
- };
-
-class cMutexLock {
-private:
- cMutex *mutex;
- bool locked;
-public:
- cMutexLock(cMutex *Mutex = NULL);
- ~cMutexLock();
- bool Lock(cMutex *Mutex);
- };
-
-
-class cCiMMI;
-
-class cCiMenu {
- friend class cCiMMI;
-private:
- enum { MAX_CIMENU_ENTRIES = 64 }; ///< XXX is there a specified maximum?
- cCiMMI *mmi;
- bool selectable;
- char *titleText;
- char *subTitleText;
- char *bottomText;
- char *entries[MAX_CIMENU_ENTRIES];
- int numEntries;
- bool AddEntry(char *s);
- cCiMenu(cCiMMI *MMI, bool Selectable);
-public:
- ~cCiMenu();
- const char *TitleText(void) { return titleText; }
- const char *SubTitleText(void) { return subTitleText; }
- const char *BottomText(void) { return bottomText; }
- const char *Entry(int n) { return n < numEntries ? entries[n] : NULL; }
- int NumEntries(void) { return numEntries; }
- bool Selectable(void) { return selectable; }
- bool Select(int Index);
- bool Cancel(void);
- };
-
-class cCiEnquiry {
- friend class cCiMMI;
-private:
- cCiMMI *mmi;
- char *text;
- bool blind;
- int expectedLength;
- cCiEnquiry(cCiMMI *MMI);
-public:
- ~cCiEnquiry();
- const char *Text(void) { return text; }
- bool Blind(void) { return blind; }
- int ExpectedLength(void) { return expectedLength; }
- bool Reply(const char *s);
- bool Cancel(void);
- };
-
-class cCiCaPmt {
- friend class cCiConditionalAccessSupport;
-private:
- int length;
- int esInfoLengthPos;
- uint8_t capmt[2048]; ///< XXX is there a specified maximum?
-public:
- cCiCaPmt(int ProgramNumber);
- void AddPid(int Pid);
- void AddCaDescriptor(int Length, uint8_t *Data);
- };
-
-#define MAX_CI_SESSION 16 //XXX
-
-class cCiSession;
-class cCiTransportLayer;
-class cCiTransportConnection;
-
-class cCiHandler {
-private:
- cMutex mutex;
- int numSlots;
- bool newCaSupport;
- bool hasUserIO;
- cCiSession *sessions[MAX_CI_SESSION];
- cCiTransportLayer *tpl;
- cCiTransportConnection *tc;
- int ResourceIdToInt(const uint8_t *Data);
- bool Send(uint8_t Tag, int SessionId, int ResourceId = 0, int Status = -1);
- cCiSession *GetSessionBySessionId(int SessionId);
- cCiSession *GetSessionByResourceId(int ResourceId, int Slot);
- cCiSession *CreateSession(int ResourceId);
- bool OpenSession(int Length, const uint8_t *Data);
- bool CloseSession(int SessionId);
- int CloseAllSessions(int Slot);
- cCiHandler(int Fd, int NumSlots);
-public:
- ~cCiHandler();
- static cCiHandler *CreateCiHandler(const char *FileName);
- int NumSlots(void) { return numSlots; }
- bool Process(void);
- bool HasUserIO(void) { return hasUserIO; }
- bool EnterMenu(int Slot);
- cCiMenu *GetMenu(void);
- cCiEnquiry *GetEnquiry(void);
- bool SetCaPmt(cCiCaPmt &CaPmt);
- const unsigned short *GetCaSystemIds(int Slot);
- bool SetCaPmt(cCiCaPmt &CaPmt, int Slot);
- bool Reset(int Slot);
- };
-
-int tcp_listen(struct sockaddr_in *name,int sckt,unsigned long address=INADDR_ANY);
-int accept_tcp(int ip_sock,struct sockaddr_in *ip_name);
-int udp_listen(struct sockaddr_un *name,char const * const filename);
-int accept_udp(int ip_sock,struct sockaddr_un *ip_name);
-
-#endif //__CI_H
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<MAX_PID; i++)
- pid[i] = -1;
- while (!in.eof()) {
- ts.init();
- in >> ts;
- int j;
- int found = 0;
- for (j=0;j<npid;j++){
- if ( ts.PID() == pid[j] )
- found = 1;
- }
- if (! found){
- out << ts.PID() << " ";
- pid[npid] = ts.PID();
- npid++;
- if (npid == MAX_PID) return -1;
- }
- }
- out << endl;
- return 0;
-}
-
-int tv_norm(istream &stream){
- uint8_t headr[4];
- int found=0;
- streampos p = 0;
- streampos q = 0;
- int hsize,vsize;
- int form= 0;
-
- q = stream.tellg();
- while (!stream.eof() && !found) {
- p = stream.tellg();
- stream.read((char *)headr,4);
- if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
- if ( headr[3] == 0xB3 ){
- found = 1;
- }
- if (! found) stream.seekg(p+streampos(1));
- }
- stream.read((char *)headr,4);
-
- hsize = (headr[1] &0xF0) >> 4 | headr[0] << 4;
- vsize = (headr[1] &0x0F) << 8 | headr[2];
- cerr << "SIZE: " << hsize << "x" << vsize << endl;
-
- switch(((headr[3]&0xF0) >>4)){
- case 1:
- cerr << "ASPECT: 1:1" << endl;
- break;
- case 2:
- cerr << "ASPECT: 4:3" << endl;
- break;
- case 3:
- cerr << "ASPECT: 16:9" << endl;
- break;
- case 4:
- cerr << "ASPECT: 2.21:1" << endl;
- break;
- }
-
- switch (int(headr[3]&0x0F)){
- case 1:
- cerr << "FRAMERATE: 23.976" << endl;
- form = pDUNNO;
- break;
- case 2:
- cerr << "FRAMERATE: 24" << endl;
- form = pDUNNO;
- break;
- case 3:
- cerr << "FRAMERATE: 25" << endl;
- form = pPAL;
- break;
- case 4:
- cerr << "FRAMERATE: 29.97" << endl;
- form = pNTSC;
- break;
- case 5:
- cerr << "FRAMERATE: 30" << endl;
- form = pNTSC;
- break;
- case 6:
- cerr << "FRAMERATE: 50" << endl;
- form = pPAL;
- break;
- case 7:
- cerr << "FRAMERATE: 59.94" << endl;
- form = pNTSC;
- break;
- case 8:
- cerr << "FRAMERATE: 60" << endl;
- form = pNTSC;
- break;
- }
-
- int mpeg = 0;
- found = 0;
- while (!stream.eof() && !found) {
- p = stream.tellg();
- stream.read((char *)headr,4);
- if (headr[0] == 0x00 && headr[1] == 0x00 && headr[2] == 0x01)
- if ( headr[3] == 0xB5 ){
- char *profile[] = {"reserved", "High", "Spatially Scalable",
- "SNR Scalable", "Main", "Simple", "undef",
- "undef"};
- char *level[] = {"res", "res", "res", "res",
- "High","res", "High 1440", "res",
- "Main","res", "Low", "res",
- "res", "res", "res", "res"};
- char *chroma[] = {"res", "4:2:0", "4:2:2", "4:4:4:"};
- mpeg = 2;
- stream.read((char *)headr,4);
- cerr << "PROFILE: " << profile[headr[0] & 0x7] << endl;
- cerr << "LEVEL: " << level[headr[1]>>4 & 0xF] << endl;
- cerr << "CHROMA: " << chroma[headr[1]>>1 & 0x3] << endl;
- found = 1;
- } else {
- mpeg = 1;
- found = 1;
- }
- if (! found) stream.seekg(p+streampos(1));
- }
-
- stream.seekg(q);
- return (form | mpeg << 4);
-}
-
-
-
-int stream_type(istream &fin){
- uint8_t headr[4];
- streampos p=fin.tellg();
-
- TS_Packet ts;
- fin >> ts;
- fin.read((char *)headr,1);
- fin.seekg(p);
- if(fin && headr[0] == 0x47){
- return TS_STREAM;
- }
-
- PS_Packet ps;
- fin >> ps;
- PES_Packet pes;
- for(int j=0;j < ps.NPES();j++){
- fin >> pes;
- }
- fin.read((char *)headr,4);
- fin.seekg(p);
- if (fin && headr[0] == 0x00 && headr[1] == 0x00
- && headr[2] == 0x01 && headr[3] == 0xBA){
- return PS_STREAM;
- }
-
- fin >> pes;
- fin.read((char *)!headr,4);
- fin.seekg(p);
- if (fin && headr[0] == 0x00 && headr[1] == 0x00
- && headr[2] == 0x01 ){
- int found = 0;
- switch ( headr[3] ) {
-
- case PROG_STREAM_MAP:
- case PRIVATE_STREAM2:
- case PROG_STREAM_DIR:
- case ECM_STREAM :
- case EMM_STREAM :
- case PADDING_STREAM :
- case DSM_CC_STREAM :
- case ISO13522_STREAM:
- case PRIVATE_STREAM1:
- case AUDIO_STREAM_S ... AUDIO_STREAM_E:
- case VIDEO_STREAM_S ... VIDEO_STREAM_E:
- found = 1;
- break;
- }
- if (found){
- return PES_STREAM;
- }
- }
-
-
-
- return -1;
-}
-
-
-void analyze(istream &fin)
-{
- PS_Packet ps;
- PES_Packet pes;
- int fc = 0;
- char *frames[3] = {"I-Frame","P-Frame","B-Frame"};
-
- while(fin){
- uint32_t pts;
- fin >> ps;
- cerr << "SCR base: " << hex << setw(5)
- << setfill('0') \
- << ps.SCR_base() << " " << dec
- << "ext : " << ps.SCR_ext();
-
- cerr << " MUX rate: " << ps.MUX()*50*8/1000000.0
- << " Mbit/s ";
- cerr << "RATE bound: " << ps.Rate()*50*8/1000000.0
- << " Mbit/s" << endl;
- cerr << " Audio bound: "
- << hex << "0x"
- << int(ps.P()->audio_bound);
- cerr << " Video bound: " << hex << "0x"
- << int(ps.P()->video_bound)
- << dec
- << endl;
- cerr << endl;
-
- for (int i=0; i < ps.NPES(); i++){
- pes.init();
- fin >> pes;
- pts2pts((uint8_t *)&pts,pes.PTS());
- pes.Info() = 1;
- cerr << pes;
-
- uint8_t *buf = pes.P()->pes_pckt_data;
- int c = 0;
- int l;
- switch (pes.P()->stream_id){
- case VIDEO_STREAM_S ... VIDEO_STREAM_E:
- l=pes.P()->length;
- break;
- default:
- l = 0;
- break;
- }
- while ( c < l - 6){
- if (buf[c] == 0x00 &&
- buf[c+1] == 0x00 &&
- buf[c+2] == 0x01 &&
- buf[c+3] == 0xB8) {
- c += 4;
- cerr << "TIME hours: "
- << int((buf[c]>>2)& 0x1F)
- << " minutes: "
- << int(((buf[c]<<4)& 0x30)|
- ((buf[c+1]>>4)& 0x0F))
- << " seconds: "
- << int(((buf[c+1]<<3)& 0x38)|
- ((buf[c+2]>>5)& 0x0F))
- << endl;
- }
-
- if ( buf[c] == 0x00 &&
- buf[c+1] == 0x00 &&
- buf[c+2] == 0x01 &&
- buf[c+3] == 0x00) {
- fc++;
- c += 4;
- cerr << "picture: "
- << fc
- << " ("
- << frames[((buf[c+1]&0x38) >>3)-1]
- << ")" << endl << endl;
- } else c++;
- }
- }
- }
-}
-
-
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 <fstream>
-#include <sstream>
-#include <iostream>
-#include <iomanip>
-using namespace std;
-
-
-#ifndef _CPPTOOLS_HH_
-#define _CPPTOOLS_HH_
-
-#include "ctools.h"
-
-
-class PES_Packet{
- int info;
- pes_packet p;
-public:
- PES_Packet(){
- info = 0;
- init_pes(&p);
- }
-
- ~PES_Packet(){
- if (p.pack_header)
- delete [] p.pack_header;
- if (p.pes_ext)
- delete [] p.pes_ext;
- if (p.pes_pckt_data)
- delete [] p.pes_pckt_data;
- if (p.mpeg1_headr)
- delete [] p.mpeg1_headr;
- }
-
- inline void init(){
- if (p.pack_header)
- delete [] p.pack_header;
- if (p.pes_ext)
- delete [] p.pes_ext;
- if (p.pes_pckt_data)
- delete [] p.pes_pckt_data;
- if (p.mpeg1_headr)
- delete [] p.mpeg1_headr;
-
- info = 0;
- init_pes(&p);
- }
-
- inline pes_packet *P(){
- return &p;
- }
-
- inline void setlength(){
- setlength_pes(&p);
- if (p.length)
- p.pes_pckt_data = new uint8_t[p.length];
- }
-
- inline void Nlength(){
- nlength_pes(&p);
- p.pes_pckt_data = new uint8_t[p.length];
- }
-
-
- inline uint8_t &Stream_ID(){
- return p.stream_id;
- }
-
- inline uint8_t &Flags1(){
- return p.flags1;
- }
-
- inline uint8_t &Flags2(){
- return p.flags2;
- }
-
- inline uint32_t &Length(){
- return p.length;
- }
-
- inline uint8_t &HLength(){
- return p.pes_hlength;
- }
-
- inline uint8_t &Stuffing(){
- return p.stuffing;
- }
-
- inline uint8_t *Data(){
- return p.pes_pckt_data;
- }
-
- inline int has_pts(){
- return (p.flags2 & PTS_DTS);
- }
-
- inline int &MPEG(){
- return p.mpeg;
- }
- inline uint8_t *PTS(){
- return p.pts;
- }
-
- inline uint8_t *DTS(){
- return p.dts;
- }
-
- inline int &Info(){
- return info;
- }
-
-
-
- inline uint8_t high_pts(){
- if (has_pts())
- return ((p.pts[0] & 0x08)>>3);
- else
- return 0;
- }
-
- inline uint8_t high_dts(){
- return ((p.dts[0] & 0x08)>>3);
- }
-
- inline int WDTS(){
- int w_dts;
- w_dts = (int)trans_pts_dts(p.dts);
- return w_dts;
- }
-
- inline int WPTS(){
- int w_dts;
- w_dts = (int)trans_pts_dts(p.pts);
- return w_dts;
- }
-
- friend ostream & operator << (ostream & stream, PES_Packet & x);
- friend istream & operator >> (istream & stream, PES_Packet & x);
-
-};
-
-
-class TS_Packet{
- ts_packet p;
- int info;
-
-public:
- TS_Packet(){
- init_ts(&p);
- info = 0;
- }
-
- ~TS_Packet(){
- if (p.priv_dat)
- delete [] p.priv_dat;
- }
-
- inline void init(){
- if (p.priv_dat)
- delete [] p.priv_dat;
-
- init_ts(&p);
- info = 0;
- }
-
- inline ts_packet *P(){
- return &p;
- }
-
- inline int &Rest(){
- return p.rest;
- }
-
- inline uint8_t *Data(){
- return p.data;
- }
-
- inline short PID(){
- return pid_ts(&p);
- }
-
- inline uint8_t FLAG1(){
- return (p.pid[0] & ~PID_MASK_HI);
- }
-
- inline int &Info(){
- return info;
- }
-
- friend ostream & operator << (ostream & stream, TS_Packet & x);
- friend istream & operator >> (istream & stream, TS_Packet & x);
-};
-
-
-class PS_Packet{
- int info;
- ps_packet p;
-public:
-
- PS_Packet(){
- init_ps(&p);
- info = 0;
- }
-
- ~PS_Packet(){
- if (p.data)
- delete [] p.data;
- }
-
- inline void init(){
- if (p.data)
- delete [] p.data;
-
- init_ps(&p);
- info = 0;
- }
-
- inline ps_packet *P(){
- return &p;
- }
-
- inline int MUX(){
- return mux_ps(&p);
- }
-
- inline int Rate(){
- return rate_ps(&p);
- }
-
- inline void setlength(){
- setlength_ps(&p);
- p.data = new uint8_t[p.sheader_length];
- }
-
- inline int Stuffing(){
- return p.stuff_length & PACK_STUFF_MASK;
- }
-
- inline int NPES(){
- return p.npes;
- }
-
- inline int &MPEG(){
- return p.mpeg;
- }
-
- inline uint8_t &operator()(int l){
- return p.data[l];
- }
-
- inline char * Data() {
- return (char *)p.data+p.stuff_length;
- }
-
- inline int &SLENGTH(){
- return p.sheader_length;
- }
-
- inline int &Info(){
- return info;
- }
-
- uint32_t SCR_base(){
- return scr_base_ps(&p);
- }
-
- uint16_t SCR_ext(){
- return scr_ext_ps(&p);
- }
-
- friend ostream & operator << (ostream & stream, PS_Packet & x);
- friend istream & operator >> (istream & stream, PS_Packet & x);
-};
-
-
-typedef void (* FILTER)(istream &in, ostream &out);
-
-typedef struct thread_args_{
- FILTER function;
- int *fd;
- int in;
- int out;
-} thread_args;
-
-
-void extract_audio_from_PES(istream &in, ostream &out);
-void extract_video_from_PES(istream &in, ostream &out);
-void extract_es_audio_from_PES(istream &in, ostream &out);
-void extract_es_video_from_PES(istream &in, ostream &out);
-int TS_PIDS(istream &in, ostream &out);
-int ifilter (istream &in, FILTER function);
-int ofilter (istream &in, FILTER function);
-int itfilter (int in, FILTER function);
-int otfilter (istream &in, FILTER function);
-int stream_type(int fd);
-int stream_type(istream &stream);
-int tv_norm(istream &fin);
-
-void analyze(istream &fin);
-
-
-#endif //_CPPTOOLS_HH_
-
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;i<p->stuffing;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 <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <libgen.h>
-#include <stdint.h>
-#include <netdb.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-
-#include "ringbuffy.h"
-#include "transform.h"
-
-#ifndef _CTOOLS_H_
-#define _CTOOLS_H_
-
-#define VIDEO_MODE_PAL 0
-#define VIDEO_MODE_NTSC 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
- enum {PS_STREAM, TS_STREAM, PES_STREAM};
- enum {pDUNNO, pPAL, pNTSC};
-
- uint64_t trans_pts_dts(uint8_t *pts);
-
-/*
- PES
-*/
-
-#define PROG_STREAM_MAP 0xBC
-#ifndef PRIVATE_STREAM1
-#define PRIVATE_STREAM1 0xBD
-#endif
-#define PADDING_STREAM 0xBE
-#ifndef PRIVATE_STREAM2
-#define PRIVATE_STREAM2 0xBF
-#endif
-#define AUDIO_STREAM_S 0xC0
-#define AUDIO_STREAM_E 0xDF
-#define VIDEO_STREAM_S 0xE0
-#define VIDEO_STREAM_E 0xEF
-#define ECM_STREAM 0xF0
-#define EMM_STREAM 0xF1
-#define DSM_CC_STREAM 0xF2
-#define ISO13522_STREAM 0xF3
-#define PROG_STREAM_DIR 0xFF
-
-#define BUFFYSIZE 10*MAX_PLENGTH
-#define MAX_PTS 8192
-#define MAX_FRAME 8192
-#define MAX_PACK_L 4096
-#define PS_HEADER_L1 14
-#define PS_HEADER_L2 (PS_HEADER_L1+18)
-#define MAX_H_SIZE (PES_H_MIN + PS_HEADER_L1 + 5)
-#define PES_MIN 7
-#define PES_H_MIN 9
-
-//flags1
-#define FLAGS 0x40
-#define SCRAMBLE_FLAGS 0x30
-#define PRIORITY_FLAG 0x08
-#define DATA_ALIGN_FLAG 0x04
-#define COPYRIGHT_FLAG 0x02
-#define ORIGINAL_FLAG 0x01
-
-//flags2
-#define PTS_DTS_FLAGS 0xC0
-#define ESCR_FLAG 0x20
-#define ES_RATE_FLAG 0x10
-#define DSM_TRICK_FLAG 0x08
-#define ADD_CPY_FLAG 0x04
-#define PES_CRC_FLAG 0x02
-#define PES_EXT_FLAG 0x01
-
-//pts_dts flags
-#define PTS_ONLY 0x80
-#define PTS_DTS 0xC0
-
-//private flags
-#define PRIVATE_DATA 0x80
-#define HEADER_FIELD 0x40
-#define PACK_SEQ_CTR 0x20
-#define P_STD_BUFFER 0x10
-#define PES_EXT_FLAG2 0x01
-
-#define MPEG1_2_ID 0x40
-#define STFF_LNGTH_MASK 0x3F
-
-
- typedef struct pes_packet_{
- uint8_t stream_id;
- uint8_t llength[2];
- uint32_t length;
- uint8_t flags1;
- uint8_t flags2;
- uint8_t pes_hlength;
- uint8_t pts[5];
- uint8_t dts[5];
- uint8_t escr[6];
- uint8_t es_rate[3];
- uint8_t trick;
- uint8_t add_cpy;
- uint8_t prev_pes_crc[2];
- uint8_t priv_flags;
- uint8_t pes_priv_data[16];
- uint8_t pack_field_length;
- uint8_t *pack_header;
- uint8_t pck_sqnc_cntr;
- uint8_t org_stuff_length;
- uint8_t p_std[2];
- uint8_t pes_ext_lngth;
- uint8_t *pes_ext;
- uint8_t *pes_pckt_data;
- int padding;
- int mpeg;
- int mpeg1_pad;
- uint8_t *mpeg1_headr;
- uint8_t stuffing;
- } pes_packet;
-
- void init_pes(pes_packet *p);
- void kill_pes(pes_packet *p);
- void setlength_pes(pes_packet *p);
- void nlength_pes(pes_packet *p);
- int cwrite_pes(uint8_t *buf, pes_packet *p, long length);
- void write_pes(int fd, pes_packet *p);
- int read_pes(int f, pes_packet *p);
- void cread_pes(char *buf, pes_packet *p);
-
-/*
- Transport Stream
-*/
-
-#define TS_SIZE 188
-#define TRANS_ERROR 0x80
-#define PAY_START 0x40
-#define TRANS_PRIO 0x20
-#define PID_MASK_HI 0x1F
-//flags
-#define TRANS_SCRMBL1 0x80
-#define TRANS_SCRMBL2 0x40
-#define ADAPT_FIELD 0x20
-#define PAYLOAD 0x10
-#define COUNT_MASK 0x0F
-
-// adaptation flags
-#define DISCON_IND 0x80
-#define RAND_ACC_IND 0x40
-#define ES_PRI_IND 0x20
-#define PCR_FLAG 0x10
-#define OPCR_FLAG 0x08
-#define SPLICE_FLAG 0x04
-#define TRANS_PRIV 0x02
-#define ADAP_EXT_FLAG 0x01
-
-// adaptation extension flags
-#define LTW_FLAG 0x80
-#define PIECE_RATE 0x40
-#define SEAM_SPLICE 0x20
-
- typedef struct ts_packet_{
- uint8_t pid[2];
- uint8_t flags;
- uint8_t count;
- uint8_t data[184];
- uint8_t adapt_length;
- uint8_t adapt_flags;
- uint8_t pcr[6];
- uint8_t opcr[6];
- uint8_t splice_count;
- uint8_t priv_dat_len;
- uint8_t *priv_dat;
- uint8_t adapt_ext_len;
- uint8_t adapt_eflags;
- uint8_t ltw[2];
- uint8_t piece_rate[3];
- uint8_t dts[5];
- int rest;
- uint8_t stuffing;
- } ts_packet;
-
- void init_ts(ts_packet *p);
- void kill_ts(ts_packet *p);
- unsigned short pid_ts(ts_packet *p);
- int cwrite_ts(uint8_t *buf, ts_packet *p, long length);
- void write_ts(int fd, ts_packet *p);
- int read_ts(int f, ts_packet *p);
- void cread_ts (char *buf, ts_packet *p, long length);
-
-
-/*
- Program Stream
-*/
-
-#define PACK_STUFF_MASK 0x07
-
-#define FIXED_FLAG 0x02
-#define CSPS_FLAG 0x01
-#define SAUDIO_LOCK_FLAG 0x80
-#define SVIDEO_LOCK_FLAG 0x40
-
-#define PS_MAX 200
-
- typedef struct ps_packet_{
- uint8_t scr[6];
- uint8_t mux_rate[3];
- uint8_t stuff_length;
- uint8_t *data;
- uint8_t sheader_llength[2];
- int sheader_length;
- uint8_t rate_bound[3];
- uint8_t audio_bound;
- uint8_t video_bound;
- uint8_t reserved;
- int npes;
- int mpeg;
- } ps_packet;
-
- void init_ps(ps_packet *p);
- void kill_ps(ps_packet *p);
- void setlength_ps(ps_packet *p);
- uint32_t scr_base_ps(ps_packet *p);
- uint16_t scr_ext_ps(ps_packet *p);
- int mux_ps(ps_packet *p);
- int rate_ps(ps_packet *p);
- int cwrite_ps(uint8_t *buf, ps_packet *p, long length);
- void write_ps(int fd, ps_packet *p);
- int read_ps (int f, ps_packet *p);
- void cread_ps (char *buf, ps_packet *p, long length);
-
-
-
-#define MAX_PLENGTH 0xFFFF
-
- typedef struct sectionstruct {
- int id;
- int length;
- int found;
- uint8_t payload[4096+3];
- } section;
-
-
- typedef uint32_t tflags;
-#define MAXFILT 32
-#define MASKL 16
- typedef struct trans_struct {
- int found;
- uint8_t packet[188];
- uint16_t pid[MAXFILT];
- uint8_t mask[MAXFILT*MASKL];
- uint8_t filt[MAXFILT*MASKL];
- uint8_t transbuf[MAXFILT*188];
- int transcount[MAXFILT];
- section sec[MAXFILT];
- tflags is_full;
- tflags pes_start;
- tflags pes_started;
- tflags pes;
- tflags set;
- } trans;
-
-
- void init_trans(trans *p);
- int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask,
- uint8_t *filt, int pes);
-
- void clear_trans_filt(trans *p,int filtn);
- int filt_is_set(trans *p, int filtn);
- int pes_is_set(trans *p, int filtn);
- int pes_is_started(trans *p, int filtn);
- int pes_is_start(trans *p, int filtn);
- int filt_is_ready(trans *p,int filtn);
-
- void trans_filt(uint8_t *buf, int count, trans *p);
- void tfilter(trans *p);
- void pes_filter(trans *p, int filtn, int off);
- void sec_filter(trans *p, int filtn, int off);
- int get_filt_buf(trans *p, int filtn,uint8_t **buf);
- section *get_filt_sec(trans *p, int filtn);
-
-
- typedef struct a2pstruct{
- int type;
- int fd;
- int found;
- int length;
- int headr;
- int plength;
- uint8_t cid;
- uint8_t flags;
- uint8_t abuf[MAX_PLENGTH];
- int alength;
- uint8_t vbuf[MAX_PLENGTH];
- int vlength;
- uint8_t last_av_pts[4];
- uint8_t av_pts[4];
- uint8_t scr[4];
- uint8_t pid0;
- uint8_t pid1;
- uint8_t pidv;
- uint8_t pida;
- } a2p;
-
-
-
- void get_pespts(uint8_t *av_pts,uint8_t *pts);
- void init_a2p(a2p *p);
- void av_pes_to_pes(uint8_t *buf,int count, a2p *p);
- int w_pesh(uint8_t id,int length ,uint8_t *pts, uint8_t *obuf);
- int w_tsh(uint8_t id,int length ,uint8_t *pts, uint8_t *obuf,a2p *p,int startpes);
- void pts2pts(uint8_t *av_pts, uint8_t *pts);
- void write_ps_headr(ps_packet *p,uint8_t *pts,int fd);
-
- typedef struct p2t_s{
- uint8_t pes[TS_SIZE];
- uint8_t counter;
- long int pos;
- int frags;
- void (*t_out)(uint8_t const *buf);
- } p2t_t;
-
- void twrite(uint8_t const *buf);
- void init_p2t(p2t_t *p, void (*fkt)(uint8_t const *buf));
- long int find_pes_header(uint8_t const *buf, long int length, int *frags);
- void pes_to_ts( uint8_t const *buf, long int length, uint16_t pid, p2t_t *p);
- void p_to_t( uint8_t const *buf, long int length, uint16_t pid,
- uint8_t *counter, void (*ts_write)(uint8_t const *));
-
-
- int write_pes_header(uint8_t id,int length , long PTS,
- uint8_t *obuf, int stuffing);
-
- int write_ps_header(uint8_t *buf,
- uint32_t SCR,
- long muxr,
- uint8_t audio_bound,
- uint8_t fixed,
- uint8_t CSPS,
- uint8_t audio_lock,
- uint8_t video_lock,
- uint8_t video_bound,
- uint8_t stream1,
- uint8_t buffer1_scale,
- uint32_t buffer1_size,
- uint8_t stream2,
- uint8_t buffer2_scale,
- uint32_t buffer2_size);
-
-
- int seek_mpg_start(uint8_t *buf, int size);
-
-
- void split_mpg(char *name, uint64_t size);
- void cut_mpg(char *name, uint64_t size);
- int http_open (char *url);
- ssize_t save_read(int fd, void *buf, size_t count);
-
- const char * strerrno(void);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /*_CTOOLS_H_*/
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 <stdint.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-
-#include "DVB.hh"
-
-#define MAXNAM 80
-#define MAXKEY 15
-
-const int maxname=80;
-const int MAXAPIDS=32;
-const uint32_t UNSET=0xffffffff;
-const uint16_t NOID=0xffff;
-const uint16_t NOPID=0xffff;
-
-class Transponder {
-public:
- uint16_t id;
- uint16_t onid;
- uint16_t satid;
- int type;
- char name[maxname+1];
- uint32_t freq;
- int pol;
- int qam;
- uint32_t srate;
- int fec;
- int band;
- int hp_rate;
- int lp_rate;
- int mod;
- int transmode;
- int guard;
- int hierarchy;
-
- struct Sat *sat;
-
- Transponder() {
- name[0]='\0';
- id = NOID;
- onid = NOID;
- satid = NOID;
- type = 0;
- }
-
- friend ostream &operator<<(ostream &stream, Transponder &x);
- friend istream &operator>>(istream &stream, Transponder &x);
-};
-
-class Sat {
-public:
- uint16_t id;
- char name[maxname+1];
- unsigned int lnbid;
- struct Lnb *lnb;
- unsigned int rotorid;
- unsigned int fmin;
- unsigned int fmax;
-
- Sat() {
- id=NOID;
- name[0]='\0';
- lnb=NULL;
- rotorid=NOID;
- lnbid=NOID;
- fmin=fmax=0;
- };
- int set(int sid, char *sname, int slnbid, int srotorid) {
- return 0;
- };
-
- friend ostream &operator<<(ostream &stream, Sat &x);
- friend istream &operator>>(istream &stream, Sat &x);
-};
-
-
-class Lnb {
-public:
- Sat *sat;
- uint16_t id;
- struct DVB *dvbd;
- char name[maxname+1];
- int type;
- unsigned int lof1;
- unsigned int lof2;
- unsigned int slof;
- int diseqcnr;
- uint16_t diseqcid;
- uint16_t swiid;
-
-
- void cpy (const Lnb &olnb){
- this->id=olnb.id;
- this->type=olnb.type;
- this->lof1=olnb.lof1;
- this->lof2=olnb.lof2;
- this->slof=olnb.slof;
- this->diseqcnr=olnb.diseqcnr;
- this->diseqcid=olnb.diseqcid;
- this->swiid=olnb.swiid;
- strncpy(this->name,olnb.name,maxname);
- }
-
- void init(int t, uint l1, uint l2, uint sl,
- int dnr, int disid, int sw) {
- type=t;
- lof1=l1;
- lof2=l2;
- slof=sl;
- diseqcnr=dnr;
- diseqcid=disid;
- swiid=sw;
- dvbd=0;
- name[0]='\0';
- }
-
- Lnb () {
- lof1=lof2=slof=0;
- swiid=NOID;
- diseqcid=NOID;
- diseqcnr=-1;
- name[0]='\0';
- }
-
- Lnb (const Lnb &olnb){
- cpy(olnb);
- }
-
-
-
- friend ostream &operator<<(ostream &stream, Lnb &x);
- friend istream &operator>>(istream &stream, Lnb &x);
-};
-
-struct diseqcmsg {
- int burst;
- int len;
- unsigned char msg[8];
-};
-
-class DiSEqC {
-public:
- uint16_t id;
- char name[maxname+1];
- diseqcmsg msgs[4];
-
- friend ostream &operator<<(ostream &stream, DiSEqC &x);
- friend istream &operator>>(istream &stream, DiSEqC &x);
-};
-
-class Rotor {
-public:
- uint16_t id;
- char name[maxname+1];
- diseqcmsg msgs[4];
-
- friend ostream &operator<<(ostream &stream, Rotor &x);
- friend istream &operator>>(istream &stream, Rotor &x);
-};
-
-class Switch {
-public:
- uint16_t id;
- int switchid;
- char name[maxname+1];
- diseqcmsg msg;
-
- friend ostream &operator<<(ostream &stream, Switch &x);
- friend istream &operator>>(istream &stream, Switch &x);
-};
-
-class Network {
-public:
- uint16_t id;
- char name[maxname+1];
-
- friend ostream &operator<<(ostream &stream, Network &x);
- friend istream &operator>>(istream &stream, Network &x);
-};
-
-class Bouquet {
-public:
- uint16_t id;
- char name[maxname+1];
-
- friend ostream &operator<<(ostream &stream, Bouquet &x);
- friend istream &operator>>(istream &stream, Bouquet &x);
-};
-
-
-#define MAX_ECM 16
-#define MAX_ECM_DESC 256
-typedef struct ecm_struct {
- int num;
- uint16_t sysid[MAX_ECM];
- uint16_t pid[MAX_ECM];
- uint16_t length[MAX_ECM];
- uint8_t data[MAX_ECM*MAX_ECM_DESC];
-} ecm_t;
-
-
-
-class Channel{
-public:
- Channel *next;
- uint32_t id;
- char name[maxname+1];
- int32_t type;
- int checked;
-
- uint16_t pnr;
- uint16_t vpid;
- uint16_t apids[MAXAPIDS];
- char apids_name[MAXAPIDS*4];
- int32_t apidnum;
- int last_apidn;
- uint16_t ac3pid;
- uint16_t ttpid;
- uint16_t pmtpid;
- uint16_t pcrpid;
- uint16_t casystem;
- uint16_t capid;
-
- ecm_t ecm;
- int (*ecm_callback)(Channel *chan);
-
- int has_eit;
- int pres_follow;
-
- uint16_t satid;
- uint16_t tpid;
- uint16_t onid;
- uint16_t bid;
- int8_t eit_ver_n;
- int8_t eit_ver_c;
-
- void clearall(void) {
- id=UNSET;
- name[0]='\0';
- type=0;
- checked = 0;
- has_eit = -1;
- pres_follow = -1;
- eit_ver_c = -1;
- eit_ver_n = -1;
-
- pnr=NOPID;
- vpid=NOPID;
- memset(apids, 0, sizeof(uint16_t)*MAXAPIDS);
- memset(apids_name, 0, sizeof(char)*MAXAPIDS*4);
- apidnum=0;
- last_apidn=-1;
- ac3pid=NOPID;
- ttpid=NOPID;
- pmtpid=NOPID;
- pcrpid=NOPID;
- capid=NOPID;
-
- satid=NOID;
- tpid=NOID;
- onid=NOID;
- bid=NOID;
- ecm_callback = NULL;
- memset(&ecm,0, sizeof(ecm_t));
- };
-
- Channel() {
- clearall();
- }
-
- Channel(int cid, char *nam, int ty, int prognr,
- int vid, int aid, int tid) {
- int l=strlen(nam);
-
- clearall();
- if (l>maxname){
- cerr << "" << endl;
- l=maxname;
- }
- strncpy(name, nam, l);
- name[l]='\0';
- type=ty;
- pnr=prognr;
- vpid=vid;
- apids[0]=aid;
- }
-
-#ifdef DEBUG
- ~Channel(){
- cerr <<"Channel " << name << " destroyed" << endl;
- }
-#endif
-
- friend ostream &operator<<(ostream &stream, Channel &x);
- friend istream &operator>>(istream &stream, Channel &x);
-};
-
-int findkey(char *name, char *keys[]);
-void getname(char *name,istream &ins);
-#endif /*channel.h*/
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 <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-//#include <libgen.h>
-#include <stdint.h>
-
-#include "ringbuffy.h"
-#include "ctools.h"
-
-#ifndef _REMUX_H_
-#define _REMUX_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
- typedef struct video_i{
- uint32_t horizontal_size;
- uint32_t vertical_size ;
- uint32_t aspect_ratio ;
- double framerate ;
- uint32_t video_format;
- uint32_t bit_rate ;
- uint32_t comp_bit_rate ;
- uint32_t vbv_buffer_size;
- uint32_t CSPF ;
- uint32_t off;
- } VideoInfo;
-
- typedef struct audio_i{
- int layer;
- uint32_t bit_rate;
- uint32_t frequency;
- uint32_t mode;
- uint32_t mode_extension;
- uint32_t emphasis;
- uint32_t framesize;
- uint32_t off;
- } AudioInfo;
-
-
-
- typedef
- struct PTS_list_struct{
- uint32_t PTS;
- int pos;
- uint32_t dts;
- int spos;
- } PTS_List;
-
- typedef
- struct frame_list_struct{
- int type;
- int pos;
- uint32_t FRAME;
- uint32_t time;
- uint32_t pts;
- uint32_t dts;
- } FRAME_List;
-
- typedef
- struct remux_struct{
- ringbuffy vid_buffy;
- ringbuffy aud_buffy;
- PTS_List vpts_list[MAX_PTS];
- PTS_List apts_list[MAX_PTS];
- FRAME_List vframe_list[MAX_FRAME];
- FRAME_List aframe_list[MAX_FRAME];
- int vptsn;
- int aptsn;
- int vframen;
- int aframen;
- long apes;
- long vpes;
- uint32_t vframe;
- uint32_t aframe;
- uint32_t vcframe;
- uint32_t acframe;
- uint32_t vpts;
- uint32_t vdts;
- uint32_t apts;
- uint32_t vpts_old;
- uint32_t apts_old;
- uint32_t SCR;
- uint32_t apts_off;
- uint32_t vpts_off;
- uint32_t apts_delay;
- uint32_t vpts_delay;
- uint32_t dts_delay;
- AudioInfo audio_info;
- VideoInfo video_info;
- int fin;
- int fout;
- long int awrite;
- long int vwrite;
- long int aread;
- long int vread;
- uint32_t group;
- uint32_t groupframe;
- uint32_t muxr;
- int pack_size;
- uint32_t time_off;
- } Remux;
-
- enum { NONE, I_FRAME, P_FRAME, B_FRAME, D_FRAME };
-
- void remux(int fin, int fout, int pack_size, int mult);
- void remux2(int fdin, int fdout);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /*_REMUX_H_*/
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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define FULL_BUFFER -1000
-typedef struct ringbuffy{
- int read_pos;
- int write_pos;
- int size;
- char *buffy;
-} ringbuffy;
-
-int ring_init (ringbuffy *rbuf, int size);
-void ring_destroy(ringbuffy *rbuf);
-int ring_write(ringbuffy *rbuf, char *data, int count);
-int ring_read(ringbuffy *rbuf, char *data, int count);
-int ring_write_file(ringbuffy *rbuf, int fd, int count);
-int ring_read_file(ringbuffy *rbuf, int fd, int count);
-int ring_rest(ringbuffy *rbuf);
-int ring_peek(ringbuffy *rbuf, char *data, int count, long off);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* RINGBUFFY_H */
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 <stdlib.h>
-#include <string.h>
-#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 <stdint.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <unistd.h>
-#include "remux.h"
-
-#define PROG_STREAM_MAP 0xBC
-#ifndef PRIVATE_STREAM1
-#define PRIVATE_STREAM1 0xBD
-#endif
-#define PADDING_STREAM 0xBE
-#ifndef PRIVATE_STREAM2
-#define PRIVATE_STREAM2 0xBF
-#endif
-#define AUDIO_STREAM_S 0xC0
-#define AUDIO_STREAM_E 0xDF
-#define VIDEO_STREAM_S 0xE0
-#define VIDEO_STREAM_E 0xEF
-#define ECM_STREAM 0xF0
-#define EMM_STREAM 0xF1
-#define DSM_CC_STREAM 0xF2
-#define ISO13522_STREAM 0xF3
-#define PROG_STREAM_DIR 0xFF
-
-#define BUFFYSIZE 10*MAX_PLENGTH
-#define MAX_PTS 8192
-#define MAX_FRAME 8192
-#define MAX_PACK_L 4096
-#define PS_HEADER_L1 14
-#define PS_HEADER_L2 (PS_HEADER_L1+18)
-#define MAX_H_SIZE (PES_H_MIN + PS_HEADER_L1 + 5)
-#define PES_MIN 7
-#define PES_H_MIN 9
-
-//flags2
-#define PTS_DTS_FLAGS 0xC0
-#define ESCR_FLAG 0x20
-#define ES_RATE_FLAG 0x10
-#define DSM_TRICK_FLAG 0x08
-#define ADD_CPY_FLAG 0x04
-#define PES_CRC_FLAG 0x02
-#define PES_EXT_FLAG 0x01
-
-//pts_dts flags
-#define PTS_ONLY 0x80
-#define PTS_DTS 0xC0
-
-#define TS_SIZE 188
-#define TRANS_ERROR 0x80
-#define PAY_START 0x40
-#define TRANS_PRIO 0x20
-#define PID_MASK_HI 0x1F
-//flags
-#define TRANS_SCRMBL1 0x80
-#define TRANS_SCRMBL2 0x40
-#define ADAPT_FIELD 0x20
-#define PAYLOAD 0x10
-#define COUNT_MASK 0x0F
-
-// adaptation flags
-#define DISCON_IND 0x80
-#define RAND_ACC_IND 0x40
-#define ES_PRI_IND 0x20
-#define PCR_FLAG 0x10
-#define OPCR_FLAG 0x08
-#define SPLICE_FLAG 0x04
-#define TRANS_PRIV 0x02
-#define ADAP_EXT_FLAG 0x01
-
-// adaptation extension flags
-#define LTW_FLAG 0x80
-#define PIECE_RATE 0x40
-#define SEAM_SPLICE 0x20
-
-
-#define MAX_PLENGTH 0xFFFF
-#define MMAX_PLENGTH (8*MAX_PLENGTH)
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#define P2P_LENGTH 2048
-
- enum{NOPES, AUDIO, VIDEO, AC3};
-
- typedef struct p2pstruct {
- int found;
- uint8_t buf[MMAX_PLENGTH];
- uint8_t cid;
- uint8_t subid;
- uint32_t plength;
- uint8_t plen[2];
- uint8_t flag1;
- uint8_t flag2;
- uint8_t hlength;
- uint8_t pts[5];
- int mpeg;
- uint8_t check;
- int fd1;
- int fd2;
- int es;
- int filter;
- int which;
- int done;
- int repack;
- uint16_t bigend_repack;
- void (*func)(uint8_t *buf, int count, void *p);
- int startv;
- int starta;
- int64_t apts;
- int64_t vpts;
- uint16_t pid;
- uint16_t pida;
- uint16_t pidv;
- uint8_t acounter;
- uint8_t vcounter;
- uint8_t count0;
- uint8_t count1;
- void *data;
- } p2p;
-
-
- uint64_t trans_pts_dts(uint8_t *pts);
- int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start,
- uint8_t *buf, uint8_t length);
- uint16_t get_pid(uint8_t *pid);
- void init_p2p(p2p *p, void (*func)(uint8_t *buf, int count, void *p),
- int repack);
- void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p));
- void get_pes (uint8_t *buf, int count, p2p *p, void (*func)(p2p *p));
- void pes_repack(p2p *p);
- void setup_pes2ts( p2p *p, uint32_t pida, uint32_t pidv,
- void (*ts_write)(uint8_t *buf, int count, void *p));
- void kpes_to_ts( p2p *p,uint8_t *buf ,int count );
- void setup_ts2pes( p2p *pa, p2p *pv, uint32_t pida, uint32_t pidv,
- void (*pes_write)(uint8_t *buf, int count, void *p));
- void kts_to_pes( p2p *p, uint8_t *buf);
- void pes_repack(p2p *p);
- void extract_from_pes(int fdin, int fdout, uint8_t id, int es);
- int64_t pes_dmx(int fdin, int fdouta, int fdoutv, int es);
- void pes_to_ts2( int fdin, int fdout, uint16_t pida, uint16_t pidv);
- void ts_to_pes( int fdin, uint16_t pida, uint16_t pidv, int pad);
- int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
- int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr);
- int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
- void filter_audio_from_pes(int fdin, int fdout, uint8_t id,
- uint8_t subid);
-
-
-//instant repack
-
- typedef struct ipack_s {
- int size;
- int size_orig;
- int found;
- int ps;
- int has_ai;
- int has_vi;
- AudioInfo ai;
- VideoInfo vi;
- uint8_t *buf;
- uint8_t cid;
- uint32_t plength;
- uint8_t plen[2];
- uint8_t flag1;
- uint8_t flag2;
- uint8_t hlength;
- uint8_t pts[5];
- uint8_t last_pts[5];
- int mpeg;
- uint8_t check;
- int which;
- int done;
- void *data;
- void *data2;
- void (*func)(uint8_t *buf, int size, void *priv);
- int count;
- int start;
- int fd;
- int fd1;
- int fd2;
- int ffd;
- int playing;
- } ipack;
-
- void instant_repack (uint8_t *buf, int count, ipack *p);
- void init_ipack(ipack *p, int size,
- void (*func)(uint8_t *buf, int size, void *priv),
- int pad);
- void free_ipack(ipack * p);
- void send_ipack(ipack *p);
- void reset_ipack(ipack *p);
- void ps_pes(ipack *p);
- // use with ipack structure, repack size and callback func
-
- int64_t ts_demux(int fd_in, int fdv_out,int fda_out,uint16_t pida,
- uint16_t pidv, int es);
-
- void ts2es(int fdin, uint16_t pidv);
- void ts2es_opt(int fdin, uint16_t pidv, ipack *p, int verb);
- void insert_pat_pmt( int fdin, int fdout);
- void change_aspect(int fdin, int fdout, int aspect);
-
-// SV: all made non-static:
- void pes_in_ts(p2p *p);
-
-// SV: moved from .c file:
-#define IPACKS 2048
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _TS_TRANSFORM_H_*/
-
-
-
diff --git a/osd.c b/osd.c
index 907171e..1fc1a22 100644
--- a/osd.c
+++ b/osd.c
@@ -1,113 +1,32 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#include "osd.h"
+#include "quantize.h"
#include "receiver.h"
#include "config.h"
#include <vdr/ringbuffer.h>
#include <vdr/remux.h>
-const uint rgb256[256] = {
- 0xff000000, 0xff400000, 0xff800000, 0xffc00000, 0xff002000, 0xff402000,
- 0xff802000, 0xffc02000, 0xff004000, 0xff404000, 0xff804000, 0xffc04000,
- 0xff006000, 0xff406000, 0xff806000, 0xffc06000, 0xff008000, 0xff408000,
- 0xff808000, 0xffc08000, 0xff00a000, 0xff40a000, 0xff80a000, 0xffc0a000,
- 0xff00c000, 0xff40c000, 0xff80c000, 0xffc0c000, 0xff00e000, 0xff40e000,
- 0xff80e000, 0xffc0e000, 0xff000020, 0xff400020, 0xff800020, 0xffc00020,
- 0xff002020, 0xff402020, 0xff802020, 0xffc02020, 0xff004020, 0xff404020,
- 0xff804020, 0xffc04020, 0xff006020, 0xff406020, 0xff806020, 0xffc06020,
- 0xff008020, 0xff408020, 0xff808020, 0xffc08020, 0xff00a020, 0xff40a020,
- 0xff80a020, 0xffc0a020, 0xff00c020, 0xff40c020, 0xff80c020, 0xffc0c020,
- 0xff00e020, 0xff40e020, 0xff80e020, 0xffc0e020, 0xff000040, 0xff400040,
- 0xff800040, 0xffc00040, 0xff002040, 0xff402040, 0xff802040, 0xffc02040,
- 0xff004040, 0xff404040, 0xff804040, 0xffc04040, 0xff006040, 0xff406040,
- 0xff806040, 0xffc06040, 0xff008040, 0xff408040, 0xff808040, 0xffc08040,
- 0xff00a040, 0xff40a040, 0xff80a040, 0xffc0a040, 0xff00c040, 0xff40c040,
- 0xff80c040, 0xffc0c040, 0xff00e040, 0xff40e040, 0xff80e040, 0xffc0e040,
- 0xff000060, 0xff400060, 0xff800060, 0xffc00060, 0xff002060, 0xff402060,
- 0xff802060, 0xffc02060, 0xff004060, 0xff404060, 0xff804060, 0xffc04060,
- 0xff006060, 0xff406060, 0xff806060, 0xffc06060, 0xff008060, 0xff408060,
- 0xff808060, 0xffc08060, 0xff00a060, 0xff40a060, 0xff80a060, 0xffc0a060,
- 0xff00c060, 0xff40c060, 0xff80c060, 0xffc0c060, 0xff00e060, 0xff40e060,
- 0xff80e060, 0xffc0e060, 0xff000080, 0xff400080, 0xff800080, 0xffc00080,
- 0xff002080, 0xff402080, 0xff802080, 0xffc02080, 0xff004080, 0xff404080,
- 0xff804080, 0xffc04080, 0xff006080, 0xff406080, 0xff806080, 0xffc06080,
- 0xff008080, 0xff408080, 0xff808080, 0xffc08080, 0xff00a080, 0xff40a080,
- 0xff80a080, 0xffc0a080, 0xff00c080, 0xff40c080, 0xff80c080, 0xffc0c080,
- 0xff00e080, 0xff40e080, 0xff80e080, 0xffc0e080, 0xff0000a0, 0xff4000a0,
- 0xff8000a0, 0xffc000a0, 0xff0020a0, 0xff4020a0, 0xff8020a0, 0xffc020a0,
- 0xff0040a0, 0xff4040a0, 0xff8040a0, 0xffc040a0, 0xff0060a0, 0xff4060a0,
- 0xff8060a0, 0xffc060a0, 0xff0080a0, 0xff4080a0, 0xff8080a0, 0xffc080a0,
- 0xff00a0a0, 0xff40a0a0, 0xff80a0a0, 0xffc0a0a0, 0xff00c0a0, 0xff40c0a0,
- 0xff80c0a0, 0xffc0c0a0, 0xff00e0a0, 0xff40e0a0, 0xff80e0a0, 0xffc0e0a0,
- 0xff0000c0, 0xff4000c0, 0xff8000c0, 0xffc000c0, 0xff0020c0, 0xff4020c0,
- 0xff8020c0, 0xffc020c0, 0xff0040c0, 0xff4040c0, 0xff8040c0, 0xffc040c0,
- 0xff0060c0, 0xff4060c0, 0xff8060c0, 0xffc060c0, 0xff0080c0, 0xff4080c0,
- 0xff8080c0, 0xffc080c0, 0xff00a0c0, 0xff40a0c0, 0xff80a0c0, 0xffc0a0c0,
- 0xff00c0c0, 0xff40c0c0, 0xff80c0c0, 0xffc0c0c0, 0xff00e0c0, 0xff40e0c0,
- 0xff80e0c0, 0xffc0e0c0, 0xff0000e0, 0xff4000e0, 0xff8000e0, 0xffc000e0,
- 0xff0020e0, 0xff4020e0, 0xff8020e0, 0xffc020e0, 0xff0040e0, 0xff4040e0,
- 0xff8040e0, 0xffc040e0, 0xff0060e0, 0xff4060e0, 0xff8060e0, 0xffc060e0,
- 0xff0080e0, 0xff4080e0, 0xff8080e0, 0xffc080e0, 0xff00a0e0, 0xff40a0e0,
- 0xff80a0e0, 0xffc0a0e0, 0xff00c0e0, 0xff40c0e0, 0xff80c0e0, 0xffc0c0e0,
- 0xff00e0e0, 0xff40e0e0, 0xff80e0e0, 0xffc0e0e0,
-};
-
-const uint grey256[256] = {
- 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
- 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
- 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff111111, 0xff111111,
- 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111,
- 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111,
- 0xff111111, 0xff111111, 0xff222222, 0xff222222, 0xff222222, 0xff222222,
- 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222,
- 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222,
- 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333,
- 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333,
- 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff444444, 0xff444444,
- 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444,
- 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444,
- 0xff444444, 0xff444444, 0xff555555, 0xff555555, 0xff555555, 0xff555555,
- 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555,
- 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555,
- 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666,
- 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666,
- 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff777777, 0xff777777,
- 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777,
- 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777,
- 0xff777777, 0xff777777, 0xff888888, 0xff888888, 0xff888888, 0xff888888,
- 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888,
- 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888,
- 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999,
- 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999,
- 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xffaaaaaa, 0xffaaaaaa,
- 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa,
- 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa,
- 0xffaaaaaa, 0xffaaaaaa, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb,
- 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb,
- 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb,
- 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc,
- 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc,
- 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffdddddd, 0xffdddddd,
- 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd,
- 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd,
- 0xffdddddd, 0xffdddddd, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee,
- 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee,
- 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-};
-
cOsdPipObject::cOsdPipObject(cDevice *Device, const cChannel *Channel):
cOsdObject(true) {
m_Channel = Channel;
m_Osd = NULL;
- m_ESBuffer = new cRingBufferLinear(MEGABYTE(3), 0, true);
+ m_ESBuffer = new cRingBufferFrame(MEGABYTE(3), true);
m_Active = false;
m_Ready = false;
m_Width = m_Height = -1;
m_Bitmap = NULL;
+ m_AlphaBase = 0xFF000000;
+ memset(m_Palette, 0, 1024);
+ m_PaletteStart = 0;
+
Device->SwitchChannel(m_Channel, false);
m_Receiver = new cOsdPipReceiver(m_Channel, m_ESBuffer);
Device->AttachReceiver(m_Receiver);
@@ -126,75 +45,270 @@ cOsdPipObject::~cOsdPipObject() {
delete m_Osd;
}
+int cOsdPipObject::Decode(unsigned char * data, int length) {
+ int gotPicture, len;
+
+ len = avcodec_decode_video(m_Context, m_PicDecoded, &gotPicture, data, length);
+ if (len < 0)
+ {
+ printf("Error while decoding frame\n");
+ return -1;
+ }
+ if (!gotPicture)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int cOsdPipObject::Resample() {
+ ImgReSampleContext * contextResample;
+
+ contextResample = img_resample_full_init(m_Width, m_Height,
+ m_Context->width, m_Context->height,
+ OsdPipSetup.CropTop, OsdPipSetup.CropBottom,
+ OsdPipSetup.CropLeft, OsdPipSetup.CropRight);
+ if (!contextResample) {
+ printf("Error initializing resample context.\n");
+ return -1;
+ }
+ avpicture_fill((AVPicture *) m_PicResample, m_BufferResample,
+ PIX_FMT_YUV420P, m_Width, m_Height);
+ img_resample(contextResample, (AVPicture *) m_PicResample, (AVPicture *) m_PicDecoded);
+ img_resample_close(contextResample);
+
+ return 0;
+}
+
+int cOsdPipObject::ConvertToRGB() {
+ avpicture_fill((AVPicture *) m_PicConvert, m_BufferConvert,
+ PIX_FMT_RGBA32, m_Width, m_Height);
+ img_convert((AVPicture *) m_PicConvert, PIX_FMT_RGBA32,
+ (AVPicture *) m_PicResample, PIX_FMT_YUV420P,
+ m_Width, m_Height);
+
+ return 0;
+}
+
+void cOsdPipObject::ProcessImage(unsigned char * data, int length) {
+ unsigned int value;
+ unsigned int * outputPalette;
+ unsigned char * outputImage;
+
+ if (OsdPipSetup.FrameMode == kFrameModeI) {
+ if (m_FrameDrop == OsdPipSetup.FrameDrop) {
+ m_FrameDrop = 0;
+ } else {
+ m_FrameDrop++;
+ return;
+ }
+ }
+
+ if (Decode(data, length) != 0)
+ return;
+
+ if (OsdPipSetup.FrameMode == kFrameModeIP ||
+ OsdPipSetup.FrameMode == kFrameModeIPB) {
+ if (m_FrameDrop == OsdPipSetup.FrameDrop) {
+ m_FrameDrop = 0;
+ } else {
+ m_FrameDrop++;
+ return;
+ }
+ }
+
+ if (!m_Ready) {
+ switch (OsdPipSetup.Size) {
+ case 0:
+ m_Width = 120;
+ m_Height = 96;
+ break;
+ case 1:
+ m_Width = 160;
+ m_Height = 128;
+ break;
+ case 2:
+ m_Width = 200;
+ m_Height = 160;
+ break;
+ case 3:
+ m_Width = 240;
+ m_Height = 192;
+ break;
+ case 4:
+ m_Width = 280;
+ m_Height = 224;
+ break;
+ case 5:
+ m_Width = 320;
+ m_Height = 256;
+ break;
+ }
+ m_Window = m_Osd->Create(OsdPipSetup.XPosition, OsdPipSetup.YPosition,
+ m_Width, m_Height, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8, false);
+ m_Bitmap = new cBitmap(m_Width, m_Height,
+ OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8, false);
+ if (OsdPipSetup.ColorDepth == kDepthGrey128)
+ for (unsigned int i = 0; i < 256; i++) {
+ m_Palette[i] = m_AlphaBase | (i << 16) | (i << 8) | i;
+ }
+ m_Ready = true;
+ }
+
+ if (Resample() != 0)
+ return;
+
+ int size;
+ size = m_Width * m_Height;
+
+ if (OsdPipSetup.ColorDepth == kDepthGrey16) {
+ outputImage = m_PicResample->data[0];
+ m_Bitmap->Clear();
+ for (int y = 0; y < m_Height; y++) {
+ for (int x = 0; x < m_Width; x++) {
+ value = outputImage[y * m_Width + x];
+ value = value / 16;
+ value = value * 16;
+ value = m_AlphaBase | (value << 16) | (value << 8) | value;
+ m_Bitmap->SetPixel(x, y, (eDvbColor) value);
+ }
+ }
+ }
+ if (OsdPipSetup.ColorDepth == kDepthGrey128) {
+ outputImage = m_PicResample->data[0];
+ m_Bitmap->Clear();
+ for (int y = 0; y < m_Height; y++) {
+ for (int x = 0; x < m_Width; x++) {
+ m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[outputImage[y * m_Width + x] & 0xFE]);
+ }
+ }
+ }
+ if (OsdPipSetup.ColorDepth == kDepthColor256fix ||
+ OsdPipSetup.ColorDepth == kDepthColor128var) {
+ if (ConvertToRGB() != 0)
+ return;
+
+ if (OsdPipSetup.SwapFfmpeg) {
+ unsigned int * bufPtr = (unsigned int *) m_BufferConvert;
+ unsigned char red, green, blue, alpha;
+ for (int i = 0; i < size; i++) {
+ value = *bufPtr;
+ blue = value;
+ green = value >> 8;
+ red = value >> 16;
+ alpha = value >> 24;
+ value = (alpha << 24) | (blue << 16) | (green << 8) | red;
+ *bufPtr = value;
+ bufPtr++;
+ }
+ }
+
+ quantizer->Quantize(m_BufferConvert, size, 128);
+
+ outputPalette = quantizer->OutputPalette();
+ outputImage = quantizer->OutputImage();
+ if (OsdPipSetup.ColorDepth == kDepthColor256fix) {
+ for (int i = 0; i < 256; i++)
+ m_Palette[i] = m_AlphaBase | outputPalette[i];
+
+ m_Bitmap->Clear();
+ for (int y = 0; y < m_Height; y++) {
+ for (int x = 0; x < m_Width; x++) {
+ m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]);
+ }
+ }
+ } else {
+ for (int i = 0; i < 128; i++)
+ {
+ m_Palette[m_PaletteStart + i] = outputPalette[i];
+ m_Palette[m_PaletteStart + i] |= m_AlphaBase;
+ }
+
+ m_Bitmap->Clear();
+ for (int i = 0; i < 256; i++)
+ m_Bitmap->SetColor(i, (eDvbColor) m_Palette[i]);
+ for (int y = 0; y < m_Height; y++) {
+ for (int x = 0; x < m_Width; x++) {
+ m_Bitmap->SetIndex(x, y, m_PaletteStart + outputImage[y * m_Width + x]);
+ }
+ }
+
+ if (m_PaletteStart == 0)
+ m_PaletteStart = 128;
+ else
+ m_PaletteStart = 0;
+ }
+ }
+
+ m_Osd->Clear();
+ m_Osd->SetBitmap(OsdPipSetup.XPosition, OsdPipSetup.YPosition,
+ *m_Bitmap);
+ m_Osd->Flush();
+}
+
void cOsdPipObject::Action(void) {
m_Active = true;
isyslog("osdpip: decoder thread started (pid = %d)", getpid());
- mpeg2dec_t *handle = mpeg2_init();
- const mpeg2_info_t *info = mpeg2_info(handle);
- mpeg2_state_t state;
+ m_Codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
+ if (!m_Codec)
+ {
+ printf("codec not found\n");
+ }
+ m_Context = avcodec_alloc_context();
+ if (avcodec_open(m_Context, m_Codec) < 0)
+ {
+ printf("could not open codec\n");
+ }
+ m_PicDecoded = avcodec_alloc_frame();
+ m_PicResample = avcodec_alloc_frame();
+ m_BufferResample = new unsigned char[(400 * 300 * 3) / 2]; // size for YUV 420
+ m_PicConvert = avcodec_alloc_frame();
+ m_BufferConvert = new unsigned char[400 * 300 * 4]; // size for RGBA32
+
+ if (OsdPipSetup.ColorDepth == kDepthColor128var)
+ quantizer = new cQuantizeWu();
+ if (OsdPipSetup.ColorDepth == kDepthColor256fix)
+ quantizer = new cQuantizeFixed();
+
+ cFrame * frame;
+ int pictureType;
+ m_FrameDrop = OsdPipSetup.FrameDrop;
while (m_Active) {
- const uchar *block;
- int recvd;
-
- state = mpeg2_parse(handle);
- switch (state) {
- case STATE_BUFFER:
- block = m_ESBuffer->Get(recvd);
- if (block && recvd > 0) {
- mpeg2_buffer(handle, (uint8_t*)block, (uint8_t*)block + recvd);
- m_ESBuffer->Del(recvd);
- } else
+ frame = m_ESBuffer->Get();
+ {
+ if (frame && frame->Count() > 0) {
+ pictureType = frame->Index();
+ if ((OsdPipSetup.FrameMode == kFrameModeI &&
+ pictureType == I_FRAME) ||
+ (OsdPipSetup.FrameMode == kFrameModeIP &&
+ (pictureType == I_FRAME || pictureType == P_FRAME)) ||
+ (OsdPipSetup.FrameMode == kFrameModeIPB)) {
+ ProcessImage(frame->Data(), frame->Count());
+ }
+ m_ESBuffer->Drop(frame);
+ } else {
+ if (frame)
+ m_ESBuffer->Drop(frame);
usleep(1);
- break;
-
- case STATE_SEQUENCE:
- if (!m_Ready) {
- m_Width = (info->sequence->width - OsdPipSetup.CropLeft
- - OsdPipSetup.CropRight) / OsdPipSetup.ZoomFactor;
- m_Height = (info->sequence->height - OsdPipSetup.CropTop
- - OsdPipSetup.CropBottom) / OsdPipSetup.ZoomFactor;
- m_Window = m_Osd->Create(OsdPipSetup.XPosition, OsdPipSetup.YPosition,
- m_Width, m_Height, OsdPipSetup.ColorDepth == 0 ? 4 : 8);
- m_Bitmap = new cBitmap(m_Width, m_Height,
- OsdPipSetup.ColorDepth == 0 ? 4 : 8);
- m_Ready = true;
}
- mpeg2_convert(handle, mpeg2convert_rgb8, NULL);
- break;
-
- case STATE_SLICE:
- case STATE_END:
- case STATE_INVALID_END:
- if (m_Ready && info->display_fbuf && (info->display_picture->flags
- & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_I) {
- int px = OsdPipSetup.CropLeft;
- int py = OsdPipSetup.CropRight;
- for (int x = 0; x < m_Width; ++x) {
- for (int y = 0; y < m_Height; ++y) {
- uint8_t idx = info->display_fbuf->buf[0][py
- * info->sequence->width + px];
- uint col = OsdPipSetup.ColorDepth == 0 ? grey256[idx] : rgb256[idx];
-
- m_Bitmap->SetPixel(x, y, (eDvbColor)col);
- py += OsdPipSetup.ZoomFactor;
- }
- px += OsdPipSetup.ZoomFactor;
- py = 0;
- }
- m_Osd->SetBitmap(OsdPipSetup.XPosition, OsdPipSetup.YPosition,
- *m_Bitmap);
- m_Osd->Flush();
- }
- break;
-
- default:
- break;
- }
+ }
}
+ if (OsdPipSetup.ColorDepth == kDepthColor128var ||
+ OsdPipSetup.ColorDepth == kDepthColor256fix)
+ delete quantizer;
+ delete[] m_BufferConvert;
+ free(m_PicConvert);
+ delete[] m_BufferResample;
+ free(m_PicResample);
+ avcodec_close(m_Context);
+ free(m_Context);
+ free(m_PicDecoded);
+
isyslog("osdpip: decoder thread stopped");
}
@@ -261,3 +375,4 @@ eOSState cOsdPipObject::ProcessKey(eKeys Key) {
}
return state;
}
+
diff --git a/osd.h b/osd.h
index a43d6b6..5b30ca1 100644
--- a/osd.h
+++ b/osd.h
@@ -1,22 +1,34 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#ifndef VDR_OSDPIP_OSD_H
#define VDR_OSDPIP_OSD_H
+extern "C"
+{
+#ifdef HAVE_FFMPEG_STATIC
+# include <avcodec.h>
+#else
+# include <ffmpeg/avcodec.h>
+#endif
+}
+
#include <vdr/osd.h>
#include <vdr/thread.h>
+#include <vdr/status.h>
#include <vdr/receiver.h>
-extern "C" {
-#include <mpeg2dec/mpeg2.h>
-#include <mpeg2dec/mpeg2convert.h>
-};
-
-class cRingBufferLinear;
+class cRingBufferFrame;
class cOsdPipReceiver;
+class cQuantize;
class cOsdPipObject: public cOsdObject, public cThread {
private:
cOsdBase *m_Osd;
- cRingBufferLinear *m_ESBuffer;
+ cRingBufferFrame *m_ESBuffer;
cOsdPipReceiver *m_Receiver;
const cChannel *m_Channel;
tWindowHandle m_Window;
@@ -25,7 +37,26 @@ private:
bool m_Active;
bool m_Ready;
int m_Width, m_Height;
+ int m_FrameDrop;
+
+ AVCodec * m_Codec;
+ AVCodecContext * m_Context;
+ AVFrame * m_PicDecoded;
+ AVFrame * m_PicResample;
+ AVFrame * m_PicConvert;
+ unsigned char * m_BufferResample;
+ unsigned char * m_BufferConvert;
+
+ unsigned int m_AlphaBase;
+ unsigned int m_Palette[256];
+ int m_PaletteStart;
+
+ cQuantize * quantizer;
+ int Decode(unsigned char * data, int length);
+ int Resample();
+ int ConvertToRGB();
+ void ProcessImage(unsigned char * data, int length);
protected:
virtual void Action(void);
diff --git a/osdpip.c b/osdpip.c
index 7507777..59abe13 100644
--- a/osdpip.c
+++ b/osdpip.c
@@ -1,18 +1,25 @@
/*
- * osdpip.c: A plugin for the Video Disk Recorder
+ * OSD Picture in Picture plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
- *
- * $Id$
*/
+extern "C"
+{
+#ifdef HAVE_FFMPEG_STATIC
+# include <avcodec.h>
+#else
+# include <ffmpeg/avcodec.h>
+#endif
+}
+
#include "osd.h"
#include "config.h"
#include "i18n.h"
#include <vdr/plugin.h>
-static const char *VERSION = "0.0.2";
+static const char *VERSION = "0.0.3";
static const char *DESCRIPTION = "OSD Picture-in-Picture";
static const char *MAINMENUENTRY = "Picture-in-Picture";
@@ -50,6 +57,11 @@ bool cPluginOsdpip::ProcessArgs(int argc, char *argv[]) {
}
bool cPluginOsdpip::Initialize(void) {
+ // must be called before using avcodec lib
+ avcodec_init();
+ // register all the codecs (you can also register only the codec
+ // you wish to have smaller code)
+ avcodec_register_all();
return true;
}
diff --git a/patches/vdr-1.2.6.diff b/patches/vdr-1.2.6.diff
new file mode 100644
index 0000000..5554889
--- /dev/null
+++ b/patches/vdr-1.2.6.diff
@@ -0,0 +1,77 @@
+diff -u vdr-1.2.6/osdbase.c vdr/osdbase.c
+--- vdr-1.2.6/osdbase.c 2003-08-24 13:38:27.000000000 +0200
++++ vdr/osdbase.c 2004-01-13 09:33:21.000000000 +0100
+@@ -104,6 +104,12 @@
+ }
+ }
+
++void cPalette::Replace(const cPalette &Palette)
++{
++ for (int i = 0; i < Palette.numColors; i++)
++ SetColor(i, Palette.color[i]);
++}
++
+ // --- cBitmap ---------------------------------------------------------------
+
+ cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground)
+@@ -220,6 +226,17 @@
+ }
+ }
+
++void cBitmap::SetBitmap256(int x, int y, const cBitmap &Bitmap)
++{
++ if (bitmap && Bitmap.bitmap) {
++ Replace(Bitmap);
++ for (int ix = 0; ix < Bitmap.width; ix++) {
++ for (int iy = 0; iy < Bitmap.height; iy++)
++ SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]);
++ }
++ }
++}
++
+ int cBitmap::Width(unsigned char c)
+ {
+ return font ? font->Width(c) : -1;
+@@ -317,7 +334,10 @@
+ x -= x0;
+ y -= y0;
+ }
+- cBitmap::SetBitmap(x, y, Bitmap);
++ if (bpp == 8)
++ cBitmap::SetBitmap256(x, y, Bitmap);
++ else
++ cBitmap::SetBitmap(x, y, Bitmap);
+ }
+
+ void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
+diff -u vdr-1.2.6/osdbase.h vdr/osdbase.h
+--- vdr-1.2.6/osdbase.h 2002-09-08 16:12:41.000000000 +0200
++++ vdr/osdbase.h 2004-01-13 09:22:24.000000000 +0100
+@@ -13,7 +13,8 @@
+ #include <stdio.h>
+ #include "font.h"
+
+-#define MAXNUMCOLORS 16
++#define MAXNUMCOLORS 256
++#define VDR_OSDPIP_PATCHED
+
+ enum eDvbColor {
+ #ifdef DEBUG_OSD
+@@ -69,7 +70,8 @@
+ // stored yet, NumColors will be set to 0 and the function will
+ // return NULL.
+ void Take(const cPalette &Palette, tIndexes *Indexes = NULL);
+- };
++ void Replace(const cPalette &Palette);
++};
+
+ class cBitmap : public cPalette {
+ private:
+@@ -89,6 +91,7 @@
+ void SetIndex(int x, int y, char Index);
+ void SetPixel(int x, int y, eDvbColor Color);
+ void SetBitmap(int x, int y, const cBitmap &Bitmap);
++ void SetBitmap256(int x, int y, const cBitmap &Bitmap);
+ int Width(void) { return width; }
+ int Width(unsigned char c);
+ int Width(const char *s);
diff --git a/patches/vdr-1.2.6_256.diff b/patches/vdr-1.2.6_256.diff
new file mode 100644
index 0000000..843bbf5
--- /dev/null
+++ b/patches/vdr-1.2.6_256.diff
@@ -0,0 +1,75 @@
+diff -u vdr-1.2.6/osdbase.c vdr/osdbase.c
+--- vdr-1.2.6/osdbase.c 2003-08-24 13:38:27.000000000 +0200
++++ vdr/osdbase.c 2004-01-13 09:33:21.000000000 +0100
+@@ -104,6 +104,12 @@
+ }
+ }
+
++void cPalette::Replace(const cPalette &Palette)
++{
++ for (int i = 0; i < Palette.numColors; i++)
++ SetColor(i, Palette.color[i]);
++}
++
+ // --- cBitmap ---------------------------------------------------------------
+
+ cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground)
+@@ -220,6 +226,17 @@
+ }
+ }
+
++void cBitmap::SetBitmap256(int x, int y, const cBitmap &Bitmap)
++{
++ if (bitmap && Bitmap.bitmap) {
++ Replace(Bitmap);
++ for (int ix = 0; ix < Bitmap.width; ix++) {
++ for (int iy = 0; iy < Bitmap.height; iy++)
++ SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]);
++ }
++ }
++}
++
+ int cBitmap::Width(unsigned char c)
+ {
+ return font ? font->Width(c) : -1;
+@@ -317,7 +334,10 @@
+ x -= x0;
+ y -= y0;
+ }
+- cBitmap::SetBitmap(x, y, Bitmap);
++ if (bpp == 8)
++ cBitmap::SetBitmap256(x, y, Bitmap);
++ else
++ cBitmap::SetBitmap(x, y, Bitmap);
+ }
+
+ void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
+diff -u vdr-1.2.6/osdbase.h vdr/osdbase.h
+--- vdr-1.2.6/osdbase.h 2002-09-08 16:12:41.000000000 +0200
++++ vdr/osdbase.h 2004-01-13 09:22:24.000000000 +0100
+@@ -14,6 +14,7 @@
+ #include "font.h"
+
+ #define MAXNUMCOLORS 256
++#define VDR_OSDPIP_PATCHED
+
+ enum eDvbColor {
+ #ifdef DEBUG_OSD
+@@ -69,7 +70,8 @@
+ // stored yet, NumColors will be set to 0 and the function will
+ // return NULL.
+ void Take(const cPalette &Palette, tIndexes *Indexes = NULL);
+- };
++ void Replace(const cPalette &Palette);
++};
+
+ class cBitmap : public cPalette {
+ private:
+@@ -89,6 +91,7 @@
+ void SetIndex(int x, int y, char Index);
+ void SetPixel(int x, int y, eDvbColor Color);
+ void SetBitmap(int x, int y, const cBitmap &Bitmap);
++ void SetBitmap256(int x, int y, const cBitmap &Bitmap);
+ int Width(void) { return width; }
+ int Width(unsigned char c);
+ int Width(const char *s);
diff --git a/pes.c b/pes.c
new file mode 100644
index 0000000..f76090e
--- /dev/null
+++ b/pes.c
@@ -0,0 +1,35 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include "pes.h"
+
+cPESPacket::cPESPacket(unsigned char * data, int length)
+: data(data),
+ length(length)
+{
+ streamId = data[3];
+ packetLength = (data[4] << 8) | data[5];
+ headerDataLength = data[8];
+ payloadStart = headerDataLength + 9;
+ payloadLength = packetLength + 6 - payloadStart;
+}
+
+void cPESPacket::Dump(FILE * fp)
+{
+ fprintf(fp, "Stream ID: %02X ", streamId);
+ fprintf(fp, "Packet Length: %d ", packetLength);
+ fprintf(fp, "Header Data Length: %d ", headerDataLength);
+ fprintf(fp, "Payload Start: %d ", payloadStart);
+ fprintf(fp, "Payload Length: %d ", payloadLength);
+ fprintf(fp, "\n");
+}
+
+unsigned char * cPESPacket::Payload(int & retLength)
+{
+ retLength = payloadLength;
+ return data + payloadStart;
+}
+
diff --git a/pes.h b/pes.h
new file mode 100644
index 0000000..35ae8d0
--- /dev/null
+++ b/pes.h
@@ -0,0 +1,31 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef VDR_OSDPIP_PES_H
+#define VDR_OSDPIP_PES_H
+
+#include <stdio.h>
+
+class cPESPacket
+{
+private:
+ unsigned char * data;
+ int length;
+
+ unsigned char streamId;
+ unsigned short packetLength;
+ unsigned char headerDataLength;
+ int payloadStart;
+ int payloadLength;
+public:
+ cPESPacket(unsigned char * data, int length);
+ void Dump(FILE * fp = stdout);
+ unsigned char StreamId() { return streamId; }
+ unsigned char * Payload(int & length);
+};
+
+#endif // VDR_OSDPIP_PES_H
+
diff --git a/quantize.c b/quantize.c
new file mode 100644
index 0000000..b513b4c
--- /dev/null
+++ b/quantize.c
@@ -0,0 +1,511 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * The Wu Quantizer is based on Benny's Wu quantizer v1.0 and on Xaolin Wu
+ * quantizer from the Graphics Gems
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "quantize.h"
+
+cQuantize::cQuantize() {
+}
+
+cQuantize::~cQuantize() {
+}
+
+cQuantizeFixed::cQuantizeFixed() {
+ redLevelCount = 8;
+ greenLevelCount = 8;
+ blueLevelCount = 4;
+
+ redLevels[0] = 0;
+ redLevels[redLevelCount - 1] = 255;
+ for (int i = 1; i < redLevelCount - 1; i++) {
+ redLevels[i] = (256 * i) / (redLevelCount - 1);
+ }
+
+ greenLevels[0] = 0;
+ greenLevels[greenLevelCount - 1] = 255;
+ for (int i = 1; i < greenLevelCount - 1; i++) {
+ greenLevels[i] = (256 * i) / (greenLevelCount - 1);
+ }
+
+ blueLevels[0] = 0;
+ blueLevels[blueLevelCount - 1] = 255;
+ for (int i = 1; i < blueLevelCount - 1; i++) {
+ blueLevels[i] = (256 * i) / (blueLevelCount - 1);
+ }
+
+ for (int r = 0; r < redLevelCount; r++) {
+ for (int g = 0; g < greenLevelCount; g++) {
+ for (int b = 0; b < blueLevelCount; b++) {
+ paletteOutput[r * greenLevelCount * blueLevelCount + g * blueLevelCount + b] =
+ (blueLevels[b] << 16) | (greenLevels[g] << 8) | redLevels[r];
+ }
+ }
+ }
+}
+
+cQuantizeFixed::~cQuantizeFixed() {
+}
+
+int cQuantizeFixed::Quantize(unsigned char * input, int size, int colors) {
+ imageInput = input;
+ imageSize = size;
+
+ unsigned int * imagePtr = (unsigned int *) imageInput;
+ int diff, diffOld;
+ unsigned int value;
+ unsigned char redValue;
+ unsigned char greenValue;
+ unsigned char blueValue;
+ int r, g, b;
+ for (int i = 0; i < imageSize; i++) {
+ value = *imagePtr;
+ redValue = value;
+ greenValue = value >> 8;
+ blueValue = value >> 16;
+ diffOld = 256;
+ for (r = 0; r < redLevelCount; r++) {
+ diff = abs(redLevels[r] - redValue);
+ if (diff > diffOld)
+ break;
+ diffOld = diff;
+ }
+ diffOld = 256;
+ for (g = 0; g < greenLevelCount; g++) {
+ diff = abs(greenLevels[g] - greenValue);
+ if (diff > diffOld)
+ break;
+ diffOld = diff;
+ }
+ diffOld = 256;
+ for (b = 0; b < blueLevelCount; b++) {
+ diff = abs(blueLevels[b] - blueValue);
+ if (diff > diffOld)
+ break;
+ diffOld = diff;
+ }
+ r--;
+ g--;
+ b--;
+ imageOutput[i] = r * greenLevelCount * blueLevelCount + g * blueLevelCount + b;
+ imagePtr++;
+ }
+ return 0;
+}
+
+cQuantizeWu::cQuantizeWu()
+{
+}
+
+cQuantizeWu::~cQuantizeWu()
+{
+}
+
+#define WEIG //>>2
+int cQuantizeWu::Quantize(unsigned char * input, int size, int colors)
+{
+ struct box cube[MAXCOLOR];
+ int next;
+ int i;
+ int j;
+ int k;
+ int l;
+ float vv[MAXCOLOR];
+ float temp;
+ unsigned char * tag;
+ long weight;
+
+ imageInput = input;
+ imageSize = size;
+ palSize = colors;
+
+ for (j = 0; j < BOX; j++)
+ for (k = 0; k < BOX; k++)
+ for (l = 0; l < BOX; l++)
+ {
+ wt[j][k][l] = 0;
+ mr[j][k][l] = 0;
+ mg[j][k][l] = 0;
+ mb[j][k][l] = 0;
+ m2[j][k][l] = 0.0;
+ }
+
+ Qadd = new unsigned short[imageSize * sizeof(unsigned short)];
+ Hist3d((long *)&wt, (long *)&mr, (long *)&mg, (long *)&mb, (float *)&m2);
+ Momt3d((long *)&wt, (long *)&mr, (long *)&mg, (long *)&mb, (float *)&m2);
+
+ cube[0].r0 = cube[0].g0 = cube[0].b0 = 0;
+ cube[0].r1 = cube[0].g1 = cube[0].b1 = 32;
+
+ next = 0;
+ for (i = 1; i < palSize; i++)
+ {
+ if (Cut(&cube[next], &cube[i]))
+ {
+ vv[next] = (cube[next].vol > 1) ? Var(&cube[next]) : 0.0;
+ vv[i] = (cube[i].vol > 1) ? Var(&cube[i]) : 0.0;
+ }
+ else
+ {
+ vv[next] = 0.0;
+ i--;
+ }
+ next = 0;
+ temp = vv[0];
+ for (k = 1; k <= i; k++)
+ if (vv[k] > temp)
+ {
+ temp = vv[k];
+ next = k;
+ }
+ if (temp <= 0.0)
+ {
+ palSize = i + 1;
+ break;
+ }
+ }
+
+ tag = new unsigned char[BOX * BOX * BOX];
+
+ unsigned char * palette = (unsigned char *) paletteOutput;
+ for (k = 0; k < palSize; ++k)
+ {
+ Mark(&cube[k], k, tag);
+ weight = Vol(&cube[k], wt);
+ if (weight)
+ {
+#ifdef NOINVERT
+ palette[k * 4 + 2] = (Vol(&cube[k], mr) / weight) WEIG;
+ palette[k * 4 + 0] = (Vol(&cube[k], mb) / weight) WEIG;
+#else
+ palette[k * 4 + 0] = (Vol(&cube[k], mr) / weight) WEIG;
+ palette[k * 4 + 2] = (Vol(&cube[k], mb) / weight) WEIG;
+#endif
+ palette[k * 4 + 1] = (Vol(&cube[k], mg) / weight) WEIG;
+ }
+ else
+ {
+ palette[k * 4 + 0] = 0;
+ palette[k * 4 + 1] = 0;
+ palette[k * 4 + 2] = 0;
+ }
+ }
+
+ for (i = 0; i < imageSize; i++)
+ {
+ imageOutput[i] = tag[Qadd[i]];
+ }
+
+ delete[] tag;
+ delete[] Qadd;
+
+ return 0;
+}
+
+// build 3-D color histogram of counts, r/g/b, c^2
+void cQuantizeWu::Hist3d(long *vwt, long *vmr, long *vmg, long *vmb, float *m_2)
+{
+ int ind;
+ int r;
+ int g;
+ int b;
+ int inr;
+ int ing;
+ int inb;
+ int table[256];
+ int i;
+
+ for (i = 0; i < 256; i++)
+ table[i] = i * i;
+
+ for (i = 0; i < imageSize; i++)
+ {
+ r = imageInput[i*4];
+ g = imageInput[i*4+1];
+ b = imageInput[i*4+2];
+
+ inr = (r >> 3) + 1;
+ ing = (g >> 3) + 1;
+ inb = (b >> 3) + 1;
+ Qadd[i] = ind = (inr << 10) + (inr << 6) + inr + (ing << 5) + ing + inb;
+
+ vwt[ind]++;
+ vmr[ind] += r;
+ vmg[ind] += g;
+ vmb[ind] += b;
+ m_2[ind] += (float) (table[r] + table[g] + table[b]);
+ }
+}
+
+// We now convert histogram into moments so that we can rapidly calculate
+// the sums of the above quantities over any desired box.
+void cQuantizeWu::Momt3d(long *vwt, long *vmr, long *vmg, long *vmb, float *m_2)
+{
+ unsigned short ind1;
+ unsigned short ind2;
+ unsigned char i;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+ long line;
+ long line_r;
+ long line_g;
+ long line_b;
+ long area[BOX];
+ long area_r[BOX];
+ long area_g[BOX];
+ long area_b[BOX];
+ float line2;
+ float area2[BOX];
+
+ for (r = 1; r <= 32; ++r)
+ {
+ for (i = 0; i <= 32; ++i)
+ area2[i] = area[i] = area_r[i] = area_g[i] = area_b[i] = 0;
+ for (g = 1; g <= 32; ++g)
+ {
+ line2 = line = line_r = line_g = line_b = 0;
+ for (b = 1; b <= 32; ++b)
+ {
+ ind1 = (r << 10) + (r << 6) + r + (g << 5) + g + b;
+ line += vwt[ind1];
+ line_r += vmr[ind1];
+ line_g += vmg[ind1];
+ line_b += vmb[ind1];
+ line2 += m_2[ind1];
+ area[b] += line;
+ area_r[b] += line_r;
+ area_g[b] += line_g;
+ area_b[b] += line_b;
+ area2[b] += line2;
+ ind2 = ind1 - 1089; /* [r-1][g][b] */
+ vwt[ind1] = vwt[ind2] + area[b];
+ vmr[ind1] = vmr[ind2] + area_r[b];
+ vmg[ind1] = vmg[ind2] + area_g[b];
+ vmb[ind1] = vmb[ind2] + area_b[b];
+ m_2[ind1] = m_2[ind2] + area2[b];
+ }
+ }
+ }
+}
+
+int cQuantizeWu::Cut(struct box * set1, struct box * set2)
+{
+ unsigned char dir;
+ int cutr;
+ int cutg;
+ int cutb;
+ float maxr;
+ float maxg;
+ float maxb;
+ long whole_r;
+ long whole_g;
+ long whole_b;
+ long whole_w;
+
+ whole_r = Vol(set1, mr);
+ whole_g = Vol(set1, mg);
+ whole_b = Vol(set1, mb);
+ whole_w = Vol(set1, wt);
+
+ maxr = Maximize(set1, RED, set1->r0 + 1, set1->r1, &cutr,
+ whole_r, whole_g, whole_b, whole_w);
+ maxg = Maximize(set1, GREEN, set1->g0 + 1, set1->g1, &cutg,
+ whole_r, whole_g, whole_b, whole_w);
+ maxb = Maximize(set1, BLUE, set1->b0 + 1, set1->b1, &cutb,
+ whole_r, whole_g, whole_b, whole_w);
+
+ if ((maxr >= maxg) && (maxr >= maxb))
+ {
+ dir = RED;
+ if (cutr < 0)
+ return 0; /* can't split the box */
+ }
+ else if ((maxg >= maxr) && (maxg >= maxb))
+ dir = GREEN;
+ else
+ dir = BLUE;
+
+ set2->r1 = set1->r1;
+ set2->g1 = set1->g1;
+ set2->b1 = set1->b1;
+
+ switch (dir)
+ {
+ case RED:
+ set2->r0 = set1->r1 = cutr;
+ set2->g0 = set1->g0;
+ set2->b0 = set1->b0;
+ break;
+ case GREEN:
+ set2->g0 = set1->g1 = cutg;
+ set2->r0 = set1->r0;
+ set2->b0 = set1->b0;
+ break;
+ case BLUE:
+ set2->b0 = set1->b1 = cutb;
+ set2->r0 = set1->r0;
+ set2->g0 = set1->g0;
+ break;
+ }
+ set1->vol = (set1->r1 - set1->r0) * (set1->g1 - set1->g0) * (set1->b1 - set1->b0);
+ set2->vol = (set2->r1 - set2->r0) * (set2->g1 - set2->g0) * (set2->b1 - set2->b0);
+ return 1;
+}
+
+long cQuantizeWu::Vol(struct box * cube, long mmt[BOX][BOX][BOX])
+{
+ return (mmt[cube->r1][cube->g1][cube->b1]
+ - mmt[cube->r1][cube->g1][cube->b0]
+ - mmt[cube->r1][cube->g0][cube->b1]
+ + mmt[cube->r1][cube->g0][cube->b0]
+ - mmt[cube->r0][cube->g1][cube->b1]
+ + mmt[cube->r0][cube->g1][cube->b0]
+ + mmt[cube->r0][cube->g0][cube->b1]
+ - mmt[cube->r0][cube->g0][cube->b0]);
+}
+
+float cQuantizeWu::Maximize(struct box * cube, unsigned char dir, int first, int last, int * cut, long whole_r, long whole_g, long whole_b, long whole_w)
+{
+ long half_r;
+ long half_g;
+ long half_b;
+ long half_w;
+ long base_r;
+ long base_g;
+ long base_b;
+ long base_w;
+ int i;
+ float temp;
+ float max;
+
+ base_r = Bottom(cube, dir, mr);
+ base_g = Bottom(cube, dir, mg);
+ base_b = Bottom(cube, dir, mb);
+ base_w = Bottom(cube, dir, wt);
+ max = 0.0;
+ *cut = -1;
+ for (i = first; i < last; i++)
+ {
+ half_r = base_r + Top(cube, dir, i, mr);
+ half_g = base_g + Top(cube, dir, i, mg);
+ half_b = base_b + Top(cube, dir, i, mb);
+ half_w = base_w + Top(cube, dir, i, wt);
+ // now half_x is sum over lower half of box, if split at i
+ if (half_w == 0)
+ {
+ // subbox could be empty of pixels!
+ continue; // never split into an empty box
+ }
+ else
+ temp = ((float) half_r * half_r + (float) half_g * half_g + (float) half_b * half_b) / half_w;
+
+ half_r = whole_r - half_r;
+ half_g = whole_g - half_g;
+ half_b = whole_b - half_b;
+ half_w = whole_w - half_w;
+ if (half_w == 0)
+ {
+ // subbox could be empty of pixels!
+ continue; // never split into an empty box
+ }
+ else
+ temp += ((float) half_r * half_r + (float) half_g * half_g + (float) half_b * half_b) / half_w;
+
+ if (temp > max)
+ {
+ max = temp;
+ *cut = i;
+ }
+ }
+ return (max);
+}
+
+float cQuantizeWu::Var(struct box * cube)
+{
+ float dr;
+ float dg;
+ float db;
+ float xx;
+
+ dr = Vol(cube, mr);
+ dg = Vol(cube, mg);
+ db = Vol(cube, mb);
+ xx = m2[cube->r1][cube->g1][cube->b1]
+ - m2[cube->r1][cube->g1][cube->b0]
+ - m2[cube->r1][cube->g0][cube->b1]
+ + m2[cube->r1][cube->g0][cube->b0]
+ - m2[cube->r0][cube->g1][cube->b1]
+ + m2[cube->r0][cube->g1][cube->b0]
+ + m2[cube->r0][cube->g0][cube->b1]
+ - m2[cube->r0][cube->g0][cube->b0];
+
+ return (xx - (dr * dr + dg * dg + db * db) / (float) Vol(cube, wt));
+}
+
+long cQuantizeWu::Bottom(struct box * cube, unsigned char dir, long mmt[BOX][BOX][BOX])
+{
+ switch (dir)
+ {
+ case RED:
+ return (-mmt[cube->r0][cube->g1][cube->b1]
+ + mmt[cube->r0][cube->g1][cube->b0]
+ + mmt[cube->r0][cube->g0][cube->b1]
+ - mmt[cube->r0][cube->g0][cube->b0]);
+ case GREEN:
+ return (-mmt[cube->r1][cube->g0][cube->b1]
+ + mmt[cube->r1][cube->g0][cube->b0]
+ + mmt[cube->r0][cube->g0][cube->b1]
+ - mmt[cube->r0][cube->g0][cube->b0]);
+ case BLUE:
+ return (-mmt[cube->r1][cube->g1][cube->b0]
+ + mmt[cube->r1][cube->g0][cube->b0]
+ + mmt[cube->r0][cube->g1][cube->b0]
+ - mmt[cube->r0][cube->g0][cube->b0]);
+ }
+ printf("error in Bottom()");
+ return 0;
+}
+
+long cQuantizeWu::Top(struct box * cube, unsigned char dir, int pos, long mmt[BOX][BOX][BOX])
+{
+ switch (dir)
+ {
+ case RED:
+ return (mmt[pos][cube->g1][cube->b1]
+ - mmt[pos][cube->g1][cube->b0]
+ - mmt[pos][cube->g0][cube->b1]
+ + mmt[pos][cube->g0][cube->b0]);
+ case GREEN:
+ return (mmt[cube->r1][pos][cube->b1]
+ - mmt[cube->r1][pos][cube->b0]
+ - mmt[cube->r0][pos][cube->b1]
+ + mmt[cube->r0][pos][cube->b0]);
+ case BLUE:
+ return (mmt[cube->r1][cube->g1][pos]
+ - mmt[cube->r1][cube->g0][pos]
+ - mmt[cube->r0][cube->g1][pos]
+ + mmt[cube->r0][cube->g0][pos]);
+ }
+ printf("error in Top()");
+ return 0;
+}
+
+void cQuantizeWu::Mark(struct box * cube, int label, unsigned char * tag)
+{
+ int r;
+ int g;
+ int b;
+
+ for (r = cube->r0 + 1; r <= cube->r1; r++)
+ for (g = cube->g0 + 1; g <= cube->g1; g++)
+ for (b = cube->b0 + 1; b <= cube->b1; b++)
+ tag[(r << 10) + (r << 6) + r + (g << 5) + g + b] = label;
+}
+
diff --git a/quantize.h b/quantize.h
new file mode 100644
index 0000000..389090b
--- /dev/null
+++ b/quantize.h
@@ -0,0 +1,96 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef VDR_OSDPIP_QUANTIZE_H
+#define VDR_OSDPIP_QUANTIZE_H
+
+#define MAXCOLOR 256
+
+class cQuantize
+{
+protected:
+ unsigned int paletteOutput[MAXCOLOR];
+ unsigned char imageOutput[1024*1024];
+public:
+ cQuantize();
+ virtual ~cQuantize();
+ virtual int Quantize(unsigned char * input, int size, int colors) = 0;
+ unsigned int * OutputPalette() { return paletteOutput; }
+ unsigned char * OutputImage() { return imageOutput; }
+};
+
+class cQuantizeFixed : public cQuantize
+{
+private:
+ unsigned char * imageInput;
+ int imageSize;
+
+ unsigned char redLevels[32];
+ unsigned char greenLevels[32];
+ unsigned char blueLevels[32];
+ int redLevelCount;
+ int greenLevelCount;
+ int blueLevelCount;
+public:
+ cQuantizeFixed();
+ virtual ~cQuantizeFixed();
+ virtual int Quantize(unsigned char * input, int size, int colors);
+};
+
+#define RED 2
+#define GREEN 1
+#define BLUE 0
+
+//#define NOINVERT // RGB or BGR
+
+struct box
+{
+ int r0;
+ int r1;
+ int g0;
+ int g1;
+ int b0;
+ int b1;
+ int vol;
+};
+
+// Histogram is in elements 1..HISTSIZE along each axis,
+// element 0 is for base or marginal value.
+// NB: these must start out 0!
+#define BOX 33
+
+class cQuantizeWu : public cQuantize
+{
+private:
+ long wt[BOX][BOX][BOX];
+ long mr[BOX][BOX][BOX];
+ long mg[BOX][BOX][BOX];
+ long mb[BOX][BOX][BOX];
+ float m2[BOX][BOX][BOX];
+
+ unsigned short * Qadd;
+
+ unsigned char * imageInput;
+ int imageSize;
+ int palSize;
+
+ void Hist3d(long *vwt, long *vmr, long *vmg, long *vmb, float *m_2);
+ void Momt3d(long *vwt, long *vmr, long *vmg, long *vmb, float *m_2);
+ int Cut(struct box * set1, struct box * set2);
+ long Vol(struct box * cube, long mmt[BOX][BOX][BOX]);
+ float Maximize(struct box * cube, unsigned char dir, int first, int last, int * cut, long whole_r, long whole_g, long whole_b, long whole_w);
+ float Var(struct box * cube);
+ long Top(struct box * cube, unsigned char dir, int pos, long mmt[BOX][BOX][BOX]);
+ long Bottom(struct box * cube, unsigned char dir, long mmt[BOX][BOX][BOX]);
+ void Mark(struct box * cube, int label, unsigned char * tag);
+public:
+ cQuantizeWu();
+ virtual ~cQuantizeWu();
+ virtual int Quantize(unsigned char * input, int size, int colors);
+};
+
+#endif // VDR_OSDPIP_QUANTIZE_H
+
diff --git a/receiver.c b/receiver.c
index 22a481c..430623f 100644
--- a/receiver.c
+++ b/receiver.c
@@ -1,15 +1,22 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#include "receiver.h"
-#include "remux/ts2es.h"
+#include "pes.h"
#include <vdr/channels.h>
+#include <vdr/remux.h>
#include <vdr/ringbuffer.h>
cOsdPipReceiver::cOsdPipReceiver(const cChannel *Channel,
- cRingBufferLinear *ESBuffer):
+ cRingBufferFrame *ESBuffer):
cReceiver(Channel->Ca(), 0, 2, Channel->Vpid(), Channel->Apid1()) {
m_TSBuffer = new cRingBufferLinear(MEGABYTE(3), TS_SIZE * 2, true);
m_ESBuffer = ESBuffer;
- m_Remux = new cTS2ESRemux(Channel->Vpid());
+ m_Remux = new cRemux(Channel->Vpid(), Channel->Apid1(), 0, 0, 0, true);
m_Active = false;
}
@@ -37,17 +44,35 @@ void cOsdPipReceiver::Receive(uchar *Data, int Length) {
void cOsdPipReceiver::Action(void) {
dsyslog("osdpip: receiver thread started (pid=%d)", getpid());
- m_Active = true;
+ m_Active = true;
+
+ unsigned char NewPictureType = NO_PICTURE;
+ unsigned char CurPictureType = NO_PICTURE;
+ unsigned char VideoBuffer[200000];
+ int VideoBufferPos = 0;
+
while (m_Active) {
int r;
const uchar *b = m_TSBuffer->Get(r);
if (b) {
int Count = r, Result;
- uchar *p = m_Remux->Process(b, Count, Result);
+ uchar *p = m_Remux->Process(b, Count, Result, &NewPictureType);
m_TSBuffer->Del(Count);
- if (p)
- m_ESBuffer->Put(p, Result);
+ if (p) {
+ if (NewPictureType != NO_PICTURE) {
+ m_ESBuffer->Put(new cFrame(VideoBuffer, VideoBufferPos, ftVideo, CurPictureType));
+ CurPictureType = NewPictureType;
+ VideoBufferPos = 0;
+ }
+ cPESPacket Packet(p, Result);
+ int PayloadLength = 0;
+ unsigned char * PayloadData = Packet.Payload(PayloadLength);
+ if ((Packet.StreamId() & 0xF0) == 0xE0) { // video packet
+ memcpy(&VideoBuffer[VideoBufferPos], PayloadData, PayloadLength);
+ VideoBufferPos += PayloadLength;
+ }
+ }
} else
usleep(1); // this keeps the CPU load low
}
diff --git a/receiver.h b/receiver.h
index 7de50db..d05b2f0 100644
--- a/receiver.h
+++ b/receiver.h
@@ -1,3 +1,9 @@
+/*
+ * OSD Picture in Picture plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
#ifndef VDR_OSDPIP_RECEIVER_H
#define VDR_OSDPIP_RECEIVER_H
@@ -5,13 +11,14 @@
#include <vdr/thread.h>
class cRingBufferLinear;
-class cTS2ESRemux;
+class cRingBufferFrame;
+class cRemux;
class cOsdPipReceiver: public cReceiver, public cThread {
private:
cRingBufferLinear *m_TSBuffer;
- cRingBufferLinear *m_ESBuffer;
- cTS2ESRemux *m_Remux;
+ cRingBufferFrame *m_ESBuffer;
+ cRemux *m_Remux;
bool m_Active;
@@ -22,7 +29,7 @@ protected:
public:
cOsdPipReceiver::cOsdPipReceiver(const cChannel *Channel,
- cRingBufferLinear *ESBuffer);
+ cRingBufferFrame *ESBuffer);
virtual ~cOsdPipReceiver();
};
diff --git a/remux/ts2es.c b/remux/ts2es.c
deleted file mode 100644
index 2f27d4f..0000000
--- a/remux/ts2es.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "remux/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 8026a1b..0000000
--- a/remux/ts2es.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef VDR_STREAMDEV_TS2ESREMUX_H
-#define VDR_STREAMDEV_TS2ESREMUX_H
-
-#include "remux/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 222c39a..0000000
--- a/remux/ts2ps.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "remux/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 (*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;
- m_VRemux = new cTS2PS(m_ResultBuffer, &m_ResultCount, 0x00, PS);
- 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_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->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 4e43ed2..0000000
--- a/remux/ts2ps.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef VDR_STREAMDEV_TS2PESREMUX_H
-#define VDR_STREAMDEV_TS2PESREMUX_H
-
-#include "remux/tsremux.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 93f513b..0000000
--- a/remux/tsremux.c
+++ /dev/null
@@ -1,185 +0,0 @@
-#include "remux/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) {
- 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;
- }
- Count = used;
-
- // When we don't need to sync, we don't need to sync :-)
- if (!m_Sync) {
- Result = m_ResultDelivered = m_ResultCount;
- return Result ? m_ResultBuffer : NULL;
- }
-
- // Check if we're getting anywhere here:
-
- if (!m_Synced && m_Skipped >= 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
- 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 3e83c73..0000000
--- a/remux/tsremux.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef VDR_STREAMDEV_TSREMUX_H
-#define VDR_STREAMDEV_TSREMUX_H
-
-#include "libdvbmpeg/transform.h"
-#include <vdr/remux.h>
-
-class cTSRemux {
-protected:
- uchar m_ResultBuffer[RESULTBUFFERSIZE];
- int m_ResultCount;
- int m_ResultDelivered;
- int m_Synced;
- int m_Skipped;
- int m_Sync;
-
- 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:
- 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