Hi!

This patch does two things: add the new sequence number handling code
(Ralph: please remove the "seqno" patch before you apply this one), and
add a correction procedure for video presentation timestamps.

The latter is only executed if the PTS is off by at most ±1%. In all
other cases, the error is reported but not corrected. That is, if you
see a message like this:

        inconsistent video PTS (<number>), NOT correcting

the output file will not be suitable for processing by dvdauthor.

If you see some gazillions of "inconsistent video PTS" messages with
mostly identical numbers, the first timestamp (which is used as the
reference throughout the file) was probably wrong. That shouldn't cause
any harm, however, as long as none of the messages says "NOT correcting"
at the end.

Can someone please check if this patch also solves the "ARD problem"?

-- 
Michael "Tired" Riepe <[EMAIL PROTECTED]>
X-Tired: Each morning I get up I die a little
Index: dvbcut/src/index.cpp
===================================================================
RCS file: /var/cvs/sys/qt3/dvbcut/src/index.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- dvbcut/src/index.cpp        24 Aug 2006 23:57:04 -0000      1.3
+++ dvbcut/src/index.cpp        2 Sep 2006 19:25:16 -0000       1.4
@@ -102,8 +102,11 @@
   int seqheaderpic=0;
   pts_t referencepts=0; // pts of picture #0 in current sequence
   int maxseqnr=-1; // maximum sequence number in current sequence
-  std::list<std::pair<int,int> > curseqnumbers; // seqnr->picnr relation for 
current sequence
   pts_t lastpts=1ll<<31;
+  int last_non_b_pic = -1;
+  int last_non_b_seqnr = -1;
+  int last_seqnr = -1;
+  int ptsmod = -1;
 
   while (mpg.streamreader(s)>0) {
     while (sd->getbuffer().inbytes()< (sd->getbuffer().getsize()/2))
@@ -149,6 +152,12 @@
 
       if (*(uint32_t*)(data+skip)==mbo32(0x000001b3)) // sequence header
         {
+        if (last_non_b_pic >= 0) {
+          p[last_non_b_pic].setsequencenumber(++maxseqnr);
+          last_non_b_pic = -1;
+          }
+       last_seqnr = -1;
+
         waitforfirstsequenceheader=false;
         foundseqheader=true;
         sd->discard(skip);
@@ -166,16 +175,6 @@
         inbytes=sd->inbytes();
         skip=0;
 
-        // ensure that sequence numbers are okay in the last sequence
-        if (!curseqnumbers.empty())
-          {
-          curseqnumbers.sort();
-          int n=0;
-          for(std::list<std::pair<int,int> >::iterator 
it=curseqnumbers.begin();it!=curseqnumbers.end();++it)
-            p[it->second].setsequencenumber(n++);
-          curseqnumbers.clear();
-          }
-
         } else if 
((*(uint32_t*)(data+skip)==mbo32(0x00000100))&&!waitforfirstsequenceheader) // 
picture header
         {
         sd->discard(skip);
@@ -183,8 +182,6 @@
 
         filepos_t picpos=sd->itemlist().front().fileposition;
         int seqnr=(data[4]<<2)|((data[5]>>6)&3);
-        if (seqnr>maxseqnr)
-          maxseqnr=seqnr;
         int frametype=(data[5]>>3)&7;
         if (frametype>3)
           frametype=0;
@@ -192,6 +189,22 @@
         pts_t pts=sd->itemlist().front().headerpts();
         if (pts>=0)
           {
+          int ptsdelta = mpgfile::frameratescr[framerate] / 300;
+          int epsilon = ptsdelta / 100;        /* allow at most 1% deviation */
+          int mod = pts % ptsdelta;
+          if (ptsmod == -1)
+           ptsmod = mod;
+          else if (mod != ptsmod) {
+           int error = (mod - ptsmod + ptsdelta) % ptsdelta;
+           if (error > ptsdelta / 2)
+             error -= ptsdelta;
+           if (-epsilon <= error && error <= epsilon) {
+             fprintf(stderr, "inconsistent video PTS (%+d), correcting\n", 
error);
+             pts -= error;
+             } else {
+             fprintf(stderr, "inconsistent video PTS (%+d), NOT correcting\n", 
error);
+             }
+           }
           referencepts=pts-(seqnr*mpgfile::frameratescr[framerate])/300;
           sd->discardheader();
           } else
@@ -205,8 +218,39 @@
           p=(picture*)realloc((void*)p,size*sizeof(picture));
           }
 
-        curseqnumbers.push_back(std::pair<int,int>(seqnr,pictures));
-        
p[pictures++]=picture(foundseqheader?seqheaderpos:picpos,pts,framerate,aspectratio,seqnr,frametype,foundseqheader);
+        
p[pictures]=picture(foundseqheader?seqheaderpos:picpos,pts,framerate,aspectratio,seqnr,frametype,foundseqheader);
+
+        if (frametype == IDX_PICTYPE_B) {
+         /* check sequence number */
+         if (seqnr != last_seqnr + 1) {
+           fprintf(stderr,
+             "missing frame(s) before B frame %d (%d != %d)\n",
+             pictures, seqnr, last_seqnr + 1);
+           if (last_non_b_pic >= 0) {
+             p[last_non_b_pic].setsequencenumber(++maxseqnr);
+             last_non_b_pic = -1;
+             }
+           }
+         p[pictures].setsequencenumber(++maxseqnr);
+         last_seqnr = seqnr;
+         } else {
+           /* I and P frames are delayed */
+           if (last_non_b_pic >= 0) {
+             /* check sequence number */
+             if (last_non_b_seqnr != last_seqnr + 1) {
+               fprintf(stderr,
+                 "missing frame(s) before %c frame %d (%d != %d)\n",
+                 p[last_non_b_pic].isiframe() ? 'I' : 'P',
+                 pictures, last_non_b_seqnr, last_seqnr + 1);
+               }
+             p[last_non_b_pic].setsequencenumber(++maxseqnr);
+             last_seqnr = last_non_b_seqnr;
+             }
+           last_non_b_pic = pictures;
+           last_non_b_seqnr = seqnr;
+         }
+
+       ++pictures;
 
         foundseqheader=false;
         sd->discard(8);
@@ -219,13 +263,9 @@
     sd->discard(skip);
     }
 
-  // ensure that sequence numbers are okay in the last sequence
-  if (!curseqnumbers.empty()) {
-    curseqnumbers.sort();
-    int n=0;
-    for(std::list<std::pair<int,int> >::iterator 
it=curseqnumbers.begin();it!=curseqnumbers.end();++it)
-      p[it->second].setsequencenumber(n++);
-    curseqnumbers.clear();
+  if (last_non_b_pic >= 0) {
+    p[last_non_b_pic].setsequencenumber(++maxseqnr);
+    last_non_b_pic = -1;
     }
 
   if (pictures==0) {
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
DVBCUT-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dvbcut-user

Reply via email to