Make mmc_read_multi_session_c1 use TOC if available

This commit is contained in:
Thomas Schmitt 2007-02-02 15:11:35 +00:00
parent a769f8aa87
commit 4e93de2cd2
3 changed files with 51 additions and 49 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.02.01.191638" #define Cdrskin_timestamP "2007.02.02.151327"

View File

@ -786,28 +786,59 @@ void mmc_read_toc(struct burn_drive *d)
} }
/* ts A70131 : If no TOC is at hand, this tries to get the start of the /* ts A70131 : This tries to get the start of the last complete session */
last complete session (mksifs -c first parameter) */ /* man mkisofs , option -C :
The first number is the sector number of the first sector in
the last session of the disk that should be appended to.
*/
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start) int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
{ {
struct buffer buf; struct buffer buf;
struct command c; struct command c;
unsigned char *tdata; unsigned char *tdata;
int num_sessions, session_no, num_tracks;
struct burn_disc *disc;
struct burn_session **sessions;
struct burn_track **tracks;
struct burn_toc_entry toc_entry;
mmc_function_spy("mmc_read_multi_session_c"); mmc_function_spy("mmc_read_multi_session_c1");
/* First try to evaluate the eventually loaded TOC before issueing
a MMC command. This search obtains the first track of the last
complete session which has a track.
*/
*trackno = 0;
disc = burn_drive_get_disc(d);
if (disc == NULL)
goto inquire_drive;
sessions = burn_disc_get_sessions(disc, &num_sessions);
for (session_no = 0; session_no<num_sessions; session_no++) {
tracks = burn_session_get_tracks(sessions[session_no],
&num_tracks);
if (tracks == NULL || num_tracks <= 0)
continue;
burn_track_get_entry(tracks[0], &toc_entry);
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
*start = toc_entry.start_lba;
*trackno = (toc_entry.point_msb << 8)| toc_entry.point;
} else {
*start = burn_msf_to_lba(toc_entry.pmin,
toc_entry.psec, toc_entry.pframe);
*trackno = toc_entry.point;
}
}
burn_disc_free(disc);
if(*trackno > 0)
return 1;
inquire_drive:;
/* mmc5r03.pdf 6.26.3.3.3 states that with non-CD this would /* 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. be a useless fake always starting at track 1, lba 0.
My drives return useful data, though. My drives return useful data, though.
MMC-3 states that DVD had not tracks. So maybe this fake is MMC-3 states that DVD had no tracks. So maybe this mandatory fake
a legacy ? is a forgotten legacy ?
*/ */
/* >>>
mmc_fake_toc() meanwhile tries to establish a useable TOC.
Evaluate this first before issueing a MMC command.
*/
memcpy(c.opcode, MMC_GET_MSINFO, sizeof(MMC_GET_MSINFO)); memcpy(c.opcode, MMC_GET_MSINFO, sizeof(MMC_GET_MSINFO));
c.retry = 1; c.retry = 1;
c.oplen = sizeof(MMC_GET_MSINFO); c.oplen = sizeof(MMC_GET_MSINFO);
@ -822,8 +853,7 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
tdata = c.page->data + 4; tdata = c.page->data + 4;
*trackno = tdata[2]; *trackno = tdata[2];
*start = (tdata[4] << 24) | (tdata[5] << 16) *start = mmc_four_char_to_int(tdata + 4);
| (tdata[6] << 8) | tdata[7];
return 1; return 1;
} }

View File

@ -437,13 +437,8 @@ int telltoc_toc(struct burn_drive *drive)
int telltoc_msinfo(struct burn_drive *drive, int telltoc_msinfo(struct burn_drive *drive,
int msinfo_explicit, int msinfo_alone) int msinfo_explicit, int msinfo_alone)
{ {
int num_sessions, session_no, ret, num_tracks; int ret, lba, nwa = -123456789, aux_lba;
int nwa = -123456789, lba = -123456789, aux_lba, lout_lba;
enum burn_disc_status s; enum burn_disc_status s;
struct burn_disc *disc= NULL;
struct burn_session **sessions;
struct burn_track **tracks;
struct burn_toc_entry toc_entry;
struct burn_write_opts *o= NULL; struct burn_write_opts *o= NULL;
s = burn_disc_get_status(drive); s = burn_disc_get_status(drive);
@ -459,29 +454,12 @@ int telltoc_msinfo(struct burn_drive *drive,
The first number is the sector number of the first sector in The first number is the sector number of the first sector in
the last session of the disk that should be appended to. the last session of the disk that should be appended to.
*/ */
disc = burn_drive_get_disc(drive); ret = burn_disc_get_msc1(drive, &lba);
if (disc==NULL) { if (ret <= 0) {
fprintf(stderr,"SORRY: Cannot obtain info about CD content\n"); fprintf(stderr,
return 2; "SORRY: Cannot obtain start address of last session\n");
}
sessions = burn_disc_get_sessions(disc, &num_sessions);
for (session_no = 0; session_no<num_sessions; session_no++) {
tracks = burn_session_get_tracks(sessions[session_no],
&num_tracks);
if (tracks==NULL || num_tracks<=0)
continue;
burn_track_get_entry(tracks[0], &toc_entry);
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
toc_entry.pframe);
}
if(lba==-123456789) {
fprintf(stderr,"SORRY: Cannot find any track on media\n");
{ ret = 0; goto ex; } { ret = 0; goto ex; }
} }
/* Prepare a qualified guess as fallback for nwa inquiry */
burn_session_get_leadout_entry(sessions[num_sessions-1], &toc_entry);
lout_lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,
toc_entry.pframe);
/* man mkisofs , option -C : /* man mkisofs , option -C :
The second number is the starting sector number of the new session. The second number is the starting sector number of the new session.
@ -498,21 +476,15 @@ int telltoc_msinfo(struct burn_drive *drive,
telltoc_regrab(drive); /* necessary to calm down my NEC drive */ telltoc_regrab(drive); /* necessary to calm down my NEC drive */
if(ret<=0) { if(ret<=0) {
fprintf(stderr, fprintf(stderr,
"NOTE: Guessing next writeable address from leadout\n"); "SORRY: Cannot obtain next writeable address\n");
if(num_sessions>0) { ret = 0; goto ex; }
nwa= lout_lba+6900;
else
nwa= lout_lba+11400;
} }
if (!msinfo_alone) if (!msinfo_alone)
printf("Media msinfo : mkisofs ... -C "); printf("Media msinfo : mkisofs ... -C ");
printf("%d,%d\n",lba,nwa); printf("%d,%d\n",lba,nwa);
ret = 1; ret = 1;
ex:; ex:;
if (disc!=NULL)
burn_disc_free(disc);
if (o!=NULL) if (o!=NULL)
burn_write_opts_free(o); burn_write_opts_free(o);
return ret; return ret;