Augmented struct burn_toc_entry by new off_t block addresses and counters
This commit is contained in:
parent
069b4edecd
commit
17a020e9fc
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2024.02.26.150632"
|
||||
#define Cdrskin_timestamP "2024.02.27.194737"
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2023 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
|
||||
This is the official API definition of libburn.
|
||||
@ -9,6 +9,8 @@
|
||||
*/
|
||||
/* Important: If you add a public API function then add its name to file
|
||||
libburn/libburn.ver
|
||||
in the node LIBBURN4_Major.Minor.Micro with the numbers of
|
||||
the next release version, citing the previous node.
|
||||
*/
|
||||
|
||||
|
||||
@ -376,6 +378,9 @@ struct burn_toc_entry
|
||||
@since 0.5.2 : DVD extensions are made valid for CD too
|
||||
bit1= LRA extension is valid @since 0.7.2
|
||||
bit2= Track status bits extension is valid @since 1.2.8
|
||||
bit3= Long block address is valid:
|
||||
long_start_lba, long_track_blocks, long_last_rec_adr
|
||||
@since 1.5.8
|
||||
*/
|
||||
unsigned char extensions_valid;
|
||||
|
||||
@ -386,8 +391,10 @@ struct burn_toc_entry
|
||||
unsigned char session_msb;
|
||||
unsigned char point_msb;
|
||||
/* pmin, psec, and pframe may be too small if DVD extension is valid */
|
||||
/* -1 means that only long_start_lba is valid */
|
||||
int start_lba;
|
||||
/* min, sec, and frame may be too small if DVD extension is valid */
|
||||
/* -1 means that only long_track_blocks is valid */
|
||||
int track_blocks;
|
||||
|
||||
/* ts A90909 : LRA extension. extensions_valid:bit1 */
|
||||
@ -396,6 +403,7 @@ struct burn_toc_entry
|
||||
DVD-R DL when LJRS = 00b, DVD-RW, HD DVD-R, and BD-R.
|
||||
This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42
|
||||
*/
|
||||
/* -1 means that only long_last_rec_adr is valid */
|
||||
int last_recorded_address;
|
||||
|
||||
/* ts B30112 : Track status bits extension. extensions_valid:bit2 */
|
||||
@ -415,6 +423,12 @@ struct burn_toc_entry
|
||||
*/
|
||||
int track_status_bits;
|
||||
|
||||
/* ts C40221 : Long block address extension. extensions_valid:bit3 */
|
||||
/* @since 1.5.8 */
|
||||
off_t long_start_lba;
|
||||
off_t long_track_blocks;
|
||||
off_t long_last_rec_adr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
133
libburn/mmc.c
133
libburn/mmc.c
@ -300,6 +300,14 @@ int mmc_four_char_to_int(unsigned char *data)
|
||||
}
|
||||
|
||||
|
||||
/* ts C40226 */
|
||||
unsigned int mmc_four_char_to_uint(unsigned char *data)
|
||||
{
|
||||
return (((unsigned int) data[0]) << 24) | (data[1] << 16) |
|
||||
(data[2] << 8) | data[3];
|
||||
}
|
||||
|
||||
|
||||
/* ts A70201 */
|
||||
int mmc_int_to_four_char(unsigned char *data, int num)
|
||||
{
|
||||
@ -311,6 +319,17 @@ int mmc_int_to_four_char(unsigned char *data, int num)
|
||||
}
|
||||
|
||||
|
||||
/* ts C40226 */
|
||||
int mmc_uint_to_four_char(unsigned char *data, unsigned int num)
|
||||
{
|
||||
data[0] = (num >> 24) & 0xff;
|
||||
data[1] = (num >> 16) & 0xff;
|
||||
data[2] = (num >> 8) & 0xff;
|
||||
data[3] = num & 0xff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int mmc_start_for_bit0 = 0;
|
||||
|
||||
/* @param flag bit0= the calling function should need no START UNIT.
|
||||
@ -1087,10 +1106,11 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
||||
unsigned char *size_data, unsigned char *start_data,
|
||||
unsigned char *last_adr_data)
|
||||
{
|
||||
int min, sec, frames, num;
|
||||
int min, sec, frames;
|
||||
unsigned int num;
|
||||
|
||||
/* mark DVD extensions and Track Info extension as valid */
|
||||
entry->extensions_valid |= (1 | 2);
|
||||
/* mark extensions as valid: DVD, Track Info, Long block address */
|
||||
entry->extensions_valid |= (1 | 2 | 8);
|
||||
|
||||
/* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
|
||||
entry->session = session_number & 0xff;
|
||||
@ -1100,9 +1120,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
||||
entry->tno = 0;
|
||||
entry->point = track_number & 0xff;
|
||||
entry->point_msb = (track_number >> 8) & 0xff;
|
||||
num = mmc_four_char_to_int(size_data);
|
||||
num = mmc_four_char_to_uint(size_data);
|
||||
if (num < 0x80000000) {
|
||||
entry->track_blocks = num;
|
||||
burn_lba_to_msf(num, &min, &sec, &frames);
|
||||
} else {
|
||||
entry->track_blocks = -1;
|
||||
min = 477218; /* ~=LBA 0x7fffffff */
|
||||
sec = frames = 0;
|
||||
}
|
||||
entry->long_track_blocks = num;
|
||||
if (min > 255) {
|
||||
min = 255;
|
||||
sec = 255;
|
||||
@ -1112,9 +1139,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
||||
entry->sec = sec;
|
||||
entry->frame = frames;
|
||||
entry->zero = 0;
|
||||
num = mmc_four_char_to_int(start_data);
|
||||
num = mmc_four_char_to_uint(start_data);
|
||||
if (num < 0x80000000) {
|
||||
entry->start_lba = num;
|
||||
burn_lba_to_msf(num, &min, &sec, &frames);
|
||||
} else {
|
||||
entry->start_lba = -1;
|
||||
min = 477218;
|
||||
sec = frames = 0;
|
||||
}
|
||||
entry->long_start_lba = num;
|
||||
if (min > 255) {
|
||||
min = 255;
|
||||
sec = 255;
|
||||
@ -1123,7 +1157,13 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
||||
entry->pmin = min;
|
||||
entry->psec = sec;
|
||||
entry->pframe = frames;
|
||||
entry->last_recorded_address = mmc_four_char_to_int(last_adr_data);
|
||||
num = mmc_four_char_to_uint(last_adr_data);
|
||||
if (num < 0x80000000) {
|
||||
entry->last_recorded_address = num;
|
||||
} else {
|
||||
entry->last_recorded_address = -1;
|
||||
}
|
||||
entry->long_last_rec_adr = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1137,7 +1177,7 @@ static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
|
||||
struct buffer *buf = NULL;
|
||||
struct command *c = NULL;
|
||||
int dlen, i, old_alloc_len, session_number, prev_session = -1, ret;
|
||||
int lba, size;
|
||||
unsigned int lba, size;
|
||||
unsigned char *tdata, size_data[4], start_data[4], end_data[4];
|
||||
|
||||
if (*alloc_len < 4)
|
||||
@ -1216,11 +1256,11 @@ err_ex:;
|
||||
if (session_number != prev_session && prev_session > 0) {
|
||||
/* leadout entry previous session */
|
||||
entry = &(d->toc_entry[(i - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data, lba - 1);
|
||||
lba = mmc_four_char_to_uint(start_data) +
|
||||
mmc_four_char_to_uint(size_data);
|
||||
mmc_uint_to_four_char(start_data, lba);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data, lba - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
@ -1245,11 +1285,11 @@ err_ex:;
|
||||
memcpy(start_data, tdata + 4, 4);
|
||||
/* size_data are estimated from next track start */
|
||||
memcpy(size_data, tdata + 8 + 4, 4);
|
||||
mmc_int_to_four_char(end_data,
|
||||
mmc_four_char_to_int(size_data) - 1);
|
||||
size = mmc_four_char_to_int(size_data) -
|
||||
mmc_four_char_to_int(start_data);
|
||||
mmc_int_to_four_char(size_data, size);
|
||||
mmc_uint_to_four_char(end_data,
|
||||
mmc_four_char_to_uint(size_data) - 1);
|
||||
size = mmc_four_char_to_uint(size_data) -
|
||||
mmc_four_char_to_uint(start_data);
|
||||
mmc_uint_to_four_char(size_data, size);
|
||||
mmc_fake_toc_entry(entry, session_number, i + 1,
|
||||
size_data, start_data, end_data);
|
||||
if (prev_session != session_number)
|
||||
@ -1262,9 +1302,9 @@ err_ex:;
|
||||
tdata = c->page->data + 4 + d->last_track_no * 8;
|
||||
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
|
||||
memcpy(start_data, tdata + 4, 4);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data,
|
||||
mmc_four_char_to_int(start_data) - 1);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data,
|
||||
mmc_four_char_to_uint(start_data) - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
@ -1301,7 +1341,8 @@ int mmc_fake_toc(struct burn_drive *d)
|
||||
struct burn_session *session;
|
||||
struct burn_toc_entry *entry;
|
||||
struct buffer *buf = NULL;
|
||||
int i, session_number, prev_session = -1, ret, lba, alloc_len = 34;
|
||||
int i, session_number, prev_session = -1, ret, alloc_len = 34;
|
||||
unsigned int lba;
|
||||
unsigned char *tdata, size_data[4], start_data[4], end_data[4];
|
||||
char *msg = NULL;
|
||||
|
||||
@ -1406,11 +1447,11 @@ int mmc_fake_toc(struct burn_drive *d)
|
||||
if (session_number != prev_session && prev_session > 0) {
|
||||
/* leadout entry previous session */
|
||||
entry = &(d->toc_entry[(i - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data, lba - 1);
|
||||
lba = mmc_four_char_to_uint(start_data) +
|
||||
mmc_four_char_to_uint(size_data);
|
||||
mmc_uint_to_four_char(start_data, lba);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data, lba - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
@ -1431,7 +1472,7 @@ int mmc_fake_toc(struct burn_drive *d)
|
||||
if (i == d->last_track_no - 1) {
|
||||
/* ts A70212 : Last track field Free Blocks */
|
||||
burn_drive_set_media_capacity_remaining(d,
|
||||
((off_t) mmc_four_char_to_int(tdata + 16)) *
|
||||
((off_t) mmc_four_char_to_uint(tdata + 16)) *
|
||||
((off_t) 2048));
|
||||
d->media_lba_limit = 0;
|
||||
}
|
||||
@ -1477,11 +1518,11 @@ int mmc_fake_toc(struct burn_drive *d)
|
||||
if (prev_session > 0 && prev_session <= d->disc->sessions) {
|
||||
/* leadout entry of last session of closed disc */
|
||||
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data, lba - 1);
|
||||
lba = mmc_four_char_to_uint(start_data) +
|
||||
mmc_four_char_to_uint(size_data);
|
||||
mmc_uint_to_four_char(start_data, lba);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data, lba - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
@ -1774,12 +1815,12 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
}
|
||||
|
||||
|
||||
/* ts A70131 : This tries to get the start of the last complete session */
|
||||
/* ts C40226 : long address reply version of mmc_read_multi_session_c1 */
|
||||
/* 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_msc1_long(struct burn_drive *d, int *trackno, off_t *start)
|
||||
{
|
||||
struct buffer *buf = NULL;
|
||||
struct command *c = NULL;
|
||||
@ -1812,7 +1853,11 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||
continue;
|
||||
burn_track_get_entry(tracks[0], &toc_entry);
|
||||
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
|
||||
if (toc_entry.extensions_valid & 8) { /* Long adr */
|
||||
*start = toc_entry.long_start_lba;
|
||||
} else {
|
||||
*start = toc_entry.start_lba;
|
||||
}
|
||||
*trackno = (toc_entry.point_msb << 8)| toc_entry.point;
|
||||
} else {
|
||||
*start = burn_msf_to_lba(toc_entry.pmin,
|
||||
@ -1847,7 +1892,7 @@ inquire_drive:;
|
||||
|
||||
tdata = c->page->data + 4;
|
||||
*trackno = tdata[2];
|
||||
*start = mmc_four_char_to_int(tdata + 4);
|
||||
*start = mmc_four_char_to_uint(tdata + 4);
|
||||
ret = 1;
|
||||
ex:;
|
||||
BURN_FREE_MEM(buf);
|
||||
@ -1856,6 +1901,24 @@ ex:;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70131 : This tries to get the start of the last complete session */
|
||||
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||
{
|
||||
int ret;
|
||||
off_t num;
|
||||
|
||||
ret = mmc_read_msc1_long(d, trackno, &num);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if(num >= 0x80000000) {
|
||||
*start = 0x7fffffff;
|
||||
return 0;
|
||||
}
|
||||
*start = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61201 */
|
||||
char *mmc_obtain_profile_name(int profile_number)
|
||||
{
|
||||
|
@ -78,6 +78,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
|
||||
/* ts A70201 */
|
||||
int mmc_four_char_to_int(unsigned char *data);
|
||||
/* ts C40226 */
|
||||
unsigned int mmc_four_char_to_uint(unsigned char *data);
|
||||
|
||||
/* ts A70201 :
|
||||
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
|
||||
|
@ -768,7 +768,7 @@ int burn_session_get_hidefirst(struct burn_session *session)
|
||||
}
|
||||
|
||||
|
||||
/* ts A80808 : Enhance CD toc to DVD toc */
|
||||
/* ts A80808,C40226 : Enhance CD toc to DVD toc with Long block addresses */
|
||||
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
|
||||
{
|
||||
int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34;
|
||||
@ -836,6 +836,7 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
|
||||
entry->point_msb = 0;
|
||||
entry->start_lba = burn_msf_to_lba(entry->pmin,
|
||||
entry->psec, entry->pframe);
|
||||
entry->long_start_lba = entry->start_lba;
|
||||
if (tidx > 0) {
|
||||
prev_entry->track_blocks =
|
||||
entry->start_lba
|
||||
@ -855,13 +856,16 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
|
||||
ret < prev_entry->track_blocks - 2))
|
||||
prev_entry->track_blocks = ret;
|
||||
}
|
||||
prev_entry->extensions_valid |= 1;
|
||||
prev_entry->long_track_blocks =
|
||||
prev_entry->track_blocks;
|
||||
prev_entry->extensions_valid |= 1 | 8;
|
||||
}
|
||||
if (tidx == d->session[sidx]->tracks) {
|
||||
entry->session_msb = 0;
|
||||
entry->point_msb = 0;
|
||||
entry->track_blocks = 0;
|
||||
entry->extensions_valid |= 1;
|
||||
entry->long_track_blocks = entry->track_blocks;
|
||||
entry->extensions_valid |= 1 | 8;
|
||||
}
|
||||
prev_entry = entry;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user