[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Layer Break positioning in DL DVD-Video recordings



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. ch#19@ts#4 or cell#50@ts#4, 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 <appro@fy.chalmers.se>
+ *
+ * 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 to: