Version 2.1.4

VDR developer version 2.1.4 is now available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-2.1.4.tar.bz2

A 'diff' against the previous version is available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-2.1.3-2.1.4.diff

MD5 checksums:

e1018c13dc257c986e0e30494913b415  vdr-2.1.4.tar.bz2
870f6f03f4697d136c886358c3be4277  vdr-2.1.3-2.1.4.diff

WARNING:
========

This is a *developer* version. Even though *I* use it in my productive
environment, I strongly recommend that you only use it under controlled
conditions and for testing and debugging.

From the HISTORY file:
- Updated 'sources.conf' (thanks to Antti Hartikainen).
- cFont::CreateFont() now returns a dummy font in case there are no fonts installed.
  This prevents a crash with the LCARS skin on a system that has no fonts.
- Improved locking for CAM slots and made the pure functions of cCiAdapter have
  default implementations, to fix a possible crash with CI adapters and CAM slots
  that are implemented in a plugin.
- Added logging the supported system ids of a CAM.
- Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 10 in order to be able to record
  channels that need more than 5 TS packets for detecting frame borders (reported by
  Eike Sauer).
- Fixed deleting the source recording after moving it to a different volume (reported
  by Christoph Haubrich).
- Now waiting explicitly until all CAM slots are ready before switching to the
  initial channel when VDR is started. This is necessary in case CI adapters are
  used that are not physically connected to a dedicated device. The respective checks
  in cDvbDevice have been removed to avoid redundancy.
- Fixed detecting frame borders in MPEG-2 streams that have "bottom fields" or varying
  GOP structures (reported by Christian Paulick, with help from Helmut Auer).
- Now unassigning CAMs from their devices when they are no longer used.
- Now making sure the primary device goes into transfer mode for live viewing if the
  CAM wants to receive the TS data.
- Fixed a wrong alignment in cCiDateTime::SendDateTime().
- Since the new cRecordingsHandler that was introduced in version 2.1.2 not only
  handles "cutting", but also "moving" and "copying" recordings, the German word
  "Schnitt" has been replaced with the more generic "Bearbeitung", which covers all
  three variations of "editing" a recording (suggested by Christoph Haubrich).
  Maintainers of translations for other languages may want to change their *.po files
  accordingly.
- The new function cStatus::ChannelChange() can be implemented by plugins to be
  informed about changes to the parameters of a channel that may require a retune.
  This may, for instance, be useful for plugins that implement live streaming, so that
  they can react on changes to a channel's PIDs or CA descriptors (problem reported
  by Mariusz Bialonczyk).
- Fixed a superfluous call to the skin's SetRecording() function after renaming a
  recording (reported by Christoph Haubrich).
This commit is contained in:
Klaus Schmidinger 2014-01-26 11:45:00 +01:00 committed by Dieter Hametner
parent 716c03a47e
commit 67e322b0dd
23 changed files with 344 additions and 171 deletions

View File

@ -620,6 +620,8 @@ Helmut Auer <vdr@helmutauer.de>
command line option to be left empty to use the default values if only ENC shall be set command line option to be left empty to use the default values if only ENC shall be set
for reporting an inconsistent behavior between opening the Recordings menu manually for reporting an inconsistent behavior between opening the Recordings menu manually
via the main menu and by pressing the Recordings key via the main menu and by pressing the Recordings key
for helping to debug a problem with frame detection in MPEG-2 streams that have "bottom fields"
or varying GOP structures
Jeremy Hall <jhall@UU.NET> Jeremy Hall <jhall@UU.NET>
for fixing an incomplete initialization of the filter parameters in eit.c for fixing an incomplete initialization of the filter parameters in eit.c
@ -2389,6 +2391,11 @@ Christoph Haubrich <christoph1.haubrich@arcor.de>
display gets hidden display gets hidden
for reporting a wrong type ('int' vs. 'eTimerEvent') in the declaration of for reporting a wrong type ('int' vs. 'eTimerEvent') in the declaration of
cSkinDisplayMenu::SetItemEvent() cSkinDisplayMenu::SetItemEvent()
for reporting that the source recording was not deleted after moving it to a different
volume
for suggesting to replace "Schnitt" with "Bearbeitung" in the German OSD texts
for reporting a superfluous call to the skin's SetRecording() function after renaming
a recording
Pekka Mauno <pekka.mauno@iki.fi> Pekka Mauno <pekka.mauno@iki.fi>
for fixing cSchedule::GetFollowingEvent() in case there is currently no present for fixing cSchedule::GetFollowingEvent() in case there is currently no present
@ -2504,6 +2511,7 @@ Anssi Hannula <anssi.hannula@gmail.com>
Antti Hartikainen <ami+vdr@ah.fi> Antti Hartikainen <ami+vdr@ah.fi>
for updating 'S13E' in 'sources.conf' for updating 'S13E' in 'sources.conf'
for adding maximum SNR value for PCTV Systems nanoStick T2 290e for adding maximum SNR value for PCTV Systems nanoStick T2 290e
for updating 'sources.conf'
Bernd Melcher <bernd@bernd-melcher.de> Bernd Melcher <bernd@bernd-melcher.de>
for reporting a problem with the 'servicedemo' plugin having no PLUGIN macro for reporting a problem with the 'servicedemo' plugin having no PLUGIN macro
@ -3236,3 +3244,15 @@ Thomas Reufer <thomas@reufer.ch>
for suggesting to add an additional parameter named Forward to cDevice::TrickSpeed() for suggesting to add an additional parameter named Forward to cDevice::TrickSpeed()
for suggesting to add a note to ePlayMode in device.h that VDR itself always uses for suggesting to add a note to ePlayMode in device.h that VDR itself always uses
pmAudioVideo when replaying a recording pmAudioVideo when replaying a recording
Eike Sauer <EikeSauer@t-online.de>
for reporting a problem with channels that need more than 5 TS packets for detecting
frame borders
Christian Paulick <cpaulick@xeatre.tv>
for reporting a problem with frame detection in MPEG-2 streams that have "bottom fields"
or varying GOP structures
Mariusz Bialonczyk <manio@skyboo.net>
for reporting a problem with live streaming of encrypted channels, when there are no
CA descriptors, yet, on initial tuning

54
HISTORY
View File

@ -8115,3 +8115,57 @@ Video Disk Recorder Revision History
identify obsolete channels when you switch to them, and you can get the complete identify obsolete channels when you switch to them, and you can get the complete
overview of all obsolete channels by sorting the Channels list by provider (by overview of all obsolete channels by sorting the Channels list by provider (by
pressing the 0 key twice). Automatic deletion of obsolete channels may follow later. pressing the 0 key twice). Automatic deletion of obsolete channels may follow later.
2014-01-07: Version 2.0.5
- The LIRC remote control now connects to the socket even if it doesn't yet exist when
VDR is started (thanks to Lars Hanisch).
- Fixed a missing initialization in the c'tor of cSkinLCARSDisplayChannel (thanks to
Marko Mäkelä).
- Fixed uninitialized item area coordinates in cSkinLCARSDisplayMenu (reported by
Marko Mäkelä).
- Fixed a possible crash if the recordings list is updated externally while the
Recordings menu is open (reported by Lars Hanisch).
- Added a missing closing ')' in the help and man page entry of the --vfat option
(reported by Lars Hanisch).
- Fixed setting the name of the video directory to avoid a crash when using --genindex,
and also to use the correct directory with --edit (the latter reported by Marko
Mäkelä).
2014-01-26: Version 2.1.4
- Updated 'sources.conf' (thanks to Antti Hartikainen).
- cFont::CreateFont() now returns a dummy font in case there are no fonts installed.
This prevents a crash with the LCARS skin on a system that has no fonts.
- Improved locking for CAM slots and made the pure functions of cCiAdapter have
default implementations, to fix a possible crash with CI adapters and CAM slots
that are implemented in a plugin.
- Added logging the supported system ids of a CAM.
- Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 10 in order to be able to record
channels that need more than 5 TS packets for detecting frame borders (reported by
Eike Sauer).
- Fixed deleting the source recording after moving it to a different volume (reported
by Christoph Haubrich).
- Now waiting explicitly until all CAM slots are ready before switching to the
initial channel when VDR is started. This is necessary in case CI adapters are
used that are not physically connected to a dedicated device. The respective checks
in cDvbDevice have been removed to avoid redundancy.
- Fixed detecting frame borders in MPEG-2 streams that have "bottom fields" or varying
GOP structures (reported by Christian Paulick, with help from Helmut Auer).
- Now unassigning CAMs from their devices when they are no longer used.
- Now making sure the primary device goes into transfer mode for live viewing if the
CAM wants to receive the TS data.
- Fixed a wrong alignment in cCiDateTime::SendDateTime().
- Since the new cRecordingsHandler that was introduced in version 2.1.2 not only
handles "cutting", but also "moving" and "copying" recordings, the German word
"Schnitt" has been replaced with the more generic "Bearbeitung", which covers all
three variations of "editing" a recording (suggested by Christoph Haubrich).
Maintainers of translations for other languages may want to change their *.po files
accordingly.
- The new function cStatus::ChannelChange() can be implemented by plugins to be
informed about changes to the parameters of a channel that may require a retune.
This may, for instance, be useful for plugins that implement live streaming, so that
they can react on changes to a channel's PIDs or CA descriptors (problem reported
by Mariusz Bialonczyk).
- Fixed a superfluous call to the skin's SetRecording() function after renaming a
recording (reported by Christoph Haubrich).

View File

@ -89,3 +89,7 @@ VDR Plugin 'dvbhddevice' Revision History
- Avoiding unnecessary pkg-config warnings in plugin Makefiles. - Avoiding unnecessary pkg-config warnings in plugin Makefiles.
- cDevice::TrickSpeed() now has an additional parameter named Forward. - cDevice::TrickSpeed() now has an additional parameter named Forward.
2014-01-17: Version 2.1.4
- Using PCR based clock recovery in transfer mode.

View File

@ -10,7 +10,7 @@
#include "menu.h" #include "menu.h"
#include "setup.h" #include "setup.h"
static const char *VERSION = "2.1.3"; static const char *VERSION = "2.1.4";
static const char *DESCRIPTION = trNOOP("HD Full Featured DVB device"); static const char *DESCRIPTION = trNOOP("HD Full Featured DVB device");
static const char *MAINMENUENTRY = "dvbhddevice"; static const char *MAINMENUENTRY = "dvbhddevice";

View File

@ -51,6 +51,12 @@ cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend)
isHdffPrimary = true; isHdffPrimary = true;
mHdffCmdIf = new HDFF::cHdffCmdIf(fd_osd); mHdffCmdIf = new HDFF::cHdffCmdIf(fd_osd);
uint32_t firmwareVersion = mHdffCmdIf->CmdGetFirmwareVersion(NULL, 0);
if (firmwareVersion < 0x401)
supportsPcrInTransferMode = false;
else
supportsPcrInTransferMode = true;
/* reset some stuff in case the VDR was killed before and had no chance /* reset some stuff in case the VDR was killed before and had no chance
to clean up. */ to clean up. */
mHdffCmdIf->CmdOsdReset(); mHdffCmdIf->CmdOsdReset();
@ -511,13 +517,15 @@ bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode)
} }
else else
{ {
mHdffCmdIf->CmdAvSetPlayMode(1, Transferring() || (cTransferControl::ReceiverDevice() == this)); isTransferMode = Transferring() || (cTransferControl::ReceiverDevice() == this);
mHdffCmdIf->CmdAvSetPlayMode(1, isTransferMode);
mHdffCmdIf->CmdAvSetStc(0, 100000); mHdffCmdIf->CmdAvSetStc(0, 100000);
mHdffCmdIf->CmdAvEnableSync(0, false); mHdffCmdIf->CmdAvEnableSync(0, false);
mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true); mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true);
playVideoPid = -1; playVideoPid = -1;
playAudioPid = -1; playAudioPid = -1;
playPcrPid = -1;
audioCounter = 0; audioCounter = 0;
videoCounter = 0; videoCounter = 0;
freezed = false; freezed = false;
@ -606,7 +614,11 @@ void cDvbHdFfDevice::ScaleVideo(const cRect &Rect)
} }
} }
#if (APIVERSNUM >= 20103)
void cDvbHdFfDevice::TrickSpeed(int Speed, bool Forward) void cDvbHdFfDevice::TrickSpeed(int Speed, bool Forward)
#else
void cDvbHdFfDevice::TrickSpeed(int Speed)
#endif
{ {
freezed = false; freezed = false;
mHdffCmdIf->CmdAvEnableSync(0, false); mHdffCmdIf->CmdAvEnableSync(0, false);
@ -896,6 +908,14 @@ int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length)
mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, MapVideoStreamTypes(PatPmtParser()->Vtype()), true); mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, MapVideoStreamTypes(PatPmtParser()->Vtype()), true);
} }
} }
if (isTransferMode && supportsPcrInTransferMode) {
if (pid != playPcrPid) {
if (pid == PatPmtParser()->Ppid()) {
playPcrPid = pid;
mHdffCmdIf->CmdAvSetPcrPid(0, playPcrPid);
}
}
}
return WriteAllOrNothing(fd_video, Data, Length, 1000, 10); return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
} }

View File

@ -77,9 +77,12 @@ protected:
private: private:
int playVideoPid; int playVideoPid;
int playAudioPid; int playAudioPid;
int playPcrPid;
bool freezed; bool freezed;
bool trickMode; bool trickMode;
bool isPlayingVideo; bool isPlayingVideo;
bool isTransferMode;
bool supportsPcrInTransferMode;
// Pes2Ts conversion stuff // Pes2Ts conversion stuff
uint8_t videoCounter; uint8_t videoCounter;
@ -99,7 +102,11 @@ public:
virtual int64_t GetSTC(void); virtual int64_t GetSTC(void);
virtual cRect CanScaleVideo(const cRect &Rect, int Alignment = taCenter); virtual cRect CanScaleVideo(const cRect &Rect, int Alignment = taCenter);
virtual void ScaleVideo(const cRect &Rect = cRect::Null); virtual void ScaleVideo(const cRect &Rect = cRect::Null);
#if (APIVERSNUM >= 20103)
virtual void TrickSpeed(int Speed, bool Forward); virtual void TrickSpeed(int Speed, bool Forward);
#else
virtual void TrickSpeed(int Speed);
#endif
virtual void Clear(void); virtual void Clear(void);
virtual void Play(void); virtual void Play(void);
virtual void Freeze(void); virtual void Freeze(void);

40
ci.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: ci.c 3.4 2014/01/02 10:31:12 kls Exp $ * $Id: ci.c 3.10 2014/01/22 09:46:38 kls Exp $
*/ */
#include "ci.h" #include "ci.h"
@ -719,11 +719,13 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
switch (Tag) { switch (Tag) {
case AOT_CA_INFO: { case AOT_CA_INFO: {
dbgprotocol("Slot %d: <== Ca Info (%d)", Tc()->CamSlot()->SlotNumber(), SessionId()); dbgprotocol("Slot %d: <== Ca Info (%d)", Tc()->CamSlot()->SlotNumber(), SessionId());
cString Ids;
numCaSystemIds = 0; numCaSystemIds = 0;
int l = 0; int l = 0;
const uint8_t *d = GetData(Data, l); const uint8_t *d = GetData(Data, l);
while (l > 1) { while (l > 1) {
uint16_t id = ((uint16_t)(*d) << 8) | *(d + 1); uint16_t id = ((uint16_t)(*d) << 8) | *(d + 1);
Ids = cString::sprintf("%s %04X", *Ids ? *Ids : "", id);
dbgprotocol(" %04X", id); dbgprotocol(" %04X", id);
d += 2; d += 2;
l -= 2; l -= 2;
@ -740,6 +742,7 @@ void cCiConditionalAccessSupport::Process(int Length, const uint8_t *Data)
timer.Set(QUERY_WAIT_TIME); // WORKAROUND: Alphacrypt 3.09 doesn't reply to QUERY immediately after reset timer.Set(QUERY_WAIT_TIME); // WORKAROUND: Alphacrypt 3.09 doesn't reply to QUERY immediately after reset
state = 2; // got ca info state = 2; // got ca info
} }
dsyslog("CAM %d: system ids:%s", Tc()->CamSlot()->SlotNumber(), *Ids ? *Ids : " none");
} }
break; break;
case AOT_CA_PMT_REPLY: { case AOT_CA_PMT_REPLY: {
@ -858,7 +861,9 @@ void cCiDateTime::SendDateTime(void)
int L = (M == 1 || M == 2) ? 1 : 0; int L = (M == 1 || M == 2) ? 1 : 0;
int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001); int MJD = 14956 + D + int((Y - L) * 365.25) + int((M + 1 + L * 12) * 30.6001);
#define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10)) #define DEC2BCD(d) uint8_t(((d / 10) << 4) + (d % 10))
#pragma pack(1)
struct tTime { uint16_t mjd; uint8_t h, m, s; short offset; }; struct tTime { uint16_t mjd; uint8_t h, m, s; short offset; };
#pragma pack()
tTime T = { mjd : htons(MJD), h : DEC2BCD(tm_gmt.tm_hour), m : DEC2BCD(tm_gmt.tm_min), s : DEC2BCD(tm_gmt.tm_sec), offset : short(htons(tm_loc.tm_gmtoff / 60)) }; tTime T = { mjd : htons(MJD), h : DEC2BCD(tm_gmt.tm_hour), m : DEC2BCD(tm_gmt.tm_min), s : DEC2BCD(tm_gmt.tm_sec), offset : short(htons(tm_loc.tm_gmtoff / 60)) };
bool OldDumpTPDUDataTransfer = DumpTPDUDataTransfer; bool OldDumpTPDUDataTransfer = DumpTPDUDataTransfer;
DumpTPDUDataTransfer &= DumpDateTime; DumpTPDUDataTransfer &= DumpDateTime;
@ -1529,15 +1534,6 @@ void cCiAdapter::AddCamSlot(cCamSlot *CamSlot)
} }
} }
bool cCiAdapter::Ready(void)
{
for (int i = 0; i < MAX_CAM_SLOTS_PER_ADAPTER; i++) {
if (camSlots[i] && !camSlots[i]->Ready())
return false;
}
return true;
}
void cCiAdapter::Action(void) void cCiAdapter::Action(void)
{ {
cTPDU TPDU; cTPDU TPDU;
@ -1559,8 +1555,6 @@ void cCiAdapter::Action(void)
// --- cCamSlot -------------------------------------------------------------- // --- cCamSlot --------------------------------------------------------------
cCamSlots CamSlots;
#define MODULE_CHECK_INTERVAL 500 // ms #define MODULE_CHECK_INTERVAL 500 // ms
#define MODULE_RESET_TIMEOUT 2 // s #define MODULE_RESET_TIMEOUT 2 // s
@ -1584,6 +1578,8 @@ cCamSlot::cCamSlot(cCiAdapter *CiAdapter, bool ReceiveCaPids)
cCamSlot::~cCamSlot() cCamSlot::~cCamSlot()
{ {
if (ciAdapter && ciAdapter->assignedDevice)
ciAdapter->assignedDevice->SetCamSlot(NULL);
delete caPidReceiver; delete caPidReceiver;
CamSlots.Del(this, false); CamSlots.Del(this, false);
DeleteAllConnections(); DeleteAllConnections();
@ -2020,6 +2016,26 @@ uchar *cCamSlot::Decrypt(uchar *Data, int &Count)
return Data; return Data;
} }
// --- cCamSlots -------------------------------------------------------------
cCamSlots CamSlots;
bool cCamSlots::WaitForAllCamSlotsReady(int Timeout)
{
for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) {
bool ready = true;
for (cCamSlot *CamSlot = CamSlots.First(); CamSlot; CamSlot = CamSlots.Next(CamSlot)) {
if (!CamSlot->Ready()) {
ready = false;
cCondWait::SleepMs(100);
}
}
if (ready)
return true;
}
return false;
}
// --- cChannelCamRelation --------------------------------------------------- // --- cChannelCamRelation ---------------------------------------------------
#define CAM_CHECKED_TIMEOUT 15 // seconds before a CAM that has been checked for a particular channel will be checked again #define CAM_CHECKED_TIMEOUT 15 // seconds before a CAM that has been checked for a particular channel will be checked again

39
ci.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: ci.h 3.3 2014/01/02 10:14:39 kls Exp $ * $Id: ci.h 3.6 2014/01/20 12:01:01 kls Exp $
*/ */
#ifndef __CI_H #ifndef __CI_H
@ -88,19 +88,19 @@ protected:
///< Handles the attached CAM slots in a separate thread. ///< Handles the attached CAM slots in a separate thread.
///< The derived class must call the Start() function to ///< The derived class must call the Start() function to
///< actually start CAM handling. ///< actually start CAM handling.
virtual int Read(uint8_t *Buffer, int MaxLength) = 0; virtual int Read(uint8_t *Buffer, int MaxLength) { return 0; }
///< Reads one chunk of data into the given Buffer, up to MaxLength bytes. ///< Reads one chunk of data into the given Buffer, up to MaxLength bytes.
///< If no data is available immediately, wait for up to CAM_READ_TIMEOUT. ///< If no data is available immediately, wait for up to CAM_READ_TIMEOUT.
///< Returns the number of bytes read (in case of an error it will also ///< Returns the number of bytes read (in case of an error it will also
///< return 0). ///< return 0).
virtual void Write(const uint8_t *Buffer, int Length) = 0; virtual void Write(const uint8_t *Buffer, int Length) {}
///< Writes Length bytes of the given Buffer. ///< Writes Length bytes of the given Buffer.
virtual bool Reset(int Slot) = 0; virtual bool Reset(int Slot) { return false; }
///< Resets the CAM in the given Slot. ///< Resets the CAM in the given Slot.
///< Returns true if the operation was successful. ///< Returns true if the operation was successful.
virtual eModuleStatus ModuleStatus(int Slot) = 0; virtual eModuleStatus ModuleStatus(int Slot) { return msNone; }
///< Returns the status of the CAM in the given Slot. ///< Returns the status of the CAM in the given Slot.
virtual bool Assign(cDevice *Device, bool Query = false) = 0; virtual bool Assign(cDevice *Device, bool Query = false) { return false; }
///< Assigns this adapter to the given Device, if this is possible. ///< Assigns this adapter to the given Device, if this is possible.
///< If Query is 'true', the adapter only checks whether it can be ///< If Query is 'true', the adapter only checks whether it can be
///< assigned to the Device, but doesn't actually assign itself to it. ///< assigned to the Device, but doesn't actually assign itself to it.
@ -113,8 +113,6 @@ public:
cCiAdapter(void); cCiAdapter(void);
virtual ~cCiAdapter(); virtual ~cCiAdapter();
///< The derived class must call Cancel(3) in its destructor. ///< The derived class must call Cancel(3) in its destructor.
virtual bool Ready(void);
///< Returns 'true' if all present CAMs in this adapter are ready.
}; };
class cTPDU; class cTPDU;
@ -149,13 +147,13 @@ private:
void Write(cTPDU *TPDU); void Write(cTPDU *TPDU);
cCiSession *GetSessionByResourceId(uint32_t ResourceId); cCiSession *GetSessionByResourceId(uint32_t ResourceId);
public: public:
cCamSlot(cCiAdapter *CiAdapter, bool ReceiveCaPids = false); cCamSlot(cCiAdapter *CiAdapter, bool WantsTsData = false);
///< Creates a new CAM slot for the given CiAdapter. ///< Creates a new CAM slot for the given CiAdapter.
///< The CiAdapter will take care of deleting the CAM slot, ///< The CiAdapter will take care of deleting the CAM slot,
///< so the caller must not delete it! ///< so the caller must not delete it!
///< If ReceiveCaPids is true, the CAM slot will take care that the CA pids ///< If WantsTsData is true, the device this CAM slot is assigned to will
///< of the selected programmes will be included in the TS data stream that ///< call the Decrypt() function of this CAM slot, presenting it the complete
///< is presented to the Decrypt() function. ///< TS data stream of the encrypted programme, including the CA pids.
virtual ~cCamSlot(); virtual ~cCamSlot();
bool Assign(cDevice *Device, bool Query = false); bool Assign(cDevice *Device, bool Query = false);
///< Assigns this CAM slot to the given Device, if this is possible. ///< Assigns this CAM slot to the given Device, if this is possible.
@ -168,6 +166,9 @@ public:
///< 'true'. ///< 'true'.
cDevice *Device(void); cDevice *Device(void);
///< Returns the device this CAM slot is currently assigned to. ///< Returns the device this CAM slot is currently assigned to.
bool WantsTsData(void) const { return caPidReceiver != NULL; }
///< Returns true if this CAM slot wants to receive the TS data through
///< its Decrypt() function.
int SlotIndex(void) { return slotIndex; } int SlotIndex(void) { return slotIndex; }
///< Returns the index of this CAM slot within its CI adapter. ///< Returns the index of this CAM slot within its CI adapter.
///< The first slot has an index of 0. ///< The first slot has an index of 0.
@ -263,11 +264,19 @@ public:
///< shall be set to 0 and the same Data pointer will be offered in the next ///< shall be set to 0 and the same Data pointer will be offered in the next
///< call to Decrypt(). ///< call to Decrypt().
///< A derived class that implements this function will also need ///< A derived class that implements this function will also need
///< to set the ReceiveCaPids parameter in the call to the base class ///< to set the WantsTsData parameter in the call to the base class
///< constructor to true in order to receive the CA pid data. ///< constructor to true in order to receive the TS data.
}; };
class cCamSlots : public cList<cCamSlot> {}; class cCamSlots : public cList<cCamSlot> {
public:
bool WaitForAllCamSlotsReady(int Timeout = 0);
///< Waits until all CAM slots have become ready, or the given Timeout
///< (seconds) has expired. While waiting, the Ready() function of each
///< CAM slot is called in turn, until they all return true.
///< Returns true if all CAM slots have become ready within the given
///< timeout.
};
extern cCamSlots CamSlots; extern cCamSlots CamSlots;

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: config.h 3.5 2013/10/20 09:32:23 kls Exp $ * $Id: config.h 3.6 2014/01/07 09:03:29 kls Exp $
*/ */
#ifndef __CONFIG_H #ifndef __CONFIG_H
@ -22,13 +22,13 @@
// VDR's own version number: // VDR's own version number:
#define VDRVERSION "2.1.3" #define VDRVERSION "2.1.4"
#define VDRVERSNUM 20103 // Version * 10000 + Major * 100 + Minor #define VDRVERSNUM 20104 // Version * 10000 + Major * 100 + Minor
// The plugin API's version number: // The plugin API's version number:
#define APIVERSION "2.1.3" #define APIVERSION "2.1.4"
#define APIVERSNUM 20103 // Version * 10000 + Major * 100 + Minor #define APIVERSNUM 20104 // Version * 10000 + Major * 100 + Minor
// When loading plugins, VDR searches them by their APIVERSION, which // When loading plugins, VDR searches them by their APIVERSION, which
// may be smaller than VDRVERSION in case there have been no changes to // may be smaller than VDRVERSION in case there have been no changes to

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 3.7 2014/01/02 10:31:58 kls Exp $ * $Id: device.c 3.11 2014/01/21 11:12:01 kls Exp $
*/ */
#include "device.h" #include "device.h"
@ -358,6 +358,7 @@ bool cDevice::HasCi(void)
void cDevice::SetCamSlot(cCamSlot *CamSlot) void cDevice::SetCamSlot(cCamSlot *CamSlot)
{ {
LOCK_THREAD;
camSlot = CamSlot; camSlot = CamSlot;
} }
@ -760,6 +761,9 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
cDevice *Device = (LiveView && IsPrimaryDevice()) ? GetDevice(Channel, LIVEPRIORITY, true) : this; cDevice *Device = (LiveView && IsPrimaryDevice()) ? GetDevice(Channel, LIVEPRIORITY, true) : this;
bool NeedsTransferMode = Device != this; bool NeedsTransferMode = Device != this;
// If the CAM slot wants the TS data, we need to switch to Transfer Mode:
if (!NeedsTransferMode && LiveView && IsPrimaryDevice() && CamSlot() && CamSlot()->WantsTsData())
NeedsTransferMode = true;
eSetChannelResult Result = scrOk; eSetChannelResult Result = scrOk;
@ -1697,8 +1701,12 @@ void cDevice::Detach(cReceiver *Receiver)
else if (receiver[i]) else if (receiver[i])
receiversLeft = true; receiversLeft = true;
} }
if (camSlot && Receiver->priority > MINPRIORITY) // priority check to avoid an infinite loop with the CAM slot's caPidReceiver if (camSlot) {
if (Receiver->priority > MINPRIORITY) // priority check to avoid an infinite loop with the CAM slot's caPidReceiver
camSlot->StartDecrypting(); camSlot->StartDecrypting();
if (!camSlot->IsDecrypting())
camSlot->Assign(NULL);
}
if (!receiversLeft) if (!receiversLeft)
Cancel(-1); Cancel(-1);
} }

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: dvbdevice.c 3.8 2014/01/02 10:30:15 kls Exp $ * $Id: dvbdevice.c 3.10 2014/01/20 11:46:26 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -1320,13 +1320,6 @@ bool cDvbDevice::QueryDeliverySystems(int fd_frontend)
return false; return false;
} }
bool cDvbDevice::Ready(void)
{
if (ciAdapter)
return ciAdapter->Ready();
return true;
}
bool cDvbDevice::BondDevices(const char *Bondings) bool cDvbDevice::BondDevices(const char *Bondings)
{ {
UnBondDevices(); UnBondDevices();
@ -1671,14 +1664,20 @@ void cDvbDevice::CloseDvr(void)
bool cDvbDevice::GetTSPacket(uchar *&Data) bool cDvbDevice::GetTSPacket(uchar *&Data)
{ {
if (tsBuffer) { if (tsBuffer) {
if (cCamSlot *cs = CamSlot()) {
if (cs->WantsTsData()) {
int Available; int Available;
Data = tsBuffer->Get(&Available); Data = tsBuffer->Get(&Available);
if (Data && CamSlot()) { if (Data) {
Data = CamSlot()->Decrypt(Data, Available); Data = cs->Decrypt(Data, Available);
tsBuffer->Skip(Available); tsBuffer->Skip(Available);
} }
return true; return true;
} }
}
Data = tsBuffer->Get();
return true;
}
return false; return false;
} }

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: dvbdevice.h 3.3 2014/01/01 14:00:56 kls Exp $ * $Id: dvbdevice.h 3.4 2014/01/16 11:45:35 kls Exp $
*/ */
#ifndef __DVBDEVICE_H #ifndef __DVBDEVICE_H
@ -185,7 +185,6 @@ public:
virtual ~cDvbDevice(); virtual ~cDvbDevice();
int Adapter(void) const { return adapter; } int Adapter(void) const { return adapter; }
int Frontend(void) const { return frontend; } int Frontend(void) const { return frontend; }
virtual bool Ready(void);
virtual cString DeviceType(void) const; virtual cString DeviceType(void) const;
virtual cString DeviceName(void) const; virtual cString DeviceName(void) const;
static bool BondDevices(const char *Bondings); static bool BondDevices(const char *Bondings);

23
font.c
View File

@ -6,7 +6,7 @@
* *
* BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya. * BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya.
* *
* $Id: font.c 3.1 2013/04/07 14:42:13 kls Exp $ * $Id: font.c 3.2 2014/01/07 12:19:45 kls Exp $
*/ */
#include "font.h" #include "font.h"
@ -382,10 +382,13 @@ void cFreetypeFont::DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColo
// A dummy font, in case there are no fonts installed: // A dummy font, in case there are no fonts installed:
class cDummyFont : public cFont { class cDummyFont : public cFont {
private:
int height;
public: public:
virtual int Width(uint c) const { return 10; } cDummyFont(int CharHeight) { height = CharHeight; }
virtual int Width(const char *s) const { return 50; } virtual int Width(uint c) const { return height; }
virtual int Height(void) const { return 20; } virtual int Width(const char *s) const { return height; }
virtual int Height(void) const { return height; }
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {} virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}
virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {}; virtual void DrawText(cPixmap *Pixmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const {};
}; };
@ -396,11 +399,8 @@ cFont *cFont::fonts[eDvbFontSize] = { NULL };
void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight) void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight)
{ {
cFont *f = CreateFont(Name, constrain(CharHeight, MINFONTSIZE, MAXFONTSIZE));
if (!f || !f->Height())
f = new cDummyFont;
delete fonts[Font]; delete fonts[Font];
fonts[Font] = f; fonts[Font] = CreateFont(Name, constrain(CharHeight, MINFONTSIZE, MAXFONTSIZE));
} }
const cFont *cFont::GetFont(eDvbFont Font) const cFont *cFont::GetFont(eDvbFont Font)
@ -423,9 +423,10 @@ const cFont *cFont::GetFont(eDvbFont Font)
cFont *cFont::CreateFont(const char *Name, int CharHeight, int CharWidth) cFont *cFont::CreateFont(const char *Name, int CharHeight, int CharWidth)
{ {
cString fn = GetFontFileName(Name); cString fn = GetFontFileName(Name);
if (*fn) cFont *f = *fn ? new cFreetypeFont(fn, CharHeight, CharWidth) : NULL;
return new cFreetypeFont(fn, CharHeight, CharWidth); if (!f || !f->Height())
return NULL; f = new cDummyFont(CharHeight);
return f;
} }
bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced) bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced)

4
font.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: font.h 3.0 2013/02/17 13:17:42 kls Exp $ * $Id: font.h 3.1 2014/01/07 12:11:55 kls Exp $
*/ */
#ifndef __FONT_H #ifndef __FONT_H
@ -75,7 +75,7 @@ public:
///< default width. Name is of the form "Family:Style", for instance ///< default width. Name is of the form "Family:Style", for instance
///< "Verdana:Bold Italic" or "Times New Roman". See GetAvailableFontNames() ///< "Verdana:Bold Italic" or "Times New Roman". See GetAvailableFontNames()
///< for how to get a list of all available font names. ///< for how to get a list of all available font names.
///< If the requested font can't be created, NULL is returned. ///< If the requested font can't be created, a dummy font is returned.
///< The caller must delete the font when it is no longer needed. ///< The caller must delete the font when it is no longer needed.
static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced = false); static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced = false);
///< Queries the font configuration for a list of available font names, ///< Queries the font configuration for a list of available font names,

10
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 3.15 2013/12/27 09:00:24 kls Exp $ * $Id: menu.c 3.16 2014/01/25 12:40:28 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -2473,12 +2473,8 @@ void cMenuRecording::Display(void)
eOSState cMenuRecording::ProcessKey(eKeys Key) eOSState cMenuRecording::ProcessKey(eKeys Key)
{ {
if (HasSubMenu()) { if (HasSubMenu())
eOSState state = cOsdMenu::ProcessKey(Key); return cOsdMenu::ProcessKey(Key);
if (state == osUser1)
CloseSubMenu();
return state;
}
else if (!RefreshRecording()) else if (!RefreshRecording())
return osBack; // the recording has vanished, so close this menu return osBack; // the recording has vanished, so close this menu
switch (int(Key)) { switch (int(Key)) {

View File

@ -809,7 +809,7 @@ msgid "Delete recording?"
msgstr "Aufzeichnung löschen?" msgstr "Aufzeichnung löschen?"
msgid "Recording is being edited - really delete?" msgid "Recording is being edited - really delete?"
msgstr "Aufzeichnung wird geschnitten - trotzdem löschen?" msgstr "Aufzeichnung wird bearbeitet - trotzdem löschen?"
msgid "Error while deleting recording!" msgid "Error while deleting recording!"
msgstr "Fehler beim Löschen der Aufzeichnung!" msgstr "Fehler beim Löschen der Aufzeichnung!"
@ -1283,13 +1283,13 @@ msgstr "Weiter"
#. TRANSLATORS: note the leading blank! #. TRANSLATORS: note the leading blank!
msgid " Cancel editing" msgid " Cancel editing"
msgstr " Schneiden abbrechen" msgstr " Bearbeitung abbrechen"
msgid "Stop recording?" msgid "Stop recording?"
msgstr "Aufzeichnung beenden?" msgstr "Aufzeichnung beenden?"
msgid "Cancel editing?" msgid "Cancel editing?"
msgstr "Schneiden abbrechen?" msgstr "Bearbeitung abbrechen?"
msgid "No audio available!" msgid "No audio available!"
msgstr "Kein Audio verfügbar!" msgstr "Kein Audio verfügbar!"
@ -1371,7 +1371,7 @@ msgid "Can't shutdown - option '-s' not given!"
msgstr "Ausschalten unmöglich - Option '-s' fehlt!" msgstr "Ausschalten unmöglich - Option '-s' fehlt!"
msgid "Editing - shut down anyway?" msgid "Editing - shut down anyway?"
msgstr "Schnitt läuft - trotzdem ausschalten?" msgstr "Bearbeitung läuft - trotzdem ausschalten?"
msgid "Recording - shut down anyway?" msgid "Recording - shut down anyway?"
msgstr "Aufnahme läuft - trotzdem ausschalten?" msgstr "Aufnahme läuft - trotzdem ausschalten?"
@ -1388,7 +1388,7 @@ msgid "Plugin %s wakes up in %ld min, continue?"
msgstr "Plugin %s wacht in %ld Min auf, weiter?" msgstr "Plugin %s wacht in %ld Min auf, weiter?"
msgid "Editing - restart anyway?" msgid "Editing - restart anyway?"
msgstr "Schnitt läuft - trotzdem neu starten?" msgstr "Bearbeitung läuft - trotzdem neu starten?"
msgid "Recording - restart anyway?" msgid "Recording - restart anyway?"
msgstr "Aufnahme läuft - trotzdem neu starten?" msgstr "Aufnahme läuft - trotzdem neu starten?"
@ -1476,10 +1476,10 @@ msgid "Switching primary DVB..."
msgstr "Primäres Interface wird umgeschaltet..." msgstr "Primäres Interface wird umgeschaltet..."
msgid "Editing process failed!" msgid "Editing process failed!"
msgstr "Schnitt gescheitert!" msgstr "Bearbeitung gescheitert!"
msgid "Editing process finished" msgid "Editing process finished"
msgstr "Schnitt beendet" msgstr "Bearbeitung beendet"
msgid "Press any key to cancel restart" msgid "Press any key to cancel restart"
msgstr "Taste drücken, um Neustart abzubrechen" msgstr "Taste drücken, um Neustart abzubrechen"

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: recording.c 3.11 2013/12/27 11:06:01 kls Exp $ * $Id: recording.c 3.13 2014/01/18 12:54:56 kls Exp $
*/ */
#include "recording.h" #include "recording.h"
@ -1519,8 +1519,11 @@ void cRecordings::DelByName(const char *FileName)
{ {
LOCK_THREAD; LOCK_THREAD;
cRecording *recording = GetByName(FileName); cRecording *recording = GetByName(FileName);
if (recording) { cRecording *dummy = NULL;
if (!recording)
recording = dummy = new cRecording(FileName); // allows us to use a FileName that is not in the Recordings list
cThreadLock DeletedRecordingsLock(&DeletedRecordings); cThreadLock DeletedRecordingsLock(&DeletedRecordings);
if (!dummy)
Del(recording, false); Del(recording, false);
char *ext = strrchr(recording->fileName, '.'); char *ext = strrchr(recording->fileName, '.');
if (ext) { if (ext) {
@ -1534,7 +1537,6 @@ void cRecordings::DelByName(const char *FileName)
delete recording; delete recording;
ChangeState(); ChangeState();
TouchUpdate(); TouchUpdate();
}
} }
void cRecordings::UpdateByName(const char *FileName) void cRecordings::UpdateByName(const char *FileName)
@ -1879,7 +1881,8 @@ bool cRecordingsHandlerEntry::Active(bool &Error)
// Clean up: // Clean up:
if (CopierFinishedOk && (Usage() & ruMove) != 0) { if (CopierFinishedOk && (Usage() & ruMove) != 0) {
cRecording Recording(FileNameSrc()); cRecording Recording(FileNameSrc());
Recording.Delete(); if (Recording.Delete())
Recordings.DelByName(Recording.FileName());
} }
Recordings.ChangeState(); Recordings.ChangeState();
Recordings.TouchUpdate(); Recordings.TouchUpdate();

30
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 3.0 2013/03/03 10:37:58 kls Exp $ * $Id: remux.c 3.1 2014/01/18 11:27:30 kls Exp $
*/ */
#include "remux.h" #include "remux.h"
@ -1004,6 +1004,7 @@ protected:
bool debug; bool debug;
bool newFrame; bool newFrame;
bool independentFrame; bool independentFrame;
int iFrameTemporalReferenceOffset;
public: public:
cFrameParser(void); cFrameParser(void);
virtual ~cFrameParser() {}; virtual ~cFrameParser() {};
@ -1017,6 +1018,7 @@ public:
void SetDebug(bool Debug) { debug = Debug; } void SetDebug(bool Debug) { debug = Debug; }
bool NewFrame(void) { return newFrame; } bool NewFrame(void) { return newFrame; }
bool IndependentFrame(void) { return independentFrame; } bool IndependentFrame(void) { return independentFrame; }
int IFrameTemporalReferenceOffset(void) { return iFrameTemporalReferenceOffset; }
}; };
cFrameParser::cFrameParser(void) cFrameParser::cFrameParser(void)
@ -1024,6 +1026,7 @@ cFrameParser::cFrameParser(void)
debug = true; debug = true;
newFrame = false; newFrame = false;
independentFrame = false; independentFrame = false;
iFrameTemporalReferenceOffset = 0;
} }
// --- cAudioParser ---------------------------------------------------------- // --- cAudioParser ----------------------------------------------------------
@ -1056,6 +1059,7 @@ class cMpeg2Parser : public cFrameParser {
private: private:
uint32_t scanner; uint32_t scanner;
bool seenIndependentFrame; bool seenIndependentFrame;
int lastIFrameTemporalReference;
public: public:
cMpeg2Parser(void); cMpeg2Parser(void);
virtual int Parse(const uchar *Data, int Length, int Pid); virtual int Parse(const uchar *Data, int Length, int Pid);
@ -1065,6 +1069,7 @@ cMpeg2Parser::cMpeg2Parser(void)
{ {
scanner = EMPTY_SCANNER; scanner = EMPTY_SCANNER;
seenIndependentFrame = false; seenIndependentFrame = false;
lastIFrameTemporalReference = -1; // invalid
} }
int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid) int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
@ -1089,10 +1094,25 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
scanner = OldScanner; scanner = OldScanner;
return tsPayload.Used() - TS_SIZE; return tsPayload.Used() - TS_SIZE;
} }
newFrame = true; uchar b1 = tsPayload.GetByte();
uchar b2 = tsPayload.GetByte();
int TemporalReference = (b1 << 2 ) + ((b2 & 0xC0) >> 6);
uchar FrameType = (b2 >> 3) & 0x07;
if (tsPayload.Find(0x000001B5)) { // Extension start code
if (((tsPayload.GetByte() & 0xF0) >> 4) == 0x08) { // Picture coding extension
tsPayload.GetByte(); tsPayload.GetByte();
uchar FrameType = (tsPayload.GetByte() >> 3) & 0x07; uchar PictureStructure = tsPayload.GetByte() & 0x03;
if (PictureStructure == 0x02) // bottom field
break;
}
}
newFrame = true;
independentFrame = FrameType == 1; // I-Frame independentFrame = FrameType == 1; // I-Frame
if (independentFrame) {
if (lastIFrameTemporalReference >= 0)
iFrameTemporalReferenceOffset = TemporalReference - lastIFrameTemporalReference;
lastIFrameTemporalReference = TemporalReference;
}
if (debug) { if (debug) {
seenIndependentFrame |= independentFrame; seenIndependentFrame |= independentFrame;
if (seenIndependentFrame) { if (seenIndependentFrame) {
@ -1457,7 +1477,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
for (int i = 0; i < numPtsValues; i++) for (int i = 0; i < numPtsValues; i++)
ptsValues[i] = ptsValues[i + 1] - ptsValues[i]; ptsValues[i] = ptsValues[i + 1] - ptsValues[i];
qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32); qsort(ptsValues, numPtsValues, sizeof(uint32_t), CmpUint32);
uint32_t Delta = ptsValues[0] / framesPerPayloadUnit; uint32_t Delta = ptsValues[0] / (framesPerPayloadUnit + parser->IFrameTemporalReferenceOffset());
// determine frame info: // determine frame info:
if (isVideo) { if (isVideo) {
if (abs(Delta - 3600) <= 1) if (abs(Delta - 3600) <= 1)
@ -1475,7 +1495,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
} }
else // audio else // audio
framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing framesPerSecond = double(PTSTICKS) / Delta; // PTS of audio frames is always increasing
dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1); dbgframes("\nDelta = %d FPS = %5.2f FPPU = %d NF = %d TRO = %d\n", Delta, framesPerSecond, framesPerPayloadUnit, numPtsValues + 1, parser->IFrameTemporalReferenceOffset());
synced = true; synced = true;
parser->SetDebug(false); parser->SetDebug(false);
} }

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 3.0 2013/01/20 11:43:59 kls Exp $ * $Id: remux.h 3.1 2014/01/16 10:15:50 kls Exp $
*/ */
#ifndef __REMUX_H #ifndef __REMUX_H
@ -462,7 +462,7 @@ void PesDump(const char *Name, const u_char *Data, int Length);
// Frame detector: // Frame detector:
#define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 5 #define MIN_TS_PACKETS_FOR_FRAME_DETECTOR 10
class cFrameParser; class cFrameParser;

View File

@ -19,57 +19,59 @@
# Europe # Europe
S3E Eutelsat 3A & Rascom 1R S3E Eutelsat 3A/3D & Rascom 1R
S4E Eurobird 4A S4E Eutelsat 4B
S4.8E Astra 4A S4.8E Astra 4A & SES 5
S7E Eutelsat W3A S7E Eutelsat 7A
S9E Eurobird 9A S9E Eutelsat 9A/Ka-Sat 9A
S10E Eutelsat W2A S10E Eutelsat 10A
S13E Hotbird 6/8/9 S13E Eutelsat Hot Bird 13B/13C/13D
S16E Eutelsat W2M & Eurobird 16A S16E Eutelsat 16A/16B
S19.2E Astra 1H/1KR/1L/1M/2C S17E Amos 5
S21.6E Eutelsat W6 S19.2E Astra 1KR/1L/1M/2C
S23.5E Astra 3A/3B S21.6E Eutelsat 21B
S25.5E Eurobird 2 S23.5E Astra 3B
S25.5E Eutelsat 25B
S26E Badr 4/5/6 S26E Badr 4/5/6
S28.2E Astra 2A/2B/2D S28.2E Astra 1N/2A/2F
S28.5E Eurobird 1 S28.5E Eutelsat 28A
S30.5E Arabsat 5A S30.5E Arabsat 5A
S31.5E Astra 1G S31.5E Astra 1G
S33E Eurobird 3 & Intelsat New Dawn S33E Eutelsat 33A & Intelsat 28
S36E Eutelsat W4/W7 S36E Eutelsat 36A/36B
S38E Paksat 1 S38E Paksat 1R
S39E Hellas Sat 2 S39E Hellas Sat 2
S40E Express AM1
S42E Turksat 2A/3A S42E Turksat 2A/3A
S45E Intelsat 12 S45E Intelsat 12
S46E Azerspace-1
S47.5E Intelsat 10
S49E Yamal 202 S49E Yamal 202
S52.5E Yahsat 1A
S53E Express AM22 S53E Express AM22
S55E Insat 3E S56E DirecTV 1R
S56E Bonum 1
S57E NSS 12 S57E NSS 12
S60E Intelsat 904 S60E Intelsat 904
S62E Intelsat 902 S62E Intelsat 902
S64E Intelsat 906 S64E Intelsat 906
S66E Intelsat 17 S66E Intelsat 17
S68.5E Intelsat 7/10 S68.5E Intelsat 7/10
S70.5E Eutelsat W5 S70.5E Eutelsat 70B
S72E Intelsat 709 S72E Intelsat 22
# Asia # Asia
S74E Insat 3C/4CR S74E Insat 3C/4CR
S75E ABS 1A S75E ABS 1A
S76.5E Apstar 2R S76.5E Apstar 7
S78.5E Thaicom 5 S78.5E Thaicom 5/6A
S80E Express AM2/MD1 S80E Express AM2
S83E Insat 2E/4A S83E Insat 4A
S85.2E Intelsat 15 S85.2E Intelsat 15 & Horizons 2
S87.5E Chinasat 5A S87.5E ChinaSat 12
S88E ST 1/2 S88E ST 2
S90E Yamal 201 S90E Yamal 201/300K
S91.5E Measat 3/3A S91.5E Measat 3/3A
S92.2E Chinasat 9 S92.2E ChinaSat 9
S93.5E Insat 3A/4B S93.5E Insat 3A/4B
S95E NSS 6 S95E NSS 6
S96.5E Express AM33 S96.5E Express AM33
@ -77,21 +79,22 @@ S100.5E Asiasat 5
S103E Express A2 S103E Express A2
S105.5E Asiasat 3S S105.5E Asiasat 3S
S108.2E Telkom 1 & NSS 11 & SES 7 S108.2E Telkom 1 & NSS 11 & SES 7
S110E N-Sat 110 & BSAT 2C/3A S110E N-Sat 110 & BSAT 3A/3C
S110.5E Chinasat 10 S110.5E ChinaSat 10
S113E Palapa D & Koreasat 5 S113E Palapa D & Koreasat 5
S116E Koreasat 6 S115.5E ChinaSat 6B
S116E ABS 7 & Koreasat 6
S118E Telkom 2 S118E Telkom 2
S119.5E Thaicom 4
S122.2E Asiasat 4 S122.2E Asiasat 4
S124E JCSAT 4A S124E JCSAT 4B
S125E Chinasat 6A S125E ChinaSat 6A
S128E JCSAT RA S128E JCSAT 3A
S132E Vinasat 1 & JCSAT5A S132E Vinasat 1/2 & JCSAT 5A
S134E Apstar 6 S134E Apstar 6
S138E Telstar 18 S138E Telstar 18
S140E Express AM3 S140E Express AM3
S144E Superbird C2 S144E Superbird C2
S146E ABS 5
S150E JCSAT 1B S150E JCSAT 1B
S152E Optus D2 S152E Optus D2
S154E JCSAT 2A S154E JCSAT 2A
@ -99,73 +102,73 @@ S156E Optus C1/D3
S160E Optus D1 S160E Optus D1
S162E Superbird B2 S162E Superbird B2
S164E Optus B3 S164E Optus B3
S166E Intelsat 8 S166E Intelsat 19
S169E Intelsat 5 S169E Intelsat 8
S172E GE 23 S172E Eutelsat 172A
S180E Intelsat 701 S180E Intelsat 18
S177W NSS 9 S177W NSS 9
# Atlantic # Atlantic
S1W Thor 5/6 & Intelsat 10-02 S1W Thor 5/6 & Intelsat 10-02
S4W Amos 2/3 S4W Amos 2/3
S5W Atlantic Bird 3 S5W Eutelsat 5 West A
S7W Nilesat 101/102/201 & Atlantic Bird 4A S7W Nilesat 101/201 & Eutelsat 7 West A
S8W Telecom 2D & Atlantic Bird 2 S8W Eutelsat 8 West A/C
S11W Express AM44 S11W Express AM44
S12.5W Atlantic Bird 1 S12.5W Eutelsat 12 West A
S14W Express A4 S14W Express A4
S15W Telstar 12 S15W Telstar 12
S18W Intelsat 901 S18W Intelsat 901
S20W NSS 5 S20W NSS 7
S22W NSS 7 S22W SES 4
S24.5W Intelsat 905 S24.5W Intelsat 905
S27.5W Intelsat 907 S27.5W Intelsat 907
S30W Hispasat 1C/1D/1E S30W Hispasat 1D/1E
S31.5W Intelsat 25 S31.5W Intelsat 25
S34.5W Intelsat 903 S34.5W Intelsat 903
S37.5W NSS 10 & Telstar 11N S37.5W NSS 10 & Telstar 11N
S40.5W NSS 806 S40.5W SES 6
S43W Intelsat 11 S43W Intelsat 11
S45W Intelsat 14 S45W Intelsat 14
S50W Intelsat 1R S50W Intelsat 1R
S53W Intelsat 707 S53W Intelsat 23
S55.5W Intelsat 805 S55.5W Intelsat 805
S58W Intelsat 9/16 S58W Intelsat 21
S61W Amazonas 1/2 S61W Amazonas 2/3
# America # America
S61.5W Echostar 12/15 S61.5W Echostar 16
S63W Telstar 14R S63W Telstar 14R
S65W Star One C1 S65W Star One C1
S67W AMC 4
S70W Star One C2 S70W Star One C2
S72W AMC 6 S72W AMC 6
S72.5W DirecTV 1R & Nimiq 5 S72.7W Nimiq 5
S74W Horizons 2 S75W Star One C3
S77W Echostar 1/8 S77W QuetzSat 1
S79W AMC 2/5
S82W Nimiq 4 S82W Nimiq 4
S83W AMC 9 S83W AMC 9
S84W Brasilsat B4 S84W Brasilsat B4
S85W AMC 16 S85W AMC 16
S85.1W XM 3 S85.1W XM 3
S87W AMC 3 S87W SES 2
S89W Galaxy 28 S89W Galaxy 28
S91W Galaxy 17 & Nimiq 1 S91W Galaxy 17 & Nimiq 6
S93W Galaxy 25 S93.1W Galaxy 25
S95W Galaxy 3C S95W Galaxy 3C
S97W Galaxy 19 S97W Galaxy 19
S99W Galaxy 16 S99.2W Galaxy 16
S99.2W Spaceway 2 & DirecTV 11
S101W DirecTV 4S/8 & SES 1 S101W DirecTV 4S/8 & SES 1
S103W AMC 1 S103W AMC 1
S105W AMC 15/18 S105W AMC 15/18
S107.3W Anik F1/F1R S107.3W Anik F1R/G1
S110W DirecTV 5 & Echostar 10/11 S110W DirecTV 5 & Echostar 10/11
S111.1W Anik F2 S111.1W Anik F2
S113W SatMex 6 S113W SatMex 6
S116.8W SatMex 5 S114.9W SatMex 5
S116.8W SatMex 8
S118.8W Anik F3 S118.8W Anik F3
S119W Echostar 14 & DirecTV 7S S119W Echostar 14 & DirecTV 7S
S121W Echostar 9/Galaxy 23 S121W Echostar 9/Galaxy 23
@ -174,7 +177,7 @@ S125W Galaxy 14 & AMC 21
S127W Galaxy 13/Horizons 1 S127W Galaxy 13/Horizons 1
S129W Ciel 2 S129W Ciel 2
S131W AMC 11 S131W AMC 11
S133W Galaxy 13/15 S133W Galaxy 15
S135W AMC 10 S135W AMC 10
S137W AMC 7 S137W AMC 7
S139W AMC 8 S139W AMC 8

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: status.c 3.0 2012/03/07 14:17:24 kls Exp $ * $Id: status.c 3.1 2014/01/25 10:47:39 kls Exp $
*/ */
#include "status.h" #include "status.h"
@ -23,6 +23,12 @@ cStatus::~cStatus()
statusMonitors.Del(this, false); statusMonitors.Del(this, false);
} }
void cStatus::MsgChannelChange(const cChannel *Channel)
{
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))
sm->ChannelChange(Channel);
}
void cStatus::MsgTimerChange(const cTimer *Timer, eTimerChange Change) void cStatus::MsgTimerChange(const cTimer *Timer, eTimerChange Change)
{ {
for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm)) for (cStatus *sm = statusMonitors.First(); sm; sm = statusMonitors.Next(sm))

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: status.h 3.0 2012/03/07 14:16:57 kls Exp $ * $Id: status.h 3.1 2014/01/25 10:47:39 kls Exp $
*/ */
#ifndef __STATUS_H #ifndef __STATUS_H
@ -24,6 +24,9 @@ private:
static cList<cStatus> statusMonitors; static cList<cStatus> statusMonitors;
protected: protected:
// These functions can be implemented by derived classes to receive status information: // These functions can be implemented by derived classes to receive status information:
virtual void ChannelChange(const cChannel *Channel) {}
// Indicates a change in the parameters of the given Channel that may
// require a retune.
virtual void TimerChange(const cTimer *Timer, eTimerChange Change) {} virtual void TimerChange(const cTimer *Timer, eTimerChange Change) {}
// Indicates a change in the timer settings. // Indicates a change in the timer settings.
// If Change is tcAdd or tcDel, Timer points to the timer that has // If Change is tcAdd or tcDel, Timer points to the timer that has
@ -85,6 +88,7 @@ public:
cStatus(void); cStatus(void);
virtual ~cStatus(); virtual ~cStatus();
// These functions are called whenever the related status information changes: // These functions are called whenever the related status information changes:
static void MsgChannelChange(const cChannel *Channel);
static void MsgTimerChange(const cTimer *Timer, eTimerChange Change); static void MsgTimerChange(const cTimer *Timer, eTimerChange Change);
static void MsgChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView); static void MsgChannelSwitch(const cDevice *Device, int ChannelNumber, bool LiveView);
static void MsgRecording(const cDevice *Device, const char *Name, const char *FileName, bool On); static void MsgRecording(const cDevice *Device, const char *Name, const char *FileName, bool On);

6
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.tvdr.de * The project's page is at http://www.tvdr.de
* *
* $Id: vdr.c 3.7 2013/12/25 11:24:26 kls Exp $ * $Id: vdr.c 3.9 2014/01/25 10:47:39 kls Exp $
*/ */
#include <getopt.h> #include <getopt.h>
@ -60,6 +60,7 @@
#include "skinsttng.h" #include "skinsttng.h"
#include "sourceparams.h" #include "sourceparams.h"
#include "sources.h" #include "sources.h"
#include "status.h"
#include "themes.h" #include "themes.h"
#include "timers.h" #include "timers.h"
#include "tools.h" #include "tools.h"
@ -810,6 +811,8 @@ int main(int argc, char *argv[])
if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT)) if (!cDevice::WaitForAllDevicesReady(DEVICEREADYTIMEOUT))
dsyslog("not all devices ready after %d seconds", DEVICEREADYTIMEOUT); dsyslog("not all devices ready after %d seconds", DEVICEREADYTIMEOUT);
if (!CamSlots.WaitForAllCamSlotsReady(DEVICEREADYTIMEOUT))
dsyslog("not all CAM slots ready after %d seconds", DEVICEREADYTIMEOUT);
if (*Setup.InitialChannel) { if (*Setup.InitialChannel) {
if (isnumber(Setup.InitialChannel)) { // for compatibility with old setup.conf files if (isnumber(Setup.InitialChannel)) { // for compatibility with old setup.conf files
if (cChannel *Channel = Channels.GetByNumber(atoi(Setup.InitialChannel))) if (cChannel *Channel = Channels.GetByNumber(atoi(Setup.InitialChannel)))
@ -922,6 +925,7 @@ int main(int argc, char *argv[])
} }
} }
} }
cStatus::MsgChannelChange(Channel);
} }
} }
Channels.Unlock(); Channels.Unlock();