Hi,

Timo J. Rinne schrieb:

>> Anyways, it's been on for 25 minutes so far and has worked perfectly.
>> If I notice something in contrary to this, I'll report further.
> 
> Nope, it still doesn't quite work.  In live mode it seems to skip
> subtitles every now and then.  It even seems to depend on the program.
> Today I watched something and saw maybe one subtitle of ten.  Sometimes
> it seems to work more or less perfectly.
> 
> When I recorded the program that in live mode didn't work too well, the
> subtitles were fine in playback.
> 
> I have ff card and I think the problems are present mainly (if not only)
> in direct live mode.  When I forced it to transport mode by
> simultaneously recording an encrypted channel and watching fta channel
> live (transport mode), subtitles showed OK.

Please try the attached patch on a vanilla VDR-1.5.11. It should write
the subtitle TS and PES packets to separate files at /video. The
additionally recorded timestamps of your system time and the primary
device's STC should allow us to determine whether the packets arrive in
time and get properly remuxed.

Once you've seen enough anomalies, please provide us (a link to) the files.

BTW: the patch is almost untested as there are currently no subtitles
running.

Bye.
-- 
Dipl.-Inform. (FH) Reinhard Nissl
mailto:[EMAIL PROTECTED]
diff -Nurp ../vdr-1.5.11-orig/device.c ./device.c
--- ../vdr-1.5.11-orig/device.c	2007-11-03 14:30:09.000000000 +0100
+++ ./device.c	2007-11-12 21:57:36.000000000 +0100
@@ -210,7 +210,7 @@ int cPesAssembler::PacketSize(const ucha
 #define DEFAULTPRIORITY  -1
 
 // The minimum number of unknown PS1 packets to consider this a "pre 1.3.19 private stream":
-#define MIN_PRE_1_3_19_PRIVATESTREAM 10
+#define MIN_PRE_1_3_19_PRIVATESTREAM 0 /*10*/
 
 int cDevice::numDevices = 0;
 int cDevice::useDevice = 0;
diff -Nurp ../vdr-1.5.11-orig/remux.c ./remux.c
--- ../vdr-1.5.11-orig/remux.c	2007-11-03 15:18:07.000000000 +0100
+++ ./remux.c	2007-11-15 23:02:54.000000000 +0100
@@ -1387,6 +1387,51 @@ int cDolbyRepacker::BreakAt(const uchar 
   return -1;
 }
 
+class cLogger {
+  static int instance;
+  FILE *logFileTS;
+  FILE *logFilePES;
+  static void Store(FILE *LogFile, const uchar *Data, int Count);
+public:
+  cLogger(void);
+  ~cLogger();
+  void PutTS(const uchar *Data) { Store(logFileTS, Data, 188); }
+  void PutPES(const uchar *Data, int Count) { Store(logFilePES, Data, Count); }
+  };
+
+int cLogger::instance = 0;
+
+cLogger::cLogger(void)
+{
+  int Instance = instance++;
+  char FileNameTS[200];
+  sprintf(FileNameTS, "/video/subtitle_log_%d_%02d.ts", getpid(), Instance);
+  logFileTS = fopen(FileNameTS, "wb");
+  char FileNamePES[200];
+  sprintf(FileNamePES, "/video/subtitle_log_%d_%02d.pes", getpid(), Instance);
+  logFilePES = fopen(FileNamePES, "wb");
+}
+
+cLogger::~cLogger()
+{
+  fclose(logFileTS);
+  fclose(logFilePES);
+}
+
+#include <sys/time.h>
+#include "device.h"
+
+void cLogger::Store(FILE *LogFile, const uchar *Data, int Count)
+{
+  timeval tv;
+  gettimeofday(&tv, 0);
+  int64_t stc = cDevice::PrimaryDevice()->GetSTC();
+  fwrite(&tv, sizeof (tv), 1, LogFile);
+  fwrite(&stc, sizeof (stc), 1, LogFile);
+  fwrite(Data, Count, 1, LogFile);
+  fflush(LogFile);
+}
+
 // --- cTS2PES ---------------------------------------------------------------
 
 #include <netinet/in.h>
@@ -1474,12 +1519,14 @@ public:
   int Pid(void) { return pid; }
   void ts_to_pes(const uint8_t *Buf); // don't need count (=188)
   void Clear(void);
+cLogger *logger;
   };
 
 uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 };
 
 cTS2PES::cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t RewriteCid, uint8_t SubStreamId, cRepacker *Repacker)
 {
+logger = (Repacker ? 0 : new cLogger);
   pid = Pid;
   resultBuffer = ResultBuffer;
   size = Size;
@@ -1504,6 +1551,7 @@ cTS2PES::cTS2PES(int Pid, cRingBufferLin
 
 cTS2PES::~cTS2PES()
 {
+delete logger;
   if (tsErrors || ccErrors)
      dsyslog("cTS2PES got %d TS errors, %d TS continuity errors", tsErrors, ccErrors);
   free(buf);
@@ -1519,6 +1567,7 @@ void cTS2PES::Clear(void)
 
 void cTS2PES::store(uint8_t *Data, int Count)
 {
+if (logger) logger->PutPES(Data, Count);
   if (repacker)
      repacker->Repack(resultBuffer, Data, Count);
   else
@@ -1749,14 +1798,15 @@ void cTS2PES::instant_repack(const uint8
        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
        case PRIVATE_STREAM1:
-
-            if (mpeg == 2 && found == 9) {
+            /* make sure to not write the data twice by looking at count */
+            if (mpeg == 2 && found == 9 && count < found) {
                write_ipack(&flag1, 1);
                write_ipack(&flag2, 1);
                write_ipack(&hlength, 1);
                }
 
-            if (mpeg == 1 && found == mpeg1_required) {
+            /* make sure to not write the data twice by looking at count */
+            if (mpeg == 1 && found == mpeg1_required && count < found) {
                write_ipack(&flag1, 1);
                if (mpeg1_required > 7) {
                   write_ipack(&flag2, 1);
@@ -1826,7 +1876,7 @@ void cTS2PES::ts_to_pes(const uint8_t *B
 {
   if (!Buf)
      return;
-
+if (logger) logger->PutTS(Buf);
   if (Buf[1] & TS_ERROR)
      tsErrors++;
 
@@ -1883,7 +1933,7 @@ cRemux::cRemux(int VPid, const int *APid
   skipped = 0;
   numTracks = 0;
   resultSkipped = 0;
-  resultBuffer = new cRingBufferLinear(RESULTBUFFERSIZE, IPACKS, false, "Result");
+  resultBuffer = new cRingBufferLinear(RESULTBUFFERSIZE, IPACKS, false, "Result", true);
   resultBuffer->SetTimeouts(0, 100);
   if (VPid)
 #define TEST_cVideoRepacker
@@ -1912,7 +1962,7 @@ cRemux::cRemux(int VPid, const int *APid
   if (SPids) {
      int n = 0;
      while (*SPids && numTracks < MAXTRACKS && n < MAXSPIDS)
-           ts2pes[numTracks++] = new cTS2PES(*SPids++, resultBuffer, SUBTITLE_PACKS, 0x00, 0x20 + n++);
+           ts2pes[numTracks++] = new cTS2PES(*SPids++, resultBuffer, IPACKS /*SUBTITLE_PACKS*/, 0x00, 0x20 + n++);
      }
 }
 
diff -Nurp ../vdr-1.5.11-orig/ringbuffer.c ./ringbuffer.c
--- ../vdr-1.5.11-orig/ringbuffer.c	2006-06-16 11:32:13.000000000 +0200
+++ ./ringbuffer.c	2007-11-10 21:05:47.000000000 +0100
@@ -151,9 +151,10 @@ void cRingBufferLinear::PrintDebugRBL(vo
   }
 #endif
 
-cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics, const char *Description)
+cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics, const char *Description, bool AssumePesContent)
 :cRingBuffer(Size, Statistics)
 {
+  assumePesContent = AssumePesContent;
   description = Description ? strdup(Description) : NULL;
   tail = head = margin = Margin;
   gotten = 0;
@@ -299,7 +300,7 @@ uchar *cRingBufferLinear::Get(int &Count
   int cont = (diff >= 0) ? diff : Size() + diff - margin;
   if (cont > rest)
      cont = rest;
-  if (cont >= margin) {
+  if (cont >= margin || assumePesContent && HasPesPacket(cont)) {
      p = buffer + tail;
      Count = gotten = cont;
      }
@@ -308,6 +309,19 @@ uchar *cRingBufferLinear::Get(int &Count
   return p;
 }
 
+bool cRingBufferLinear::HasPesPacket(int &Count)
+{
+  uchar *p = buffer + tail;
+  if (Count >= 6 && !p[0] && !p[1] && p[2] == 0x01) {
+     int Length = 6 + p[4] * 256 + p[5];
+     if (Length <= Count) {
+        Count = Length;
+        return true;
+        }
+     }
+  return false;
+}
+
 void cRingBufferLinear::Del(int Count)
 {
   if (Count > gotten) {
diff -Nurp ../vdr-1.5.11-orig/ringbuffer.h ./ringbuffer.h
--- ../vdr-1.5.11-orig/ringbuffer.h	2005-12-10 11:54:51.000000000 +0100
+++ ./ringbuffer.h	2007-11-10 21:05:47.000000000 +0100
@@ -60,12 +60,17 @@ private:
   int gotten;
   uchar *buffer;
   char *description;
+  bool assumePesContent;
+  bool HasPesPacket(int &Count);
 public:
-  cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL);
+  cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL, bool AssumePesContent = false);
     ///< Creates a linear ring buffer.
     ///< The buffer will be able to hold at most Size-Margin-1 bytes of data, and will
     ///< be guaranteed to return at least Margin bytes in one consecutive block.
     ///< The optional Description is used for debugging only.
+    ///< AssumePesContent specializes the buffer and changes its behavior when less
+    ///< than Margin bytes are available. The buffer is then allowed to return at
+    ///< least a complete PES packet.
   virtual ~cRingBufferLinear();
   virtual int Available(void);
   virtual int Free(void) { return Size() - Available() - 1 - margin; }
_______________________________________________
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

Reply via email to