New API call burn_write_opts_set_leadin_text()

This commit is contained in:
2011-12-05 20:36:31 +00:00
parent b385a3863e
commit 7be652ac6b
9 changed files with 281 additions and 19 deletions

View File

@ -1310,8 +1310,8 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
0x8f = binary: Size Information of the Block
The second byte tells the track number to which the first text piece in
a pack is associated. Number 0 means the whole album. Higher numbers are
valid for types 0x80 to 0x85, and 0x8e. There should be one text for each
track with these types.
valid for types 0x80 to 0x85, and 0x8e. With these types, there should be
one text for the disc and one for each track.
The third byte is a sequential counter.
The fourth byte is the Block Number and Character Position Indicator.
It consists of three bit fields:
@ -1321,13 +1321,14 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
the current text inherited from the previous pack, or
15 if the current text started before the previous pack.
The two CRC bytes are optional. Polynomial is x^16 + x^12 + x^5 + 1.
"All bits shall be inverted."
@param d The drive to query.
@param text_packs Will point to an allocated memory buffer with CD-TEXT.
It will only contain text packs, and not be prepended
by the TOC header of four bytes, which gets stored with
file cdtext.dat by cdrecord -vv -toc. The first two of
these bytes are supposed hold the number of CD-TEXT
these bytes are supposed to hold the number of CD-TEXT
bytes + 2. The other two bytes are supposed to be 0.
Dispose this buffer by free(), when no longer needed.
@param num_packs Will tell the number of text packs, i.e. the number of
@ -2431,6 +2432,23 @@ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned cha
*/
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts B11204 */
/** Submit an array of CD-TEXT packs which shall be written to the Lead-in
of a SAO write run on CD.
@param opts The option object to be manipulated
@param text_packs Array of bytes which form CD-TEXT packs of 18 bytes
each. See burn_disc_get_leadin_text() for a description
of the text pack format.
No header of 4 bytes must be prepended which would
tell the number of pack bytes + 2.
@param num_packs The number of 18 byte packs in text_packs.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return 1 on success, <= 0 on failure
@since 1.2.0
*/
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag);
/* ts A61222 */
/** Sets a start address for writing to media and write modes which allow to

View File

@ -154,6 +154,7 @@ burn_write_opts_set_fillup;
burn_write_opts_set_force;
burn_write_opts_set_format;
burn_write_opts_set_has_mediacatalog;
burn_write_opts_set_leadin_text;
burn_write_opts_set_mediacatalog;
burn_write_opts_set_multi;
burn_write_opts_set_perform_opc;

View File

@ -577,6 +577,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled.
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -945,7 +945,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
#ifdef Libburn_log_in_and_out_streaM
/* <<< ts A61031 */
if(tee_fd!=-1) {
write(tee_fd,c->page->data,len*2048);
write(tee_fd, c->page->data, c->page->bytes);
}
#endif /* Libburn_log_in_and_out_streaM */

View File

@ -12,6 +12,7 @@
#include "options.h"
#include "drive.h"
#include "transport.h"
#include "init.h"
/* ts A61007 */
/* #include <a ssert.h> */
@ -51,6 +52,8 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->do_stream_recording = 0;
opts->dvd_obs_override = 0;
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
opts->text_packs = NULL;
opts->num_text_packs = 0;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
@ -60,8 +63,11 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
void burn_write_opts_free(struct burn_write_opts *opts)
{
if (--opts->refcount <= 0)
free(opts);
if (--opts->refcount > 0)
return;
if (opts->text_packs != NULL)
free(opts->text_packs);
free(opts);
}
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
@ -189,6 +195,41 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
}
/* ts B11204 */
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag)
{
int ret;
unsigned char *pack_buffer = NULL;
if (num_packs > 3640) {
/* READ TOC/PMA/ATIP can at most return 3640.7 packs */
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
0x0002018b,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Too many CD-TEXT packs (> 3640)", 0, 0);
ret= 0; goto ex;
}
if (num_packs > 0)
BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18);
if (opts->text_packs != NULL) {
free(opts->text_packs);
opts->text_packs = NULL;
}
if (num_packs > 0) {
memcpy(pack_buffer, text_packs, num_packs * 18);
opts->text_packs = pack_buffer;
}
opts->num_text_packs = num_packs;
ret = 1;
ex:;
return ret;
}
/* ts A61222 */
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
{
@ -296,6 +337,10 @@ do_sao:;
{wt = BURN_WRITE_SAO; goto ex;}
no_sao:;
try_tao:;
if (opts->num_text_packs > 0) {
strcat(reasons, "CD-TEXT: write type SAO required, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
goto try_raw;
reason_pt = reasons + strlen(reasons);

View File

@ -69,6 +69,9 @@ struct burn_write_opts
Values 0 or >= 32 counted in 2 KB blocks. */
int stdio_fsync_size;
/* ts B11203 : CD-TEXT */
unsigned char *text_packs;
int num_text_packs;
/** A disc can have a media catalog number */
int has_mediacatalog;

View File

@ -368,6 +368,7 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
int nwa)
{
int i, m, s, f, form, pform, runtime = -150, ret, track_length;
int leadin_form;
unsigned char ctladr;
struct burn_drive *d;
struct burn_toc_entry *e;
@ -404,7 +405,11 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
"Track mode has unusable value", 0, 0);
goto failed;
}
ret = add_cue(sheet, ctladr | 1, 0, 0, 1, 0, runtime);
if (o->num_text_packs > 0)
leadin_form = 0x41;
else
leadin_form = 0x01;
ret = add_cue(sheet, ctladr | 1, 0, 0, leadin_form, 0, runtime);
if (ret <= 0)
goto failed;
ret = add_cue(sheet, ctladr | 1, 1, 0, form, 0, runtime);
@ -650,11 +655,110 @@ int burn_write_leadout(struct burn_write_opts *o,
return 1;
}
int burn_write_leadin_cdtext(struct burn_write_opts *o, struct burn_session *s,
int flag)
{
int ret, i, j, si, lba, sub_cursor = 0, err, write_lba, sectors = 0;
unsigned char *subdata = NULL;
struct burn_drive *d = o->drive;
struct buffer *buf = NULL;
enum burn_drive_status was_busy;
#ifdef Libburn_debug_cd_texT
unsigned char *packs;
#endif
if (o->num_text_packs <= 0)
{ret = 1; goto ex;}
was_busy = d->busy;
d->busy = BURN_DRIVE_WRITING_LEADIN;
#ifdef Libburn_debug_cd_texT
packs = o->text_packs;
fprintf(stderr,
"libburn_DEBUG: 8 bit CD-TEXT packs to be transmitted:\n");
for (i = 0; i < 18 * o->num_text_packs; i += 18) {
fprintf(stderr, "%4d :", i / 18);
for (j = 0; j < 18; j++) {
if (j >= 4 && j <= 15 && packs[i + j] >= 32 &&
packs[i + j] <= 126 && packs[i] != 0x88 &&
packs[i] != 0x89 && packs[i] != 0x8f)
fprintf(stderr, " %c", packs[i + j]);
else
fprintf(stderr, " %2.2X", packs[i + j]);
}
fprintf(stderr, "\n");
}
#endif /* Libburn_debug_cd_texT */
/* Chop from 8 bit text pack to 6 bit subchannel */
BURN_ALLOC_MEM(subdata, unsigned char, o->num_text_packs * 24);
for (i = 0; i < 18 * o->num_text_packs; i += 3) {
si = i / 3 * 4;
subdata[si + 0] = (o->text_packs[i + 0] >> 2) & 0x3f;
subdata[si + 1] = (o->text_packs[i + 0] << 4) & 0x30;
subdata[si + 1] |= (o->text_packs[i + 1] >> 4) & 0x0f;
subdata[si + 2] = (o->text_packs[i + 1] << 2) & 0x3c;
subdata[si + 2] |= (o->text_packs[i + 2] >> 6) & 0x03;
subdata[si + 3] = (o->text_packs[i + 2] >> 0) & 0x3f;
}
/* Start at Lead-in address of ATIP and write blocks up to -150 */
BURN_ALLOC_MEM(buf, struct buffer, 1);
write_lba = d->start_lba;
for (lba = d->start_lba; lba < -150; lba++) {
/* Collect subdata in buf */
for (j = 0; j < 4; j++) {
memcpy(buf->data + buf->bytes,
subdata + sub_cursor * 24, 24);
sub_cursor = (sub_cursor + 1) % o->num_text_packs;
buf->bytes += 24;
}
buf->sectors++;
sectors++;
/* When full or last sector : perform WRITE */
if (buf->bytes + 96 >= 32768 || lba == -151) {
#ifdef Libburn_debug_cd_texT
fprintf(stderr,
"libburn_DEBUG: 6 bit data to be transmitted:\n");
for (i = 0; i < buf->bytes; i += 24) {
fprintf(stderr, "%4d :", i / 24);
for (j = 0; j < 24; j++)
fprintf(stderr, " %2.2X",
buf->data[i + j]);
fprintf(stderr, "\n");
}
#endif /* Libburn_debug_cd_texT */
err = d->write(d, write_lba, buf);
if (err == BE_CANCELLED)
{ ret = 0; goto ex; }
write_lba += sectors;
sectors = buf->sectors = buf->bytes = 0;
}
}
ret = 1;
ex:;
BURN_FREE_MEM(subdata);
BURN_FREE_MEM(buf);
d->busy = was_busy;
return ret;
}
int burn_write_session(struct burn_write_opts *o, struct burn_session *s)
{
struct burn_drive *d = o->drive;
int i, ret;
if (o->write_type == BURN_WRITE_SAO) {
ret = burn_write_leadin_cdtext(o, s, 0);
if (ret <= 0)
goto ex;
}
d->rlba = 0;
for (i = 0; i < s->tracks; i++) {
if (!burn_write_track(o, s, i))
@ -1001,6 +1105,10 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
reason_pt= reasons + strlen(reasons);
if (d->status == BURN_DISC_UNSUITABLE)
goto unsuitable_profile;
if (d->current_profile != 0x09 && d->current_profile != 0x0a)
if (o->num_text_packs > 0)
strcat(reasons,
"CD-TEXT supported only with write CD media, ");
if (d->drive_role == 2 || d->drive_role == 5 ||
d->current_profile == 0x1a || d->current_profile == 0x12 ||
d->current_profile == 0x43) {
@ -1014,6 +1122,14 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
strcat(reasons, "unsuitable track mode found, ");
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
if (o->num_text_packs > 0) {
if (o->write_type != BURN_WRITE_SAO)
strcat(reasons,
"CD-TEXT supported only with write type SAO, ");
if (d->start_lba == -2000000000)
strcat(reasons,
"No Lead-in start address known with CD-TEXT, ");
}
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
if (o->start_byte >= 0 && (o->start_byte % 32768))