The PCR pid is now recorded for channels where this is different from the video PID

This commit is contained in:
Klaus Schmidinger 2010-01-30 11:10:25 +01:00
parent a9543347af
commit 0889960232
14 changed files with 156 additions and 75 deletions

14
HISTORY
View File

@ -6276,7 +6276,7 @@ Video Disk Recorder Revision History
- Fixed plugin arguments corruption with glibc 2.11 on x86_64 (thanks to - Fixed plugin arguments corruption with glibc 2.11 on x86_64 (thanks to
Anssi Hannula). Anssi Hannula).
2010-01-24: Version 1.7.12 2010-01-30: Version 1.7.12
- Changed the EVCONTENTMASK_* macros to enums and changed "mask" to "group". - Changed the EVCONTENTMASK_* macros to enums and changed "mask" to "group".
- Updated the Estonian OSD texts (thanks to Arthur Konovalov). - Updated the Estonian OSD texts (thanks to Arthur Konovalov).
@ -6296,9 +6296,13 @@ Video Disk Recorder Revision History
to Matti Lehtimäki). to Matti Lehtimäki).
- Fixed determining the frame duration on channels where the PTS deltas jitter by - Fixed determining the frame duration on channels where the PTS deltas jitter by
+/-1 around 1800. +/-1 around 1800.
- The PCR pid in generated PMTs is now set to the channel's PCR pid again, which - The PCR pid in generated PMTs is now set to the channel's PCR pid again.
in most cases is the same as the video pid. For channels that use a separate
PCR pid, no TS packets are recorded from that PID (I have yet to see a case where
this actually is a problem).
- Fixed determining the frame duration on channels where the PTS deltas jitter by - Fixed determining the frame duration on channels where the PTS deltas jitter by
+/-1 around 3600. +/-1 around 3600.
- The PCR pid is now recorded for channels where this is different from the video
PID. To facilitate this, the interfaces of cTransfer, cTransferControl, cRecorder
and cReceiver have been modified, so that the PIDs are no longer given in separate
parameters, but rather the whole channel is handed down for processing. The old
constructor of cReceiver is still available, but it is recommended to plugin authors
that they switch to the new interface as soon as possible.
When replaying such a recording, the PCR packets are sent to PlayTsVideo()

View File

@ -10,3 +10,8 @@ VDR Plugin 'dvbsddevice' Revision History
- Calling the MakePrimaryDevice() function of the base class to allow - Calling the MakePrimaryDevice() function of the base class to allow
the cDevice to stop displaying subtitles. the cDevice to stop displaying subtitles.
- Added support for DVB cards with multiple fontends. - Added support for DVB cards with multiple fontends.
2010-01-30: Version 0.0.3
- The PCR pid is now recorded for channels where this is different from the
video PID.

View File

@ -3,13 +3,13 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: dvbsddevice.c 1.2 2010/01/01 15:01:01 kls Exp $ * $Id: dvbsddevice.c 1.3 2010/01/30 10:05:42 kls Exp $
*/ */
#include <vdr/plugin.h> #include <vdr/plugin.h>
#include "dvbsdffdevice.h" #include "dvbsdffdevice.h"
static const char *VERSION = "0.0.2"; static const char *VERSION = "0.0.3";
static const char *DESCRIPTION = "SD Full Featured DVB device"; static const char *DESCRIPTION = "SD Full Featured DVB device";
class cPluginDvbsddevice : public cPlugin { class cPluginDvbsddevice : public cPlugin {

View File

@ -3,7 +3,7 @@
* *
* See the README file for copyright information and how to reach the author. * See the README file for copyright information and how to reach the author.
* *
* $Id: dvbsdffdevice.c 2.25 2010/01/04 12:56:56 kls Exp $ * $Id: dvbsdffdevice.c 2.26 2010/01/30 10:05:23 kls Exp $
*/ */
#include "dvbsdffdevice.h" #include "dvbsdffdevice.h"
@ -434,7 +434,7 @@ bool cDvbSdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
} }
else if (StartTransferMode) else if (StartTransferMode)
cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), vpid, Channel->Apids(), Channel->Dpids(), Channel->Spids())); cControl::Launch(new cTransferControl(this, Channel));
return true; return true;
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: device.c 2.31 2010/01/01 15:40:35 kls Exp $ * $Id: device.c 2.32 2010/01/30 11:06:51 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -30,8 +30,8 @@ public:
}; };
cLiveSubtitle::cLiveSubtitle(int SPid) cLiveSubtitle::cLiveSubtitle(int SPid)
:cReceiver(tChannelID(), -1, SPid)
{ {
AddPid(SPid);
} }
cLiveSubtitle::~cLiveSubtitle() cLiveSubtitle::~cLiveSubtitle()
@ -676,7 +676,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
if (Device && CanReplay()) { if (Device && CanReplay()) {
cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
if (Device->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()! if (Device->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()!
cControl::Launch(new cTransferControl(Device, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); cControl::Launch(new cTransferControl(Device, Channel));
else else
Result = scrNoTransfer; Result = scrNoTransfer;
} }
@ -1364,10 +1364,10 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped); esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
return Played + Skipped; return Played + Skipped;
} }
int Pid = TsPid(Data);
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
int PayloadOffset = TsPayloadOffset(Data); int PayloadOffset = TsPayloadOffset(Data);
if (PayloadOffset < TS_SIZE) { if (PayloadOffset < TS_SIZE) {
int Pid = TsPid(Data);
if (Pid == 0) if (Pid == 0)
patPmtParser.ParsePat(Data, TS_SIZE); patPmtParser.ParsePat(Data, TS_SIZE);
else if (Pid == patPmtParser.PmtPid()) else if (Pid == patPmtParser.PmtPid())
@ -1396,6 +1396,13 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
} }
} }
} }
else if (Pid == patPmtParser.Ppid()) {
int w = PlayTsVideo(Data, TS_SIZE);
if (w < 0)
return Played ? Played : w;
if (w == 0)
break;
}
Played += TS_SIZE; Played += TS_SIZE;
Length -= TS_SIZE; Length -= TS_SIZE;
Data += TS_SIZE; Data += TS_SIZE;

4
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.c 2.12 2010/01/17 15:10:07 kls Exp $ * $Id: menu.c 2.13 2010/01/29 16:36:57 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -4055,7 +4055,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
isyslog("record %s", fileName); isyslog("record %s", fileName);
if (MakeDirs(fileName, true)) { if (MakeDirs(fileName, true)) {
const cChannel *ch = timer->Channel(); const cChannel *ch = timer->Channel();
recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids()); recorder = new cRecorder(fileName, ch, timer->Priority());
if (device->AttachReceiver(recorder)) { if (device->AttachReceiver(recorder)) {
Recording.WriteInfo(); Recording.WriteInfo();
cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true); cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: receiver.c 2.1 2010/01/01 15:38:48 kls Exp $ * $Id: receiver.c 2.2 2010/01/30 10:25:38 kls Exp $
*/ */
#include "receiver.h" #include "receiver.h"
@ -12,28 +12,26 @@
#include <stdio.h> #include <stdio.h>
#include "tools.h" #include "tools.h"
#ifdef LEGACY_CRECEIVER
cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3) cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3)
{ {
device = NULL; device = NULL;
channelID = ChannelID; channelID = ChannelID;
priority = Priority; priority = Priority;
numPids = 0; numPids = 0;
if (Pid) AddPid(Pid);
pids[numPids++] = Pid; AddPids(Pids1);
if (Pids1) { AddPids(Pids2);
while (*Pids1 && numPids < MAXRECEIVEPIDS) AddPids(Pids3);
pids[numPids++] = *Pids1++; }
} #endif
if (Pids2) {
while (*Pids2 && numPids < MAXRECEIVEPIDS) cReceiver::cReceiver(const cChannel *Channel, int Priority)
pids[numPids++] = *Pids2++; {
} device = NULL;
if (Pids3) { priority = Priority;
while (*Pids3 && numPids < MAXRECEIVEPIDS) numPids = 0;
pids[numPids++] = *Pids3++; SetPids(Channel);
}
if (numPids >= MAXRECEIVEPIDS)
dsyslog("too many PIDs in cReceiver");
} }
cReceiver::~cReceiver() cReceiver::~cReceiver()
@ -46,6 +44,49 @@ cReceiver::~cReceiver()
} }
} }
bool cReceiver::AddPid(int Pid)
{
if (Pid) {
if (numPids < MAXRECEIVEPIDS)
pids[numPids++] = Pid;
else {
dsyslog("too many PIDs in cReceiver (Pid = %d)", Pid);
return false;
}
}
return true;
}
bool cReceiver::AddPids(const int *Pids)
{
if (Pids) {
while (*Pids) {
if (!AddPid(*Pids++))
return false;
}
}
return true;
}
bool cReceiver::AddPids(int Pid1, int Pid2, int Pid3, int Pid4, int Pid5, int Pid6, int Pid7, int Pid8, int Pid9)
{
return AddPid(Pid1) && AddPid(Pid2) && AddPid(Pid3) && AddPid(Pid4) && AddPid(Pid5) && AddPid(Pid6) && AddPid(Pid7) && AddPid(Pid8) && AddPid(Pid9);
}
bool cReceiver::SetPids(const cChannel *Channel)
{
numPids = 0;
if (Channel) {
channelID = Channel->GetChannelID();
return AddPid(Channel->Vpid()) &&
(Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) &&
AddPids(Channel->Apids()) &&
(!Setup.UseDolbyDigital || AddPids(Channel->Dpids())) &&
AddPids(Channel->Spids());
}
return true;
}
bool cReceiver::WantsPid(int Pid) bool cReceiver::WantsPid(int Pid)
{ {
if (Pid) { if (Pid) {

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: receiver.h 1.5 2007/01/07 14:40:36 kls Exp $ * $Id: receiver.h 2.1 2010/01/30 10:25:19 kls Exp $
*/ */
#ifndef __RECEIVER_H #ifndef __RECEIVER_H
@ -14,6 +14,8 @@
#define MAXRECEIVEPIDS 64 // the maximum number of PIDs per receiver #define MAXRECEIVEPIDS 64 // the maximum number of PIDs per receiver
#define LEGACY_CRECEIVER // Code enclosed with this macro is deprecated and may be removed in a future version
class cReceiver { class cReceiver {
friend class cDevice; friend class cDevice;
private: private:
@ -38,20 +40,35 @@ protected:
///< will be delivered only ONCE, so the cReceiver must make sure that ///< will be delivered only ONCE, so the cReceiver must make sure that
///< it will be able to buffer the data if necessary. ///< it will be able to buffer the data if necessary.
public: public:
#ifdef LEGACY_CRECEIVER
cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
///< Creates a new receiver for the channel with the given ChannelID with #endif
///< the given Priority. Pid is a single PID (typically the video PID), while cReceiver(const cChannel *Channel = NULL, int Priority = -1);
///< Pids1...Pids3 are pointers to zero terminated lists of PIDs. ///< Creates a new receiver for the given Channel with the given Priority.
///< If any of these PIDs are 0, they will be silently ignored. ///< If Channel is not NULL, its pids set by a call to SetPids().
///< The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS. ///< Otherwise pids can be added to the receiver by separate calls to the AddPid[s]
///< functions.
///< The total number of PIDs added to a receiver must not exceed MAXRECEIVEPIDS.
///< Priority may be any value in the range -99..99. Negative values indicate ///< Priority may be any value in the range -99..99. Negative values indicate
///< that this cReceiver may be detached at any time (without blocking the ///< that this cReceiver may be detached at any time (without blocking the
///< cDevice it is attached to). ///< cDevice it is attached to).
///< The ChannelID is necessary to allow the device that will be used for this
///< receiver to detect and store whether the channel can be decrypted in case
///< this is an encrypted channel. If the channel is not encrypted or this
///< detection is not wanted, an invalid tChannelID may be given.
virtual ~cReceiver(); virtual ~cReceiver();
bool AddPid(int Pid);
///< Adds the given Pid to the list of PIDs of this receiver.
bool AddPids(const int *Pids);
///< Adds the given izero terminated list of Pids to the list of PIDs of this
///< receiver.
bool AddPids(int Pid1, int Pid2, int Pid3 = 0, int Pid4 = 0, int Pid5 = 0, int Pid6 = 0, int Pid7 = 0, int Pid8 = 0, int Pid9 = 0);
///< Adds the given Pids to the list of PIDs of this receiver.
bool SetPids(const cChannel *Channel);
///< Sets the PIDs of this receiver to those of the given Channel,
///< replacing and previously stored PIDs. If Channel is NULL, all
///< PIDs will be cleared. Parameters in the Setup may control whether
///< certain types of PIDs (like Dolby Digital, for instance) are
///< actually set. The Channel's ID is stored and can later be retrieved
///< through ChannelID(). The ChannelID is necessary to allow the device
///< that will be used for this receiver to detect and store whether the
///< channel can be decrypted in case this is an encrypted channel.
tChannelID ChannelID(void) { return channelID; } tChannelID ChannelID(void) { return channelID; }
bool IsAttached(void) { return device != NULL; } bool IsAttached(void) { return device != NULL; }
///< Returns true if this receiver is (still) attached to a device. ///< Returns true if this receiver is (still) attached to a device.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recorder.c 2.7 2009/12/06 11:34:41 kls Exp $ * $Id: recorder.c 2.8 2010/01/29 16:37:22 kls Exp $
*/ */
#include "recorder.h" #include "recorder.h"
@ -21,8 +21,8 @@
// --- cRecorder ------------------------------------------------------------- // --- cRecorder -------------------------------------------------------------
cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) cRecorder::cRecorder(const char *FileName, const cChannel *Channel, int Priority)
:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) :cReceiver(Channel, Priority)
,cThread("recording") ,cThread("recording")
,recordingInfo(FileName) ,recordingInfo(FileName)
{ {
@ -32,15 +32,15 @@ cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, i
ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE, true, "Recorder"); ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE, true, "Recorder");
ringBuffer->SetTimeouts(0, 100); ringBuffer->SetTimeouts(0, 100);
cChannel *Channel = Channels.GetByChannelID(ChannelID);
int Pid = VPid; int Pid = Channel->Vpid();
int Type = Channel ? Channel->Vtype() : 0; int Type = Channel->Vtype();
if (!Pid && APids) { if (!Pid && Channel->Apid(0)) {
Pid = APids[0]; Pid = Channel->Apid(0);
Type = 0x04; Type = 0x04;
} }
if (!Pid && DPids) { if (!Pid && Channel->Dpid(0)) {
Pid = DPids[0]; Pid = Channel->Dpid(0);
Type = 0x06; Type = 0x06;
} }
frameDetector = new cFrameDetector(Pid, Type); frameDetector = new cFrameDetector(Pid, Type);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: recorder.h 2.1 2009/01/06 10:44:58 kls Exp $ * $Id: recorder.h 2.2 2010/01/29 16:32:32 kls Exp $
*/ */
#ifndef __RECORDER_H #ifndef __RECORDER_H
@ -34,9 +34,9 @@ protected:
virtual void Receive(uchar *Data, int Length); virtual void Receive(uchar *Data, int Length);
virtual void Action(void); virtual void Action(void);
public: public:
cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids); cRecorder(const char *FileName, const cChannel *Channel, int Priority);
// Creates a new recorder for the channel with the given ChannelID and // Creates a new recorder for the given Channel and
// the given Priority that will record the given PIDs into the file FileName. // the given Priority that will record into the file FileName.
virtual ~cRecorder(); virtual ~cRecorder();
}; };

13
remux.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.c 2.40 2010/01/24 16:13:12 kls Exp $ * $Id: remux.c 2.41 2010/01/30 10:43:12 kls Exp $
*/ */
#include "remux.h" #include "remux.h"
@ -144,7 +144,7 @@ void TsSetTeiOnBrokenPackets(uchar *p, int l)
// --- cPatPmtGenerator ------------------------------------------------------ // --- cPatPmtGenerator ------------------------------------------------------
cPatPmtGenerator::cPatPmtGenerator(cChannel *Channel) cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel)
{ {
numPmtPackets = 0; numPmtPackets = 0;
patCounter = pmtCounter = 0; patCounter = pmtCounter = 0;
@ -243,7 +243,7 @@ int cPatPmtGenerator::MakeCRC(uchar *Target, const uchar *Data, int Length)
#define P_PMT_PID 0x0084 // pseudo PMT pid #define P_PMT_PID 0x0084 // pseudo PMT pid
#define MAXPID 0x2000 // the maximum possible number of pids #define MAXPID 0x2000 // the maximum possible number of pids
void cPatPmtGenerator::GeneratePmtPid(cChannel *Channel) void cPatPmtGenerator::GeneratePmtPid(const cChannel *Channel)
{ {
bool Used[MAXPID] = { false }; bool Used[MAXPID] = { false };
#define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; } #define SETPID(p) { if ((p) >= 0 && (p) < MAXPID) Used[p] = true; }
@ -287,7 +287,7 @@ void cPatPmtGenerator::GeneratePat(void)
IncVersion(patVersion); IncVersion(patVersion);
} }
void cPatPmtGenerator::GeneratePmt(cChannel *Channel) void cPatPmtGenerator::GeneratePmt(const cChannel *Channel)
{ {
// generate the complete PMT section: // generate the complete PMT section:
uchar buf[MAX_SECTION_SIZE]; uchar buf[MAX_SECTION_SIZE];
@ -364,7 +364,7 @@ void cPatPmtGenerator::SetVersions(int PatVersion, int PmtVersion)
pmtVersion = PmtVersion & 0x1F; pmtVersion = PmtVersion & 0x1F;
} }
void cPatPmtGenerator::SetChannel(cChannel *Channel) void cPatPmtGenerator::SetChannel(const cChannel *Channel)
{ {
if (Channel) { if (Channel) {
GeneratePmtPid(Channel); GeneratePmtPid(Channel);
@ -402,6 +402,7 @@ void cPatPmtParser::Reset(void)
patVersion = pmtVersion = -1; patVersion = pmtVersion = -1;
pmtPid = -1; pmtPid = -1;
vpid = vtype = 0; vpid = vtype = 0;
ppid = 0;
} }
void cPatPmtParser::ParsePat(const uchar *Data, int Length) void cPatPmtParser::ParsePat(const uchar *Data, int Length)
@ -486,6 +487,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
int NumDpids = 0; int NumDpids = 0;
int NumSpids = 0; int NumSpids = 0;
vpid = vtype = 0; vpid = vtype = 0;
ppid = 0;
apids[0] = 0; apids[0] = 0;
dpids[0] = 0; dpids[0] = 0;
spids[0] = 0; spids[0] = 0;
@ -500,6 +502,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
case 0x1B: // MPEG4 case 0x1B: // MPEG4
vpid = stream.getPid(); vpid = stream.getPid();
vtype = stream.getStreamType(); vtype = stream.getStreamType();
ppid = Pmt.getPCRPid();
break; break;
case 0x03: // STREAMTYPE_11172_AUDIO case 0x03: // STREAMTYPE_11172_AUDIO
case 0x04: // STREAMTYPE_13818_AUDIO case 0x04: // STREAMTYPE_13818_AUDIO

14
remux.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: remux.h 2.23 2009/12/31 15:35:37 kls Exp $ * $Id: remux.h 2.24 2010/01/29 16:51:26 kls Exp $
*/ */
#ifndef __REMUX_H #ifndef __REMUX_H
@ -172,16 +172,16 @@ protected:
int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId);
int MakeLanguageDescriptor(uchar *Target, const char *Language); int MakeLanguageDescriptor(uchar *Target, const char *Language);
int MakeCRC(uchar *Target, const uchar *Data, int Length); int MakeCRC(uchar *Target, const uchar *Data, int Length);
void GeneratePmtPid(cChannel *Channel); void GeneratePmtPid(const cChannel *Channel);
///< Generates a PMT pid that doesn't collide with any of the actual ///< Generates a PMT pid that doesn't collide with any of the actual
///< pids of the Channel. ///< pids of the Channel.
void GeneratePat(void); void GeneratePat(void);
///< Generates a PAT section for later use with GetPat(). ///< Generates a PAT section for later use with GetPat().
void GeneratePmt(cChannel *Channel); void GeneratePmt(const cChannel *Channel);
///< Generates a PMT section for the given Channel, for later use ///< Generates a PMT section for the given Channel, for later use
///< with GetPmt(). ///< with GetPmt().
public: public:
cPatPmtGenerator(cChannel *Channel = NULL); cPatPmtGenerator(const cChannel *Channel = NULL);
void SetVersions(int PatVersion, int PmtVersion); void SetVersions(int PatVersion, int PmtVersion);
///< Sets the version numbers for the generated PAT and PMT, in case ///< Sets the version numbers for the generated PAT and PMT, in case
///< this generator is used to, e.g., continue a previously interrupted ///< this generator is used to, e.g., continue a previously interrupted
@ -191,7 +191,7 @@ public:
///< higher bits will automatically be cleared. ///< higher bits will automatically be cleared.
///< SetVersions() needs to be called before SetChannel() in order to ///< SetVersions() needs to be called before SetChannel() in order to
///< have an effect from the very start. ///< have an effect from the very start.
void SetChannel(cChannel *Channel); void SetChannel(const cChannel *Channel);
///< Sets the Channel for which the PAT/PMT shall be generated. ///< Sets the Channel for which the PAT/PMT shall be generated.
uchar *GetPat(void); uchar *GetPat(void);
///< Returns a pointer to the PAT section, which consists of exactly ///< Returns a pointer to the PAT section, which consists of exactly
@ -213,6 +213,7 @@ private:
int pmtVersion; int pmtVersion;
int pmtPid; int pmtPid;
int vpid; int vpid;
int ppid;
int vtype; int vtype;
int apids[MAXAPIDS + 1]; // list is zero-terminated int apids[MAXAPIDS + 1]; // list is zero-terminated
int atypes[MAXAPIDS + 1]; // list is zero-terminated int atypes[MAXAPIDS + 1]; // list is zero-terminated
@ -252,6 +253,9 @@ public:
int Vpid(void) const { return vpid; } int Vpid(void) const { return vpid; }
///< Returns the video pid as defined by the current PMT, or 0 if no video ///< Returns the video pid as defined by the current PMT, or 0 if no video
///< pid has been detected, yet. ///< pid has been detected, yet.
int Ppid(void) const { return ppid; }
///< Returns the PCR pid as defined by the current PMT, or 0 if no PCR
///< pid has been detected, yet.
int Vtype(void) const { return vtype; } int Vtype(void) const { return vtype; }
///< Returns the video stream type as defined by the current PMT, or 0 if no video ///< Returns the video stream type as defined by the current PMT, or 0 if no video
///< stream type has been detected, yet. ///< stream type has been detected, yet.

View File

@ -4,17 +4,17 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: transfer.c 2.4 2009/12/06 14:22:23 kls Exp $ * $Id: transfer.c 2.5 2010/01/30 11:10:25 kls Exp $
*/ */
#include "transfer.h" #include "transfer.h"
// --- cTransfer ------------------------------------------------------------- // --- cTransfer -------------------------------------------------------------
cTransfer::cTransfer(tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids) cTransfer::cTransfer(const cChannel *Channel)
:cReceiver(ChannelID, -1, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) :cReceiver(Channel)
{ {
patPmtGenerator.SetChannel(Channels.GetByChannelID(ChannelID)); patPmtGenerator.SetChannel(Channel);
} }
cTransfer::~cTransfer() cTransfer::~cTransfer()
@ -55,8 +55,8 @@ void cTransfer::Receive(uchar *Data, int Length)
cDevice *cTransferControl::receiverDevice = NULL; cDevice *cTransferControl::receiverDevice = NULL;
cTransferControl::cTransferControl(cDevice *ReceiverDevice, tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids) cTransferControl::cTransferControl(cDevice *ReceiverDevice, const cChannel *Channel)
:cControl(transfer = new cTransfer(ChannelID, VPid, APids, DPids, SPids), true) :cControl(transfer = new cTransfer(Channel), true)
{ {
ReceiverDevice->AttachReceiver(transfer); ReceiverDevice->AttachReceiver(transfer);
receiverDevice = ReceiverDevice; receiverDevice = ReceiverDevice;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: transfer.h 2.1 2008/05/25 12:44:49 kls Exp $ * $Id: transfer.h 2.2 2010/01/29 16:38:09 kls Exp $
*/ */
#ifndef __TRANSFER_H #ifndef __TRANSFER_H
@ -21,7 +21,7 @@ protected:
virtual void Activate(bool On); virtual void Activate(bool On);
virtual void Receive(uchar *Data, int Length); virtual void Receive(uchar *Data, int Length);
public: public:
cTransfer(tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids); cTransfer(const cChannel *Channel);
virtual ~cTransfer(); virtual ~cTransfer();
}; };
@ -30,7 +30,7 @@ private:
cTransfer *transfer; cTransfer *transfer;
static cDevice *receiverDevice; static cDevice *receiverDevice;
public: public:
cTransferControl(cDevice *ReceiverDevice, tChannelID ChannelID, int VPid, const int *APids, const int *DPids, const int *SPids); cTransferControl(cDevice *ReceiverDevice, const cChannel *Channel);
~cTransferControl(); ~cTransferControl();
virtual void Hide(void) {} virtual void Hide(void) {}
static cDevice *ReceiverDevice(void) { return receiverDevice; } static cDevice *ReceiverDevice(void) { return receiverDevice; }