Re: mkisofs udf help!
Thanks for your reply Andy,
I don't think I was clear enough. I know that the data is not specifically
looked for on location always, but instead scanned as you said and then told
where to look, but in practice, it packs the data close together such that
if
the file descriptors are at blocks 259 through 269, the data blocks these
file
descriptors are targetted at might be 277 for the file descriptor at 263,
then
maybe 280 for the file descriptor at 264, etc.
I would like to hard code where the data is actually located instead of
making
it dependant upon where the filesystem information is. With this in mind I
would like to scan the data to find the relative locations to each other so
that
I the file data will ALWAYS start at block 2048 (for my purposes). Then use
my
hacked mkisofs to generate the filesystem data belonging at the beginnning
of
the disc padded up to 2048 so that file descriptor at block 263 is mapped to
data at 2048 block and file descriptor at block 264 maps to the data at 2051
block etc. etc.
With this idea, making the data always start at block 2048 allows for enough
growth of the filesystem data at the beginning of the disc so that as I add
files to the disc, I can just rewrite that beginning data without having to
rewrite all the file data.
Is this far-fetched as in unrealistic and very hard? Or just awkward but
doable?
So far, I've made some attempts to modify the mkisofs code and it appears
that
it works but something is still wrong! I am using the mkisofs that
came with dvdrtools-0.1.5. Attached is a patch I made for it for what I've
done so far.
Some example output...
bash-2.05b$ ./mkisofs/mkisofs -v -v -dvd-video -o simple.iso simple/
mkisofs 2.0 (i686-pc-linux-gnu)
Scanning simple/
Scanning simple/VIDEO_TS
Scanning simple/AUDIO_TS
274 152
275 308 VIDEO_TS
276 68 AUDIO_TS
Cache hit for '/..'
Cache hit for 'VIDEO_TS/.'
Cache hit for 'VIDEO_TS/..'
2048 2050 simple/VIDEO_TS/VIDEO_TS.BUP
2051 2053 simple/VIDEO_TS/VIDEO_TS.IFO
2054 2059 simple/VIDEO_TS/VTS_01_0.BUP
2060 2065 simple/VIDEO_TS/VTS_01_0.IFO
2066 2493 simple/VIDEO_TS/VTS_01_1.VOB
Cache hit for 'AUDIO_TS/.'
Cache hit for 'AUDIO_TS/..'
Writing: Initial Padbock Start Block 0
Done with: Initial Padbock Block(s) 16
Writing: Primary Volume Descriptor Start Block 16
Done with: Primary Volume Descriptor Block(s) 1
Writing: End Volume Descriptor Start Block 17
Done with: End Volume Descriptor Block(s) 1
Writing: UDF volume recognition area Start Block 18
Done with: UDF volume recognition area Block(s) 3
Writing: Version block Start Block 21
Done with: Version block Block(s) 1
Writing: UDF pad to sector 32 write Start Block 22
Done with: UDF pad to sector 32 write Block(s) 10
Writing: UDF main seq Start Block 32
Done with: UDF main seq Block(s) 16
Writing: UDF second seq Start Block 48
Done with: UDF second seq Block(s) 16
Writing: UDF integ seq Start Block 64
Done with: UDF integ seq Block(s) 2
Writing: UDF pad to sector 256 Start Block 66
Done with: UDF pad to sector 256 Block(s) 190
Writing: UDF Anchor volume Start Block 256
Done with: UDF Anchor volume Block(s) 1
Writing: UDF file set Start Block 257
Done with: UDF file set Block(s) 2
Writing: UDF directory tree Start Block 259
Done with: UDF directory tree Block(s) 6
Writing: UDF file entries Start Block 265
Done with: UDF file entries Block(s) 5
Writing: Path table Start Block 270
Done with: Path table Block(s) 4
Writing: Directory tree Start Block 274
Done with: Directory tree Block(s) 3
Writing: Directory tree cleanup Start Block 277
Done with: Directory tree cleanup Block(s) 0
Writing: UDF pad to sector files start Start Block 277
Done with: UDF pad to sector files start Block(s) 1771
Writing: The File(s) Start Block 2048
Total extents scheduled to be written = 2512
Total translation table size: 0
Total rockridge attributes bytes: 0
Total directory bytes: 4096
Path table size(bytes): 42
Done with: The File(s) Block(s) 446
Writing: UDF Pad end Start Block 2494
Done with: UDF Pad end Block(s) 18
Max brk space used 5000
2512 extents written (4 Mb)
Now if I do isoinfo on it...
bash-2.05b$ isoinfo -i simple.iso -l
Directory listing of /
d--------- 0 0 0 2048 Aug 4 2004 [ 274] .
d--------- 0 0 0 2048 Aug 4 2004 [ 274] ..
d--------- 0 0 0 2048 Aug 4 2004 [ 276] AUDIO_TS
d--------- 0 0 0 2048 Aug 4 2004 [ 275] VIDEO_TS
Directory listing of /AUDIO_TS/
d--------- 0 0 0 2048 Aug 4 2004 [ 276] .
d--------- 0 0 0 2048 Aug 4 2004 [ 274] ..
Directory listing of /VIDEO_TS/
d--------- 0 0 0 2048 Aug 4 2004 [ 275] .
d--------- 0 0 0 2048 Aug 4 2004 [ 274] ..
---------- 0 0 0 6144 Aug 4 2004 [ 2051]
VIDEO_TS.BUP;1
---------- 0 0 0 6144 Aug 4 2004 [ 2048]
VIDEO_TS.IFO;1
---------- 0 0 0 12288 Aug 4 2004 [ 2488]
VTS_01_0.BUP;1
---------- 0 0 0 12288 Aug 4 2004 [ 2054]
VTS_01_0.IFO;1
---------- 0 0 0 876544 Aug 4 2004 [ 2060]
VTS_01_1.VOB;1
And if I mount and view the files...
bash-2.05b$ mount -oloop simple.iso mnt/
bash-2.05b$ ls -liaR mnt/
mnt/:
total 10
259 dr-xr-xr-x 4 4294967295 4294967295 136 Aug 4 10:25 .
2879199 drwxr-xr-x 21 liaj users 4096 Aug 5 11:26 ..
263 dr-xr-xr-x 2 4294967295 4294967295 40 Aug 4 10:25
AUDIO_TS
261 dr-xr-xr-x 2 4294967295 4294967295 300 Aug 4 10:25
VIDEO_TS
mnt/AUDIO_TS:
total 4
263 dr-xr-xr-x 2 4294967295 4294967295 40 Aug 4 10:25 .
259 dr-xr-xr-x 4 4294967295 4294967295 136 Aug 4 10:25 ..
mnt/VIDEO_TS:
total 896
261 dr-xr-xr-x 2 4294967295 4294967295 300 Aug 4 10:25 .
259 dr-xr-xr-x 4 4294967295 4294967295 136 Aug 4 10:25 ..
266 -r--r--r-- 1 4294967295 4294967295 6144 Aug 4 10:25
VIDEO_TS.BUP
265 -r--r--r-- 1 4294967295 4294967295 6144 Aug 4 10:25
VIDEO_TS.IFO
267 -r--r--r-- 1 4294967295 4294967295 12288 Aug 4 10:25
VTS_01_0.BUP
268 -r--r--r-- 1 4294967295 4294967295 12288 Aug 4 10:25
VTS_01_0.IFO
269 -r--r--r-- 1 4294967295 4294967295 876544 Aug 4 10:25
VTS_01_1.VOB
As you can see, it appears as though the data was written correctly because
isoinfo tells where the file data lies corresponding to the file descriptors
at
266 through 269 which appear correclty via "ls -liaR". I can literally
strip
out the data from the iso (using split) from bytes 4194304 (block 2048) to
4200448 (block 2051) and compare it to the original VIDEO_TS.IFO file and it
is
perfect. I can do this with any of the files and all of them are exact!
My next step to check its correctness is to play the dvd directly using
xine.
On a working iso created with the original mkisofs, I do...
xine dvd:/home/liaj/dvd/DVDR/dvdrtools-0.1.5-new/mnt/VIDEO_TS/
and all is well. However with the hacked iso mount xine gives me an "Input
plugin failed to open MRL" error?
I'll keep working on this of course, but anything you can provide will be
greatly appreciated. If you know someone else that might be able to help as
well, feel free to forward this on to them. I'm still learning and can use
all
the help I can get!
Much thanks as always!
Jeff
Here is the patch:
diff -Nru dvdrtools-0.1.5/mkisofs/mkisofs.c
dvdrtools-0.1.5-inprog/mkisofs/mkisofs.c
--- dvdrtools-0.1.5/mkisofs/mkisofs.c 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/mkisofs.c 2004-08-05 10:36:25.000000000
-0400
@@ -3026,6 +3026,8 @@
}
outputlist_insert(&dirtree_clean);
+ outputlist_insert(&udf_pad_to_sector_files_start_frag);//Jeff Lia
+
if (extension_record) {
outputlist_insert(&extension_desc);
}
diff -Nru dvdrtools-0.1.5/mkisofs/mkisofs.h
dvdrtools-0.1.5-inprog/mkisofs/mkisofs.h
--- dvdrtools-0.1.5/mkisofs/mkisofs.h 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/mkisofs.h 2004-08-05 10:39:48.000000000
-0400
@@ -639,6 +639,7 @@
* ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible.
*/
#define SECTOR_SIZE (2048)
+#define FILE_STARTING_BLOCK (2048)
#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0))
diff -Nru dvdrtools-0.1.5/mkisofs/udf.c dvdrtools-0.1.5-inprog/mkisofs/udf.c
--- dvdrtools-0.1.5/mkisofs/udf.c 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/udf.c 2004-08-05 10:46:15.000000000 -0400
@@ -317,6 +317,19 @@
static int
#ifdef PROTOTYPES
+udf_pad_to_sector_files_start_size(int starting_extent)
+#else
+udf_pad_to_sector_files_start_size(starting_extent)
+ int starting_extent;
+#endif
+{
+ if (last_extent < session_start+FILE_STARTING_BLOCK)
+ last_extent = session_start+FILE_STARTING_BLOCK;
+ return 0;
+}
+
+static int
+#ifdef PROTOTYPES
udf_padend_avdp_size(int starting_extent)
#else
udf_padend_avdp_size(starting_extent)
@@ -942,6 +955,7 @@
* XXX 234 GB. With more we would cause a buffer overflow.
* XXX We need to check whether UDF would allow files > 234 GB.
*/
+ int starting_file_rba = file_rba;
for (; length > 0; length -= chunk) {
chunk = (length > 0x3ffff800) ? 0x3ffff800 : length;
set32(&allocation_desc->extent_length, chunk);
@@ -952,7 +966,7 @@
set32(&fe->length_of_allocation_descs,
(unsigned char *) allocation_desc -
(unsigned char *) &fe->allocation_desc);
- set_tag(&fe->desc_tag, UDF_TAGID_FILE_ENTRY, rba,
+ set_tag(&fe->desc_tag, UDF_TAGID_FILE_ENTRY, rba,
(unsigned char *) allocation_desc - buf);
}
@@ -1115,20 +1129,23 @@
#endif
{
Uchar buf[SECTOR_SIZE];
+ int starting_position=-1;
memset(buf, 0, SECTOR_SIZE);
if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
- struct directory_entry *de;
- for (de = dpnt->jcontents; de; de = de->jnext) {
+ struct directory_entry *de = dpnt->jcontents;
+ for (; de; de = de->jnext) {
if (!(de->de_flags & RELOCATED_DIRECTORY)
&& !(de->isorec.flags[0] & ISO_DIRECTORY)) {
+ if(starting_position == -1)
+ starting_position = read_733(de->isorec.extent) -
lba_udf_partition_start;
memset(buf, 0, 512);
set_file_entry(
buf,
(last_extent_written++) - lba_udf_partition_start,
- read_733(de->isorec.extent) - lba_udf_partition_start,
+ read_733(de->isorec.extent) - lba_udf_partition_start +
FILE_STARTING_BLOCK - starting_position,
read_733(de->isorec.size),
de->isorec.date,
0, /* is_directory */
@@ -1343,6 +1360,17 @@
static int
#ifdef PROTOTYPES
+udf_pad_to_sector_files_start_write(FILE *out)
+#else
+udf_pad_to_sector_files_start_write(out)
+ FILE *out;
+#endif
+{
+ return pad_to(session_start+FILE_STARTING_BLOCK, out);
+}
+
+static int
+#ifdef PROTOTYPES
udf_padend_avdp_write(FILE *out)
#else
udf_padend_avdp_write(out)
@@ -1373,6 +1401,7 @@
struct output_fragment udf_pad_to_sector_32_frag = { NULL,
udf_pad_to_sector_32_size, NULL, udf_pad_to_sector_32_write, "UDF pad to
sector 32 write" };
struct output_fragment udf_pad_to_sector_256_frag = { NULL,
udf_pad_to_sector_256_size, NULL, udf_pad_to_sector_256_write, "UDF pad to
sector 256" };
+struct output_fragment udf_pad_to_sector_files_start_frag = { NULL,
udf_pad_to_sector_files_start_size, NULL,
udf_pad_to_sector_files_start_write, "UDF pad to sector files start" };
struct output_fragment udf_padend_avdp_frag = { NULL, udf_padend_avdp_size,
NULL, udf_padend_avdp_write, "UDF Pad end" };
/*
diff -Nru dvdrtools-0.1.5/mkisofs/udf.h dvdrtools-0.1.5-inprog/mkisofs/udf.h
--- dvdrtools-0.1.5/mkisofs/udf.h 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/udf.h 2004-08-05 10:37:35.000000000 -0400
@@ -35,6 +35,7 @@
extern struct output_fragment udf_pad_to_sector_32_frag;
extern struct output_fragment udf_pad_to_sector_256_frag;
+extern struct output_fragment udf_pad_to_sector_files_start_frag;
extern struct output_fragment udf_padend_avdp_frag;
int assign_dvd_weights __PR((char *name, struct directory *this_dir, int
val));
From: Andy Polyakov <appro@fy.chalmers.se>
To: Jeff Lia <jeffreyallenlia@hotmail.com>
CC: cdwrite@other.debian.org
Subject: Re: mkisofs udf help!
Date: Wed, 04 Aug 2004 22:28:55 +0200
Within mkisofs, the udf part is told to look for the file data
specifically at
a certain starting sector location. Can someone tell me where/how do I
modify
the code to specify a different starting location?
This is misconception. Having scanned the data set mkisofs *calculates*
where
it will be recording the data. In order words it's not hard-coded in any way
and
totally depends on number of directory entries in original data-set.
I would like to hardcode it so the filesystem looks for the files at 592
so I
can manually write the files at those locations using growisofs
-use-the-force-luke=seek:592 then make the iso image and strip off the first
1212416 bytes (592 2k blocks) from the iso and write those starting at block
0.
Well, it's a bit far-fetched and you supposedly are totally on your own.
http://lists.debian.org/cdwrite/2004/07/msg00102.html can give some starting
point. Idea there is to slide DVD-Video content as whole toward outer edge
of
volume for given amount of blocks. By changing the criteria you can as well
target for a specific LBA for any given point. A.
_________________________________________________________________
Planning a family vacation? Check out the MSN Family Travel guide!
http://dollar.msn.com
diff -Nru dvdrtools-0.1.5/mkisofs/mkisofs.c
dvdrtools-0.1.5-inprog/mkisofs/mkisofs.c
--- dvdrtools-0.1.5/mkisofs/mkisofs.c 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/mkisofs.c 2004-08-05 10:36:25.000000000
-0400
@@ -3026,6 +3026,8 @@
}
outputlist_insert(&dirtree_clean);
+ outputlist_insert(&udf_pad_to_sector_files_start_frag);//Jeff Lia
+
if (extension_record) {
outputlist_insert(&extension_desc);
}
diff -Nru dvdrtools-0.1.5/mkisofs/mkisofs.h
dvdrtools-0.1.5-inprog/mkisofs/mkisofs.h
--- dvdrtools-0.1.5/mkisofs/mkisofs.h 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/mkisofs.h 2004-08-05 10:39:48.000000000
-0400
@@ -639,6 +639,7 @@
* ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible.
*/
#define SECTOR_SIZE (2048)
+#define FILE_STARTING_BLOCK (2048)
#define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
#define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0))
diff -Nru dvdrtools-0.1.5/mkisofs/udf.c dvdrtools-0.1.5-inprog/mkisofs/udf.c
--- dvdrtools-0.1.5/mkisofs/udf.c 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/udf.c 2004-08-05 10:46:15.000000000 -0400
@@ -317,6 +317,19 @@
static int
#ifdef PROTOTYPES
+udf_pad_to_sector_files_start_size(int starting_extent)
+#else
+udf_pad_to_sector_files_start_size(starting_extent)
+ int starting_extent;
+#endif
+{
+ if (last_extent < session_start+FILE_STARTING_BLOCK)
+ last_extent = session_start+FILE_STARTING_BLOCK;
+ return 0;
+}
+
+static int
+#ifdef PROTOTYPES
udf_padend_avdp_size(int starting_extent)
#else
udf_padend_avdp_size(starting_extent)
@@ -942,6 +955,7 @@
* XXX 234 GB. With more we would cause a buffer overflow.
* XXX We need to check whether UDF would allow files > 234 GB.
*/
+ int starting_file_rba = file_rba;
for (; length > 0; length -= chunk) {
chunk = (length > 0x3ffff800) ? 0x3ffff800 : length;
set32(&allocation_desc->extent_length, chunk);
@@ -952,7 +966,7 @@
set32(&fe->length_of_allocation_descs,
(unsigned char *) allocation_desc -
(unsigned char *) &fe->allocation_desc);
- set_tag(&fe->desc_tag, UDF_TAGID_FILE_ENTRY, rba,
+ set_tag(&fe->desc_tag, UDF_TAGID_FILE_ENTRY, rba,
(unsigned char *) allocation_desc - buf);
}
@@ -1115,20 +1129,23 @@
#endif
{
Uchar buf[SECTOR_SIZE];
+ int starting_position=-1;
memset(buf, 0, SECTOR_SIZE);
if (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY)) {
- struct directory_entry *de;
- for (de = dpnt->jcontents; de; de = de->jnext) {
+ struct directory_entry *de = dpnt->jcontents;
+ for (; de; de = de->jnext) {
if (!(de->de_flags & RELOCATED_DIRECTORY)
&& !(de->isorec.flags[0] & ISO_DIRECTORY)) {
+ if(starting_position == -1)
+ starting_position = read_733(de->isorec.extent) -
lba_udf_partition_start;
memset(buf, 0, 512);
set_file_entry(
buf,
(last_extent_written++) - lba_udf_partition_start,
- read_733(de->isorec.extent) - lba_udf_partition_start,
+ read_733(de->isorec.extent) - lba_udf_partition_start +
FILE_STARTING_BLOCK - starting_position,
read_733(de->isorec.size),
de->isorec.date,
0, /* is_directory */
@@ -1343,6 +1360,17 @@
static int
#ifdef PROTOTYPES
+udf_pad_to_sector_files_start_write(FILE *out)
+#else
+udf_pad_to_sector_files_start_write(out)
+ FILE *out;
+#endif
+{
+ return pad_to(session_start+FILE_STARTING_BLOCK, out);
+}
+
+static int
+#ifdef PROTOTYPES
udf_padend_avdp_write(FILE *out)
#else
udf_padend_avdp_write(out)
@@ -1373,6 +1401,7 @@
struct output_fragment udf_pad_to_sector_32_frag = { NULL,
udf_pad_to_sector_32_size, NULL, udf_pad_to_sector_32_write, "UDF pad to
sector 32 write" };
struct output_fragment udf_pad_to_sector_256_frag = { NULL,
udf_pad_to_sector_256_size, NULL, udf_pad_to_sector_256_write, "UDF pad to
sector 256" };
+struct output_fragment udf_pad_to_sector_files_start_frag = { NULL,
udf_pad_to_sector_files_start_size, NULL,
udf_pad_to_sector_files_start_write, "UDF pad to sector files start" };
struct output_fragment udf_padend_avdp_frag = { NULL, udf_padend_avdp_size,
NULL, udf_padend_avdp_write, "UDF Pad end" };
/*
diff -Nru dvdrtools-0.1.5/mkisofs/udf.h dvdrtools-0.1.5-inprog/mkisofs/udf.h
--- dvdrtools-0.1.5/mkisofs/udf.h 2004-06-03 01:45:18.000000000 -0400
+++ dvdrtools-0.1.5-inprog/mkisofs/udf.h 2004-08-05 10:37:35.000000000 -0400
@@ -35,6 +35,7 @@
extern struct output_fragment udf_pad_to_sector_32_frag;
extern struct output_fragment udf_pad_to_sector_256_frag;
+extern struct output_fragment udf_pad_to_sector_files_start_frag;
extern struct output_fragment udf_padend_avdp_frag;
int assign_dvd_weights __PR((char *name, struct directory *this_dir, int
val));
Reply to: