Layer Break positioning in Double Layer DVD-Video recordings presents certain challenge. The trouble is that we have three rather loose components which need to work together: 1) DVD-Video content preparation program, something similar to dvdauthor 2) file system layout generator, mkisofs in our case and 3) a recording program. Ultimately it's content preparation program responsibility to pick the Layer Break point. Then file system layout generator has to make sure that it's aligned at DVD ECC block boundary of 32KB and perhaps even that it resides in second half of the image. Finally recording program has to pass it down to burner unit.

As the first step in addressing this challenge I'd like to nominate attached mkisofs patch for inclusion to cdrtools. As you can see it's not really final code, but only a framework. As at this point it merely enables mkisofs to slide DVD-Video content toward the end of the image. The dvd_align.c module is currently a dummy place holder which will be implemented as time permits. The main idea behind this submission is to have public audit and iron the framework code. As for proposed -layer-break command line option syntax. I haven't decided yet, but preliminary idea is to specify chapter point or cell in given title set, e.g. [EMAIL PROTECTED] or [EMAIL PROTECTED], those chosen by the content preparation program. But the plan is even to try to locate it automatically, if it wasn't explicitly specified in command line.

As for recording program, growisofs in my case, the idea is to use dvd_align.c code in both mkisofs and growisofs in order to ensure that both programs identify Layer Break position in exactly same way, so that the intended value will be passed down to the burner unit. Cheers. A.


--- ./mkisofs/write.c.orig      Wed Jul 14 18:28:41 2004
+++ ./mkisofs/write.c   Fri Jul 16 23:04:20 2004
@@ -535,16 +535,42 @@
 {
        struct deferred_write   *dwpnt,
                                *dwnext;
+#if    defined(APPLE_HYB) || defined(DVD_VIDEO)
+static char blk[SECTOR_SIZE];  /* place it in .bss */  
+#endif
 
        dwpnt = dw_head;
        while (dwpnt) {
 /*#define DEBUG*/
 #ifdef DEBUG
                fprintf(stderr,
-               "The file name is %s and pad is %d, size is %lld and extent is %d\n",
+               "The file name is %s and pad is %u, size is %lld, extent is %u",
                                dwpnt->name, dwpnt->pad,
                                (Llong)dwpnt->size, dwpnt->extent);
+               if (dwpnt->extent > last_extent_written)
+                       fprintf(stderr, " and is being padded from %u\n",
+                               last_extent_written);
+               else    fprintf(stderr, "\n");
+#endif
+               if (dwpnt->extent < last_extent_written) {
+#ifdef USE_LIBSCHILY
+                       comerrno(EX_BAD,"Fatal goof - out of sync extent for '%s'\n",
+                               dwpnt->name);
+#else
+                       fprintf(stderr,"Fatal goof - out of sync extent for '%s'\n",
+                               dwpnt->name);
 #endif
+                       exit(1);
+               }
+               else if (dwpnt->extent > last_extent_written) {
+                       unsigned int i=last_extent_written;
+
+                       while (i++ < dwpnt->extent)
+                               xfwrite (blk,sizeof(blk),1,outfile,0,FALSE);
+
+                       last_extent_written = dwpnt->extent;
+               }
+
                if (dwpnt->table) {
                        xfwrite(dwpnt->table, ISO_ROUND_UP(dwpnt->size), 1,
                                                        outfile,
@@ -586,7 +612,6 @@
                         * we may have to pad out ISO files to work with HFS
                         * clump sizes
                         */
-                       char    blk[SECTOR_SIZE];
                        Uint    i;
 
                        for (i = 0; i < dwpnt->pad; i++)
@@ -927,9 +952,12 @@
        struct deferred_write   *dwpnt;
        struct deferred_write   **sortlist;
        struct directory_entry  *s_entry;
-       int                     start_extent;
+       unsigned int            start_extent;
        int                     num = 0;
        int                     i;
+#ifdef DVD_VIDEO
+       int                     dvd_video_align=dvd_video;
+#endif
 
        /* need to store start extents for linked files */
        flush_hash();
@@ -976,6 +1004,21 @@
 
        /* set the new start extents for the sorted list */
        for (i = 0, dwpnt = dw_head; i < num; i++, dwpnt = dwpnt->next) {
+#ifdef DVD_VIDEO
+               if (dvd_video_align) {
+                       size_t len = strlen(dwpnt->name);
+                       unsigned int align;
+
+                       if (!strcmp(dwpnt->name+len-21,"VIDEO_TS/VIDEO_TS.IFO") &&
+                           (len==21 || dwpnt->name[len-22]=='/')) {
+                               dvd_video_align=0;
+                               /* do this only once */
+                               align = DVDLayerAlignment 
(dwpnt->name,start_extent,last_extent);
+                               start_extent += align;
+                               last_extent  += align;
+                       }
+               }
+#endif /* DVD_VIDEO */
                s_entry = dwpnt->s_entry;
                dwpnt->extent = s_entry->starting_block = start_extent;
                set_733((char *) s_entry->isorec.extent, start_extent);
--- ./mkisofs/Makefile.orig     Sun Feb 22 16:13:43 2004
+++ ./mkisofs/Makefile  Wed Jul 14 22:36:34 2004
@@ -43,7 +43,7 @@
                scsi_cdr.c cd_misc.c \
                modes.c \
                apple.c volume.c desktop.c mac_label.c stream.c \
-               ifo_read.c dvd_file.c dvd_reader.c \
+               ifo_read.c dvd_file.c dvd_reader.c dvd_align.c \
                defaults.c getnum.c
 HFILES=                apple.h bootinfo.h config.h defaults.h diskmbr.h exclude.h \
                fnmatch.h getopt.h iso9660.h mac_label.h mactypes.h match.h \
--- ./mkisofs/dvd_align.c.orig  Thu Jul 15 00:11:06 2004
+++ ./mkisofs/dvd_align.c       Fri Jul 16 22:22:14 2004
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004  Andy Polyakov <[EMAIL PROTECTED]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef GROWISOFS
+/*
+ * In mkisofs context the purpose of this module is to provide a hint
+ * for Layer Break position alignment at DVD ECC block boundary.
+ * DVDLayerAlignment() is invoked with pathname to VIDEO_TS.IFO, its
+ * extent number and volume size. The function returns the amount of
+ * extents to be injected prior VMG structure [or in other words prior
+ * VIDEO_TS.IFO file] to achieve the goal. If Layer Break position was
+ * not explicitly specified in command line, an effort is made to locate
+ * one. If there is still none found, then the Cell above and closest to
+ * the middle of image gets aligned, which is basically the best shot...
+ */
+#ifdef DVD_VIDEO
+
+#include "mkisofs.h"
+
+EXPORT unsigned int    DVDLayerAlignment       __PR((char *video_ts, unsigned int 
extent, unsigned int vol_size));
+
+EXPORT
+unsigned int DVDLayerAlignment (video_ts, extent, vol_size)
+       char *video_ts;
+       unsigned int extent;
+       unsigned int vol_size;
+{
+       /* just a place holder for now... */
+       return 0;
+}
+#endif
+#endif
--- ./mkisofs/dvd_reader.h.orig Tue Mar  2 00:50:27 2004
+++ ./mkisofs/dvd_reader.h      Fri Jul 16 22:01:02 2004
@@ -133,6 +133,8 @@
 extern ssize_t DVDFileSize             __PR((dvd_file_t *));
 
 
+extern unsigned int    DVDLayerAlignment       __PR((char *video_ts, unsigned int 
extent, unsigned int vol_size));
+
 #ifdef __cplusplus
 };
 #endif
--- ./mkisofs/mkisofs.h.orig    Thu May 27 00:54:59 2004
+++ ./mkisofs/mkisofs.h Thu Jul 15 01:26:14 2004
@@ -365,6 +365,7 @@
 
 #ifdef DVD_VIDEO
 extern int     dvd_video;
+extern char *  layer_break;
 #endif /* DVD_VIDEO */
 
 
--- ./mkisofs/mkisofs.c.orig    Sun Jul 11 17:30:27 2004
+++ ./mkisofs/mkisofs.c Fri Jul 16 19:02:04 2004
@@ -217,6 +217,7 @@
 
 #ifdef DVD_VIDEO
 int    dvd_video = 0;
+char * layer_break = NULL;
 #endif
 
 #ifdef SORTING
@@ -372,6 +373,7 @@
 #endif
 #ifdef DVD_VIDEO
 #define        OPTION_DVD                      1501
+#define OPTION_LAYER_BREAK             1502
 #endif
 
 #ifdef APPLE_HYB
@@ -621,6 +623,8 @@
 #ifdef DVD_VIDEO
        {{"dvd-video", no_argument, NULL, OPTION_DVD},
        '\0', NULL, "Generate DVD-Video compliant UDF file system", ONE_DASH},
+       {{"layer-break", required_argument, NULL, OPTION_LAYER_BREAK},
+       '\0', "PARAM", "Specify Layer Break position",ONE_DASH},
 #endif
 
        {{"uid", required_argument, NULL, OPTION_UID},
@@ -1813,6 +1817,9 @@
                case OPTION_DVD:
                        use_udf++;
                        dvd_video++;
+                       break;
+               case OPTION_LAYER_BREAK:
+                       layer_break = strdup(optarg);
                        break;
 #endif
                case OPTION_USE_FILEVERSION:

Reply via email to