Hi all -

This is a posting about how to generate MPEG material from IVTV which
can be fed directly into dvdauthor without the need to re-multiplex the
audio and video.  Doing this saves a lot of time and subsequent problems
with A/V sync.

I am using a CX23416 based video capture and encoding card (Adaptec
VideOh! AVC-2010), version 1.1.0 of the ivtv driver and Linux
2.6.24.7-92.fc8.  I believe the method described should work with other
CX2341x based cards but YMMV.

I live in the UK so my TV standard is PAL-I (720x576, 25fps) and I'm
capturing in widescreen (16:9) via the Composite-1 input for video and
the line-in input for audio.  Make the necessary changes relevant to
your locale and setup.

There are two things you need to do in order to use IVTV streams direct
into dvdauthor:

        (1) set IVTV to produce the correct format; and
        
        (2) apply some patches to dvdauthor.

I developed the dvdauthor patches waaaay back in 2005, so they are
against an old version (0.6.11).  If I get time in the near future I
will post an updated patch against the current release (0.6.14 at this
time).

Note that the patches to dvdauthor could potentially impact the
compatibility of the disks which that application produces.  They do
however seem to work fine in my standalone players (Sony DVP-S715, Denon
DVD-1920).  I'd welcome any further reports.


- - -   P A R T   1 :   I V T V   S e t t i n g s   - - -

We need to set the driver to produce the following format:

  ivtv0: Stream: MPEG-2 DVD-compatible Stream
  ivtv0: VBI Format: No VBI
  ivtv0: Video:  720x576, 25 fps
  ivtv0: Video:  MPEG-2, 16x9, Variable Bitrate, 2750000, Peak 5000000
  ivtv0: Video:  GOP Size 15, 2 B-Frames, GOP Closure
  ivtv0: Audio:  48 kHz, Layer II, 256 kbps, Stereo, No Emphasis, No CRC

Note: do NOT insert additional navigation packets as they will crash
dvdauthor. For info on mpeg streams, B-frames etc, see
http://www.cs.cf.ac.uk/Dave/Multimedia/node258.html .

So from a clean restart do something like this:

        vl42-ctl -s pal-I
        v4l2-ctl -c stream_type=3
        v4l2-ctl -c insert_navigation_packets=0
        v4l2-ctl -c stream_vbi_format=0
        v4l2-ctl -c video_encoding=1
        vl42-ctl -c video_aspect=2
        v4l2-ctl -c video_bitrate=2750000
        v4l2-ctl -c video_peak_bitrate=5000000
        v4l2-ctl -c video_gop_size=15
        v4l2-ctl -c video_b_frames=2
        v4l2-ctl -c video_gop_closure=1
        v4l2-ctl -c audio_sampling_frequency=1
        v4l2-ctl -c audio_encoding_layer=1
        v4l2-ctl -c audio_layer_ii_bitrate=11
        v4l2-ctl -c audio_stereo_mode=0
        v4l2-ctl -c audio_emphasis=0
        v4l2-ctl -c audio_crc=0
        
For explanation of these options use "v4l2-ctl --list-ctrls-menus" and
"v4l2-ctl --help".  Many settings such as the aspect ratio and the
bitrates are non critical and can be tuned to our requirements - within
the constraints of the DVD standard: see for example
http://www.digitalfaq.com/dvdguides/authorburn/intro.htm .

Now review your configuration using "v4l2-ctl --log-status".  Carefully
compare the output to the one at the top of this section.

Now capture some video:

        cd ~
        mkdir test
        cd test
        cp /dev/video0 ivtv.mpg
        [ after 30secs or so, hit 'ctrl-c' ]
        
Test the file with a reliable application (personally I use xine or
mplayer) to make sure the capture was successful.


- - -   P A R T   2   :   P a t c h i n g   d v d a u t h o r   - - -

As I mentioned above, my patches are currently against version 0.6.11 of
dvdauthor (yes, I know... I'm working on it).  So go and download the
source tarball for version 0.6.11 from sourceforge.  The link is
currently http://sourceforge.net/project/showfiles.php?group_id=59028 .
You need to click on 'show older releases' near the bottom of the page
in order to find the necessary version.

Unpack the source tarball and configure the build environment:

        tar -xzf dvdauthor-0.6.11.tar.gz
        cd dvdauthor-0.6.11
        ./configure
        
Note that you may need to install a couple of dependencies to get a
successful configure (e.g. libdvdread).  I assume you can work that one
out for yourself.

Now apply my patch named "dvdauthor-0.6.11-ivtv-patch.txt".  A copy is
attached to this posting.

        cd dvdauthor-0.6.11
        patch -p0 < dvdauthor-0.6.11-ivtv-patch.txt

                patching file src/da-internal.h
                patching file src/dvdauthor.c
                patching file src/dvdauthor.h
                patching file src/dvdcli.c
                patching file src/dvdvob.c

Now go ahead and build dvdauthor.  Assuming that you already have a more
up-to-date version of the package installed, I suggest doing it like
this so as to preserve your existing build: 

        cd dvdauthor-0.6.11
        make dvdauthor
        cp ./src/dvdauthor ~/bin/ivtvdvdauthor
                [ or somewhere else in your $PATH ]
        
It is normal to get a few compiler warnings during the make but nothing
fatal.  If you get problems check that you did the ./configure correctly
and also that you installed the necessary dependencies (libdvdread etc).


- - -   P A R T   3 :   T r y i n g   i t   o u t   - - -

We should now be able to use the patched version of dvdauthor to encode
the sample video that we captured in part 1.

First we need to create a minimal XML configuration file.  Using your
favorite editor (allegedly some people can't handle the raw power of
'vi') create a file ~/test/config.xml and paste in the following lines:

        <dvdauthor dest="DVD"> 
           <vmgm /> 
           <titleset> 
             <titles>
               <video format="pal"
                 aspect="16:9"
                 resolution="720x576"
                 widescreen="nopanscan" />
               <audio format="mp2"
                 channels="2"
                 samplerate="48khz" />
               <pgc> 
               <vob file="ivtv.mpg" /> 
               </pgc> 
             </titles> 
           </titleset> 
        </dvdauthor>
        
Note that this version of dvdauthor will not reliably auto-detect the
video format (PAL/NTSC) of ivtv material so it is safest to explicitly
specify it like this.
        
Now it is time for the moment of truth:

        cd ~/test
        rm -rf ./DVD
        ivtvdvdauthor -x config.xml
        
The authoring tool may spit out a warning about the Video PTS field
alignment, but if all went well you should now have a DVD file structure
in ~/test/DVD.

You can test the DVD with xine:

        cd ~/test
        xine dvd:`pwd`/DVD/VIDEO_TS/
        
In case you didn't know, you can burn this to a disk using growisofs
(see http://freshmeat.net/projects/dvdrw-tools/ ):

        cd ~/test
        growisofs -Z /dev/dvd -dvd-video DVD
        
        
Et voila!  I hope it worked for you, and that this helps a few people
out.  For the sake of completeness I also attach a text file with some
pertinent details about my system configuration (kernel version etc),
and a personal aide memoir that I use to remind myself how to do nice
anti-aliased menus and buttons with spumux/dvdauthor

MJC
29 May 2008
diff -u src/da-internal.h src/da-internal.h
--- src/da-internal.h	2005-02-01 02:26:19.000000000 +0000
+++ src/da-internal.h	2005-04-24 09:31:54.000000000 +0100
@@ -166,6 +166,7 @@
 
 extern char *entries[];
 extern int jumppad;
+extern int printWarnings;
 extern char *pstypes[];
 
 void write8(unsigned char *p,unsigned char d0,unsigned char d1,
diff -u src/dvdauthor.c src/dvdauthor.c
--- src/dvdauthor.c	2005-02-01 02:26:19.000000000 +0000
+++ src/dvdauthor.c	2005-04-24 13:24:04.000000000 +0100
@@ -38,6 +38,10 @@
 // jumping/calling to a wider number of destinations
 int jumppad=0;
 
+// this flag allows the user to turn off any WARNings that we might not
+// want to see.  Audio discontinuity and re-muxing come to mind.
+int printWarnings=1;
+
 static char *vmpegdesc[4]={"","mpeg1","mpeg2",0};
 static char *vresdesc[6]={"","720xfull","704xfull","352xfull","352xhalf",0};
 static char *vformatdesc[4]={"","ntsc","pal",0};
@@ -230,7 +234,21 @@
     int w;
 
     if( ATTRMATCH(VIDEO_MPEG) ) {
+	
+	//MJC DEBUG CODE
+	//fprintf(stderr, "DEBUG: found VIDEO_MPEG attribute\n");
+	//fprintf(stderr, "\tcalling scanandwarnupdate\n");
+	//fprintf(stderr, "\t\toldval = %s\n", vmpegdesc[va->vd.vmpeg]);
+        //fprintf(stderr, "\t\tnewval = %s\n", s);
+        //fprintf(stderr, "\t\twarnval = %s\n", vmpegdesc[va->vdwarn.vmpeg]);
+	//
+
         w=scanandwarnupdate(&va->vd.vmpeg,s,&va->vdwarn.vmpeg,"mpeg format",vmpegdesc);
+	
+	//MJC DEBUG CODE
+	//fprintf(stderr, "\treturn value was %i\n", w);
+	//
+
         if(w) return w-1;
     }
 
@@ -1040,6 +1058,11 @@
     jumppad=1;
 }
 
+void dvdauthor_disable_warnings()
+{
+    printWarnings=0;
+}
+
 void dvdauthor_vmgm_gen(struct pgc *fpc,struct menugroup *menus,char *fbase)
 {
     DIR *d;
diff -u src/dvdauthor.h src/dvdauthor.h
--- src/dvdauthor.h	2005-02-01 02:26:19.000000000 +0000
+++ src/dvdauthor.h	2005-04-24 09:31:54.000000000 +0100
@@ -63,6 +63,7 @@
 void source_set_filename(struct source *v,const char *s);
 
 void dvdauthor_enable_jumppad();
+void dvdauthor_disable_warnings();
 void dvdauthor_vts_gen(struct menugroup *menus,struct pgcgroup *titles,char *fbase);
 void dvdauthor_vmgm_gen(struct pgc *fpc,struct menugroup *menus,char *fbase);
 
diff -u src/dvdcli.c dvdauthor-0.6.11-ivtv/src/dvdcli.c
--- src/dvdcli.c	2005-02-01 02:26:19.000000000 +0000
+++ src/dvdcli.c	2005-04-24 09:31:54.000000000 +0100
@@ -232,6 +232,8 @@
             "\n\t-x XMLFILE where XMLFILE is a configuration file describing the\n"
             "\t    structure of the DVD to create.  If you use a config file, then you\n"
             "\t    do not need to specify any other options, except -o.\n"
+		"\n\t-w will turn off the WARN: messages telling you to re-multiplex\n"
+		"\t the audio and/or video.\n"
             "\n\t" LONGOPT("--video=VOPTS or ") "-v VOPTS where VOPTS is a plus (+) separated list of\n"
             "\t    video options.  dvdauthor will try to infer any unspecified options.\n"
             "\t\tpal, ntsc, 4:3, 16:9, 720xfull, 720x576, 720x480, 704xfull,\n"
@@ -360,7 +362,7 @@
 
     while(1) {
         struct pgcgroup *vc=va[curva];
-        int c=GETOPTFUNC(argc,argv,"f:o:v:a:s:hc:Cp:Pmtb:Ti:e:x:");
+        int c=GETOPTFUNC(argc,argv,"f:o:v:a:s:hc:Cp:Pmtb:Ti:e:x:w");
         if( c == -1 )
             break;
         switch(c) {
@@ -492,6 +494,10 @@
                 source_add_cell(curvob,0,-1,1,0,0);
             break;
 
+	case 'w':
+		dvdauthor_disable_warnings();
+		break;
+
         default:
             fprintf(stderr,"ERR:  getopt returned bad code %d\n",c);
             return 1;
diff -u src/dvdvob.c dvdauthor-0.6.11-ivtv/src/dvdvob.c
--- src/dvdvob.c	2005-02-10 20:47:32.000000000 +0000
+++ src/dvdvob.c	2005-04-24 13:23:40.000000000 +0100
@@ -58,20 +58,24 @@
     // I assume pts should round down?  That seems to be how mplex deals with it
     // also see later comment
 
+//MJC
     int fpts=getframepts(va);
     int bpframe=(basepts*2-*align+fpts/2)/fpts;
     if( (*align+bpframe*fpts)/2 != basepts ) {
         if( !*didcomplain ) {
             if( cancomplain )
-                fprintf(stderr,"WARN: Video PTS does not line up on a multiple of a field.\n");
+                fprintf(stderr,"(MJC override) WARN: Video PTS does not line up on a multiple of a field.\n");
             *didcomplain=1;
         }
-        *align=basepts;
-    } else
-        nfields += bpframe;
+//        *align=basepts;
+//    } else nfields += bpframe;
+    } nfields += bpframe;
     return (*align+nfields*fpts)/2;
+//MJC
+
 }
 
+
 static int findnextvideo(struct vob *va, int cur, int dir)
 {
     // find next (dir=1) or previous(dir=-1) vobu with video
@@ -225,7 +229,9 @@
     return dflt;
 }
 
-static void transpose_ts(unsigned char *buf,pts_t tsoffs)
+
+//static void transpose_ts(unsigned char *buf,pts_t tsoffs)
+static void transpose_ts(unsigned char *buf,int scroffs, int tsoffs)
 {
     // pack scr
     if( buf[0] == 0 &&
@@ -233,25 +239,62 @@
         buf[2] == 1 &&
         buf[3] == 0xba )
     {
-        writescr(buf+4,readscr(buf+4)+tsoffs);
+//        writescr(buf+4,readscr(buf+4)+tsoffs);
+        int offs = (buf[17] == 0xbb) ? 24 : 0;
+
+        writescr(buf+4,readscr(buf+4)+scroffs);
 
         // 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))
+//        if( buf[14] == 0 &&
+//            buf[15] == 0 &&
+//            buf[16] == 1 &&
+//            (buf[17]==0xbd || (buf[17]>=0xc0 && buf[17]<=0xef)) &&
+//            (buf[21] & 128))
+        if( buf[offs+14] == 0 &&
+            buf[offs+15] == 0 &&
+            buf[offs+16] == 1 &&
+            (buf[offs+17]==0xbd || (buf[offs+17]>=0xc0 && buf[offs+17]<=0xef)) &&
+            (buf[offs+21] & 128))
         {
-            writepts(buf+23,readpts(buf+23)+tsoffs);
+//            writepts(buf+23,readpts(buf+23)+tsoffs);
+            writepts(buf+offs+23,readpts(buf+offs+23)+tsoffs);
             // dts?
-            if( buf[21] & 64 ) {
-                writepts(buf+28,readpts(buf+28)+tsoffs);
+//            if( buf[21] & 64 ) {
+//                writepts(buf+28,readpts(buf+28)+tsoffs);
+            if( buf[offs+21] & 64 ) {
+                writepts(buf+offs+28,readpts(buf+offs+28)+tsoffs);
             }
         }
     }
 }
 
+int find_gop(unsigned char *buf)
+{
+    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];
@@ -533,8 +576,14 @@
         if( buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 )
             scanvideoptr(va,buf+i,thisvi,cursect,vsi);
     }
+
+
+//MJC: change default behaviour here to avoid incorrect missed detection of format in ivtv streams
     if( !va->vd.vmpeg )
-        vobgroup_set_video_attr(va,VIDEO_MPEG,"mpeg1");
+	//vobgroup_set_video_attr(va,VIDEO_MPEG,"mpeg1");
+	vobgroup_set_video_attr(va,VIDEO_MPEG,"mpeg2");
+
+
     // if the mpeg version changed, then rerun scanvideoframe, because
     // scanvideoptr updates the aspect ratio in the sequence header
     if( mpf != va->vd.vmpeg ) {
@@ -809,6 +858,7 @@
 int FindVobus(char *fbase,struct vobgroup *va,int ismenu)
 {
     unsigned char *buf;
+    unsigned char *buf_copy = (unsigned char*) malloc(2048);;
     FILE *h;
     int cursect=0,fsect=-1,vnum,outnum=-ismenu+1;
     int ispipe,vobid=0;
@@ -823,6 +873,7 @@
         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;
@@ -850,8 +901,12 @@
             }
             buf=writegrabbuf();
 
-            i=fread(buf,1,2048,h);
-            if( i!=2048 ) {
+	    if (copy_packet == 1 ) {
+                memcpy( buf, buf_copy, 2048);
+            } else if( 2048 != (i=fread(buf,1,2048,h)) ) {
+
+//            i=fread(buf,1,2048,h);
+//            if( i!=2048 ) {
                 if( i==-1 ) {
                     fprintf(stderr,"\nERR:  Error while reading: %s\n",strerror(errno));
                     exit(1);
@@ -956,6 +1011,42 @@
                 writeundo();
                 continue;
             }
+
+// new section from patch
+            if( fsect == -1 ) {
+                char newname[200];
+                fsect=0;
+	        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,"Found GOP with no 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;
+// end of new section
+
             if( buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba ) {
                 pts_t newscr=readscr(buf+4);
                 if( newscr < lastscr ) {
@@ -966,15 +1057,27 @@
                 if( !hadfirstvobu )
                     backoffs=newscr;
             }
-            transpose_ts(buf,-backoffs);
-            if( fsect == -1 ) {
-                char newname[200];
-                fsect=0;
-                if( outnum>=0 )
-                    sprintf(newname,"%s_%d.VOB",fbase,outnum);
-                else
-                    strcpy(newname,fbase);
-                writeopen(newname);
+//            transpose_ts(buf,-backoffs);
+//            if( fsect == -1 ) {
+//                char newname[200];
+//                fsect=0;
+//                if( outnum>=0 )
+//                    sprintf(newname,"%s_%d.VOB",fbase,outnum);
+//                else
+//                    strcpy(newname,fbase);
+//                writeopen(newname);
+
+// new section from patch
+            if( !hadfirstvobu && buf[0]==0 && buf[1]==0 && buf[2]==1 && buf[3]==0xba )
+            {
+                int offs = (buf[17] == 0xbb) ? 24 : 0;
+                if( buf[offs+14] == 0 &&
+                    buf[offs+15] == 0 &&
+                    buf[offs+16] == 1 &&
+                    (buf[offs+17]==0xbd || (buf[offs+17]>=0xc0 && buf[offs+17]<=0xef)) &&
+                    (buf[offs+21] & 128))
+	                    tsoffs = readpts(buf+offs+23);
+// end of new section
             }
             if( buf[14] == 0 &&
                 buf[15] == 0 &&
@@ -1020,12 +1123,13 @@
                         printvobustatus(va,cursect);
                     vsi.lastrefsect=0;
                     vsi.firstgop=1;
-                } else {
+//                } 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 ) {
-                fprintf(stderr,"WARN: Skipping sector, waiting for first VOBU...\n");
+//                fprintf(stderr,"WARN: Skipping sector, waiting for first VOBU...\n");
                 writeundo();
                 continue;
             }
@@ -1155,20 +1259,48 @@
                         if( ach->audpts[ach->numaudpts-1].pts[1]<pts0 ) {
                             if( audch>=32 )
                                 goto noshow;
-                            fprintf(stderr,"WARN: Discontinuity in audio channel %d; please remultiplex input.\n",audch);
-                        } else if( ach->audpts[ach->numaudpts-1].pts[1]>pts0 )
-                            fprintf(stderr,"WARN: Audio pts for channel %d moves backwards; please remultiplex input.\n",audch);
+
+//                            fprintf(stderr,"WARN: Discontinuity in audio channel %d; please remultiplex input.\n",audch);
+//                        } else if( ach->audpts[ach->numaudpts-1].pts[1]>pts0 )
+//                            fprintf(stderr,"WARN: Audio pts for channel %d moves backwards; please remultiplex input.\n",audch);
+
+// new section from patch
+                            if (printWarnings)
+                                fprintf(stderr,"WARN: Discontinuity in audio channel %d; please remultiplex input.\n",audch);
+                        } else if( ach->audpts[ach->numaudpts-1].pts[1]>pts0 ) {
+                            if (printWarnings)
+                                fprintf(stderr,"WARN: Audio pts for channel %d moves backwards; please remultiplex input.\n",audch);
+			}
+// end of new section
+
+                                                                
                         else
                             goto noshow;
-                        fprintf(stderr,"WARN: Previous sector: ");
-                        printpts(ach->audpts[ach->numaudpts-1].pts[0]);
-                        fprintf(stderr," - ");
-                        printpts(ach->audpts[ach->numaudpts-1].pts[1]);
-                        fprintf(stderr,"\nWARN: Current sector: ");
-                        printpts(pts0);
-                        fprintf(stderr," - ");
-                        printpts(pts1);
-                        fprintf(stderr,"\n");
+//                        fprintf(stderr,"WARN: Previous sector: ");
+//                        printpts(ach->audpts[ach->numaudpts-1].pts[0]);
+//                        fprintf(stderr," - ");
+//                        printpts(ach->audpts[ach->numaudpts-1].pts[1]);
+//                        fprintf(stderr,"\nWARN: Current sector: ");
+//                        printpts(pts0);
+//                        fprintf(stderr," - ");
+//                        printpts(pts1);
+//                        fprintf(stderr,"\n");
+
+// new section from patch
+                        if (printWarnings)
+                        {
+                            fprintf(stderr,"WARN: Previous sector: ");
+                            printpts(ach->audpts[ach->numaudpts-1].pts[0]);
+                            fprintf(stderr," - ");
+                            printpts(ach->audpts[ach->numaudpts-1].pts[1]);
+                            fprintf(stderr,"\nWARN: Current sector: ");
+                            printpts(pts0);
+                            fprintf(stderr," - ");
+                            printpts(pts1);
+                            fprintf(stderr,"\n");
+                        }
+// end of new section
+
                         ach->audpts[ach->numaudpts-1].pts[1]=pts0;
                     }
                 noshow:
@@ -1342,6 +1474,7 @@
         }
     }
     writeclose();
+    free(buf_copy);
     printvobustatus(va,cursect);
     fprintf(stderr,"\n");
     free(crs);
@@ -1640,10 +1773,16 @@
                 if( s>=0 ) {
                     s=s-vi->sector;
                     if( s > 0x1fff || s < -(0x1fff)) {
-                        fprintf(stderr,"\nWARN: audio sector out of range: %d (vobu #%d, pts ",s,i);
-                        printpts(vi->sectpts[0]);
-                        fprintf(stderr,")\n");
-                        s=0;
+
+// new and potantially dangerous override
+			if(printWarnings) {
+                        	fprintf(stderr,"\nWARN: audio sector out of range: %d (vobu #%d, pts ",s,i);
+                        	printpts(vi->sectpts[0]);
+                        	fprintf(stderr,")\n");
+                        	s=0;
+			}
+//
+
                     }
                     if( s < 0 )
                         s=(-s)|0x8000;
MJC notes on how to make a DVD with animated menus and anti-aliased text
started 26 July 2006

notes: this is what I used to do the 'ER' DVDs

NOTE ON ASPECT RATIOS
----------
Normal 16:9 video material has a resolution of 720x576 but the pixels are not 
square.  So when you are doing your text overlays for the menus you need to 
draw them on a image with a resolution of 1024x576 - and then resize the 
completed result to 720x576.  This will mean that text (and for that matter 
graphics) will display as intended when the DVD is played on a widescreen TV.

----------
1. capture mpeg clip to use as the intro - i.e. the short clip that plays 
before the menu comes up

[detailed instructions on how to do this will go here]

----------
2. capture mpeg clip which will form the menu background

[same method as above]

----------
3. demux the menu clip into seperate audio and video files

tcextract -imenu_clip.mpg -tvob -a0 -xmp2 -d0 > menu_clip_audio.mp2
tcextract -imenu_clip.mpg -xmpeg2 -d0 > menu_clip_video.m2v

[from ~/video_scripts/demux_ivtv.sh]

----------
4. extract menu video frames to a sequence of PPM images

mkdir menu_clip_frames
transcode -imenu_video.m2v -o./menu_clip_frames/ -xmpeg2,null -yppm,null 
-Y0,10,6,12 -Z742x582

[the -Y and -Z are to remove capture card border. Omit for DVD material.]
[don't mess with --export_asr or --input_asr.  Transcode knows what it's doing.]

[from ~/video_scripts/extract_ivtv_frames.sh]

----------
5. make a template for the menu text

open any one of the menu clip frames using GIMP
resize to 1024x576
position guides as required to align text
create layer 'background text' and add text that will be visible all the time
create layer 'highlight text' and add text that will only be visible when a 
button is highlighted
create layer 'highlight colour' and fill it completely with the highlight text 
colour
position more guides at the corners of all buttons
save as 'menu_stack.xcf'
resize to 720x576
note the coordinates of all button corners
save as 'menu_stack_resized.xcf'

[to make text blurred, use 'create path from text' each time you use the text 
tool then stroke the path with brush circle fuzzy 09.  When all text is done, 
merge visible layers then finish with 5 pixel gaussian blur]


----------
6. overlay background text onto menu frames

open menu_stack_resized.xcf using GIMP
create a working copy [image->duplicate] and close original image
delete all layers except 'background text'
save as 'menu_overlay.xcf'
close image
open the first menu clip frame
use my 'animated gallery' plug-in to overlay menu_overlay.xcf to each frame 
[python-fu->alchemy->animated gallery]
set number of frames=0,
        directory path=directory above 'menu_clip_frames',
        Animation 1=menu_overlay.xcf (all others set to OFF)
        output filename=menu_background_frames/000000.xcf
close and exit

[note: if there are a LOT of frames, do them in sections or GIMP will die]

----------
7. assemble menu background frames into M2V video

cd menu_background_frames
cat ./*.ppm | ppmtoy4m -v1 -F25:1 -A59:54 -Ip -S420mpeg2 | mpeg2enc -v1 -f8 
-b9000 -V237 -F3 -a2 -q1 -g10 -G15 -Q0.0 -H -D10 -o ../menu_background_video.m2v

[from ~/video_scripts/ppm-to-m2v.sh]


----------
8. multiplex the audio back in

mplex -v1 -V -omenu_background.mpg -f8 menu_background.m2v menu_clip_audio.mp2


----------
9. create custom GIMP palette (if not already present)

open GIMP
open palette dialogue [file->dialogues->palettes]
click 'new palette' button
set name as '4 colour grey'
set foreground colour to white
click 'new colour from FG' button
edit foreground colour to HTML AAAAAA
click 'new colour from FG' button
repeat for colours 555555 and finally 000000
click 'save palette' button


----------
10. create anti-aliased 4 colour PNG images for buttons

open menu_stack_resized.xcf using GIMP
create a working copy [image->duplicate] and close original image
delete all layers except 'highlight text'
decompose to RGBA [image->mode->decompose->rgba]
delete the red, green and blue layers
select the alpha layer
open the 'convert to indexed' dialogue [image->mode->indexed]
select 'use custom palette'
click on the mini-palette icon and select '4 colour grey' palette
select colour dithering 'none'
click 'OK'
convert back to greyscale [image->mode->greyscale]
switch back to the un-decomposed image
use 'undo' [ctrl-Z] to undelete the 'highlight colour' layer
delete all other layers
decompose to RGB [image->mode->decompose->RGB]
close the un-decomposed image [no need to save]
return to the image with the quantised alpha layer
drag the 'alpha' layer from the layers dialogue and drop it onto the decomposed 
RGB image
close the quantised alpha layer image [no need to save]
re-compose the decomposed RGB image, with the new Alpha layer 
[image->mode->compose->RGBA]
save as 'menu_highlight.png' [all 'save as PNG' options boxes should be 
unticked]
close the composed image
return to the 4-layer decomposed image
fill the Red, Green and Blue layers with required colour for 'select' [normally 
all white]
re-compose RGBA as above
save as 'menu_select.png'
close and exit


----------
11. create XML file describing button positions

refer to the notes of the coordinates of the button corners on 
menu_stack_resized.xcf (720x576)
create file buttons.xml, based on example below:

<subpictures>
        <stream>
                <spu
                        start="00:00:00.00"
                        transparent="000000"
                        highlight="menu_highlight.png"
                        select="menu_select.png"
                        force="yes"
                >
                        <button name="1" x0="230" y0="400" x1="600" y1="452"/>
                        <button name="2" x0="230" y0="453" x1="600" y1="505"/>
                        <button name="3" x0="230" y0="506" x1="600" y1="557"/>
                </spu>
        </stream>
</subpictures>


----------
12. multiplex buttons into background MPG

spumux -mdvd -v2 buttons.xml < menu_background.mpg > menu_with_buttons.mpg


----------
13. create suitable dvd layout XML file

create file dvd_layout.xml, based on the following example:

<dvdauthor>
        <vmgm>
                <menus lang="EN">
                        <video format="pal" aspect="16:9"></video>
                        <audio format="mp2" lang="EN"></audio>
                        <pgc entry="title">
                                <vob file="intro.mpg" pause="1"></vob>
                                <post>jump titleset 1 menu;</post>
                        </pgc>
                </menus>
        </vmgm>

        <titleset>
                <menus>
                        <video format="pal" aspect="16:9"></video>
                        <audio format="mp2" lang="EN"></audio>
                        <pgc entry="root">
                                <vob file="menu_with_buttons.mpg"></vob>
                                <button name="1">jump title 1 chapter 
1;</button>
                                <button name="2">jump title 2 chapter 
1;</button>
                                <button name="3">jump title 3 chapter 
1;</button>
                                <post>jump cell 1;</post>
                        </pgc>
                </menus>
                <titles>
                        <video format="pal" aspect="16:9"></video>
                        <audio format="mp2" lang="EN"></audio>
                        <pgc>
                                <vob file="clip1.mpg" chapters="0"></vob>
                                <post>call menu entry root;</post>
                        </pgc>
                        <pgc>
                                <vob file="clip2.mpg" chapters="0"></vob>
                                <post>call menu entry root;</post>
                        </pgc>
                        <pgc>
                                <vob file="clip1.mpg" chapters="0"></vob>
                                <post>call menu entry root;</post>
                        </pgc>
                </titles>
        </titleset>
</dvdauthor>


---------
14. author the DVD

rm -r DVD
dvdauthor -w -o DVD -x dvd_layout.xml


---------
15. test the DVD image

xine dvd:/full/path/to/DVD


---------
16. burn the DVD

su to root
pkill hald
[insert blank DVD-R]
growisofs -Z /dev/dvd -dvd-video DVD

[from ~/video_scripts/burn_dvd.sh]
$ uname -srvp
        Linux 2.6.24.7-92.fc8 #1 SMP Wed May 7 16:50:09 EDT 2008 i686

# lspci -vv
        03:0b.0 Multimedia video controller: Internext Compression Inc
        iTVC16 (CX23416) MPEG-2 Encoder (rev 01)
                Subsystem: Adaptec VideOh! AVC-2010
                Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+
        VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
                Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium 
>TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
                Latency: 64 (32000ns min, 2000ns max), Cache Line Size: 16 bytes
                Interrupt: pin A routed to IRQ 16
                Region 0: Memory at e8000000 (32-bit, prefetchable)
        [size=64M]
                Capabilities: [44] Power Management version 2
                        Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA 
PME(D0-,D1-,D2-,D3hot-,D3cold-)
                        Status: D0 PME-Enable- DSel=0 DScale=0 PME-
                Kernel driver in use: ivtv
                Kernel modules: ivtv

$ dmesg
        <snip>
        Linux video capture interface: v2.00
        ivtv:  Start initialization, version 1.1.0
        ivtv0: Initializing card #0$ uname -srvp
        Linux 2.6.24.7-92.fc8 #1 SMP Wed May 7 16:50:09 EDT 2008 i686

# lspci -vv
        03:0b.0 Multimedia video controller: Internext Compression Inc
        iTVC16 (CX23416) MPEG-2 Encoder (rev 01)
                Subsystem: Adaptec VideOh! AVC-2010
                Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+
        VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
                Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium
        >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
                Latency: 64 (32000ns min, 2000ns max), Cache Line Size:
        16 bytes
                Interrupt: pin A routed to IRQ 16
                Region 0: Memory at e8000000 (32-bit, prefetchable)
        [size=64M]
                Capabilities: [44] Power Management version 2
                        Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
        PME(D0-,D1-,D2-,D3hot-,D3cold-)
                        Status: D0 PME-Enable- DSel=0 DScale=0 PME-
                Kernel driver in use: ivtv
                Kernel modules: ivtv

$ dmesg
        <snip>
        Linux video capture interface: v2.00
        ivtv:  Start initialization, version 1.1.0
        ivtv0: Initializing card #0
        ivtv0: Autodetected Adaptec VideOh! AVC-2010 card (cx23416
        based)
        ACPI: PCI Interrupt 0000:03:0b.0[A] -> GSI 23 (level, low) ->
        IRQ 16
        saa7115 1-0021: saa7115 found (1f7115d0e100000) @ 0x42 (ivtv i2c
        driver #0)
        cs53l32a 1-0011: chip found @ 0x22 (ivtv i2c driver #0)
        ivtv0: Registered device video0 for encoder MPG (4096 kB)
        ivtv0: Registered device video32 for encoder YUV (2048 kB)
        ivtv0: Registered device vbi0 for encoder VBI (1024 kB)
        ivtv0: Registered device video24 for encoder PCM (320 kB)
        ivtv0: Initialized card #0: Adaptec VideOh! AVC-2010
        ivtv:  End initialization
        <snip>
        ivtv0: Loaded v4l-cx2341x-enc.fw firmware (376836 bytes)
        ivtv0: Encoder revision: 0x02060039
        <snip>

$ modinfo ivtv
        filename:       
/lib/modules/2.6.24.7-92.fc8/kernel/drivers/media/video/ivtv/ivtv.ko
        version:        1.1.0
        license:        GPL
        description:    CX23415/CX23416 driver
        author:         Kevin Thayer, Chris Kennedy, Hans Verkuil
        srcversion:     D6CC38A86F1DF58DD1BA944
        <snip>
        
$ lsmod |grep ivtv
        ivtv                  120577  0 
        i2c_algo_bit            9029  1 ivtv
        cx2341x                14149  1 ivtv
        tveeprom               17489  1 ivtv
        videodev               27713  1 ivtv
        v4l2_common            18497  5
        cs53l32a,saa7115,ivtv,cx2341x,videodev
        v4l1_compat            15813  2 ivtv,videodev
        i2c_core               21057  6
        cs53l32a,saa7115,ivtv,i2c_algo_bit,tveeprom,i2c_i801

$ v4l2-ctl --log-status
   ivtv0: =================  START STATUS CARD #0  =================
   ivtv0: Version: 1.1.0 Card: Adaptec VideOh! AVC-2010
   saa7115 1-0021: Audio frequency: 48000 Hz
   saa7115 1-0021: Input:           Composite 3
   saa7115 1-0021: Video signal:    broadcast/DVD
   saa7115 1-0021: Frequency:       50 Hz
   saa7115 1-0021: Detected format: PAL
   saa7115 1-0021: Width, Height:   720, 576
   cs53l32a 1-0011: Input:  2
   cs53l32a 1-0011: Volume: 0 dB
   ivtv0: Video Input:  Composite 1
   ivtv0: Audio Input:  Line In 1
   ivtv0: Tuner:  TV
   ivtv0: Stream: MPEG-2 DVD-compatible Stream
   ivtv0: VBI Format: No VBI
   ivtv0: Video:  720x576, 25 fps
   ivtv0: Video:  MPEG-2, 16x9, Variable Bitrate, 2750000, Peak 5000000
   ivtv0: Video:  GOP Size 15, 2 B-Frames, GOP Closure
   ivtv0: Audio:  48 kHz, Layer II, 256 kbps, Stereo, No Emphasis, No
CRC
   ivtv0: Spatial Filter:  Manual, Luma 1D Horizontal, Chroma 1D
Horizontal, 0
   ivtv0: Temporal Filter: Manual, 8
   ivtv0: Median Filter:   Off, Luma [0, 255], Chroma [0, 255]
   ivtv0: Status flags:    0x00200000
   ivtv0: Stream encoder MPG: status 0x0000, 0% of 4096 KiB (128
buffers) in use
   ivtv0: Stream encoder YUV: status 0x0000, 0% of 2056 KiB (195
buffers) in use
   ivtv0: Stream encoder VBI: status 0x0000, 0% of 1040 KiB (61 buffers)
in use
   ivtv0: Stream encoder PCM: status 0x0000, 0% of 324 KiB (72 buffers)
in use
   ivtv0: Read MPG/VBI: 10360768/0 bytes
   ivtv0: ==================  END STATUS CARD #0  ==================

        ivtv0: Autodetected Adaptec VideOh! AVC-2010 card (cx23416 based)
        ACPI: PCI Interrupt 0000:03:0b.0[A] -> GSI 23 (level, low) -> IRQ 16
        saa7115 1-0021: saa7115 found (1f7115d0e100000) @ 0x42 (ivtv i2c driver 
#0)
        cs53l32a 1-0011: chip found @ 0x22 (ivtv i2c driver #0)
        ivtv0: Registered device video0 for encoder MPG (4096 kB)
        ivtv0: Registered device video32 for encoder YUV (2048 kB)
        ivtv0: Registered device vbi0 for encoder VBI (1024 kB)
        ivtv0: Registered device video24 for encoder PCM (320 kB)
        ivtv0: Initialized card #0: Adaptec VideOh! AVC-2010
        ivtv:  End initialization
        <snip>
        ivtv0: Loaded v4l-cx2341x-enc.fw firmware (376836 bytes)
        ivtv0: Encoder revision: 0x02060039
        <snip>

$ modinfo ivtv
        filename:       
/lib/modules/2.6.24.7-92.fc8/kernel/drivers/media/video/ivtv/ivtv.ko
        version:        1.1.0
        license:        GPL
        description:    CX23415/CX23416 driver
        author:         Kevin Thayer, Chris Kennedy, Hans Verkuil
        srcversion:     D6CC38A86F1DF58DD1BA944
        <snip>
        
$ lsmod |grep ivtv
        ivtv                  120577  0 
        i2c_algo_bit            9029  1 ivtv
        cx2341x                14149  1 ivtv
        tveeprom               17489  1 ivtv
        videodev               27713  1 ivtv
        v4l2_common            18497  5
        cs53l32a,saa7115,ivtv,cx2341x,videodev
        v4l1_compat            15813  2 ivtv,videodev
        i2c_core               21057  6
        cs53l32a,saa7115,ivtv,i2c_algo_bit,tveeprom,i2c_i801

$ v4l2-ctl --log-status
   ivtv0: =================  START STATUS CARD #0  =================
   ivtv0: Version: 1.1.0 Card: Adaptec VideOh! AVC-2010
   saa7115 1-0021: Audio frequency: 48000 Hz
   saa7115 1-0021: Input:           Composite 3
   saa7115 1-0021: Video signal:    broadcast/DVD
   saa7115 1-0021: Frequency:       50 Hz
   saa7115 1-0021: Detected format: PAL
   saa7115 1-0021: Width, Height:   720, 576
   cs53l32a 1-0011: Input:  2
   cs53l32a 1-0011: Volume: 0 dB
   ivtv0: Video Input:  Composite 1
   ivtv0: Audio Input:  Line In 1
   ivtv0: Tuner:  TV
   ivtv0: Stream: MPEG-2 DVD-compatible Stream
   ivtv0: VBI Format: No VBI
   ivtv0: Video:  720x576, 25 fps
   ivtv0: Video:  MPEG-2, 16x9, Variable Bitrate, 2750000, Peak 5000000
   ivtv0: Video:  GOP Size 15, 2 B-Frames, GOP Closure
   ivtv0: Audio:  48 kHz, Layer II, 256 kbps, Stereo, No Emphasis, No CRC
   ivtv0: Spatial Filter:  Manual, Luma 1D Horizontal, Chroma 1D Horizontal, 0
   ivtv0: Temporal Filter: Manual, 8
   ivtv0: Median Filter:   Off, Luma [0, 255], Chroma [0, 255]
   ivtv0: Status flags:    0x00200000
   ivtv0: Stream encoder MPG: status 0x0000, 0% of 4096 KiB (128 buffers) in use
   ivtv0: Stream encoder YUV: status 0x0000, 0% of 2056 KiB (195 buffers) in use
   ivtv0: Stream encoder VBI: status 0x0000, 0% of 1040 KiB (61 buffers) in use
   ivtv0: Stream encoder PCM: status 0x0000, 0% of 324 KiB (72 buffers) in use
   ivtv0: Read MPG/VBI: 10360768/0 bytes
   ivtv0: ==================  END STATUS CARD #0  ==================

_______________________________________________
ivtv-users mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-users

Reply via email to