--- mythburn_dist.py	2010-01-26 06:14:12.000000000 +0000
+++ mythburn.py	2010-04-19 15:32:29.483036033 +0100
@@ -1,4 +1,7 @@
 #!/usr/bin/env python2.6
+# -*- coding: utf-8 -*-
+# This 'coding utf-8' line was suggested by the konqueror embedded editor
+
 # mythburn.py
 # The ported MythBurn scripts which feature:
 
@@ -24,8 +27,9 @@
 #dvd+rw-tools - v5.21.4.10.8
 #cdrtools - v2.01
 
-#Optional (only needed for tcrequant)
-#transcode - v1.0.2
+#Optional for shrink-to-fit requantisation 
+#M2VRequantiser (from flexion, based on the newer code from Metakine) 
+#replaces the deprecated tcrequant from transcode - v1.0.2
 
 #Optional (for Right To Left languages)
 #pyfribidi
@@ -38,7 +42,8 @@
 #******************************************************************************
 
 # version of script - change after each update
-VERSION="0.1.20090139-1"
+VERSION="0.1.20090139-1_jp_for_mp2, bitrate-capped_requant"
+
 
 # keep all temporary files for debugging purposes
 # set this to True before a first run through when testing
@@ -54,7 +59,8 @@
 debug_secondrunthrough = False
 
 # default encoding profile to use
-defaultEncodingProfile = "SP"
+# defaultEncodingProfile = "SP"
+defaultEncodingProfile = "NONE"
 
 # add audio sync offset when re-muxing
 useSyncOffset = True
@@ -94,6 +100,7 @@
 
 #Single and dual layer recordable DVD free space in MBytes
 dvdrsize=(4482,8106)
+#dvdrsize=(400,8106)  # for quicker tests
 
 frameratePAL=25
 framerateNTSC=29.97
@@ -147,8 +154,10 @@
 dvddrivepath = "/dev/dvd"
 
 #default option settings
-docreateiso = False
-doburn = True
+# docreateiso = False
+# doburn = True
+docreateiso = True
+doburn = False
 erasedvdrw = False
 mediatype = DVD_SL
 savefilename = ''
@@ -243,8 +252,12 @@
     sys.stdout.flush()
 
     if progress == True and progresslog != "":
-        progressfile.write(time.strftime("%Y-%m-%d %H:%M:%S ") + text + "\n")
-        progressfile.flush()
+      if len(text)<30 :
+         progressfile.write(time.strftime("%H:%M:%S  %Y-%m-%d ") + text + "\n")
+      else:
+         progressfile.write(time.strftime("%H:%M:%S ") + text + "\n")
+
+      progressfile.flush()
 
 #############################################################
 # Display an error message and exit
@@ -462,6 +475,13 @@
     return result
 
 #############################################################
+# Truncate to even value ( to silence 'odd y-coordinate' complaints)
+
+def even(num):
+    evennum = int(num / 2) * 2
+    return evennum
+
+#############################################################
 # Convert a time in seconds to a frame number
 
 def secondsToFrames(seconds):
@@ -485,22 +505,25 @@
 
     totalframes=int(musiclength * framespersecond)
 
-    command = path_jpeg2yuv[0] + " -n %s -v0 -I p -f %s -j '%s' | %s -b 5000 -a %s -v 1 -f 8 -o '%s'" \
+    command = "ionice -c3 " 
+    command += path_jpeg2yuv[0] + " -n %s -v 0 -I p -f %s -j '%s' | %s -b 5000 -a %s -v 0 -f 8 -o '%s'" \
               % (totalframes, framespersecond, background, path_mpeg2enc[0], aspectratio, tempvideo)
     result = runCommand(command)
     if result<>0:
-        fatalError("Failed while running jpeg2yuv - %s" % command)
+        fatalError("Failed while running:  %s" % command)
 
-    command = path_mplex[0] + " -f 8 -v 0 -o '%s' '%s' '%s'" % (tempmovie, tempvideo, music)
+    command ="ionice -c3 " 
+    command += path_mplex[0] + " -f 8 -v 0 -o '%s' '%s' '%s'" % (tempmovie, tempvideo, music)
     result = runCommand(command)
     if result<>0:
-        fatalError("Failed while running mplex - %s" % command)
+        fatalError("Failed while running: %s" % command)
 
     if xmlfile != "":
-        command = path_spumux[0] + " -m dvd -s 0 '%s' < '%s' > '%s'" % (xmlfile, tempmovie, finaloutput)
+        command ="ionice -c3 " 
+        command += path_spumux[0] + " -m dvd -s 0 '%s' < '%s' > '%s'" % (xmlfile, tempmovie, finaloutput)
         result = runCommand(command)
         if result<>0:
-            fatalError("Failed while running spumux - %s" % command)
+            fatalError("Failed while running: %s" % command)
     else:
         os.rename(tempmovie, finaloutput)
 
@@ -1875,7 +1898,8 @@
         result=os.spawnlp(mode, path_mplex[0], path_mplex[1],
                     '-M',
                     '-f', '8',
-                    '-v', '0',
+                    '-b', '500', '-r', '16000',
+                    '-v', '1',
                     '--sync-offset', '%sms' % syncOffset,
                     '-o', destination,
                     video,
@@ -1897,7 +1921,7 @@
         return result
     else:
         if result != 0:
-            fatalError("mplex failed with result %d" % result)
+           nonfatalError("mplex failed with result %d" % result)
 
     # run spumux to add subtitles if they exist
     if os.path.exists(os.path.dirname(destination) + "/stream.d/spumux.xml"):
@@ -1908,7 +1932,8 @@
             fatalError("Failed while running testsubtitlepngs.sh - %s" % command)
 
         write("Running spumux to add subtitles")
-        command = path_spumux[0] + " -P %s/stream.d/spumux.xml <%s >%s" % (os.path.dirname(destination), destination, os.path.splitext(destination)[0] + "-sub.mpg")
+        command ="ionice -c3 " 
+        command += path_spumux[0] + " -P %s/stream.d/spumux.xml <%s >%s" % (os.path.dirname(destination), destination, os.path.splitext(destination)[0] + "-sub.mpg")
         result = runCommand(command)
         if result<>0:
             nonfatalError("Failed while running spumux.\n"
@@ -2053,7 +2078,8 @@
     qfile = quoteFilename(file)
     qcutlist = os.path.join(folder, "cutlist_x.txt")
 
-    command = path_projectx[0] + " -id %s" % getStreamList(folder)
+    command ="ionice -c3 " 
+    command += path_projectx[0] + " -id %s" % getStreamList(folder)
     if usecutlist == True:
         command += " -cut %s -out %s -name %s %s" % (qcutlist, qdestdir, qpxbasename, qfile)
     else:
@@ -2078,7 +2104,8 @@
         if (os.path.exists(os.path.join(folder, "stream.sup")) and
             os.path.exists(os.path.join(folder, "stream.sup.IFO"))):
             write("Found DVB subtitles converting to DVD subtitles")
-            command = "mytharchivehelper --sup2dast "
+            command ="ionice -c3 " 
+            command += "mytharchivehelper --sup2dast "
             command += " %s %s 0" % (os.path.join(folder, "stream.sup"), os.path.join(folder, "stream.sup.IFO"))
 
             result = runCommand(command)
@@ -2220,12 +2247,12 @@
 # convert time stamp to pts
 
 def ts2pts(time):
-    h = int(time[0:2]) * 3600 * 90000
-    m = int(time[3:5]) * 60 * 90000
-    s = int(time[6:8]) * 90000
-    ms = int(time[9:11])
-
-    return h + m + s + ms
+    h =  int(time[0:2])  
+    m =  int(time[3:5]) + 60 * h
+    s =  int(time[6:8]) + 60 * m 
+    ms = int(time[9:11]) + 1000 * s
+#         original clumsy and did not convert ms  JP
+    return  ms * 90
 
 #############################################################
 # check the given spumux.xml file for consistancy
@@ -2289,7 +2316,8 @@
 
         source = quoteFilename(source)
 
-        command = "mytharchivehelper -t  %s '%s' %s" % (source, seconds, destination)
+        command ="ionice -c3 " 
+        command += "mytharchivehelper -t  %s '%s' %s" % (source, seconds, destination)
         result = runCommand(command)
         if result <> 0:
             fatalError("Failed while running mytharchivehelper to get thumbnails.\n"
@@ -2555,10 +2583,16 @@
 
 def runDVDAuthor():
     write( "Starting dvdauthor")
-    checkCancelFlag()
-    result=os.spawnlp(os.P_WAIT, path_dvdauthor[0],path_dvdauthor[1],'-x',os.path.join(getTempPath(),'dvdauthor.xml'))
+#    checkCancelFlag()
+#    result=os.spawnlp(os.P_WAIT, path_dvdauthor[0],path_dvdauthor[1],'-x',os.path.join(getTempPath(),'dvdauthor.xml'))
+    command ="ionice -c3 " 
+    command += path_dvdauthor[0] + ' -x ' + os.path.join(getTempPath(),'dvdauthor.xml')
+
+    write("Command is %s " % command) 
+    result = runCommand(command)
+
     if result<>0:
-        fatalError("Failed while running dvdauthor. Result: %d" % result)
+      nonfatalError("Failed while running dvdauthor. Result: %d" % result)
     write( "Finished  dvdauthor")
 
 #############################################################
@@ -2567,18 +2601,24 @@
 def CreateDVDISO(title):
     write("Creating ISO image")
     checkCancelFlag()
-    command = path_mkisofs[0] + ' -dvd-video '
+#    command = path_mkisofs[0] + ' -dvd-video  -quiet '
+    command ="ionice -c3 " 
+    command += path_mkisofs[0] + ' -dvd-video '
     command += ' -V ' + quoteFilename(title)
     command += ' -o ' + os.path.join(getTempPath(), 'mythburn.iso')
     command += " " + os.path.join(getTempPath(),'dvd')
 
+    write("Command is %s " % command) 
     result = runCommand(command)
 
     if result<>0:
         fatalError("Failed while running mkisofs.\n"
                    "Command was %s" % command)
 
-    write("Finished creating ISO image")
+    vobsize = os.path.getsize(os.path.join(getTempPath(), 'mythburn.iso'))
+    write("Finished creating mythburn.iso, size %.2f Mb." % (float(vobsize)/(1024.0*1024.0)) )
+    write("DVD capacities are %s, %s Mb " % ( dvdrsize[0], dvdrsize[1]) )
+
 
 #############################################################
 # Burns the contents of a directory to create a DVD 
@@ -2586,7 +2626,6 @@
 def BurnDVDISO(title):
     write( "Burning ISO image to %s" % dvddrivepath)
     checkCancelFlag()
-
     finished = False
     tries = 0
     while not finished and tries < 10:
@@ -2669,7 +2708,8 @@
 def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):
 
     if getFileType(folder) == "mpegts":
-        command = "mythreplex --demux --fix_sync -t TS -o %s " % (folder + "/stream")
+        command ="ionice -c3 " 
+        command += "mythreplex --demux --fix_sync -t TS -o %s " % (folder + "/stream")
         command += "-v %d " % (video[VIDEO_ID])
 
         if audio1[AUDIO_ID] != -1: 
@@ -2685,7 +2725,8 @@
                 command += "-c %d " % (audio2[AUDIO_ID])
 
     else:
-        command = "mythreplex --demux --fix_sync -o %s " % (folder + "/stream")
+        command ="ionice -c3 " 
+        command += "mythreplex --demux --fix_sync -o %s " % (folder + "/stream")
         command += "-v %d " % (video[VIDEO_ID] & 255)
 
         if audio1[AUDIO_ID] != -1: 
@@ -2707,22 +2748,39 @@
     result = runCommand(command)
 
     if result<>0:
-        fatalError("Failed while running mythreplex. Command was %s" % command)
+        fatalError("Failed while running: %s " % command)
 
 #############################################################
 # Run tcrequant
 
-def runTcrequant(source,destination,percentage):
-    checkCancelFlag()
 
-    write (path_tcrequant[0] + " %s %s %s" % (source,destination,percentage))
-    result=os.spawnlp(os.P_WAIT, path_tcrequant[0],path_tcrequant[1],
-            "-i",source,
-            "-o",destination,
-            "-d","2",
-            "-f","%s" % percentage)
-    if result<>0:
-        fatalError("Failed while running tcrequant")
+def runTcrequant(source,destination,factor):
+        mega=1024.0*1024.0
+        M2Vsize0 = os.path.getsize(source)
+        write("Initial M2Vsize is %.2f Mb , target is %.2f Mb" % ( (float(M2Vsize0)/mega), (float(M2Vsize0)/(factor*mega)) ))
+
+#   path_tcrequant must be defined in frontend setup as eg  M2VRequantiser,  *NOT* tcrequant
+#       command = "M2VRequantiser  %s  " %  factor
+        command ="ionice -c3 " 
+        command += path_tcrequant[0]   
+        command += " %.5f "  % factor
+        command += " %s "  % M2Vsize0
+        command += " <  %s " % source
+        command += " >  %s " % destination
+ 
+        write("Running: " + command)
+        result = runCommand(command)
+
+        M2Vsize1 = os.path.getsize(destination)
+       
+        write("M2Vsize after requant is  %.2f Mb " % (float(M2Vsize1)/mega))
+        fac1=float(M2Vsize0) / float(M2Vsize1)
+        write("Factor demanded %.5f, achieved %.5f, ratio %.5f " % ( factor, fac1, fac1/factor))
+            
+        if result<>0:
+          nonfatalError("Error reported from: %s " % command)
+
+
 
 #############################################################
 # Calculates the total size of all the video, audio and menu files 
@@ -2740,84 +2798,144 @@
         folder=getItemTempPath(filecount)
         #Process this file
         file=os.path.join(folder,"stream.mv2")
-        #Get size of video in MBytes
-        totalvideosize+=os.path.getsize(file) / 1024 / 1024
+        #Get size of vobfile in MBytes
+        totalvideosize+=os.path.getsize(file) 
 
         #Get size of audio track 1
         if doesFileExist(os.path.join(folder,"stream0.ac3")):
-            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.ac3")) / 1024 / 1024
+            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.ac3")) 
         if doesFileExist(os.path.join(folder,"stream0.mp2")):
-            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.mp2")) / 1024 / 1024
+            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.mp2")) 
 
         #Get size of audio track 2 if available 
         if doesFileExist(os.path.join(folder,"stream1.ac3")):
-            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.ac3")) / 1024 / 1024
+            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.ac3")) 
         if doesFileExist(os.path.join(folder,"stream1.mp2")):
-            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.mp2")) / 1024 / 1024
+            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.mp2")) 
 
         # add chapter menu if available
         if doesFileExist(os.path.join(getTempPath(),"chaptermenu-%s.mpg" % filecount)):
-            totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"chaptermenu-%s.mpg" % filecount)) / 1024 / 1024
+            totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"chaptermenu-%s.mpg" % filecount)) 
 
         # add details page if available
         if doesFileExist(os.path.join(getTempPath(),"details-%s.mpg" % filecount)):
-            totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"details-%s.mpg" % filecount)) / 1024 / 1024
+            totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"details-%s.mpg" % filecount))
 
     filecount=1
     while doesFileExist(os.path.join(getTempPath(),"menu-%s.mpg" % filecount)):
-        totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"menu-%s.mpg" % filecount)) / 1024 / 1024
+        totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"menu-%s.mpg" % filecount))
         filecount+=1
 
     return totalvideosize,totalaudiosize,totalmenusize
 
-#############################################################
-# Uses tcrequant if available to shrink the video streams so 
+########################################
+def total_mv2_brl(files,rate): 
+#returns total size of bitrate-limited m2v files
+    tvsize=0  
+    filecount=0
+    for node in files:
+        filecount+=1
+        folder=getItemTempPath(filecount)
+        progduration=getLengthOfVideo(filecount)
+        file=os.path.join(folder,"stream.mv2")
+        progvsize=os.path.getsize(file)
+        progvbitrate=progvsize/progduration
+        if progvbitrate>rate : 
+           tvsize+=progduration*rate
+        else:
+           tvsize+=progvsize
+
+    return tvsize    
+
+#########################################
+
+# Uses requantiser if available to shrink the video streams so 
 # they will fit on a DVD
 
 def performMPEG2Shrink(files,dvdrsize):
     checkCancelFlag()
+    mega=1024.0*1024.0
+    fudge_pack=1.04  # for mpeg packing
+    fudge_requant=1.05 # for requant shrinkage uncertainty
 
     totalvideosize,totalaudiosize,totalmenusize=calculateFileSizes(files)
+    allfiles=totalvideosize+totalaudiosize+totalmenusize
 
     #Report findings
-    write( "Total size of video files, before multiplexing, is %s Mbytes, audio is %s MBytes, menus are %s MBytes." % (totalvideosize,totalaudiosize,totalmenusize))
-
-    #Subtract the audio and menus from the size of the disk (we cannot shrink this further)
-    dvdrsize-=totalaudiosize
-    dvdrsize-=totalmenusize
-
-    #Add a little bit for the multiplexing stream data
-    totalvideosize=totalvideosize*1.08
+    write( "Total video  %.2f Mb, audio %.2f Mb, menus %.2f Mb." % (totalvideosize/mega,totalaudiosize/mega,totalmenusize/mega))
 
-    if dvdrsize<0:
-        fatalError("Audio and menu files are greater than the size of a recordable DVD disk.  Giving up!")
+    #Subtract the audio, menus and packaging overhead from the size of the disk (we cannot shrink this further)
+    mv2space=((dvdrsize*mega-totalmenusize)/fudge_pack)-totalaudiosize
+ 
+    if mv2space<0:
+        fatalError("Audio and menu files are too big. No room for video. Giving up!")
+
+    if totalvideosize>mv2space:
+        write( "Video files are %.1f Mb too big. Need to shrink." % ((totalvideosize - mv2space)/mega) )
+
+        #tcrequant (transcode) was an optional install that is now deprecated.
+        #this script requires that path_tcrequant, if not null, leads to M2VRequantiser
+        #it is defined, like the other 'path_ ' parameters, from the frontend media setup screens
 
-    if totalvideosize>dvdrsize:
-        write( "Need to shrink MPEG2 video files to fit onto recordable DVD, video is %s MBytes too big." % (totalvideosize - dvdrsize))
-        scalepercentage=totalvideosize/dvdrsize
-        write( "Need to scale by %s" % scalepercentage)
-
-        if scalepercentage>3:
-            write( "Large scale to shrink, may not work!")
-
-        #tcrequant (transcode) is an optional install so may not be available
         if path_tcrequant[0] == "":
-            fatalError("tcrequant is not available to resize the files.  Giving up!")
+            fatalError("M2VRequantiser is not available to resize the files.  Giving up!")
 
+        vsize=0
+        duration=0
         filecount=0
         for node in files:
-            filecount+=1
-            runTcrequant(os.path.join(getItemTempPath(filecount),"stream.mv2"),os.path.join(getItemTempPath(filecount),"video.small.m2v"),scalepercentage)
-            os.remove(os.path.join(getItemTempPath(filecount),"stream.mv2"))
-            os.rename(os.path.join(getItemTempPath(filecount),"video.small.m2v"),os.path.join(getItemTempPath(filecount),"stream.mv2"))
-
-        totalvideosize,totalaudiosize,totalmenusize=calculateFileSizes(files)
-        write( "Total DVD size AFTER TCREQUANT is %s MBytes" % (totalaudiosize + totalmenusize + (totalvideosize*1.05)))
-
+          filecount+=1
+          folder=getItemTempPath(filecount)
+          file=os.path.join(folder,"stream.mv2")
+          vsize+=os.path.getsize(file)
+          duration+=getLengthOfVideo(filecount)
+
+        #We need to shrink the video files to fit into the space available.  It seems sensible 
+        #to do this by imposing a common upper limit on the mean video bit-rate of each recording; 
+        #this will not further reduce the visual quality of any that were transmitted at lower bit-rates.
+
+        #Now find the bit-rate limit by iteration between initially defined upper and lower bounds. 
+        #The code is based on 'rtbis' from Numerical Recipes by W H Press et al., CUP.
+        
+        #A small multiple of the average input bit-rate should be ok as the initial upper bound,
+        #(although a fixed value or one related to the max value could be used), and zero as the lower bound.
+        #The function relating bit-rate upper limit to total file size is smooth and monotonic,
+        #so there should be no convergence problem. 
+     
+        vrLo=0.0
+        vrHi=3.0*float(vsize)/duration
+        
+        vrate=vrLo
+        vrinc=vrHi-vrLo
+        count=0
+
+        while count<30 :
+           count+=1
+           vrinc=vrinc*0.5
+           vrtest=vrate+vrinc
+           testsize=total_mv2_brl(files,vrtest)
+           if (testsize<mv2space):
+               vrate=vrtest
+           
+        write("vrate %.3f kb/s, testsize %.4f , mv2space %.4f Mb " % ((vrate)/1000.0, (testsize)/mega, (mv2space)/mega) )
+        filecount=0
+        for node in files:
+           filecount+=1
+           folder=getItemTempPath(filecount)
+           file=os.path.join(folder,"stream.mv2")
+           progvsize=os.path.getsize(file)
+           progduration=getLengthOfVideo(filecount)
+           progvbitrate=progvsize/progduration
+           write( "File %s, size %.2f Mb, rate %.2f, limit %.2f kb/s " %( filecount, float(progvsize)/mega, progvbitrate/1000.0, vrate/1000.0 ))
+           if progvbitrate>vrate :
+              scalefactor=1.0+(fudge_requant*float(progvbitrate-vrate)/float(vrate))
+              if scalefactor>3.0 :
+                 write( "Large shrink factor. You may not like the result! ")
+              runTcrequant(os.path.join(getItemTempPath(filecount),"stream.mv2"),os.path.join(getItemTempPath(filecount),"stream.small.mv2"),scalefactor)
+              os.remove(os.path.join(getItemTempPath(filecount),"stream.mv2"))
+              os.rename(os.path.join(getItemTempPath(filecount),"stream.small.mv2"),os.path.join(getItemTempPath(filecount),"stream.mv2"))
     else:
-        dvdrsize-=totalvideosize
-        write( "Video will fit onto DVD. %s MBytes of space remaining on recordable DVD." % dvdrsize)
-
+        write( "Unpackaged total %.2f Mb. About %.0f Mb will be unused." % ((allfiles/mega),(mv2space-totalvideosize)/mega))
 
 #############################################################
 # Creates the DVDAuthor xml file used to create a standard DVD with menus
@@ -3113,7 +3231,7 @@
                                                    chapterLength, 
                                                    getLengthOfVideo(itemnum)))
 
-            vob.setAttribute("file",os.path.join(getItemTempPath(itemnum),"final.mpg"))
+            vob.setAttribute("file",os.path.join(getItemTempPath(itemnum),"final.vob"))
             pgc.appendChild(vob)
 
             post = dvddom.createElement("post")
@@ -3357,7 +3475,7 @@
         pgc = dvddom.createElement("pgc")
 
         vob = dvddom.createElement("vob")
-        vob.setAttribute("file", os.path.join(getItemTempPath(itemNum), "final.mpg"))
+        vob.setAttribute("file", os.path.join(getItemTempPath(itemNum), "final.vob"))
         vob.setAttribute("chapters", createVideoChaptersFixedLength(itemNum,
                                                                     chapterLength,
                                                                     getLengthOfVideo(itemNum)))
@@ -3425,7 +3543,8 @@
                 height = getScaledAttribute(node, "h")
                 frames = int(secondsToFrames(menulength))
 
-                command = "mytharchivehelper -t  %s '%s' '%s' %d" % (inputfile, starttime, outputfile, frames)
+                command ="ionice -c3 " 
+                command += "mytharchivehelper -t  %s '%s' '%s' %d" % (inputfile, starttime, outputfile, frames)
                 result = runCommand(command)
                 if (result != 0):
                     write( "mytharchivehelper failed with code %d. Command = %s" % (result, command) )
@@ -3537,10 +3656,10 @@
                 button = spumuxdom.createElement("button")
                 button.setAttribute("name","previous")
                 button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
-                button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
+                button.setAttribute("y0","%s" % even(getScaledAttribute(node, "y")))
                 button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") + 
                                                 getScaledAttribute(node, "w")))
-                button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") +
+                button.setAttribute("y1","%s" % even(getScaledAttribute(node, "y") +
                                                 getScaledAttribute(node, "h")))
                 spunode.appendChild(button)
 
@@ -3561,10 +3680,10 @@
                 button = spumuxdom.createElement("button")
                 button.setAttribute("name","next")
                 button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
-                button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
+                button.setAttribute("y0","%s" % even(getScaledAttribute(node, "y")))
                 button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") + 
                                                  getScaledAttribute(node, "w")))
-                button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") + 
+                button.setAttribute("y1","%s" % even(getScaledAttribute(node, "y") + 
                                                  getScaledAttribute(node, "h")))
                 spunode.appendChild(button)
 
@@ -3582,10 +3701,10 @@
             button = spumuxdom.createElement("button")
             button.setAttribute("name","playall")
             button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
-            button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
+            button.setAttribute("y0","%s" % even(getScaledAttribute(node, "y")))
             button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") + 
                                              getScaledAttribute(node, "w")))
-            button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") +
+            button.setAttribute("y1","%s" % even(getScaledAttribute(node, "y") +
                                              getScaledAttribute(node, "h")))
             spunode.appendChild(button)
 
@@ -3605,10 +3724,10 @@
                 button = spumuxdom.createElement("button")
                 button.setAttribute("name","titlemenu")
                 button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
-                button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
+                button.setAttribute("y0","%s" % even(getScaledAttribute(node, "y")))
                 button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") +
                                                 getScaledAttribute(node, "w")))
-                button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") +
+                button.setAttribute("y1","%s" % even(getScaledAttribute(node, "y") +
                                                 getScaledAttribute(node, "h")))
                 spunode.appendChild(button)
 
@@ -3654,9 +3773,9 @@
     else:
         node.setAttribute("name","%s" % itemnum)
     node.setAttribute("x0","%d" % int(boundarybox[0]))
-    node.setAttribute("y0","%d" % int(boundarybox[1]))
+    node.setAttribute("y0","%d" % even(boundarybox[1]))
     node.setAttribute("x1","%d" % int(boundarybox[2] + 1))
-    node.setAttribute("y1","%d" % int(boundarybox[3] + 1))
+    node.setAttribute("y1","%d" % even(boundarybox[3] + 2))
     spunode.appendChild(node)
 
 #############################################################
@@ -3692,9 +3811,9 @@
         highlightcolor = menunode.attributes["highlightcolor"].value
 
     #Get menu music
-    menumusic = "menumusic.ac3"
-    if menunode.hasAttribute("music"):
-        menumusic = menunode.attributes["music"].value
+    menumusic = "menumusic.mp2"
+#    if menunode.hasAttribute("music"):
+#        menumusic = menunode.attributes["music"].value
 
     #Get menu length
     menulength = 15
@@ -3904,9 +4023,9 @@
         highlightcolor = menunode.attributes["highlightcolor"].value
 
     #Get menu music
-    menumusic = "menumusic.ac3"
-    if menunode.hasAttribute("music"):
-        menumusic = menunode.attributes["music"].value
+    menumusic = "menumusic.mp2"
+#    if menunode.hasAttribute("music"):
+#       menumusic = menunode.attributes["music"].value
 
     #Get menu length
     menulength = 15
@@ -4099,9 +4218,9 @@
         fatalError("Background image not found (%s)" % backgroundfilename)
 
     #Get menu music
-    menumusic = "menumusic.ac3"
-    if detailnode.hasAttribute("music"):
-        menumusic = detailnode.attributes["music"].value
+    menumusic = "menumusic.mp2"
+#    if detailnode.hasAttribute("music"):
+#        menumusic = detailnode.attributes["music"].value
 
     #Get menu length
     menulength = 15
@@ -5168,7 +5287,7 @@
             else:
                 createDVDAuthorXML(format, files.length)
 
-            #Check all the files will fit onto a recordable DVD
+    #Check all the files will fit onto a recordable DVD
             if mediatype == DVD_DL:
                 # dual layer
                 performMPEG2Shrink(files, dvdrsize[1])
@@ -5176,6 +5295,8 @@
                 #single layer
                 performMPEG2Shrink(files, dvdrsize[0])
 
+
+       
             filecount=0
             for node in files:
                 filecount+=1
@@ -5186,9 +5307,12 @@
                 pid=multiplexMPEGStream(os.path.join(folder,'stream.mv2'),
                         os.path.join(folder,'stream0'),
                         os.path.join(folder,'stream1'),
-                        os.path.join(folder,'final.mpg'),
+                        os.path.join(folder,'final.vob'),
                         calcSyncOffset(filecount))
 
+ 
+
+
             #Now all the files are completed and ready to be burnt
             runDVDAuthor()
 
@@ -5442,6 +5566,7 @@
             saveSetting("MythArchiveLastRunStatus", "Success")
             saveSetting("MythArchiveLastRunEnd", time.strftime("%Y-%m-%d %H:%M:%S "))
             write("Finished processing jobs!!!")
+
         finally:
             # remove our lock file
             os.remove(lckpath)
