Hi, Timo J. Rinne schrieb: > Posting to the mailing list seems to be for subscribers only and I'm > reading it only through archive. However ... > >> Reinhard Nissl schrieb: >> >> >>> Though, a cleaner solution would be to fix the result buffer to >> allow >>>>> retrieving any packet as soon as it is completely available in the >>>>> buffer (final subtitle packets are about 100 bytes in size). >>>> >>>> That sounds like the right thing to do. >>>> Can you suggest a patch for this? >>> >>> I hope to get something ready till tomorrow 12:00. >> See attachment. Tested in transfer mode with audio packets only (= >> radio), as there is no broadcast running which would provide >> subtitles. > > The picture doesn't freeze any longer. But after a while (5-10 minutes) > subtitles disappear. You'll have to provide some more information. Do you use subtitles with a FF card? Can you reproduce the issue in a recording? Did you apply all the posted fixes? Attached you'll find a single patch against vanilla VDR-1.5.11. It contains the remuxer fix and the ringbuffer extension, but also reverts some changes from 1.5.10 to 1.5.11 which should be addressed by the other two parts. I've just watched subtitles now for almost 2 hours on ZDF (ASTRA 19.2E) with vdr-xine without any issues. But vdr-xine works different (transfer mode) and may not see issues which happen with FF cards. Bye. -- Dipl.-Inform. (FH) Reinhard Nissl mailto:rnissl@xxxxxx
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-12 21:50:41.000000000 +0100 @@ -1749,14 +1749,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); @@ -1883,7 +1884,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 +1913,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@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr