Adapted media evaluation to CD peculiarities
This commit is contained in:
@ -6557,18 +6557,21 @@ int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag)
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* @return <=0 error, 1= done, 2= aborted due to limit
|
||||
*/
|
||||
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
|
||||
struct CheckmediajoB *job,
|
||||
int from_lba, int block_count,
|
||||
int read_chunk, int min_block_size, int flag)
|
||||
{
|
||||
int i, ret, total_count= 0;
|
||||
int prev_quality= -1, quality= -1;
|
||||
int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
|
||||
int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd;
|
||||
int start_sec, end_sec, first_value;
|
||||
char profile_name[80];
|
||||
int start_lba= 0;
|
||||
struct burn_drive *drive;
|
||||
struct burn_drive_info *dinfo;
|
||||
char data[64*1024];
|
||||
char data[64*1024], sfe[5*SfileadrL];
|
||||
off_t data_count, to_read;
|
||||
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
|
||||
|
||||
@ -6576,9 +6579,25 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
|
||||
"on attempt to check media readability", 0);
|
||||
if(ret<=0)
|
||||
goto ex;
|
||||
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
|
||||
if(ret > 0)
|
||||
if(profile_no >= 0x08 && profile_no <= 0x0a)
|
||||
is_cd= 1;
|
||||
|
||||
if(job->sector_map != NULL) {
|
||||
Sectorbitmap_get_layout(job->sector_map, §ors, §or_size, 0);
|
||||
sector_size/= 2048;
|
||||
}
|
||||
|
||||
if(job->retry > 0)
|
||||
retry= 1;
|
||||
else if(job-retry == 0 && is_cd)
|
||||
retry= 1;
|
||||
|
||||
start_lba= from_lba;
|
||||
for(i= 0; i < block_count; i+= read_chunk) {
|
||||
to_read= read_chunk;
|
||||
for(i= 0; i < block_count; i+= to_read) {
|
||||
skip_reading= 0;
|
||||
if(job->item_limit > 0 &&
|
||||
Spotlist_count(spotlist, 0) + 2 >= job->item_limit) {
|
||||
sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d",
|
||||
@ -6599,7 +6618,7 @@ abort_check:;
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - 1,
|
||||
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i,
|
||||
Xorriso_read_quality_untesteD, 0);
|
||||
if(ret > 0)
|
||||
ret= 2;
|
||||
@ -6608,27 +6627,103 @@ abort_check:;
|
||||
to_read= read_chunk;
|
||||
if(i + to_read > block_count)
|
||||
to_read= block_count - i;
|
||||
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
|
||||
to_read * (off_t) 2048, &data_count, 4);
|
||||
post_read_time= Sfile_microtime(0);
|
||||
time_diff= post_read_time - pre_read_time;
|
||||
total_time_diff+= time_diff;
|
||||
total_count++;
|
||||
if(ret <= 0) {
|
||||
Xorriso_process_msg_queues(xorriso,0);
|
||||
quality= Xorriso_read_quality_unreadablE;
|
||||
if(read_chunk > min_block_size) {
|
||||
if(is_cd && i + to_read + 2 >= block_count) {
|
||||
/* Read last 2 blocks of CD track separately, because with TAO tracks
|
||||
they are always unreadable but with SAO tracks they contain data.
|
||||
*/
|
||||
if(to_read > 2)
|
||||
to_read-= 2;
|
||||
else if(to_read > 1)
|
||||
to_read--;
|
||||
}
|
||||
|
||||
/* >>> evaluate min blocks */;
|
||||
#ifdef NIX
|
||||
/* >>> this is not yet suitable for min_block_size */
|
||||
#endif
|
||||
|
||||
if(sector_size == read_chunk && from_lba % read_chunk == 0) {
|
||||
if(Sectorbitmap_is_set(job->sector_map, (i + from_lba) / read_chunk, 0)) {
|
||||
quality= Xorriso_read_quality_valiD;
|
||||
skip_reading= 1;
|
||||
}
|
||||
} else if(sector_size > 0) {
|
||||
start_sec= (i + from_lba) / sector_size;
|
||||
end_sec= (i + to_read + from_lba) / sector_size;
|
||||
first_value= Sectorbitmap_is_set(job->sector_map, start_sec, 0);
|
||||
for(j= start_sec; j < end_sec; j++)
|
||||
if(Sectorbitmap_is_set(job->sector_map, j, 0) != first_value)
|
||||
break;
|
||||
to_read= j * sector_size - i - from_lba;
|
||||
skip_reading= !!first_value;
|
||||
if(skip_reading)
|
||||
quality= Xorriso_read_quality_valiD;
|
||||
}
|
||||
|
||||
if(skip_reading) {
|
||||
pre_read_time= post_read_time= Sfile_microtime(0);
|
||||
} else {
|
||||
quality= Xorriso_read_quality_gooD;
|
||||
data_count= 0;
|
||||
pre_read_time= Sfile_microtime(0);
|
||||
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
|
||||
to_read * (off_t) 2048, &data_count, 4 * !retry);
|
||||
post_read_time= Sfile_microtime(0);
|
||||
time_diff= post_read_time - pre_read_time;
|
||||
total_time_diff+= time_diff;
|
||||
total_count++;
|
||||
if(ret <= 0) {
|
||||
Xorriso_process_msg_queues(xorriso,0);
|
||||
|
||||
/* >>> find better threshold than 1.0 */
|
||||
if(data_count > 0 && retry) {
|
||||
if(prev_quality >= 0) {
|
||||
ret= Spotlist_add_item(spotlist, start_lba,
|
||||
i + from_lba - start_lba, prev_quality, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048,
|
||||
Xorriso_read_quality_partiaL, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
start_lba= i + from_lba + data_count / 2048;
|
||||
prev_quality= Xorriso_read_quality_unreadablE;
|
||||
}
|
||||
quality= Xorriso_read_quality_unreadablE;
|
||||
|
||||
if(time_diff > 1.0 && i > 0)
|
||||
quality= Xorriso_read_quality_sloW;
|
||||
#ifdef NIX
|
||||
if(read_chunk > min_block_size) {
|
||||
|
||||
/* >>> evaluate min blocks */;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} else {
|
||||
quality= Xorriso_read_quality_gooD;
|
||||
|
||||
/* >>> find better threshold than 1.0 */
|
||||
|
||||
if(time_diff > 1.0 && i > 0)
|
||||
quality= Xorriso_read_quality_sloW;
|
||||
}
|
||||
if(data_count > 0) {
|
||||
if(job->data_to_fd >= 0) {
|
||||
ret= lseek(job->data_to_fd, ((off_t) (i + from_lba)) * (off_t) 2048,
|
||||
SEEK_SET);
|
||||
if(ret == -1) {
|
||||
failed_to_write:;
|
||||
sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of %s",
|
||||
(int) data_count, i + from_lba,
|
||||
Text_shellsafe(job->data_to_path, sfe, 0));
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
|
||||
"FAILURE", 0);
|
||||
{ret= 0; goto ex;}
|
||||
}
|
||||
ret= write(job->data_to_fd, data, data_count);
|
||||
if(ret == -1)
|
||||
goto failed_to_write;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(quality != prev_quality) {
|
||||
if(prev_quality >= 0) {
|
||||
@ -6669,10 +6764,17 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
|
||||
struct CheckmediajoB *job, int flag)
|
||||
{
|
||||
int media_blocks= 0, read_chunk= 16, ret, mode, min_block_size, start_lba= 0;
|
||||
int blocks;
|
||||
int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba;
|
||||
int num_sessions, num_tracks, declare_untested= 0, sector_size, count;
|
||||
int lba, quality;
|
||||
char sfe[5*SfileadrL];
|
||||
struct burn_drive *drive;
|
||||
struct burn_drive_info *dinfo;
|
||||
struct isoburn_toc_disc *isoburn_disc= NULL;
|
||||
struct isoburn_toc_session **isoburn_sessions;
|
||||
struct isoburn_toc_track **iso_burn_tracks;
|
||||
struct burn_toc_entry isoburn_entry;
|
||||
struct stat stbuf;
|
||||
|
||||
*spotlist= NULL;
|
||||
|
||||
@ -6692,6 +6794,30 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
|
||||
if(ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
|
||||
if(job->sector_map_path[0]) {
|
||||
Sectorbitmap_destroy(&(job->sector_map), 0);
|
||||
if(stat(job->sector_map_path, &stbuf) != -1) {
|
||||
ret= Sectorbitmap_from_file(&(job->sector_map), job->sector_map_path,
|
||||
xorriso->info_text, &os_errno, 0);
|
||||
if(ret <= 0) {
|
||||
if(xorriso->info_text[0])
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno,
|
||||
"FAILURE", 0);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(job->data_to_path[0]) {
|
||||
job->data_to_fd= open(job->data_to_path, O_WRONLY | O_CREAT,
|
||||
S_IRUSR | S_IWUSR);
|
||||
if(job->data_to_fd == -1) {
|
||||
sprintf(xorriso->info_text, "Cannot open path %s",
|
||||
Text_shellsafe(job->data_to_path, sfe, 0));
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
|
||||
{ret= 0; goto ex;}
|
||||
}
|
||||
}
|
||||
Xorriso_pacifier_reset(xorriso, 0);
|
||||
job->start_time= time(NULL);
|
||||
mode= job->mode;
|
||||
@ -6705,11 +6831,55 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
|
||||
} else if(mode == 0) {
|
||||
} else if(mode == 0) { /* track by track */
|
||||
isoburn_disc= isoburn_toc_drive_get_disc(drive);
|
||||
if(isoburn_disc == NULL)
|
||||
goto no_content_visible;
|
||||
isoburn_sessions=
|
||||
isoburn_toc_disc_get_sessions(isoburn_disc, &num_sessions);
|
||||
for(i= 0; i < num_sessions; i++) {
|
||||
iso_burn_tracks= isoburn_toc_session_get_tracks(isoburn_sessions[i],
|
||||
&num_tracks);
|
||||
for(j= 0; j < num_tracks; j++) {
|
||||
isoburn_toc_track_get_entry(iso_burn_tracks[j], &isoburn_entry);
|
||||
if(!(isoburn_entry.extensions_valid & 1)) /* should not happen */
|
||||
continue;
|
||||
track_lba= isoburn_entry.start_lba;
|
||||
track_blocks= isoburn_entry.track_blocks;
|
||||
if(last_track_end >= 0 && last_track_end < track_lba &&
|
||||
last_track_end >= start_lba) {
|
||||
ret= Spotlist_add_item(*spotlist, last_track_end,
|
||||
track_lba - last_track_end,
|
||||
Xorriso_read_quality_off_tracK, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
last_track_end= track_lba + track_blocks;
|
||||
|
||||
/* >>> track by track */;
|
||||
if(track_lba < start_lba) {
|
||||
track_blocks-= start_lba - track_lba;
|
||||
track_lba= start_lba;
|
||||
}
|
||||
if(track_blocks <= 0)
|
||||
continue;
|
||||
if(declare_untested) {
|
||||
ret= Spotlist_add_item(*spotlist, track_lba, track_blocks,
|
||||
Xorriso_read_quality_untesteD, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
} else {
|
||||
ret= Xorriso_check_interval(xorriso, *spotlist, job,
|
||||
track_lba, track_blocks,
|
||||
read_chunk, min_block_size, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
if(ret == 2)
|
||||
declare_untested= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if(mode == 1) {
|
||||
} else if(mode == 1) { /* isoburn disc capacity */
|
||||
isoburn_disc= isoburn_toc_drive_get_disc(drive);
|
||||
if(isoburn_disc == NULL) {
|
||||
no_content_visible:;
|
||||
@ -6738,6 +6908,32 @@ no_content_visible:;
|
||||
xorriso->pacifier_count, xorriso->pacifier_total, "", 1);
|
||||
ret= 1;
|
||||
ex:;
|
||||
if(job->data_to_fd != -1)
|
||||
close(job->data_to_fd);
|
||||
if(ret > 0 && job->sector_map_path[0]) {
|
||||
sector_size= read_chunk * 2048;
|
||||
count= Spotlist_count(*spotlist, 0);
|
||||
for(i= 0; i < count; i++) {
|
||||
ret= Spotlist_get_item(*spotlist, i, &lba, &blocks, &quality, 0);
|
||||
if(ret <= 0)
|
||||
continue;
|
||||
if(lba % read_chunk) {
|
||||
sector_size= 2048;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, sector_size,
|
||||
&(job->sector_map), 0);
|
||||
if(ret > 0) {
|
||||
ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path,
|
||||
xorriso->info_text, &os_errno, 0);
|
||||
if(ret <= 0) {
|
||||
if(xorriso->info_text[0])
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno,
|
||||
"FAILURE", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ret < 0)
|
||||
Spotlist_destroy(spotlist, 0);
|
||||
return(ret);
|
||||
|
Reference in New Issue
Block a user