Preparations for supporting DVD+R[/DL]

This commit is contained in:
2007-03-01 12:07:29 +00:00
parent e38875f0fd
commit a25ab4d433
6 changed files with 348 additions and 120 deletions

View File

@ -890,6 +890,84 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
}
/* ts A70219 : API */
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int silent)
{
enum burn_write_types wt;
struct burn_drive *d = o->drive;
char msg[160], *reason_pt;
int no_media = 0;
reason_pt= reasons;
reasons[0] = 0;
/* check write mode against write job */
wt = burn_write_opts_auto_write_type(o, disc, reasons, 1);
if (wt == BURN_WRITE_NONE) {
if (strncmp(reasons, "MEDIA: ", 7)==0)
no_media = 1;
goto ex;
}
sprintf(reasons, "%s: ", d->current_profile_text);
reason_pt= reasons + strlen(reasons);
if (d->status == BURN_DISC_UNSUITABLE)
goto unsuitable_profile;
if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
if (!burn_disc_write_is_ok(o, disc, (!!silent) << 1))
strcat(reasons, "unsuitable track mode found, ");
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else if (d->current_profile == 0x1a || d->current_profile == 0x12) {
/* DVD+RW , DVD-RAM */
if (o->start_byte >= 0 && (o->start_byte % 2048))
strcat(reasons,
"write start address not properly aligned to 2048, ");
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
if (o->start_byte >= 0 && (o->start_byte % 32768))
strcat(reasons,
"write start address not properly aligned to 32k, ");
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15 ||
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
/* DVD-R* Sequential , DVD+R[/DL] */
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else {
unsuitable_profile:;
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);
if (!silent)
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
strcat(reasons, "no suitable media profile detected, ");
return 0;
}
ex:;
if (reason_pt[0]) {
if (no_media) {
if (!silent)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002013a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"No suitable media detected", 0, 0);
return -1;
}
if (!silent)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Write job parameters are unsuitable", 0, 0);
return 0;
}
return 1;
}
/* ts A70129 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */
int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
@ -931,6 +1009,46 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
}
/* ts A70226 */
int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
{
struct burn_drive *d = o->drive;
char msg[160];
int ret, lba, nwa;
off_t size;
ret = d->get_nwa(d, -1, &lba, &nwa);
sprintf(msg,
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
tnum+1, nwa, ret, d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
if (nwa > d->nwa)
d->nwa = nwa;
/* ts A70214 : eventually adjust already expanded size of track */
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
if (o->write_type == BURN_WRITE_SAO) {
/* Round track size up to 32 KiB and reserve track */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
* (off_t) 2048;
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
ret = d->reserve_track(d, size);
if (ret <= 0) {
sprintf(msg, "Cannot reserve track of %.f bytes",
(double) size);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020138,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
}
return 1;
}
/* ts A70129 */
int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
@ -956,6 +1074,28 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
}
/* ts A70226 */
int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
{
struct burn_drive *d = o->drive;
char msg[80];
sprintf(msg,
"Closing track %2.2d (absolute track and session number %d)",
tnum + 1, d->last_track_no);
libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
d->busy = BURN_DRIVE_CLOSING_SESSION;
d->close_track_session(d, 0, d->last_track_no); /* CLOSE TRACK, 001b */
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
d->busy = BURN_DRIVE_WRITING;
d->last_track_no++;
return 1;
}
/* ts A61218 - A70129 */
int burn_dvd_write_track(struct burn_write_opts *o,
struct burn_session *s, int tnum)
@ -975,6 +1115,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
if (ret <= 0)
goto ex;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
if (ret <= 0)
goto ex;
}
sectors = burn_track_get_sectors(t);
@ -1035,7 +1180,12 @@ int burn_dvd_write_track(struct burn_write_opts *o,
d->current_profile == 0x15) {
/* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */
ret = burn_disc_close_track_dvd_minus_r(o, s, tnum);
if (ret != 2)
if (ret <= 0)
goto ex;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
ret = burn_disc_close_track_dvd_plus_r(o, s, tnum);
if (ret <= 0)
goto ex;
}
ret = 1;
@ -1148,6 +1298,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
if (ret <= 0)
return 0;
}
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL do each track as an own session */;
}
return 1;
}
@ -1258,76 +1410,30 @@ int burn_disc_setup_dvd_minus_r(struct burn_write_opts *o,
}
/* ts A70219 : API */
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int silent)
/* ts A70226 : for DVD+R , DVD+R/DL */
int burn_disc_setup_dvd_plus_r(struct burn_write_opts *o,
struct burn_disc *disc)
{
enum burn_write_types wt;
struct burn_drive *d = o->drive;
char msg[160], *reason_pt;
int no_media = 0;
reason_pt= reasons;
reasons[0] = 0;
/* most setup is in burn_disc_setup_track_dvd_plus_r() */;
/* check write mode against write job */
wt = burn_write_opts_auto_write_type(o, disc, reasons, 1);
if (wt == BURN_WRITE_NONE) {
if (strncmp(reasons, "MEDIA: ", 7)==0)
no_media = 1;
goto ex;
}
d->nwa = 0;
return 1;
}
sprintf(reasons, "%s: ", d->current_profile_text);
reason_pt= reasons + strlen(reasons);
if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
if (!burn_disc_write_is_ok(o, disc, (!!silent) << 1))
strcat(reasons, "unsuitable track mode found, ");
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else if (d->current_profile == 0x1a || d->current_profile == 0x12) {
/* DVD+RW , DVD-RAM */
if (o->start_byte >= 0 && (o->start_byte % 2048))
strcat(reasons,
"write start address not properly aligned to 2048, ");
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
if (o->start_byte >= 0 && (o->start_byte % 32768))
strcat(reasons,
"write start address not properly aligned to 32k, ");
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R* Sequential */
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else {
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);
if (!silent)
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
strcat(reasons, "no suitable media profile detected, ");
return 0;
}
ex:;
if (reason_pt[0]) {
if (no_media) {
if (!silent)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002013a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"No suitable media detected", 0, 0);
return -1;
}
if (!silent)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Write job parameters are unsuitable", 0, 0);
return 0;
}
/* ts A70229 */
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
{
struct burn_drive *d = o->drive;
if (o->multi)
return 2;
d->busy = BURN_DRIVE_CLOSING_SESSION;
/* CLOSE SESSION, 101b, Finalize with minimal radius */
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
d->busy = BURN_DRIVE_WRITING;
return 1;
}
@ -1534,6 +1640,38 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
t = disc->session[0]->track[0];
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
default_size = burn_track_get_default_size(t);
#ifndef Libburn_precheck_write_ruleS
/* >>> oldfashioned checks hopefully never re-enabled */
#endif /* ! Libburn_precheck_write_ruleS */
if (o->write_type == BURN_WRITE_SAO && o_end) {
sprintf(msg, "Activated track default size %.f",
(double) default_size);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002012e,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
burn_track_set_size(t, default_size);
}
ret = burn_disc_setup_dvd_plus_r(o, disc);
if (ret <= 0) {
sprintf(msg,
"Write preparation setup failed for DVD+R");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto early_failure;
}
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
} else {
@ -1564,8 +1702,11 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
d->progress.sectors = 0;
}
/* >>> eventual normal finalization measures */
if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
ret = burn_disc_finalize_dvd_plus_r(o);
if (ret <= 0)
goto ex;
}
ret = 1;
ex:;