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: