diff -u vdr-1.4.0/config.c vdr-1.4.0-ts/config.c --- vdr-1.4.0/config.c 2006-04-17 08:43:57.000000000 -0400 +++ vdr-1.4.0-ts/config.c 2006-11-17 22:52:03.000000000 -0500 @@ -273,6 +273,7 @@ CurrentDolby = 0; InitialChannel = 0; InitialVolume = -1; + RecordPES = 1; } cSetup& cSetup::operator= (const cSetup &s) @@ -434,6 +435,7 @@ else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value); else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = atoi(Value); else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value); + else if (!strcasecmp(Name, "RecordPES")) RecordPES = atoi(Value); else return false; return true; @@ -502,7 +504,8 @@ Store("CurrentDolby", CurrentDolby); Store("InitialChannel", InitialChannel); Store("InitialVolume", InitialVolume); - + Store("RecordPES", RecordPES); + Sort(); if (cConfig::Save()) { diff -u vdr-1.4.0/config.h vdr-1.4.0-ts/config.h --- vdr-1.4.0/config.h 2006-04-29 05:24:07.000000000 -0400 +++ vdr-1.4.0-ts/config.h 2006-11-17 22:52:03.000000000 -0500 @@ -252,6 +252,7 @@ int CurrentDolby; int InitialChannel; int InitialVolume; + int RecordPES; int __EndData__; cSetup(void); cSetup& operator= (const cSetup &s); diff -u vdr-1.4.0/device.c vdr-1.4.0-ts/device.c --- vdr-1.4.0/device.c 2006-10-15 19:41:19.000000000 -0400 +++ vdr-1.4.0-ts/device.c 2006-12-11 10:17:37.000000000 -0500 @@ -1093,6 +1093,11 @@ return Length; } +int cDevice::PlayTs(const uchar *Data, int Length, int* pids) +{ + return PlayTsData(Data, Length, pids); +} + int cDevice::PlayPes(const uchar *Data, int Length, bool VideoOnly) { if (!Data) { diff -u vdr-1.4.0/device.h vdr-1.4.0-ts/device.h --- vdr-1.4.0/device.h 2006-04-14 10:35:13.000000000 -0400 +++ vdr-1.4.0-ts/device.h 2006-12-11 09:57:40.000000000 -0500 @@ -446,6 +446,7 @@ ///< If VideoOnly is true, only the video will be displayed, ///< which is necessary for trick modes like 'fast forward'. ///< Data must point to one single, complete PES packet. + virtual int PlayTsData(const uchar *Data, int Length, int* pids) { return -1; } public: virtual int64_t GetSTC(void); ///< Gets the current System Time Counter, which can be used to @@ -491,6 +492,9 @@ ///< to a complete packet with data from the next call to PlayPes(). ///< That way any functions called from within PlayPes() will be ///< guaranteed to always receive complete PES packets. + virtual int PlayTs(const uchar *Data, int Length, int* pids); + virtual void StopTs(void) {} + bool Replaying(void) const; ///< Returns true if we are currently replaying. bool Transferring(void) const; diff -u vdr-1.4.0/dvbdevice.c vdr-1.4.0-ts/dvbdevice.c --- vdr-1.4.0/dvbdevice.c 2006-12-02 16:17:32.000000000 -0500 +++ vdr-1.4.0-ts/dvbdevice.c 2006-12-11 23:56:47.000000000 -0500 @@ -1229,6 +1229,70 @@ return true; } + +static void set_pid(int fd, int pid, dmx_pes_type_t type) +{ + struct dmx_pes_filter_params pesFilterParams; + + fprintf(stderr, "set PID 0x%04x (%d)\n", pid, type); + if (ioctl(fd, DMX_STOP) < 0) + perror("DMX STOP:"); + + if (ioctl(fd, DMX_SET_BUFFER_SIZE, 64*1024) < 0) + perror("DMX SET BUFFER:"); + + pesFilterParams.pid = pid; + pesFilterParams.input = DMX_IN_DVR; + pesFilterParams.output = DMX_OUT_DECODER; + pesFilterParams.pes_type = type; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) + perror("DMX SET FILTER"); +} + +int cDvbDevice::PlayTsData(const uchar *Data, int Length, int* pids) +{ + if (Data == NULL) // Get ready for real data + { + CloseDvr(); // Need this? + SetPlayMode(pmNone); + + dvrfd = vfd = afd = dfd = -1; + + if ((dvrfd = DvbOpen(DEV_DVB_DVR, CardIndex(), O_WRONLY)) == -1) { + fprintf(stderr, "Failed to open '%s': %d %m\n", dvrfd, errno); + //return; + } + if ((vfd = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_WRONLY)) == -1) { + fprintf(stderr, "Failed to open video '%s': %d %m\n", fd_stc, errno); + //return; + } + if ((afd = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_WRONLY)) == -1) { + fprintf(stderr, "Failed to open audio '%s': %d %m\n", fd_stc, errno); + //return; + } + if ((dfd = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_WRONLY)) == -1) { + fprintf(stderr, "Failed to open dd-audio '%s': %d %m\n", fd_stc, errno); + //return; + } + + set_pid(afd, pids[1], DMX_PES_AUDIO); + set_pid(vfd, pids[0], DMX_PES_VIDEO); + set_pid(dfd, pids[2], DMX_PES_OTHER); + + fprintf(stderr, "Starting TS Playback. VPid=%d, APid=%d, DPid=%d.\n", pids[0],pids[1],pids[2]); + return 0; + } + + return WriteAllOrNothing(dvrfd, Data, Length, 1000, 10); +} + +void cDvbDevice::StopTs(void) +{ + close(dvrfd); close(vfd); close(afd); close(dfd); + dvrfd = vfd = afd = dfd = -1; +} + int cDvbDevice::PlayVideo(const uchar *Data, int Length) { return WriteAllOrNothing(fd_video, Data, Length, 1000, 10); diff -u vdr-1.4.0/dvbdevice.h vdr-1.4.0-ts/dvbdevice.h --- vdr-1.4.0/dvbdevice.h 2006-04-01 09:18:59.000000000 -0500 +++ vdr-1.4.0-ts/dvbdevice.h 2006-12-11 10:03:59.000000000 -0500 @@ -116,11 +116,15 @@ // Player facilities protected: + int dvrfd, vfd, afd, dfd; + ePlayMode playMode; virtual bool CanReplay(void) const; virtual bool SetPlayMode(ePlayMode PlayMode); virtual int PlayVideo(const uchar *Data, int Length); virtual int PlayAudio(const uchar *Data, int Length, uchar Id); + virtual int PlayTsData(const uchar *Data, int Length, int* pids); + virtual void StopTs(void); public: virtual int64_t GetSTC(void); virtual void TrickSpeed(int Speed); diff -u vdr-1.4.0/dvbplayer.c vdr-1.4.0-ts/dvbplayer.c --- vdr-1.4.0/dvbplayer.c 2006-04-17 08:45:48.000000000 -0400 +++ vdr-1.4.0-ts/dvbplayer.c 2006-12-17 00:46:03.000000000 -0500 @@ -194,6 +194,8 @@ cRingBufferFrame *ringBuffer; cBackTrace *backTrace; cFileName *fileName; + bool isPES; + int pids[3]; cIndexFile *index; cUnbufferedFile *replayFile; bool eof; @@ -253,6 +255,16 @@ replayFile = fileName->Open(); if (!replayFile) return; + + isPES = true; + char *ext = strrchr(fileName->Name(), '.'); + if (ext) + if (strcmp(ext, TSRECEXT) == 0) { + isPES = false; + cRecording::readPidFile(FileName, pids); + } + + ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE); // Create the index file: index = new cIndexFile(FileName, false); @@ -262,18 +274,20 @@ delete index; index = NULL; } - backTrace = new cBackTrace; + backTrace = new cBackTrace; } cDvbPlayer::~cDvbPlayer() { + if (!isPES) StopTs(); + Detach(); Save(); delete readFrame; // might not have been stored in the buffer in Action() delete index; delete fileName; delete backTrace; - delete ringBuffer; + delete ringBuffer; } void cDvbPlayer::TrickSpeed(int Increment) @@ -488,14 +502,22 @@ pc = playFrame->Count(); if (p) { if (firstPacket) { - PlayPes(NULL, 0); + if (isPES) + PlayPes(NULL, 0); + else { + PlayTs(NULL, 0, pids); + } cRemux::SetBrokenLink(p, pc); firstPacket = false; } } } if (p) { - int w = PlayPes(p, pc, playMode != pmPlay); + int w; + if (isPES) + w = PlayPes(p, pc, playMode != pmPlay); + else + w = PlayTs(p, pc, pids); if (w > 0) { p += w; pc -= w; diff -u vdr-1.4.0/menu.c vdr-1.4.0-ts/menu.c --- vdr-1.4.0/menu.c 2006-04-28 08:48:01.000000000 -0400 +++ vdr-1.4.0-ts/menu.c 2006-12-17 00:19:11.000000000 -0500 @@ -642,6 +642,8 @@ Add(new cMenuEditDateItem(tr("Day"), &data.day, &data.weekdays)); Add(new cMenuEditTimeItem(tr("Start"), &data.start)); Add(new cMenuEditTimeItem(tr("Stop"), &data.stop)); + if (!timer->recording) + Add(new cMenuEditBoolItem(tr("Format"), &data.recordPES, tr("TS"), tr("PES"))); Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps)); Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME)); @@ -2538,6 +2540,7 @@ cMenuSetupRecord::cMenuSetupRecord(void) { SetSection(tr("Recording")); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Default recording format"), &data.RecordPES, tr("TS"), tr("PES"))); Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at start (min)"), &data.MarginStart)); Add(new cMenuEditIntItem( tr("Setup.Recording$Margin at stop (min)"), &data.MarginStop)); Add(new cMenuEditIntItem( tr("Setup.Recording$Primary limit"), &data.PrimaryLimit, 0, MAXPRIORITY)); @@ -3521,7 +3524,7 @@ isyslog("record %s", fileName); if (MakeDirs(fileName, true)) { const cChannel *ch = timer->Channel(); - recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids()); + recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids(), timer->RecordPES() ); if (device->AttachReceiver(recorder)) { Recording.WriteInfo(); cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true); diff -u vdr-1.4.0/player.c vdr-1.4.0-ts/player.c --- vdr-1.4.0/player.c 2006-01-06 06:30:07.000000000 -0500 +++ vdr-1.4.0-ts/player.c 2006-12-11 09:55:47.000000000 -0500 @@ -31,6 +31,20 @@ return -1; } +int cPlayer::PlayTs(const uchar *Data, int Length, int* pids) +{ + if (device) { + return device->PlayTs(Data, Length, pids); + } + esyslog("ERROR: attempt to use cPlayer::PlayTs() without attaching to a cDevice!"); + return -1; +} + +void cPlayer::StopTs(void) +{ + if (device) device->StopTs(); +} + void cPlayer::Detach(void) { if (device) diff -u vdr-1.4.0/player.h vdr-1.4.0-ts/player.h --- vdr-1.4.0/player.h 2006-01-06 06:29:27.000000000 -0500 +++ vdr-1.4.0-ts/player.h 2006-12-11 09:55:42.000000000 -0500 @@ -40,6 +40,8 @@ // Sends the given PES Data to the device and returns the number of // bytes that have actually been accepted by the device (or a // negative value in case of an error). + int PlayTs(const uchar *Data, int Length, int* pids); + void StopTs(void); public: cPlayer(ePlayMode PlayMode = pmAudioVideo); virtual ~cPlayer(); Common subdirectories: vdr-1.4.0/PLUGINS and vdr-1.4.0-ts/PLUGINS diff -u vdr-1.4.0/recorder.c vdr-1.4.0-ts/recorder.c --- vdr-1.4.0/recorder.c 2006-01-08 06:01:25.000000000 -0500 +++ vdr-1.4.0-ts/recorder.c 2006-12-17 00:58:55.000000000 -0500 @@ -35,11 +35,11 @@ protected: virtual void Action(void); public: - cFileWriter(const char *FileName, cRemux *Remux); + cFileWriter(const char *FileName, cRemux *Remux, bool RecordPES); virtual ~cFileWriter(); }; -cFileWriter::cFileWriter(const char *FileName, cRemux *Remux) +cFileWriter::cFileWriter(const char *FileName, cRemux *Remux, bool RecordPES) :cThread("file writer") { fileName = NULL; @@ -48,7 +48,7 @@ pictureType = NO_PICTURE; fileSize = 0; lastDiskSpaceCheck = time(NULL); - fileName = new cFileName(FileName, true); + fileName = new cFileName(FileName, true, false, RecordPES); recordFile = fileName->Open(); if (!recordFile) return; @@ -121,7 +121,7 @@ } } -cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) +cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, bool RecordPES) :cReceiver(Ca, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) ,cThread("recording") { @@ -131,8 +131,14 @@ ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder"); ringBuffer->SetTimeouts(0, 100); - remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, true); - writer = new cFileWriter(FileName, remux); + if (RecordPES) + remux = new cPESRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, true); + else { // Record TS + remux = new cTSRemux(); + int pids[3] ; pids[0] = VPid; pids[1] = APids[0]; pids[2] = DPids[0]; + cRecording::createPidFile(FileName, pids); + } + writer = new cFileWriter(FileName, remux, RecordPES); } cRecorder::~cRecorder() diff -u vdr-1.4.0/recorder.h vdr-1.4.0-ts/recorder.h --- vdr-1.4.0/recorder.h 2005-08-13 07:31:18.000000000 -0400 +++ vdr-1.4.0-ts/recorder.h 2006-12-16 23:49:50.000000000 -0500 @@ -28,7 +28,7 @@ virtual void Receive(uchar *Data, int Length); virtual void Action(void); public: - cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids); + cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, bool RecordPES); // Creates a new recorder that requires conditional access Ca, has // the given Priority and will record the given PIDs into the file FileName. virtual ~cRecorder(); diff -u vdr-1.4.0/recording.c vdr-1.4.0-ts/recording.c --- vdr-1.4.0/recording.c 2006-04-29 09:22:20.000000000 -0400 +++ vdr-1.4.0-ts/recording.c 2006-12-17 00:41:43.000000000 -0500 @@ -838,6 +838,45 @@ resume = RESUME_NOT_INITIALIZED; } +#define PIDSFILESUFFIX "/pids.vdr" + +void cRecording::createPidFile(const char* FileName, int* pids) +{ + if (FileName) { + char* fn = NULL; + fn = MALLOC(char, strlen(FileName) + strlen(PIDSFILESUFFIX) + 1); + if (fn) { + strcpy(fn, FileName); + char *pFileExt = fn + strlen(fn); + strcpy(pFileExt, PIDSFILESUFFIX); + FILE *f = fopen(fn, "w"); + if (f) { + fprintf(f, "%d:%d:%d", pids[0], pids[1], pids[2]); + fclose(f); + } + } + free(fn); + } +} + +void cRecording::readPidFile(const char* FileName, int* pids) +{ + if (FileName) { + char* fn = NULL; + fn = MALLOC(char, strlen(FileName) + strlen(PIDSFILESUFFIX) + 1); + if (fn) { + strcpy(fn, FileName); + char *pFileExt = fn + strlen(fn); + strcpy(pFileExt, PIDSFILESUFFIX); + FILE *f = fopen(fn, "r"); + if (f) + fscanf(f, "%d:%d:%d", pids, pids+1, pids+2); + fclose (f); + } + free(fn); + } +} + // --- cRecordings ----------------------------------------------------------- cRecordings Recordings; @@ -1383,11 +1422,12 @@ #include "videodir.h" #define MAXFILESPERRECORDING 255 -#define RECORDFILESUFFIX "/%03d.vdr" +#define RECORDFILESUFFIX "/%03d%s" #define RECORDFILESUFFIXLEN 20 // some additional bytes for safety... -cFileName::cFileName(const char *FileName, bool Record, bool Blocking) +cFileName::cFileName(const char *FileName, bool Record, bool Blocking, bool RecordPES) { + recordPES = RecordPES; file = NULL; fileNumber = 0; record = Record; @@ -1448,7 +1488,19 @@ Close(); if (0 < Number && Number <= MAXFILESPERRECORDING) { fileNumber = Number; - sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber); + + if (record) { + if (recordPES) + sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber, ".vdr"); + else + sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber, TSRECEXT); + } + else { // playing + sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber, ".vdr"); // try vdr extension first + if (access(fileName, F_OK) != 0) + sprintf(pFileNumber, RECORDFILESUFFIX, fileNumber, TSRECEXT); + } + if (record) { if (access(fileName, F_OK) == 0) { // files exists, check if it has non-zero size diff -u vdr-1.4.0/recording.h vdr-1.4.0-ts/recording.h --- vdr-1.4.0/recording.h 2006-04-09 09:47:11.000000000 -0400 +++ vdr-1.4.0-ts/recording.h 2006-12-17 00:41:47.000000000 -0500 @@ -98,6 +98,8 @@ bool Remove(void); // Actually removes the file from the disk // Returns false in case of error + static void createPidFile(const char* fileName, int* pids); + static void readPidFile(const char* fileName, int* pids); }; class cRecordings : public cList, public cThread { @@ -213,6 +215,8 @@ bool IsStillRecording(void); }; +#define TSRECEXT ".ts" + class cFileName { private: cUnbufferedFile *file; @@ -220,8 +224,9 @@ char *fileName, *pFileNumber; bool record; bool blocking; + bool recordPES; public: - cFileName(const char *FileName, bool Record, bool Blocking = false); + cFileName(const char *FileName, bool Record, bool Blocking = false, bool RecordPES = true); ~cFileName(); const char *Name(void) { return fileName; } int Number(void) { return fileNumber; } diff -u vdr-1.4.0/remux.c vdr-1.4.0-ts/remux.c --- vdr-1.4.0/remux.c 2006-04-17 08:48:12.000000000 -0400 +++ vdr-1.4.0-ts/remux.c 2006-12-17 01:04:35.000000000 -0500 @@ -1849,11 +1849,81 @@ instant_repack(Buf + 4 + off, TS_SIZE - 4 - off); } -// --- cRemux ---------------------------------------------------------------- +// --- cRemux ------------------------------------------------------------------- #define RESULTBUFFERSIZE KILOBYTE(256) -cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) +cRemux::~cRemux() +{ + delete resultBuffer; +} + +void cRemux::Del(int Count) +{ + resultBuffer->Del(Count); +} + +// --- cTSRemux ----------------------------------------------------------------- + +cTSRemux::cTSRemux(void) +{ + resultBuffer = new cRingBufferLinear(MEGABYTE(2), TS_SIZE * 2, true, "TSRemux Result"); + resultBuffer->SetTimeouts(0, 100); +} + +int cTSRemux::Put(const uchar *Data, int Count) +{ + int used = 0; + + while (Count > TS_SIZE) { + if (Data[0] == TS_SYNC_BYTE && Data[TS_SIZE] == TS_SYNC_BYTE) + break; + Data++; + Count--; + used++; + } + if (used) + esyslog("ERROR: skipped %d byte to sync on TS packet", used); + + for (int i = 0; i < Count; i += TS_SIZE) { + if (Count - i < TS_SIZE) + break; + if (Data[i] != TS_SYNC_BYTE) + break; + if (resultBuffer->Free() < TS_SIZE) + break; + + uchar *d = (uchar*) Data; + d[i+3] = (d[i+3] & 0x3F); // Remove scrambling control bits + + int n = resultBuffer->Put(Data + i, TS_SIZE); + if (n != TS_SIZE) break; + + used += TS_SIZE; + } + + return used; +} + +uchar *cTSRemux::Get(int &Count, uchar *PictureType) +{ + //if (PictureType) + // *PictureType = I_FRAME; // Should we define a new pt? + // return resultBuffer->Get(Count); + + uchar* data = resultBuffer->Get(Count); + if (data && PictureType) + if (Count > TS_SIZE && data[0] == TS_SYNC_BYTE && data[TS_SIZE] == TS_SYNC_BYTE) + *PictureType = I_FRAME; + else + *PictureType = NO_PICTURE; + + return data; +} + +// --- cPESRemux ---------------------------------------------------------------- + +cPESRemux::cPESRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) { exitOnFailure = ExitOnFailure; isRadio = VPid == 0 || VPid == 1 || VPid == 0x1FFF; @@ -1897,14 +1967,13 @@ */ } -cRemux::~cRemux() +cPESRemux::~cPESRemux() { for (int t = 0; t < numTracks; t++) delete ts2pes[t]; - delete resultBuffer; } -int cRemux::GetPid(const uchar *Data) +int cPESRemux::GetPid(const uchar *Data) { return (((uint16_t)Data[0] & PID_MASK_HI) << 8) | (Data[1] & 0xFF); } @@ -1966,9 +2035,8 @@ return -1; } -#define TS_SYNC_BYTE 0x47 -int cRemux::Put(const uchar *Data, int Count) +int cPESRemux::Put(const uchar *Data, int Count) { int used = 0; @@ -2020,7 +2088,7 @@ return used; } -uchar *cRemux::Get(int &Count, uchar *PictureType) +uchar *cPESRemux::Get(int &Count, uchar *PictureType) { // Remove any previously skipped data from the result buffer: @@ -2108,12 +2176,7 @@ return resultData; } -void cRemux::Del(int Count) -{ - resultBuffer->Del(Count); -} - -void cRemux::Clear(void) +void cPESRemux::Clear(void) { for (int t = 0; t < numTracks; t++) ts2pes[t]->Clear(); diff -u vdr-1.4.0/remux.h vdr-1.4.0-ts/remux.h --- vdr-1.4.0/remux.h 2006-03-25 07:27:30.000000000 -0500 +++ vdr-1.4.0-ts/remux.h 2006-11-17 23:23:09.000000000 -0500 @@ -32,9 +32,38 @@ #define MAXTRACKS 64 +#define TS_SYNC_BYTE 0x47 + class cTS2PES; class cRemux { +protected: + cRingBufferLinear *resultBuffer; +public: + virtual ~cRemux(); + virtual void Del(int Count); + + void SetTimeouts(int PutTimeout, int GetTimeout) { resultBuffer->SetTimeouts(PutTimeout, GetTimeout); } + virtual int Put(const uchar *Data, int Count) = 0; + virtual uchar *Get(int &Count, uchar *PictureType = NULL) = 0; + virtual void Clear(void) = 0; + static void SetBrokenLink(uchar *Data, int Length); + static int GetPacketLength(const uchar *Data, int Count, int Offset); + static int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); +}; + +class cTSRemux : public cRemux { +public: + cTSRemux(void); + int Put(const uchar *Data, int Count); + uchar *Get(int &Count, uchar *PictureType = NULL); + void Clear(void) { resultBuffer->Clear(); } + //void SetBrokenLink(uchar *Data, int Length) {} + //int GetPacketLength(const uchar *Data, int Count, int Offset) { return -1; } + //int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType) { return -1; } +}; + +class cPESRemux : public cRemux { private: bool exitOnFailure; bool isRadio; @@ -43,18 +72,18 @@ int skipped; cTS2PES *ts2pes[MAXTRACKS]; int numTracks; - cRingBufferLinear *resultBuffer; + int resultSkipped; int GetPid(const uchar *Data); public: - cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false); + cPESRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false); ///< Creates a new remuxer for the given PIDs. VPid is the video PID, while ///< APids, DPids and SPids are pointers to zero terminated lists of audio, ///< dolby and subtitle PIDs (the pointers may be NULL if there is no such ///< PID). If ExitOnFailure is true, the remuxer will initiate an "emergency ///< exit" in case of problems with the data stream. - ~cRemux(); - void SetTimeouts(int PutTimeout, int GetTimeout) { resultBuffer->SetTimeouts(PutTimeout, GetTimeout); } + ~cPESRemux(); + //void SetTimeouts(int PutTimeout, int GetTimeout) { resultBuffer->SetTimeouts(PutTimeout, GetTimeout); } ///< By default cRemux assumes that Put() and Get() are called from different ///< threads, and uses a timeout in the Get() function in case there is no ///< data available. SetTimeouts() can be used to modify these timeouts. @@ -68,7 +97,7 @@ ///< \return Count contains the number of bytes the result points to, and ///< PictureType (if not NULL) will contain one of NO_PICTURE, I_FRAME, P_FRAME ///< or B_FRAME. - void Del(int Count); + //void Del(int Count); ///< Deletes Count bytes from the remuxer. Count must be the number returned ///< from a previous call to Get(). Several calls to Del() with fractions of ///< a previously returned Count may be made, but the total sum of all Count @@ -76,9 +105,9 @@ void Clear(void); ///< Clears the remuxer of all data it might still contain, keeping the PID ///< settings as they are. - static void SetBrokenLink(uchar *Data, int Length); - static int GetPacketLength(const uchar *Data, int Count, int Offset); - static int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); + //void SetBrokenLink(uchar *Data, int Length); + //int GetPacketLength(const uchar *Data, int Count, int Offset); + //int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); }; #endif // __REMUX_H diff -u vdr-1.4.0/timers.c vdr-1.4.0-ts/timers.c --- vdr-1.4.0/timers.c 2006-04-21 11:12:49.000000000 -0400 +++ vdr-1.4.0-ts/timers.c 2006-12-17 00:25:53.000000000 -0500 @@ -47,6 +47,7 @@ event = NULL; if (Instant && channel) snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name()); + recordPES = Setup.RecordPES; } cTimer::cTimer(const cEvent *Event) @@ -81,6 +82,7 @@ strn0cpy(file, Event->Title(), sizeof(file)); aux = NULL; event = NULL; // let SetEvent() be called to get a log message + recordPES = Setup.RecordPES; } cTimer::~cTimer() @@ -113,7 +115,7 @@ { char *buffer; strreplace(file, ':', '|'); - asprintf(&buffer, "%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays), start, stop, priority, lifetime, file, aux ? aux : ""); + asprintf(&buffer, "%u:%s:%s:%04d:%04d:%d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays), start, stop, priority, lifetime, recordPES, file, aux ? aux : ""); strreplace(file, '|', ':'); return cString(buffer, true); } @@ -246,7 +248,7 @@ s = s2; } bool result = false; - if (8 <= sscanf(s, "%u :%a[^:]:%a[^:]:%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &flags, &channelbuffer, &daybuffer, &start, &stop, &priority, &lifetime, &filebuffer, &aux)) { + if (9 <= sscanf(s, "%u :%a[^:]:%a[^:]:%d :%d :%d :%d :%d :%a[^:\n]:%a[^\n]", &flags, &channelbuffer, &daybuffer, &start, &stop, &priority, &lifetime, &recordPES, &filebuffer, &aux)) { ClrFlags(tfRecording); if (aux && !*skipspace(aux)) { free(aux); diff -u vdr-1.4.0/timers.h vdr-1.4.0-ts/timers.h --- vdr-1.4.0/timers.h 2006-04-08 08:41:44.000000000 -0400 +++ vdr-1.4.0-ts/timers.h 2006-12-17 00:26:55.000000000 -0500 @@ -41,6 +41,7 @@ char file[MaxFileName]; char *aux; const cEvent *event; + int recordPES; public: cTimer(bool Instant = false, bool Pause = false, cChannel *Channel = NULL); cTimer(const cEvent *Event); @@ -94,6 +95,7 @@ static int TimeToInt(int t); static bool ParseDay(const char *s, time_t &Day, int &WeekDays); static cString PrintDay(time_t Day, int WeekDays); + bool RecordPES(void) { return recordPES; } }; class cTimers : public cConfig { diff -u vdr-1.4.0/transfer.c vdr-1.4.0-ts/transfer.c --- vdr-1.4.0/transfer.c 2006-01-29 12:24:39.000000000 -0500 +++ vdr-1.4.0-ts/transfer.c 2006-11-17 23:19:58.000000000 -0500 @@ -19,7 +19,7 @@ ,cThread("transfer") { ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); - remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); + remux = new cPESRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); } cTransfer::~cTransfer()