diff --git a/xorriso/drive_mgt.c b/xorriso/drive_mgt.c index 4de434a1..4bd41620 100644 --- a/xorriso/drive_mgt.c +++ b/xorriso/drive_mgt.c @@ -1550,49 +1550,80 @@ ex:; } +/* @param flag bit0= This is write speed. Consider the existence of + combo drives (e.g. DVD-ROM/CD-RW or BD-ROM/DVD+-RW) +*/ int Xorriso_choose_speed_factor(struct XorrisO *xorriso, int speed, int profile, + struct burn_drive *drive, double *speed_factor, char **speed_unit, int flag) { - double cd_factor = 75.0 * 2352; - double cd_speed_tolerance= 1.5, cd_speed_add; - int int_cd_speed, i; - static int cd_speed_list[]= {8, 10, 12, 16, 24, 32, 40, 48, 52, 0}; + int i, no_dvd_read= 1, no_dvd_write= 1, no_bd_read= 1, no_bd_write= 1, ret; + int num_profiles, profiles[64]; + char is_current[64]; *speed_unit= "D"; *speed_factor= 1385000.0; - /* Does this look like an integer CD speed ? */ - int_cd_speed= ((double) speed) * 1000.0 / cd_factor; - cd_speed_add= cd_speed_tolerance * (double) int_cd_speed; - int_cd_speed= (((double) speed) + cd_speed_add) - * 1000.0 / cd_factor; - if(abs((int) ((double) int_cd_speed) * cd_factor / 1000.0 - - ((double) speed)) > 2 * cd_speed_add || - int_cd_speed > 64) - int_cd_speed= 0; - if(int_cd_speed > 7) { - for(i= 0; cd_speed_list[i]; i++) - if(int_cd_speed == cd_speed_list[i]) - break; - if(cd_speed_list[i] == 0) - int_cd_speed= 0; + if((flag & 1) || profile == 0x00) { + ret= burn_drive_get_all_profiles(drive, &num_profiles, + profiles, is_current); + if(ret > 0) { + for(i= 0; i < num_profiles; i++) { + if(profiles[i] > 0x10 && profiles[i] < 0x30) + no_dvd_read= no_dvd_write= 0; + else if(profiles[i] == 0x10) + no_dvd_read= 0; + else if(profiles[i] > 0x40 && profiles[i] <= 0x43) + no_bd_read= no_bd_write= 0; + else if(profiles[i] == 0x40) + no_bd_read= 0; + } + } } - - if(((profile < 0x08 || profile >= 0x100 || profile == 0x10 || profile == 0x40) - && int_cd_speed) || - (profile >= 0x08 && profile <= 0x0a)) { + if(profile == 0x00) { /* No medium loaded, guess from profile list */ + if(flag & 1) { + if(no_bd_write && no_dvd_write) + *speed_unit= "C"; + else if(!no_bd_write) + *speed_unit= "B"; + } else { + if(no_bd_read && no_dvd_read) + *speed_unit= "C"; + else if(!no_bd_read) + *speed_unit= "B"; + } + } else if((profile > 0x00 && profile <= 0x0a) || + (((no_dvd_write || no_bd_write) && (flag & 1)))) { *speed_unit= "C"; - *speed_factor= cd_factor; - } else if(profile >= 0x40 && profile <= 0x43) { + } else if((profile >= 0x40 && profile <= 0x43) && + !(no_bd_write && (flag & 1))) { *speed_unit= "B"; - *speed_factor= 4495625.0; } + if((*speed_unit)[0] == 'C') + *speed_factor= 75.0 * 2352.0; + else if((*speed_unit)[0] == 'B') + *speed_factor= 4495625.0; return(1); } +/* For sorting the int *speeds array +*/ +int Xorriso__reverse_int_cmp(const void *a, const void *b) +{ + int diff; + + diff= *((int *) a) - *((int *) b); + if(diff < 0) + return(1); + else if(diff > 0) + return(-1); + return(0); +} + + /* @flag bit0= do not issue TOC bit1= Report about outdev (else indev) bit2= Report about write speed (else read speed) @@ -1600,8 +1631,9 @@ int Xorriso_choose_speed_factor(struct XorrisO *xorriso, */ int Xorriso_list_speeds_sub(struct XorrisO *xorriso, int flag) { - int ret, high= -1, low= 0x7fffffff, is_cd= 0, i, speed; - int recent_profile= 0, inout_flag, prev_speed= -1; + int ret, high= -1, low= 0x7fffffff, is_cd= 0, i, speed, profile= 0; + int inout_flag, prev_speed= -1, speed_count= 0; + int *speeds= NULL; char *respt, *speed_unit= "D"; double speed_factor= 1385000.0, cd_factor= 75.0 * 2352; struct burn_drive_info *dinfo; @@ -1638,21 +1670,24 @@ int Xorriso_list_speeds_sub(struct XorrisO *xorriso, int flag) } } - for (item= speed_list; item != NULL; item= item->next) { + speed_count= 0; + for(item= speed_list; item != NULL; item= item->next) + speed_count++; + if(speed_count > 0) + Xorriso_alloc_meM(speeds, int, speed_count); + + speed_count= 0; + for(item= speed_list; item != NULL; item= item->next) { sprintf(xorriso->info_text, "read_speed= %5dk , write_speed= %5dk , source= %d", item->read_speed, item->write_speed, item->source); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - if(item->profile_loaded >= 0x08 && item->profile_loaded <= 0x0a) - is_cd= item->profile_loaded; - if(item->profile_loaded > 0) - recent_profile= item->profile_loaded; if(item->source == 1) { /* CD mode page 2Ah : report only if not same speed by GET PERFORMANCE */ if(!(flag & 4)) - continue; /* 2Ah only tells write speed */ + continue; /* 2Ah only tells write speed */ for(other= speed_list; other != NULL; other= other->next) if(other->source == 2 && item->write_speed == other->write_speed) break; @@ -1660,18 +1695,38 @@ int Xorriso_list_speeds_sub(struct XorrisO *xorriso, int flag) continue; } if(flag & 4) { - sprintf(respt, "Write speed : "); + if(item->write_speed <= 0) + continue; speed= item->write_speed; } else { - sprintf(respt, "Read speed : "); + if(item->read_speed <= 0) + continue; speed= item->read_speed; } + speeds[speed_count]= speed; + if(item->profile_loaded > 0) + profile= item->profile_loaded; + speed_count++; + } + + if(speed_count > 0) + qsort(speeds, (size_t) speed_count, sizeof(int), Xorriso__reverse_int_cmp); + + if(profile >= 0x08 && profile <= 0x0a) + is_cd= profile; + for(i= 0; i < speed_count; i++) { + + speed= speeds[i]; if(speed == prev_speed) continue; prev_speed= speed; - Xorriso_choose_speed_factor(xorriso, speed, - item->profile_loaded, - &speed_factor, &speed_unit, 0); + if(flag & 4) + sprintf(respt, "Write speed : "); + else + sprintf(respt, "Read speed : "); + + Xorriso_choose_speed_factor(xorriso, speed, profile, drive, + &speed_factor, &speed_unit, !!(flag & 4)); sprintf(respt + strlen(respt), " %5dk , %4.1fx%s\n", speed, ((double) speed) * 1000.0 / speed_factor, speed_unit); Xorriso_result(xorriso,0); @@ -1712,8 +1767,8 @@ int Xorriso_list_speeds_sub(struct XorrisO *xorriso, int flag) } } if(high > -1) { - Xorriso_choose_speed_factor(xorriso, low, recent_profile, - &speed_factor, &speed_unit, 0); + Xorriso_choose_speed_factor(xorriso, low, profile, drive, + &speed_factor, &speed_unit, !!(flag & 4)); if(flag & 4) sprintf(respt, "Write speed L: "); else @@ -1721,8 +1776,8 @@ int Xorriso_list_speeds_sub(struct XorrisO *xorriso, int flag) sprintf(respt + strlen(respt), " %5dk , %4.1fx%s\n", low, ((double) low) * 1000.0 / speed_factor, speed_unit); Xorriso_result(xorriso,0); - Xorriso_choose_speed_factor(xorriso, low, recent_profile, - &speed_factor, &speed_unit, 0); + Xorriso_choose_speed_factor(xorriso, low, profile, drive, + &speed_factor, &speed_unit, !!(flag & 4)); if(flag & 4) sprintf(respt, "Write speed H: "); else @@ -1749,6 +1804,7 @@ int Xorriso_list_speeds_sub(struct XorrisO *xorriso, int flag) ex:; if(speed_list != NULL) burn_drive_free_speedlist(&speed_list); + Xorriso_free_meM(speeds); return(ret); } diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 899031f9..2c01a254 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2014.01.09.154437" +#define Xorriso_timestamP "2014.01.09.215206"