Preparations for supporting DVD+R[/DL]
This commit is contained in:
parent
0c4cfdd359
commit
3b5c80e867
@ -4524,9 +4524,11 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
||||
} else if((profile_number==0x1a || profile_number==0x13 ||
|
||||
profile_number==0x12 ||
|
||||
profile_number==0x11 || profile_number==0x14 ||
|
||||
profile_number==0x15)
|
||||
profile_number==0x15 ||
|
||||
profile_number==0x1b || profile_number==0x2b)
|
||||
&& might_do_tao) {
|
||||
/* DVD+RW, DVD-RW Restr. Overwrite, DVD-RAM, DVD-R[W][/DL] Sequential */
|
||||
/* DVD+RW, DVD-RW Restricted Overwrite, DVD-RAM,
|
||||
DVD-R[W][/DL] Sequential Recording, DVD+R[/DL] */
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
} else {
|
||||
strcpy(skin->preskin->write_mode_name,"SAO");
|
||||
|
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.02.25.112733"
|
||||
#define Cdrskin_timestamP "2007.03.01.120945"
|
||||
|
108
doc/cookbook.txt
108
doc/cookbook.txt
@ -5,7 +5,7 @@ Content:
|
||||
- SAO CD Cookbook (CD-R, CD-RW, pure audio or pure data only)
|
||||
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW)
|
||||
- Sequential DVD-R[W] Cookbook
|
||||
|
||||
- >>> DVD+R Cookbook (emerging, totally untested yet)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
TAO Multi-Session CD Cookbook
|
||||
@ -973,7 +973,7 @@ with DVD-R.
|
||||
|
||||
A half-sentence in mmc5r03c.pdf 6.3.3.3.3 might indicate that closing a session
|
||||
by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits
|
||||
in mode page 5.
|
||||
in mode page 05h.
|
||||
growisofs applies this function in case of not DAO, though. A comment in
|
||||
growisofs_mmc.cpp states: "// DVD-R DL Seq has no notion of multi-session".
|
||||
I am not reading this from the specs - but not explicitely the contrary either.
|
||||
@ -985,3 +985,107 @@ close session if multi-session is demanded.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
INCOMPLETE, YET TOTALLY UNTESTED
|
||||
|
||||
DVD+R Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
backed by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
||||
|
||||
For libburnia.pykix.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
|
||||
(mmc5r03c.pdf 6.6.2.1)
|
||||
DVD+R 001bh
|
||||
DVD+R/DL 002bh
|
||||
|
||||
- About empty, appendable and finalized DVD+R
|
||||
- Writing a Pseudo Session to DVD+R
|
||||
- >>> Obtaining multi-session info for extending ISO-9660 filesystems
|
||||
- >>> Obtaining a Table Of Content from CD
|
||||
- >>> Hearsay about DVD+R/DL (Dual Layer) :
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
About blank, appendable and finalized DVD+R :
|
||||
|
||||
In the beginning a DVD+R holds an empty session and the Incomplete Fragment.
|
||||
From these one may spawn reserved fragments or one may write directly to
|
||||
the incomplete fragment. As soon as this is done the empty session becomes the
|
||||
open session which finally needs to get closed. By closing fragments and
|
||||
session a new empty session with empty Incomplete Fragment gets spawned.
|
||||
So the disc stays appendable.
|
||||
|
||||
A DVD+R may hold 153 closed sessions with a single track each.
|
||||
The open session may hold up to 15 open fragments. But on closure of the
|
||||
session those fragments together form a single logical track. So one will
|
||||
usually only use a single fragment for sequential writing.
|
||||
(mmc5r03c.pdf 4.3.6.2)
|
||||
|
||||
The disc may get finalized by another close command so that no more data can
|
||||
be written.
|
||||
(mmc5r03c.pdf 6.3.3.4.4)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Writing a Pseudo Session to DVD+R :
|
||||
|
||||
Session writing has to be pseudo because only one logical track per session
|
||||
can be distinguished. So actually there have to be written multiple sessions
|
||||
to mark multiple tracks. The pseudo session cannot get marked on disc and thus
|
||||
the tracks of a pseudo session cannot be grouped accordingly in a TOC.
|
||||
|
||||
Speed can be influenced by B6h SET STREAMING , speed capabilities can be
|
||||
inquired by ACh GET PERFORMANCE. It is advised to set only speeds and sizes
|
||||
which are returned by ACh.
|
||||
(mmc5r03c.pdf 6.39 SET STREAMING, 6.8 GET PERFORMANCE)
|
||||
|
||||
No mode page 05h is to be sent.
|
||||
growisofs sends a page but the specs clearly state that one shall not do.
|
||||
(mmc5r03c.pdf 7.5.3)
|
||||
|
||||
It is optional wether a track size is reserved in advance or not. Eventually
|
||||
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
||||
already be aligned to 32 KiB.
|
||||
(mmc5r03c.pdf 6.31)
|
||||
The specs promise to pad up the track if not enough data get written.
|
||||
(mmc5r03c.pdf 6.3.3.4.2)
|
||||
|
||||
Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION
|
||||
with track number FFh.
|
||||
(mmc5r03c.pdf 6.27)
|
||||
Since the fixely set write type is 16-block packet, full 32 kB buffers have
|
||||
to be transmitted via 2Ah WRITE.
|
||||
(mmc5r03c.pdf 4.3.6.2.2)
|
||||
|
||||
When writing is done, it is mandatory to force the drive's buffer to media by
|
||||
35h SYNCHRONIZE CACHE.
|
||||
(mmc5r03c.pdf 6.41)
|
||||
|
||||
The written fragment (i.e. track-to-be) has to be closed by 5Bh CLOSE TRACK
|
||||
SESSION Close Function 001b.
|
||||
(mmc5r03c.pdf 6.3.3.4.2)
|
||||
libburn obtains the necessary logical track number from Last Track Number in
|
||||
Last Session from the reply of 51h READ DISC INFORMATION requesting
|
||||
Data Type 000b.
|
||||
(mmc5r03c.pdf 6.22)
|
||||
After each track 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
||||
Number 0 closes the DVD+R session but keeps the media appendable.
|
||||
(mmc5r03c.pdf 6.3.3.4.3)
|
||||
|
||||
|
||||
Eventually 5Bh CLOSE TRACK SESSION Close Function 101b is used to finalize
|
||||
the media with minimal radius. After that the disc is not appendable any more !
|
||||
(mmc5r03c.pdf 6.3.3.4.4)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Hearsay about DVD+R/DL (Dual Layer) :
|
||||
|
||||
>>>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -1696,8 +1696,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||
o->advised_write_mode = BURN_WRITE_TAO;
|
||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||
/* DVD+R , DVD+R/DL */
|
||||
o->multi_session = 1;
|
||||
o->multi_track = 1;
|
||||
o->multi_session = o->multi_track = 1;
|
||||
o->might_do_tao = 2;
|
||||
o->might_do_sao = 1;
|
||||
o->advised_write_mode = BURN_WRITE_TAO;
|
||||
|
@ -89,8 +89,6 @@ extern struct libdax_msgs *libdax_messenger;
|
||||
size prediction mandatory.
|
||||
ts A70208 : Finally made tests with DVD-R. Worked exactly as new DVD-RW.
|
||||
|
||||
Todo:
|
||||
Determine first free lba for appending data on overwriteables.
|
||||
*/
|
||||
|
||||
|
||||
@ -242,7 +240,6 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
|
||||
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf)
|
||||
{
|
||||
struct command c;
|
||||
int i;
|
||||
|
||||
mmc_function_spy("mmc_read_track_info");
|
||||
c.retry = 1;
|
||||
@ -263,8 +260,7 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf)
|
||||
else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */
|
||||
trackno = 0xFF;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
c.opcode[2 + i] = (trackno >> (24 - 8 * i)) & 0xff;
|
||||
mmc_int_to_four_char(c.opcode + 2, trackno);
|
||||
c.page = buf;
|
||||
memset(buf->data, 0, BUFFER_SIZE);
|
||||
c.dir = FROM_DRIVE;
|
||||
@ -285,26 +281,11 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
||||
unsigned char *data;
|
||||
|
||||
mmc_function_spy("mmc_get_nwa");
|
||||
if(trackno<=0) {
|
||||
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x12 )
|
||||
/* DVD+RW , DVD-RW restricted overwrite , DVD-RAM */
|
||||
trackno = 1;
|
||||
else if (d->current_profile == 0x10 ||
|
||||
d->current_profile == 0x11 ||
|
||||
d->current_profile == 0x14 ||
|
||||
d->current_profile == 0x15)
|
||||
/* DVD-ROM, DVD-R[W] Sequential */
|
||||
trackno = d->last_track_no;
|
||||
else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */
|
||||
trackno = 0xFF;
|
||||
}
|
||||
|
||||
ret = mmc_read_track_info(d, trackno, &buf);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
data = buf.data;
|
||||
|
||||
*lba = mmc_four_char_to_int(data + 8);
|
||||
*nwa = mmc_four_char_to_int(data + 12);
|
||||
num = mmc_four_char_to_int(data + 16);
|
||||
@ -375,6 +356,11 @@ void mmc_close_session(struct burn_write_opts *o)
|
||||
mmc_close(d, 1, 0);
|
||||
}
|
||||
|
||||
/* ts A70227 : extended meaning of session to address all possible values
|
||||
of 5Bh CLOSE TRACK SESSION to address any Close Function.
|
||||
@param session contains the two high bits of Close Function
|
||||
@param track if not 0: sets the lowest bit of Close Function
|
||||
*/
|
||||
void mmc_close(struct burn_drive *d, int session, int track)
|
||||
{
|
||||
struct command c;
|
||||
@ -385,8 +371,8 @@ void mmc_close(struct burn_drive *d, int session, int track)
|
||||
c.oplen = sizeof(MMC_CLOSE);
|
||||
memcpy(c.opcode, MMC_CLOSE, sizeof(MMC_CLOSE));
|
||||
|
||||
/* ts A61030 : shifted !!session rather than or-ing plain session */
|
||||
c.opcode[2] = ((!!session)<<1) | !!track;
|
||||
/* (ts A61030 : shifted !!session rather than or-ing plain session ) */
|
||||
c.opcode[2] = ((session & 3) << 1) | !!track;
|
||||
c.opcode[4] = track >> 8;
|
||||
c.opcode[5] = track & 0xFF;
|
||||
c.page = NULL;
|
||||
@ -431,14 +417,8 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
|
||||
memcpy(c.opcode, MMC_WRITE_12, sizeof(MMC_WRITE_12));
|
||||
c.retry = 1;
|
||||
c.oplen = sizeof(MMC_WRITE_12);
|
||||
c.opcode[2] = start >> 24;
|
||||
c.opcode[3] = (start >> 16) & 0xFF;
|
||||
c.opcode[4] = (start >> 8) & 0xFF;
|
||||
c.opcode[5] = start & 0xFF;
|
||||
c.opcode[6] = len >> 24;
|
||||
c.opcode[7] = (len >> 16) & 0xFF;
|
||||
c.opcode[8] = (len >> 8) & 0xFF;
|
||||
c.opcode[9] = len & 0xFF;
|
||||
mmc_int_to_four_char(c.opcode + 2, start);
|
||||
mmc_int_to_four_char(c.opcode + 6, len);
|
||||
c.page = buf;
|
||||
c.dir = TO_DRIVE;
|
||||
|
||||
@ -491,10 +471,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
memcpy(c.opcode, MMC_WRITE_10, sizeof(MMC_WRITE_10));
|
||||
c.retry = 1;
|
||||
c.oplen = sizeof(MMC_WRITE_10);
|
||||
c.opcode[2] = start >> 24;
|
||||
c.opcode[3] = (start >> 16) & 0xFF;
|
||||
c.opcode[4] = (start >> 8) & 0xFF;
|
||||
c.opcode[5] = start & 0xFF;
|
||||
mmc_int_to_four_char(c.opcode + 2, start);
|
||||
c.opcode[6] = 0;
|
||||
c.opcode[7] = (len >> 8) & 0xFF;
|
||||
c.opcode[8] = len & 0xFF;
|
||||
@ -1561,6 +1538,11 @@ void mmc_get_configuration(struct burn_drive *d)
|
||||
if (cp == 0x15 && burn_support_untested_profiles) /* DVD-R/DL */
|
||||
d->current_is_supported_profile = 1;
|
||||
#endif
|
||||
#ifdef Libburn_support_dvd_plusR
|
||||
if ((cp == 0x1b || cp == 0x2b) &&
|
||||
burn_support_untested_profiles) /* DVD+R , DVD+R/DL */
|
||||
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
|
||||
@ -1916,8 +1898,8 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
|
||||
c.page->data[1] = 0x02; /* Immed */
|
||||
c.page->data[3] = 8; /* Format descriptor length */
|
||||
num_of_blocks = size / 2048;
|
||||
for (i = 0; i < 4; i++)
|
||||
c.page->data[4 + i] = (num_of_blocks >> (24 - 8 * i)) & 0xff;
|
||||
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
||||
|
||||
if (flag & 128) { /* explicitely chosen format descriptor */
|
||||
/* use case: the app knows what to do */
|
||||
|
||||
@ -1947,9 +1929,7 @@ selected_not_suitable:;
|
||||
if (flag & 4) {
|
||||
num_of_blocks =
|
||||
d->format_descriptors[index].size / 2048;
|
||||
for (i = 0; i < 4; i++)
|
||||
c.page->data[4 + i] =
|
||||
(num_of_blocks >> (24 - 8 * i)) & 0xff;
|
||||
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
|
||||
}
|
||||
if (format_type != 0x26)
|
||||
for (i = 0; i < 3; i++)
|
||||
@ -2024,9 +2004,8 @@ selected_not_suitable:;
|
||||
num_of_blocks = diff;
|
||||
}
|
||||
if (num_of_blocks > 0)
|
||||
for (i = 0; i < 4; i++)
|
||||
c.page->data[4 + i] =
|
||||
(num_of_blocks >> (24 - 8 * i)) & 0xff;
|
||||
mmc_int_to_four_char(c.page->data + 4,
|
||||
num_of_blocks);
|
||||
}
|
||||
/* 6.5.4.2.8 , DVD-RW Quick Grow Last Border */
|
||||
format_type = 0x13;
|
||||
@ -2050,9 +2029,8 @@ selected_not_suitable:;
|
||||
if ((flag & 4)
|
||||
|| d->best_format_type == full_format_type) {
|
||||
num_of_blocks = d->best_format_size / 2048;
|
||||
for (i = 0; i < 4; i++)
|
||||
c.page->data[4 + i] =
|
||||
(num_of_blocks >> (24 - 8 * i)) & 0xff;
|
||||
mmc_int_to_four_char(c.page->data + 4,
|
||||
num_of_blocks);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -2356,6 +2334,10 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
/* Packet Size */
|
||||
pd[13] = 16;
|
||||
|
||||
} else if (d->current_profile == 0x1a || d->current_profile == 0x1b ||
|
||||
d->current_profile == 0x2b || d->current_profile == 0x12) {
|
||||
/* not with DVD+R[W][/DL] or DVD-RAM */;
|
||||
return 0;
|
||||
} else {
|
||||
/* Traditional setup for CD */
|
||||
|
||||
|
277
libburn/write.c
277
libburn/write.c
@ -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:;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user