Version 2.1.5

VDR developer version 2.1.5 is now available at

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

A 'diff' against the previous version is available at

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

MD5 checksums:

ce561eef64c13e24e4817f70a6d9d5b0  vdr-2.1.5.tar.bz2
f433e78d90bc414bd9d858ca6e58e539  vdr-2.1.4-2.1.5.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:
- Now checking whether the primary device actually has a decoder before retuning the
  current channel after a change in its parameters. This fixes broken recordings on
  the primary device on "headless" systems.
- Increased MIN_TS_PACKETS_FOR_FRAME_DETECTOR to 100 and introduced counting the number
  of actual video TS packets in cTsPayload in order to be able to record channels that
  sometimes need even more than 10 TS packets for detecting frame borders (reported by
  Oliver Endriss).
- Fixed sorting recordings by time in the Recordings menu if "Setup/OSD/Recording
  directories" is set to "no".
- Fixed clearing non-editable members in the channel editor (thanks to Rolf Ahrenberg).
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- Further clarified the semantics of cCamSlot::Decrypt().
- Fixed flickering if subtitles are active while the OSD demo is running.
- Fixed numbering frames. Previously they were numbered starting from 1, while it
  is apparently standard to number them from 0. Any existing recordings with editing
  marks (which will now be off by one) can still be cut with all VDR versions from
  1.7.32, because these will automatically adjust editing marks to I-frames.
  Users of stable releases shouldn't notice any problems.
- Fixed a possible crash in the OSD demo (reported by Christopher Reimer).
- Fixed some compiler warnings with Clang 3.4.1 (reported by Paul Menzel).
- Added LinkageTypePremiere to libsi/si.h and eit.c to avoid a compiler warning with
  Clang 3.4.1 (suggested by Tony Houghten).
- Replaced the NULL pointer assignment in ~cReceiver() to force a segfault with
  a call to abort() (suggested by Tony Houghten).
- Fixed learning keyboard remote control codes (thanks to Lars Hanisch).
- Improved PAT/PMT scanning to speed up initial tuning to encrypted channels on
  transponders with many PAT entries (reported by Mariusz Bialonczyk).
- Fixed the replay progress display for very long recordings.
- Fixed detecting broken video data streams when recording.
- Fixed handling frame detection buffer length (reported by Eike Sauer).
This commit is contained in:
Klaus Schmidinger
2014-02-23 14:12:00 +01:00
committed by Dieter Hametner
parent 67e322b0dd
commit 797dc7d1a1
29 changed files with 307 additions and 176 deletions

60
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 3.1 2014/01/18 11:27:30 kls Exp $
* $Id: remux.c 3.3 2014/02/21 11:51:55 kls Exp $
*/
#include "remux.h"
@@ -23,6 +23,10 @@ static bool DebugFrames = false;
#define dbgpatpmt(a...) if (DebugPatPmt) fprintf(stderr, a)
#define dbgframes(a...) if (DebugFrames) fprintf(stderr, a)
#define MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION 6
#define WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION (MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION / 2)
#define WRN_TS_PACKETS_FOR_FRAME_DETECTOR (MIN_TS_PACKETS_FOR_FRAME_DETECTOR / 2)
#define EMPTY_SCANNER (0xFFFFFFFF)
ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader)
@@ -231,7 +235,7 @@ cTsPayload::cTsPayload(void)
data = NULL;
length = 0;
pid = -1;
index = 0;
Reset();
}
cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
@@ -239,12 +243,25 @@ cTsPayload::cTsPayload(uchar *Data, int Length, int Pid)
Setup(Data, Length, Pid);
}
uchar cTsPayload::SetEof(void)
{
length = index; // triggers EOF
return 0x00;
}
void cTsPayload::Reset(void)
{
index = 0;
numPacketsPid = 0;
numPacketsOther = 0;
}
void cTsPayload::Setup(uchar *Data, int Length, int Pid)
{
data = Data;
length = Length;
pid = Pid >= 0 ? Pid : TsPid(Data);
index = 0;
Reset();
}
uchar cTsPayload::GetByte(void)
@@ -255,20 +272,20 @@ uchar cTsPayload::GetByte(void)
if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end
uchar *p = data + index;
if (TsPid(p) == pid) { // only handle TS packets for the initial PID
if (numPacketsPid++ > MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
return SetEof();
if (TsHasPayload(p)) {
if (index > 0 && TsPayloadStart(p)) { // checking index to not skip the very first TS packet
length = index; // triggers EOF
return 0x00;
}
if (index > 0 && TsPayloadStart(p)) // checking index to not skip the very first TS packet
return SetEof();
index += TsPayloadOffset(p);
break;
}
}
else
numPacketsOther++;
}
else {
length = index; // triggers EOF
return 0x00;
}
else
return SetEof();
}
}
return data[index++];
@@ -302,6 +319,8 @@ void cTsPayload::SetByte(uchar Byte, int Index)
bool cTsPayload::Find(uint32_t Code)
{
int OldIndex = index;
int OldNumPacketsPid = numPacketsPid;
int OldNumPacketsOther = numPacketsOther;
uint32_t Scanner = EMPTY_SCANNER;
while (!Eof()) {
Scanner = (Scanner << 8) | GetByte();
@@ -309,9 +328,19 @@ bool cTsPayload::Find(uint32_t Code)
return true;
}
index = OldIndex;
numPacketsPid = OldNumPacketsPid;
numPacketsOther = OldNumPacketsOther;
return false;
}
void cTsPayload::Statistics(void) const
{
if (numPacketsPid + numPacketsOther > WRN_TS_PACKETS_FOR_FRAME_DETECTOR)
dsyslog("WARNING: required (%d+%d) TS packets to determine frame type", numPacketsOther, numPacketsPid);
if (numPacketsPid > WRN_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION)
dsyslog("WARNING: required %d video TS packets to determine frame type", numPacketsPid);
}
// --- cPatPmtGenerator ------------------------------------------------------
cPatPmtGenerator::cPatPmtGenerator(const cChannel *Channel)
@@ -1120,11 +1149,11 @@ int cMpeg2Parser::Parse(const uchar *Data, int Length, int Pid)
dbgframes("%c", FrameTypes[FrameType]);
}
}
tsPayload.Statistics();
break;
}
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
|| tsPayload.Eof()) // or if we're out of data
break;
}
return tsPayload.Used();
@@ -1266,6 +1295,8 @@ int cH264Parser::Parse(const uchar *Data, int Length, int Pid)
case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) {
ParseSliceHeader();
gotAccessUnitDelimiter = false;
if (newFrame)
tsPayload.Statistics();
return tsPayload.Used();
}
break;
@@ -1273,8 +1304,7 @@ int cH264Parser::Parse(const uchar *Data, int Length, int Pid)
}
}
if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary
|| (tsPayload.Available() < MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE // stop if the available data is below the limit...
&& (tsPayload.Available() <= 0 || tsPayload.AtTsStart()))) // ...but only if there is no more data at all, or if we are at a TS boundary
|| tsPayload.Eof()) // or if we're out of data
break;
}
return tsPayload.Used();