Implemented DVD-R[W] DAO as BURN_WRITE_SAO

ZeroThreeEight
Thomas Schmitt 16 years ago
parent 330e0e2d5f
commit 2799fe1b44
  1. 2
      cdrskin/cdrskin_timestamp.h
  2. 10
      libburn/drive.c
  3. 31
      libburn/libburn.h
  4. 6
      libburn/libdax_msgs.h
  5. 53
      libburn/mmc.c
  6. 91
      libburn/write.c

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

@ -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 &&
(wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) {
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) {
/* CD-R , CD-RW */
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)
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) {
/* 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) {
o->multi_session = o->multi_track = 1;
o->might_do_tao = 2;
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 ||
d->current_profile == 0x1a) {
/* DVD-RAM, overwriteable DVD-RW, DVD+RW */

@ -107,24 +107,31 @@ struct burn_write_opts;
enum burn_write_types
{
/** Packet writing.
currently unsupported
currently unsupported, (for DVD Incremental Streaming use TAO)
*/
BURN_WRITE_PACKET,
/** Track At Once recording.
2s gaps between tracks, no fonky lead-ins
/** With CD: Track At Once recording
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,
/** Session At Once.
Block type MUST be BURN_BLOCK_SAO
ts A70122 : Currently not capable of mixing data and audio tracks.
/** With CD: Session At Once
Block type MUST be BURN_BLOCK_SAO
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,
/** Raw disc at once recording.
all subcodes must be provided by lib or user
only raw block types are supported
/** With CD: Raw disc at once recording.
all subcodes must be provided by lib or user
only raw block types are supported
*/
BURN_WRITE_RAW,
@ -1385,6 +1392,10 @@ struct burn_multi_caps {
writing a session. It also guarantees that the drive will be able
to predict and use the appropriate Next Writeable Address to place
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)
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.
@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_TAO the
get returned. If set to a write mode like BURN_WRITE_SAO the
capabilities with that particular mode are returned.
@param caps returns the info structure
@param flag Bitfield for control purposes (unused yet, submit 0)

@ -352,6 +352,12 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
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
0x00020137 (HINT,HIGH) = TAO would be possible
0x00020138 (FATAL,HIGH) = Cannot reserve track
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

@ -208,20 +208,27 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
{
struct command c;
int lba;
char msg[80];
mmc_function_spy("mmc_reserve_track");
c.retry = 1;
c.oplen = 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;
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.dir = NO_TRANSFER;
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)
d->current_is_supported_profile = 1;
#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 :
#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.page = NULL;
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);
}
@ -2232,8 +2243,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
pd[0] = 5;
pd[1] = d->mdata->write_page_length;
/* ts A61229 */
if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */
if (d->current_profile == 0x13) {
/* A61229 : DVD-RW restricted overwrite */
/* learned from transport.hxx : page05_setup()
and mmc3r10g.pdf table 347 */
/* 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;
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11)
&& d->current_has_feat21h == 1) { /* ts A70128 */
/* learned from transport.hxx : page05_setup()
&& o->write_type == BURN_WRITE_SAO) {
/* 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 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)
| (1 << 5)
| ((!!o->simulate) << 4);
@ -2279,6 +2307,7 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
} else {
/* Traditional setup for CD */
pd[2] = ((!!o->underrun_proof) << 6)
| ((!!o->simulate) << 4)
| (o->write_type & 0x0f);

@ -869,22 +869,40 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
/* 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;
char msg[160];
int ret, lba, nwa;
off_t size;
d->send_write_parameters(d, o);
ret = d->get_nwa(d, -1, &lba, &nwa);
sprintf(msg,
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d\n",
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);
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;
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;
}
@ -896,8 +914,8 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
struct burn_drive *d = o->drive;
char msg[80];
/* only DVD-R or sequential DVD-RW */
if (d->current_has_feat21h != 1) /* only with Incremental writing */
/* only with Incremental writing */
if (o->write_type != BURN_WRITE_TAO)
return 2;
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) {
/* 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)
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;
if (d->current_has_feat21h != 1)
return 2; /* only for Incremental writing */
/* 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_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
@ -1047,7 +1066,7 @@ int burn_dvd_write_session(struct burn_write_opts *o,
int i,ret;
struct burn_drive *d = o->drive;
/* >>> open_session ? (maybe with DAO) */
/* >>> open_session ? */
for (i = 0; i < s->tracks; 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;
if (d->current_has_feat21h) {
/* most setup is in burn_disc_setup_track_dvd_minus_r() */;
} else {
return 0; /* >>> no DAO for now */
}
/* most setup is in burn_disc_setup_track_dvd_minus_r() */;
d->nwa = 0;
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,
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;
char msg[160];
@ -1289,9 +1304,47 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
/* _Rigid_ Restricted Overwrite demands this */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else if ((d->current_profile == 0x11 || d->current_profile == 0x14)
&& d->current_has_feat21h == 1) {
/* DVD-R , DVD-RW Sequential (for now only Incremental) */
} else if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R , DVD-RW Sequential */
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) {
sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index,

Loading…
Cancel
Save