ivtv patches gone?

View: New views
6 Messages — Rating Filter:   Alert me  

ivtv patches gone?

by Lawrence D'Oliveiro-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi folks.

Once upon a time there were dvdauthor patches posted at the
ivtvdriver.org wiki. I just searched for them
<http://ivtvdriver.org/index.php?title=Special%3ASearch&search=dvdauthor&fulltext=Search>,
and found a couple of hits, but they led to nonexistent pages.

Wonder what’s happened to these?

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Dvdauthor-developer mailing list
Dvdauthor-developer@...
https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer

Re: ivtv patches gone?

by Martin Crossley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi L and all

Thanks for pointing out that they have gone!

Next time I write some patches, I will know to post them in more than one
place :-)

I have just posted a copy of my patch to 0.6.14 (dvdvob.c) taken from an
archive site, but I'll go back to my development machine and make sure that
is the final version.

For reference, here also is a link to a copy of the earlier (and less
well-developed) version of the patch against 0.6.11 (it's in the first
attachment, at the bottom of the page).

Cheers MartinC


----- Original Message -----
From: "Lawrence D'Oliveiro" <ldo@...>
To: <dvdauthor-developer@...>
Sent: Sunday, November 08, 2009 4:27 AM
Subject: [Dvdauthor-developer] ivtv patches gone?


> Hi folks.
>
> Once upon a time there were dvdauthor patches posted at the
> ivtvdriver.org wiki. I just searched for them
> <http://ivtvdriver.org/index.php?title=Special%3ASearch&search=dvdauthor&fulltext=Search>,
> and found a couple of hits, but they led to nonexistent pages.
>
> Wonder what’s happened to these?
>
> ------------------------------------------------------------------------------
> Let Crystal Reports handle the reporting - Free Crystal Reports 2008
> 30-Day
> trial. Simplify your report design, integration and deployment - and focus
> on
> what you do best, core application coding. Discover what's new with
> Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Dvdauthor-developer mailing list
> Dvdauthor-developer@...
> https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer
>


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Dvdauthor-developer mailing list
Dvdauthor-developer@...
https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer

Re: ivtv patches gone?

by Joo Martin-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

----
Am Sun, 08 Nov 2009 17:27:51 +1300 schrieb
"Lawrence D'Oliveiro" <ldo@...>:

> Once upon a time there were dvdauthor patches posted at the
> ivtvdriver.org wiki. I just searched for them
> <http://ivtvdriver.org/index.php?title=Special%3ASearch&search=dvdauthor&fulltext=Search>,
> and found a couple of hits, but they led to nonexistent pages.

I have found in my archives a version of the dvdauthor patch from 06/06/2008.

Ciao, Joo



--- src/dvdvob.c.dist 2008-06-06 13:16:57.000000000 +0100
+++ src/dvdvob.c 2008-06-06 13:29:47.000000000 +0100
@@ -16,8 +16,31 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  * USA
  */
 
+/* NOTE TO THOSE UNFAMILIAR WITH MPEG FORMAT
+ *       This code contains many 'magic numbers' related to analysing and
+ *       and parsing MPEG data. MPEG content consists of a series of
+ *       2048 byte 'packs'. Each pack begins with a pack header that is
+ *       identified by the byte sequence 00 00 01 BA. The rest of the pack
+ *       contains other headers (each identified by their own start code),
+ *       plus payload data and optional stuffing bytes. The headers contain
+ *       data fields describing different aspect of the payload, timing etc.
+ *       Frequently encountered types of header include:
+ * 00 00 01 BA : pack header;
+ * 00 00 01 BB : system header;
+ * 00 00 01 B3 : sequence header;
+ * 00 00 01 B5 : extension header;
+ * 00 00 01 B8 : group-of-pictures (GOP) header;
+ * 00 00 01 E0 : programme-elementary-stream (PES) header for first video channel
+ * etc...
+ *       A useful quick reference for identifying and decoding MPEG headers
+ *       is available at http://dvd.sourceforge.net/dvdinfo/mpeghdrs.html
+ *       For detailed information try chapter 10 (p230) of 'digital video
+ *       introduction to mpeg2' (Haskell, Puri and Netravali), which you can
+ *       read online at http://books.google.com
+ */
+
 #include "config.h"
 
 #include "compat.h"
 
@@ -233,8 +254,10 @@
 }
 
 static void transpose_ts(unsigned char *buf,pts_t tsoffs)
 {
+    int shift;
+
     // pack scr
     if( buf[0] == 0 &&
         buf[1] == 0 &&
         buf[2] == 1 &&
@@ -243,23 +266,51 @@
         writescr(buf+4,readscr(buf+4)+tsoffs);
 
         // video/audio?
         // pts?
-        if( buf[14] == 0 &&
-            buf[15] == 0 &&
-            buf[16] == 1 &&
-            (buf[17]==0xbd || (buf[17]>=0xc0 && buf[17]<=0xef)) &&
-            (buf[21] & 128))
+ // allow for optional system header before the PES header
+ shift = (buf[17] == 0xbb) ? 24 : 0;
+        if( buf[14+shift] == 0 &&
+            buf[15+shift] == 0 &&
+            buf[16+shift] == 1 &&
+            (buf[17+shift]==0xbd || (buf[17+shift]>=0xc0 && buf[17+shift]<=0xef)) &&
+            (buf[21+shift] & 128))
         {
-            writepts(buf+23,readpts(buf+23)+tsoffs);
+            writepts(buf+23+shift,readpts(buf+23+shift)+tsoffs);
             // dts?
-            if( buf[21] & 64 ) {
-                writepts(buf+28,readpts(buf+28)+tsoffs);
+            if( buf[21+shift] & 64 ) {
+                writepts(buf+28+shift,readpts(buf+28+shift)+tsoffs);
             }
         }
     }
 }
 
+int find_gop(unsigned char *buf)
+{
+    // if the pack has a system header and a video PES header, then check whether there is a GOP header
+    if (buf[14] == 0 &&
+        buf[15] == 0 &&
+        buf[16] == 1 &&
+        buf[17] == 0xbb &&
+        buf[38] == 0 &&
+        buf[39] == 0 &&
+        buf[40] == 1 &&
+        buf[41] == 0xe0)
+    {
+        int i = 42;
+        while (i < 1024)
+        {
+            if (buf[i] == 0 &&
+                buf[i+1] == 0 &&
+                buf[i+2] == 1 &&
+                buf[i+3] == 0xb8)
+                return 1;
+            i += 4;
+        }
+    }
+    return 0;
+}
+
 static int mpa_valid(unsigned char *b)
 {
     unsigned int v=(b[0]<<24)|(b[1]<<16)|(b[2]<<8)|b[3];
     int t;
@@ -823,10 +874,12 @@
 
 int FindVobus(char *fbase,struct vobgroup *va,int ismenu)
 {
     unsigned char *buf;
+    unsigned char *buf_copy = (unsigned char*) malloc(2048);
     int cursect=0,fsect=-1,vnum,outnum=-ismenu+1;
     int vobid=0;
+    int shift;
     struct mp2info {
         int hdrptr;
         unsigned char buf[6];
     } mp2hdr[8];
@@ -836,8 +889,9 @@
     for( vnum=0; vnum<va->numvobs; vnum++ ) {
         int i,j;
         int hadfirstvobu=0;
         pts_t backoffs=0, lastscr=0;
+        int generate_vobu=0,copy_packet=0,tsoffs=0;
         struct vob *s=va->vobs[vnum];
         int prevvidsect=-1;
         struct vscani vsi;
         struct vfile vf;
@@ -868,10 +922,11 @@
                 fsect=-1;
             }
             buf=writegrabbuf();
 
-            i=fread(buf,1,2048,vf.h);
-            if( i!=2048 ) {
+            if (copy_packet == 1 ) {
+                memcpy( buf, buf_copy, 2048);
+            } else if( 2048 != (i=fread(buf,1,2048,vf.h)) ) {
                 if( i==-1 ) {
                     fprintf(stderr,"\nERR:  Error while reading: %s\n",strerror(errno));
                     exit(1);
                 } else if( i>0 )
@@ -985,8 +1040,44 @@
 
                 writeundo();
                 continue;
             }
+
+            if( fsect == -1 ) {
+                char newname[200];
+                fsect=0;
+                if( fbase ) {
+                    if( outnum>=0 )
+                        sprintf(newname,"%s_%d.VOB",fbase,outnum);
+                    else
+                        strcpy(newname,fbase);
+                    writeopen(newname);
+                }
+            }
+
+            // we should get a VOBU before a video with GOP
+            if( (generate_vobu == 1 || hadfirstvobu == 0) &&
+                copy_packet == 0 && find_gop(buf) )
+            {
+                // create VOBU
+ //fprintf(stderr,"INFO: found video GOP without a preceding VOBU - creating VOBU\n");
+                generate_vobu = 1;
+                copy_packet = 1;
+                memcpy( buf_copy, buf, 2048);
+
+                buf[41] = 0xbf;
+                buf[42] = 0x03;
+                buf[43] = 0xd4;
+                buf[44] = 0x81;
+                memset( buf+45, 0, 2048-45);
+                buf[1026] = 1;
+                buf[1027] = 0xbf;
+                buf[1028] = 0x03;
+                buf[1029] = 0xfa;
+                buf[1030] = 0x81;
+            } else if (copy_packet == 1)
+                copy_packet = 0;
+
             if( buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) {
                 pts_t newscr=readscr(buf+4);
                 if( newscr < lastscr ) {
                     fprintf(stderr,"ERR:  SCR moves backwards, remultiplex input.\n");
@@ -996,18 +1087,19 @@
                 if( !hadfirstvobu )
                     backoffs=newscr;
             }
             transpose_ts(buf,-backoffs);
-            if( fsect == -1 ) {
-                char newname[200];
-                fsect=0;
-                if( fbase ) {
-                    if( outnum>=0 )
-                        sprintf(newname,"%s_%d.VOB",fbase,outnum);
-                    else
-                        strcpy(newname,fbase);
-                    writeopen(newname);
-                }
+
+            if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba )
+            {
+                // allow for optional system header before the PES header
+                shift = (buf[17] == 0xbb) ? 24 : 0;
+                if( buf[14+shift] == 0 &&
+                    buf[15+shift] == 0 &&
+                    buf[16+shift] == 1 &&
+                    (buf[17+shift]==0xbd || (buf[17+shift]>=0xc0 && buf[17+shift]<=0xef)) &&
+                    (buf[21+shift] & 128))
+                    tsoffs = readpts(buf+23+shift);
             }
             if( buf[14] == 0 &&
                 buf[15] == 0 &&
                 buf[16] == 1 &&
@@ -1050,9 +1142,9 @@
                     if( !(s->numvobus&15) )
                         printvobustatus(va,cursect);
                     vsi.lastrefsect=0;
                     vsi.firstgop=1;
-                } else {
+                } else if (generate_vobu == 0 || copy_packet == 1) {
                     fprintf(stderr,"WARN: System header found, but PCI/DSI information is not where expected\n\t(make sure your system header is 18 bytes!)\n");
                 }
             }
             if( !hadfirstvobu ) {
@@ -1077,36 +1169,40 @@
                 }
                 break;
             }
 
+            // allow for optional system header before the PES header
+            shift = (buf[17] == 0xbb) ? 24 : 0;
             if( buf[0] == 0 &&
                 buf[1] == 0 &&
                 buf[2] == 1 &&
                 buf[3] == 0xba &&
-                buf[14] == 0 &&
-                buf[15] == 0 &&
-                buf[16] == 1 &&
-                buf[17] == 0xe0 ) { // video
+                buf[14+shift] == 0 &&
+                buf[15+shift] == 0 &&
+                buf[16+shift] == 1 &&
+                buf[17+shift] == 0xe0 ) { // video
                 struct vobuinfo *vi=&s->vi[s->numvobus-1];
                 vi->hasvideo=1;
-                scanvideoframe(va,buf,vi,cursect,prevvidsect,&vsi);
-                if( (buf[21] & 128) && vi->firstvideopts==-1 ) { // check whether there's a pts
-                    vi->firstvideopts=readpts(buf+23);
+                scanvideoframe(va,buf+shift,vi,cursect,prevvidsect,&vsi);
+                if( (buf[21+shift] & 128) && vi->firstvideopts==-1 ) { // check whether there's a pts
+                    vi->firstvideopts=readpts(buf+23+shift);
                 }
                 prevvidsect=cursect;
             }
+
+            shift = (buf[17] == 0xbb) ? 24 : 0;
             if( buf[0] == 0 &&
                 buf[1] == 0 &&
                 buf[2] == 1 &&
                 buf[3] == 0xba &&
-                buf[14] == 0 &&
-                buf[15] == 0 &&
-                buf[16] == 1 &&
-                ((buf[17] & 0xf8) == 0xc0 || buf[17]==0xbd)) {
+                buf[14+shift] == 0 &&
+                buf[15+shift] == 0 &&
+                buf[16+shift] == 1 &&
+                ((buf[17+shift] & 0xf8) == 0xc0 || buf[17+shift]==0xbd)) {
                 pts_t pts0=0,pts1=0,backpts1=0;
-                int dptr=buf[22]+23,endop=read2(buf+18)+20;
-                int audch,haspts=(buf[21]&128);
-                if( buf[17]==0xbd ) {
+                int dptr=buf[22+shift]+23,endop=read2(buf+shift+18)+20; // NB: indices based on dptr should be correct - do not adjust them
+                int audch,haspts=(buf[21+shift]&128);
+                if( buf[17+shift]==0xbd ) {
                     int sid=buf[dptr],offs=read2(buf+dptr+2);
 
                     switch(sid&0xf8) {
                     case 0x20:                          // subpicture
@@ -1130,9 +1226,9 @@
                     default:   audch=-1; break;         // unknown
                     }
                 } else {
                     int len=endop-dptr;
-                    int index=buf[17]&7;
+                    int index=buf[17+shift]&7;
                     audch=8|index;                      // mp2
                     memcpy(mp2hdr[index].buf+3,buf+dptr,3);
                     while(mp2hdr[index].hdrptr+4<=len) {
                         unsigned char *h;
@@ -1156,9 +1252,9 @@
                     memcpy(mp2hdr[index].buf,buf+dptr+len-3,3);
                     audiodesc_set_audio_attr(&s->audch[audch].ad,&s->audch[audch].adwarn,AUDIO_SAMPLERATE,"48khz");
                 }
                 if( haspts ) {
-                    pts0=readpts(buf+23);
+                    pts0=readpts(buf+23+shift);
                     pts1+=pts0;
                 } else if( pts1>0 ) {
                     fprintf(stderr,"WARN: Audio channel %d contains sync headers but has no PTS.\n",audch);
                 }
@@ -1214,17 +1310,18 @@
                 }
             }
             // the following code scans subtitle code in order to
             // remap the colors and update the end pts
+            shift = (buf[17] == 0xbb) ? 24 : 0;
             if( buf[0] == 0 &&
                 buf[1] == 0 &&
                 buf[2] == 1 &&
                 buf[3] == 0xba &&
-                buf[14] == 0 &&
-                buf[15] == 0 &&
-                buf[16] == 1 &&
-                buf[17] == 0xbd) {
-                int dptr=buf[22]+23,ml=read2(buf+18)+20;
+                buf[14+shift] == 0 &&
+                buf[15+shift] == 0 &&
+                buf[16+shift] == 1 &&
+                buf[17+shift] == 0xbd) {
+                int dptr=buf[22+shift]+23,ml=read2(buf+18+shift)+20;
                 int st=buf[dptr];
                 dptr++;
                 if( (st&0xf8)==0x20 ) { // subtitle
                     procremap(&crs[st&31],buf+dptr,ml-dptr,&s->audch[st].audpts[s->audch[st].numaudpts-1].pts[1]);
@@ -1368,8 +1465,9 @@
             fprintf(stderr,"\n");
         }
     }
     writeclose();
+    free(buf_copy);
     printvobustatus(va,cursect);
     fprintf(stderr,"\n");
     free(crs);
     return 1;

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Dvdauthor-developer mailing list
Dvdauthor-developer@...
https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer

Re: ivtv patches gone?

by Martin Crossley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Joo -

That's my patch :-)  thanks very much for keeping a local copy; I don't know
what happened to the copies I posted to the IVTV site (I'll check back in
the archive on my development machine in a minute or two, but I need to
reboot out of Vista and back into OpenBSD and I have couple of things I need
to finish first).

The version you have here is great, because I actually included some
comments (unlike me ;-) - but do you happen to know whether what you have
there is against 0.6.14 or 0.6.11 ?  I had two different versions floating
around...

I'm so glad these patches helped a few people out.

Krgds, MartinC


----- Original Message -----
From: "Joo Martin" <joomart2009@...>
To: <dvdauthor-developer@...>
Sent: Sunday, November 08, 2009 8:32 PM
Subject: Re: [Dvdauthor-developer] ivtv patches gone?


> Hello,
>
> ----
> Am Sun, 08 Nov 2009 17:27:51 +1300 schrieb
> "Lawrence D'Oliveiro" <ldo@...>:
>
>> Once upon a time there were dvdauthor patches posted at the
>> ivtvdriver.org wiki. I just searched for them
>> <http://ivtvdriver.org/index.php?title=Special%3ASearch&search=dvdauthor&fulltext=Search>,
>> and found a couple of hits, but they led to nonexistent pages.
>
> I have found in my archives a version of the dvdauthor patch from
> 06/06/2008.
>
> Ciao, Joo
>
>
>
> --- src/dvdvob.c.dist 2008-06-06 13:16:57.000000000 +0100
> +++ src/dvdvob.c 2008-06-06 13:29:47.000000000 +0100
> @@ -16,8 +16,31 @@
>  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
>  * USA
>  */
>
> +/* NOTE TO THOSE UNFAMILIAR WITH MPEG FORMAT
> + *       This code contains many 'magic numbers' related to analysing and
> + *       and parsing MPEG data. MPEG content consists of a series of
> + *       2048 byte 'packs'. Each pack begins with a pack header that is
> + *       identified by the byte sequence 00 00 01 BA. The rest of the
> pack
> + *       contains other headers (each identified by their own start
> code),
> + *       plus payload data and optional stuffing bytes. The headers
> contain
> + *       data fields describing different aspect of the payload, timing
> etc.
> + *       Frequently encountered types of header include:
> + * 00 00 01 BA : pack header;
> + * 00 00 01 BB : system header;
> + * 00 00 01 B3 : sequence header;
> + * 00 00 01 B5 : extension header;
> + * 00 00 01 B8 : group-of-pictures (GOP) header;
> + * 00 00 01 E0 : programme-elementary-stream (PES) header for first video
> channel
> + * etc...
> + *       A useful quick reference for identifying and decoding MPEG
> headers
> + *       is available at http://dvd.sourceforge.net/dvdinfo/mpeghdrs.html
> + *       For detailed information try chapter 10 (p230) of 'digital video
> + *       introduction to mpeg2' (Haskell, Puri and Netravali), which you
> can
> + *       read online at http://books.google.com
> + */
> +
> #include "config.h"
>
> #include "compat.h"
>
> @@ -233,8 +254,10 @@
> }
>
> static void transpose_ts(unsigned char *buf,pts_t tsoffs)
> {
> +    int shift;
> +
>     // pack scr
>     if( buf[0] == 0 &&
>         buf[1] == 0 &&
>         buf[2] == 1 &&
> @@ -243,23 +266,51 @@
>         writescr(buf+4,readscr(buf+4)+tsoffs);
>
>         // video/audio?
>         // pts?
> -        if( buf[14] == 0 &&
> -            buf[15] == 0 &&
> -            buf[16] == 1 &&
> -            (buf[17]==0xbd || (buf[17]>=0xc0 && buf[17]<=0xef)) &&
> -            (buf[21] & 128))
> + // allow for optional system header before the PES header
> + shift = (buf[17] == 0xbb) ? 24 : 0;
> +        if( buf[14+shift] == 0 &&
> +            buf[15+shift] == 0 &&
> +            buf[16+shift] == 1 &&
> +            (buf[17+shift]==0xbd || (buf[17+shift]>=0xc0 &&
> buf[17+shift]<=0xef)) &&
> +            (buf[21+shift] & 128))
>         {
> -            writepts(buf+23,readpts(buf+23)+tsoffs);
> +            writepts(buf+23+shift,readpts(buf+23+shift)+tsoffs);
>             // dts?
> -            if( buf[21] & 64 ) {
> -                writepts(buf+28,readpts(buf+28)+tsoffs);
> +            if( buf[21+shift] & 64 ) {
> +                writepts(buf+28+shift,readpts(buf+28+shift)+tsoffs);
>             }
>         }
>     }
> }
>
> +int find_gop(unsigned char *buf)
> +{
> +    // if the pack has a system header and a video PES header, then check
> whether there is a GOP header
> +    if (buf[14] == 0 &&
> +        buf[15] == 0 &&
> +        buf[16] == 1 &&
> +        buf[17] == 0xbb &&
> +        buf[38] == 0 &&
> +        buf[39] == 0 &&
> +        buf[40] == 1 &&
> +        buf[41] == 0xe0)
> +    {
> +        int i = 42;
> +        while (i < 1024)
> +        {
> +            if (buf[i] == 0 &&
> +                buf[i+1] == 0 &&
> +                buf[i+2] == 1 &&
> +                buf[i+3] == 0xb8)
> +                return 1;
> +            i += 4;
> +        }
> +    }
> +    return 0;
> +}
> +
> static int mpa_valid(unsigned char *b)
> {
>     unsigned int v=(b[0]<<24)|(b[1]<<16)|(b[2]<<8)|b[3];
>     int t;
> @@ -823,10 +874,12 @@
>
> int FindVobus(char *fbase,struct vobgroup *va,int ismenu)
> {
>     unsigned char *buf;
> +    unsigned char *buf_copy = (unsigned char*) malloc(2048);
>     int cursect=0,fsect=-1,vnum,outnum=-ismenu+1;
>     int vobid=0;
> +    int shift;
>     struct mp2info {
>         int hdrptr;
>         unsigned char buf[6];
>     } mp2hdr[8];
> @@ -836,8 +889,9 @@
>     for( vnum=0; vnum<va->numvobs; vnum++ ) {
>         int i,j;
>         int hadfirstvobu=0;
>         pts_t backoffs=0, lastscr=0;
> +        int generate_vobu=0,copy_packet=0,tsoffs=0;
>         struct vob *s=va->vobs[vnum];
>         int prevvidsect=-1;
>         struct vscani vsi;
>         struct vfile vf;
> @@ -868,10 +922,11 @@
>                 fsect=-1;
>             }
>             buf=writegrabbuf();
>
> -            i=fread(buf,1,2048,vf.h);
> -            if( i!=2048 ) {
> +            if (copy_packet == 1 ) {
> +                memcpy( buf, buf_copy, 2048);
> +            } else if( 2048 != (i=fread(buf,1,2048,vf.h)) ) {
>                 if( i==-1 ) {
>                     fprintf(stderr,"\nERR:  Error while reading:
> %s\n",strerror(errno));
>                     exit(1);
>                 } else if( i>0 )
> @@ -985,8 +1040,44 @@
>
>                 writeundo();
>                 continue;
>             }
> +
> +            if( fsect == -1 ) {
> +                char newname[200];
> +                fsect=0;
> +                if( fbase ) {
> +                    if( outnum>=0 )
> +                        sprintf(newname,"%s_%d.VOB",fbase,outnum);
> +                    else
> +                        strcpy(newname,fbase);
> +                    writeopen(newname);
> +                }
> +            }
> +
> +            // we should get a VOBU before a video with GOP
> +            if( (generate_vobu == 1 || hadfirstvobu == 0) &&
> +                copy_packet == 0 && find_gop(buf) )
> +            {
> +                // create VOBU
> + //fprintf(stderr,"INFO: found video GOP without a preceding VOBU -
> creating VOBU\n");
> +                generate_vobu = 1;
> +                copy_packet = 1;
> +                memcpy( buf_copy, buf, 2048);
> +
> +                buf[41] = 0xbf;
> +                buf[42] = 0x03;
> +                buf[43] = 0xd4;
> +                buf[44] = 0x81;
> +                memset( buf+45, 0, 2048-45);
> +                buf[1026] = 1;
> +                buf[1027] = 0xbf;
> +                buf[1028] = 0x03;
> +                buf[1029] = 0xfa;
> +                buf[1030] = 0x81;
> +            } else if (copy_packet == 1)
> +                copy_packet = 0;
> +
>             if( buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) {
>                 pts_t newscr=readscr(buf+4);
>                 if( newscr < lastscr ) {
>                     fprintf(stderr,"ERR:  SCR moves backwards, remultiplex
> input.\n");
> @@ -996,18 +1087,19 @@
>                 if( !hadfirstvobu )
>                     backoffs=newscr;
>             }
>             transpose_ts(buf,-backoffs);
> -            if( fsect == -1 ) {
> -                char newname[200];
> -                fsect=0;
> -                if( fbase ) {
> -                    if( outnum>=0 )
> -                        sprintf(newname,"%s_%d.VOB",fbase,outnum);
> -                    else
> -                        strcpy(newname,fbase);
> -                    writeopen(newname);
> -                }
> +
> +            if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 &&
> buf[3]==0xba )
> +            {
> +                // allow for optional system header before the PES header
> +                shift = (buf[17] == 0xbb) ? 24 : 0;
> +                if( buf[14+shift] == 0 &&
> +                    buf[15+shift] == 0 &&
> +                    buf[16+shift] == 1 &&
> +                    (buf[17+shift]==0xbd || (buf[17+shift]>=0xc0 &&
> buf[17+shift]<=0xef)) &&
> +                    (buf[21+shift] & 128))
> +                     tsoffs = readpts(buf+23+shift);
>             }
>             if( buf[14] == 0 &&
>                 buf[15] == 0 &&
>                 buf[16] == 1 &&
> @@ -1050,9 +1142,9 @@
>                     if( !(s->numvobus&15) )
>                         printvobustatus(va,cursect);
>                     vsi.lastrefsect=0;
>                     vsi.firstgop=1;
> -                } else {
> +                } else if (generate_vobu == 0 || copy_packet == 1) {
>                     fprintf(stderr,"WARN: System header found, but PCI/DSI
> information is not where expected\n\t(make sure your system header is 18
> bytes!)\n");
>                 }
>             }
>             if( !hadfirstvobu ) {
> @@ -1077,36 +1169,40 @@
>                 }
>                 break;
>             }
>
> +            // allow for optional system header before the PES header
> +            shift = (buf[17] == 0xbb) ? 24 : 0;
>             if( buf[0] == 0 &&
>                 buf[1] == 0 &&
>                 buf[2] == 1 &&
>                 buf[3] == 0xba &&
> -                buf[14] == 0 &&
> -                buf[15] == 0 &&
> -                buf[16] == 1 &&
> -                buf[17] == 0xe0 ) { // video
> +                buf[14+shift] == 0 &&
> +                buf[15+shift] == 0 &&
> +                buf[16+shift] == 1 &&
> +                buf[17+shift] == 0xe0 ) { // video
>                 struct vobuinfo *vi=&s->vi[s->numvobus-1];
>                 vi->hasvideo=1;
> -                scanvideoframe(va,buf,vi,cursect,prevvidsect,&vsi);
> -                if( (buf[21] & 128) && vi->firstvideopts==-1 ) { // check
> whether there's a pts
> -                    vi->firstvideopts=readpts(buf+23);
> +                scanvideoframe(va,buf+shift,vi,cursect,prevvidsect,&vsi);
> +                if( (buf[21+shift] & 128) && vi->firstvideopts==-1 ) { //
> check whether there's a pts
> +                    vi->firstvideopts=readpts(buf+23+shift);
>                 }
>                 prevvidsect=cursect;
>             }
> +
> +            shift = (buf[17] == 0xbb) ? 24 : 0;
>             if( buf[0] == 0 &&
>                 buf[1] == 0 &&
>                 buf[2] == 1 &&
>                 buf[3] == 0xba &&
> -                buf[14] == 0 &&
> -                buf[15] == 0 &&
> -                buf[16] == 1 &&
> -                ((buf[17] & 0xf8) == 0xc0 || buf[17]==0xbd)) {
> +                buf[14+shift] == 0 &&
> +                buf[15+shift] == 0 &&
> +                buf[16+shift] == 1 &&
> +                ((buf[17+shift] & 0xf8) == 0xc0 || buf[17+shift]==0xbd))
> {
>                 pts_t pts0=0,pts1=0,backpts1=0;
> -                int dptr=buf[22]+23,endop=read2(buf+18)+20;
> -                int audch,haspts=(buf[21]&128);
> -                if( buf[17]==0xbd ) {
> +                int dptr=buf[22+shift]+23,endop=read2(buf+shift+18)+20;
> // NB: indices based on dptr should be correct - do not adjust them
> +                int audch,haspts=(buf[21+shift]&128);
> +                if( buf[17+shift]==0xbd ) {
>                     int sid=buf[dptr],offs=read2(buf+dptr+2);
>
>                     switch(sid&0xf8) {
>                     case 0x20:                          // subpicture
> @@ -1130,9 +1226,9 @@
>                     default:   audch=-1; break;         // unknown
>                     }
>                 } else {
>                     int len=endop-dptr;
> -                    int index=buf[17]&7;
> +                    int index=buf[17+shift]&7;
>                     audch=8|index;                      // mp2
>                     memcpy(mp2hdr[index].buf+3,buf+dptr,3);
>                     while(mp2hdr[index].hdrptr+4<=len) {
>                         unsigned char *h;
> @@ -1156,9 +1252,9 @@
>                     memcpy(mp2hdr[index].buf,buf+dptr+len-3,3);
>
> audiodesc_set_audio_attr(&s->audch[audch].ad,&s->audch[audch].adwarn,AUDIO_SAMPLERATE,"48khz");
>                 }
>                 if( haspts ) {
> -                    pts0=readpts(buf+23);
> +                    pts0=readpts(buf+23+shift);
>                     pts1+=pts0;
>                 } else if( pts1>0 ) {
>                     fprintf(stderr,"WARN: Audio channel %d contains sync
> headers but has no PTS.\n",audch);
>                 }
> @@ -1214,17 +1310,18 @@
>                 }
>             }
>             // the following code scans subtitle code in order to
>             // remap the colors and update the end pts
> +            shift = (buf[17] == 0xbb) ? 24 : 0;
>             if( buf[0] == 0 &&
>                 buf[1] == 0 &&
>                 buf[2] == 1 &&
>                 buf[3] == 0xba &&
> -                buf[14] == 0 &&
> -                buf[15] == 0 &&
> -                buf[16] == 1 &&
> -                buf[17] == 0xbd) {
> -                int dptr=buf[22]+23,ml=read2(buf+18)+20;
> +                buf[14+shift] == 0 &&
> +                buf[15+shift] == 0 &&
> +                buf[16+shift] == 1 &&
> +                buf[17+shift] == 0xbd) {
> +                int dptr=buf[22+shift]+23,ml=read2(buf+18+shift)+20;
>                 int st=buf[dptr];
>                 dptr++;
>                 if( (st&0xf8)==0x20 ) { // subtitle
>
> procremap(&crs[st&31],buf+dptr,ml-dptr,&s->audch[st].audpts[s->audch[st].numaudpts-1].pts[1]);
> @@ -1368,8 +1465,9 @@
>             fprintf(stderr,"\n");
>         }
>     }
>     writeclose();
> +    free(buf_copy);
>     printvobustatus(va,cursect);
>     fprintf(stderr,"\n");
>     free(crs);
>     return 1;
>
> ------------------------------------------------------------------------------
> Let Crystal Reports handle the reporting - Free Crystal Reports 2008
> 30-Day
> trial. Simplify your report design, integration and deployment - and focus
> on
> what you do best, core application coding. Discover what's new with
> Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Dvdauthor-developer mailing list
> Dvdauthor-developer@...
> https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer
>


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Dvdauthor-developer mailing list
Dvdauthor-developer@...
https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer

Re: ivtv patches gone?

by Martin Crossley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello all -

OK from the original development files, here is a copy of my final version
of dvdauthor-0.6.14-ivtv-patch-0.2

I think it is almost certainly the same as the one that Joo just posted,
but I did make a few tweaks in the final days.  The attached is the
definitive final version.

thank heavens for backups...

Kind regards to all

MartinC

PS - Although the MPEG headers are a bit intimidating to start with (I
find most of the specs almost impenetrable) it's well worth persevering,
and the sources I referenced in the following make it much more accessible.



===========================
--- src/dvdvob.c.dist 2008-06-06 13:16:57.000000000 +0100
+++ src/dvdvob.c 2008-06-06 13:29:47.000000000 +0100
@@ -16,8 +16,31 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  * USA
  */
 
+/* NOTE TO THOSE UNFAMILIAR WITH MPEG FORMAT
+ *       This code contains many 'magic numbers' related to analysing and
+ *       and parsing MPEG data. MPEG content consists of a series of
+ *       2048 byte 'packs'. Each pack begins with a pack header that is
+ *       identified by the byte sequence 00 00 01 BA. The rest of the
pack
+ *       contains other headers (each identified by their own start
code),
+ *       plus payload data and optional stuffing bytes. The headers
contain
+ *       data fields describing different aspect of the payload, timing
etc.
+ *       Frequently encountered types of header include:
+ * 00 00 01 BA : pack header;
+ * 00 00 01 BB : system header;
+ * 00 00 01 B3 : sequence header;
+ * 00 00 01 B5 : extension header;
+ * 00 00 01 B8 : group-of-pictures (GOP) header;
+ * 00 00 01 E0 : programme-elementary-stream (PES) header for first
video channel
+ * etc...
+ *       A useful quick reference for identifying and decoding MPEG
headers
+ *       is available at http://dvd.sourceforge.net/dvdinfo/mpeghdrs.html
+ *       For detailed information try chapter 10 (p230) of 'digital video
+ *       introduction to mpeg2' (Haskell, Puri and Netravali), which you
can
+ *       read online at http://books.google.com
+ */
+
 #include "config.h"
 
 #include "compat.h"
 
@@ -233,8 +254,10 @@
 }
 
 static void transpose_ts(unsigned char *buf,pts_t tsoffs)
 {
+    int shift;
+
     // pack scr
     if( buf[0] == 0 &&
         buf[1] == 0 &&
         buf[2] == 1 &&
@@ -243,23 +266,51 @@
         writescr(buf+4,readscr(buf+4)+tsoffs);
 
         // video/audio?
         // pts?
-        if( buf[14] == 0 &&
-            buf[15] == 0 &&
-            buf[16] == 1 &&
-            (buf[17]==0xbd || (buf[17]>=0xc0 && buf[17]<=0xef)) &&
-            (buf[21] & 128))
+ // allow for optional system header before the PES header
+ shift = (buf[17] == 0xbb) ? 24 : 0;
+        if( buf[14+shift] == 0 &&
+            buf[15+shift] == 0 &&
+            buf[16+shift] == 1 &&
+            (buf[17+shift]==0xbd || (buf[17+shift]>=0xc0 &&
buf[17+shift]<=0xef)) &&
+            (buf[21+shift] & 128))
         {
-            writepts(buf+23,readpts(buf+23)+tsoffs);
+            writepts(buf+23+shift,readpts(buf+23+shift)+tsoffs);
             // dts?
-            if( buf[21] & 64 ) {
-                writepts(buf+28,readpts(buf+28)+tsoffs);
+            if( buf[21+shift] & 64 ) {
+                writepts(buf+28+shift,readpts(buf+28+shift)+tsoffs);
             }
         }
     }
 }
 
+int find_gop(unsigned char *buf)
+{
+    // if the pack has a system header and a video PES header, then check
whether there is a GOP header
+    if (buf[14] == 0 &&
+        buf[15] == 0 &&
+        buf[16] == 1 &&
+        buf[17] == 0xbb &&
+        buf[38] == 0 &&
+        buf[39] == 0 &&
+        buf[40] == 1 &&
+        buf[41] == 0xe0)
+    {
+        int i = 42;
+        while (i < 1024)
+        {
+            if (buf[i] == 0 &&
+                buf[i+1] == 0 &&
+                buf[i+2] == 1 &&
+                buf[i+3] == 0xb8)
+                return 1;
+            i += 4;
+        }
+    }
+    return 0;
+}
+
 static int mpa_valid(unsigned char *b)
 {
     unsigned int v=(b[0]<<24)|(b[1]<<16)|(b[2]<<8)|b[3];
     int t;
@@ -823,10 +874,12 @@
 
 int FindVobus(char *fbase,struct vobgroup *va,int ismenu)
 {
     unsigned char *buf;
+    unsigned char *buf_copy = (unsigned char*) malloc(2048);
     int cursect=0,fsect=-1,vnum,outnum=-ismenu+1;
     int vobid=0;
+    int shift;
     struct mp2info {
         int hdrptr;
         unsigned char buf[6];
     } mp2hdr[8];
@@ -836,8 +889,9 @@
     for( vnum=0; vnum<va->numvobs; vnum++ ) {
         int i,j;
         int hadfirstvobu=0;
         pts_t backoffs=0, lastscr=0;
+        int generate_vobu=0,copy_packet=0,tsoffs=0;
         struct vob *s=va->vobs[vnum];
         int prevvidsect=-1;
         struct vscani vsi;
         struct vfile vf;
@@ -868,10 +922,11 @@
                 fsect=-1;
             }
             buf=writegrabbuf();
 
-            i=fread(buf,1,2048,vf.h);
-            if( i!=2048 ) {
+            if (copy_packet == 1 ) {
+                memcpy( buf, buf_copy, 2048);
+            } else if( 2048 != (i=fread(buf,1,2048,vf.h)) ) {
                 if( i==-1 ) {
                     fprintf(stderr,"\nERR:  Error while reading:
%s\n",strerror(errno));
                     exit(1);
                 } else if( i>0 )
@@ -985,8 +1040,44 @@
 
                 writeundo();
                 continue;
             }
+
+            if( fsect == -1 ) {
+                char newname[200];
+                fsect=0;
+                if( fbase ) {
+                    if( outnum>=0 )
+                        sprintf(newname,"%s_%d.VOB",fbase,outnum);
+                    else
+                        strcpy(newname,fbase);
+                    writeopen(newname);
+                }
+            }
+
+            // we should get a VOBU before a video with GOP
+            if( (generate_vobu == 1 || hadfirstvobu == 0) &&
+                copy_packet == 0 && find_gop(buf) )
+            {
+                // create VOBU
+ //fprintf(stderr,"INFO: found video GOP without a preceding VOBU -
creating VOBU\n");
+                generate_vobu = 1;
+                copy_packet = 1;
+                memcpy( buf_copy, buf, 2048);
+
+                buf[41] = 0xbf;
+                buf[42] = 0x03;
+                buf[43] = 0xd4;
+                buf[44] = 0x81;
+                memset( buf+45, 0, 2048-45);
+                buf[1026] = 1;
+                buf[1027] = 0xbf;
+                buf[1028] = 0x03;
+                buf[1029] = 0xfa;
+                buf[1030] = 0x81;
+            } else if (copy_packet == 1)
+                copy_packet = 0;
+
             if( buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) {
                 pts_t newscr=readscr(buf+4);
                 if( newscr < lastscr ) {
                     fprintf(stderr,"ERR:  SCR moves backwards,
remultiplex input.\n");
@@ -996,18 +1087,19 @@
                 if( !hadfirstvobu )
                     backoffs=newscr;
             }
             transpose_ts(buf,-backoffs);
-            if( fsect == -1 ) {
-                char newname[200];
-                fsect=0;
-                if( fbase ) {
-                    if( outnum>=0 )
-                        sprintf(newname,"%s_%d.VOB",fbase,outnum);
-                    else
-                        strcpy(newname,fbase);
-                    writeopen(newname);
-                }
+
+            if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 &&
buf[3]==0xba )
+            {
+                // allow for optional system header before the PES header
+                shift = (buf[17] == 0xbb) ? 24 : 0;
+                if( buf[14+shift] == 0 &&
+                    buf[15+shift] == 0 &&
+                    buf[16+shift] == 1 &&
+                    (buf[17+shift]==0xbd || (buf[17+shift]>=0xc0 &&
buf[17+shift]<=0xef)) &&
+                    (buf[21+shift] & 128))
+                    tsoffs = readpts(buf+23+shift);
             }
             if( buf[14] == 0 &&
                 buf[15] == 0 &&
                 buf[16] == 1 &&
@@ -1050,9 +1142,9 @@
                     if( !(s->numvobus&15) )
                         printvobustatus(va,cursect);
                     vsi.lastrefsect=0;
                     vsi.firstgop=1;
-                } else {
+                } else if (generate_vobu == 0 || copy_packet == 1) {
                     fprintf(stderr,"WARN: System header found, but
PCI/DSI information is not where expected\n\t(make sure your system header
is 18 bytes!)\n");
                 }
             }
             if( !hadfirstvobu ) {
@@ -1077,36 +1169,40 @@
                 }
                 break;
             }
 
+            // allow for optional system header before the PES header
+            shift = (buf[17] == 0xbb) ? 24 : 0;
             if( buf[0] == 0 &&
                 buf[1] == 0 &&
                 buf[2] == 1 &&
                 buf[3] == 0xba &&
-                buf[14] == 0 &&
-                buf[15] == 0 &&
-                buf[16] == 1 &&
-                buf[17] == 0xe0 ) { // video
+                buf[14+shift] == 0 &&
+                buf[15+shift] == 0 &&
+                buf[16+shift] == 1 &&
+                buf[17+shift] == 0xe0 ) { // video
                 struct vobuinfo *vi=&s->vi[s->numvobus-1];
                 vi->hasvideo=1;
-                scanvideoframe(va,buf,vi,cursect,prevvidsect,&vsi);
-                if( (buf[21] & 128) && vi->firstvideopts==-1 ) { // check
whether there's a pts
-                    vi->firstvideopts=readpts(buf+23);
+                scanvideoframe(va,buf+shift,vi,cursect,prevvidsect,&vsi);
+                if( (buf[21+shift] & 128) && vi->firstvideopts==-1 ) { //
check whether there's a pts
+                    vi->firstvideopts=readpts(buf+23+shift);
                 }
                 prevvidsect=cursect;
             }
+
+            shift = (buf[17] == 0xbb) ? 24 : 0;
             if( buf[0] == 0 &&
                 buf[1] == 0 &&
                 buf[2] == 1 &&
                 buf[3] == 0xba &&
-                buf[14] == 0 &&
-                buf[15] == 0 &&
-                buf[16] == 1 &&
-                ((buf[17] & 0xf8) == 0xc0 || buf[17]==0xbd)) {
+                buf[14+shift] == 0 &&
+                buf[15+shift] == 0 &&
+                buf[16+shift] == 1 &&
+                ((buf[17+shift] & 0xf8) == 0xc0 || buf[17+shift]==0xbd))
{
                 pts_t pts0=0,pts1=0,backpts1=0;
-                int dptr=buf[22]+23,endop=read2(buf+18)+20;
-                int audch,haspts=(buf[21]&128);
-                if( buf[17]==0xbd ) {
+                int
dptr=buf[22+shift]+23,endop=read2(buf+shift+18)+20; // NB: indices based on
dptr should be correct - do not adjust them
+                int audch,haspts=(buf[21+shift]&128);
+                if( buf[17+shift]==0xbd ) {
                     int sid=buf[dptr],offs=read2(buf+dptr+2);
 
                     switch(sid&0xf8) {
                     case 0x20:                          // subpicture
@@ -1130,9 +1226,9 @@
                     default:   audch=-1; break;         // unknown
                     }
                 } else {
                     int len=endop-dptr;
-                    int index=buf[17]&7;
+                    int index=buf[17+shift]&7;
                     audch=8|index;                      // mp2
                     memcpy(mp2hdr[index].buf+3,buf+dptr,3);
                     while(mp2hdr[index].hdrptr+4<=len) {
                         unsigned char *h;
@@ -1156,9 +1252,9 @@
                     memcpy(mp2hdr[index].buf,buf+dptr+len-3,3);
                   
audiodesc_set_audio_attr(&s->audch[audch].ad,&s->audch[audch].adwarn,AUDIO_SAMPLERATE,"48khz");
                 }
                 if( haspts ) {
-                    pts0=readpts(buf+23);
+                    pts0=readpts(buf+23+shift);
                     pts1+=pts0;
                 } else if( pts1>0 ) {
                     fprintf(stderr,"WARN: Audio channel %d contains sync
headers but has no PTS.\n",audch);
                 }
@@ -1214,17 +1310,18 @@
                 }
             }
             // the following code scans subtitle code in order to
             // remap the colors and update the end pts
+            shift = (buf[17] == 0xbb) ? 24 : 0;
             if( buf[0] == 0 &&
                 buf[1] == 0 &&
                 buf[2] == 1 &&
                 buf[3] == 0xba &&
-                buf[14] == 0 &&
-                buf[15] == 0 &&
-                buf[16] == 1 &&
-                buf[17] == 0xbd) {
-                int dptr=buf[22]+23,ml=read2(buf+18)+20;
+                buf[14+shift] == 0 &&
+                buf[15+shift] == 0 &&
+                buf[16+shift] == 1 &&
+                buf[17+shift] == 0xbd) {
+                int dptr=buf[22+shift]+23,ml=read2(buf+18+shift)+20;
                 int st=buf[dptr];
                 dptr++;
                 if( (st&0xf8)==0x20 ) { // subtitle
                   
procremap(&crs[st&31],buf+dptr,ml-dptr,&s->audch[st].audpts[s->audch[st].numaudpts-1].pts[1]);
@@ -1368,8 +1465,9 @@
             fprintf(stderr,"\n");
         }
     }
     writeclose();
+    free(buf_copy);
     printvobustatus(va,cursect);
     fprintf(stderr,"\n");
     free(crs);
     return 1;





------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Dvdauthor-developer mailing list
Dvdauthor-developer@...
https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer

dvdauthor-0.6.14-ivtv-patch-0.2 (16K) Download Attachment

Re: ivtv patches gone?

by Lawrence D'Oliveiro-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

martin wrote:

> I think it is almost certainly the same as the one that Joo just posted
 > ...

I have done a diff and verified that they are identical.

Thanks to both of you for resurrecting this. :)

Lawrence

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Dvdauthor-developer mailing list
Dvdauthor-developer@...
https://lists.sourceforge.net/lists/listinfo/dvdauthor-developer