diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index a8e1352..57d9fae 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.02.06.185534" +#define Cdrskin_timestamP "2007.02.07.162836" diff --git a/libburn/drive.c b/libburn/drive.c index e776886..3afca92 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -1584,6 +1584,8 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, o->might_do_tao = o->might_do_sao = o->might_do_raw = 0; o->advised_write_mode = BURN_WRITE_NONE; o->selected_write_mode = wt; + o->current_profile = d->current_profile; + o->current_is_cd_profile = d->current_is_cd_profile; if (s != BURN_DISC_BLANK && s != BURN_DISC_APPENDABLE) { return 0; @@ -1662,6 +1664,13 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, if (s == BURN_DISC_APPENDABLE) o->might_do_sao = o->might_do_raw = 0; + + if (wt == BURN_WRITE_TAO && !o->might_do_tao) + return 0; + else if (wt == BURN_WRITE_SAO && !o->might_do_sao) + return 0; + else if (wt == BURN_WRITE_RAW && !o->might_do_raw) + return 0; return 1; } @@ -1676,3 +1685,36 @@ int burn_disc_free_multi_caps(struct burn_multi_caps **caps) return 1; } + +/* ts A70207 : evaluate write mode related peculiarities of a disc */ +int burn_disc_get_write_mode_demands(struct burn_disc *disc, + struct burn_disc_mode_demands *result, int flag) +{ + struct burn_session *session; + struct burn_track *track; + int i, j, mode; + + memset((char *) result, 0, sizeof(struct burn_disc_mode_demands)); + if (disc->sessions > 1) + result->multi_session = 1; + for (i = 0; i < disc->sessions; i++) { + session = disc->session[i]; + if (session->tracks <= 0) + continue; + mode = session->track[0]->mode; + if (session->tracks > 1) + result->multi_track = 1; + for (j = 0; j < session->tracks; j++) { + track = session->track[j]; + if (burn_track_is_open_ended(track)) + result->unknown_track_size = 1; + if (mode != track->mode) + result->mixed_mode = 1; + if (track->mode != BURN_MODE1) + result->exotic_track = 1; + if (track->mode == BURN_AUDIO) + result->audio = 1; + } + } + return (disc->sessions > 0); +} diff --git a/libburn/drive.h b/libburn/drive.h index dca49d4..e658b51 100644 --- a/libburn/drive.h +++ b/libburn/drive.h @@ -95,4 +95,17 @@ int burn_mdata_free_subs(struct scsi_mode_data *m); /* ts A61230 */ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag); + +/* ts A70207 : evaluate write mode related peculiarities of a disc */ +struct burn_disc_mode_demands { + int multi_session; + int multi_track; + int unknown_track_size; + int mixed_mode; + int audio; + int exotic_track; +}; +int burn_disc_get_write_mode_demands(struct burn_disc *disc, + struct burn_disc_mode_demands *result, int flag); + #endif /* __DRIVE */ diff --git a/libburn/libburn.h b/libburn/libburn.h index fdeef0e..bd2e7a1 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -1215,6 +1215,22 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts, enum burn_write_types write_type, int block_type); +/* ts A70207 */ +/** As an alternative to burn_write_opts_set_write_type() this function tries + to find a suitable write type and block type for a given write job + described by opts and disc. To be used after all other setups have been + made, i.e. immediately before burn_disc_write(). + @param opts The nearly complete write opts to change + @param disc The already composed session and track model + @param reasons This text string collects reasons for decision resp. failure + @param flag Bitfield for control purposes (unused yet, submit 0) + @return Chosen write type. BURN_WRITE_NONE on failure. +*/ +enum burn_write_types burn_write_opts_auto_write_type( + struct burn_write_opts *opts, struct burn_disc *disc, + char reasons[1024], int flag); + + /** Supplies toc entries for writing - not normally required for cd mastering @param opts The write opts to change @param count The number of entries @@ -1385,7 +1401,8 @@ int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list); /* ts A70203 */ -/** The reply structure for burn_disc_get_multi_caps() */ +/** The reply structure for burn_disc_get_multi_caps() +*/ struct burn_multi_caps { /* Multi-session capability allows to keep the media appendable after @@ -1442,14 +1459,20 @@ struct burn_multi_caps { int might_do_tao; int might_do_sao; int might_do_raw; - - /* Advised write mode. + + /** Advised write mode. */ enum burn_write_types advised_write_mode; - /* Write mode as given by parameter wt of burn_disc_get_multi_caps(). + /** Write mode as given by parameter wt of burn_disc_get_multi_caps(). */ enum burn_write_types selected_write_mode; + + /** Profile number which was current when the reply was generated */ + int current_profile; + + /** Wether the current profile indicates CD media. 1=yes, 0=no */ + int current_is_cd_profile; }; /** Allocates a struct burn_multi_caps (see above) and fills it with values @@ -1459,7 +1482,8 @@ struct burn_multi_caps { @param d The drive to inquire @param wt With BURN_WRITE_NONE the best capabilities of all write modes get returned. If set to a write mode like BURN_WRITE_SAO the - capabilities with that particular mode are returned. + capabilities with that particular mode are returned and the + return value is 0 if the desired mode is not possible. @param caps returns the info structure @param flag Bitfield for control purposes (unused yet, submit 0) @return < 0 : error , 0 : writing seems impossible , 1 : writing possible diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 72d3a3f..77c6aed 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -348,6 +348,9 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020127 (NOTE,HIGH) = Write start address is ... 0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance 0x00020129 (SORRY,HIGH) = Will not format media type + 0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities + 0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job + 0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking 0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive 0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn diff --git a/libburn/options.c b/libburn/options.c index 59c926c..42e3a09 100644 --- a/libburn/options.c +++ b/libburn/options.c @@ -1,5 +1,6 @@ #include "libburn.h" #include "options.h" +#include "drive.h" #include "transport.h" /* ts A61007 */ @@ -170,6 +171,96 @@ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value) } +/* ts A70207 API */ +enum burn_write_types burn_write_opts_auto_write_type( + struct burn_write_opts *opts, struct burn_disc *disc, + char reasons[1024], int flag) +{ + struct burn_multi_caps *caps = NULL; + struct burn_drive *d = opts->drive; + struct burn_disc_mode_demands demands; + int ret; + char *reason_pt; + + reasons[0] = 0; + ret = burn_disc_get_write_mode_demands(disc, &demands, 0); + if (ret <= 0) { + strcat(reasons, "cannot recognize job demands, "); + return BURN_WRITE_NONE; + } + if (demands.exotic_track && !d->current_is_cd_profile) { + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x00020123, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "DVD Media are unsuitable for desired track type", + 0, 0); + if (demands.audio) + strcat(reasons, "audio track prohibited by non-CD, "); + else + strcat(reasons, "exotic track prohibited by non-CD, "); + return BURN_WRITE_NONE; + } + + ret = burn_disc_get_multi_caps(d, BURN_WRITE_SAO, &caps, 0); + if (ret < 0) { +no_caps:; + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x0002012a, + LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, + "Cannot inquire write mode capabilities", + 0, 0); + strcat(reasons, "cannot inquire write mode capabilities, "); + return BURN_WRITE_NONE; + } if (ret > 0) { + reason_pt = reasons + strlen(reasons); + strcat(reasons, "SAO: "); + if ((opts->multi || demands.multi_session) && + !caps->multi_session) + strcat(reasons, "multi session capability lacking, "); + if (demands.multi_track && !caps->multi_track) + strcat(reasons, "multi track capability lacking, "); + if (demands.unknown_track_size) + strcat(reasons, "track size unpredictable, "); + if (demands.mixed_mode) + strcat(reasons, "tracks of different modes mixed, "); + if (strcmp(reason_pt, "SAO: ") != 0) + goto no_sao; + burn_write_opts_set_write_type(opts, + BURN_WRITE_SAO, BURN_BLOCK_SAO); + return BURN_WRITE_SAO; + } else + strcat(reasons, "SAO: no SAO offered by drive and media, "); +no_sao:; + burn_disc_free_multi_caps(&caps); + strcat(reasons, "\n"); + reason_pt = reasons + strlen(reasons); + strcat(reasons, "TAO: "); + ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0); + if (ret < 0) + goto no_caps; + if (ret == 0) { + strcat(reasons, "no TAO offered by drive and media, "); +no_write_mode:; + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x0002012b, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "Drive offers no suitable write mode with this job", + 0, 0); + return BURN_WRITE_NONE; + } + if ((opts->multi || demands.multi_session) && !caps->multi_session) + strcat(reasons, "multi session capability lacking, "); + if (demands.multi_track && !caps->multi_track) + strcat(reasons, "multi track capability lacking, "); + if (strcmp(reason_pt, "TAO: ") != 0) + goto no_write_mode; + /* ( TAO data/audio block size will be handled automatically ) */ + burn_write_opts_set_write_type(opts, + BURN_WRITE_TAO, BURN_BLOCK_MODE1); + return BURN_WRITE_TAO; +} + + void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw) { opts->raw = raw;