Commit b6475c3d authored by Thomas Schmitt's avatar Thomas Schmitt

Re-arranged checking and defaulting of write parameters

parent afd54a1f
#define Cdrskin_timestamP "2007.02.19.184132"
#define Cdrskin_timestamP "2007.02.19.225102"
......@@ -12,6 +12,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
#include <a ssert.h>
......@@ -332,7 +333,11 @@ static void *write_disc_worker_func(struct w_list *w)
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{
struct write_opts o;
char reasons[1024+80];
#ifndef Libburn_precheck_write_ruleS
int i, j, mode, mixed_mode = 0;
#endif
/* For the next lines any return indicates failure */
opts->drive->cancel = 1;
......@@ -360,10 +365,37 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
"Drive capabilities not inquired yet", 0, 0);
return;
}
/* ts A70219 : intended to replace all further tests here and many
tests in burn_*_write_sync()
*/
strcpy(reasons, "Write job parameters seem unsuitable:\n");
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 0)
== BURN_WRITE_NONE) {
#ifndef Libburn_precheck_write_ruleS
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
#else
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
return;
#endif /* Libburn_precheck_write_ruleS */
}
#ifndef Libburn_precheck_write_ruleS
/* <<< covered burn_precheck_write() */
/* ts A61009 : obsolete Assert in sector_headers() */
if (! burn_disc_write_is_ok(opts, disc)) /* issues own msgs */
if (! burn_disc_write_is_ok(opts, disc, 0)) /* issues own msgs */
return;
/* <<< covered burn_precheck_write() */
/* ts A70122 : libburn SAO code mishandles mode changes */
for (i = 0; i < disc->sessions; i++) {
if (disc->session[i]->tracks <= 0)
......@@ -380,6 +412,7 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
"Cannot mix data and audio in SAO mode", 0, 0);
return;
}
#endif /* ! Libburn_precheck_write_ruleS */
opts->drive->cancel = 0; /* End of the return = failure area */
......
......@@ -29,6 +29,9 @@
/* ts A70107 : to get BE_CANCELLED */
#include "error.h"
/* ts A70219 : for burn_disc_get_write_mode_demands() */
#include "options.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
......@@ -1707,15 +1710,21 @@ int burn_disc_free_multi_caps(struct burn_multi_caps **caps)
@param flag bit0= fill_up_media is active
*/
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag)
{
struct burn_session *session;
struct burn_track *track;
int i, j, mode, unknown_track_sizes = 0, last_track_is_unknown = 0;
enum burn_disc_status s;
memset((char *) result, 0, sizeof(struct burn_disc_mode_demands));
if (disc == NULL)
return 2;
s = burn_disc_get_status(opts->drive);
if (s == BURN_DISC_APPENDABLE || disc->sessions > 1)
result->will_append = 1;
if (disc->sessions > 1)
result->multi_session = 1;
for (i = 0; i < disc->sessions; i++) {
......@@ -1728,17 +1737,27 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
for (j = 0; j < session->tracks; j++) {
track = session->track[j];
if (burn_track_is_open_ended(track)) {
result->unknown_track_size = 1;
if (burn_track_get_default_size(track) > 0) {
if (result->unknown_track_size == 0)
result->unknown_track_size = 2;
} else
result->unknown_track_size = 1;
unknown_track_sizes++;
last_track_is_unknown = 1;
} else
last_track_is_unknown = 0;
if (mode != track->mode)
result->mixed_mode = 1;
if (track->mode != BURN_MODE1)
result->exotic_track = 1;
if (track->mode == BURN_AUDIO)
if (track->mode == BURN_MODE1) {
result->block_types |= BURN_BLOCK_MODE1;
} else if (track->mode == BURN_AUDIO) {
result->audio = 1;
result->block_types |= BURN_BLOCK_RAW0;
result->exotic_track = 1;
} else {
result->block_types |= opts->block_type;
result->exotic_track = 1;
}
}
}
if (flag&1) {/* fill_up_media will define the size of the last track */
......
......@@ -100,12 +100,15 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag);
struct burn_disc_mode_demands {
int multi_session;
int multi_track;
int unknown_track_size;
int unknown_track_size; /* 0=known, 1=unknown, 2=unknown+defaulted */
int mixed_mode;
int audio;
int exotic_track;
int block_types;
int will_append; /* because of media state or multi session disc */
};
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_disc_mode_demands *result, int flag);
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag);
#endif /* __DRIVE */
......@@ -997,6 +997,23 @@ int burn_disc_get_format_descr(struct burn_drive *drive, int index,
*/
void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
/* ts A70219 */
/** Examines a completed setup for burn_disc_write() wether it is permissible
with drive and media. This function is called by burn_disc_write() but
an application might be interested in this check in advance.
@param o The options for the writing operation.
@param disc The descrition of the disc to be created
@param reasons Eventually returns a list of rejection reason statements
@param silent 1= do not issue error messages , 0= report severe problems
*/
int burn_precheck_write( struct burn_write_opts *o, struct burn_disc *disc,
char reasons[1024], int silent);
/* <<< enabling switch for internal usage and trust in this functiion */
#define Libburn_precheck_write_ruleS 1
/** Write a disc in the drive. The drive must be grabbed successfully before
calling this function. Always ensure that the drive reports a status of
BURN_DISC_BLANK before calling this function.
......@@ -1177,6 +1194,20 @@ struct burn_disc *burn_drive_get_disc(struct burn_drive *d);
enum burn_source_status burn_track_set_source(struct burn_track *t,
struct burn_source *s);
/* ts A70218 */
/** Set a default track size to be used only if the track turns out to be of
unpredictable length and if the effective write type demands a fixed size.
This can be useful to enable write types CD SAO or DVD DAO together with
a track source like stdin. If the track source delivers fewer bytes than
announced then the track will be padded up with zeros.
@param t The track to change
@param size The size to set
@return 0=failure 1=sucess
*/
int burn_track_set_default_size(struct burn_track *t, off_t size);
/** Free a burn_source (decrease its refcount and maybe free it)
@param s Source to free
*/
......@@ -1196,6 +1227,7 @@ struct burn_source *burn_file_source_new(const char *path,
*/
struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
/** Tells how long a track will be on disc
>>> NOTE: Not reliable with tracks of undefined length
*/
......@@ -1241,7 +1273,9 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts,
@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)
@param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
@return Chosen write type. BURN_WRITE_NONE on failure.
*/
enum burn_write_types burn_write_opts_auto_write_type(
......@@ -1446,7 +1480,7 @@ struct burn_multi_caps {
of multi-session by keeping a disc appendable. But .might_do_sao
will be 0 afterwards, when checking the appendable media.)
1= media may be kept appendable by burn_write_opts_set_multi(o,1)
0= media will not be apendable appendable
0= media will not be appendable
*/
int multi_session;
......
......@@ -352,16 +352,19 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job
0x0002012c (SORRY,HIGH) = Too many logical tracks recorded
0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses
0x0002012e (NOTE,HIGH) = Activated track default size
0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session
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
0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode
0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO
0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO
0x00020136 (SORRY,HIGH) = DAO Burning restricted to single fixed size track
0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track
0x00020137 (HINT,HIGH) = TAO would be possible
0x00020138 (FATAL,HIGH) = Cannot reserve track
0x00020139 (WARN,HIGH) = Unsuitable write type and/or block types detected
to become ^ SORRY ^ soon
libdax_audioxtr:
......
......@@ -173,9 +173,6 @@ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
/* ts A70207 API */
/* @param flag Bitfield for control purposes
bit0=do not look for suitable type but check preset type in opts
*/
enum burn_write_types burn_write_opts_auto_write_type(
struct burn_write_opts *opts, struct burn_disc *disc,
char reasons[1024], int flag)
......@@ -183,41 +180,45 @@ enum burn_write_types burn_write_opts_auto_write_type(
struct burn_multi_caps *caps = NULL;
struct burn_drive *d = opts->drive;
struct burn_disc_mode_demands demands;
int ret;
enum burn_write_types wt;
int ret, would_do_sao = 0;
char *reason_pt;
reasons[0] = 0;
ret = burn_disc_get_write_mode_demands(disc, &demands,
ret = burn_disc_get_write_mode_demands(disc, opts, &demands,
!!opts->fill_up_media);
if (ret <= 0) {
strcat(reasons, "cannot recognize job demands, ");
return BURN_WRITE_NONE;
{wt = BURN_WRITE_NONE; goto ex;}
}
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 (!(flag & 2))
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;
{wt = BURN_WRITE_NONE; goto ex;}
}
if ((flag & 1) && opts->write_type != BURN_WRITE_SAO)
goto try_tao;
burn_disc_free_multi_caps(&caps);
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,
if (!(flag & 2))
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;
{wt = BURN_WRITE_NONE; goto ex;}
} else if (ret == 0) {
strcat(reasons, "SAO: no SAO offered by drive and media, ");
goto no_sao;
......@@ -227,26 +228,42 @@ no_caps:;
if ((opts->multi || demands.multi_session) &&
!caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.will_append)
strcat(reasons, "appended session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.unknown_track_size)
if (demands.unknown_track_size == 1)
strcat(reasons, "track size unpredictable, ");
if (demands.mixed_mode)
strcat(reasons, "tracks of different modes mixed, ");
if (demands.exotic_track)
strcat(reasons, "non-audio, non-data track, ");
else if (d->current_is_cd_profile)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (d->current_is_cd_profile && opts->fill_up_media)
strcat(reasons, "cd sao cannot do media fill up yet, ");
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;
would_do_sao = 1;
if (demands.unknown_track_size == 2 && !(flag & 1)) {
strcat(reasons, "would have to use default track sizes, ");
goto no_sao;
}
do_sao:;
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_SAO, BURN_BLOCK_SAO);
{wt = BURN_WRITE_SAO; goto ex;}
no_sao:;
burn_disc_free_multi_caps(&caps);
strcat(reasons, "\n");
try_tao:;
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
goto no_tao;
goto try_raw;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "TAO: ");
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0);
if (ret < 0)
goto no_caps;
......@@ -258,31 +275,57 @@ try_tao:;
strcat(reasons, "multi session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (d->current_is_cd_profile) {
/* >>> check block types */;
}
if (demands.exotic_track)
strcat(reasons, "non-audio, non-data track, ");
if (d->current_is_cd_profile)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "TAO: ") != 0)
goto no_tao;
/* ( 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;
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1);
{wt = BURN_WRITE_TAO; goto ex;}
no_tao:;
if (would_do_sao && !(flag &1))
goto do_sao;
if (!d->current_is_cd_profile)
goto no_write_mode;
strcat(reasons, "\n");
try_raw:;
if ((flag & 1) && opts->write_type != BURN_WRITE_RAW)
goto no_write_mode;
/* >>> evaluate RAW modes */;
if (!(flag & 1)) /* For now: no automatic raw write modes */
goto no_write_mode;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "RAW: ");
if (!d->current_is_cd_profile)
strcat(reasons, "prohibited by non-CD, ");
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "RAW: ") != 0)
goto no_write_mode;
/* For now: no setting of raw write modes */
{wt = BURN_WRITE_RAW; goto ex;}
no_write_mode:;
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012b,
if (!(flag & (1 | 2)))
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;
wt = BURN_WRITE_NONE;
ex:;
burn_disc_free_multi_caps(&caps);
return wt;
}
......
......@@ -116,6 +116,8 @@ struct burn_track *burn_track_create(void)
/* ts A70213 */
t->fill_up_media = 0;
/* ts A70218 */
t->default_size = 0;
t->entry = NULL;
t->source = NULL;
......@@ -351,6 +353,13 @@ int burn_track_set_sectors(struct burn_track *t, int sectors)
}
/* ts A70218 */
int burn_track_set_size(struct burn_track *t, off_t size)
{
return t->source->set_size(t->source, size);
}
/* ts A70213 */
int burn_track_set_fillup(struct burn_track *t, int fill_up_media)
{
......@@ -392,6 +401,22 @@ int burn_track_is_open_ended(struct burn_track *t)
return !!t->open_ended;
}
/* ts A70218 : API */
int burn_track_set_default_size(struct burn_track *t, off_t size)
{
t->default_size = size;
return 1;
}
/* ts A70218 */
off_t burn_track_get_default_size(struct burn_track *t)
{
return t->default_size;
}
/* ts A61101 : API function */
int burn_track_get_counters(struct burn_track *t,
off_t *read_bytes, off_t *written_bytes)
......
......@@ -31,6 +31,9 @@ struct burn_track
/* ts A70213 : wether to expand this track to full available media */
int fill_up_media;
/* ts A70218 : a track size to use if it is mandarory to have some */
off_t default_size;
/** Data source */
struct burn_source *source;
/** End of Source flag */
......@@ -92,13 +95,18 @@ int burn_track_get_shortage(struct burn_track *t);
int burn_track_is_open_ended(struct burn_track *t);
int burn_track_is_data_done(struct burn_track *t);
/* ts A70125 */
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
int burn_track_set_sectors(struct burn_track *t, int sectors);
/* ts A70218 : sets the payload size alone */
int burn_track_set_size(struct burn_track *t, off_t size);
/* ts A70213 */
int burn_track_set_fillup(struct burn_track *t, int fill_up_media);
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag);
/* ts A70218 */
off_t burn_track_get_default_size(struct burn_track *t);
#endif /* BURN__STRUCTURE_H */
This diff is collapsed.
......@@ -15,7 +15,8 @@ int burn_sector_length(int trackmode);
int burn_subcode_length(int trackmode);
/* ts A61009 */
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc);
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc,
int flag);
void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc);
int burn_write_leadin(struct burn_write_opts *o,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment