From 4903bb997130f0bb6126d729564c0a73fbc3a73d Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 13 Feb 2007 14:37:25 +0000 Subject: [PATCH] Mew API function burn_disc_available_space() --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 19 ++++++- libburn/libburn.h | 18 ++++++- libburn/mmc.c | 102 +++++++++++++++++------------------- libburn/spc.c | 22 ++++++-- libburn/transport.h | 6 +++ 6 files changed, 107 insertions(+), 62 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index f7f1eec..ff4e916 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.02.13.115459" +#define Cdrskin_timestamP "2007.02.13.143718" diff --git a/libburn/drive.c b/libburn/drive.c index 3afca92..d3f1761 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -1402,7 +1402,7 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, 0, 0); return -1; } - if (o!=NULL) + if (o != NULL) d->send_write_parameters(d, o); ret = d->get_nwa(d, trackno, lba, nwa); return ret; @@ -1435,6 +1435,23 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start) } +/* ts A70213 : new API function */ +off_t burn_disc_available_space(struct burn_drive *d, + struct burn_write_opts *o) +{ + int lba, nwa; + + if (burn_drive_is_released(d)) + return d->media_capacity_remaining; + if (d->busy != BURN_DRIVE_IDLE) + return d->media_capacity_remaining; + if (o != NULL) + d->send_write_parameters(d, o); + d->get_nwa(d, -1, &lba, &nwa); + return d->media_capacity_remaining; +} + + /* ts A61202 : New API function */ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]) { diff --git a/libburn/libburn.h b/libburn/libburn.h index bd2e7a1..5a181b6 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -838,11 +838,27 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, */ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba); + +/* ts A70213 */ +/** Return the best possible estimation of the currently available capacity of + the media. This might depend on particular write option settings. For + inquiring the space with such a set of options, the drive has to be + grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value + from the most recent automatic inquiry (e.g. during last drive grabbing). + @param d The drive to query. + @param o If not NULL: write parameters to be set on drive before query + @return number of most probably available free bytes +*/ +off_t burn_disc_available_space(struct burn_drive *d, + struct burn_write_opts *o); + + /* ts A61202 */ /** Tells the MMC Profile identifier of the loaded media. The drive must be grabbed in order to get a non-zero result. libburn currently writes only to profiles 0x09 "CD-R", 0x0a "CD-RW", - 0x12 "DVD-RAM", 0x13 "DVD-RW restricted overwrite" or 0x1a "DVD+RW". + 0x11 "DVD-R", 0x12 "DVD-RAM", 0x13 "DVD-RW restricted overwrite", + 0x14 "DVD-RW Sequential Recording" or 0x1a "DVD+RW". @param d The drive where the media is inserted. @param pno Profile Number as of mmc5r03c.pdf, table 89 @param name Profile Name (e.g "CD-RW", unknown profiles have empty name) diff --git a/libburn/mmc.c b/libburn/mmc.c index 8205605..cd1726e 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -251,8 +251,10 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf) d->current_profile == 0x12 ) /* DVD+RW , DVD-RW restricted overwrite , DVD-RAM */ trackno = 1; - else if (d->current_profile == 0x11 || - d->current_profile == 0x14) /* DVD-R[W] Sequential */ + else if (d->current_profile == 0x10 || + d->current_profile == 0x11 || + d->current_profile == 0x14) + /* DVD-ROM , DVD-R[W] Sequential */ trackno = d->last_track_no; else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */ trackno = 0xFF; @@ -275,13 +277,7 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf) int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) { struct buffer buf; - int ret; - -#ifdef Libburn_get_nwa_standalonE - struct command c; - int i; -#endif - + int ret, num; unsigned char *data; mmc_function_spy("mmc_get_nwa"); @@ -290,43 +286,27 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) d->current_profile == 0x12 ) /* DVD+RW , DVD-RW restricted overwrite , DVD-RAM */ trackno = 1; - else if (d->current_profile == 0x11 || - d->current_profile == 0x14) /* DVD-R[W] Sequential */ + else if (d->current_profile == 0x10 || + d->current_profile == 0x11 || + d->current_profile == 0x14) + /* DVD-ROM, DVD-R[W] Sequential */ trackno = d->last_track_no; else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */ trackno = 0xFF; } -#ifdef Libburn_get_nwa_standalonE - - c.retry = 1; - c.oplen = sizeof(MMC_TRACK_INFO); - memcpy(c.opcode, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO)); - c.opcode[1] = 1; - for (i = 0; i < 4; i++) - c.opcode[2 + i] = (trackno >> (24 - 8 * i)) & 0xff; - c.page = &buf; - c.dir = FROM_DRIVE; - d->issue_command(d, &c); - data = c.page->data; - -#else /* Libburn_get_nwa_standalonE */ - ret = mmc_read_track_info(d, trackno, &buf); if (ret <= 0) return ret; data = buf.data; -#endif /* ! Libburn_get_nwa_standalonE */ - - - *lba = (data[8] << 24) + (data[9] << 16) - + (data[10] << 8) + data[11]; - *nwa = (data[12] << 24) + (data[13] << 16) - + (data[14] << 8) + data[15]; - if (d->current_profile == 0x1a || d->current_profile == 0x13) { - /* DVD+RW or DVD-RW restricted overwrite */ - *lba = *nwa = 0; + *lba = mmc_four_char_to_int(data + 8); + *nwa = mmc_four_char_to_int(data + 12); + num = mmc_four_char_to_int(data + 16); + if (d->current_profile == 0x1a || d->current_profile == 0x13 || + d->current_profile == 0x12) { + /* overwriteable */ + *lba = *nwa = num = 0; } else if (!(data[7]&1)) { /* ts A61106 : MMC-1 Table 142 : NWA_V = NWA Valid Flag */ libdax_msgs_submit(libdax_messenger, -1, 0x00000002, @@ -334,6 +314,8 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) "mmc_get_nwa: Track Info Block: NWA_V == 0", 0, 0); return 0; } + if (num > 0) + d->media_capacity_remaining = ((off_t) num) * ((off_t) 2048); return 1; } @@ -546,8 +528,7 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number, entry->tno = 0; entry->point = track_number & 0xff; entry->point_msb = (track_number >> 8) & 0xff; - num = (size_data[0] << 24) | (size_data[1] << 16) | - (size_data[2] << 8) | size_data[3]; + num = mmc_four_char_to_int(size_data); entry->track_blocks = num; burn_lba_to_msf(num, &min, &sec, &frames); if (min > 255) { @@ -559,8 +540,7 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number, entry->sec = sec; entry->frame = frames; entry->zero = 0; - num = (start_data[0] << 24) | (start_data[1] << 16) | - (start_data[2] << 8) | start_data[3]; + num = mmc_four_char_to_int(start_data); entry->start_lba = num; burn_lba_to_msf(num, &min, &sec, &frames); if (min > 255) { @@ -644,8 +624,15 @@ int mmc_fake_toc(struct burn_drive *d) entry; } - if (session_number > d->disc->sessions) + if (session_number > d->disc->sessions) { + if (i == d->last_track_no - 1) { + /* ts A70212 : Last track field Free Blocks */ + d->media_capacity_remaining = + ((off_t) mmc_four_char_to_int(tdata + 16)) * + ((off_t) 2048); + } continue; + } entry = &(d->toc_entry[i + session_number - 1]); track = burn_track_create(); @@ -924,6 +911,9 @@ void mmc_read_disc_info(struct burn_drive *d) d->erasable = 0; d->last_track_no = 1; + /* ts A70212 */ + d->media_capacity_remaining = 0; + /* ts A61202 */ d->toc_entries = 0; if (d->status == BURN_DISC_EMPTY) @@ -1006,6 +996,15 @@ void mmc_read_disc_info(struct burn_drive *d) */ d->bg_format_status = data[7] & 3; + /* Preliminarily declare blank: + ts A61219 : DVD+RW (is not bg_format_status==0 "blank") + ts A61229 : same for DVD-RW Restricted overwrite + ts A70112 : same for DVD-RAM + */ + if (d->current_profile == 0x1a || d->current_profile == 0x13 || + d->current_profile == 0x12) + d->status = BURN_DISC_BLANK; + if (d->status == BURN_DISC_BLANK) { d->last_track_no = 1; /* The "incomplete track" */ d->complete_sessions = 0; @@ -1023,15 +1022,6 @@ void mmc_read_disc_info(struct burn_drive *d) d->last_track_no = (data[11] << 8) | data[6]; } - /* Preliminarily declare blank: - ts A61219 : DVD+RW (is not bg_format_status==0 "blank") - ts A61229 : same for DVD-RW Restricted overwrite - ts A70112 : same for DVD-RAM - */ - if (d->current_profile == 0x1a || d->current_profile == 0x13 || - d->current_profile == 0x12) - d->status = BURN_DISC_BLANK; - if (do_read_toc) mmc_read_toc(d); } @@ -1503,10 +1493,7 @@ void mmc_get_configuration(struct burn_drive *d) if (c.error) return; - len = (c.page->data[0] << 24) - | (c.page->data[1] << 16) - | (c.page->data[2] << 8) - | c.page->data[3]; + len = mmc_four_char_to_int(c.page->data); if (len<8) return; @@ -1743,14 +1730,20 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted) /* Criterion is proximity to quick intermediate state */ if (type == 0x00) { /* full format (with lead out) */ score = 1 * sign; + if(d->current_profile == 0x12 && + d->media_capacity_remaining == 0) + d->media_capacity_remaining = size; } else if (type == 0x10) { /* DVD-RW full format */ score = 10 * sign; } else if(type == 0x13) { /* DVD-RW quick grow last session */ score = 100 * sign; } else if(type == 0x15) { /* DVD-RW Quick */ score = 50 * sign; + if(d->current_profile == 0x13) + d->media_capacity_remaining = size; } else if(type == 0x26) { /* DVD+RW */ score = 1 * sign; + d->media_capacity_remaining = size; } else { continue; } @@ -2226,6 +2219,7 @@ int mmc_setup_drive(struct burn_drive *d) d->num_format_descr = 0; d->complete_sessions = 0; d->last_track_no = 1; + d->media_capacity_remaining = 0; return 1; } diff --git a/libburn/spc.c b/libburn/spc.c index a63cafb..7131633 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -318,7 +318,7 @@ void spc_sense_write_params(struct burn_drive *d) { struct buffer buf; struct scsi_mode_data *m; - int size; + int size, dummy; unsigned char *page; struct command c; @@ -343,6 +343,22 @@ void spc_sense_write_params(struct burn_drive *d) m->write_page_length = page[1]; m->write_page_valid = 1; mmc_read_disc_info(d); + + /* ts A70212 : try to setup d->media_capacity_remaining */ + if (d->current_profile == 0x1a || d->current_profile == 0x13 || + d->current_profile == 0x12) + d->read_format_capacities(d, -1); + else if (d->status == BURN_DISC_BLANK || + (d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) { + d->get_nwa(d, -1, &dummy, &dummy); + } + /* others are hopefully up to date from mmc_read_disc_info() */ + +/* + fprintf(stderr, "LIBBURN_DEBUG: media_capacity_remaining = %.f\n", + (double) d->media_capacity_remaining); +*/ + } @@ -434,10 +450,6 @@ void spc_getcaps(struct burn_drive *d) spc_inquiry(d); spc_sense_caps(d); spc_sense_error_params(d); - - /* <<< for debugging. >>> ??? to be fixely included here ? - mmc_read_format_capacities(d, -1); - */ } /* diff --git a/libburn/transport.h b/libburn/transport.h index 80bc4e2..ac64131 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -206,6 +206,12 @@ struct burn_drive /* ts A70129 : from 51h READ DISC INFORMATION Last Track Number in Last Session */ int last_track_no; + /* ts A70212 : from various sources : free space on media (in bytes) + With CD this might change after particular write + parameters have been set and nwa has been inquired. + (e.g. by d->send_write_parameters() ; d->get_nwa()). + */ + off_t media_capacity_remaining; int toc_temp;