Provisorily obtain multi-session -C parameters (violates MMC specs but works)
This commit is contained in:
parent
163509011c
commit
d0a2ff1278
@ -149,8 +149,9 @@ Note: The support for sequentially recordable media is still emerging.
|
|||||||
DVD-R have not been tested yet. If no Incremental Streaming feature (21h)
|
DVD-R have not been tested yet. If no Incremental Streaming feature (21h)
|
||||||
is offered, then the media is regarded as unsuitable without further
|
is offered, then the media is regarded as unsuitable without further
|
||||||
explanation. (One can torture DVD-RW to make them offer only DAO (2Fh)).
|
explanation. (One can torture DVD-RW to make them offer only DAO (2Fh)).
|
||||||
Only single-track sessions have been tested yet. Multi-session works but
|
Multi-session works, but -toc is not implemented yet. -msinfo works although
|
||||||
-toc and -msinfo are not implemented yet.
|
otherwise predicted by MMC-3 to MMC-5. Be mistrusting when appending a third
|
||||||
|
session for the first time with your drive.
|
||||||
.br
|
.br
|
||||||
---------------
|
---------------
|
||||||
.br
|
.br
|
||||||
@ -165,6 +166,8 @@ It resembles much TAO writing with CD, as it allows track sources of
|
|||||||
unpredicted length and to keep media appendable by option
|
unpredicted length and to keep media appendable by option
|
||||||
.B -multi .
|
.B -multi .
|
||||||
Only restriction towards CD-RW is the lack of support for -audio tracks.
|
Only restriction towards CD-RW is the lack of support for -audio tracks.
|
||||||
|
Multiple tracks per session are permissible. A reasonable use case for
|
||||||
|
this has still to be found, though.
|
||||||
.br
|
.br
|
||||||
(The other write mode, DAO, is not implemented yet. It will allow no -multi and
|
(The other write mode, DAO, is not implemented yet. It will allow no -multi and
|
||||||
only a single track.)
|
only a single track.)
|
||||||
|
@ -127,6 +127,9 @@ or
|
|||||||
#ifdef Cdrskin_libburn_0_3_1
|
#ifdef Cdrskin_libburn_0_3_1
|
||||||
#define Cdrskin_libburn_versioN "0.3.1"
|
#define Cdrskin_libburn_versioN "0.3.1"
|
||||||
#define Cdrskin_libburn_from_pykix_svN 1
|
#define Cdrskin_libburn_from_pykix_svN 1
|
||||||
|
|
||||||
|
#define Cdrskin_libburn_has_get_msc1 1
|
||||||
|
|
||||||
#endif /* Cdrskin_libburn_0_3_1 */
|
#endif /* Cdrskin_libburn_0_3_1 */
|
||||||
|
|
||||||
#ifndef Cdrskin_libburn_versioN
|
#ifndef Cdrskin_libburn_versioN
|
||||||
@ -3484,12 +3487,19 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
|
|||||||
s= burn_disc_get_status(drive);
|
s= burn_disc_get_status(drive);
|
||||||
if(s!=BURN_DISC_APPENDABLE) {
|
if(s!=BURN_DISC_APPENDABLE) {
|
||||||
Cdrskin_report_disc_status(skin,s,0);
|
Cdrskin_report_disc_status(skin,s,0);
|
||||||
fprintf(stderr,
|
fprintf(stderr,"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) discs\n");
|
||||||
"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) CD\n");
|
|
||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
}
|
}
|
||||||
disc= burn_drive_get_disc(drive);
|
disc= burn_drive_get_disc(drive);
|
||||||
if(disc==NULL) {
|
if(disc==NULL) {
|
||||||
|
|
||||||
|
#ifdef Cdrskin_libburn_has_get_msc1
|
||||||
|
/* No TOC available. Try to inquire directly. */
|
||||||
|
ret= burn_disc_get_msc1(drive,&lba);
|
||||||
|
if(ret>0)
|
||||||
|
goto obtain_nwa;
|
||||||
|
#endif /* Cdrskin_libburn_has_get_msc1 */
|
||||||
|
|
||||||
fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n");
|
fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n");
|
||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
}
|
}
|
||||||
@ -3506,6 +3516,7 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
|
|||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obtain_nwa:;
|
||||||
ret= Cdrskin_obtain_nwa(skin,&nwa,flag);
|
ret= Cdrskin_obtain_nwa(skin,&nwa,flag);
|
||||||
if(ret<=0) {
|
if(ret<=0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -4394,8 +4405,9 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
|||||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||||
was_still_default= 2; /* prevents trying of SAO if drive dislikes TAO*/
|
was_still_default= 2; /* prevents trying of SAO if drive dislikes TAO*/
|
||||||
} else if(profile_number==0x1a || profile_number==0x13 ||
|
} else if(profile_number==0x1a || profile_number==0x13 ||
|
||||||
profile_number==0x12) {
|
profile_number==0x12 ||
|
||||||
/* DVD+RW , DVD-RW Restricted Overwrite , DVD-RAM */
|
profile_number==0x11 || profile_number==0x14) {
|
||||||
|
/* DVD+RW, DVD-RW Restr. Overwrite, DVD-RAM, DVD-R, DVD-RW Sequential */
|
||||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||||
} else {
|
} else {
|
||||||
strcpy(skin->preskin->write_mode_name,"SAO");
|
strcpy(skin->preskin->write_mode_name,"SAO");
|
||||||
@ -4639,9 +4651,6 @@ burn_failed:;
|
|||||||
burn_write_opts_set_perform_opc(o, 0);
|
burn_write_opts_set_perform_opc(o, 0);
|
||||||
|
|
||||||
#ifdef Cdrskin_libburn_has_multI
|
#ifdef Cdrskin_libburn_has_multI
|
||||||
if(skin->multi)
|
|
||||||
fprintf(stderr,
|
|
||||||
"cdrskin: NOTE : Option -multi set. Media will be appendable.\n");
|
|
||||||
burn_write_opts_set_multi(o,skin->multi);
|
burn_write_opts_set_multi(o,skin->multi);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2007.01.31.130100"
|
#define Cdrskin_timestamP "2007.01.31.173611"
|
||||||
|
@ -1409,6 +1409,32 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A70131 : new API function */
|
||||||
|
int burn_disc_get_msc1(struct burn_drive *d, int *start)
|
||||||
|
{
|
||||||
|
int ret, trackno;
|
||||||
|
|
||||||
|
if (burn_drive_is_released(d)) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x0002011b,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Attempt to read track info from ungrabbed drive",
|
||||||
|
0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (d->busy != BURN_DRIVE_IDLE) {
|
||||||
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
d->global_index, 0x0002011c,
|
||||||
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
"Attempt to read track info from busy drive",
|
||||||
|
0, 0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = d->read_multi_session_c1(d, &trackno, start);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61202 : New API function */
|
/* ts A61202 : New API function */
|
||||||
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
|
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
|
||||||
{
|
{
|
||||||
|
@ -788,6 +788,16 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive,
|
|||||||
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||||
int trackno, int *lba, int *nwa);
|
int trackno, int *lba, int *nwa);
|
||||||
|
|
||||||
|
/* ts A70131 */
|
||||||
|
/** Read start lba of the first track in the last complete session.
|
||||||
|
This is the first parameter of mkisofs option -C. The second parameter
|
||||||
|
is nwa as obtained by burn_disc_track_lba_nwa() with trackno 0.
|
||||||
|
@param d The drive to query.
|
||||||
|
@param start_lba returns the start address of that track
|
||||||
|
@return <= 0 : failure, 1 = ok
|
||||||
|
*/
|
||||||
|
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
||||||
|
|
||||||
/* ts A61202 */
|
/* ts A61202 */
|
||||||
/** Tells the MMC Profile identifier of the loaded media. The drive must be
|
/** Tells the MMC Profile identifier of the loaded media. The drive must be
|
||||||
grabbed in order to get a non-zero result.
|
grabbed in order to get a non-zero result.
|
||||||
|
@ -84,6 +84,8 @@ Todo:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned char MMC_GET_MSINFO[] =
|
||||||
|
{ 0x43, 0, 1, 0, 0, 0, 0, 16, 0, 0 };
|
||||||
static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 };
|
static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 };
|
||||||
static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
|
static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
|
||||||
static unsigned char MMC_GET_DISC_INFO[] =
|
static unsigned char MMC_GET_DISC_INFO[] =
|
||||||
@ -421,6 +423,18 @@ void mmc_read_toc(struct burn_drive *d)
|
|||||||
|
|
||||||
mmc_function_spy("mmc_read_toc");
|
mmc_function_spy("mmc_read_toc");
|
||||||
memcpy(c.opcode, MMC_GET_TOC, sizeof(MMC_GET_TOC));
|
memcpy(c.opcode, MMC_GET_TOC, sizeof(MMC_GET_TOC));
|
||||||
|
if(!d->current_is_cd_profile) {
|
||||||
|
/* ts A70131 : MMC_GET_TOC uses Response Format 2
|
||||||
|
For DVD this fails with 5,24,00 */
|
||||||
|
/* One could try Response Format 0: mmc5r03.pdf 6.26.3.2 */
|
||||||
|
/* One could try
|
||||||
|
51h READ DISC INFORMATION and 52h READ TRACK INFORMATION
|
||||||
|
where 51h gives the number of tracks and 52h tells the
|
||||||
|
session number with each track. */
|
||||||
|
|
||||||
|
/* >>> One must do someting */;
|
||||||
|
|
||||||
|
}
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
c.oplen = sizeof(MMC_GET_TOC);
|
c.oplen = sizeof(MMC_GET_TOC);
|
||||||
c.page = &buf;
|
c.page = &buf;
|
||||||
@ -442,7 +456,7 @@ void mmc_read_toc(struct burn_drive *d)
|
|||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002010d,
|
0x0002010d,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Could not inquire TOC (non-blank DVD media ?)", 0,0);
|
"Could not inquire TOC", 0,0);
|
||||||
d->status = BURN_DISC_UNSUITABLE;
|
d->status = BURN_DISC_UNSUITABLE;
|
||||||
d->toc_entries = 0;
|
d->toc_entries = 0;
|
||||||
/* Prefering memory leaks over fandangos */
|
/* Prefering memory leaks over fandangos */
|
||||||
@ -541,6 +555,47 @@ void mmc_read_toc(struct burn_drive *d)
|
|||||||
toc_find_modes(d);
|
toc_find_modes(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A70131 : If no TOC is at hand, this tries to get the start of the
|
||||||
|
last complete session (mksifs -c first parameter) */
|
||||||
|
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||||
|
{
|
||||||
|
struct buffer buf;
|
||||||
|
struct command c;
|
||||||
|
unsigned char *tdata;
|
||||||
|
|
||||||
|
mmc_function_spy("mmc_read_multi_session_c");
|
||||||
|
|
||||||
|
/* mmc5r03.pdf 6.26.3.3.3 states that with non-CD this would
|
||||||
|
be a useless fake always starting at track 1, lba 0.
|
||||||
|
My drives return useful data, though.
|
||||||
|
MMC-3 states that DVD had not tracks. So maybe this fake is
|
||||||
|
a legacy ?
|
||||||
|
|
||||||
|
>>> Possibly one will have to fake this reply from
|
||||||
|
51h READ DISC INFORMATION and 52h READ TRACK INFORMATION
|
||||||
|
(I still have to find out what growisofs is using)
|
||||||
|
*/
|
||||||
|
memcpy(c.opcode, MMC_GET_MSINFO, sizeof(MMC_GET_MSINFO));
|
||||||
|
c.retry = 1;
|
||||||
|
c.oplen = sizeof(MMC_GET_MSINFO);
|
||||||
|
c.page = &buf;
|
||||||
|
c.page->bytes = 0;
|
||||||
|
c.page->sectors = 0;
|
||||||
|
c.dir = FROM_DRIVE;
|
||||||
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
|
if (c.error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
tdata = c.page->data + 4;
|
||||||
|
*trackno = tdata[2];
|
||||||
|
*start = (tdata[4] << 24) | (tdata[5] << 16)
|
||||||
|
| (tdata[6] << 8) | tdata[7];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mmc_read_disc_info(struct burn_drive *d)
|
void mmc_read_disc_info(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
@ -1806,6 +1861,7 @@ int mmc_setup_drive(struct burn_drive *d)
|
|||||||
d->send_cue_sheet = mmc_send_cue_sheet;
|
d->send_cue_sheet = mmc_send_cue_sheet;
|
||||||
d->sync_cache = mmc_sync_cache;
|
d->sync_cache = mmc_sync_cache;
|
||||||
d->get_nwa = mmc_get_nwa;
|
d->get_nwa = mmc_get_nwa;
|
||||||
|
d->read_multi_session_c1 = mmc_read_multi_session_c1;
|
||||||
d->close_disc = mmc_close_disc;
|
d->close_disc = mmc_close_disc;
|
||||||
d->close_session = mmc_close_session;
|
d->close_session = mmc_close_session;
|
||||||
d->close_track_session = mmc_close;
|
d->close_track_session = mmc_close;
|
||||||
|
@ -250,6 +250,11 @@ struct burn_drive
|
|||||||
int (*get_erase_progress) (struct burn_drive *);
|
int (*get_erase_progress) (struct burn_drive *);
|
||||||
int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa);
|
int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa);
|
||||||
|
|
||||||
|
/* ts A70131 : obtain (possibly fake) TOC number and start lba of
|
||||||
|
first track in last complete session */
|
||||||
|
int (*read_multi_session_c1)(struct burn_drive *d,
|
||||||
|
int *trackno, int *start);
|
||||||
|
|
||||||
/* ts A61009 : removed d in favor of o->drive */
|
/* ts A61009 : removed d in favor of o->drive */
|
||||||
/* void (*close_disc) (struct burn_drive * d,
|
/* void (*close_disc) (struct burn_drive * d,
|
||||||
struct burn_write_opts * o);
|
struct burn_write_opts * o);
|
||||||
|
Loading…
Reference in New Issue
Block a user