Version 1.7.19

Original announce message:
VDR developer version 1.7.19 is now available at

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

A 'diff' against the previous version is available at

       ftp://ftp.tvdr.de/vdr/Developer/vdr-1.7.18-1.7.19.diff

MD5 checksums:

1eb04ecdc2b11ab8641ebfaa2cb93f42  vdr-1.7.19.tar.bz2
db16ce7bb51e0db837ed56ef4744a67e  vdr-1.7.18-1.7.19.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.

This version introduces functions to determine the "signal strength"
and "signal quality" through cDevice. If you are using a DVB card that
contains an stb0899 frontend chip (like the TT-budget S2-3200) you may
want to apply the patches from

   ftp://ftp.tvdr.de/vdr/Developer/Driver-Patches

to the LinuxDVB driver source in order to receive useful results from
that frontend.
Since apparently the various frontend drivers return different maximum
values in their FE_READ_SIGNAL_STRENGTH and FE_READ_SNR functions (some
deliver a value in the range 0x0000...0xFFFF, while others return values
as "dB/10" or "dBm/10" (the latter with an offset to make the value positive,
since the parameter is unsigned), the functions cDvbTuner::GetSignalStrength()
and cDvbTuner::GetSignalQuality() use the device's "subsystem ID" to
map these values into the range 0...100, which is the normalized return
value of these functions.
Take a look at these two functions and maybe remove the comment characters
from the lines
//#define DEBUG_SIGNALSTRENGTH
//#define DEBUG_SIGNALQUALITY
in dvbdevice.c to get some debug output if your device doesn't return any
directly useful values and may have to be added appropriately to the
'switch (subsystemId)' statement.
The channel display of the 'sttng' skin uses these values to implement
a signal strength/quality display.

From the HISTORY file:
- Fixed cString's operator=(const char *String) in case the given string is the
  same as the existing one (thanks to Dirk Leber).
- Avoiding a gcc 4.6 compiler error in the skincurses plugin (thanks to Tobias Grimm).
- TsGetPayload() now checks if there actually is a payload in the given TS packet
  (reported by Dirk Leber).
- Now sorting the source file names in the call to xgettext, to make sure the results
  are not dependent on the sequence of the files.
  Plugin authors may want to change the line containing the xgettext call in their
  Makefile accordingly by changing "$^" to "`ls $^`".
- The primary device is now only avoided for recording if it is an old SD full
  featured card. This is done through the new function cDevice::AvoidRecording().
- Subtitle PIDs are now also decrypted (thanks to Reinhard Nissl).
- Fixed a possible race condition in cDiseqc::Execute() (reported by Marco Göbenich).
  The return value of cDiseqcs::Get() is now const, so plugin authors may need to
  adjust their code if they use this function.
- The new functions cDevice::SignalStrength() and cDevice::SignalQuality() can be
  used to determine the signal strength and quality of a given device (thanks to
  Rolf Ahrenberg for some input on how to use BER and UNC values to generate a
  "quality" value).
- The 'sttng' skin now displays two colored bars at the bottom of the channel display,
  indicating the strength (upper bar) and quality (lower bar) of the received signal.
  The number to the left of these bars indicates the actual device the current
  channel is being received with.
- Fixed detecting frames in case the Picture Start Code or Access Unit Delimiter
  extends over TS packet boundaries (reported by Johan Andersson).
  In order to fix this, the semantics of cFrameDetector had to be changed a little.
  See cRecorder::Action() and cIndexFileGenerator::Action() on how to use the new
  cFrameDetector::NewPayload() function.
- The frame detector now only starts collecting PTS values after it has seen the
  first I-frame, otherwise it might get MaxPtsValues values and stop analyzing
  even though the incoming data is still garbage (reported by Derek Kelly).
- The info file of a recording is now only overwritten with a new fps value if
  that new value is not the default value (thanks to Derek Kelly for reporting a
  problem with the fps value being overwritten in case a recording was interrupted
  and resumed, and the fps value could not be determined after resuming recording).
- The initial channel is now stored by the channel ID in the setup.conf file, in
  order to avoid problems in case channels are reordered or deleted (reported by
  Lars Bläser).
- Added support for "content identifier descriptor" and "default authority descriptor"
  to 'libsi' (thanks to Dave Pickles).
This commit is contained in:
Klaus Schmidinger
2011-06-19 12:41:00 +02:00
committed by Dieter Hametner
parent 8b9350c091
commit bd61fee1e9
108 changed files with 968 additions and 397 deletions

69
remux.c
View File

@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: remux.c 2.53 2011/03/20 10:21:14 kls Exp $
* $Id: remux.c 2.57 2011/06/12 14:24:09 kls Exp $
*/
#include "remux.h"
@@ -12,6 +12,7 @@
#include "libsi/si.h"
#include "libsi/section.h"
#include "libsi/descriptor.h"
#include "recording.h"
#include "shutdown.h"
#include "tools.h"
@@ -781,7 +782,8 @@ cFrameDetector::cFrameDetector(int Pid, int Type)
{
SetPid(Pid, Type);
synced = false;
newFrame = independentFrame = false;
newPayload = newFrame = independentFrame = false;
frameTypeOffset = -1;
numPtsValues = 0;
numFrames = 0;
numIFrames = 0;
@@ -808,7 +810,8 @@ void cFrameDetector::SetPid(int Pid, int Type)
void cFrameDetector::Reset(void)
{
newFrame = independentFrame = false;
newPayload = newFrame = independentFrame = false;
frameTypeOffset = -1;
payloadUnitOfFrame = 0;
scanning = false;
scanner = EMPTY_SCANNER;
@@ -816,9 +819,8 @@ void cFrameDetector::Reset(void)
int cFrameDetector::Analyze(const uchar *Data, int Length)
{
int SeenPayloadStart = false;
int Processed = 0;
newFrame = independentFrame = false;
newPayload = newFrame = independentFrame = false;
while (Length >= TS_SIZE) {
if (Data[0] != TS_SYNC_BYTE) {
int Skipped = 1;
@@ -831,16 +833,13 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
int Pid = TsPid(Data);
if (Pid == pid) {
if (TsPayloadStart(Data)) {
SeenPayloadStart = true;
if (synced && Processed)
return Processed;
if (Length < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE)
return Processed; // need more data, in case the frame type is not stored in the first TS packet
return Processed; // flush everything before this new payload
if (framesPerSecond <= 0.0) {
// frame rate unknown, so collect a sequence of PTS values:
if (numPtsValues < MaxPtsValues && numIFrames < 2) { // collect a sequence containing at least two I-frames
const uchar *Pes = Data + TsPayloadOffset(Data);
if (PesHasPts(Pes)) {
if (numIFrames && PesHasPts(Pes)) {
ptsValues[numPtsValues] = PesGetPts(Pes);
// check for rollover:
if (numPtsValues && ptsValues[numPtsValues - 1] > 0xF0000000 && ptsValues[numPtsValues] < 0x10000000) {
@@ -885,8 +884,8 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
else
framesPerSecond = 60.0 / 1.001;
else {
framesPerSecond = 25.0;
dsyslog("unknown frame delta (%d), assuming 25 fps", Delta);
framesPerSecond = DEFAULTFRAMESPERSECOND;
dsyslog("unknown frame delta (%d), assuming %5.2f fps", Delta, DEFAULTFRAMESPERSECOND);
}
}
else // audio
@@ -900,6 +899,10 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
if (scanning) {
int PayloadOffset = TsPayloadOffset(Data);
if (TsPayloadStart(Data)) {
if (synced && Processed)
return Processed; // flush everything before this new payload
newPayload = true;
scanner = EMPTY_SCANNER;
PayloadOffset += PesPayloadOffset(Data + PayloadOffset);
if (!framesPerPayloadUnit)
framesPerPayloadUnit = framesInPayloadUnit;
@@ -907,17 +910,30 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
dbgframes("/");
}
for (int i = PayloadOffset; scanning && i < TS_SIZE; i++) {
scanner <<= 8;
scanner |= Data[i];
if (frameTypeOffset < 0) {
scanner <<= 8;
scanner |= Data[i];
}
else
frameTypeOffset += PayloadOffset;
switch (type) {
case 0x01: // MPEG 1 video
case 0x02: // MPEG 2 video
if (scanner == 0x00000100) { // Picture Start Code
if (frameTypeOffset < 0) {
frameTypeOffset = i + 2;
if (frameTypeOffset >= TS_SIZE) { // the byte to check is in the next TS packet
frameTypeOffset -= TS_SIZE;
if (!synced)
dbgframes("%d>", frameTypeOffset);
break;
}
}
scanner = EMPTY_SCANNER;
if (synced && !SeenPayloadStart && Processed)
return Processed; // flush everything before this new frame
newFrame = true;
independentFrame = ((Data[i + 2] >> 3) & 0x07) == 1; // I-Frame
uchar FrameType = (Data[frameTypeOffset] >> 3) & 0x07;
frameTypeOffset = -1;
independentFrame = FrameType == 1; // I-Frame
if (synced) {
if (framesPerPayloadUnit <= 1)
scanning = false;
@@ -928,7 +944,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
numIFrames++;
if (numIFrames == 1)
numFrames++;
dbgframes("%d ", (Data[i + 2] >> 3) & 0x07);
dbgframes("%u ", FrameType);
}
if (synced)
return Processed + TS_SIZE; // flag this new frame
@@ -936,11 +952,20 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
break;
case 0x1B: // MPEG 4 video
if (scanner == 0x00000109) { // Access Unit Delimiter
if (frameTypeOffset < 0) {
frameTypeOffset = i + 1;
if (frameTypeOffset >= TS_SIZE) { // the byte to check is in the next TS packet
frameTypeOffset -= TS_SIZE;
if (!synced)
dbgframes("%d>", frameTypeOffset);
break;
}
}
scanner = EMPTY_SCANNER;
if (synced && !SeenPayloadStart && Processed)
return Processed; // flush everything before this new frame
newFrame = true;
independentFrame = Data[i + 1] == 0x10;
uchar FrameType = Data[frameTypeOffset];
frameTypeOffset = -1;
independentFrame = FrameType == 0x10;
if (synced) {
if (framesPerPayloadUnit < 0) {
payloadUnitOfFrame = (payloadUnitOfFrame + 1) % -framesPerPayloadUnit;
@@ -958,7 +983,7 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
numIFrames++;
if (numIFrames == 1)
numFrames++;
dbgframes("%02X ", Data[i + 1]);
dbgframes("%02X ", FrameType);
}
if (synced)
return Processed + TS_SIZE; // flag this new frame