From patchwork Sun Nov 20 17:35:07 2005 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reinhard Nissl X-Patchwork-Id: 12098 Received: from mail.gmx.net ([213.165.64.20]) by www.linuxtv.org with smtp (Exim 4.50) id 1Edt6K-00035t-Pb for vdr@linuxtv.org; Sun, 20 Nov 2005 18:35:40 +0100 Received: (qmail invoked by alias); 20 Nov 2005 17:35:09 -0000 Received: from ambg-c34713f1.pool.mediaWays.net (EHLO [192.168.101.15]) [195.71.19.241] by mail.gmx.net (mp037) with SMTP; 20 Nov 2005 18:35:09 +0100 X-Authenticated: #527675 Message-ID: <4380B3CB.9070504@gmx.de> Date: Sun, 20 Nov 2005 18:35:07 +0100 From: Reinhard Nissl User-Agent: Mozilla Thunderbird 1.0.6 (X11/20050716) X-Accept-Language: en-us, en MIME-Version: 1.0 To: VDR Mailing List Subject: Re: [vdr] index.vdr misses pictures References: <200511061102.09445.ws@seh.de> <436DE1CA.7050408@gmx.de> <200511061213.34898.ws@seh.de> In-Reply-To: <200511061213.34898.ws@seh.de> X-Y-GMX-Trusted: 0 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Nov 2005 17:35:40 -0000 Status: O X-Status: X-Keywords: X-UID: 6268 Hi, Werner wrote: >>>in recent recording from premiere i saw that not all pictures in >>>the data stream are indexed in index.vdr. The displayed movie lenghts are >>>slightly to short and the cutmarks in marks.vdr are wrong. I use >>>marks.vdr in an external program. The resulting cutted movies are >>>sometimes about 1-2 minutes too short. This does not affect normal >>>vdr users too much because vdr cutted movies have the right len. >>> >>>Im not an mpeg expert, so only some speculations: >>>It looks that every index.vdr entry points to an "packet start code" >>>(0x000001). Vdr assumes that every packet has mostly one picture start >>>code. The difference i saw between old recordings and new recordings >>>is that in new recordings are sometimes two picture start codes in a >>>packet. The second one is dropped by vdr. >>>I have no idea of how to fix this assuming that vdr can only resume >>>on a packet start code. Anyone any idea? >> >>If you were right, then cVideoRepacker is buggy. Are you shure that you >>see two picture start codes (0x00000100) in one PES-Packet? > > yes, thats what i saw. My app demuxes the data stream (with the help > of some libmpeg2 code) and two printfs show that sometimes (<5%) there are > two picture start codes in a packet. In the sample you sent me, there really are two picture start codes in one PES packet. You've already got the attached patch which records a snipplet of the TS stream in such a case. Do you already have some test material, as I'm ready to replay and debug it? Bye. --- ../vdr-1.3.36-orig/remux.h 2005-08-26 15:22:19.000000000 +0200 +++ remux.h 2005-11-07 22:29:05.000000000 +0100 @@ -33,9 +33,11 @@ ePesHeader AnalyzePesHeader(const uchar #define MAXTRACKS 64 class cTS2PES; +class cTSLogger; class cRemux { private: +cTSLogger *tsLogger; bool exitOnFailure; bool isRadio; int numUPTerrors; @@ -65,6 +67,7 @@ public: int Put(const uchar *Data, int Count); ///< Puts at most Count bytes of Data into the remuxer. ///< \return Returns the number of bytes actually consumed from Data. + uchar *Get0(int &Count, uchar *PictureType = NULL); uchar *Get(int &Count, uchar *PictureType = NULL); ///< Gets all currently available data from the remuxer. ///< \return Count contains the number of bytes the result points to, and --- ../vdr-1.3.36-orig/remux.c 2005-09-11 15:26:50.000000000 +0200 +++ remux.c 2005-11-07 22:36:52.000000000 +0100 @@ -86,6 +86,60 @@ ePesHeader AnalyzePesHeader(const uchar return phMPEG1; // MPEG 1 } +// --- cTSLogger ------------------------------------------------------------- + +class cTSLogger +{ + uchar *buffer; + int size; + int fill; + int64_t count; + int dumps; + int cid; + +public: + cTSLogger(int Cid); + ~cTSLogger(); + void Put(const uchar *Data); + void Dump(); +}; + +cTSLogger::cTSLogger(int Cid) +{ + size = 1000; // number of TS packets to log + buffer = new uchar[size * 188]; + fill = 0; + count = 0; + dumps = 0; + cid = Cid; +} + +cTSLogger::~cTSLogger() +{ + delete [] buffer; +} + +void cTSLogger::Put(const uchar *Data) +{ + memcpy(&buffer[(count++ % size) * 188], Data, 188); + if (fill < size) + fill++; +} + +void cTSLogger::Dump() +{ + char name[200]; + sprintf(name, "/video/ts_%d_%ld_0x%02X_%03d_%lld_%d.log", getpid(), pthread_self(), cid, dumps++, count, fill); + esyslog("cTSLogger: dumping to file '%s'", name); + + FILE *f = fopen(name, "wb"); + for (int64_t n = count - fill; n < count; n++) + fwrite(&buffer[(n % size) * 188], 188, 1, f); + fclose(f); + + fill = 0; +} + // --- cRepacker ------------------------------------------------------------- class cRepacker { @@ -1675,6 +1731,7 @@ void cTS2PES::ts_to_pes(const uint8_t *B cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) { +tsLogger = new cTSLogger(0xe0); exitOnFailure = ExitOnFailure; isRadio = VPid == 0 || VPid == 1 || VPid == 0x1FFF; numUPTerrors = 0; @@ -1722,6 +1779,7 @@ cRemux::~cRemux() for (int t = 0; t < numTracks; t++) delete ts2pes[t]; delete resultBuffer; +delete tsLogger; } int cRemux::GetPid(const uchar *Data) @@ -1793,6 +1851,7 @@ int cRemux::Put(const uchar *Data, int C if (Data[i + 3] & 0x10) { // got payload for (int t = 0; t < numTracks; t++) { if (ts2pes[t]->Pid() == pid) { +if (t == 0) tsLogger->Put(Data + i); ts2pes[t]->ts_to_pes(Data + i); break; } @@ -1818,6 +1877,52 @@ int cRemux::Put(const uchar *Data, int C uchar *cRemux::Get(int &Count, uchar *PictureType) { + uchar *r = Get0(Count, PictureType); + + int n = 0; + while (r && n < Count) + { + if (r[ n + 0 ] != 0x00 + || r[ n + 1 ] != 0x00 + || r[ n + 2 ] != 0x01) + { + esyslog("out of sync ======================"); + break; + } + + int l = 6 + r[ n + 4 ] * 256 + r[ n + 5 ]; + if ((r[ n + 3 ] & 0xf0) != 0xe0) + { + n += l; + continue; + } + + ulong scanner = 0xffffffff; + int k = 0; + + int o = 6 + 3 + r[ n + 8 ]; + for (int i = o; i < l; i++) + { + scanner <<= 8; + scanner |= r[ n + i ]; + + if (scanner == 0x00000100) + { + k++; + + if (k > 1) + tsLogger->Dump(); + } + } + + n += l; + } + + return r; +} + +uchar *cRemux::Get0(int &Count, uchar *PictureType) +{ // Remove any previously skipped data from the result buffer: if (resultSkipped > 0) {