New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
This commit is contained in:
parent
738b83ac03
commit
79a33ca2ac
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2009.11.15.152541"
|
#define Cdrskin_timestamP "2009.11.15.153140"
|
||||||
|
@ -767,6 +767,9 @@ void burn_set_verbosity(int level);
|
|||||||
This call can be made at any time - even before burn_initialize().
|
This call can be made at any time - even before burn_initialize().
|
||||||
It is in effect for all active drives and currently not very thread
|
It is in effect for all active drives and currently not very thread
|
||||||
safe for multiple drives.
|
safe for multiple drives.
|
||||||
|
|
||||||
|
>>> ??? Shouldn't the file path with bit1 be adjustable ?
|
||||||
|
|
||||||
@param flag Bitfield for control purposes. The default is 0.
|
@param flag Bitfield for control purposes. The default is 0.
|
||||||
bit0= log to file /tmp/libburn_sg_command_log
|
bit0= log to file /tmp/libburn_sg_command_log
|
||||||
bit1= log to stderr
|
bit1= log to stderr
|
||||||
@ -2119,6 +2122,32 @@ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force);
|
|||||||
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
||||||
int value);
|
int value);
|
||||||
|
|
||||||
|
/* ts A91115 */
|
||||||
|
/** Overrides the write chunk size for DVD and BD media which is normally
|
||||||
|
determined according to media type and setting of stream recording.
|
||||||
|
A chunk size of 64 KB may improve throughput with bus systems which show
|
||||||
|
latency problems.
|
||||||
|
@param opts The write opts to change
|
||||||
|
@param obs Number of bytes which shall be sent by a single write command.
|
||||||
|
0 means automatic size, 32768 and 65336 are the only other
|
||||||
|
accepted sizes for now.
|
||||||
|
@since 0.7.4
|
||||||
|
*/
|
||||||
|
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs);
|
||||||
|
|
||||||
|
/* ts A91115 */
|
||||||
|
/** Sets the rythm by which stdio pseudo drives force their output data to
|
||||||
|
be consumed by the receiving storage device. This forcing keeps the memory
|
||||||
|
from being clogged with lots of pending data for slow devices.
|
||||||
|
@param opts The write opts to change
|
||||||
|
@param rythm Number of 2KB output blocks after which fsync(2) is
|
||||||
|
performed. -1 means no fsync(), 0 means default,
|
||||||
|
elsewise the value must be >= 32.
|
||||||
|
Default is currently 8192 = 16 MB.
|
||||||
|
@since 0.7.4
|
||||||
|
*/
|
||||||
|
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm);
|
||||||
|
|
||||||
|
|
||||||
/** Sets whether to read in raw mode or not
|
/** Sets whether to read in raw mode or not
|
||||||
@param opts The read opts to change
|
@param opts The read opts to change
|
||||||
|
@ -39,6 +39,8 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
|||||||
opts->fill_up_media = 0;
|
opts->fill_up_media = 0;
|
||||||
opts->force_is_set = 0;
|
opts->force_is_set = 0;
|
||||||
opts->do_stream_recording = 0;
|
opts->do_stream_recording = 0;
|
||||||
|
opts->dvd_obs_override = 0;
|
||||||
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
opts->has_mediacatalog = 0;
|
opts->has_mediacatalog = 0;
|
||||||
opts->format = BURN_CDROM;
|
opts->format = BURN_CDROM;
|
||||||
opts->multi = 0;
|
opts->multi = 0;
|
||||||
@ -389,6 +391,25 @@ void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91115: API */
|
||||||
|
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
|
||||||
|
{
|
||||||
|
if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024)
|
||||||
|
return;
|
||||||
|
opts->dvd_obs_override = obs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ts A91115: API */
|
||||||
|
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
|
||||||
|
{
|
||||||
|
if (rythm == -1)
|
||||||
|
opts->stdio_fsync_size = 0;
|
||||||
|
else if (rythm == 0)
|
||||||
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
|
else if (rythm >= 32)
|
||||||
|
opts->stdio_fsync_size = rythm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A70901: API */
|
/* ts A70901: API */
|
||||||
|
@ -51,9 +51,19 @@ struct burn_write_opts
|
|||||||
|
|
||||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||||
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
||||||
This gets transferred to burn_drive.do_stream_recording */
|
This gets transferred to burn_drive.do_stream_recording
|
||||||
|
*/
|
||||||
int do_stream_recording;
|
int do_stream_recording;
|
||||||
|
|
||||||
|
/* ts A91115 : override value for .obs on DVD media.
|
||||||
|
Only values 0, 32K and 64K are allowed for now. */
|
||||||
|
int dvd_obs_override;
|
||||||
|
|
||||||
|
/* ts A91115 : size of the fsync() interval for stdio writing.
|
||||||
|
Values 0 or >= 32 counted in 2 KB blocks. */
|
||||||
|
int stdio_fsync_size;
|
||||||
|
|
||||||
|
|
||||||
/** A disc can have a media catalog number */
|
/** A disc can have a media catalog number */
|
||||||
int has_mediacatalog;
|
int has_mediacatalog;
|
||||||
unsigned char mediacatalog[13];
|
unsigned char mediacatalog[13];
|
||||||
@ -64,6 +74,11 @@ struct burn_write_opts
|
|||||||
unsigned char multi;
|
unsigned char multi;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Default value for burn_write_opts.stdio_flush_size
|
||||||
|
*/
|
||||||
|
#define Libburn_stdio_fsync_limiT 8192
|
||||||
|
|
||||||
|
|
||||||
/** Options for disc reading operations. This should be created with
|
/** Options for disc reading operations. This should be created with
|
||||||
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||||
struct burn_read_opts
|
struct burn_read_opts
|
||||||
|
148
libburn/write.c
148
libburn/write.c
@ -1246,6 +1246,126 @@ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* <<<
|
||||||
|
#define Libburn_simplified_dvd_chunk_transactioN 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef Libburn_simplified_dvd_chunk_transactioN
|
||||||
|
|
||||||
|
/* ts A91114 : EXPERIMENTAL, NOT COMPLETELY IMPLEMENTED
|
||||||
|
|
||||||
|
Simplified data transmission for DVD. libburn via Linux USB is 30 % slower
|
||||||
|
than growisofs or cdrecord when transmitting 32 KB chunks.
|
||||||
|
With 64 KB chunks it is 20% faster than the competitors.
|
||||||
|
No heavy CPU load is visible but there might be subtle race conditions in
|
||||||
|
the USB driver which work better with shorter time gaps between WRITE
|
||||||
|
commands.
|
||||||
|
|
||||||
|
Insight: It is actually about the interference of track source reading
|
||||||
|
with SCSI writing via USB. growisofs reads with O_DIRECT into a
|
||||||
|
mmap()ed buffer. When doing the same, libburn with 32 KB chunks
|
||||||
|
reaches similar write speed.
|
||||||
|
On the other hand, 64 KB chunks are 20% faster than that and
|
||||||
|
are not improved by reading O_DIRECT.
|
||||||
|
|
||||||
|
O_DIRECT is a property of the input fd of struct burn_source.
|
||||||
|
It can only be done with properly aligned memory and with aligned
|
||||||
|
read size. Alignment size is file system system specific.
|
||||||
|
System call
|
||||||
|
mmap(NULL, (size_t) buffer_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
|
||||||
|
is supposed to allocate a properly aligned buffer.
|
||||||
|
64 KB is supposed to be a safe size.
|
||||||
|
|
||||||
|
@return 1= ok, go on , 2= no input with track->open_ended = nothing written
|
||||||
|
<= 0 = error
|
||||||
|
*/
|
||||||
|
static int transact_dvd_chunk(struct burn_write_opts *opts,
|
||||||
|
struct burn_track *track)
|
||||||
|
{
|
||||||
|
int curr = 0, valid, err;
|
||||||
|
struct burn_drive *d = opts->drive;
|
||||||
|
struct buffer *out = d->buffer;
|
||||||
|
unsigned char *data = out->data;
|
||||||
|
|
||||||
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
|
/* <<< ts A61031 */
|
||||||
|
static int tee_fd= -1;
|
||||||
|
if(tee_fd==-1)
|
||||||
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
|
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
|
||||||
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
|
||||||
|
/* Read a chunk full of data */
|
||||||
|
|
||||||
|
/* ??? Do we have offset padding ? >>> First produce offset padding */;
|
||||||
|
|
||||||
|
/* <<<< */
|
||||||
|
if (0 && !track->eos) {
|
||||||
|
for (curr = 0; curr < opts->obs; curr += 2048) {
|
||||||
|
if (track->source->read != NULL)
|
||||||
|
valid = track->source->read(track->source,
|
||||||
|
data + curr, 2048);
|
||||||
|
else
|
||||||
|
valid = track->source->read_xt(track->source,
|
||||||
|
data + curr, 2048);
|
||||||
|
if (valid <= 0) {
|
||||||
|
track->eos = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
track->sourcecount += valid;
|
||||||
|
|
||||||
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
|
if(tee_fd!=-1 && valid>0) {
|
||||||
|
write(tee_fd, data + curr, valid);
|
||||||
|
}
|
||||||
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (!track->eos){
|
||||||
|
valid = track->source->read(track->source, data, opts->obs);
|
||||||
|
if (valid <= 0) {
|
||||||
|
track->eos = 1;
|
||||||
|
} else {
|
||||||
|
track->sourcecount += valid;
|
||||||
|
curr = valid;
|
||||||
|
|
||||||
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
|
if(tee_fd!=-1 && valid>0) {
|
||||||
|
write(tee_fd, data, valid);
|
||||||
|
}
|
||||||
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (curr == 0 && track->open_ended) {
|
||||||
|
|
||||||
|
/* >>> allow tail padding */;
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (curr < opts->obs)
|
||||||
|
memset(data + curr , 0, opts->obs - curr);
|
||||||
|
|
||||||
|
/* Write chunk */
|
||||||
|
out->bytes = opts->obs;
|
||||||
|
out->sectors = out->bytes / 2048;
|
||||||
|
err = d->write(d, d->nwa, out);
|
||||||
|
if (err == BE_CANCELLED)
|
||||||
|
return 0;
|
||||||
|
track->writecount += out->bytes;
|
||||||
|
track->written_sectors += out->sectors;
|
||||||
|
d->progress.buffered_bytes += out->bytes;
|
||||||
|
d->nwa += out->sectors;
|
||||||
|
out->bytes = 0;
|
||||||
|
out->sectors = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_simplified_dvd_chunk_transactioN */
|
||||||
|
|
||||||
|
|
||||||
/* ts A61218 - A81208 */
|
/* ts A61218 - A81208 */
|
||||||
int burn_dvd_write_track(struct burn_write_opts *o,
|
int burn_dvd_write_track(struct burn_write_opts *o,
|
||||||
struct burn_session *s, int tnum, int is_last_track)
|
struct burn_session *s, int tnum, int is_last_track)
|
||||||
@ -1322,9 +1442,18 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
d->progress.buffer_capacity / 2048 + 128;
|
d->progress.buffer_capacity / 2048 + 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_simplified_dvd_chunk_transactioN
|
||||||
|
|
||||||
|
ret = transact_dvd_chunk(o, t);
|
||||||
|
if (ret <= 0)
|
||||||
|
{ret = 0; goto ex;}
|
||||||
|
i += o->obs / 2048 - 1;
|
||||||
|
d->progress.sector += o->obs / 2048 - 1;
|
||||||
|
#else
|
||||||
/* transact a (CD sized) sector */
|
/* transact a (CD sized) sector */
|
||||||
if (!sector_data(o, t, 0))
|
if (!sector_data(o, t, 0))
|
||||||
{ ret = 0; goto ex; }
|
{ ret = 0; goto ex; }
|
||||||
|
#endif
|
||||||
|
|
||||||
if (open_ended) {
|
if (open_ended) {
|
||||||
d->progress.sectors = sectors = i;
|
d->progress.sectors = sectors = i;
|
||||||
@ -1789,11 +1918,22 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
/* <<< test only : Does this increase effective speed with USB ?
|
/* <<< test only : Does this increase effective speed with USB ?
|
||||||
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
|
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
|
||||||
128kB: glibc complains about double free
|
128kB: glibc complains about double free
|
||||||
BURN_OS_TRANSPORT_BUFFER_SIZE would need to
|
With BURN_OS_TRANSPORT_BUFFER_SIZE
|
||||||
be enlarged anyway.
|
enlarged to 128 MB, the first WRITE fails
|
||||||
|
with an i/o error.
|
||||||
o->obs = 64 * 1024;
|
o->obs = 64 * 1024;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (o->dvd_obs_override >= 32 * 1024)
|
||||||
|
o->obs = o->dvd_obs_override;
|
||||||
|
|
||||||
|
if (o->obs > BUFFER_SIZE) {
|
||||||
|
sprintf(msg, "Chosen write chunk size %d exceeds system dependent buffer size", o->obs);
|
||||||
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
|
0x00000002, LIBDAX_MSGS_SEV_DEBUG,
|
||||||
|
LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
|
||||||
|
o->obs = BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
||||||
d->current_profile, o->obs, o->obs_pad);
|
d->current_profile, o->obs, o->obs_pad);
|
||||||
@ -2043,8 +2183,6 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush write buffer after each 16 MB */
|
|
||||||
#define Libburn_stdio_flush_limiT 8192
|
|
||||||
|
|
||||||
/* ts A70904 */
|
/* ts A70904 */
|
||||||
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||||
@ -2085,7 +2223,7 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
d->progress.sector++;
|
d->progress.sector++;
|
||||||
/* Flush to disk from time to time */
|
/* Flush to disk from time to time */
|
||||||
if (d->progress.sector - prev_sync_sector >=
|
if (d->progress.sector - prev_sync_sector >=
|
||||||
Libburn_stdio_flush_limiT) {
|
o->stdio_fsync_size && o->stdio_fsync_size > 0) {
|
||||||
prev_sync_sector = d->progress.sector;
|
prev_sync_sector = d->progress.sector;
|
||||||
if (!o->simulate)
|
if (!o->simulate)
|
||||||
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user