Implemented DVD-R[W] DAO as BURN_WRITE_SAO

This commit is contained in:
Thomas Schmitt 2007-02-06 13:06:39 +00:00
parent 330e0e2d5f
commit 2799fe1b44
6 changed files with 151 additions and 42 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.02.05.132335" #define Cdrskin_timestamP "2007.02.06.130410"

View File

@ -1590,6 +1590,8 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
} else if (s == BURN_DISC_APPENDABLE && } else if (s == BURN_DISC_APPENDABLE &&
(wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) { (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) {
return 0; return 0;
} else if (wt == BURN_WRITE_RAW && !d->current_is_cd_profile) {
return 0;
} else if (d->current_profile == 0x09 || d->current_profile == 0x0a) { } else if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
/* CD-R , CD-RW */ /* CD-R , CD-RW */
if (d->block_types[BURN_WRITE_TAO]) { if (d->block_types[BURN_WRITE_TAO]) {
@ -1609,13 +1611,21 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
if (o->advised_write_mode == BURN_WRITE_NONE) if (o->advised_write_mode == BURN_WRITE_NONE)
o->advised_write_mode = BURN_WRITE_RAW; o->advised_write_mode = BURN_WRITE_RAW;
} }
if (wt == BURN_WRITE_RAW)
o->multi_session = o->multi_track = 0;
} else if (d->current_profile == 0x11 || d->current_profile == 0x14) { } else if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R , sequential DVD-RW */ /* DVD-R , sequential DVD-RW */
if (s == BURN_DISC_BLANK) {
o->might_do_sao = 1;
o->advised_write_mode = BURN_WRITE_SAO;
}
if (d->current_has_feat21h) { if (d->current_has_feat21h) {
o->multi_session = o->multi_track = 1; o->multi_session = o->multi_track = 1;
o->might_do_tao = 2; o->might_do_tao = 2;
o->advised_write_mode = BURN_WRITE_TAO; o->advised_write_mode = BURN_WRITE_TAO;
} }
if (wt == BURN_WRITE_SAO)
o->multi_session = o->multi_track = 0;
} else if (d->current_profile == 0x12 || d->current_profile == 0x13 || } else if (d->current_profile == 0x12 || d->current_profile == 0x13 ||
d->current_profile == 0x1a) { d->current_profile == 0x1a) {
/* DVD-RAM, overwriteable DVD-RW, DVD+RW */ /* DVD-RAM, overwriteable DVD-RW, DVD+RW */

View File

@ -107,22 +107,29 @@ struct burn_write_opts;
enum burn_write_types enum burn_write_types
{ {
/** Packet writing. /** Packet writing.
currently unsupported currently unsupported, (for DVD Incremental Streaming use TAO)
*/ */
BURN_WRITE_PACKET, BURN_WRITE_PACKET,
/** Track At Once recording. /** With CD: Track At Once recording
2s gaps between tracks, no fonky lead-ins 2s gaps between tracks, no fonky lead-ins
With sequential DVD-R[W]: Incremental Streaming
With DVD-RAM/+RW: Random Writeable (used sequentially)
With overwriteable DVD-RW: Rigid Restricted Overwrite
*/ */
BURN_WRITE_TAO, BURN_WRITE_TAO,
/** Session At Once. /** With CD: Session At Once
Block type MUST be BURN_BLOCK_SAO Block type MUST be BURN_BLOCK_SAO
ts A70122: Currently not capable of mixing data and audio tracks. ts A70122: Currently not capable of mixing data and audio tracks.
With sequential DVD-R[W]: Disc-at-once, DAO
Single session, single track, fixed size mandatory, (-dvd-compat)
*/ */
BURN_WRITE_SAO, BURN_WRITE_SAO,
/** Raw disc at once recording. /** With CD: Raw disc at once recording.
all subcodes must be provided by lib or user all subcodes must be provided by lib or user
only raw block types are supported only raw block types are supported
*/ */
@ -1385,6 +1392,10 @@ struct burn_multi_caps {
writing a session. It also guarantees that the drive will be able writing a session. It also guarantees that the drive will be able
to predict and use the appropriate Next Writeable Address to place to predict and use the appropriate Next Writeable Address to place
the next session on the media without overwriting the existing ones. the next session on the media without overwriting the existing ones.
It does not guarantee that the selected write type is able to do
an appending session after the next session. (E.g. CD SAO is capable
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) 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 apendable appendable
*/ */
@ -1447,7 +1458,7 @@ struct burn_multi_caps {
via burn_disc_free_multi_caps() when no longer needed. via burn_disc_free_multi_caps() when no longer needed.
@param d The drive to inquire @param d The drive to inquire
@param wt With BURN_WRITE_NONE the best capabilities of all write modes @param wt With BURN_WRITE_NONE the best capabilities of all write modes
get returned. If set to a write mode like BURN_WRITE_TAO the 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.
@param caps returns the info structure @param caps returns the info structure
@param flag Bitfield for control purposes (unused yet, submit 0) @param flag Bitfield for control purposes (unused yet, submit 0)

View File

@ -352,6 +352,12 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive 0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive
0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn 0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn
0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode 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
0x00020137 (HINT,HIGH) = TAO would be possible
0x00020138 (FATAL,HIGH) = Cannot reserve track
libdax_audioxtr: libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file 0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -208,20 +208,27 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
{ {
struct command c; struct command c;
int lba; int lba;
char msg[80];
mmc_function_spy("mmc_reserve_track"); mmc_function_spy("mmc_reserve_track");
c.retry = 1; c.retry = 1;
c.oplen = sizeof(MMC_RESERVE_TRACK); c.oplen = sizeof(MMC_RESERVE_TRACK);
memcpy(c.opcode, MMC_RESERVE_TRACK, sizeof(MMC_RESERVE_TRACK)); memcpy(c.opcode, MMC_RESERVE_TRACK, sizeof(MMC_RESERVE_TRACK));
/* Nice rounding trick learned from dvd+rw-tools */ /* Round to 32 KiB and divide by 2048
(by nice binary rounding trick learned from dvd+rw-tools) */
lba = ((size + (off_t) 0x7fff) >> 11) & ~0xf; lba = ((size + (off_t) 0x7fff) >> 11) & ~0xf;
mmc_int_to_four_char(c.opcode+5, lba); mmc_int_to_four_char(c.opcode+5, lba);
sprintf(msg, "reserving track of %d blocks", lba);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
c.page = NULL; c.page = NULL;
c.dir = NO_TRANSFER; c.dir = NO_TRANSFER;
d->issue_command(d, &c); d->issue_command(d, &c);
return !!c.error; return !c.error;
} }
@ -1521,6 +1528,10 @@ void mmc_get_configuration(struct burn_drive *d)
if (cp == 0x12) if (cp == 0x12)
d->current_is_supported_profile = 1; d->current_is_supported_profile = 1;
#endif #endif
#ifdef Libburn_support_dvd_r_seQ
if (cp == 0x11 || cp == 0x14)
d->current_is_supported_profile = 1;
#endif
/* Enable this to get loud and repeated reports about the feature set : /* Enable this to get loud and repeated reports about the feature set :
#define Libburn_print_feature_descriptorS 1 #define Libburn_print_feature_descriptorS 1
@ -1645,11 +1656,6 @@ void mmc_get_configuration(struct burn_drive *d)
} }
} }
#ifdef Libburn_support_dvd_r_seQ
/* might get adjusted later by mmc_read_disc_info() */
if ((cp == 0x11 || cp == 0x14) && d->current_has_feat21h)
d->current_is_supported_profile = 1;
#endif
} }
@ -1778,6 +1784,11 @@ void mmc_sync_cache(struct burn_drive *d)
c.oplen = sizeof(MMC_SYNC_CACHE); c.oplen = sizeof(MMC_SYNC_CACHE);
c.page = NULL; c.page = NULL;
c.dir = NO_TRANSFER; c.dir = NO_TRANSFER;
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"\nsyncing cache", 0, 0);
d->issue_command(d, &c); d->issue_command(d, &c);
} }
@ -2232,8 +2243,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
pd[0] = 5; pd[0] = 5;
pd[1] = d->mdata->write_page_length; pd[1] = d->mdata->write_page_length;
/* ts A61229 */ if (d->current_profile == 0x13) {
if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */ /* A61229 : DVD-RW restricted overwrite */
/* learned from transport.hxx : page05_setup() /* learned from transport.hxx : page05_setup()
and mmc3r10g.pdf table 347 */ and mmc3r10g.pdf table 347 */
/* BUFE (burnproof), no LS_V (i.e. default Link Size, i hope), /* BUFE (burnproof), no LS_V (i.e. default Link Size, i hope),
@ -2247,11 +2258,28 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
pd[5] = 0; pd[5] = 0;
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11) } else if ((d->current_profile == 0x14 || d->current_profile == 0x11)
&& d->current_has_feat21h == 1) { /* ts A70128 */ && o->write_type == BURN_WRITE_SAO) {
/* learned from transport.hxx : page05_setup() /* ts A70205 : DVD-R[W} : Disc-at-once, DAO */
/* Learned from dvd+rw-tools and mmc5r03c.pdf .
See doc/cookbook.txt for more detailed references. */
/* BUFE , LS_V = 0, Test Write, Write Type = 2 SAO (DAO) */
pd[2] = ((!!o->underrun_proof) << 6)
| ((!!o->simulate) << 4)
| 2;
/* No multi-session , FP = 0 , Track Mode = 5 */
pd[3] = 5;
/* Data Block Type = 8 */
pd[4] = 8;
} else if (d->current_profile == 0x14 || d->current_profile == 0x11) {
/* ts A70128 : DVD-R[W] Incremental Streaming */
/* Learned from transport.hxx : page05_setup()
and mmc5r03c.pdf 7.5, 4.2.3.4 Table 17 and mmc5r03c.pdf 7.5, 4.2.3.4 Table 17
and spc3r23.pdf 6.8, 7.4.3 */ and spc3r23.pdf 6.8, 7.4.3 */
/* BUFE , LS_V = 1, Test Write, Write Type = 00h Incremental */
/* BUFE , LS_V = 1, Test Write,
Write Type = 0 Packet/Incremental */
pd[2] = ((!!o->underrun_proof) << 6) pd[2] = ((!!o->underrun_proof) << 6)
| (1 << 5) | (1 << 5)
| ((!!o->simulate) << 4); | ((!!o->simulate) << 4);
@ -2279,6 +2307,7 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
} else { } else {
/* Traditional setup for CD */ /* Traditional setup for CD */
pd[2] = ((!!o->underrun_proof) << 6) pd[2] = ((!!o->underrun_proof) << 6)
| ((!!o->simulate) << 4) | ((!!o->simulate) << 4)
| (o->write_type & 0x0f); | (o->write_type & 0x0f);

View File

@ -869,11 +869,13 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
/* ts A70129 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */ /* 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, int tnum) int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
{ {
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
char msg[160]; char msg[160];
int ret, lba, nwa; int ret, lba, nwa;
off_t size;
d->send_write_parameters(d, o); d->send_write_parameters(d, o);
ret = d->get_nwa(d, -1, &lba, &nwa); ret = d->get_nwa(d, -1, &lba, &nwa);
@ -881,10 +883,26 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o, int tnum)
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d\n", "DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d\n",
tnum+1, nwa, ret, d->nwa); tnum+1, nwa, ret, d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002, libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
msg,0,0);
if (nwa > d->nwa) if (nwa > d->nwa)
d->nwa = nwa; d->nwa = nwa;
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
/* 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; return 1;
} }
@ -896,8 +914,8 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
char msg[80]; char msg[80];
/* only DVD-R or sequential DVD-RW */ /* only with Incremental writing */
if (d->current_has_feat21h != 1) /* only with Incremental writing */ if (o->write_type != BURN_WRITE_TAO)
return 2; return 2;
sprintf(msg, "Closing track %2.2d (absolute track number %d)", sprintf(msg, "Closing track %2.2d (absolute track number %d)",
@ -929,7 +947,7 @@ int burn_dvd_write_track(struct burn_write_opts *o,
if (d->current_profile == 0x11 || d->current_profile == 0x14) { if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R, DVD-RW Sequential */ /* DVD-R, DVD-RW Sequential */
ret = burn_disc_open_track_dvd_minus_r(o, tnum); ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
if (ret <= 0) if (ret <= 0)
goto ex; goto ex;
} }
@ -1026,8 +1044,9 @@ int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o,
{ {
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
if (d->current_has_feat21h != 1) /* only for Incremental writing */
return 2; /* only for Incremental writing */ if (o->write_type != BURN_WRITE_TAO)
return 2;
libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
@ -1047,7 +1066,7 @@ int burn_dvd_write_session(struct burn_write_opts *o,
int i,ret; int i,ret;
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
/* >>> open_session ? (maybe with DAO) */ /* >>> open_session ? */
for (i = 0; i < s->tracks; i++) { for (i = 0; i < s->tracks; i++) {
ret = burn_dvd_write_track(o, s, i); ret = burn_dvd_write_track(o, s, i);
@ -1189,11 +1208,7 @@ int burn_disc_setup_dvd_minus_r(struct burn_write_opts *o,
{ {
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
if (d->current_has_feat21h) {
/* most setup is in burn_disc_setup_track_dvd_minus_r() */; /* most setup is in burn_disc_setup_track_dvd_minus_r() */;
} else {
return 0; /* >>> no DAO for now */
}
d->nwa = 0; d->nwa = 0;
return 1; return 1;
@ -1204,7 +1219,7 @@ int burn_disc_setup_dvd_minus_r(struct burn_write_opts *o,
int burn_dvd_write_sync(struct burn_write_opts *o, int burn_dvd_write_sync(struct burn_write_opts *o,
struct burn_disc *disc) struct burn_disc *disc)
{ {
int i, ret, sx, tx, mode, exotic_track = 0; int i, ret, sx, tx, mode, exotic_track = 0, dao_is_ok;
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
char msg[160]; char msg[160];
@ -1289,9 +1304,47 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
/* _Rigid_ Restricted Overwrite demands this */ /* _Rigid_ Restricted Overwrite demands this */
o->obs_pad = 1; /* fill-up track's last 32k buffer */ o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else if ((d->current_profile == 0x11 || d->current_profile == 0x14) } else if (d->current_profile == 0x11 || d->current_profile == 0x14) {
&& d->current_has_feat21h == 1) { /* DVD-R , DVD-RW Sequential */
/* DVD-R , DVD-RW Sequential (for now only Incremental) */ dao_is_ok =
(disc->sessions == 1 &&
disc->session[0]->tracks == 1 &&
(! burn_track_is_open_ended(
disc->session[0]->track[0])) &&
(!o->multi) && d->status == BURN_DISC_BLANK
);
if (o->write_type == BURN_WRITE_TAO &&
!d->current_has_feat21h) {
if (dao_is_ok) {
o->write_type = BURN_WRITE_SAO;
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020134,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Defaulted TAO to DAO (lack of feature 21h)",
0, 0);
} else {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020135,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot perform TAO (lack of feature 21h), job unsuitable for DAO",
0, 0);
goto early_failure;
}
} else if (o->write_type == BURN_WRITE_SAO && !dao_is_ok) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020136,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"DAO burning is restricted to a single fixed size track and no multi-session",
0,0);
if (d->current_has_feat21h)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020137,
LIBDAX_MSGS_SEV_HINT,
LIBDAX_MSGS_PRIO_HIGH,
"TAO would be possible and could do the job",
0,0);
goto early_failure;
}
if (o->start_byte >= 0) { if (o->start_byte >= 0) {
sprintf(msg, "Write start address not supported"); sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,