summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FORMATS9
-rw-r--r--HISTORY17
-rw-r--r--MANUAL2
-rw-r--r--dvbapi.c149
-rw-r--r--dvbapi.h17
-rw-r--r--menu.c8
-rw-r--r--remux.c49
-rw-r--r--remux.h21
8 files changed, 174 insertions, 98 deletions
diff --git a/FORMATS b/FORMATS
index 3a70871e..0f047352 100644
--- a/FORMATS
+++ b/FORMATS
@@ -128,3 +128,12 @@ Video Disk Recorder File Formats
- marks must have a frame number, and that frame MUST be an I-frame (this
means that only marks generated by VDR itself can be used, since they
will always be guaranteed to mark I-frames).
+
+* 001.vdr ... 255.vdr
+
+ These are the actual recorded MPEG data files. In order to keep the size of
+ an individual file below a given limit, a recording is split into several
+ files. The contents of these files is "Packetized Elementary Stream" (PES)
+ and contains ES packets with ids 0xE0 for video, 0xC0 for audio 1 and 0xC1
+ for audio 2 (if available).
+
diff --git a/HISTORY b/HISTORY
index 855b3011..3617b25d 100644
--- a/HISTORY
+++ b/HISTORY
@@ -510,3 +510,20 @@ Video Disk Recorder Revision History
- Increased timeout until reporting "broken video data stream" when recording.
- Modified method of turning off PIDs when switching channel.
+- Increased amount of non-useful data received by cRemux before assuming the
+ recording will fail.
+- If there are two audio PIDs defined for a channel, both audio tracks will
+ now be recorded and can be selectively replayed later. See the FORMATS file
+ for details on how these different audio tracks are stored in the recorded
+ files. In order for this to work properly you need to make sure that the
+ StartHWFilter() function in the driver's 'dvb.c' has
+
+ u16 mode=0x0320;
+
+ instead of the default
+
+ u16 mode=0x0820;
+
+ This will create packets for the second audio track that are small enough
+ to multiplex smoothly with the video data.
+
diff --git a/MANUAL b/MANUAL
index 9a72c512..06686f14 100644
--- a/MANUAL
+++ b/MANUAL
@@ -122,6 +122,8 @@ Video Disk Recorder User's Manual
to toggle between these. There can be two different audio PIDs per channel,
assuming that typically a channel broadcasts a country specific language
plus the movie's original soundtrack.
+ Recordings made form such channels will contain both audio tracks, and when
+ replaying the desired audio track can be selected the same way.
* Switching through channel groups
diff --git a/dvbapi.c b/dvbapi.c
index a9e52b8f..325d095e 100644
--- a/dvbapi.c
+++ b/dvbapi.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbapi.c 1.72 2001/06/14 08:19:43 kls Exp $
+ * $Id: dvbapi.c 1.73 2001/06/14 15:10:16 kls Exp $
*/
#include "dvbapi.h"
@@ -451,14 +451,14 @@ protected:
virtual void Input(void);
virtual void Output(void);
public:
- cRecordBuffer(cDvbApi *DvbApi, const char *FileName, dvb_pid_t VPid, dvb_pid_t APid);
+ cRecordBuffer(cDvbApi *DvbApi, const char *FileName, dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2);
virtual ~cRecordBuffer();
};
-cRecordBuffer::cRecordBuffer(cDvbApi *DvbApi, const char *FileName, dvb_pid_t VPid, dvb_pid_t APid)
+cRecordBuffer::cRecordBuffer(cDvbApi *DvbApi, const char *FileName, dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2)
:cRingBuffer(VIDEOBUFSIZE, true)
,fileName(FileName, true)
-,remux(VPid, APid, true)
+,remux(VPid, APid1, APid2, true)
{
dvbApi = DvbApi;
index = NULL;
@@ -608,12 +608,14 @@ private:
bool eof;
int blockInput, blockOutput;
bool paused, fastForward, fastRewind;
- int lastIndex, stillIndex;
+ int lastIndex, stillIndex, playIndex;
+ bool canToggleAudioTrack;
+ uchar audioTrack;
bool NextFile(uchar FileNumber = 0, int FileOffset = -1);
void Clear(bool Block = false);
void Close(void);
int ReadFrame(uchar *b, int Length, int Max);
- void StripAudioPackets(uchar *b, int Length);
+ void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00);
void DisplayFrame(uchar *b, int Length);
int Resume(void);
bool Save(void);
@@ -631,6 +633,8 @@ public:
void SkipSeconds(int Seconds);
void Goto(int Position, bool Still = false);
void GetIndex(int &Current, int &Total, bool SnapToIFrame = false);
+ bool CanToggleAudioTrack(void) { return canToggleAudioTrack; }
+ void ToggleAudioTrack(void);
};
cReplayBuffer::cReplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, const char *FileName)
@@ -646,7 +650,9 @@ cReplayBuffer::cReplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, const
eof = false;
blockInput = blockOutput = false;
paused = fastForward = fastRewind = false;
- lastIndex = stillIndex = -1;
+ lastIndex = stillIndex = playIndex = -1;
+ canToggleAudioTrack = false;
+ audioTrack = 0xC0;
if (!fileName.Name())
return;
// Create the index file:
@@ -701,12 +707,19 @@ void cReplayBuffer::Input(void)
continue;
}
lastIndex = Index;
+ playIndex = -1;
r = ReadFrame(b, Length, sizeof(b));
- StripAudioPackets(b, Length);
+ StripAudioPackets(b, r);
}
else {
lastIndex = -1;
- r = read(replayFile, b, sizeof(b));
+ playIndex = (playIndex >= 0) ? playIndex + 1 : index->Get(fileName.Number(), fileOffset);
+ uchar FileNumber;
+ int FileOffset, Length;
+ if (!(index->Get(playIndex, &FileNumber, &FileOffset, NULL, &Length) && NextFile(FileNumber, FileOffset)))
+ break;
+ r = ReadFrame(b, Length, sizeof(b));
+ StripAudioPackets(b, r, audioTrack);
}
if (r > 0) {
uchar *p = b;
@@ -778,17 +791,20 @@ int cReplayBuffer::ReadFrame(uchar *b, int Length, int Max)
return -1;
}
-void cReplayBuffer::StripAudioPackets(uchar *b, int Length)
+void cReplayBuffer::StripAudioPackets(uchar *b, int Length, uchar Except)
{
for (int i = 0; i < Length - 6; i++) {
if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
- switch (b[i + 3]) {
+ uchar c = b[i + 3];
+ switch (c) {
case 0xC0 ... 0xDF: // audio
- {
- int n = b[i + 4] * 256 + b[i + 5];
- for (int j = i; j < Length && n--; j++)
- b[j] = 0x00;
- }
+ if (c == 0xC1)
+ canToggleAudioTrack = true;
+ if (!Except || c != Except) {
+ int n = b[i + 4] * 256 + b[i + 5];
+ for (int j = i; j < Length && n--; j++)
+ b[j] = 0x00;
+ }
break;
case 0xE0 ... 0xEF: // video
i += b[i + 4] * 256 + b[i + 5];
@@ -816,6 +832,7 @@ void cReplayBuffer::Clear(bool Block)
usleep(1);
Lock();
cRingBuffer::Clear();
+ playIndex = -1;
CHECK(ioctl(videoDev, VIDEO_FREEZE));
CHECK(ioctl(videoDev, VIDEO_CLEAR_BUFFER));
CHECK(ioctl(audioDev, AUDIO_CLEAR_BUFFER));
@@ -969,6 +986,7 @@ void cReplayBuffer::Goto(int Index, bool Still)
Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length);
if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) {
stillIndex = Index;
+ playIndex = -1;
uchar b[MAXFRAMESIZE];
int r = ReadFrame(b, Length, sizeof(b));
if (r > 0)
@@ -977,7 +995,7 @@ void cReplayBuffer::Goto(int Index, bool Still)
paused = true;
}
else
- stillIndex = -1;
+ stillIndex = playIndex = -1;
Clear(false);
}
}
@@ -1015,6 +1033,14 @@ bool cReplayBuffer::NextFile(uchar FileNumber, int FileOffset)
return replayFile >= 0;
}
+void cReplayBuffer::ToggleAudioTrack(void)
+{
+ if (CanToggleAudioTrack()) {
+ audioTrack = (audioTrack == 0xC0) ? 0xC1 : 0xC0;
+ Clear();
+ }
+}
+
// --- cTransferBuffer -------------------------------------------------------
class cTransferBuffer : public cRingBuffer {
@@ -1329,33 +1355,34 @@ cDvbApi::cDvbApi(int n)
// Devices that are only present on DVB-C or DVB-S cards:
- fd_qamfe = OstOpen(DEV_OST_QAMFE, n, O_RDWR);
- fd_qpskfe = OstOpen(DEV_OST_QPSKFE, n, O_RDWR);
- fd_sec = OstOpen(DEV_OST_SEC, n, O_RDWR);
+ fd_qamfe = OstOpen(DEV_OST_QAMFE, n, O_RDWR);
+ fd_qpskfe = OstOpen(DEV_OST_QPSKFE, n, O_RDWR);
+ fd_sec = OstOpen(DEV_OST_SEC, n, O_RDWR);
// Devices that all DVB cards must have:
- fd_demuxv = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
- fd_demuxa = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
- fd_demuxt = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
+ fd_demuxv = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
+ fd_demuxa1 = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
+ fd_demuxa2 = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
+ fd_demuxt = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true);
// Devices not present on "budget" cards:
- fd_osd = OstOpen(DEV_OST_OSD, n, O_RDWR);
- fd_video = OstOpen(DEV_OST_VIDEO, n, O_RDWR | O_NONBLOCK);
- fd_audio = OstOpen(DEV_OST_AUDIO, n, O_RDWR | O_NONBLOCK);
+ fd_osd = OstOpen(DEV_OST_OSD, n, O_RDWR);
+ fd_video = OstOpen(DEV_OST_VIDEO, n, O_RDWR | O_NONBLOCK);
+ fd_audio = OstOpen(DEV_OST_AUDIO, n, O_RDWR | O_NONBLOCK);
// Devices that may not be available, and are not necessary for normal operation:
- videoDev = OstOpen(DEV_VIDEO, n, O_RDWR);
+ videoDev = OstOpen(DEV_VIDEO, n, O_RDWR);
// Devices that will be dynamically opened and closed when necessary:
- fd_dvr = -1;
+ fd_dvr = -1;
// We only check the devices that must be present - the others will be checked before accessing them:
- if (((fd_qpskfe >= 0 && fd_sec >= 0) || fd_qamfe >= 0) && fd_demuxv >= 0 && fd_demuxa >= 0 && fd_demuxt >= 0) {
+ if (((fd_qpskfe >= 0 && fd_sec >= 0) || fd_qamfe >= 0) && fd_demuxv >= 0 && fd_demuxa1 >= 0 && fd_demuxa2 >= 0 && fd_demuxt >= 0) {
siProcessor = new cSIProcessor(OstName(DEV_OST_DEMUX, n));
if (!dvbApi[0]) // only the first one shall set the system time
siProcessor->SetUseTSTime(Setup.SetSystemTime);
@@ -2026,7 +2053,8 @@ bool cDvbApi::SetPid(int fd, dmxPesType_t PesType, dvb_pid_t Pid, dmxOutput_t Ou
bool cDvbApi::SetPids(bool ForRecording)
{
return SetVpid(vPid, ForRecording ? DMX_OUT_TS_TAP : DMX_OUT_DECODER) &&
- SetApid(aPid1, ForRecording ? DMX_OUT_TS_TAP : DMX_OUT_DECODER);
+ SetApid1(aPid1, ForRecording ? DMX_OUT_TS_TAP : DMX_OUT_DECODER) &&
+ SetApid2(ForRecording ? aPid2 : 0, DMX_OUT_TS_TAP);
}
bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Tpid, int Ca, int Pnr)
@@ -2048,9 +2076,10 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
// Turn off current PIDs:
- SetVpid(0, DMX_OUT_DECODER);
- SetApid(0, DMX_OUT_DECODER);
- SetTpid(0, DMX_OUT_DECODER);
+ SetVpid( 0, DMX_OUT_DECODER);
+ SetApid1(0, DMX_OUT_DECODER);
+ SetApid2(0, DMX_OUT_DECODER);
+ SetTpid( 0, DMX_OUT_DECODER);
bool ChannelSynced = false;
@@ -2110,7 +2139,7 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
esyslog(LOG_ERR, "ERROR %d in qpsk get event", res);
}
else
- fprintf(stderr, "ERROR: timeout while tuning\n");
+ esyslog(LOG_ERR, "ERROR: timeout while tuning\n");
}
else if (fd_qamfe >= 0) { // DVB-C
@@ -2137,7 +2166,7 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
esyslog(LOG_ERR, "ERROR %d in qam get event", res);
}
else
- fprintf(stderr, "ERROR: timeout while tuning\n");
+ esyslog(LOG_ERR, "ERROR: timeout while tuning\n");
}
else {
esyslog(LOG_ERR, "ERROR: attempt to set channel without DVB-S or DVB-C device");
@@ -2187,28 +2216,6 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization,
return true;
}
-bool cDvbApi::CanToggleAudioPid(void)
-{
- return aPid1 && aPid2 && aPid1 != aPid2;
-}
-
-bool cDvbApi::ToggleAudioPid(void)
-{
- if (CanToggleAudioPid()) {
- int a = aPid2;
- aPid2 = aPid1;
- aPid1 = a;
- if (transferringFromDvbApi)
- return transferringFromDvbApi->ToggleAudioPid();
- else {
- if (transferBuffer)
- transferBuffer->SetAudioPid(aPid1);
- return SetPids(transferBuffer != NULL);
- }
- }
- return false;
-}
-
bool cDvbApi::Transferring(void)
{
return transferBuffer;
@@ -2278,7 +2285,7 @@ bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority)
// Create recording buffer:
- recordBuffer = new cRecordBuffer(this, FileName, vPid, aPid1);
+ recordBuffer = new cRecordBuffer(this, FileName, vPid, aPid1, aPid2);
if (recordBuffer) {
ca = Ca;
@@ -2390,6 +2397,32 @@ void cDvbApi::Goto(int Position, bool Still)
replayBuffer->Goto(Position, Still);
}
+bool cDvbApi::CanToggleAudioTrack(void)
+{
+ return replayBuffer ? replayBuffer->CanToggleAudioTrack() : (aPid1 && aPid2 && aPid1 != aPid2);
+}
+
+bool cDvbApi::ToggleAudioTrack(void)
+{
+ if (replayBuffer) {
+ replayBuffer->ToggleAudioTrack();
+ return true;
+ }
+ else {
+ int a = aPid2;
+ aPid2 = aPid1;
+ aPid1 = a;
+ if (transferringFromDvbApi)
+ return transferringFromDvbApi->ToggleAudioTrack();
+ else {
+ if (transferBuffer)
+ transferBuffer->SetAudioPid(aPid1);
+ return SetPids(transferBuffer != NULL);
+ }
+ }
+ return false;
+}
+
// --- cEITScanner -----------------------------------------------------------
cEITScanner::cEITScanner(void)
diff --git a/dvbapi.h b/dvbapi.h
index e9b59cdc..02211eab 100644
--- a/dvbapi.h
+++ b/dvbapi.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbapi.h 1.37 2001/06/03 11:51:30 kls Exp $
+ * $Id: dvbapi.h 1.38 2001/06/14 14:54:25 kls Exp $
*/
#ifndef __DVBAPI_H
@@ -66,11 +66,12 @@ class cDvbApi {
friend class cTransferBuffer;
private:
int videoDev;
- int fd_osd, fd_qpskfe, fd_qamfe, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa, fd_demuxv, fd_demuxt;
+ int fd_osd, fd_qpskfe, fd_qamfe, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa1, fd_demuxa2, fd_demuxv, fd_demuxt;
int vPid, aPid1, aPid2;
bool SetPid(int fd, dmxPesType_t PesType, dvb_pid_t Pid, dmxOutput_t Output);
bool SetVpid(int Vpid, dmxOutput_t Output) { return SetPid(fd_demuxv, DMX_PES_VIDEO, Vpid, Output); }
- bool SetApid(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa, DMX_PES_AUDIO, Apid, Output); }
+ bool SetApid1(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa1, DMX_PES_AUDIO, Apid, Output); }
+ bool SetApid2(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa2, DMX_PES_OTHER, Apid, Output); }
bool SetTpid(int Tpid, dmxOutput_t Output) { return SetPid(fd_demuxt, DMX_PES_TELETEXT, Tpid, Output); }
bool SetPids(bool ForRecording);
cDvbApi(int n);
@@ -180,8 +181,6 @@ public:
bool SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Tpid, int Ca, int Pnr);
static int CurrentChannel(void) { return PrimaryDvbApi ? PrimaryDvbApi->currentChannel : 0; }
int Channel(void) { return currentChannel; }
- bool CanToggleAudioPid(void);
- bool ToggleAudioPid(void);
// Transfer facilities
@@ -262,6 +261,14 @@ public:
void Goto(int Index, bool Still = false);
// Positions to the given index and displays that frame as a still picture
// if Still is true.
+
+ // Audio track facilities
+
+ bool CanToggleAudioTrack(void);
+ // Returns true if we are currently replaying and this recording has two
+ // audio tracks, or if the current channel has two audio PIDs.
+ bool ToggleAudioTrack(void);
+ // Toggles the audio track if possible.
};
class cEITScanner {
diff --git a/menu.c b/menu.c
index d45ac8dd..78539237 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.72 2001/06/02 13:51:28 kls Exp $
+ * $Id: menu.c 1.73 2001/06/14 14:55:16 kls Exp $
*/
#include "menu.h"
@@ -1726,7 +1726,7 @@ cMenuMain::cMenuMain(bool Replaying)
}
if (cVideoCutter::Active())
Add(new cOsdItem(tr(" Cancel editing"), osCancelEdit));
- SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioPid() ? tr("Language") : NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
+ SetHelp(tr("Record"), cDvbApi::PrimaryDvbApi->CanToggleAudioTrack() ? tr("Language") : NULL, NULL, cReplayControl::LastReplayed() ? tr("Resume") : NULL);
Display();
lastActivity = time(NULL);
SetHasHotkeys();
@@ -1761,9 +1761,9 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
case kRed: if (!HasSubMenu())
state = osRecord;
break;
- case kGreen: if (cDvbApi::PrimaryDvbApi->CanToggleAudioPid()) {
+ case kGreen: if (cDvbApi::PrimaryDvbApi->CanToggleAudioTrack()) {
Interface->Clear();
- cDvbApi::PrimaryDvbApi->ToggleAudioPid();
+ cDvbApi::PrimaryDvbApi->ToggleAudioTrack();
state = osEnd;
}
break;
diff --git a/remux.c b/remux.c
index 1fdb579d..51bd2a4a 100644
--- a/remux.c
+++ b/remux.c
@@ -8,7 +8,7 @@
* the Linux DVB driver's 'tuxplayer' example and were rewritten to suit
* VDR's needs.
*
- * $Id: remux.c 1.3 2001/06/02 15:39:16 kls Exp $
+ * $Id: remux.c 1.4 2001/06/14 15:30:09 kls Exp $
*/
/* The calling interface of the 'cRemux::Process()' function is defined
@@ -107,6 +107,11 @@
#define IPACKS 2048
+// Start codes:
+#define SC_PICTURE 0x00 // "picture header"
+
+#define MAXNONUSEFULDATA (10*1024*1024)
+
class cTS2PES {
private:
int size;
@@ -114,6 +119,7 @@ private:
int count;
uint8_t *buf;
uint8_t cid;
+ uint8_t audioCid;
int plength;
uint8_t plen[2];
uint8_t flag1;
@@ -132,7 +138,7 @@ private:
void write_ipack(const uint8_t *Data, int Count);
void instant_repack(const uint8_t *Buf, int Count);
public:
- cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size);
+ cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t AudioCid = 0x00);
~cTS2PES();
void ts_to_pes(const uint8_t *Buf); // don't need count (=188)
void Clear(void);
@@ -140,11 +146,12 @@ public:
uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 };
-cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size)
+cTS2PES::cTS2PES(uint8_t *ResultBuffer, int *ResultCount, int Size, uint8_t AudioCid)
{
resultBuffer = ResultBuffer;
resultCount = ResultCount;
size = Size;
+ audioCid = AudioCid;
if (!(buf = new uint8_t[size]))
esyslog(LOG_ERR, "Not enough memory for ts_transform");
@@ -164,7 +171,10 @@ void cTS2PES::Clear(void)
void cTS2PES::store(uint8_t *Data, int Count)
{
- //XXX overflow check???
+ if (*resultCount + Count > RESULTBUFFERSIZE) {
+ esyslog(LOG_ERR, "ERROR: result buffer overflow (%d + %d > %d)", *resultCount, Count, RESULTBUFFERSIZE);
+ Count = RESULTBUFFERSIZE - *resultCount;
+ }
memcpy(resultBuffer + *resultCount, Data, Count);
*resultCount += Count;
}
@@ -188,7 +198,7 @@ void cTS2PES::send_ipack(void)
{
if (count < 10)
return;
- buf[3] = cid;
+ buf[3] = (AUDIO_STREAM_S <= cid && cid <= AUDIO_STREAM_E && audioCid) ? audioCid : cid;
buf[4] = (uint8_t)(((count - 6) & 0xFF00) >> 8);
buf[5] = (uint8_t)((count - 6) & 0x00FF);
store(buf, count);
@@ -409,22 +419,25 @@ void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188)
// --- cRemux ----------------------------------------------------------------
-cRemux::cRemux(dvb_pid_t VPid, dvb_pid_t APid, bool ExitOnFailure)
+cRemux::cRemux(dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2, bool ExitOnFailure)
{
vPid = VPid;
- aPid = APid;
+ aPid1 = APid1;
+ aPid2 = APid2;
exitOnFailure = ExitOnFailure;
synced = false;
skipped = 0;
resultCount = resultDelivered = 0;
- vTS2PES = new cTS2PES(resultBuffer, &resultCount, IPACKS);
- aTS2PES = new cTS2PES(resultBuffer, &resultCount, IPACKS);
+ vTS2PES = new cTS2PES(resultBuffer, &resultCount, IPACKS);
+ aTS2PES1 = new cTS2PES(resultBuffer, &resultCount, IPACKS, 0xC0);
+ aTS2PES2 = aPid2 ? new cTS2PES(resultBuffer, &resultCount, IPACKS, 0xC1) : NULL;
}
cRemux::~cRemux()
{
delete vTS2PES;
- delete aTS2PES;
+ delete aTS2PES1;
+ delete aTS2PES2;
}
int cRemux::GetPid(const uchar *Data)
@@ -463,9 +476,9 @@ int cRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &Pic
void cRemux::SetAudioPid(int APid)
{
- aPid = APid;
+ aPid1 = APid;
vTS2PES->Clear();
- aTS2PES->Clear();
+ aTS2PES1->Clear();
resultCount = resultDelivered = 0;
}
@@ -501,8 +514,10 @@ XXX*/
if (Data[i + 3] & 0x10) { // got payload
if (pid == vPid)
vTS2PES->ts_to_pes(Data + i);
- else if (pid == aPid)
- aTS2PES->ts_to_pes(Data + i);
+ else if (pid == aPid1)
+ aTS2PES1->ts_to_pes(Data + i);
+ else if (pid == aPid2 && aTS2PES2)
+ aTS2PES2->ts_to_pes(Data + i);
}
used += TS_SIZE;
if (resultCount > (int)sizeof(resultBuffer) / 2)
@@ -520,7 +535,7 @@ XXX*/
// Check if we're getting anywhere here:
if (!synced && skipped >= 0) {
- if (skipped > 1024*1024) {
+ if (skipped > MAXNONUSEFULDATA) {
esyslog(LOG_ERR, "ERROR: no useful data seen within %d byte of video stream", skipped);
skipped = -1;
if (exitOnFailure)
@@ -538,7 +553,7 @@ XXX*/
for (int i = 0; i < resultCount; i++) {
if (resultBuffer[i] == 0 && resultBuffer[i + 1] == 0 && resultBuffer[i + 2] == 1) {
switch (resultBuffer[i + 3]) {
- case SC_VIDEO:
+ case VIDEO_STREAM_S ... VIDEO_STREAM_E:
{
uchar pt = NO_PICTURE;
int l = ScanVideoPacket(resultBuffer, resultCount, i, pt);
@@ -572,7 +587,7 @@ XXX*/
}
}
break;
- case SC_AUDIO:
+ case AUDIO_STREAM_S ... AUDIO_STREAM_E:
{
int l = GetPacketLength(resultBuffer, resultCount, i);
if (l < 0)
diff --git a/remux.h b/remux.h
index 011dd3b6..ae19a441 100644
--- a/remux.h
+++ b/remux.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remux.h 1.3 2001/06/02 15:15:43 kls Exp $
+ * $Id: remux.h 1.4 2001/06/14 15:27:07 kls Exp $
*/
#ifndef __REMUX_H
@@ -19,18 +19,11 @@
#define P_FRAME 2
#define B_FRAME 3
-//XXX -> remux.c???
-// Start codes:
-#define SC_PICTURE 0x00 // "picture header"
-#define SC_SEQU 0xB3 // "sequence header"
-#define SC_PHEAD 0xBA // "pack header"
-#define SC_SHEAD 0xBB // "system header"
-#define SC_AUDIO 0xC0
-#define SC_VIDEO 0xE0
-
// The minimum amount of video data necessary to identify frames:
#define MINVIDEODATA (16*1024) // just a safe guess (max. size of any frame block, plus some safety)
+#define RESULTBUFFERSIZE (MINVIDEODATA * 4)
+
typedef unsigned char uchar;
class cTS2PES;
@@ -39,16 +32,16 @@ private:
bool exitOnFailure;
bool synced;
int skipped;
- dvb_pid_t vPid, aPid;
- cTS2PES *vTS2PES, *aTS2PES;
- uchar resultBuffer[MINVIDEODATA * 4];//XXX
+ dvb_pid_t vPid, aPid1, aPid2;
+ cTS2PES *vTS2PES, *aTS2PES1, *aTS2PES2;
+ uchar resultBuffer[RESULTBUFFERSIZE];
int resultCount;
int resultDelivered;
int GetPid(const uchar *Data);
int GetPacketLength(const uchar *Data, int Count, int Offset);
int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType);
public:
- cRemux(dvb_pid_t VPid, dvb_pid_t APid, bool ExitOnFailure = false);
+ cRemux(dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2 = 0, bool ExitOnFailure = false);
~cRemux();
void SetAudioPid(int APid);
const uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL);