# This patch set is no longer maintained. The relevant parts have been rebased # on top of dvdbackup and bug fixes and further improvements have not been # ported back: # # http://www.fabiankeil.de/sourcecode/dvdbackup-0.4.2-combined-patches.diff # From e06023d187a542fe0e706a42765768f3c8ce053b Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 28 Feb 2010 14:19:47 +0100 Subject: [PATCH 01/28] Skip unreadable sectors faster. Don't try to repeat failed reads. --- vobcopy.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 1a0f8b6..715d93b 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1311,7 +1311,8 @@ next: /*for the goto - ugly, I know... */ starttime = time(NULL); for( i = start; ( i - start ) * DVD_VIDEO_LB_LEN < file_size; i += file_block_count) { - int tries = 0, skipped_blocks = 0; + int tries = 0, skipped_blocks = 0; + static int skip_factor = 1; /* Only read and write as many blocks as there are left in the file */ if ( ( i - start + file_block_count ) * DVD_VIDEO_LB_LEN > file_size ) { @@ -1319,30 +1320,27 @@ next: /*for the goto - ugly, I know... */ } /* DVDReadBlocks( dvd_file, i, 1, bufferin );this has to be wrong with the 1 there...*/ - - while( ( blocks = DVDReadBlocks( dvd_file, i, file_block_count, bufferin ) ) <= 0 && tries < 10 ) - { - if( tries == 9 ) - { - i += file_block_count; - skipped_blocks +=1; - overall_skipped_blocks +=1; - tries=0; - } - /* if( verbosity_level >= 1 ) - fprintf( stderr, _("[Warn] Had to skip %d blocks (reading block %d)! \n "), skipped_blocks, i ); */ - tries++; + + while( ( blocks = DVDReadBlocks( dvd_file, i, file_block_count, bufferin ) ) <= 0) + { + i += file_block_count * skip_factor; + skipped_blocks += skip_factor; + if( verbosity_level >= 1 ) + { + fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); + skip_factor = skip_factor * 2; + fprintf( stderr, "\n[Warn] Increasing skip factor to %d\n", skip_factor ); + } } - - if( verbosity_level >= 1 && skipped_blocks > 0 ) - fprintf( stderr, _("[Warn] Had to skip (couldn't read) %d blocks (before block %d)! \n "), skipped_blocks, i ); - -/*TODO: this skipping here writes too few bytes to the output */ - - if( write( streamout, bufferin, DVD_VIDEO_LB_LEN * blocks ) < 0 ) + if (skip_factor > 2) { - fprintf( stderr, _("\n[Error] Error writing to %s \n"), output_file ); - fprintf( stderr, _("[Error] Error: %s, errno: %d \n"), strerror( errno ), errno ); + fprintf( stderr, "\n[Warn] Resetting skip factor from %d to %d\n", skip_factor, skip_factor/2 ); + skip_factor /= 2; + } + if( write( streamout, bufferin, DVD_VIDEO_LB_LEN * blocks ) < 0 ) + { + fprintf( stderr, "\n[Error] Error writing to %s \n", output_file ); + fprintf( stderr, _("[Error] Error: %s, errno: %d \n"), strerror( errno ), errno ); exit( 1 ); } -- 1.8.0.2 From 77a1e56554f5c7168752a174453a06fac1c645bd Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Fri, 27 May 2011 17:57:11 +0200 Subject: [PATCH 02/28] Reset the skip factor independantly of the verbosity_level. Doh --- vobcopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index 715d93b..ea43951 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1325,10 +1325,10 @@ next: /*for the goto - ugly, I know... */ { i += file_block_count * skip_factor; skipped_blocks += skip_factor; + skip_factor = skip_factor * 2; if( verbosity_level >= 1 ) { fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); - skip_factor = skip_factor * 2; fprintf( stderr, "\n[Warn] Increasing skip factor to %d\n", skip_factor ); } } -- 1.8.0.2 From 70ce32e4beb5ac880eb266dbb7c6dce10a20e9db Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Fri, 27 May 2011 18:01:52 +0200 Subject: [PATCH 03/28] After skipping worked, reset the skip factor to 1, but go right back to the last working value when skipping again --- vobcopy.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index ea43951..abe46a0 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1313,6 +1313,8 @@ next: /*for the goto - ugly, I know... */ { int tries = 0, skipped_blocks = 0; static int skip_factor = 1; + static int last_skip_factor = 1; + /* Only read and write as many blocks as there are left in the file */ if ( ( i - start + file_block_count ) * DVD_VIDEO_LB_LEN > file_size ) { @@ -1325,17 +1327,33 @@ next: /*for the goto - ugly, I know... */ { i += file_block_count * skip_factor; skipped_blocks += skip_factor; - skip_factor = skip_factor * 2; + if (skip_factor >= last_skip_factor) + { + if (skip_factor < 4096) + { + skip_factor = skip_factor * 2; + } + } + else + { + skip_factor = last_skip_factor; + } if( verbosity_level >= 1 ) { fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); - fprintf( stderr, "\n[Warn] Increasing skip factor to %d\n", skip_factor ); + fprintf( stderr, "[Warn] Increasing skip factor to %d\n", skip_factor ); } } - if (skip_factor > 2) + + if (skip_factor > last_skip_factor) + { + fprintf( stderr, "\n[Warn] Storing skip factor %d\n", skip_factor); + last_skip_factor = skip_factor; + } + if (skip_factor > 1) { - fprintf( stderr, "\n[Warn] Resetting skip factor from %d to %d\n", skip_factor, skip_factor/2 ); - skip_factor /= 2; + fprintf( stderr, "[Warn] Resetting skip factor from %d to %d\n", skip_factor, 1 ); + skip_factor = 1; } if( write( streamout, bufferin, DVD_VIDEO_LB_LEN * blocks ) < 0 ) { -- 1.8.0.2 From 54ede50d72faf9a416adfa43f9303834c63f6e75 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sat, 28 May 2011 22:16:42 +0200 Subject: [PATCH 04/28] Only skip skip_factor bytes at a time, not skip_factor times file_block_count --- vobcopy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index abe46a0..3af58c5 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1311,9 +1311,10 @@ next: /*for the goto - ugly, I know... */ starttime = time(NULL); for( i = start; ( i - start ) * DVD_VIDEO_LB_LEN < file_size; i += file_block_count) { - int tries = 0, skipped_blocks = 0; + int tries = 0; static int skip_factor = 1; static int last_skip_factor = 1; + unsigned skipped_blocks = 0; /* Only read and write as many blocks as there are left in the file */ if ( ( i - start + file_block_count ) * DVD_VIDEO_LB_LEN > file_size ) @@ -1325,7 +1326,7 @@ next: /*for the goto - ugly, I know... */ while( ( blocks = DVDReadBlocks( dvd_file, i, file_block_count, bufferin ) ) <= 0) { - i += file_block_count * skip_factor; + i += skip_factor; skipped_blocks += skip_factor; if (skip_factor >= last_skip_factor) { -- 1.8.0.2 From 159e98598b48b5cc074113cdfbea9bc987ad8528 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sat, 28 May 2011 22:16:58 +0200 Subject: [PATCH 05/28] Write dummy blocks for the skipped ones --- vobcopy.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vobcopy.c b/vobcopy.c index 3af58c5..0906b9b 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1353,8 +1353,19 @@ next: /*for the goto - ugly, I know... */ } if (skip_factor > 1) { + unsigned int dummy_blocks; fprintf( stderr, "[Warn] Resetting skip factor from %d to %d\n", skip_factor, 1 ); skip_factor = 1; + fprintf( stderr, "[Warn] Duplicating first readable block as dummy for the %d skipped ones\n", skipped_blocks ); + for (dummy_blocks = 0; dummy_blocks < skipped_blocks; dummy_blocks++) + { + if( write( streamout, bufferin, DVD_VIDEO_LB_LEN ) < 0 ) + { + fprintf( stderr, "\n[Error] Error writing dummy blocks to %s \n", output_file ); + fprintf( stderr, _("[Error] Error: %s, errno: %d \n"), strerror( errno ), errno ); + exit( 1 ); + } + } } if( write( streamout, bufferin, DVD_VIDEO_LB_LEN * blocks ) < 0 ) { -- 1.8.0.2 From e433ba3a866536ed8f823b2ec429a51c42825447 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 12:06:04 +0200 Subject: [PATCH 06/28] Rename skip_factor to skip_steps --- vobcopy.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 0906b9b..ce9433e 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1312,8 +1312,8 @@ next: /*for the goto - ugly, I know... */ for( i = start; ( i - start ) * DVD_VIDEO_LB_LEN < file_size; i += file_block_count) { int tries = 0; - static int skip_factor = 1; - static int last_skip_factor = 1; + static int skip_step = 1; + static int last_skip_step = 1; unsigned skipped_blocks = 0; /* Only read and write as many blocks as there are left in the file */ @@ -1326,36 +1326,36 @@ next: /*for the goto - ugly, I know... */ while( ( blocks = DVDReadBlocks( dvd_file, i, file_block_count, bufferin ) ) <= 0) { - i += skip_factor; - skipped_blocks += skip_factor; - if (skip_factor >= last_skip_factor) + i += skip_step; + skipped_blocks += skip_step; + if (skip_step >= last_skip_step) { - if (skip_factor < 4096) + if (skip_step < 4096) { - skip_factor = skip_factor * 2; + skip_step = skip_step * 2; } } else { - skip_factor = last_skip_factor; + skip_step = last_skip_step; } if( verbosity_level >= 1 ) { fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); - fprintf( stderr, "[Warn] Increasing skip factor to %d\n", skip_factor ); + fprintf( stderr, "[Warn] Increasing skip steps to %d\n", skip_step ); } } - if (skip_factor > last_skip_factor) + if (skip_step > last_skip_step) { - fprintf( stderr, "\n[Warn] Storing skip factor %d\n", skip_factor); - last_skip_factor = skip_factor; + fprintf( stderr, "\n[Warn] Storing skip steps %d\n", skip_step); + last_skip_step = skip_step; } - if (skip_factor > 1) + if (skip_step > 1) { unsigned int dummy_blocks; - fprintf( stderr, "[Warn] Resetting skip factor from %d to %d\n", skip_factor, 1 ); - skip_factor = 1; + fprintf( stderr, "[Warn] Resetting skip factor from %d to %d\n", skip_step, 1 ); + skip_step = 1; fprintf( stderr, "[Warn] Duplicating first readable block as dummy for the %d skipped ones\n", skipped_blocks ); for (dummy_blocks = 0; dummy_blocks < skipped_blocks; dummy_blocks++) { -- 1.8.0.2 From f03028988c8ce1ca394a66bb41148e915606facc Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 12:07:50 +0200 Subject: [PATCH 07/28] Log when reaching the max skip steps --- vobcopy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vobcopy.c b/vobcopy.c index ce9433e..48aacf4 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1334,6 +1334,10 @@ next: /*for the goto - ugly, I know... */ { skip_step = skip_step * 2; } + else + { + fprintf( stderr, "[Warn] Max skip steps reached %d\n", skip_step); + } } else { -- 1.8.0.2 From 4acd2dda257e37a4594206370b9d1fa1f1309d68 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 12:28:24 +0200 Subject: [PATCH 08/28] Enable the retry logic again and put the sector skipping behind the -s flag Note that the retry logic has been changed to only skip one block at a time, not file_block_count blocks. --- vobcopy.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 48aacf4..5a3b447 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -92,6 +92,7 @@ and potentially fatal." - Thanks Leigh!*/ bool stdout_flag = FALSE, space_greater_2gb_flag = TRUE; bool fast_switch = FALSE, onefile_flag = FALSE; bool quiet_flag = FALSE, longest_title_flag = FALSE; + bool skip_invalid_blocks_flag = FALSE; struct stat buf; float lastpos = 0; int starttime; @@ -152,6 +153,7 @@ and potentially fatal." - Thanks Leigh!*/ {"version", 0, 0, 'V'}, {"watchdog", 1, 0, 'w'}, {"overwrite-all", 0, 0, 'x'}, + {"skip-invalid-blocks", 0, 0, 's'}, {0, 0, 0, 0} }; #endif @@ -173,10 +175,10 @@ and potentially fatal." - Thanks Leigh!*/ { #ifdef HAVE_GETOPT_LONG options_char = getopt_long( argc, argv, - "1:2:3:4:a:b:c:e:i:n:o:qO:t:vfF:lmMhL:Vw:Ix", + "1:2:3:4:a:b:c:e:i:n:o:qO:s:t:vfF:lmMhL:Vw:Ix", long_options ,&option_index); #else - options_char = getopt( argc, argv, "1:2:3:4:a:b:c:e:i:n:o:qO:t:vfF:lmMhL:Vw:Ix-" ); + options_char = getopt( argc, argv, "1:2:3:4:a:b:c:e:i:n:o:qO:s:t:vfF:lmMhL:Vw:Ix-" ); #endif if ( options_char == -1 ) break; @@ -369,6 +371,10 @@ and potentially fatal." - Thanks Leigh!*/ /* force_flag = TRUE; */ break; + case 's': /* skip invalid blocks */ + skip_invalid_blocks_flag = TRUE; + break; + case'q':/*quiet flag* - meaning no progress and such output*/ quiet_flag = TRUE; break; @@ -1326,6 +1332,22 @@ next: /*for the goto - ugly, I know... */ while( ( blocks = DVDReadBlocks( dvd_file, i, file_block_count, bufferin ) ) <= 0) { + if (!skip_invalid_blocks_flag) + { + if (tries == 9) + { + fprintf( stderr, "[Warn] Retry attempt for block %d are up. " + "Consider using the -s flag to skip invalid blocks faster.\n", i); + i ++; + skipped_blocks++; + overall_skipped_blocks++; + tries = 0; + break; + } + fprintf( stderr, "[Warn] Retrying to read block %d.\n", i); + tries++; + continue; + } i += skip_step; skipped_blocks += skip_step; if (skip_step >= last_skip_step) @@ -2130,6 +2152,7 @@ void usage( char *program_name ) fprintf( stderr, _("[-w ]\n" ) ); fprintf( stderr, _("[-x (overwrite all)]\n" ) ); fprintf( stderr, _("[-F ]\n") ); + fprintf( stderr, _("[-s (try to skip sections with invalid blocks writing dummy blocks instead)]\n") ); #if defined( HAS_LARGEFILE ) || defined ( MAC_LARGEFILE ) fprintf( stderr, _("[-l (large-file support for files > 2GB)] \n") ); -- 1.8.0.2 From 526623a1ad53bb0b27a80480dd8fef596554a625 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 13:28:58 +0200 Subject: [PATCH 09/28] Start skip step with 1024. Is this a good idea? --- vobcopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index 5a3b447..906e9c8 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1318,7 +1318,7 @@ next: /*for the goto - ugly, I know... */ for( i = start; ( i - start ) * DVD_VIDEO_LB_LEN < file_size; i += file_block_count) { int tries = 0; - static int skip_step = 1; + static int skip_step = 1024; static int last_skip_step = 1; unsigned skipped_blocks = 0; -- 1.8.0.2 From a3b5d5160bd368a59d8e08184032c5fd858e2ed8 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 13:29:38 +0200 Subject: [PATCH 10/28] Get retry code working as it did previously. Reduce retries from 9 to 3. --- vobcopy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 906e9c8..c1a7fee 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1334,15 +1334,15 @@ next: /*for the goto - ugly, I know... */ { if (!skip_invalid_blocks_flag) { - if (tries == 9) + if (tries == 3) { fprintf( stderr, "[Warn] Retry attempt for block %d are up. " "Consider using the -s flag to skip invalid blocks faster.\n", i); - i ++; + i++; skipped_blocks++; overall_skipped_blocks++; tries = 0; - break; + continue; } fprintf( stderr, "[Warn] Retrying to read block %d.\n", i); tries++; -- 1.8.0.2 From e3fbfa6d71022d2dffdf62b3f9d77d085c16147a Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 13:29:54 +0200 Subject: [PATCH 11/28] Move a log message to the right place. Squash --- vobcopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index c1a7fee..622933a 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -1355,6 +1355,7 @@ next: /*for the goto - ugly, I know... */ if (skip_step < 4096) { skip_step = skip_step * 2; + fprintf( stderr, "[Warn] Increasing skip steps to %d\n", skip_step ); } else { @@ -1368,7 +1369,6 @@ next: /*for the goto - ugly, I know... */ if( verbosity_level >= 1 ) { fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); - fprintf( stderr, "[Warn] Increasing skip steps to %d\n", skip_step ); } } -- 1.8.0.2 From 0119379a6861266962f5bfae6073b2cbbcab4ae0 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 29 May 2011 18:47:32 +0200 Subject: [PATCH 12/28] Factor get_number_of_blocks_to_skip() out of main and let it try to figure out to the last non-working block XXX: no really --- vobcopy.c | 71 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 622933a..47976cb 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -58,6 +58,47 @@ bool overwrite_flag = FALSE; bool overwrite_all_flag = FALSE; int overall_skipped_blocks = 0; +static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offset) +{ + unsigned char bufferin[DVD_VIDEO_LB_LEN * BLOCK_COUNT]; + int blocks; + int offset; + /* + * Static so we use the last working value when called more than once. + * The initial value seems to be a reasonable guess but maybe it should be + * configurable. + */ + static int blocks_to_skip = 64; + + blocks_to_skip /= 2; + + do + { + blocks_to_skip *= 2; + fprintf( stderr, _("Reading block %d failed, trying block %d\n"), offset, original_offset + blocks_to_skip); + offset = original_offset + blocks_to_skip; + } while ((blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) <= 0); + + fprintf( stderr, _("Got a valid block at offset %d, after skipping %d. Trying to reduce the skipped blocks\n"), + offset, blocks_to_skip); + + do + { + /* + * XXX: This could be done smarter, for example by using a binary search. + */ + blocks_to_skip--; + offset = original_offset + blocks_to_skip; + } + while (blocks_to_skip > 0 && (blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) > 0); + + fprintf( stderr, _("Got an ivalid block at offset %d, after skipping %d. Returning %d\n"), + offset, blocks_to_skip, blocks_to_skip +1); + + return blocks_to_skip + 1; +} + + /* --------------------------------------------------------------------------*/ /* MAIN */ /* --------------------------------------------------------------------------*/ @@ -1318,8 +1359,7 @@ next: /*for the goto - ugly, I know... */ for( i = start; ( i - start ) * DVD_VIDEO_LB_LEN < file_size; i += file_block_count) { int tries = 0; - static int skip_step = 1024; - static int last_skip_step = 1; + int skip_step = 0; unsigned skipped_blocks = 0; /* Only read and write as many blocks as there are left in the file */ @@ -1348,40 +1388,17 @@ next: /*for the goto - ugly, I know... */ tries++; continue; } + skip_step = get_number_of_blocks_to_skip(dvd_file, i); i += skip_step; skipped_blocks += skip_step; - if (skip_step >= last_skip_step) - { - if (skip_step < 4096) - { - skip_step = skip_step * 2; - fprintf( stderr, "[Warn] Increasing skip steps to %d\n", skip_step ); - } - else - { - fprintf( stderr, "[Warn] Max skip steps reached %d\n", skip_step); - } - } - else - { - skip_step = last_skip_step; - } if( verbosity_level >= 1 ) { fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); } } - - if (skip_step > last_skip_step) - { - fprintf( stderr, "\n[Warn] Storing skip steps %d\n", skip_step); - last_skip_step = skip_step; - } - if (skip_step > 1) + if (skip_step > 0) { unsigned int dummy_blocks; - fprintf( stderr, "[Warn] Resetting skip factor from %d to %d\n", skip_step, 1 ); - skip_step = 1; fprintf( stderr, "[Warn] Duplicating first readable block as dummy for the %d skipped ones\n", skipped_blocks ); for (dummy_blocks = 0; dummy_blocks < skipped_blocks; dummy_blocks++) { -- 1.8.0.2 From 81fd0032da5be0ea85e6db983e8d285ebef4e0b3 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 28 Mar 2012 19:49:02 +0200 Subject: [PATCH 13/28] Start with 1024 blocks to skip. Good idea? --- vobcopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index 47976cb..c800107 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -68,7 +68,7 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse * The initial value seems to be a reasonable guess but maybe it should be * configurable. */ - static int blocks_to_skip = 64; + static int blocks_to_skip = 1024; blocks_to_skip /= 2; -- 1.8.0.2 From 0201ba3e0cfd58fcc38099568d981b982f1fe2e9 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 28 Mar 2012 19:50:29 +0200 Subject: [PATCH 14/28] At the beginning of get_number_of_blocks_to_skip(), do not let blocks_to_skip shrink below the default. --- vobcopy.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index c800107..527adfe 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -70,7 +70,10 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse */ static int blocks_to_skip = 1024; - blocks_to_skip /= 2; + if (blocks_to_skip >= 1024) + { + blocks_to_skip /= 2; + } do { -- 1.8.0.2 From de8f013e4714dfb326bdf2b771ff02b329f40a90 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Fri, 30 Mar 2012 17:07:27 +0200 Subject: [PATCH 15/28] Turn blocks_to_skip into and unsigned. Skipping a negative number of blocks makes no sense --- vobcopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index 527adfe..d6ec169 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -68,7 +68,7 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse * The initial value seems to be a reasonable guess but maybe it should be * configurable. */ - static int blocks_to_skip = 1024; + static unsigned int blocks_to_skip = 1024; if (blocks_to_skip >= 1024) { -- 1.8.0.2 From 8dceeeef924d0096e37487201055c3f2c8a814e2 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 12:59:04 +0200 Subject: [PATCH 16/28] Reduce initial skip count to 128. 1024 breaks too many rips --- vobcopy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index d6ec169..64bbe08 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -68,9 +68,9 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse * The initial value seems to be a reasonable guess but maybe it should be * configurable. */ - static unsigned int blocks_to_skip = 1024; + static unsigned int blocks_to_skip = 128; - if (blocks_to_skip >= 1024) + if (blocks_to_skip >= 128) { blocks_to_skip /= 2; } -- 1.8.0.2 From 786f640fb4e8cca14b3754097c84df8e9428d5d0 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 13:32:09 +0200 Subject: [PATCH 17/28] Increase BLOCK_COUNT to 16384 --- vobcopy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.h b/vobcopy.h index a4de500..94ab0e9 100644 --- a/vobcopy.h +++ b/vobcopy.h @@ -9,7 +9,7 @@ #endif #define DVDCSS_VERBOSE 1 -#define BLOCK_COUNT 64 +#define BLOCK_COUNT 16384 #define MAX_STRING 81 #define MAX_DIFFER 2000 -- 1.8.0.2 From b1e70b0cdb0c31be99248426d1816b96f5f6e126 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 13:33:00 +0200 Subject: [PATCH 18/28] Prevent skip counts below 1 --- vobcopy.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vobcopy.c b/vobcopy.c index 64bbe08..6c2d16d 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -87,6 +87,10 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse do { + if (blocks_to_skip < 2) + { + break; + } /* * XXX: This could be done smarter, for example by using a binary search. */ -- 1.8.0.2 From 3f581634d94477603d00a80740a97c50ce677511 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 13:33:22 +0200 Subject: [PATCH 19/28] Fix typo --- vobcopy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index 6c2d16d..4a24c01 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -99,7 +99,7 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse } while (blocks_to_skip > 0 && (blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) > 0); - fprintf( stderr, _("Got an ivalid block at offset %d, after skipping %d. Returning %d\n"), + fprintf( stderr, _("Got an invalid block at offset %d, after skipping %d. Returning %d\n"), offset, blocks_to_skip, blocks_to_skip +1); return blocks_to_skip + 1; -- 1.8.0.2 From a5df853ac5532cc361c79655b76fdf3b9c2c4499 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 13:34:34 +0200 Subject: [PATCH 20/28] WIP implementation of --skip-existing-files --- vobcopy.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 4a24c01..f718152 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -141,6 +141,7 @@ and potentially fatal." - Thanks Leigh!*/ bool fast_switch = FALSE, onefile_flag = FALSE; bool quiet_flag = FALSE, longest_title_flag = FALSE; bool skip_invalid_blocks_flag = FALSE; + bool skip_existing_files_flag = FALSE; struct stat buf; float lastpos = 0; int starttime; @@ -202,6 +203,7 @@ and potentially fatal." - Thanks Leigh!*/ {"watchdog", 1, 0, 'w'}, {"overwrite-all", 0, 0, 'x'}, {"skip-invalid-blocks", 0, 0, 's'}, + {"skip-existing-files", 0, 0, 'S'}, {0, 0, 0, 0} }; #endif @@ -223,10 +225,10 @@ and potentially fatal." - Thanks Leigh!*/ { #ifdef HAVE_GETOPT_LONG options_char = getopt_long( argc, argv, - "1:2:3:4:a:b:c:e:i:n:o:qO:s:t:vfF:lmMhL:Vw:Ix", + "sS1:2:3:4:a:b:c:e:i:n:o:qO:t:vfF:lmMhL:Vw:Ix", long_options ,&option_index); #else - options_char = getopt( argc, argv, "1:2:3:4:a:b:c:e:i:n:o:qO:s:t:vfF:lmMhL:Vw:Ix-" ); + options_char = getopt( argc, argv, "sS1:2:3:4:a:b:c:e:i:n:o:qO::t:vfF:lmMhL:Vw:Ix-" ); #endif if ( options_char == -1 ) break; @@ -421,6 +423,12 @@ and potentially fatal." - Thanks Leigh!*/ case 's': /* skip invalid blocks */ skip_invalid_blocks_flag = TRUE; + fprintf( stderr, _("[Hint] Enabled skipping of invalid blocks\n") ); + break; + + case 'S': /* skip already existing files without user input */ + fprintf( stderr, _("[Hint] Enabled skipping of already existing files\n") ); + skip_existing_files_flag = TRUE; break; case'q':/*quiet flag* - meaning no progress and such output*/ @@ -1102,11 +1110,23 @@ next: /*for the goto - ugly, I know... */ { bool bSkip = FALSE; + if (skip_existing_files_flag) + { + fprintf( stderr, _("\n[Error] Skipping already existing file '%s'.\n"), output_file ); + continue; + } if ( overwrite_all_flag == FALSE ) fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all, [s]kip or [q]uit? "), output_file ); /*TODO: add [a]ppend and seek thought stream till point of append is there */ while ( 1 ) { + if (skip_existing_files_flag) + { + fprintf( stderr, _("\n[Error] Skipping already existing file '%s'.\n"), output_file ); + bSkip = TRUE; + break; + } + /* process a single character from stdin, ignore EOF bytes & newlines*/ if ( overwrite_all_flag == TRUE ) op = 'o'; @@ -1728,7 +1748,7 @@ The man replies, "I was talking to the sheep." if( open( name, O_RDONLY ) >= 0 ) { if ( overwrite_all_flag == FALSE ) - fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all or [q]uit? \n"), name ); + fprintf( stderr, _("\n[Error] File '%s' already exists. shit, [o]verwrite, [x]overwrite all or [q]uit? \n"), name ); /*TODO: add [a]ppend and seek thought stream till point of append is there */ while ( 1 ) { @@ -1785,7 +1805,7 @@ The man replies, "I was talking to the sheep." exit ( 1 ); } if ( overwrite_all_flag == FALSE ) - fprintf( stderr, _("\n[Error] File '%s' already exists, [o]verwrite, [x]overwrite all, [a]ppend, [q]uit? \n"), name ); + fprintf( stderr, _("\n[Error] Oops File '%s' already exists, [o]verwrite, [x]overwrite all, [a]ppend, [q]uit? \n"), name ); while ( 1 ) { if ( overwrite_all_flag == TRUE ) -- 1.8.0.2 From f59b8d134f1883012285f4f2a05ae75451352d94 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 13:57:23 +0200 Subject: [PATCH 21/28] After skipping unreadable blocks, never try to read more blocks then we know are readable --- vobcopy.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index f718152..ae6a742 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -58,7 +58,9 @@ bool overwrite_flag = FALSE; bool overwrite_all_flag = FALSE; int overall_skipped_blocks = 0; -static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offset) +#define INITIAL_SKIP_COUNT 128 + +static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int original_offset, unsigned int *known_good_blocks) { unsigned char bufferin[DVD_VIDEO_LB_LEN * BLOCK_COUNT]; int blocks; @@ -68,10 +70,20 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse * The initial value seems to be a reasonable guess but maybe it should be * configurable. */ - static unsigned int blocks_to_skip = 128; + static unsigned int blocks_to_skip = INITIAL_SKIP_COUNT; + + if (blocks_to_skip < INITIAL_SKIP_COUNT) + { + /* + * The last value is too low and would slow us down, + * so pretend it doesn't exist. + */ + blocks_to_skip = INITIAL_SKIP_COUNT; + } - if (blocks_to_skip >= 128) + if (blocks_to_skip >= INITIAL_SKIP_COUNT) { + /* Will be doubled again in the next loop. */ blocks_to_skip /= 2; } @@ -85,6 +97,8 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse fprintf( stderr, _("Got a valid block at offset %d, after skipping %d. Trying to reduce the skipped blocks\n"), offset, blocks_to_skip); + *known_good_blocks = blocks_to_skip; + do { if (blocks_to_skip < 2) @@ -99,8 +113,10 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, int original_offse } while (blocks_to_skip > 0 && (blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) > 0); - fprintf( stderr, _("Got an invalid block at offset %d, after skipping %d. Returning %d\n"), - offset, blocks_to_skip, blocks_to_skip +1); + *known_good_blocks -= blocks_to_skip; + + fprintf( stderr, _("Got an invalid block at offset %d, after skipping %d. Known good blocks: %u. Returning %d\n"), + offset, blocks_to_skip, *known_good_blocks, blocks_to_skip +1); return blocks_to_skip + 1; } @@ -1388,6 +1404,7 @@ next: /*for the goto - ugly, I know... */ int tries = 0; int skip_step = 0; unsigned skipped_blocks = 0; + unsigned known_good_blocks; /* Only read and write as many blocks as there are left in the file */ if ( ( i - start + file_block_count ) * DVD_VIDEO_LB_LEN > file_size ) @@ -1415,12 +1432,17 @@ next: /*for the goto - ugly, I know... */ tries++; continue; } - skip_step = get_number_of_blocks_to_skip(dvd_file, i); + skip_step = get_number_of_blocks_to_skip(dvd_file, i, &known_good_blocks); i += skip_step; skipped_blocks += skip_step; + if (file_block_count > known_good_blocks) + { + file_block_count = known_good_blocks; + } if( verbosity_level >= 1 ) { - fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading at offset %d\n", skipped_blocks, i ); + fprintf( stderr, "[Warn] Had to skip %d blocks! Now reading %u blocks at offset %d\n", + skipped_blocks, file_block_count, i ); } } if (skip_step > 0) -- 1.8.0.2 From ed89ac690b22271bf76ea57f76f688580ef4c084 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 14:41:36 +0200 Subject: [PATCH 22/28] Add a comment about the purpose of get_number_of_blocks_to_skip() --- vobcopy.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vobcopy.c b/vobcopy.c index ae6a742..10c27f8 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -60,6 +60,16 @@ int overall_skipped_blocks = 0; #define INITIAL_SKIP_COUNT 128 +/* + * Given an offset to a dvd_file_t, figure out how many + * unreadable blocks have to be skipped to reach the next + * readable block. + * + * Also reports the number of readable sectors that are known + * to exist, so the caller can adjust it's buffer size + * accordingly to make sure the next read operation can be + * successful. + */ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int original_offset, unsigned int *known_good_blocks) { unsigned char bufferin[DVD_VIDEO_LB_LEN * BLOCK_COUNT]; -- 1.8.0.2 From f954ab4cd0323ec45d7240894669c6597f38ecdb Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 1 Apr 2012 15:55:18 +0200 Subject: [PATCH 23/28] In get_number_of_blocks_to_skip(), deal with the possibility that all block in the window are readable --- vobcopy.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 10c27f8..9c46f3e 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -74,13 +74,14 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int origi { unsigned char bufferin[DVD_VIDEO_LB_LEN * BLOCK_COUNT]; int blocks; - int offset; + int offset = original_offset; + int known_readable_sectors; /* * Static so we use the last working value when called more than once. * The initial value seems to be a reasonable guess but maybe it should be * configurable. */ - static unsigned int blocks_to_skip = INITIAL_SKIP_COUNT; + static int blocks_to_skip = INITIAL_SKIP_COUNT; if (blocks_to_skip < INITIAL_SKIP_COUNT) { @@ -100,21 +101,18 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int origi do { blocks_to_skip *= 2; - fprintf( stderr, _("Reading block %d failed, trying block %d\n"), offset, original_offset + blocks_to_skip); + fprintf( stderr, _("Reading blocks starting at %d failed, trying to read a single block at %d\n"), + offset, original_offset + blocks_to_skip); offset = original_offset + blocks_to_skip; } while ((blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) <= 0); fprintf( stderr, _("Got a valid block at offset %d, after skipping %d. Trying to reduce the skipped blocks\n"), offset, blocks_to_skip); - *known_good_blocks = blocks_to_skip; + known_readable_sectors = blocks_to_skip; do { - if (blocks_to_skip < 2) - { - break; - } /* * XXX: This could be done smarter, for example by using a binary search. */ @@ -123,12 +121,26 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int origi } while (blocks_to_skip > 0 && (blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) > 0); - *known_good_blocks -= blocks_to_skip; + blocks_to_skip++; + + if (blocks_to_skip == 0) + { + /* + * This can happen if the caller tried to read more blocks at + * once then we did. + */ + fprintf( stderr, _("All of the %d blocks starting at offset %d appear to be readable\n"), + *known_good_blocks, original_offset); + } + else + { + fprintf( stderr, _("Got an invalid block at offset %d, after skipping %d. Known good blocks: %u. Returning %d\n"), + offset, blocks_to_skip-1, *known_good_blocks, blocks_to_skip); + } - fprintf( stderr, _("Got an invalid block at offset %d, after skipping %d. Known good blocks: %u. Returning %d\n"), - offset, blocks_to_skip, *known_good_blocks, blocks_to_skip +1); + *known_good_blocks = known_readable_sectors - blocks_to_skip; - return blocks_to_skip + 1; + return blocks_to_skip; } -- 1.8.0.2 From 911dc0381c22d66dfdb24f3aad16346213829ada Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sat, 28 Apr 2012 19:55:05 +0200 Subject: [PATCH 24/28] Let get_number_of_blocks_to_skip() ensure that that at least one good block is known --- vobcopy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vobcopy.c b/vobcopy.c index 9c46f3e..401a94b 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -140,6 +140,11 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int origi *known_good_blocks = known_readable_sectors - blocks_to_skip; + if (*known_good_blocks == 0) + { + *known_good_blocks = 1; + } + return blocks_to_skip; } -- 1.8.0.2 From bea80e593022ef6f5f5c32906a5441e3057233de Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sat, 28 Apr 2012 19:55:56 +0200 Subject: [PATCH 25/28] Let get_number_of_blocks_to_skip() use the fast_factor as INITIAL_SKIP_COUNT. --- vobcopy.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 401a94b..4c778ae 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -58,8 +58,6 @@ bool overwrite_flag = FALSE; bool overwrite_all_flag = FALSE; int overall_skipped_blocks = 0; -#define INITIAL_SKIP_COUNT 128 - /* * Given an offset to a dvd_file_t, figure out how many * unreadable blocks have to be skipped to reach the next @@ -70,7 +68,9 @@ int overall_skipped_blocks = 0; * accordingly to make sure the next read operation can be * successful. */ -static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int original_offset, unsigned int *known_good_blocks) +static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, + unsigned int original_offset, unsigned int *known_good_blocks, + unsigned int INITIAL_SKIP_COUNT) { unsigned char bufferin[DVD_VIDEO_LB_LEN * BLOCK_COUNT]; int blocks; @@ -81,7 +81,8 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, unsigned int origi * The initial value seems to be a reasonable guess but maybe it should be * configurable. */ - static int blocks_to_skip = INITIAL_SKIP_COUNT; + static int blocks_to_skip; + if (blocks_to_skip < INITIAL_SKIP_COUNT) { @@ -1459,7 +1460,7 @@ next: /*for the goto - ugly, I know... */ tries++; continue; } - skip_step = get_number_of_blocks_to_skip(dvd_file, i, &known_good_blocks); + skip_step = get_number_of_blocks_to_skip(dvd_file, i, &known_good_blocks, fast_factor); i += skip_step; skipped_blocks += skip_step; if (file_block_count > known_good_blocks) -- 1.8.0.2 From 6bd53acca8cbfed406ca7a0d71b83e215efb8960 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Fri, 6 Jul 2012 14:23:21 +0200 Subject: [PATCH 26/28] Print a message when increasing the skip count to INITIAL_SKIP_COUNT --- vobcopy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/vobcopy.c b/vobcopy.c index 4c778ae..86bb32c 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -91,6 +91,7 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, * so pretend it doesn't exist. */ blocks_to_skip = INITIAL_SKIP_COUNT; + fprintf( stderr, _("Increased skip count to %d\n"), blocks_to_skip); } if (blocks_to_skip >= INITIAL_SKIP_COUNT) -- 1.8.0.2 From 4de4dff14b5c0f2484fc7b25ea6fb4d16133a2fc Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Fri, 6 Jul 2012 14:28:47 +0200 Subject: [PATCH 27/28] Add an UPPER_INITIAL_SKIP_LIMIT --- vobcopy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vobcopy.c b/vobcopy.c index 86bb32c..5a754e0 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -83,7 +83,7 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, */ static int blocks_to_skip; - + #define UPPER_INITIAL_SKIP_LIMIT 10000 if (blocks_to_skip < INITIAL_SKIP_COUNT) { /* @@ -93,6 +93,11 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, blocks_to_skip = INITIAL_SKIP_COUNT; fprintf( stderr, _("Increased skip count to %d\n"), blocks_to_skip); } + else if (UPPER_INITIAL_SKIP_LIMIT < blocks_to_skip) + { + blocks_to_skip = INITIAL_SKIP_COUNT; + fprintf( stderr, _("Decreased skip count to %d\n"), blocks_to_skip); + } if (blocks_to_skip >= INITIAL_SKIP_COUNT) { -- 1.8.0.2 From a678cc584b99f045ed90559f701af4e9534eff7f Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Fri, 6 Jul 2012 15:04:35 +0200 Subject: [PATCH 28/28] Attempt to properly deal with files that do not contain valid blocks at the end --- vobcopy.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/vobcopy.c b/vobcopy.c index 5a754e0..fa724ed 100644 --- a/vobcopy.c +++ b/vobcopy.c @@ -69,7 +69,8 @@ int overall_skipped_blocks = 0; * successful. */ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, - unsigned int original_offset, unsigned int *known_good_blocks, + unsigned int original_offset, unsigned int last_valid_offset, + unsigned int *known_good_blocks, unsigned int INITIAL_SKIP_COUNT) { unsigned char bufferin[DVD_VIDEO_LB_LEN * BLOCK_COUNT]; @@ -107,10 +108,25 @@ static int get_number_of_blocks_to_skip(dvd_file_t *dvd_file, do { + /* XXX: Could be reached in normal operation. Use temporary variable. */ + if (offset == last_valid_offset) + { + fprintf( stderr, _("The last valid sector %d appears to be unreachable. Shit.\n"), + offset); + *known_good_blocks = 0; + return offset; + } blocks_to_skip *= 2; fprintf( stderr, _("Reading blocks starting at %d failed, trying to read a single block at %d\n"), offset, original_offset + blocks_to_skip); offset = original_offset + blocks_to_skip; + + if (offset > last_valid_offset) + { + fprintf( stderr, _("Reducing offset from %d to the last valid offset %d\n"), + offset, last_valid_offset); + offset = last_valid_offset; + } } while ((blocks = DVDReadBlocks(dvd_file, offset, 1, bufferin)) <= 0); fprintf( stderr, _("Got a valid block at offset %d, after skipping %d. Trying to reduce the skipped blocks\n"), @@ -1439,6 +1455,7 @@ next: /*for the goto - ugly, I know... */ int skip_step = 0; unsigned skipped_blocks = 0; unsigned known_good_blocks; + const unsigned last_valid_offset = tmp_file_size - start; /* Only read and write as many blocks as there are left in the file */ if ( ( i - start + file_block_count ) * DVD_VIDEO_LB_LEN > file_size ) @@ -1466,10 +1483,14 @@ next: /*for the goto - ugly, I know... */ tries++; continue; } - skip_step = get_number_of_blocks_to_skip(dvd_file, i, &known_good_blocks, fast_factor); + skip_step = get_number_of_blocks_to_skip(dvd_file, i, last_valid_offset, &known_good_blocks, fast_factor); + if (known_good_blocks == 0) + { + fprintf( stderr, "[Warn] The rest of the file appears to be garbage.\n", i); + } i += skip_step; skipped_blocks += skip_step; - if (file_block_count > known_good_blocks) + if ((known_good_blocks != 0) && (file_block_count > known_good_blocks)) { file_block_count = known_good_blocks; } -- 1.8.0.2