summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS2
-rw-r--r--HISTORY4
-rw-r--r--remux.c28
-rw-r--r--ringbuffer.c18
-rw-r--r--ringbuffer.h9
5 files changed, 50 insertions, 11 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 5eeff57d..60a99e72 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1150,6 +1150,8 @@ Reinhard Nissl <rnissl@gmx.de>
attached to a device
for reporting a missing SetVolumeDevice() call in cDevice::SetPrimaryDevice()
for fixing assembling PS1 packets in cTS2PES::instant_repack()
+ for a patch that was used to fix handling small PES packets that caused subtitles
+ to be displayed late in live mode
Richard Robson <richard_robson@beeb.net>
for reporting freezing replay if a timer starts while in Transfer Mode from the
diff --git a/HISTORY b/HISTORY
index 89e0614d..40451bd1 100644
--- a/HISTORY
+++ b/HISTORY
@@ -5519,8 +5519,10 @@ Video Disk Recorder Revision History
- Fixed decoding filename characters in case there are not two hex digits after
the '#' (reported by Helmut Auer).
-2007-11-10: Version 1.5.12
+2007-11-17: Version 1.5.12
- Fixed assembling PS1 packets in cTS2PES::instant_repack() (thanks to Reinhard
Nissl).
- Updated the Russian OSD texts (thanks to Oleg Roitburd).
+- Fixed handling small PES packets that caused subtitles to be displayed late
+ in live mode (based on a patch from Reinhard Nissl).
diff --git a/remux.c b/remux.c
index a658e194..416ec1cd 100644
--- a/remux.c
+++ b/remux.c
@@ -11,7 +11,7 @@
* The cRepacker family's code was originally written by Reinhard Nissl <rnissl@gmx.de>,
* and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de.
*
- * $Id: remux.c 1.61 2007/11/10 13:36:47 kls Exp $
+ * $Id: remux.c 1.62 2007/11/17 13:49:34 kls Exp $
*/
#include "remux.h"
@@ -1870,6 +1870,30 @@ void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188)
instant_repack(Buf + 4 + off, TS_SIZE - 4 - off);
}
+// --- cRingBufferLinearPes --------------------------------------------------
+
+class cRingBufferLinearPes : public cRingBufferLinear {
+protected:
+ virtual int DataReady(const uchar *Data, int Count);
+public:
+ cRingBufferLinearPes(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL)
+ :cRingBufferLinear(Size, Margin, Statistics, Description) {}
+ };
+
+int cRingBufferLinearPes::DataReady(const uchar *Data, int Count)
+{
+ int c = cRingBufferLinear::DataReady(Data, Count);
+ if (!c) {
+ const uchar *p = Data;
+ if (Count >= 6 && !p[0] && !p[1] && p[2] == 0x01) {
+ int Length = 6 + p[4] * 256 + p[5];
+ if (Length <= Count)
+ return Length;
+ }
+ }
+ return c;
+}
+
// --- cRemux ----------------------------------------------------------------
#define RESULTBUFFERSIZE KILOBYTE(256)
@@ -1883,7 +1907,7 @@ cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, b
skipped = 0;
numTracks = 0;
resultSkipped = 0;
- resultBuffer = new cRingBufferLinear(RESULTBUFFERSIZE, IPACKS, false, "Result");
+ resultBuffer = new cRingBufferLinearPes(RESULTBUFFERSIZE, IPACKS, false, "Result");
resultBuffer->SetTimeouts(0, 100);
if (VPid)
#define TEST_cVideoRepacker
diff --git a/ringbuffer.c b/ringbuffer.c
index 0633bd37..d74706ab 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -7,7 +7,7 @@
* Parts of this file were inspired by the 'ringbuffy.c' from the
* LinuxDVB driver (see linuxtv.org).
*
- * $Id: ringbuffer.c 1.24 2006/06/16 09:32:13 kls Exp $
+ * $Id: ringbuffer.c 1.25 2007/11/17 13:49:34 kls Exp $
*/
#include "ringbuffer.h"
@@ -187,6 +187,11 @@ cRingBufferLinear::~cRingBufferLinear()
free(description);
}
+int cRingBufferLinear::DataReady(const uchar *Data, int Count)
+{
+ return Count >= margin ? Count : 0;
+}
+
int cRingBufferLinear::Available(void)
{
int diff = head - tail;
@@ -284,7 +289,6 @@ int cRingBufferLinear::Put(const uchar *Data, int Count)
uchar *cRingBufferLinear::Get(int &Count)
{
- uchar *p = NULL;
int Head = head;
if (getThreadTid <= 0)
getThreadTid = cThread::ThreadId();
@@ -299,13 +303,13 @@ uchar *cRingBufferLinear::Get(int &Count)
int cont = (diff >= 0) ? diff : Size() + diff - margin;
if (cont > rest)
cont = rest;
- if (cont >= margin) {
- p = buffer + tail;
+ uchar *p = buffer + tail;
+ if ((cont = DataReady(p, cont)) > 0) {
Count = gotten = cont;
+ return p;
}
- if (!p)
- WaitForGet();
- return p;
+ WaitForGet();
+ return NULL;
}
void cRingBufferLinear::Del(int Count)
diff --git a/ringbuffer.h b/ringbuffer.h
index dba0e619..f6664cf8 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ringbuffer.h 1.17 2005/12/10 10:54:51 kls Exp $
+ * $Id: ringbuffer.h 1.18 2007/11/17 13:49:34 kls Exp $
*/
#ifndef __RINGBUFFER_H
@@ -60,6 +60,13 @@ private:
int gotten;
uchar *buffer;
char *description;
+protected:
+ virtual int DataReady(const uchar *Data, int Count);
+ ///< By default a ring buffer has data ready as soon as there are at least
+ ///< 'margin' bytes available. A derived class can reimplement this function
+ ///< if it has other conditions that define when data is ready.
+ ///< The return value is either 0 if there is not yet enough data available,
+ ///< or the number of bytes from the beginning of Data that are "ready".
public:
cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL);
///< Creates a linear ring buffer.