Branching for libburn bugfix release 0.7.4.pl01
This commit is contained in:
commit
9d18ddcbfa
12
Makefile.am
12
Makefile.am
@ -12,6 +12,9 @@ lib_LTLIBRARIES = libburn/libburn.la
|
||||
# Build libraries
|
||||
libburn_libburn_la_LDFLAGS = \
|
||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
||||
# This causes undesired .o names
|
||||
# configure.ac appends -D options to variable CFLAG
|
||||
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
|
||||
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||
libburn_libburn_la_SOURCES = \
|
||||
libburn/async.c \
|
||||
@ -25,6 +28,8 @@ libburn_libburn_la_SOURCES = \
|
||||
libburn/debug.h \
|
||||
libburn/drive.c \
|
||||
libburn/drive.h \
|
||||
libburn/ecma130ab.c \
|
||||
libburn/ecma130ab.h \
|
||||
libburn/error.h \
|
||||
libburn/file.c \
|
||||
libburn/file.h \
|
||||
@ -65,9 +70,6 @@ libburn_libburn_la_SOURCES = \
|
||||
libburn/write.h \
|
||||
version.h
|
||||
|
||||
## libburn/lec.c \
|
||||
## libburn/lec.h \
|
||||
|
||||
## libburn/sg-@ARCH@.c \
|
||||
|
||||
libinclude_HEADERS = \
|
||||
@ -108,9 +110,9 @@ test_structest_CPPFLAGS = -Ilibburn
|
||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_structest_SOURCES = test/structest.c
|
||||
|
||||
## cdrskin construction site - ts A60816 - A91012
|
||||
## cdrskin construction site - ts A60816 - A91206
|
||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_2
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_4
|
||||
|
||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||
|
42
README
42
README
@ -11,7 +11,7 @@ Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||
and Ben Jansens <xor@orodu.net>
|
||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||
|
||||
http://files.libburnia-project.org/releases/libburn-0.7.2.pl00.tar.gz
|
||||
http://files.libburnia-project.org/releases/libburn-0.7.4.pl00.tar.gz
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||
|
||||
From tarball
|
||||
|
||||
Obtain libburn-0.7.2.pl00.tar.gz, take it to a directory of your choice and do:
|
||||
Obtain libburn-0.7.4.pl00.tar.gz, take it to a directory of your choice and do:
|
||||
|
||||
tar xzf libburn-0.7.2.pl00.tar.gz
|
||||
cd libburn-0.7.2
|
||||
tar xzf libburn-0.7.4.pl00.tar.gz
|
||||
cd libburn-0.7.4
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
|
||||
@ -57,6 +57,26 @@ Do in a directory of your choice:
|
||||
Warning: The trunk might contain experimental features which might not
|
||||
persist until next release.
|
||||
|
||||
|
||||
Special ./configure options
|
||||
|
||||
In some situations Linux may deliver a better write performance to drives if
|
||||
the track input is read with O_DIRECT (see man 2 open). The API call
|
||||
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
||||
can be told to use this peculiar read mode by:
|
||||
--enable-track-src-odirect
|
||||
|
||||
But often libburn call burn_write_opts_set_dvd_obs(opts, 64*1024) will yield
|
||||
even better performance in such a situation. 64k can be made default at
|
||||
configure time by:
|
||||
--enable-dvd-obs-64k
|
||||
This may be combined with above --enable-track-src-odirect .
|
||||
|
||||
Make sure to re-compile all source files after running ./configure
|
||||
make clean ; make
|
||||
make install
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||
@ -137,7 +157,8 @@ The project components (list subject to growth, hopefully):
|
||||
Rock Ridge extensions. Manipulation is not only adding or
|
||||
overwriting of files but also deleting, renaming, attribute
|
||||
changing, incremental backups, activating boot images, and
|
||||
extracting of files from ISO images to disk.
|
||||
extracting of files from ISO images to disk. An own ISO 9660
|
||||
extension stores ACLs, xattr, and MD5 of file content.
|
||||
See xorriso/README for more.
|
||||
|
||||
- "test" is a collection of application gestures and examples given by the
|
||||
@ -443,6 +464,17 @@ Project history as far as known to me:
|
||||
It can retrieve media product info and can process track input which was
|
||||
prepared for CD-ROM XA Mode 2 Form 1. cdrskin now performs option -minfo.
|
||||
|
||||
- 28 Oct 2009 libisoburn-0.4.4 fixes a bug with cdrecord emulation and
|
||||
introduces new information options about media type and ISO image id strings.
|
||||
On Linux it helps with mounting two sessions of the same media
|
||||
simultaneously.
|
||||
|
||||
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
|
||||
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
|
||||
|
||||
- 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners,
|
||||
provides throughput enhancements with hampered busses on Linux, and new
|
||||
API calls to log SCSI commands and to control the libburn fifo.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||
Integrated sub project of libburnia-project.org but also published via:
|
||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||
http://scdbackup.sourceforge.net/cdrskin-0.7.2.pl00.tar.gz
|
||||
http://scdbackup.sourceforge.net/cdrskin-0.7.4.pl00.tar.gz
|
||||
|
||||
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
|
||||
------------------------------------------------------------------------------
|
||||
@ -24,10 +24,10 @@ By using this software you agree to the disclaimer at the end of this text
|
||||
|
||||
Compilation, First Glimpse, Installation
|
||||
|
||||
Obtain cdrskin-0.7.2.pl00.tar.gz, take it to a directory of your choice and do:
|
||||
Obtain cdrskin-0.7.4.pl00.tar.gz, take it to a directory of your choice and do:
|
||||
|
||||
tar xzf cdrskin-0.7.2.pl00.tar.gz
|
||||
cd cdrskin-0.7.2
|
||||
tar xzf cdrskin-0.7.4.pl00.tar.gz
|
||||
cd cdrskin-0.7.4
|
||||
|
||||
Within that directory execute:
|
||||
|
||||
@ -35,8 +35,7 @@ Within that directory execute:
|
||||
make
|
||||
|
||||
This will already produce a cdrskin binary. But it will be necessary to
|
||||
install libburn in order to use this binary. Installation of libburn is
|
||||
beyond the scope of cdrskin. For this, see included libburn docs.
|
||||
install libburn in order to use this binary.
|
||||
|
||||
In order to surely get a standalone binary, execute
|
||||
|
||||
@ -73,7 +72,7 @@ It is not necessary for the standalone cdrskin binary to have libburn
|
||||
installed, since it incorporates the necessary libburn parts at compile time.
|
||||
It will not collide with an installed version of libburn either.
|
||||
But libpthread must be installed on the system and glibc has to match. (See
|
||||
below for a way to create a statically linked binary.)
|
||||
below for a way to create a totally static linked binary.)
|
||||
|
||||
To install the man page, you may do: echo $MANPATH and choose one of the
|
||||
listed directories to copy the man-page under its ./man1 directory. Like:
|
||||
@ -398,6 +397,21 @@ drive. See man page section FILES for a way to lift that ban.
|
||||
|
||||
Special compilation variations
|
||||
|
||||
All following options of ./configure and cdrskin/compile_cdrskin.sh are
|
||||
combinable.
|
||||
|
||||
In some situations Linux may deliver a better write performance to drives if
|
||||
the track input is read with O_DIRECT (see man 2 open). The API call
|
||||
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
||||
can be told to use this peculiar read mode by:
|
||||
--enable-track-src-odirect
|
||||
|
||||
But often cdrskin option dvd_obs=64k will yield even better performance in
|
||||
such a situation. 64k can be made default at compile time by
|
||||
cdrskin/compile_cdrskin.sh -dvd_obs_64k
|
||||
It can also be enabled at configure time by
|
||||
./configure ... --enable-dvd-obs-64k ...
|
||||
|
||||
You may get a (super fat) statically linked binary by :
|
||||
cdrskin/compile_cdrskin.sh -static
|
||||
if your system supports static linking, at all. This will not help with kernels
|
||||
|
@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
|
||||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-release"
|
||||
|
||||
skin_release="0.7.2"
|
||||
skin_release="0.7.4"
|
||||
patch_level=".pl00"
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
|
||||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-develop"
|
||||
|
||||
skin_release="0.7.3"
|
||||
skin_release="0.7.5"
|
||||
patch_level=""
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
@ -25,6 +25,11 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#ifndef Cdrfifo_standalonE
|
||||
/* <<< until release of 0.7.4 : for Libburn_has_open_trac_srC */
|
||||
#include "../libburn/libburn.h"
|
||||
#endif
|
||||
|
||||
#include "cdrfifo.h"
|
||||
|
||||
|
||||
@ -120,7 +125,7 @@ struct CdrfifO {
|
||||
struct burn_source object.
|
||||
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||
@param buffer_size Size of fifo buffer
|
||||
@param flag Unused yet
|
||||
@param flag bit0= Debugging verbosity
|
||||
@return 1 on success, <=0 on failure
|
||||
*/
|
||||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||
@ -174,7 +179,13 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||
o->follow_up_fd_idx= -1;
|
||||
o->next= o->prev= NULL;
|
||||
o->chain_idx= 0;
|
||||
|
||||
#ifdef Libburn_has_open_trac_srC
|
||||
o->buffer= burn_os_alloc_buffer((size_t) buffer_size, 0);
|
||||
#else
|
||||
o->buffer= TSOB_FELD(char,buffer_size);
|
||||
#endif /* ! Libburn_has_open_trac_srC */
|
||||
|
||||
if(o->buffer==NULL)
|
||||
goto failed;
|
||||
return(1);
|
||||
@ -226,8 +237,14 @@ int Cdrfifo_destroy(struct CdrfifO **ff, int flag)
|
||||
|
||||
if(o->iso_fs_descr!=NULL)
|
||||
free((char *) o->iso_fs_descr);
|
||||
|
||||
if(o->buffer!=NULL)
|
||||
#ifdef Libburn_has_open_trac_srC
|
||||
burn_os_free_buffer(o->buffer, o->buffer_size, 0);
|
||||
#else
|
||||
free((char *) o->buffer);
|
||||
#endif /* Libburn_has_open_trac_srC */
|
||||
|
||||
free((char *) o);
|
||||
(*ff)= NULL;
|
||||
return(1);
|
||||
@ -616,7 +633,7 @@ return: <0 = error , 0 = idle , 1 = did some work
|
||||
*/
|
||||
{
|
||||
double buffer_space;
|
||||
int can_read,can_write,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
|
||||
int can_read,can_write= 0,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
|
||||
|
||||
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
||||
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
||||
@ -659,6 +676,46 @@ return: <0 = error , 0 = idle , 1 = did some work
|
||||
after_write:;
|
||||
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
||||
can_read= o->buffer_size - o->write_idx;
|
||||
|
||||
#ifdef Libburn_has_open_trac_srC
|
||||
|
||||
/* ts A91115
|
||||
This chunksize must be aligned to filesystem blocksize.
|
||||
*/
|
||||
#define Cdrfifo_o_direct_chunK 32768
|
||||
|
||||
if(o->write_idx < o->read_idx && o->write_idx + can_read > o->read_idx)
|
||||
can_read= o->read_idx - o->write_idx;
|
||||
if(o->fd_in_limit>=0.0)
|
||||
if(can_read > o->fd_in_limit - o->fd_in_counter)
|
||||
can_read= o->fd_in_limit - o->fd_in_counter;
|
||||
/* Make sure to read with properly aligned size */
|
||||
if(can_read > Cdrfifo_o_direct_chunK)
|
||||
can_read= Cdrfifo_o_direct_chunK;
|
||||
else if(can_read < Cdrfifo_o_direct_chunK)
|
||||
can_read= -1;
|
||||
ret= 0;
|
||||
if(can_read>0)
|
||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||
if(can_read < 0) {
|
||||
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
|
||||
if(can_write <= 0 && o->dest_fd >= 0) {
|
||||
fd_set rds,wts,exs;
|
||||
struct timeval wt;
|
||||
|
||||
FD_ZERO(&rds);
|
||||
FD_ZERO(&wts);
|
||||
FD_ZERO(&exs);
|
||||
FD_SET((o->dest_fd),&wts);
|
||||
wt.tv_sec= 0;
|
||||
wt.tv_usec= 10000;
|
||||
select(o->dest_fd + 1,&rds, &wts, &exs, &wt);
|
||||
|
||||
}
|
||||
} else
|
||||
|
||||
#else /* Libburn_has_open_trac_srC */
|
||||
|
||||
if(can_read>o->chunk_size)
|
||||
can_read= o->chunk_size;
|
||||
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
||||
@ -669,6 +726,9 @@ after_write:;
|
||||
ret= 0;
|
||||
if(can_read>0)
|
||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||
|
||||
#endif /* ! Libburn_has_open_trac_srC */
|
||||
|
||||
if(ret==-1) {
|
||||
|
||||
/* >>> handle input error */;
|
||||
|
@ -33,7 +33,7 @@ struct CdrfifO;
|
||||
struct burn_source object.
|
||||
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||
@param buffer_size Size of fifo buffer
|
||||
@param flag unused yet
|
||||
@param flag bit0= Debugging verbosity
|
||||
@return 1 on success, <=0 on failure
|
||||
*/
|
||||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||
|
@ -2,7 +2,7 @@
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH CDRSKIN 1 "Sep 10, 2009"
|
||||
.TH CDRSKIN 1 "Nov 16, 2009"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@ -796,6 +796,11 @@ Level 2 additionally reports about option settings derived from arguments or
|
||||
startup files. Level 3 is for debugging and useful mainly in conjunction with
|
||||
somebody who had a look into the program sourcecode.
|
||||
.TP
|
||||
.BI \-V
|
||||
Enable logging of SCSI commands to stderr. This allows expert examination
|
||||
of the interaction between libburn and the drive. The commands are specified
|
||||
in SCSI-3 standards SPC, SBC, MMC.
|
||||
.TP
|
||||
.BI \-waiti
|
||||
Wait until input data is available at stdin or EOF occurs at stdin.
|
||||
Only then begin to access any drives.
|
||||
@ -894,6 +899,14 @@ Both, write_start_address and direct_write_amount size must be aligned to a
|
||||
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
|
||||
overwriteable DVD-RW it is 32k.
|
||||
.TP
|
||||
.BI dvd_obs= default|32k|64k
|
||||
Linux specific:
|
||||
Set the number of bytes to be transmitted with each write operation to DVD
|
||||
or BD media. Tracks get padded up to the next multiple of this write
|
||||
size. A number of 64 KB may improve throughput with bus systems which
|
||||
show latency problems. The default depends on media type, option
|
||||
stream_recording=, and on compile time options.
|
||||
.TP
|
||||
.BI fallback_program= command
|
||||
Set a command name to be executed if cdrskin encounters a known cdrecord
|
||||
option which it does not yet support. If a non-empty command is given with
|
||||
@ -1008,6 +1021,22 @@ which can only do DAO but not Incremental Streaming.
|
||||
.BI \--single_track
|
||||
Accept only the last argument of the command line as track source address.
|
||||
.TP
|
||||
.BI stdio_sync= on|off|number
|
||||
Set the number of bytes after which to force output to drives with prefix
|
||||
"stdio:". This forcing keeps the memory from being clogged with lots of
|
||||
pending data for slow devices. Default "on" is the same as "16m".
|
||||
Forced output can be disabled by "off".
|
||||
.TP
|
||||
.BI stream_recording= on|off|number
|
||||
By setting "on" request that compliance to the desired speed setting is
|
||||
preferred over management of write errors. With DVD-RAM and BD this can
|
||||
bring effective write speed near to the nominal write speed of the media.
|
||||
But it will also disable the automatic use of replacement blocks
|
||||
if write errors occur. It might as well be disliked or ignored by the drive.
|
||||
.br
|
||||
If a number is given, then error management stays enabled for all byte
|
||||
addresses below that number. Any number below 16s is the same as "off".
|
||||
.TP
|
||||
.BI tao_to_sao_tsize= size
|
||||
Set an exact fixed size for the next track to be in effect only if the track
|
||||
source cannot deliver a size prediction and no tsize= was specified and an
|
||||
@ -1194,17 +1223,6 @@ Linux specific:
|
||||
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||
original cdrecord.
|
||||
.TP
|
||||
.BI stream_recording="on"|"off"|number
|
||||
By setting "on" request that compliance to the desired speed setting is
|
||||
preferred over management of write errors. With DVD-RAM and BD this can
|
||||
bring effective write speed near to the nominal write speed of the media.
|
||||
But it will also disable the automatic use of replacement blocks
|
||||
if write errors occur. It might as well be disliked or ignored by the drive.
|
||||
.br
|
||||
If a number is given, then error management stays enabled for all byte
|
||||
addresses below that number. Any number below 16s is the same as "off".
|
||||
.TP
|
||||
.BI --xa1-ignore
|
||||
Silently interpret option -xa1 as -data. This may be necessary if a frontent
|
||||
does not prepare -xa1 block headers but insists in using option -xa1.
|
||||
|
@ -88,7 +88,7 @@ or
|
||||
|
||||
/** The official program version */
|
||||
#ifndef Cdrskin_prog_versioN
|
||||
#define Cdrskin_prog_versioN "0.7.2"
|
||||
#define Cdrskin_prog_versioN "0.7.4"
|
||||
#endif
|
||||
|
||||
/** The official libburn interface revision to use.
|
||||
@ -101,7 +101,7 @@ or
|
||||
#define Cdrskin_libburn_minoR 7
|
||||
#endif
|
||||
#ifndef Cdrskin_libburn_micrO
|
||||
#define Cdrskin_libburn_micrO 2
|
||||
#define Cdrskin_libburn_micrO 4
|
||||
#endif
|
||||
|
||||
|
||||
@ -135,42 +135,43 @@ or
|
||||
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
||||
|
||||
|
||||
#ifdef Cdrskin_libburn_0_7_2
|
||||
#define Cdrskin_libburn_versioN "0.7.2"
|
||||
#ifdef Cdrskin_libburn_0_7_4
|
||||
#define Cdrskin_libburn_versioN "0.7.4"
|
||||
#define Cdrskin_libburn_from_pykix_svN 1
|
||||
#endif /* Cdrskin_libburn_0_7_2 */
|
||||
#endif /* Cdrskin_libburn_0_7_4 */
|
||||
|
||||
#ifdef Cdrskin_libburn_0_7_3
|
||||
#define Cdrskin_libburn_versioN "0.7.3"
|
||||
#ifdef Cdrskin_libburn_0_7_5
|
||||
#define Cdrskin_libburn_versioN "0.7.5"
|
||||
#define Cdrskin_libburn_from_pykix_svN 1
|
||||
|
||||
/* Place novelty switch macros here.
|
||||
Move them down to Cdrskin_libburn_from_pykix_svN on version leap
|
||||
*/
|
||||
|
||||
#endif /* Cdrskin_libburn_0_7_3 */
|
||||
|
||||
#endif /* Cdrskin_libburn_0_7_5 */
|
||||
|
||||
#ifndef Cdrskin_libburn_versioN
|
||||
#define Cdrskin_libburn_0_7_2
|
||||
#define Cdrskin_libburn_versioN "0.7.2"
|
||||
#define Cdrskin_libburn_0_7_4
|
||||
#define Cdrskin_libburn_versioN "0.7.4"
|
||||
#define Cdrskin_libburn_from_pykix_svN 1
|
||||
#endif
|
||||
|
||||
#ifdef Cdrskin_libburn_0_7_2
|
||||
#ifdef Cdrskin_libburn_0_7_4
|
||||
#undef Cdrskin_libburn_majoR
|
||||
#undef Cdrskin_libburn_minoR
|
||||
#undef Cdrskin_libburn_micrO
|
||||
#define Cdrskin_libburn_majoR 0
|
||||
#define Cdrskin_libburn_minoR 7
|
||||
#define Cdrskin_libburn_micrO 2
|
||||
#define Cdrskin_libburn_micrO 4
|
||||
#endif
|
||||
#ifdef Cdrskin_libburn_0_7_3
|
||||
#ifdef Cdrskin_libburn_0_7_5
|
||||
#undef Cdrskin_libburn_majoR
|
||||
#undef Cdrskin_libburn_minoR
|
||||
#undef Cdrskin_libburn_micrO
|
||||
#define Cdrskin_libburn_majoR 0
|
||||
#define Cdrskin_libburn_minoR 7
|
||||
#define Cdrskin_libburn_micrO 3
|
||||
#define Cdrskin_libburn_micrO 5
|
||||
#endif
|
||||
|
||||
|
||||
@ -322,10 +323,15 @@ or
|
||||
/** A macro which is able to eat up a function call like printf() */
|
||||
#ifdef Cdrskin_extra_leaN
|
||||
#define ClN(x)
|
||||
#define Cdrskin_no_cdrfifO 1
|
||||
#else
|
||||
#define ClN(x) x
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
/*
|
||||
# define Cdrskin_no_cdrfifO 1
|
||||
*/
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/** Verbosity level for pacifying progress messages */
|
||||
#define Cdrskin_verbose_progresS 1
|
||||
@ -865,12 +871,12 @@ backward:;
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
|
||||
/* Program is to be linked with cdrfifo.c */
|
||||
#include "cdrfifo.h"
|
||||
|
||||
#else /* ! Cdrskin_extra_leaN */
|
||||
#else /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
/* Dummy */
|
||||
|
||||
@ -878,7 +884,7 @@ struct CdrfifO {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
#endif /* Cdrskin_extra_leaN */
|
||||
#endif /* Cdrskin_no_cdrfifO */
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -941,6 +947,10 @@ struct CdrtracK {
|
||||
|
||||
struct burn_track *libburn_track;
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
struct burn_source *libburn_fifo;
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
};
|
||||
|
||||
int Cdrtrack_destroy(struct CdrtracK **o, int flag);
|
||||
@ -998,6 +1008,9 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss,
|
||||
o->ff_fifo= NULL;
|
||||
o->ff_idx= -1;
|
||||
o->libburn_track= NULL;
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
o->libburn_fifo= NULL;
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size),
|
||||
&(o->tao_to_sao_tsize),&(o->use_data_image_size),
|
||||
@ -1034,7 +1047,7 @@ int Cdrtrack_destroy(struct CdrtracK **o, int flag)
|
||||
if(track==NULL)
|
||||
return(0);
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
Cdrfifo_destroy(&(track->fifo),0);
|
||||
#endif
|
||||
|
||||
@ -1120,6 +1133,61 @@ int Cdrtrack_get_source_path(struct CdrtracK *track,
|
||||
}
|
||||
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
|
||||
int Cdrtrack_get_libburn_fifo(struct CdrtracK *track,
|
||||
struct burn_source **fifo, int flag)
|
||||
{
|
||||
*fifo= track->libburn_fifo;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int Cdrtrack_report_fifo(struct CdrtracK *track, int flag)
|
||||
{
|
||||
int size, free_bytes, ret;
|
||||
int total_min_fill, interval_min_fill, put_counter, get_counter;
|
||||
int empty_counter, full_counter;
|
||||
double fifo_percent;
|
||||
char *status_text;
|
||||
|
||||
if(track->libburn_fifo == NULL)
|
||||
return(0);
|
||||
|
||||
/* Check for open input or leftover bytes in liburn fifo */
|
||||
ret = burn_fifo_inquire_status(track->libburn_fifo, &size, &free_bytes,
|
||||
&status_text);
|
||||
if(ret >= 0 && size - free_bytes > 1) {
|
||||
/* not clear why free_bytes is reduced by 1 */
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : Fifo still contains data after burning has ended.\n");
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : %d bytes left.\n", size - free_bytes - 1);
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : This indicates an overflow of the last track.\n");
|
||||
fprintf(stderr,
|
||||
"cdrskin: NOTE : The media might appear ok but is probably truncated.\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
burn_fifo_get_statistics(track->libburn_fifo, &total_min_fill,
|
||||
&interval_min_fill, &put_counter, &get_counter,
|
||||
&empty_counter, &full_counter);
|
||||
fifo_percent= 100.0*((double) total_min_fill)/(double) size;
|
||||
if(fifo_percent==0 && total_min_fill>0)
|
||||
fifo_percent= 1;
|
||||
fflush(stdout);
|
||||
fprintf(stderr,"Cdrskin: fifo had %d puts and %d gets.\n",
|
||||
put_counter,get_counter);
|
||||
fprintf(stderr,
|
||||
"Cdrskin: fifo was %d times empty and %d times full, min fill was %.f%%.\n",
|
||||
empty_counter, full_counter, fifo_percent);
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
|
||||
int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag)
|
||||
{
|
||||
*fifo= track->fifo;
|
||||
@ -1234,7 +1302,7 @@ int Cdrtrack_activate_image_size(struct CdrtracK *track, double *size_used,
|
||||
}
|
||||
track->extracting_container= 1;
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
if(track->ff_fifo!=NULL)
|
||||
Cdrfifo_set_fd_in_limit(track->ff_fifo,track->fixed_size,track->ff_idx,0);
|
||||
#endif
|
||||
@ -1298,6 +1366,7 @@ int Cdrtrack_seek_isosize(struct CdrtracK *track, int fd, int flag)
|
||||
bit0=debugging verbosity
|
||||
bit1=open as source for direct write:
|
||||
no audio extract, no minimum track size
|
||||
bit2=permission to use burn_os_open_track_src() (evtl O_DIRECT)
|
||||
@return <=0 error, 1 success
|
||||
*/
|
||||
int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
|
||||
@ -1387,8 +1456,15 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
|
||||
return(-1);
|
||||
if(is_wav==-3)
|
||||
return(0);
|
||||
if(is_wav==0)
|
||||
*fd= open(track->source_path,O_RDONLY);
|
||||
if(is_wav==0) {
|
||||
if(track->track_type != BURN_MODE1 ||
|
||||
(track->cdxa_conversion & 0x7fffffff))
|
||||
flag&= ~4; /* Better avoid O_DIRECT with odd sectors */
|
||||
if(flag & 4)
|
||||
*fd= burn_os_open_track_src(track->source_path, O_RDONLY, 0);
|
||||
else
|
||||
*fd= open(track->source_path, O_RDONLY);
|
||||
}
|
||||
if(*fd==-1) {
|
||||
fprintf(stderr,"cdrskin: failed to open source address '%s'\n",
|
||||
track->source_path);
|
||||
@ -1452,7 +1528,7 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
|
||||
}
|
||||
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
|
||||
/** Install a fifo object between data source and libburn.
|
||||
Its parameters are known to track.
|
||||
@ -1474,7 +1550,8 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
|
||||
*outlet_fd= -1;
|
||||
if(track->fifo_size<=0)
|
||||
return(2);
|
||||
ret= Cdrtrack_open_source_path(track,&source_fd,flag&1);
|
||||
ret= Cdrtrack_open_source_path(track,&source_fd,
|
||||
(flag&1) | (4 * (track->fifo_size >= 256 * 1024)));
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
if(pipe(pipe_fds)==-1)
|
||||
@ -1491,7 +1568,7 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
|
||||
|
||||
/* >>> ??? obtain track sector size and use instead of 2048 ? */
|
||||
|
||||
ret= Cdrfifo_new(&ff,source_fd,pipe_fds[1],2048,track->fifo_size,0);
|
||||
ret= Cdrfifo_new(&ff,source_fd,pipe_fds[1],2048,track->fifo_size, flag & 1);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
if(previous_fifo!=NULL)
|
||||
@ -1514,18 +1591,100 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
/** Read data into the fifo until either it is full or the data source is
|
||||
exhausted.
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
|
||||
/** Read data into the eventual libburn fifo until either fifo_start_at bytes
|
||||
are read (-1 = no limit), it is full or or the data source is exhausted.
|
||||
@return <=0 error, 1 success
|
||||
*/
|
||||
int Cdrtrack_fill_libburn_fifo(struct CdrtracK *track, int fifo_start_at,
|
||||
int flag)
|
||||
{
|
||||
int ret, bs= 32 * 1024;
|
||||
int buffer_size, buffer_free;
|
||||
double data_image_size;
|
||||
char buf[64 * 1024], *buffer_text;
|
||||
|
||||
if(fifo_start_at == 0)
|
||||
return(2);
|
||||
if(track->libburn_fifo == NULL)
|
||||
return(2);
|
||||
|
||||
if(fifo_start_at>0 && fifo_start_at<track->fifo_size)
|
||||
printf(
|
||||
"cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n",
|
||||
fifo_start_at);
|
||||
printf("Waiting for reader process to fill input buffer ... ");
|
||||
fflush(stdout);
|
||||
ret= burn_fifo_fill(track->libburn_fifo, fifo_start_at,
|
||||
(fifo_start_at == -1));
|
||||
if(ret < 0)
|
||||
return(0);
|
||||
|
||||
/** Ticket 55: check fifos for input, throw error on 0-bytes from stdin
|
||||
@return <=0 abort run, 1 go on with burning
|
||||
*/
|
||||
ret= burn_fifo_inquire_status(track->libburn_fifo, &buffer_size,
|
||||
&buffer_free, &buffer_text);
|
||||
if(track->is_from_stdin) {
|
||||
if(ret<0 || buffer_size <= buffer_free) {
|
||||
fprintf(stderr,"\ncdrskin: FATAL : (First track) fifo did not read a single byte from stdin\n");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to obtain ISO 9660 Volume Descriptors and size from fifo.
|
||||
Not an error if there is no ISO 9660. */
|
||||
if(track->iso_fs_descr != NULL)
|
||||
free(track->iso_fs_descr);
|
||||
track->iso_fs_descr = NULL;
|
||||
if(buffer_size - buffer_free >= 64 * 1024) {
|
||||
ret= burn_fifo_peek_data(track->libburn_fifo, buf, 64 * 1024, 0);
|
||||
if(ret == 1) {
|
||||
track->iso_fs_descr = calloc(1, bs);
|
||||
if(track->iso_fs_descr == NULL)
|
||||
return(-1);
|
||||
memcpy(track->iso_fs_descr, buf + bs, bs);
|
||||
ret= Scan_for_iso_size((unsigned char *) buf + bs, &data_image_size, 0);
|
||||
if(ret > 0)
|
||||
track->data_image_size= data_image_size;
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
|
||||
#ifdef Cdrskin_no_cdrfifO
|
||||
|
||||
int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
|
||||
{
|
||||
return(Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0));
|
||||
}
|
||||
|
||||
#else /* Cdrskin_no_cdrfifO */
|
||||
|
||||
int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
|
||||
{
|
||||
int ret,buffer_fill,buffer_space;
|
||||
double data_image_size;
|
||||
|
||||
if(track->fifo==NULL || fifo_start_at==0)
|
||||
if(fifo_start_at==0)
|
||||
return(2);
|
||||
if(track->fifo==NULL) {
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
ret= Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0);
|
||||
return(ret);
|
||||
#else
|
||||
return(2);
|
||||
#endif
|
||||
}
|
||||
if(fifo_start_at>0 && fifo_start_at<track->fifo_size)
|
||||
printf(
|
||||
"cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n",
|
||||
@ -1555,6 +1714,7 @@ int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
#endif /* ! Cdrskin_extra_leaN */
|
||||
|
||||
|
||||
@ -1566,10 +1726,11 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
|
||||
/*
|
||||
bit0= debugging verbosity
|
||||
bit1= apply padding hack (<<< should be unused for now)
|
||||
bit2= permission to use O_DIRECT (if enabled at compile time)
|
||||
*/
|
||||
{
|
||||
struct burn_track *tr;
|
||||
struct burn_source *src= NULL;
|
||||
struct burn_source *src= NULL, *fd_src= NULL;
|
||||
double padding,lib_padding;
|
||||
int ret,sector_pad_up;
|
||||
double fixed_size;
|
||||
@ -1581,7 +1742,7 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
|
||||
|
||||
/* Note: track->track_type may get set in here */
|
||||
if(track->source_fd==-1) {
|
||||
ret= Cdrtrack_open_source_path(track,&source_fd,(flag&1));
|
||||
ret= Cdrtrack_open_source_path(track, &source_fd, flag & (4 | 1));
|
||||
if(ret<=0)
|
||||
goto ex;
|
||||
}
|
||||
@ -1626,6 +1787,41 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
|
||||
}
|
||||
src= burn_fd_source_new(track->source_fd,-1,(off_t) fixed_size);
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
|
||||
if(src != NULL && track->fifo == NULL) {
|
||||
int fifo_enabled, fifo_size, fifo_start_at, chunksize, chunks;
|
||||
int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled,
|
||||
int *fifo_size, int *fifo_start_at, int flag);
|
||||
|
||||
Cdrskin_get_fifo_par(track->boss, &fifo_enabled, &fifo_size, &fifo_start_at,
|
||||
0);
|
||||
fd_src= src;
|
||||
|
||||
if(track->track_type == BURN_AUDIO)
|
||||
chunksize= 2352;
|
||||
else if (track->cdxa_conversion == 1)
|
||||
chunksize= 2056;
|
||||
else
|
||||
chunksize= 2048;
|
||||
chunks= fifo_size / chunksize;
|
||||
if(chunks > 1 && fifo_enabled) {
|
||||
src= burn_fifo_source_new(fd_src, chunksize, chunks,
|
||||
(chunksize * chunks >= 128 * 1024));
|
||||
if((flag & 1) || src == NULL)
|
||||
fprintf(stderr, "cdrskin_DEBUG: %s libburn fifo of %d bytes\n",
|
||||
src != NULL ? "installed" : "failed to install",
|
||||
chunksize * chunks);
|
||||
track->libburn_fifo= src;
|
||||
if(src == NULL) {
|
||||
src= fd_src;
|
||||
fd_src= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
if(src==NULL) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : Could not create libburn data source object\n");
|
||||
@ -1638,6 +1834,8 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
|
||||
burn_session_add_track(session,tr,BURN_POS_END);
|
||||
ret= 1;
|
||||
ex:
|
||||
if(fd_src!=NULL)
|
||||
burn_source_free(fd_src);
|
||||
if(src!=NULL)
|
||||
burn_source_free(src);
|
||||
return(ret);
|
||||
@ -1688,7 +1886,7 @@ int Cdrtrack_get_sectors(struct CdrtracK *track, int flag)
|
||||
}
|
||||
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
|
||||
/** Try to read bytes from the track's fifo outlet and eventually discard
|
||||
them. Not to be called unless the track is completely written.
|
||||
@ -1709,7 +1907,7 @@ int Cdrtrack_has_input_left(struct CdrtracK *track, int flag)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_extra_leaN */
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -2136,6 +2334,8 @@ int Cdrpreskin_fallback(struct CdrpreskiN *preskin, int argc, char **argv,
|
||||
int i, wp= 1;
|
||||
char *ept, *upt;
|
||||
|
||||
if(preskin->fallback_program[0] == 0)
|
||||
return(1);
|
||||
if(getuid()!=geteuid() && !preskin->allow_setuid) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : uid and euid differ. Will not start external fallback program.\n");
|
||||
@ -2672,6 +2872,9 @@ set_dev:;
|
||||
printf(
|
||||
" --drive_scsi_exclusive try to exclusively reserve device files\n");
|
||||
printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n");
|
||||
printf(" dvd_obs=\"default\"|number\n");
|
||||
printf(
|
||||
" set number of bytes per DVD/BD write: 32k or 64k\n");
|
||||
#ifdef Cdrskin_burn_drive_eject_brokeN
|
||||
printf(
|
||||
" eject_device=<path> set the device address for command eject\n");
|
||||
@ -2722,6 +2925,11 @@ set_dev:;
|
||||
printf(
|
||||
" byte addresses below that number.\n");
|
||||
#endif
|
||||
printf(" stdio_sync=\"default\"|\"off\"|number\n");
|
||||
printf(
|
||||
" set number of bytes after which to force output\n");
|
||||
printf(
|
||||
" to drives with prefix \"stdio:\".\n");
|
||||
|
||||
#ifdef Cdrskin_allow_libburn_taO
|
||||
printf(
|
||||
@ -2787,7 +2995,9 @@ see_cdrskin_eng_html:;
|
||||
"\tdev=target\tpseudo-SCSI target to use as CD-Recorder\n");
|
||||
fprintf(stderr,
|
||||
"\tgracetime=#\tset the grace time before starting to write to #.\n");
|
||||
fprintf(stderr,"\t-v\t\tincrement verbose level by one\n");
|
||||
fprintf(stderr,"\t-v\t\tincrement general verbose level by one\n");
|
||||
fprintf(stderr,
|
||||
"\t-V\t\tincrement SCSI command transport verbose level by one\n");
|
||||
fprintf(stderr,
|
||||
"\tdriveropts=opt\topt= one of {burnfree,noburnfree,help}\n");
|
||||
fprintf(stderr,
|
||||
@ -2914,12 +3124,16 @@ see_cdrskin_eng_html:;
|
||||
} else if(strcmp(argv[i],"-tao")==0) {
|
||||
strcpy(o->write_mode_name,"TAO");
|
||||
|
||||
} else if(strcmp(argv[i],"-V")==0 || strcmp(argv[i],"-Verbose")==0) {
|
||||
burn_set_scsi_logging(2 | 4); /* log SCSI to stderr */
|
||||
|
||||
} else if(strcmp(argv[i],"-v")==0 || strcmp(argv[i],"-verbose")==0) {
|
||||
(o->verbosity)++;
|
||||
ClN(printf("cdrskin: verbosity level : %d\n",o->verbosity));
|
||||
set_severities:;
|
||||
if(o->verbosity>=Cdrskin_verbose_debuG)
|
||||
Cdrpreskin_set_severities(o,"NEVER","DEBUG",0);
|
||||
|
||||
} else if(strcmp(argv[i],"-vv")==0 || strcmp(argv[i],"-vvv")==0 ||
|
||||
strcmp(argv[i],"-vvvv")==0) {
|
||||
(o->verbosity)+= strlen(argv[i])-1;
|
||||
@ -3101,19 +3315,10 @@ ex:;
|
||||
|
||||
|
||||
/** List of furter wishes towards libburn:
|
||||
- write mode which does not demand a track size in advance
|
||||
- obtain minimum drive speed (for cdrskin -atip)
|
||||
- obtain MMC profile of inserted media (for cdrskin -v -atip)
|
||||
- a possibility to implement cdrskin -multi
|
||||
- a possibilty to implement cdrskin -reset
|
||||
*/
|
||||
|
||||
|
||||
/** <<< Hopefully obsolete:
|
||||
Limit to prevent int rollovers within libburn as long as not everything is
|
||||
changed to 64 bit off_t : 2 GB minus 800 MB for eventual computations.
|
||||
#define Cdrskin_tracksize_maX 1308622848
|
||||
*/
|
||||
#define Cdrskin_tracksize_maX 1024.0*1024.0*1024.0*1024.0
|
||||
|
||||
|
||||
@ -3162,6 +3367,8 @@ struct CdrskiN {
|
||||
int dummy_mode;
|
||||
int force_is_set;
|
||||
int stream_recording_is_set; /* see burn_write_opts_set_stream_recording() */
|
||||
int dvd_obs; /* DVD write chunk size: 0, 32k or 64k */
|
||||
int stdio_sync; /* stdio fsync interval: -1, 0, >=32 */
|
||||
int single_track;
|
||||
int prodvd_cli_compatible;
|
||||
|
||||
@ -3380,6 +3587,8 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
|
||||
o->dummy_mode= 0;
|
||||
o->force_is_set= 0;
|
||||
o->stream_recording_is_set= 0;
|
||||
o->dvd_obs= 0;
|
||||
o->stdio_sync= 0;
|
||||
o->single_track= 0;
|
||||
o->prodvd_cli_compatible= 0;
|
||||
o->do_devices= 0;
|
||||
@ -3554,6 +3763,8 @@ int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled,
|
||||
}
|
||||
|
||||
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
|
||||
/** Create and install fifo objects between track data sources and libburn.
|
||||
The sources and parameters are known to skin.
|
||||
@return <=0 error, 1 success
|
||||
@ -3563,6 +3774,20 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
|
||||
struct CdrfifO *ff= NULL;
|
||||
int ret,i,hflag;
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
|
||||
int profile_number;
|
||||
char profile_name[80];
|
||||
|
||||
/* Refuse here and thus use libburn fifo only with single track, non-CD */
|
||||
ret= burn_disc_get_profile(skin->drives[skin->driveno].drive,
|
||||
&profile_number, profile_name);
|
||||
if(profile_number != 0x09 && profile_number != 0x0a &&
|
||||
skin->track_counter == 1)
|
||||
return(1);
|
||||
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
skin->fifo= NULL;
|
||||
for(i=0;i<skin->track_counter;i++) {
|
||||
hflag= (skin->verbosity>=Cdrskin_verbose_debuG);
|
||||
@ -3594,6 +3819,8 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
|
||||
/** Read data into the track fifos until either #1 is full or its data source
|
||||
is exhausted.
|
||||
@ -3936,7 +4163,7 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag)
|
||||
if(skin->preskin->abort_handler==3)
|
||||
fprintf(stderr,"cdrskin: ABORT : Trying to ignore any further signals\n");
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
if(skin->fifo!=NULL)
|
||||
Cdrfifo_close_all(skin->fifo,0);
|
||||
#endif
|
||||
@ -5831,16 +6058,28 @@ int Cdrskin_burn_pacifier(struct CdrskiN *skin,
|
||||
bit0= growisofs style
|
||||
*/
|
||||
{
|
||||
double bytes_to_write,written_bytes= 0.0,written_total_bytes= 0.0,buffer_size;
|
||||
double bytes_to_write= 0.0;
|
||||
double written_bytes= 0.0,written_total_bytes= 0.0;
|
||||
double fixed_size,padding,sector_size,speed_factor;
|
||||
double measured_total_speed,measured_speed;
|
||||
double elapsed_time,elapsed_total_time,current_time;
|
||||
double estim_time,estim_minutes,estim_seconds,percent;
|
||||
int ret,fifo_percent,fill,space,advance_interval=0,new_mb,old_mb,time_to_tell;
|
||||
int fs,bs,old_track_idx,buffer_fill,formatting= 0,use_data_image_size;
|
||||
char fifo_text[80],mb_text[40];
|
||||
int ret,fifo_percent,fill,advance_interval=0,new_mb,old_mb,time_to_tell;
|
||||
int old_track_idx,buffer_fill,formatting= 0,use_data_image_size;
|
||||
char fifo_text[80],mb_text[40], pending[40];
|
||||
char *debug_mark= ""; /* use this to prepend a marker text for experiments */
|
||||
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
double buffer_size;
|
||||
int fs, bs, space;
|
||||
#endif
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
struct burn_source *current_fifo= NULL;
|
||||
int size, free_space;
|
||||
char *status_text= "";
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
/* for debugging */
|
||||
static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out;
|
||||
|
||||
@ -5944,9 +6183,14 @@ thank_you_for_patience:;
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS) {
|
||||
if(skin->is_writing)
|
||||
fprintf(stderr,"\n");
|
||||
pending[0]= 0;
|
||||
/*
|
||||
if(bytes_to_write > 0 && skin->verbosity >= Cdrskin_verbose_debuG)
|
||||
sprintf(pending, " pnd %.f", bytes_to_write - written_total_bytes);
|
||||
*/
|
||||
fprintf(stderr,
|
||||
"\rcdrskin: thank you for being patient for %.f seconds ",
|
||||
elapsed_total_time);
|
||||
"\rcdrskin: thank you for being patient for %.f seconds%21.21s",
|
||||
elapsed_total_time, pending);
|
||||
}
|
||||
advance_interval= 1;
|
||||
}
|
||||
@ -6011,6 +6255,37 @@ thank_you_for_patience:;
|
||||
fifo_text[0]= 0;
|
||||
curr_fifo_in= last_fifo_in;
|
||||
curr_fifo_out= last_fifo_out;
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
|
||||
/* Inquire fifo fill and format fifo pacifier text */
|
||||
if(skin->fifo == NULL && skin->supposed_track_idx >= 0 &&
|
||||
skin->supposed_track_idx < skin->track_counter &&
|
||||
skin->fifo_size > 0) {
|
||||
Cdrtrack_get_libburn_fifo(skin->tracklist[skin->supposed_track_idx],
|
||||
¤t_fifo, 0);
|
||||
if(current_fifo != NULL) {
|
||||
ret= burn_fifo_inquire_status(current_fifo, &size, &free_space,
|
||||
&status_text);
|
||||
if(ret <= 0 || ret >= 4) {
|
||||
strcpy(fifo_text, "(fifo 0%) ");
|
||||
} else if(ret == 1) {
|
||||
burn_fifo_next_interval(current_fifo, &fill);
|
||||
fifo_percent= 100.0 * ((double) fill) / (double) size;
|
||||
if(fifo_percent<100 && fill>0)
|
||||
fifo_percent++;
|
||||
sprintf(fifo_text, "(fifo %3d%%) ", fifo_percent);
|
||||
} else
|
||||
strcpy(fifo_text, "(fifo 100%) ");
|
||||
} else if(skin->fifo_size > 0) {
|
||||
strcpy(fifo_text, "(fifo 100%) ");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
|
||||
if(skin->fifo!=NULL) {
|
||||
ret= Cdrfifo_get_buffer_state(skin->fifo,&fill,&space,0);
|
||||
buffer_size= fill+space;
|
||||
@ -6039,6 +6314,9 @@ thank_you_for_patience:;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
if(skin->supposed_track_idx >= 0 &&
|
||||
skin->supposed_track_idx < skin->track_counter) {
|
||||
/* fixed_size,padding are fetched above via Cdrtrack_get_size() */;
|
||||
@ -6549,7 +6827,8 @@ int Cdrskin_direct_write(struct CdrskiN *skin, int flag)
|
||||
&source_path,&source_fd,&is_from_stdin,0);
|
||||
if(source_fd==-1) {
|
||||
ret= Cdrtrack_open_source_path(skin->tracklist[0],&source_fd,
|
||||
2|(skin->verbosity>=Cdrskin_verbose_debuG));
|
||||
2 | (skin->verbosity >= Cdrskin_verbose_debuG) |
|
||||
(4 * (skin->fifo_size >= 256 * 1024)));
|
||||
if(ret<=0)
|
||||
goto ex;
|
||||
}
|
||||
@ -6716,15 +6995,19 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
|
||||
struct burn_progress p;
|
||||
struct burn_drive *drive;
|
||||
int ret,loop_counter= 0,max_track= -1,i,hflag,nwa,num, wrote_well= 2;
|
||||
int fifo_disabled= 0,fifo_percent,total_min_fill,min_buffer_fill= 101;
|
||||
int fifo_disabled= 0, min_buffer_fill= 101;
|
||||
int use_data_image_size, needs_early_fifo_fill= 0,iso_size= -1;
|
||||
double put_counter,get_counter,empty_counter,full_counter;
|
||||
double start_time,last_time;
|
||||
double total_count= 0.0,last_count= 0.0,size,padding,sector_size= 2048.0;
|
||||
char *doing;
|
||||
char *source_path;
|
||||
int source_fd, is_from_stdin;
|
||||
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
double put_counter, get_counter, empty_counter, full_counter;
|
||||
int total_min_fill, fifo_percent;
|
||||
#endif
|
||||
|
||||
if(skin->tell_media_space)
|
||||
doing= "estimating";
|
||||
else
|
||||
@ -6783,6 +7066,11 @@ burn_failed:;
|
||||
hflag= (skin->verbosity>=Cdrskin_verbose_debuG);
|
||||
if(i==skin->track_counter-1)
|
||||
Cdrtrack_ensure_padding(skin->tracklist[i],hflag&1);
|
||||
|
||||
/* if(skin->fifo_size >= 256 * 1024) */
|
||||
|
||||
hflag|= 4;
|
||||
|
||||
ret= Cdrtrack_add_to_session(skin->tracklist[i],i,session,hflag);
|
||||
if(ret<=0) {
|
||||
fprintf(stderr,"cdrskin: FATAL : Cannot add track %d to session.\n",i+1);
|
||||
@ -6918,6 +7206,13 @@ burn_failed:;
|
||||
#ifdef Cdrskin_libburn_has_stream_recordinG
|
||||
burn_write_opts_set_stream_recording(o, skin->stream_recording_is_set);
|
||||
#endif
|
||||
#ifdef Cdrskin_dvd_obs_default_64K
|
||||
if(skin->dvd_obs == 0)
|
||||
burn_write_opts_set_dvd_obs(o, 64 * 1024);
|
||||
else
|
||||
#endif
|
||||
burn_write_opts_set_dvd_obs(o, skin->dvd_obs);
|
||||
burn_write_opts_set_stdio_fsync(o, skin->stdio_sync);
|
||||
|
||||
if(skin->dummy_mode) {
|
||||
fprintf(stderr,
|
||||
@ -7041,6 +7336,14 @@ fifo_filling_failed:;
|
||||
if(skin->fifo==NULL || fifo_disabled) {
|
||||
usleep(20000);
|
||||
} else {
|
||||
|
||||
#ifdef Cdrskin_no_cdrfifO
|
||||
|
||||
/* Should never happen as skin->fifo should be NULL */
|
||||
usleep(20000);
|
||||
|
||||
#else /* Cdrskin_no_cdrfifO */
|
||||
|
||||
ret= Cdrfifo_try_to_work(skin->fifo,20000,NULL,NULL,0);
|
||||
if(ret<0) {
|
||||
int abh;
|
||||
@ -7066,7 +7369,11 @@ fifo_filling_failed:;
|
||||
fprintf(stderr,"\ncdrskin_debug: fifo ended work with ret=%d\n",ret);
|
||||
fifo_disabled= 1;
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
}
|
||||
|
||||
#else /* ! Cdrskin_extra_leaN */
|
||||
usleep(20000);
|
||||
#endif /* Cdrskin_extra_leaN */
|
||||
@ -7106,6 +7413,19 @@ fifo_filling_failed:;
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
|
||||
#ifdef Cdrskin_use_libburn_fifO
|
||||
|
||||
if(skin->fifo == NULL && skin->verbosity>=Cdrskin_verbose_progresS) {
|
||||
/* >>> this should rather be done for each track
|
||||
(for now this libburn_fifo should only be used with single track)
|
||||
*/
|
||||
Cdrtrack_report_fifo(skin->tracklist[skin->track_counter - 1], 0);
|
||||
}
|
||||
|
||||
#endif /* Cdrskin_use_libburn_fifO */
|
||||
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
|
||||
if(skin->fifo!=NULL && skin->fifo_size>0 && wrote_well) {
|
||||
int dummy,final_fill;
|
||||
Cdrfifo_get_buffer_state(skin->fifo,&final_fill,&dummy,0);
|
||||
@ -7153,6 +7473,11 @@ fifo_full_at_end:;
|
||||
"Cdrskin: fifo was %.f times empty and %.f times full, min fill was %d%%.\n",
|
||||
empty_counter,full_counter,fifo_percent);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS) {
|
||||
drive_status= burn_drive_get_status(drive, &p);
|
||||
|
||||
#ifdef Cdrskin_libburn_has_buffer_min_filL
|
||||
@ -7450,7 +7775,7 @@ int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag)
|
||||
""
|
||||
};
|
||||
static char ignored_full_options[][41]= {
|
||||
"-d", "-Verbose", "-V", "-silent", "-s", "-setdropts", "-prcap",
|
||||
"-d", "-silent", "-s", "-setdropts", "-prcap",
|
||||
"-reset", "-abort", "-overburn", "-ignsize", "-useinfo",
|
||||
"-fix", "-nofix",
|
||||
"-raw", "-raw96p", "-raw16", "-raw96r",
|
||||
@ -7792,6 +8117,22 @@ set_driveropts:;
|
||||
} else if(strcmp(argv[i],"-dummy")==0) {
|
||||
skin->dummy_mode= 1;
|
||||
|
||||
} else if(strncmp(argv[i], "-dvd_obs=", 9)==0) {
|
||||
value_pt= argv[i] + 9;
|
||||
goto dvd_obs;
|
||||
} else if(strncmp(argv[i], "dvd_obs=", 8)==0) {
|
||||
value_pt= argv[i] + 8;
|
||||
dvd_obs:;
|
||||
if(strcmp(value_pt, "default") == 0)
|
||||
num= 0;
|
||||
else
|
||||
num = Scanf_io_size(value_pt,0);
|
||||
if(num != 0 && num != 32768 && num != 65536) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : Option dvd_obs= accepts only sizes 0, 32k, 64k\n");
|
||||
} else
|
||||
skin->dvd_obs= num;
|
||||
|
||||
} else if(strcmp(argv[i],"-eject")==0) {
|
||||
skin->do_eject= 1;
|
||||
if(skin->verbosity>=Cdrskin_verbose_cmD)
|
||||
@ -8182,6 +8523,26 @@ set_speed:;
|
||||
if(skin->verbosity>=Cdrskin_verbose_cmD)
|
||||
ClN(printf("cdrskin: speed : %f\n",skin->x_speed));
|
||||
|
||||
} else if(strncmp(argv[i], "-stdio_sync=", 12)==0) {
|
||||
value_pt= argv[i] + 12;
|
||||
goto stdio_sync;
|
||||
} else if(strncmp(argv[i], "stdio_sync=", 11)==0) {
|
||||
value_pt= argv[i] + 11;
|
||||
stdio_sync:;
|
||||
if(strcmp(value_pt, "default") == 0 || strcmp(value_pt, "on") == 0)
|
||||
num= 0;
|
||||
else if(strcmp(value_pt, "off") == 0)
|
||||
num= -1;
|
||||
else
|
||||
num = Scanf_io_size(value_pt,0);
|
||||
if(num > 0)
|
||||
num/= 2048;
|
||||
if(num != -1 && num != 0 && (num < 32 || num > 512 * 1024)) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : Option stdio_sync= accepts only sizes -1, 0, 32k ... 1g\n");
|
||||
} else
|
||||
skin->stdio_sync= num;
|
||||
|
||||
} else if(strncmp(argv[i],"-stream_recording=",18)==0) {
|
||||
value_pt= argv[i]+18;
|
||||
goto set_stream_recording;
|
||||
@ -8261,6 +8622,8 @@ track_too_large:;
|
||||
if(skin->smallest_tsize<0 || skin->smallest_tsize>skin->fixed_size)
|
||||
skin->smallest_tsize= skin->fixed_size;
|
||||
|
||||
} else if(strcmp(argv[i],"-V")==0 || strcmp(argv[i],"-Verbose")==0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
} else if(strcmp(argv[i],"-v")==0 || strcmp(argv[i],"-verbose")==0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
} else if(strcmp(argv[i],"-vv")==0 || strcmp(argv[i],"-vvv")==0 ||
|
||||
@ -8451,13 +8814,13 @@ ignore_unknown:;
|
||||
if(skin->track_counter>0) {
|
||||
skin->do_burn= 1;
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
#ifndef Cdrskin_no_cdrfifO
|
||||
if(!skin->do_direct_write) {
|
||||
ret= Cdrskin_attach_fifo(skin,0);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
}
|
||||
#endif /* ! Cdrskin_extra_leaN */
|
||||
#endif /* ! Cdrskin_no_cdrfifO */
|
||||
|
||||
}
|
||||
return(1);
|
||||
|
@ -61,7 +61,7 @@ via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||
GPL software included:<BR>
|
||||
</H2>
|
||||
<DL>
|
||||
<DT>libburn-0.7.2</DT>
|
||||
<DT>libburn-0.7.4</DT>
|
||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||
developed and maintained since August 2006 by
|
||||
Thomas Schmitt from team of libburnia-project.org)
|
||||
@ -193,8 +193,8 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
|
||||
<P>
|
||||
<DL>
|
||||
<DT>Download as source code (see README):</DT>
|
||||
<DD><A HREF="cdrskin-0.7.2.pl00.tar.gz">cdrskin-0.7.2.pl00.tar.gz</A>
|
||||
(780 KB).
|
||||
<DD><A HREF="cdrskin-0.7.4.pl00.tar.gz">cdrskin-0.7.4.pl00.tar.gz</A>
|
||||
(810 KB).
|
||||
</DD>
|
||||
<DD>
|
||||
The cdrskin tarballs are source code identical with libburn releases
|
||||
@ -245,18 +245,22 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
||||
<P>
|
||||
Enhancements towards previous stable version cdrskin-0.7.0.pl00:
|
||||
<UL>
|
||||
<LI>Better interpretation of options -mode2, -xa, -xa1, -xa2</LI>
|
||||
<LI>New option --xa1-ignore</LI>
|
||||
<LI>New -atip report lines "Product Id:" and "Producer:"</LI>
|
||||
<LI>Emulation of some -minfo output</LI>
|
||||
<LI>Implemented option -V for logging of SCSI commands</LI>
|
||||
<LI>New options dvd_obs= and stdio_fsync=</LI>
|
||||
<LI>New ./configure options --enable-track-src-odirect, --enable-dvd-obs-64k
|
||||
</LI>
|
||||
<LI>New compile_cdrskin.sh option -dvd_obs_64k</LI>
|
||||
<!--
|
||||
<LI>none</LI>
|
||||
-->
|
||||
</UL>
|
||||
|
||||
Bug fixes towards cdrskin-0.7.0.pl00:
|
||||
Bug fixes towards cdrskin-0.7.2.pl00:
|
||||
<UL>
|
||||
<LI>CD TAO sessions with multiple tracks did not work in -dummy mode</LI>
|
||||
<LI>Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.</LI>
|
||||
<LI>Workaround for Pioneer DVR-216D which did not always eject the tray.</LI>
|
||||
<LI>DVD DAO track size was rounded up much too generously</LI>
|
||||
<LI>SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30</LI>
|
||||
<!--
|
||||
<LI>none</LI>
|
||||
-->
|
||||
@ -266,8 +270,8 @@ Bug fixes towards cdrskin-0.7.0.pl00:
|
||||
|
||||
<P>
|
||||
<DL>
|
||||
<DT><H3>Development snapshot, version 0.7.3 :</H3></DT>
|
||||
<DD>Enhancements towards current stable version 0.7.2.pl00:
|
||||
<DT><H3>Development snapshot, version 0.7.5 :</H3></DT>
|
||||
<DD>Enhancements towards current stable version 0.7.4.pl00:
|
||||
<UL>
|
||||
<LI>none yet</LI>
|
||||
<!--
|
||||
@ -276,7 +280,7 @@ Bug fixes towards cdrskin-0.7.0.pl00:
|
||||
</UL>
|
||||
</DD>
|
||||
|
||||
<DD>Bug fixes towards cdrskin-0.7.2.pl00:
|
||||
<DD>Bug fixes towards cdrskin-0.7.4.pl00:
|
||||
<UL>
|
||||
<LI>none yet</LI>
|
||||
<!--
|
||||
@ -285,10 +289,10 @@ Bug fixes towards cdrskin-0.7.0.pl00:
|
||||
</DD>
|
||||
|
||||
<DD> </DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 0.7.3</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.3 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.3 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.3)</A></DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 0.7.5</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.5 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.5 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.5)</A></DD>
|
||||
<DD> </DD>
|
||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||
@ -308,8 +312,8 @@ admins with full system souvereignty.</DT>
|
||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||
</DD>
|
||||
<DD>
|
||||
<A HREF="cdrskin-0.7.3.tar.gz">cdrskin-0.7.3.tar.gz</A>
|
||||
(780 KB).
|
||||
<A HREF="cdrskin-0.7.5.tar.gz">cdrskin-0.7.5.tar.gz</A>
|
||||
(810 KB).
|
||||
</DD>
|
||||
|
||||
<!-- This is not offered any more since spring 2008
|
||||
|
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2009.10.12.080001"
|
||||
#define Cdrskin_timestamP "2009.12.06.160001"
|
||||
|
@ -7143,11 +7143,10 @@ Made number transition and activated development documentation
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_7_3
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
[]
|
||||
12 Oct 2009 [2867]
|
||||
cdrskin/changelog.txt
|
||||
Documented changes and release timestamp
|
||||
|
||||
|
||||
------------------------------ release - cdrskin-0.7.2.pl00 - 2009.10.12.080001
|
||||
* Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode
|
||||
* Better interpretation of options -mode2, -xa, -xa1, -xa2
|
||||
@ -7159,10 +7158,441 @@ Documented changes and release timestamp
|
||||
* New API call burn_disc_get_cd_info()
|
||||
* New API call burn_track_set_cdxa_conv()
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 -
|
||||
|
||||
2009.10.12.103503 [2858]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
README
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
cdrskin/cdrskin_eng.html
|
||||
Made number transition to 0.7.3
|
||||
|
||||
12 Oct 2009 [2859]
|
||||
- cdrskin/add_ts_changes_to_libburn_0_7_0
|
||||
- cdrskin/add_ts_changes_to_libburn_0_7_1
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_7_2
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_7_3
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
12 Oct 2009 [2860]
|
||||
cdrskin/changelog.txt
|
||||
Documented changes and release timestamp
|
||||
|
||||
12 Oct 2009 [2861]
|
||||
svn move -m "libburn release 0.7.2 is ready" \
|
||||
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwo \
|
||||
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.12.105750
|
||||
|
||||
|
||||
2009.10.17.131852 [2865] [2864]
|
||||
Makefile.am
|
||||
libburn/libburn.h
|
||||
libburn/sector.c
|
||||
+ libburn/ecma130ab.h
|
||||
+ libburn/ecma130ab.c
|
||||
cdrskin/compile_cdrskin.sh
|
||||
Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 -
|
||||
------------------------------------ cycle - cdrskin-0.7.3 -
|
||||
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
|
||||
|
||||
|
||||
2009.10.19.115722 [2867]
|
||||
libburn/ecma130ab.c
|
||||
Optimizations with parity computation, clarification about nature of logarithms
|
||||
|
||||
2009.10.20.160131 [2868]
|
||||
libburn/libburn.h
|
||||
libburn/ecma130ab.c
|
||||
More optimizations with parity computation
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.20.160131
|
||||
|
||||
|
||||
2009.10.27.100637 [2871]
|
||||
libburn/mmc.c
|
||||
Bug fix: burn_drive->disc_id or burn_drive->disc_app_code altered by stray 0. Thanks to George Danchev.
|
||||
|
||||
2009.10.27.101031 [2872]
|
||||
libburn/sg-freebsd.c
|
||||
Bug fix: Closed memory leak with failure to open device file under FreeBSD. Thanks to George Danchev.
|
||||
|
||||
2009.10.30.134640 [2880]
|
||||
libburn/libburn.h
|
||||
libburn/spc.c
|
||||
libburn/mmc.c
|
||||
libburn/sg-linux.c
|
||||
Test macros for finding reason of stall problem with Pioneer DVD-216D on DVD-R
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.30.134640
|
||||
|
||||
|
||||
2009.11.03.184626 [2881]
|
||||
libburn/libburn.h
|
||||
libburn/mmc.c
|
||||
Test macro for SL_V in mode page 05
|
||||
|
||||
2009.11.04.084506 [2882]
|
||||
libburn/libburn.h
|
||||
libburn/write.c
|
||||
Test macro for SEND OPC INFORMATION before DVD-R track
|
||||
|
||||
2009.11.05.170409 [2883]
|
||||
libburn/libburn.h
|
||||
libburn/transport.h
|
||||
libburn/write.c
|
||||
libburn/sbc.c
|
||||
libburn/mmc.c
|
||||
Test macros for double START UNIT and SET CD SPEED
|
||||
|
||||
2009.11.08.120917 [2884]
|
||||
libburn/mmc.c
|
||||
Corrected allocation length with GET CONFIGURATION
|
||||
|
||||
2009.11.08.121334 [2885]
|
||||
libburn/spc.h
|
||||
libburn/spc.c
|
||||
libburn/mmc.h
|
||||
libburn/sg-linux.c
|
||||
Made SCSI command log more complete and more readable
|
||||
|
||||
2009.11.10.132154 [2886]
|
||||
libburn/mmc.c
|
||||
Avoiding START UNIT before the drive gets released
|
||||
|
||||
2009.11.10.203412 [2887]
|
||||
libburn/libburn.h
|
||||
libburn/write.c
|
||||
libburn/spc.c
|
||||
libburn/sbc.c
|
||||
libburn/mmc.c
|
||||
libburn/sg-linux.c
|
||||
Hopefully solved the endless burn problem with Pioneer DVR-216D
|
||||
|
||||
2009.11.11.100714 [2888]
|
||||
libburn/write.c
|
||||
Increased stdio flush interval from 1 MB to 16 MB
|
||||
|
||||
2009.11.11.100822 [2889]
|
||||
cdrskin/cdrskin.c
|
||||
Reporting number of pending bytes while thanking for patience in -vvv mode
|
||||
|
||||
2009.11.11.105028 [2890]
|
||||
cdrskin/cdrskin.c
|
||||
Silenced a compiler warning about potentially uninitialized variable
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.11.105159
|
||||
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns
|
||||
|
||||
|
||||
11 Nov 2009 [2891]
|
||||
cdrskin/cdrskin_eng.html
|
||||
Updated cdrskin home page about DVR-216D workaround
|
||||
|
||||
2009.11.12.175514 [2892]
|
||||
libburn/libburn.h
|
||||
libburn/init.c
|
||||
libburn/write.c
|
||||
libburn/sg-linux.c
|
||||
Made SCSI logger permanent and controllable via API call
|
||||
|
||||
2009.11.12.175735 [2893]
|
||||
libburn/spc.c
|
||||
libburn/sbc.c
|
||||
libburn/mmc.c
|
||||
Workaround for Pioneer DVR-216D refusal to eject
|
||||
|
||||
2009.11.12.180048 [2894]
|
||||
libburn/drive.c
|
||||
Macro Libburn_pioneer_dvr_216d_dummy_probe_wM for omitting write mode probe
|
||||
|
||||
2009.11.12.180241 [2895]
|
||||
cdrskin/cdrskin.c
|
||||
Implemented option -V for logging of SCSI commands
|
||||
|
||||
2009.11.12.193617 [2896]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Man page entry and help text for option -V
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.12.194644
|
||||
* Implemented option -V for logging of SCSI commands
|
||||
* Workaround for Pioneer DVR-216D refusal to eject
|
||||
|
||||
|
||||
13 Nov 2009 [2898]
|
||||
svn copy -m Branching for libburn bugfix release 0.7.2.pl01 \
|
||||
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo \
|
||||
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01
|
||||
|
||||
2009.11.12.230001 [2899]
|
||||
README
|
||||
libburn/write.c
|
||||
libburn/sbc.c
|
||||
cdrskin/README
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
libburn-0.7.2.pl01 : Workarounds for Pioneer DVR-216D rev 1.09
|
||||
|
||||
13 Nov 2009 [2900]
|
||||
svn move -m libburn bugfix release 0.7.2.pl01 is ready \
|
||||
http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01 \
|
||||
http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwoPl01
|
||||
|
||||
-------------------------------- patch - cdrskin-0.7.2.pl01 - 2009.11.12.230001
|
||||
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns
|
||||
* Workaround for Pioneer DVR-216D refusal to eject
|
||||
|
||||
|
||||
2009.11.15.115923 [2901]
|
||||
libburn/file.c
|
||||
Corrected an outdated remark
|
||||
|
||||
2009.11.15.152541 [2902]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrfifo.c
|
||||
cdrskin/compile_cdrskin.sh
|
||||
New compile_cdrskin.sh option -o_direct (Linux only)
|
||||
|
||||
2009.11.15.153140 [2903]
|
||||
libburn/libburn.h
|
||||
libburn/options.h
|
||||
libburn/options.c
|
||||
libburn/write.c
|
||||
New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
|
||||
|
||||
2009.11.15.165016 [2904]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
New options dvd_obs= and stdio_fsync=
|
||||
|
||||
2009.11.16.165420 [2905]
|
||||
configure.ac
|
||||
Makefile.am
|
||||
libburn/write.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrfifo.h
|
||||
cdrskin/cdrfifo.c
|
||||
cdrskin/cdrskin.1
|
||||
Configure options --enable-cdrskin-fifo-odirect, --enable-dvd-obs-64k
|
||||
|
||||
16 Nov 2009 [2906]
|
||||
cdrskin/compile_cdrskin.sh
|
||||
New compile_cdrskin.sh option -dvd_obs_64k, adapted to new .o names of libburn
|
||||
|
||||
16 Nov 2009 [2907]
|
||||
README
|
||||
cdrskin/README
|
||||
cdrskin/cdrskin_eng.html
|
||||
Updated build instructions of libburn and cdrskin
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.16.180334
|
||||
* New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
|
||||
* New options dvd_obs= and stdio_fsync=
|
||||
* Configure option --enable-dvd-obs-64k
|
||||
* New compile_cdrskin.sh option -dvd_obs_64k
|
||||
|
||||
|
||||
2009.11.17.093602 [2908]
|
||||
configure.ac
|
||||
Makefile.am
|
||||
cdrskin/compile_cdrskin.sh
|
||||
Revoked usage of libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.17.100248
|
||||
|
||||
|
||||
17 Nov 2009 [2912]
|
||||
cdrskin/compile_cdrskin.sh
|
||||
Corrected help text of cdrskin static compile script
|
||||
|
||||
2009.11.18.122713 [2913]
|
||||
libburn/drive.c
|
||||
libburn/spc.c
|
||||
libburn/mmc.h
|
||||
libburn/mmc.c
|
||||
Split automatic drive start function from mmc_function_spy()
|
||||
|
||||
2009.11.18.185733 [2914]
|
||||
libburn/write.c
|
||||
Reserving enough track space for 64 kB write chunks
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.18.190403
|
||||
|
||||
|
||||
2009.11.20.134952 [2915]
|
||||
libburn/libburn.h
|
||||
libburn/write.c
|
||||
libburn/sg-linux.c
|
||||
Experiment about SG_FLAG_DIRECT_IO
|
||||
|
||||
2009.11.20.175854 [2916]
|
||||
cdrskin/cdrfifo.c
|
||||
Avoided use of uninitialized variable
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.21.122202
|
||||
|
||||
|
||||
2009.11.21.191516 [2917]
|
||||
libburn/write.c
|
||||
Longer READ BUFFER CAPACITY interval with DVD/BD writing
|
||||
|
||||
2009.11.21.191717 [2918]
|
||||
cdrskin/cdrskin.c
|
||||
Enabled cdrskin O_DIRECT with fs=0
|
||||
|
||||
2009.11.22.115227 [2919]
|
||||
libburn/write.c
|
||||
Bug fix: DVD DAO track size was rounded up much too generously
|
||||
|
||||
2009.11.23.185725 [2920]
|
||||
configure.ac
|
||||
Makefile.am
|
||||
README
|
||||
libburn/libburn.h
|
||||
libburn/file.h
|
||||
libburn/file.c
|
||||
libburn/async.c
|
||||
libburn/write.c
|
||||
libburn/sg-linux.c
|
||||
libburn/sg-freebsd.c
|
||||
libburn/sg-freebsd-port.c
|
||||
libburn/sg-dummy.c
|
||||
New API calls burn_os_open_track_src() , burn_os_alloc_buffer()
|
||||
|
||||
2009.11.23.193252 [2921]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrfifo.c
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/README
|
||||
Gave up cdrskin specific O_DIRECT compile option
|
||||
|
||||
2009.11.25.122233 [2920]
|
||||
libburn/libburn.h
|
||||
libburn/sg-linux.c
|
||||
libburn/sg-freebsd.c
|
||||
libburn/sg-freebsd-port.c
|
||||
libburn/sg-dummy.c
|
||||
Gave up call burn_os_close_track_src() introduced by rev 2920
|
||||
|
||||
2009.11.25.160153 [2923]
|
||||
libburn/libburn.h
|
||||
libburn/file.c
|
||||
libburn/libdax_msgs.h
|
||||
New API call burn_fifo_fill()
|
||||
|
||||
2009.11.26.144452 [2924]
|
||||
libburn/libburn.h
|
||||
libburn/file.h
|
||||
libburn/file.c
|
||||
New API calls burn_fifo_get_statistics(), burn_fifo_next_interval()
|
||||
|
||||
2009.11.26.211418 [2925]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/compile_cdrskin.sh
|
||||
Compiler option -use_libburn_fifo to switch non-CD from cdrfifo to libburn fifo
|
||||
|
||||
2009.11.28.122436 [2926]
|
||||
libburn/sg-linux.c
|
||||
Using mmap() by default for allocating read buffers
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.28.165658
|
||||
* Bug fix: DVD DAO track size was rounded up much too generously
|
||||
* New API call burn_fifo_fill()
|
||||
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval()
|
||||
* Configure option --enable-track-src-odirect
|
||||
|
||||
|
||||
2009.11.30.100152 [2929]
|
||||
libburn/sbc.c
|
||||
Documented meaning of START/STOP UNIT bits
|
||||
|
||||
2009.12.02.103036 [2930]
|
||||
libburn/write.c
|
||||
Gave up CLOSE TRACK with CD TAO burn runs
|
||||
|
||||
2009.12.05.111822 [2931]
|
||||
libburn/mmc.c
|
||||
Bug fix: SIGSEGV with LG GH22LS30 when inquiring media product id
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.3 - 2009.12.05.112623
|
||||
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30
|
||||
|
||||
|
||||
2009.12.05.142309 [2932]
|
||||
libburn/libburn.h
|
||||
libburn/write.c
|
||||
Made effect of macro Libburn_pioneer_dvr_216d_read_buf_caP unconditional
|
||||
|
||||
2009.12.05.143707 [2933]
|
||||
libburn/mmc.c
|
||||
libburn/sg-linux.c
|
||||
Converted stderr experiment messages to DEBUG messages
|
||||
|
||||
2009.12.06.073404 [2934]
|
||||
libburn/mmc.c
|
||||
Some clarifications about the GH22LS30 problem
|
||||
|
||||
2009.12.06.074622 [2935]
|
||||
libburn/write.c
|
||||
Some clarifications about the Linux throughput problem
|
||||
|
||||
2009.12.06.093847 [2936]
|
||||
cdrskin/compile_cdrskin.sh
|
||||
Now default in cdrskin: use of libburn fifo with DVD and BD single track
|
||||
|
||||
06 Dec 2009 [2937]
|
||||
svn copy -m Branching for libburn release 0.7.4
|
||||
http://svn.libburnia-project.org/libburn/trunk
|
||||
http://svn.libburnia-project.org/libburn/branches/ZeroSevenFour
|
||||
|
||||
|
||||
2009.12.06.160001 [2938]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
README
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
cdrskin/cdrskin_eng.html
|
||||
Made number transition to 0.7.4
|
||||
|
||||
06 Dec 2009 [2939]
|
||||
- cdrskin/add_ts_changes_to_libburn_0_7_2
|
||||
- cdrskin/add_ts_changes_to_libburn_0_7_3
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_7_4
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_7_5
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
[]
|
||||
cdrskin/changelog.txt
|
||||
Documented changes and release timestamp
|
||||
|
||||
------------------------------ release - cdrskin-0.7.4.pl00 - 2009.12.06.160001
|
||||
* Configure options --enable-dvd-obs-64k, --enable-track-src-odirect
|
||||
* New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync()
|
||||
* New API call burn_set_scsi_logging()
|
||||
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(), burn_fifo_fill()
|
||||
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
|
||||
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns
|
||||
* Workaround for Pioneer DVR-216D refusal to eject
|
||||
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30
|
||||
* Bug fix: DVD DAO track size was rounded up much too generously
|
||||
* cdrskin option -V for logging of SCSI commands
|
||||
* New cdrskin options dvd_obs= and stdio_fsync=
|
||||
* New compile_cdrskin.sh option -dvd_obs_64k
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.7.5 -
|
||||
------------------------------------ cycle - cdrskin-0.7.5 -
|
||||
|
||||
===============================================================================
|
||||
TODO
|
||||
@ -7194,6 +7624,9 @@ READ TRACK INFORMATION[#5]:
|
||||
|
||||
------------------------------ end of bugs ---------------------------------
|
||||
|
||||
|
||||
- Make Libburn_stdio_flush_limiT adjustable
|
||||
|
||||
Support for BD-R SRM+POW
|
||||
|
||||
? Provide an option to open track source file O_DIRECT ?
|
||||
|
@ -7,10 +7,16 @@
|
||||
debug_opts="-O2"
|
||||
def_opts=
|
||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||
libvers="-DCdrskin_libburn_0_7_2"
|
||||
cleanup_src_or_obj="libburn/cleanup.o"
|
||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||
fifo_opts="-DCdrskin_use_libburn_fifO"
|
||||
libvers="-DCdrskin_libburn_0_7_4"
|
||||
|
||||
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
||||
# burn="libburn/libburn_libburn_la-"
|
||||
burn="libburn/"
|
||||
|
||||
cleanup_src_or_obj="$burn"cleanup.o
|
||||
libdax_msgs_o="$burn"libdax_msgs.o
|
||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||
do_strip=0
|
||||
static_opts=
|
||||
warn_opts="-Wall"
|
||||
@ -31,20 +37,20 @@ do
|
||||
then
|
||||
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
||||
libdax_audioxtr_o=
|
||||
libdax_msgs_o="libburn/message.o"
|
||||
libdax_msgs_o="$burn"message.o
|
||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
||||
elif test "$i" = "-libburn_0_7_2"
|
||||
elif test "$i" = "-libburn_0_7_4"
|
||||
then
|
||||
libvers="-DCdrskin_libburn_0_7_2"
|
||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||
cleanup_src_or_obj="libburn/cleanup.o"
|
||||
libvers="-DCdrskin_libburn_0_7_4"
|
||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||
libdax_msgs_o="$burn"libdax_msgs.o
|
||||
cleanup_src_or_obj="$burn"cleanup.o
|
||||
elif test "$i" = "-libburn_svn"
|
||||
then
|
||||
libvers="-DCdrskin_libburn_0_7_3"
|
||||
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||
cleanup_src_or_obj="libburn/cleanup.o"
|
||||
libvers="-DCdrskin_libburn_0_7_5"
|
||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||
libdax_msgs_o="$burn"libdax_msgs.o
|
||||
cleanup_src_or_obj="$burn"cleanup.o
|
||||
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||
then
|
||||
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
||||
@ -55,6 +61,9 @@ do
|
||||
elif test "$i" = "-no_largefile"
|
||||
then
|
||||
largefile_opts=
|
||||
elif test "$i" = "-dvd_obs_64k"
|
||||
then
|
||||
def_opts="$def_opts -DCdrskin_dvd_obs_default_64K"
|
||||
elif test "$i" = "-do_not_compile_cdrskin"
|
||||
then
|
||||
compile_cdrskin=0
|
||||
@ -66,6 +75,16 @@ do
|
||||
elif test "$i" = "-do_strip"
|
||||
then
|
||||
do_strip=1
|
||||
elif test "$i" = "-use_libburn_fifo"
|
||||
then
|
||||
fifo_opts="-DCdrskin_use_libburn_fifO"
|
||||
elif test "$i" = "-use_no_libburn_fifo"
|
||||
then
|
||||
fifo_opts=""
|
||||
elif test "$i" = "-use_no_cdrfifo"
|
||||
then
|
||||
fifo_source=
|
||||
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
||||
elif test "$i" = "-g"
|
||||
then
|
||||
debug_opts="-g"
|
||||
@ -75,9 +94,12 @@ do
|
||||
echo "Options:"
|
||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||
echo " -compile_dewav compile program test/dewav without libburn."
|
||||
echo " -libburn_0_7_2 set macro to match libburn-0.7.2"
|
||||
echo " -libburn_0_7_4 set macro to match libburn-0.7.4"
|
||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
||||
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
||||
echo " -experimental use newly introduced libburn features."
|
||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
||||
echo " -do_diet produce capability reduced lean version."
|
||||
@ -98,13 +120,14 @@ echo "Build timestamp : $timestamp"
|
||||
|
||||
if test "$compile_cdrskin"
|
||||
then
|
||||
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj"
|
||||
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj"
|
||||
cc -I. \
|
||||
$warn_opts \
|
||||
$static_opts \
|
||||
$debug_opts \
|
||||
$libvers \
|
||||
$largefile_opts \
|
||||
$fifo_opts \
|
||||
$def_opts \
|
||||
\
|
||||
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
||||
@ -116,30 +139,31 @@ then
|
||||
\
|
||||
$cleanup_src_or_obj \
|
||||
\
|
||||
libburn/async.o \
|
||||
libburn/debug.o \
|
||||
libburn/drive.o \
|
||||
libburn/file.o \
|
||||
libburn/init.o \
|
||||
libburn/options.o \
|
||||
libburn/source.o \
|
||||
libburn/structure.o \
|
||||
"$burn"async.o \
|
||||
"$burn"debug.o \
|
||||
"$burn"drive.o \
|
||||
"$burn"file.o \
|
||||
"$burn"init.o \
|
||||
"$burn"options.o \
|
||||
"$burn"source.o \
|
||||
"$burn"structure.o \
|
||||
\
|
||||
libburn/sg.o \
|
||||
libburn/write.o \
|
||||
libburn/read.o \
|
||||
"$burn"sg.o \
|
||||
"$burn"write.o \
|
||||
"$burn"read.o \
|
||||
$libdax_audioxtr_o \
|
||||
$libdax_msgs_o \
|
||||
\
|
||||
libburn/mmc.o \
|
||||
libburn/sbc.o \
|
||||
libburn/spc.o \
|
||||
libburn/util.o \
|
||||
"$burn"mmc.o \
|
||||
"$burn"sbc.o \
|
||||
"$burn"spc.o \
|
||||
"$burn"util.o \
|
||||
\
|
||||
libburn/sector.o \
|
||||
libburn/toc.o \
|
||||
"$burn"sector.o \
|
||||
"$burn"toc.o \
|
||||
\
|
||||
libburn/crc.o \
|
||||
"$burn"crc.o \
|
||||
"$burn"ecma130ab.o \
|
||||
\
|
||||
-lpthread
|
||||
|
||||
@ -182,8 +206,8 @@ then
|
||||
-DDewav_without_libburN \
|
||||
-o test/dewav \
|
||||
test/dewav.c \
|
||||
libburn/libdax_audioxtr.o \
|
||||
libburn/libdax_msgs.o \
|
||||
"$burn"libdax_audioxtr.o \
|
||||
"$burn"libdax_msgs.o \
|
||||
\
|
||||
-lpthread
|
||||
|
||||
|
49
configure.ac
49
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libburn], [0.7.2], [http://libburnia-project.org])
|
||||
AC_INIT([libburn], [0.7.4], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -75,6 +75,7 @@ dnl 0.6.6 = libburn.so.4.31.0
|
||||
dnl 0.6.8 = libburn.so.4.33.0
|
||||
dnl 0.7.0 = libburn.so.4.35.0
|
||||
dnl 0.7.2 = libburn.so.4.37.0
|
||||
dnl 0.7.4 = libburn.so.4.39.0
|
||||
dnl
|
||||
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||
@ -100,7 +101,7 @@ dnl
|
||||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||
BURN_MAJOR_VERSION=0
|
||||
BURN_MINOR_VERSION=7
|
||||
BURN_MICRO_VERSION=2
|
||||
BURN_MICRO_VERSION=4
|
||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
|
||||
AC_SUBST(BURN_MAJOR_VERSION)
|
||||
@ -111,15 +112,15 @@ AC_SUBST(BURN_VERSION)
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
dnl
|
||||
dnl ts A91012
|
||||
dnl ### This is the release version libburn-0.7.2 = libburn.so.4.37.0
|
||||
dnl This is the development version after above release version
|
||||
dnl ts A91206
|
||||
dnl This is the release version libburn-0.7.4 = libburn.so.4.39.0
|
||||
dnl ### This is the development version after above release version
|
||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||
dnl
|
||||
dnl SONAME = 41 - 37 = 4 . Linux library name = libburn.so.4.37.0
|
||||
LT_CURRENT=41
|
||||
LT_AGE=37
|
||||
dnl SONAME = 43 - 39 = 4 . Linux library name = libburn.so.4.39.0
|
||||
LT_CURRENT=43
|
||||
LT_AGE=39
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
@ -179,6 +180,37 @@ dnl If this would be done more specifically in Makefile.am
|
||||
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
|
||||
CFLAGS="$CFLAGS $STATVFS_DEF"
|
||||
|
||||
dnl ts A91122
|
||||
AC_ARG_ENABLE(track-src-odirect,
|
||||
[ --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no],
|
||||
, enable_track_src_odirect=no)
|
||||
if test x$enable_track_src_odirect = xyes; then
|
||||
LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
||||
echo "enabled use of O_DIRECT with track input"
|
||||
else
|
||||
LIBBURN_O_DIRECT_DEF=
|
||||
echo "disabled use of O_DIRECT with track input"
|
||||
fi
|
||||
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
|
||||
dnl ### AC_SUBST(LIBBURN_O_DIRECT_DEF)
|
||||
CFLAGS="$CFLAGS $LIBBURN_O_DIRECT_DEF"
|
||||
|
||||
dnl ts A91116
|
||||
AC_ARG_ENABLE(dvd-obs-64k,
|
||||
[ --enable-dvd-obs-64k 64 KB default size for DVD/BD writing, default=no],
|
||||
, enable_fifo_odirect=no)
|
||||
if test x$enable_dvd_obs_64k = xyes; then
|
||||
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
||||
echo "enabled write size default 64 KB on DVD and BD"
|
||||
else
|
||||
LIBBURN_DVD_OBS_64K=
|
||||
echo "disabled write size default 64 KB on DVD and BD"
|
||||
fi
|
||||
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
|
||||
dnl ### AC_SUBST(LIBBURN_DVD_OBS_64K)
|
||||
CFLAGS="$CFLAGS $LIBBURN_DVD_OBS_64K"
|
||||
|
||||
|
||||
dnl Add compiler-specific flags
|
||||
|
||||
dnl See if the user wants aggressive optimizations of the code
|
||||
@ -198,7 +230,6 @@ else
|
||||
CFLAGS="$CFLAGS -DDEBUG"
|
||||
fi
|
||||
|
||||
|
||||
dnl Determine target directory for libburn-*.pc
|
||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||
dnl
|
||||
|
@ -627,7 +627,8 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
||||
fs->is_started = -1;
|
||||
|
||||
/* create and set up ring buffer */;
|
||||
fs->buf = calloc(fs->chunksize, fs->chunks);
|
||||
fs->buf = burn_os_alloc_buffer(
|
||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||
if (fs->buf == NULL) {
|
||||
/* >>> could not start ring buffer */;
|
||||
return -1;
|
||||
|
@ -424,10 +424,6 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
||||
char msg[BURN_DRIVE_ADR_LEN + 160];
|
||||
int ret;
|
||||
|
||||
/* ts A60821
|
||||
<<< debug: for tracing calls which might use open drive fds */
|
||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||
|
||||
d->drive_role = 1; /* MMC drive */
|
||||
|
||||
t = burn_drive_register(d);
|
||||
@ -910,6 +906,22 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
||||
out->write_simulate = !!d->mdata->simulate;
|
||||
out->c2_errors = !!d->mdata->c2_pointers;
|
||||
out->drive = d;
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_dummy_probe_wM
|
||||
|
||||
/* ts A91112 */
|
||||
/* Set default block types. The call d->probe_write_modes() is quite
|
||||
obtrusive. It may be performed explicitely by new API call
|
||||
burn_drive_probe_cd_write_modes().
|
||||
*/
|
||||
out->tao_block_types = d->block_types[BURN_WRITE_TAO] =
|
||||
BURN_BLOCK_MODE1 | BURN_BLOCK_RAW0;
|
||||
out->sao_block_types = d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
|
||||
out->raw_block_types = d->block_types[BURN_WRITE_RAW] = 0;
|
||||
out->packet_block_types = 0;
|
||||
|
||||
#else /* Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
||||
|
||||
/* update available block types for burners */
|
||||
if (out->write_dvdram || out->write_dvdr ||
|
||||
out->write_cdrw || out->write_cdr)
|
||||
@ -918,10 +930,37 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
||||
out->sao_block_types = d->block_types[BURN_WRITE_SAO];
|
||||
out->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
||||
out->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
||||
|
||||
#endif /* ! Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_dummy_probe_wM
|
||||
|
||||
/* ts A91112 candidate for API */
|
||||
/* Probe available CD write modes and block types.
|
||||
*/
|
||||
int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo)
|
||||
{
|
||||
struct burn_drive *d = dinfo->drive;
|
||||
|
||||
if (d == NULL)
|
||||
return 0;
|
||||
if (dinfo->write_dvdram || dinfo->write_dvdr ||
|
||||
dinfo->write_cdrw || dinfo->write_cdr)
|
||||
d->probe_write_modes(d);
|
||||
dinfo->tao_block_types = d->block_types[BURN_WRITE_TAO];
|
||||
dinfo->sao_block_types = d->block_types[BURN_WRITE_SAO];
|
||||
dinfo->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
||||
dinfo->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
||||
|
||||
|
||||
/* ts A70907 : added parameter flag */
|
||||
/* @param flag bit0= reset global drive list */
|
||||
int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
||||
|
850
libburn/ecma130ab.c
Normal file
850
libburn/ecma130ab.c
Normal file
@ -0,0 +1,850 @@
|
||||
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c
|
||||
|
||||
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
||||
|
||||
This code module implements the production of RSPC parity bytes (P- and Q-
|
||||
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
|
||||
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf
|
||||
|
||||
The following statements about Galois Fields have been learned mostly from
|
||||
http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.pdf
|
||||
by James S. Plank after an e-mail exchange with Norbert Preining.
|
||||
|
||||
The output has been compared with the output of the old code of libburn
|
||||
which was labeled "borrowed HEAVILY from cdrdao" and claimed by Joerg
|
||||
Schilling to stem from code by Heiko Eissfeldt.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Note: In this text, "^" denotes exponentiation and not the binary exor
|
||||
operation. Confusingly in the C code "^" is said exor.
|
||||
Note: This is not C1, C2 which is rather mentioned in ECMA-130 Annex C and
|
||||
always performed inside the drive.
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
|
||||
RSPC resp. P- and Q-Parity
|
||||
|
||||
ECMA-130 Annex A prescribes to compute the parity bytes for P-columns and
|
||||
Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating
|
||||
polynomials x^8+x^4+x^3+x^2+1 (i.e. 0x11d) and x^1 (i.e. 0x02).
|
||||
Bytes 12 to 2075 of a audio-sized sector get ordered in two byte words
|
||||
as 24 rows and 43 columns. Then this matrix is split into a LSB matrix
|
||||
and a MSB matrix of the same layout. Parity bytes are to be computed
|
||||
from these 8-bit values.
|
||||
2 P-bytes cover each column of 24 bytes. They get appended to the matrix
|
||||
as rows 24 and 25.
|
||||
2 Q-bytes cover each the 26 diagonals of the extended matrix.
|
||||
|
||||
Both parity byte pairs have to be computed so that extended rows or
|
||||
diagonals match this linear equation:
|
||||
H x V = (0,0)
|
||||
H is a 2-row matrix of size n matching the length of the V ectors
|
||||
[ 1 1 ... 1 1 ]
|
||||
[ x^(n-1) x^(n-2) x^1 1 ]
|
||||
Vp represents a P-row. It is a byte vector consisting of row bytes at
|
||||
position 0 to 23 and the two parity bytes which shall be determined
|
||||
at position 24 and 25. So Hp has 26 columns.
|
||||
Vq represents a Q-diagonal. It is a byte vector consisting of diagonal
|
||||
bytes at position 0 to 42 and the two parity bytes at position 43 and 44.
|
||||
So Hq has 45 columns. The Q-diagonals cover P-parity bytes.
|
||||
|
||||
By applying some high school algebra one gets the parity bytes b0, b1 of
|
||||
vector V = (n_payload_bytes, b0 , b1) as
|
||||
|
||||
b0 = ( H[n] * SUM(n_payload_bytes) - H[0..(n-1)] x n_payload_bytes )
|
||||
/ (H[n+1] - H[n])
|
||||
b1 = - SUM(n_payload_bytes) - b0
|
||||
|
||||
H[i] is the i-the element of the second row of matrix H. E.g. H[0] = x^(n-1)
|
||||
The result has to be computed by Galois field arithmetics. See below.
|
||||
|
||||
The P-parity bytes of each column get reunited as LSB and MSB of two words.
|
||||
word1 gets written to positions 1032 to 1074, word0 to 1075 to 1117.
|
||||
The Q-parity bytes of each diagonal get reunited too. word1 goes to 1118
|
||||
to 1143, word0 to 1144 to 1169.
|
||||
>>> I do not read this swap of word1 and word0 from ECMA-130 Annex A.
|
||||
>>> But the new output matches the old output only if it is done that way.
|
||||
>>> See correctness reservation below.
|
||||
|
||||
Algebra on Galois fields is the same as on Rational Numbers.
|
||||
But arithmetics is defined by operations on polynomials rather than the
|
||||
usual integer arithmetics on binary numbers.
|
||||
Addition and subtraction are identical with the binary exor operator.
|
||||
Multiplication and division would demand polynomial division, e.g. by the
|
||||
euclidian algorithm. The computing path over logarithms and powers follows
|
||||
algebra and allows to reduce the arithmetic task to table lookups, additions
|
||||
modulo 255, and exor operations. Note that the logarithms are natural
|
||||
numbers, not polynomials. They get added or subtracted by the usual addition
|
||||
(not by exor) and their polynomial power depends on their value modulo 255.
|
||||
|
||||
Needed are a logarithm table and a power table (or inverse logarithm table)
|
||||
for Galois Field GF(2^8) which will serve to perform the peculiar
|
||||
multiplication and division operation of Galois fields.
|
||||
|
||||
The power table is simply an enumeration of x^n accorting to
|
||||
GF-multiplication. It also serves as second line of matrix H for the parity
|
||||
equations:
|
||||
Hp[i] = gfpow[25-i] , i out of {0,..,25}
|
||||
Hq[i] = gfpow[44-i] , i out of {0,..,44}
|
||||
|
||||
The logarithm table is the inverse permutation of the power table.
|
||||
|
||||
Some simplifications apply to the implementation:
|
||||
In the world of Galois fields there is no difference between - and +.
|
||||
The term (H[n+1] - H[n]) is constant: 3.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
|
||||
Scrambling
|
||||
|
||||
ECMA-130 Annex B prescribes to exor the byte stream of an audio-sized sector
|
||||
with a sequence of pseudo random bytes. It mentions polynomial x^15+x+1 and
|
||||
a 15-bit register.
|
||||
It shows a diagram of a Feedback Shift Register with 16 bit boxes, though.
|
||||
|
||||
Comparing this with explanations in
|
||||
http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm
|
||||
one can recognize the diagram as a Fibonacci Implementation. But there seems
|
||||
really to be one bit box too many.
|
||||
|
||||
The difference of both lengths is expressed in function next_bit() by
|
||||
the constants 0x3fff,0x4000 for 15 bit versus 0x7fff,0x8000 for 16 bits.
|
||||
Comparing the output of both alternatives with the old scrambler output
|
||||
lets 15 bit win for now.
|
||||
|
||||
So the prescription is to start with 15 bit value 1, to use the lowest bit
|
||||
as output, to shift the bits down by one, to exor the output bit with the
|
||||
next lowest bit, and to put that exor result into bit 14 of the register.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
|
||||
Correctness Reservation
|
||||
|
||||
In both cases, parity and scrambling, the goal for now is to replicate the
|
||||
output of the dismissed old lec.c by output which is based on published
|
||||
specs and own implementation code. Whether they comply to ECMA-130 is a
|
||||
different question which can only be answered by real test cases for
|
||||
raw CD recording.
|
||||
|
||||
Of course this implementation will be corrected so that it really complies
|
||||
to ECMA-130 as soon as evidence emerges that it does not yet.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Power and logarithm tables for GF(2^8), parity matrices for ECMA-130.
|
||||
Generated by burn_rspc_setup_tables() and burn_rspc_print_tables().
|
||||
|
||||
The highest possible sum of gflog[] values is is 508. So the table gfpow[]
|
||||
with period 255 was manually unrolled to 509 elements to avoid one modulo
|
||||
255 operation in burn_rspc_mult().
|
||||
Proposed by D. Hugh Redelmeier.
|
||||
|
||||
*/
|
||||
|
||||
static unsigned char gfpow[509] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
|
||||
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
|
||||
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
|
||||
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
|
||||
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
|
||||
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
|
||||
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
|
||||
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
|
||||
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
|
||||
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
|
||||
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
|
||||
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
|
||||
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
|
||||
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
|
||||
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
|
||||
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
|
||||
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
|
||||
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
|
||||
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
||||
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
|
||||
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
|
||||
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
|
||||
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
|
||||
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
|
||||
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
|
||||
108, 216, 173, 71, 142,
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
|
||||
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
|
||||
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
|
||||
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
|
||||
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
|
||||
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
|
||||
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
|
||||
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
|
||||
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
|
||||
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
|
||||
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
|
||||
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
|
||||
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
|
||||
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
|
||||
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
|
||||
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
|
||||
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
|
||||
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
|
||||
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
||||
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
|
||||
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
|
||||
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
|
||||
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
|
||||
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
|
||||
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
|
||||
108, 216, 173, 71,
|
||||
};
|
||||
|
||||
static unsigned char gflog[256] = {
|
||||
0, 0, 1, 25, 2, 50, 26, 198, 3, 223,
|
||||
51, 238, 27, 104, 199, 75, 4, 100, 224, 14,
|
||||
52, 141, 239, 129, 28, 193, 105, 248, 200, 8,
|
||||
76, 113, 5, 138, 101, 47, 225, 36, 15, 33,
|
||||
53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
|
||||
194, 125, 106, 39, 249, 185, 201, 154, 9, 120,
|
||||
77, 228, 114, 166, 6, 191, 139, 98, 102, 221,
|
||||
48, 253, 226, 152, 37, 179, 16, 145, 34, 136,
|
||||
54, 208, 148, 206, 143, 150, 219, 189, 241, 210,
|
||||
19, 92, 131, 56, 70, 64, 30, 66, 182, 163,
|
||||
195, 72, 126, 110, 107, 58, 40, 84, 250, 133,
|
||||
186, 61, 202, 94, 155, 159, 10, 21, 121, 43,
|
||||
78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
|
||||
192, 247, 140, 128, 99, 13, 103, 74, 222, 237,
|
||||
49, 197, 254, 24, 227, 165, 153, 119, 38, 184,
|
||||
180, 124, 17, 68, 146, 217, 35, 32, 137, 46,
|
||||
55, 63, 209, 91, 149, 188, 207, 205, 144, 135,
|
||||
151, 178, 220, 252, 190, 97, 242, 86, 211, 171,
|
||||
20, 42, 93, 158, 132, 60, 57, 83, 71, 109,
|
||||
65, 162, 31, 45, 67, 216, 183, 123, 164, 118,
|
||||
196, 23, 73, 236, 127, 12, 111, 246, 108, 161,
|
||||
59, 82, 41, 157, 85, 170, 251, 96, 134, 177,
|
||||
187, 204, 62, 90, 203, 89, 95, 176, 156, 169,
|
||||
160, 81, 11, 245, 22, 235, 122, 117, 44, 215,
|
||||
79, 174, 213, 233, 230, 231, 173, 232, 116, 214,
|
||||
244, 234, 168, 80, 88, 175
|
||||
};
|
||||
|
||||
|
||||
#define Libburn_use_h_matriceS 1
|
||||
|
||||
#ifdef Libburn_use_h_matriceS
|
||||
|
||||
/* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time
|
||||
than using gfpow[25-i] resp. gfpow[44-1]. I blame this on the more
|
||||
condensed data representation which slightly increases the rate of cache
|
||||
hits.
|
||||
Nevertheless this effect is very likely depending on the exact cache
|
||||
size and architecture. In general, using h[] saves more than 8000
|
||||
subtractions per sector.
|
||||
*/
|
||||
|
||||
/* Parity matrices H as prescribed by ECMA-130 Annex A.
|
||||
Actually just reverted order start pieces of gfpow[].
|
||||
*/
|
||||
static unsigned char h26[26] = {
|
||||
3, 143, 201, 234, 117, 180, 90, 45, 152, 76,
|
||||
38, 19, 135, 205, 232, 116, 58, 29, 128, 64,
|
||||
32, 16, 8, 4, 2, 1,
|
||||
};
|
||||
|
||||
static unsigned char h45[45] = {
|
||||
238, 119, 181, 212, 106, 53, 148, 74, 37, 156,
|
||||
78, 39, 157, 192, 96, 48, 24, 12, 6, 3,
|
||||
143, 201, 234, 117, 180, 90, 45, 152, 76, 38,
|
||||
19, 135, 205, 232, 116, 58, 29, 128, 64, 32,
|
||||
16, 8, 4, 2, 1,
|
||||
};
|
||||
|
||||
#endif /* Libburn_use_h_matriceS */
|
||||
|
||||
|
||||
/* Pseudo-random bytes which of course are exactly the same as with the
|
||||
previously used code.
|
||||
Generated by function print_ecma_130_scrambler().
|
||||
*/
|
||||
static unsigned char ecma_130_annex_b[2340] = {
|
||||
1, 128, 0, 96, 0, 40, 0, 30, 128, 8,
|
||||
96, 6, 168, 2, 254, 129, 128, 96, 96, 40,
|
||||
40, 30, 158, 136, 104, 102, 174, 170, 252, 127,
|
||||
1, 224, 0, 72, 0, 54, 128, 22, 224, 14,
|
||||
200, 4, 86, 131, 126, 225, 224, 72, 72, 54,
|
||||
182, 150, 246, 238, 198, 204, 82, 213, 253, 159,
|
||||
1, 168, 0, 126, 128, 32, 96, 24, 40, 10,
|
||||
158, 135, 40, 98, 158, 169, 168, 126, 254, 160,
|
||||
64, 120, 48, 34, 148, 25, 175, 74, 252, 55,
|
||||
1, 214, 128, 94, 224, 56, 72, 18, 182, 141,
|
||||
182, 229, 182, 203, 54, 215, 86, 222, 190, 216,
|
||||
112, 90, 164, 59, 59, 83, 83, 125, 253, 225,
|
||||
129, 136, 96, 102, 168, 42, 254, 159, 0, 104,
|
||||
0, 46, 128, 28, 96, 9, 232, 6, 206, 130,
|
||||
212, 97, 159, 104, 104, 46, 174, 156, 124, 105,
|
||||
225, 238, 200, 76, 86, 181, 254, 247, 0, 70,
|
||||
128, 50, 224, 21, 136, 15, 38, 132, 26, 227,
|
||||
75, 9, 247, 70, 198, 178, 210, 245, 157, 135,
|
||||
41, 162, 158, 249, 168, 66, 254, 177, 128, 116,
|
||||
96, 39, 104, 26, 174, 139, 60, 103, 81, 234,
|
||||
188, 79, 49, 244, 20, 71, 79, 114, 180, 37,
|
||||
183, 91, 54, 187, 86, 243, 126, 197, 224, 83,
|
||||
8, 61, 198, 145, 146, 236, 109, 141, 237, 165,
|
||||
141, 187, 37, 179, 91, 53, 251, 87, 3, 126,
|
||||
129, 224, 96, 72, 40, 54, 158, 150, 232, 110,
|
||||
206, 172, 84, 125, 255, 97, 128, 40, 96, 30,
|
||||
168, 8, 126, 134, 160, 98, 248, 41, 130, 158,
|
||||
225, 168, 72, 126, 182, 160, 118, 248, 38, 194,
|
||||
154, 209, 171, 28, 127, 73, 224, 54, 200, 22,
|
||||
214, 142, 222, 228, 88, 75, 122, 183, 99, 54,
|
||||
169, 214, 254, 222, 192, 88, 80, 58, 188, 19,
|
||||
49, 205, 212, 85, 159, 127, 40, 32, 30, 152,
|
||||
8, 106, 134, 175, 34, 252, 25, 129, 202, 224,
|
||||
87, 8, 62, 134, 144, 98, 236, 41, 141, 222,
|
||||
229, 152, 75, 42, 183, 95, 54, 184, 22, 242,
|
||||
142, 197, 164, 83, 59, 125, 211, 97, 157, 232,
|
||||
105, 142, 174, 228, 124, 75, 97, 247, 104, 70,
|
||||
174, 178, 252, 117, 129, 231, 32, 74, 152, 55,
|
||||
42, 150, 159, 46, 232, 28, 78, 137, 244, 102,
|
||||
199, 106, 210, 175, 29, 188, 9, 177, 198, 244,
|
||||
82, 199, 125, 146, 161, 173, 184, 125, 178, 161,
|
||||
181, 184, 119, 50, 166, 149, 186, 239, 51, 12,
|
||||
21, 197, 207, 19, 20, 13, 207, 69, 148, 51,
|
||||
47, 85, 220, 63, 25, 208, 10, 220, 7, 25,
|
||||
194, 138, 209, 167, 28, 122, 137, 227, 38, 201,
|
||||
218, 214, 219, 30, 219, 72, 91, 118, 187, 102,
|
||||
243, 106, 197, 239, 19, 12, 13, 197, 197, 147,
|
||||
19, 45, 205, 221, 149, 153, 175, 42, 252, 31,
|
||||
1, 200, 0, 86, 128, 62, 224, 16, 72, 12,
|
||||
54, 133, 214, 227, 30, 201, 200, 86, 214, 190,
|
||||
222, 240, 88, 68, 58, 179, 83, 53, 253, 215,
|
||||
1, 158, 128, 104, 96, 46, 168, 28, 126, 137,
|
||||
224, 102, 200, 42, 214, 159, 30, 232, 8, 78,
|
||||
134, 180, 98, 247, 105, 134, 174, 226, 252, 73,
|
||||
129, 246, 224, 70, 200, 50, 214, 149, 158, 239,
|
||||
40, 76, 30, 181, 200, 119, 22, 166, 142, 250,
|
||||
228, 67, 11, 113, 199, 100, 82, 171, 125, 191,
|
||||
97, 176, 40, 116, 30, 167, 72, 122, 182, 163,
|
||||
54, 249, 214, 194, 222, 209, 152, 92, 106, 185,
|
||||
239, 50, 204, 21, 149, 207, 47, 20, 28, 15,
|
||||
73, 196, 54, 211, 86, 221, 254, 217, 128, 90,
|
||||
224, 59, 8, 19, 70, 141, 242, 229, 133, 139,
|
||||
35, 39, 89, 218, 186, 219, 51, 27, 85, 203,
|
||||
127, 23, 96, 14, 168, 4, 126, 131, 96, 97,
|
||||
232, 40, 78, 158, 180, 104, 119, 110, 166, 172,
|
||||
122, 253, 227, 1, 137, 192, 102, 208, 42, 220,
|
||||
31, 25, 200, 10, 214, 135, 30, 226, 136, 73,
|
||||
166, 182, 250, 246, 195, 6, 209, 194, 220, 81,
|
||||
153, 252, 106, 193, 239, 16, 76, 12, 53, 197,
|
||||
215, 19, 30, 141, 200, 101, 150, 171, 46, 255,
|
||||
92, 64, 57, 240, 18, 196, 13, 147, 69, 173,
|
||||
243, 61, 133, 209, 163, 28, 121, 201, 226, 214,
|
||||
201, 158, 214, 232, 94, 206, 184, 84, 114, 191,
|
||||
101, 176, 43, 52, 31, 87, 72, 62, 182, 144,
|
||||
118, 236, 38, 205, 218, 213, 155, 31, 43, 72,
|
||||
31, 118, 136, 38, 230, 154, 202, 235, 23, 15,
|
||||
78, 132, 52, 99, 87, 105, 254, 174, 192, 124,
|
||||
80, 33, 252, 24, 65, 202, 176, 87, 52, 62,
|
||||
151, 80, 110, 188, 44, 113, 221, 228, 89, 139,
|
||||
122, 231, 99, 10, 169, 199, 62, 210, 144, 93,
|
||||
172, 57, 189, 210, 241, 157, 132, 105, 163, 110,
|
||||
249, 236, 66, 205, 241, 149, 132, 111, 35, 108,
|
||||
25, 237, 202, 205, 151, 21, 174, 143, 60, 100,
|
||||
17, 235, 76, 79, 117, 244, 39, 7, 90, 130,
|
||||
187, 33, 179, 88, 117, 250, 167, 3, 58, 129,
|
||||
211, 32, 93, 216, 57, 154, 146, 235, 45, 143,
|
||||
93, 164, 57, 187, 82, 243, 125, 133, 225, 163,
|
||||
8, 121, 198, 162, 210, 249, 157, 130, 233, 161,
|
||||
142, 248, 100, 66, 171, 113, 191, 100, 112, 43,
|
||||
100, 31, 107, 72, 47, 118, 156, 38, 233, 218,
|
||||
206, 219, 20, 91, 79, 123, 116, 35, 103, 89,
|
||||
234, 186, 207, 51, 20, 21, 207, 79, 20, 52,
|
||||
15, 87, 68, 62, 179, 80, 117, 252, 39, 1,
|
||||
218, 128, 91, 32, 59, 88, 19, 122, 141, 227,
|
||||
37, 137, 219, 38, 219, 90, 219, 123, 27, 99,
|
||||
75, 105, 247, 110, 198, 172, 82, 253, 253, 129,
|
||||
129, 160, 96, 120, 40, 34, 158, 153, 168, 106,
|
||||
254, 175, 0, 124, 0, 33, 192, 24, 80, 10,
|
||||
188, 7, 49, 194, 148, 81, 175, 124, 124, 33,
|
||||
225, 216, 72, 90, 182, 187, 54, 243, 86, 197,
|
||||
254, 211, 0, 93, 192, 57, 144, 18, 236, 13,
|
||||
141, 197, 165, 147, 59, 45, 211, 93, 157, 249,
|
||||
169, 130, 254, 225, 128, 72, 96, 54, 168, 22,
|
||||
254, 142, 192, 100, 80, 43, 124, 31, 97, 200,
|
||||
40, 86, 158, 190, 232, 112, 78, 164, 52, 123,
|
||||
87, 99, 126, 169, 224, 126, 200, 32, 86, 152,
|
||||
62, 234, 144, 79, 44, 52, 29, 215, 73, 158,
|
||||
182, 232, 118, 206, 166, 212, 122, 223, 99, 24,
|
||||
41, 202, 158, 215, 40, 94, 158, 184, 104, 114,
|
||||
174, 165, 188, 123, 49, 227, 84, 73, 255, 118,
|
||||
192, 38, 208, 26, 220, 11, 25, 199, 74, 210,
|
||||
183, 29, 182, 137, 182, 230, 246, 202, 198, 215,
|
||||
18, 222, 141, 152, 101, 170, 171, 63, 63, 80,
|
||||
16, 60, 12, 17, 197, 204, 83, 21, 253, 207,
|
||||
1, 148, 0, 111, 64, 44, 48, 29, 212, 9,
|
||||
159, 70, 232, 50, 206, 149, 148, 111, 47, 108,
|
||||
28, 45, 201, 221, 150, 217, 174, 218, 252, 91,
|
||||
1, 251, 64, 67, 112, 49, 228, 20, 75, 79,
|
||||
119, 116, 38, 167, 90, 250, 187, 3, 51, 65,
|
||||
213, 240, 95, 4, 56, 3, 82, 129, 253, 160,
|
||||
65, 184, 48, 114, 148, 37, 175, 91, 60, 59,
|
||||
81, 211, 124, 93, 225, 249, 136, 66, 230, 177,
|
||||
138, 244, 103, 7, 106, 130, 175, 33, 188, 24,
|
||||
113, 202, 164, 87, 59, 126, 147, 96, 109, 232,
|
||||
45, 142, 157, 164, 105, 187, 110, 243, 108, 69,
|
||||
237, 243, 13, 133, 197, 163, 19, 57, 205, 210,
|
||||
213, 157, 159, 41, 168, 30, 254, 136, 64, 102,
|
||||
176, 42, 244, 31, 7, 72, 2, 182, 129, 182,
|
||||
224, 118, 200, 38, 214, 154, 222, 235, 24, 79,
|
||||
74, 180, 55, 55, 86, 150, 190, 238, 240, 76,
|
||||
68, 53, 243, 87, 5, 254, 131, 0, 97, 192,
|
||||
40, 80, 30, 188, 8, 113, 198, 164, 82, 251,
|
||||
125, 131, 97, 161, 232, 120, 78, 162, 180, 121,
|
||||
183, 98, 246, 169, 134, 254, 226, 192, 73, 144,
|
||||
54, 236, 22, 205, 206, 213, 148, 95, 47, 120,
|
||||
28, 34, 137, 217, 166, 218, 250, 219, 3, 27,
|
||||
65, 203, 112, 87, 100, 62, 171, 80, 127, 124,
|
||||
32, 33, 216, 24, 90, 138, 187, 39, 51, 90,
|
||||
149, 251, 47, 3, 92, 1, 249, 192, 66, 208,
|
||||
49, 156, 20, 105, 207, 110, 212, 44, 95, 93,
|
||||
248, 57, 130, 146, 225, 173, 136, 125, 166, 161,
|
||||
186, 248, 115, 2, 165, 193, 187, 16, 115, 76,
|
||||
37, 245, 219, 7, 27, 66, 139, 113, 167, 100,
|
||||
122, 171, 99, 63, 105, 208, 46, 220, 28, 89,
|
||||
201, 250, 214, 195, 30, 209, 200, 92, 86, 185,
|
||||
254, 242, 192, 69, 144, 51, 44, 21, 221, 207,
|
||||
25, 148, 10, 239, 71, 12, 50, 133, 213, 163,
|
||||
31, 57, 200, 18, 214, 141, 158, 229, 168, 75,
|
||||
62, 183, 80, 118, 188, 38, 241, 218, 196, 91,
|
||||
19, 123, 77, 227, 117, 137, 231, 38, 202, 154,
|
||||
215, 43, 30, 159, 72, 104, 54, 174, 150, 252,
|
||||
110, 193, 236, 80, 77, 252, 53, 129, 215, 32,
|
||||
94, 152, 56, 106, 146, 175, 45, 188, 29, 177,
|
||||
201, 180, 86, 247, 126, 198, 160, 82, 248, 61,
|
||||
130, 145, 161, 172, 120, 125, 226, 161, 137, 184,
|
||||
102, 242, 170, 197, 191, 19, 48, 13, 212, 5,
|
||||
159, 67, 40, 49, 222, 148, 88, 111, 122, 172,
|
||||
35, 61, 217, 209, 154, 220, 107, 25, 239, 74,
|
||||
204, 55, 21, 214, 143, 30, 228, 8, 75, 70,
|
||||
183, 114, 246, 165, 134, 251, 34, 195, 89, 145,
|
||||
250, 236, 67, 13, 241, 197, 132, 83, 35, 125,
|
||||
217, 225, 154, 200, 107, 22, 175, 78, 252, 52,
|
||||
65, 215, 112, 94, 164, 56, 123, 82, 163, 125,
|
||||
185, 225, 178, 200, 117, 150, 167, 46, 250, 156,
|
||||
67, 41, 241, 222, 196, 88, 83, 122, 189, 227,
|
||||
49, 137, 212, 102, 223, 106, 216, 47, 26, 156,
|
||||
11, 41, 199, 94, 210, 184, 93, 178, 185, 181,
|
||||
178, 247, 53, 134, 151, 34, 238, 153, 140, 106,
|
||||
229, 239, 11, 12, 7, 69, 194, 179, 17, 181,
|
||||
204, 119, 21, 230, 143, 10, 228, 7, 11, 66,
|
||||
135, 113, 162, 164, 121, 187, 98, 243, 105, 133,
|
||||
238, 227, 12, 73, 197, 246, 211, 6, 221, 194,
|
||||
217, 145, 154, 236, 107, 13, 239, 69, 140, 51,
|
||||
37, 213, 219, 31, 27, 72, 11, 118, 135, 102,
|
||||
226, 170, 201, 191, 22, 240, 14, 196, 4, 83,
|
||||
67, 125, 241, 225, 132, 72, 99, 118, 169, 230,
|
||||
254, 202, 192, 87, 16, 62, 140, 16, 101, 204,
|
||||
43, 21, 223, 79, 24, 52, 10, 151, 71, 46,
|
||||
178, 156, 117, 169, 231, 62, 202, 144, 87, 44,
|
||||
62, 157, 208, 105, 156, 46, 233, 220, 78, 217,
|
||||
244, 90, 199, 123, 18, 163, 77, 185, 245, 178,
|
||||
199, 53, 146, 151, 45, 174, 157, 188, 105, 177,
|
||||
238, 244, 76, 71, 117, 242, 167, 5, 186, 131,
|
||||
51, 33, 213, 216, 95, 26, 184, 11, 50, 135,
|
||||
85, 162, 191, 57, 176, 18, 244, 13, 135, 69,
|
||||
162, 179, 57, 181, 210, 247, 29, 134, 137, 162,
|
||||
230, 249, 138, 194, 231, 17, 138, 140, 103, 37,
|
||||
234, 155, 15, 43, 68, 31, 115, 72, 37, 246,
|
||||
155, 6, 235, 66, 207, 113, 148, 36, 111, 91,
|
||||
108, 59, 109, 211, 109, 157, 237, 169, 141, 190,
|
||||
229, 176, 75, 52, 55, 87, 86, 190, 190, 240,
|
||||
112, 68, 36, 51, 91, 85, 251, 127, 3, 96,
|
||||
1, 232, 0, 78, 128, 52, 96, 23, 104, 14,
|
||||
174, 132, 124, 99, 97, 233, 232, 78, 206, 180,
|
||||
84, 119, 127, 102, 160, 42, 248, 31, 2, 136,
|
||||
1, 166, 128, 122, 224, 35, 8, 25, 198, 138,
|
||||
210, 231, 29, 138, 137, 167, 38, 250, 154, 195,
|
||||
43, 17, 223, 76, 88, 53, 250, 151, 3, 46,
|
||||
129, 220, 96, 89, 232, 58, 206, 147, 20, 109,
|
||||
207, 109, 148, 45, 175, 93, 188, 57, 177, 210,
|
||||
244, 93, 135, 121, 162, 162, 249, 185, 130, 242,
|
||||
225, 133, 136, 99, 38, 169, 218, 254, 219, 0,
|
||||
91, 64, 59, 112, 19, 100, 13, 235, 69, 143,
|
||||
115, 36, 37, 219, 91, 27, 123, 75, 99, 119,
|
||||
105, 230, 174, 202, 252, 87, 1, 254, 128, 64,
|
||||
96, 48, 40, 20, 30, 143, 72, 100, 54, 171,
|
||||
86, 255, 126, 192, 32, 80, 24, 60, 10, 145,
|
||||
199, 44, 82, 157, 253, 169, 129, 190, 224, 112,
|
||||
72, 36, 54, 155, 86, 235, 126, 207, 96, 84,
|
||||
40, 63, 94, 144, 56, 108, 18, 173, 205, 189,
|
||||
149, 177, 175, 52, 124, 23, 97, 206, 168, 84,
|
||||
126, 191, 96, 112, 40, 36, 30, 155, 72, 107,
|
||||
118, 175, 102, 252, 42, 193, 223, 16, 88, 12,
|
||||
58, 133, 211, 35, 29, 217, 201, 154, 214, 235,
|
||||
30, 207, 72, 84, 54, 191, 86, 240, 62, 196,
|
||||
16, 83, 76, 61, 245, 209, 135, 28, 98, 137,
|
||||
233, 166, 206, 250, 212, 67, 31, 113, 200, 36,
|
||||
86, 155, 126, 235, 96, 79, 104, 52, 46, 151,
|
||||
92, 110, 185, 236, 114, 205, 229, 149, 139, 47,
|
||||
39, 92, 26, 185, 203, 50, 215, 85, 158, 191,
|
||||
40, 112, 30, 164, 8, 123, 70, 163, 114, 249,
|
||||
229, 130, 203, 33, 151, 88, 110, 186, 172, 115,
|
||||
61, 229, 209, 139, 28, 103, 73, 234, 182, 207,
|
||||
54, 212, 22, 223, 78, 216, 52, 90, 151, 123,
|
||||
46, 163, 92, 121, 249, 226, 194, 201, 145, 150,
|
||||
236, 110, 205, 236, 85, 141, 255, 37, 128, 27,
|
||||
32, 11, 88, 7, 122, 130, 163, 33, 185, 216,
|
||||
114, 218, 165, 155, 59, 43, 83, 95, 125, 248,
|
||||
33, 130, 152, 97, 170, 168, 127, 62, 160, 16,
|
||||
120, 12, 34, 133, 217, 163, 26, 249, 203, 2,
|
||||
215, 65, 158, 176, 104, 116, 46, 167, 92, 122,
|
||||
185, 227, 50, 201, 213, 150, 223, 46, 216, 28,
|
||||
90, 137, 251, 38, 195, 90, 209, 251, 28, 67,
|
||||
73, 241, 246, 196, 70, 211, 114, 221, 229, 153
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* This is the new implementation of P- and Q-parity generation.
|
||||
It needs about the same computing time as the old implementation (both
|
||||
with gcc -O2 on AMD 64 bit). Measurements indicate that about 280 MIPS
|
||||
are needed for 48x CD speed (7.1 MB/s).
|
||||
*/
|
||||
|
||||
static unsigned char burn_rspc_mult(unsigned char a, unsigned char b)
|
||||
{
|
||||
if (a == 0 || b == 0)
|
||||
return 0;
|
||||
/* Optimization of (a == 0 || b == 0) by D. Hugh Redelmeier
|
||||
if((((int)a - 1) | ((int)b - 1)) < 0)
|
||||
return 0;
|
||||
*/
|
||||
|
||||
return gfpow[gflog[a] + gflog[b]];
|
||||
/* % 255 not necessary because gfpow is unrolled up to index 510 */
|
||||
}
|
||||
|
||||
|
||||
/* Divide by polynomial 0x03. Derived from burn_rspc_div() and using the
|
||||
unrolled size of the gfpow[] array.
|
||||
*/
|
||||
static unsigned char burn_rspc_div_3(unsigned char a)
|
||||
{
|
||||
if (a == 0)
|
||||
return 0;
|
||||
return gfpow[230 + gflog[a]];
|
||||
}
|
||||
|
||||
|
||||
static void burn_rspc_p0p1(unsigned char *sector, int col,
|
||||
unsigned char *p0_lsb, unsigned char *p0_msb,
|
||||
unsigned char *p1_lsb, unsigned char *p1_msb)
|
||||
{
|
||||
unsigned char *start, b;
|
||||
unsigned int i, sum_v_lsb = 0, sum_v_msb = 0;
|
||||
unsigned int hxv_lsb = 0, hxv_msb = 0;
|
||||
|
||||
start = sector + 12 + 2 * col;
|
||||
for(i = 0; i < 24; i++) {
|
||||
b = *start;
|
||||
sum_v_lsb ^= b;
|
||||
|
||||
#ifdef Libburn_use_h_matriceS
|
||||
hxv_lsb ^= burn_rspc_mult(b, h26[i]);
|
||||
#else
|
||||
hxv_lsb ^= burn_rspc_mult(b, gfpow[25 - i]);
|
||||
#endif
|
||||
|
||||
b = *(start + 1);
|
||||
sum_v_msb ^= b;
|
||||
|
||||
#ifdef Libburn_use_h_matriceS
|
||||
hxv_msb ^= burn_rspc_mult(b, h26[i]);
|
||||
#else
|
||||
hxv_msb ^= burn_rspc_mult(b, gfpow[25 - i]);
|
||||
#endif
|
||||
|
||||
start += 86;
|
||||
}
|
||||
|
||||
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
|
||||
*p0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
|
||||
*p0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
|
||||
*p1_lsb = sum_v_lsb ^ *p0_lsb;
|
||||
*p1_msb = sum_v_msb ^ *p0_msb;
|
||||
}
|
||||
|
||||
|
||||
void burn_rspc_parity_p(unsigned char *sector)
|
||||
{
|
||||
int i;
|
||||
unsigned char p0_lsb, p0_msb, p1_lsb, p1_msb;
|
||||
|
||||
/* Loop over P columns */
|
||||
for(i = 0; i < 43; i++) {
|
||||
burn_rspc_p0p1(sector, i, &p0_lsb, &p0_msb, &p1_lsb, &p1_msb);
|
||||
sector[2162 + 2 * i] = p0_lsb;
|
||||
sector[2162 + 2 * i + 1] = p0_msb;
|
||||
sector[2076 + 2 * i] = p1_lsb;
|
||||
sector[2076 + 2 * i + 1] = p1_msb;
|
||||
|
||||
#ifdef Libburn_with_lec_generatoR
|
||||
if(verbous) {
|
||||
printf("p %2d : %2.2X %2.2X ", i,
|
||||
(unsigned int) p0_lsb, (unsigned int) p0_msb);
|
||||
printf("%2.2X %2.2X ",
|
||||
(unsigned int) p1_lsb, (unsigned int) p1_msb);
|
||||
printf("-> %d,%d\n", 2162 + 2 * i, 2076 + 2 * i);
|
||||
}
|
||||
#endif /* Libburn_with_lec_generatoR */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void burn_rspc_q0q1(unsigned char *sector, int diag,
|
||||
unsigned char *q0_lsb, unsigned char *q0_msb,
|
||||
unsigned char *q1_lsb, unsigned char *q1_msb)
|
||||
{
|
||||
unsigned char *start, b;
|
||||
unsigned int i, idx, sum_v_lsb = 0, sum_v_msb = 0;
|
||||
unsigned int hxv_lsb = 0, hxv_msb = 0;
|
||||
|
||||
start = sector + 12;
|
||||
idx = 2 * 43 * diag;
|
||||
for(i = 0; i < 43; i++) {
|
||||
if (idx >= 2236)
|
||||
idx -= 2236;
|
||||
b = start[idx];
|
||||
sum_v_lsb ^= b;
|
||||
|
||||
#ifdef Libburn_use_h_matriceS
|
||||
hxv_lsb ^= burn_rspc_mult(b, h45[i]);
|
||||
#else
|
||||
hxv_lsb ^= burn_rspc_mult(b, gfpow[44 - i]);
|
||||
#endif
|
||||
|
||||
b = start[idx + 1];
|
||||
sum_v_msb ^= b;
|
||||
|
||||
#ifdef Libburn_use_h_matriceS
|
||||
hxv_msb ^= burn_rspc_mult(b, h45[i]);
|
||||
#else
|
||||
hxv_msb ^= burn_rspc_mult(b, gfpow[44 - i]);
|
||||
#endif
|
||||
|
||||
idx += 88;
|
||||
}
|
||||
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
|
||||
*q0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
|
||||
*q0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
|
||||
*q1_lsb = sum_v_lsb ^ *q0_lsb;
|
||||
*q1_msb = sum_v_msb ^ *q0_msb;
|
||||
}
|
||||
|
||||
|
||||
void burn_rspc_parity_q(unsigned char *sector)
|
||||
{
|
||||
int i;
|
||||
unsigned char q0_lsb, q0_msb, q1_lsb, q1_msb;
|
||||
|
||||
/* Loop over Q diagonals */
|
||||
for(i = 0; i < 26; i++) {
|
||||
burn_rspc_q0q1(sector, i, &q0_lsb, &q0_msb, &q1_lsb, &q1_msb);
|
||||
sector[2300 + 2 * i] = q0_lsb;
|
||||
sector[2300 + 2 * i + 1] = q0_msb;
|
||||
sector[2248 + 2 * i] = q1_lsb;
|
||||
sector[2248 + 2 * i + 1] = q1_msb;
|
||||
|
||||
#ifdef Libburn_with_lec_generatoR
|
||||
if(verbous) {
|
||||
printf("q %2d : %2.2X %2.2X ", i,
|
||||
(unsigned int) q0_lsb, (unsigned int) q0_msb);
|
||||
printf("%2.2X %2.2X ",
|
||||
(unsigned int) q1_lsb, (unsigned int) q1_msb);
|
||||
printf("-> %d,%d\n", 2300 + 2 * i, 2248 + 2 * i);
|
||||
}
|
||||
#endif /* Libburn_with_lec_generatoR */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* The new implementation of the ECMA-130 Annex B scrambler.
|
||||
It is totally unoptimized. One should make use of larger word operations.
|
||||
Measurements indicate that about 50 MIPS are needed for 48x CD speed.
|
||||
*/
|
||||
|
||||
void burn_ecma130_scramble(unsigned char *sector)
|
||||
{
|
||||
int i;
|
||||
unsigned char *s;
|
||||
|
||||
s = sector + 12;
|
||||
for (i = 0; i < 2340; i++)
|
||||
s[i] ^= ecma_130_annex_b[i];
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* The following code is not needed for libburn but rather documents the
|
||||
origin of the tables above. In libburn it will not be compiled.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef Libburn_with_lec_generatoR
|
||||
|
||||
|
||||
/* This function produced the content of gflog[] and gfpow[]
|
||||
*/
|
||||
static int burn_rspc_setup_tables(void)
|
||||
{
|
||||
unsigned int b, l;
|
||||
|
||||
memset(gflog, 0, sizeof(gflog));
|
||||
memset(gfpow, 0, sizeof(gfpow));
|
||||
b = 1;
|
||||
for (l = 0; l < 255; l++) {
|
||||
gfpow[l] = (unsigned char) b;
|
||||
gflog[b] = (unsigned char) l;
|
||||
b = b << 1;
|
||||
if (b & 256)
|
||||
b = b ^ 0x11d;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function printed the content of gflog[] and gfpow[] as C code
|
||||
and compared the content with the tables of the old implementation.
|
||||
h26[] and h45[] are reverted order copies of gfpow[]
|
||||
*/
|
||||
static int burn_rspc_print_tables(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("static unsigned char gfpow[255] = {");
|
||||
printf("\n\t");
|
||||
for(i= 0; i < 255; i++) {
|
||||
printf("%3u, ", gfpow[i]);
|
||||
|
||||
#ifdef Libburn_with_old_lec_comparisoN
|
||||
if(gfpow[i] != gf8_ilog[i])
|
||||
fprintf(stderr, "*** ILOG %d : %d != %d ***\n", i, gfpow[i], gf8_ilog[i]);
|
||||
#endif
|
||||
|
||||
if((i % 10) == 9)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
|
||||
printf("static unsigned char gflog[256] = {");
|
||||
printf("\n\t");
|
||||
for(i= 0; i < 256; i++) {
|
||||
printf(" %3u,", gflog[i]);
|
||||
|
||||
#ifdef Libburn_with_old_lec_comparisoN
|
||||
if(gflog[i] != gf8_log[i])
|
||||
fprintf(stderr, "*** LOG %d : %d != %d ***\n", i, gflog[i], gf8_log[i]);
|
||||
#endif
|
||||
|
||||
if((i % 10) == 9)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
|
||||
printf("static unsigned char h26[26] = {");
|
||||
printf("\n\t");
|
||||
for(i= 0; i < 26; i++) {
|
||||
printf(" %3u,", gfpow[25 - i]);
|
||||
if((i % 10) == 9)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
|
||||
printf("static unsigned char h45[45] = {");
|
||||
printf("\n\t");
|
||||
for(i= 0; i < 45; i++) {
|
||||
printf(" %3u,",gfpow[44 - i]);
|
||||
if((i % 10) == 9)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This code was used to generate the content of array ecma_130_annex_b[].
|
||||
*/
|
||||
static unsigned short ecma_130_fsr = 1;
|
||||
|
||||
static int next_bit(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ecma_130_fsr & 1;
|
||||
ecma_130_fsr = (ecma_130_fsr >> 1) & 0x3fff;
|
||||
if (ret ^ (ecma_130_fsr & 1))
|
||||
ecma_130_fsr |= 0x4000;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int print_ecma_130_scrambler(void)
|
||||
{
|
||||
int i, j, b;
|
||||
|
||||
ecma_130_fsr = 1;
|
||||
printf("static unsigned char ecma_130_annex_b[2340] = {");
|
||||
printf("\n\t");
|
||||
for (i = 0; i < 2340; i++) {
|
||||
b = 0;
|
||||
for (j = 0; j < 8; j++)
|
||||
b |= next_bit() << j;
|
||||
|
||||
printf("%3u, ", b);
|
||||
if ((i % 10) == 9)
|
||||
printf("\n\t");
|
||||
}
|
||||
printf("\n};\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libburn_with_general_rspc_diV
|
||||
|
||||
/* This is a general polynomial division function.
|
||||
burn_rspc_div_3() has been derived from this by setting b to constant 3.
|
||||
*/
|
||||
static unsigned char burn_rspc_div(unsigned char a, unsigned char b)
|
||||
{
|
||||
int d;
|
||||
|
||||
if (a == 0)
|
||||
return 0;
|
||||
if (b == 0)
|
||||
return -1;
|
||||
d = gflog[a] - gflog[b];
|
||||
if (d < 0)
|
||||
d += 255;
|
||||
return gfpow[d];
|
||||
}
|
||||
|
||||
#endif /* Libburn_with_general_rspc_diV */
|
||||
|
||||
|
||||
#endif /* Libburn_with_lec_generatoR */
|
||||
|
23
libburn/ecma130ab.h
Normal file
23
libburn/ecma130ab.h
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
|
||||
|
||||
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
||||
|
||||
This code module implements the computations prescribed in ECMA-130 Annex A
|
||||
and B. For explanations of the underlying mathematics see ecma130ab.c .
|
||||
|
||||
*/
|
||||
|
||||
#ifndef Libburn_ecma130ab_includeD
|
||||
#define Libburn_ecma130ab_includeD 1
|
||||
|
||||
void burn_rspc_parity_p(unsigned char *sector);
|
||||
|
||||
void burn_rspc_parity_q(unsigned char *sector);
|
||||
|
||||
void burn_ecma130_scramble(unsigned char *sector);
|
||||
|
||||
#endif /* ! Libburn_ecma130ab_includeD */
|
||||
|
189
libburn/file.c
189
libburn/file.c
@ -1,5 +1,6 @@
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
@ -27,8 +28,6 @@ an unreadable disc */
|
||||
/* This is a generic OS oriented function wrapper which compensates
|
||||
shortcommings of read() in respect to a guaranteed amount of return data.
|
||||
See man 2 read , paragraph "RETURN VALUE".
|
||||
Possibly libburn/file.c is not the right storage location for this.
|
||||
To make it ready for a move, this function is not declared static.
|
||||
*/
|
||||
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
||||
{
|
||||
@ -211,7 +210,7 @@ static int fifo_read(struct burn_source *source,
|
||||
int size)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
int ret, todo, rpos, bufsize, diff;
|
||||
int ret, todo, rpos, bufsize, diff, counted = 0;
|
||||
|
||||
if (fs->end_of_consumption) {
|
||||
/* ??? msg: reading has been ended already */;
|
||||
@ -256,6 +255,9 @@ static int fifo_read(struct burn_source *source,
|
||||
"Forwarded input error ends output", 0, 0);
|
||||
return -1;
|
||||
}
|
||||
if (!counted)
|
||||
fs->empty_counter++;
|
||||
counted = 1;
|
||||
fifo_sleep(0);
|
||||
}
|
||||
diff = fs->buf_writepos - rpos; /* read volatile only once */
|
||||
@ -285,6 +287,7 @@ static int fifo_read(struct burn_source *source,
|
||||
(size - todo), fs->buf_readpos, (double) fs->out_counter);
|
||||
*/
|
||||
|
||||
fs->get_counter++;
|
||||
return (size - todo);
|
||||
}
|
||||
|
||||
@ -312,8 +315,10 @@ static void fifo_free(struct burn_source *source)
|
||||
burn_fifo_abort(fs, 0);
|
||||
if (fs->inp != NULL)
|
||||
burn_source_free(fs->inp);
|
||||
|
||||
if (fs->buf != NULL)
|
||||
free(fs->buf);
|
||||
burn_os_free_buffer(fs->buf,
|
||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||
free((char *) fs);
|
||||
}
|
||||
|
||||
@ -321,7 +326,8 @@ static void fifo_free(struct burn_source *source)
|
||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
|
||||
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes, fill;
|
||||
int counted;
|
||||
char *bufpt;
|
||||
pthread_t thread_handle_storage;
|
||||
|
||||
@ -335,6 +341,7 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
|
||||
/* wait for enough buffer space available */
|
||||
wpos = fs->buf_writepos;
|
||||
counted = 0;
|
||||
while (1) {
|
||||
rpos = fs->buf_readpos;
|
||||
diff = rpos - wpos;
|
||||
@ -345,18 +352,28 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
free_bytes = diff - 1;
|
||||
else {
|
||||
free_bytes = (bufsize - wpos) + rpos - 1;
|
||||
if (bufsize - wpos < fs->chunksize)
|
||||
if (bufsize - wpos < fs->inp_read_size)
|
||||
trans_end = 1;
|
||||
}
|
||||
if (free_bytes >= fs->chunksize)
|
||||
if (free_bytes >= fs->inp_read_size)
|
||||
break;
|
||||
if (!counted)
|
||||
fs->full_counter++;
|
||||
counted = 1;
|
||||
fifo_sleep(0);
|
||||
}
|
||||
|
||||
fill = bufsize - free_bytes - 1;
|
||||
if (fill < fs->total_min_fill)
|
||||
fs->total_min_fill = fill;
|
||||
if (fill < fs->interval_min_fill)
|
||||
fs->interval_min_fill = fill;
|
||||
|
||||
/* prepare the receiving memory */
|
||||
bufpt = fs->buf + wpos;
|
||||
if (trans_end) {
|
||||
bufpt = calloc(fs->chunksize, 1);
|
||||
bufpt = burn_os_alloc_buffer(
|
||||
(size_t) fs->inp_read_size, 0);
|
||||
if (bufpt == NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, -1,
|
||||
0x00000003,
|
||||
@ -370,15 +387,13 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
/* Obtain next chunk */
|
||||
if (fs->inp->read != NULL)
|
||||
ret = fs->inp->read(fs->inp,
|
||||
(unsigned char *) bufpt, fs->chunksize);
|
||||
(unsigned char *) bufpt, fs->inp_read_size);
|
||||
else
|
||||
ret = fs->inp->read_xt( fs->inp,
|
||||
(unsigned char *) bufpt, fs->chunksize);
|
||||
if (ret > 0)
|
||||
fs->in_counter += ret;
|
||||
else if (ret == 0)
|
||||
(unsigned char *) bufpt, fs->inp_read_size);
|
||||
if (ret == 0)
|
||||
break; /* EOF */
|
||||
else {
|
||||
else if (ret < 0) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Read error on fifo input", errno, 0);
|
||||
@ -387,17 +402,21 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
fs->input_error = EIO;
|
||||
break;
|
||||
}
|
||||
fs->in_counter += ret;
|
||||
fs->put_counter++;
|
||||
|
||||
/* activate read chunk */
|
||||
if (ret > fs->chunksize) /* beware of ill custom burn_source */
|
||||
ret = fs->chunksize;
|
||||
if (ret > fs->inp_read_size)
|
||||
/* beware of ill custom burn_source */
|
||||
ret = fs->inp_read_size;
|
||||
if (trans_end) {
|
||||
/* copy to end of buffer */
|
||||
memcpy(fs->buf + wpos, bufpt, bufsize - wpos);
|
||||
/* copy to start of buffer */
|
||||
memcpy(fs->buf, bufpt + (bufsize - wpos),
|
||||
fs->chunksize - (bufsize - wpos));
|
||||
free(bufpt);
|
||||
fs->inp_read_size - (bufsize - wpos));
|
||||
burn_os_free_buffer(bufpt, (size_t) fs->inp_read_size,
|
||||
0);
|
||||
if (ret >= bufsize - wpos)
|
||||
fs->buf_writepos = ret - (bufsize - wpos);
|
||||
else
|
||||
@ -433,7 +452,9 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||
So in both cases the consumer is aware that reading is futile
|
||||
or even fatal.
|
||||
*/
|
||||
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
|
||||
if(fs->buf != NULL)
|
||||
burn_os_free_buffer(fs->buf,
|
||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||
fs->buf = NULL;
|
||||
|
||||
fs->thread_handle= NULL;
|
||||
@ -450,7 +471,9 @@ int burn_fifo_cancel(struct burn_source *source)
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@param flag bit0= allow larger read chunks
|
||||
*/
|
||||
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
int chunksize, int chunks, int flag)
|
||||
{
|
||||
@ -477,6 +500,10 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
fs->thread_pid = 0;
|
||||
fs->thread_is_valid = 0;
|
||||
fs->inp = NULL; /* set later */
|
||||
if (flag & 1)
|
||||
fs->inp_read_size = 32 * 1024;
|
||||
else
|
||||
fs->inp_read_size = chunksize;
|
||||
fs->chunksize = chunksize;
|
||||
fs->chunks = chunks;
|
||||
fs->buf = NULL;
|
||||
@ -485,6 +512,9 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
fs->input_error = 0;
|
||||
fs->end_of_consumption = 0;
|
||||
fs->in_counter = fs->out_counter = 0;
|
||||
fs->total_min_fill = fs->interval_min_fill = 0;
|
||||
fs->put_counter = fs->get_counter = 0;
|
||||
fs->empty_counter = fs->full_counter = 0;
|
||||
|
||||
src = burn_source_new();
|
||||
if (src == NULL) {
|
||||
@ -550,34 +580,89 @@ int burn_fifo_inquire_status(struct burn_source *source,
|
||||
}
|
||||
|
||||
|
||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||
/* ts A91125 : API */
|
||||
void burn_fifo_get_statistics(struct burn_source *source,
|
||||
int *total_min_fill, int *interval_min_fill,
|
||||
int *put_counter, int *get_counter,
|
||||
int *empty_counter, int *full_counter)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
*total_min_fill = fs->total_min_fill;
|
||||
*interval_min_fill = fs->interval_min_fill;
|
||||
*put_counter = fs->put_counter;
|
||||
*get_counter = fs->get_counter;
|
||||
*empty_counter = fs->empty_counter;
|
||||
*full_counter = fs->full_counter;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91125 : API */
|
||||
void burn_fifo_next_interval(struct burn_source *source,
|
||||
int *interval_min_fill)
|
||||
{
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
int size, free_bytes, ret;
|
||||
char *status_text;
|
||||
|
||||
*interval_min_fill = fs->interval_min_fill;
|
||||
ret = burn_fifo_inquire_status(source,
|
||||
&size, &free_bytes, &status_text);
|
||||
fs->interval_min_fill = size - free_bytes - 1;
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= do not copy to buf but only wait until the fifo has read
|
||||
bufsize or input ended.
|
||||
The same happens if buf is NULL.
|
||||
bit1= fill to max fifo size
|
||||
*/
|
||||
int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
|
||||
int flag)
|
||||
{
|
||||
int size, free_bytes, ret, wait_count= 0;
|
||||
char *status_text;
|
||||
struct burn_source_fifo *fs = source->data;
|
||||
|
||||
if (buf == NULL)
|
||||
flag |= 1;
|
||||
|
||||
/* Eventually start fifo thread by reading 0 bytes */
|
||||
ret = fifo_read(source, (unsigned char *) NULL, 0);
|
||||
if (ret<0)
|
||||
return 0;
|
||||
{ret = 0; goto ex;}
|
||||
|
||||
/* wait for at least bufsize bytes being ready */
|
||||
while (1) {
|
||||
ret= burn_fifo_inquire_status(source,
|
||||
&size, &free_bytes, &status_text);
|
||||
if (size < bufsize) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015c,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo size is smaller than desired peek buffer", 0, 0);
|
||||
return -1;
|
||||
if (flag & 2) {
|
||||
bufsize = size - (size % fs->inp_read_size) -
|
||||
fs->inp_read_size;
|
||||
if (bufsize <= 0)
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
if (size - fs->inp_read_size < bufsize) {
|
||||
if (flag & 1) {
|
||||
bufsize = size - (size % fs->inp_read_size) -
|
||||
fs->inp_read_size;
|
||||
if (bufsize <= 0)
|
||||
{ret = 0; goto ex;}
|
||||
} else {
|
||||
libdax_msgs_submit(libdax_messenger, -1,
|
||||
0x0002015c, LIBDAX_MSGS_SEV_FAILURE,
|
||||
LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo size too small for desired peek buffer",
|
||||
0, 0);
|
||||
{ret = -1; goto ex;}
|
||||
}
|
||||
}
|
||||
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo is already under consumption when peeking is desired",
|
||||
0, 0);
|
||||
return -1;
|
||||
{ret = -1; goto ex;}
|
||||
}
|
||||
if(size - free_bytes >= bufsize) {
|
||||
|
||||
@ -586,17 +671,33 @@ int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
|
||||
wait_count, status_text, size - free_bytes);
|
||||
*/
|
||||
|
||||
memcpy(buf, fs->buf, bufsize);
|
||||
return 1;
|
||||
if(!(flag & 1))
|
||||
memcpy(buf, fs->buf, bufsize);
|
||||
{ret = 1; goto ex;}
|
||||
}
|
||||
if (ret&2) { /* input has ended, not enough data arrived */
|
||||
|
||||
if (ret & 2) {
|
||||
/* input has ended, not enough data arrived */
|
||||
if (flag & 1)
|
||||
{ret = 0; goto ex;}
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo input ended short of desired peek buffer size",
|
||||
0, 0);
|
||||
return 0;
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
|
||||
if (free_bytes < fs->inp_read_size) {
|
||||
/* Usable fifo size filled, not enough data arrived */
|
||||
if (flag & 1)
|
||||
{ret = 0; goto ex;}
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020174,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Fifo alignment does not allow desired read size",
|
||||
0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
|
||||
usleep(100000);
|
||||
wait_count++;
|
||||
|
||||
@ -608,5 +709,25 @@ int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||
*/
|
||||
|
||||
}
|
||||
return(0);
|
||||
ret = 0;
|
||||
ex:;
|
||||
fs->total_min_fill = fs->interval_min_fill = fs->buf_writepos;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* ts A80713 : API */
|
||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||
int flag)
|
||||
{
|
||||
return burn_fifo_fill_data(source, buf, bufsize, 0);
|
||||
}
|
||||
|
||||
|
||||
/* ts A91125 : API */
|
||||
int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
|
||||
{
|
||||
return burn_fifo_fill_data(source, NULL, bufsize,
|
||||
1 | ((flag & 1) << 1));
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ struct burn_source_fifo {
|
||||
|
||||
/* the burn_source for which this fifo is acting as proxy */
|
||||
struct burn_source *inp;
|
||||
int inp_read_size;
|
||||
|
||||
/* <<< up to now it was only a pipe. This is on its way out. */
|
||||
int outlet[2];
|
||||
@ -51,6 +52,14 @@ struct burn_source_fifo {
|
||||
|
||||
off_t in_counter;
|
||||
off_t out_counter;
|
||||
|
||||
int total_min_fill;
|
||||
int interval_min_fill;
|
||||
int put_counter;
|
||||
int get_counter;
|
||||
int empty_counter;
|
||||
int full_counter;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,6 +75,13 @@ burn_abort_handler_t burn_global_signal_handler = NULL;
|
||||
/* ts A70223 : wether implemented untested profiles are supported */
|
||||
int burn_support_untested_profiles = 0;
|
||||
|
||||
/* ts A91111 :
|
||||
whether to log SCSI commands (to be implemented in sg-*.c)
|
||||
bit0= log in /tmp/libburn_sg_command_log
|
||||
bit1= log to stderr
|
||||
bit2= flush every line
|
||||
*/
|
||||
int burn_sg_log_scsi = 0;
|
||||
|
||||
/* ts A60925 : ticket 74 */
|
||||
/** Create the messenger object for libburn. */
|
||||
@ -414,3 +421,9 @@ int burn_set_messenger(void *messenger)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91111 API */
|
||||
void burn_set_scsi_logging(int flag)
|
||||
{
|
||||
burn_sg_log_scsi = flag & 7;
|
||||
}
|
||||
|
@ -141,19 +141,22 @@ enum burn_write_types
|
||||
only raw block types are supported
|
||||
With DVD and BD media: not supported.
|
||||
|
||||
ts A90901: THIS HAS BEEN DISABLED because its implementation
|
||||
ts A90901: This had been disabled because its implementation
|
||||
relied on code from cdrdao which is not understood
|
||||
currently.
|
||||
A burn run will abort with "FATAL" error message
|
||||
if this mode is attempted.
|
||||
@since 0.7.2
|
||||
ts A91016: Re-implemented according to ECMA-130 Annex A and B.
|
||||
Now understood, explained and not stemming from cdrdao.
|
||||
@since 0.7.4
|
||||
*/
|
||||
BURN_WRITE_RAW,
|
||||
|
||||
/** In replies this indicates that not any writing will work.
|
||||
As parameter for inquiries it indicates that no particular write
|
||||
mode shall is specified.
|
||||
Do not use for setting a write mode for burning. It won't work.
|
||||
Do not use for setting a write mode for burning. It will not work.
|
||||
*/
|
||||
BURN_WRITE_NONE
|
||||
};
|
||||
@ -759,6 +762,19 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed);
|
||||
*/
|
||||
void burn_set_verbosity(int level);
|
||||
|
||||
/* ts A91111 */
|
||||
/** Enable resp. disable logging of SCSI commands (currently Linux only).
|
||||
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
|
||||
safe for multiple drives.
|
||||
@param flag Bitfield for control purposes. The default is 0.
|
||||
bit0= log to file /tmp/libburn_sg_command_log
|
||||
bit1= log to stderr
|
||||
bit2= flush output after each line
|
||||
@since 0.7.4
|
||||
*/
|
||||
void burn_set_scsi_logging(int flag);
|
||||
|
||||
/* ts A60813 */
|
||||
/** Set parameters for behavior on opening device files. To be called early
|
||||
after burn_initialize() and before any bus scan. But not mandatory at all.
|
||||
@ -1562,9 +1578,11 @@ void burn_drive_cancel(struct burn_drive *drive);
|
||||
|
||||
|
||||
/* ts A61223 */
|
||||
/** Inquire whether the most recent write run was successful. Reasons for
|
||||
non-success may be: rejection of burn parameters, abort during fatal errors
|
||||
during write, a call to burn_drive_cancel() by the application thread.
|
||||
/** Inquire whether the most recent asynchronous media job was successful.
|
||||
This applies to burn_disc_erase(), burn_disc_format(), burn_disc_write().
|
||||
Reasons for non-success may be: rejection of burn parameters, abort due to
|
||||
fatal errors during write, blank or format, a call to burn_drive_cancel()
|
||||
by the application thread.
|
||||
@param d The drive to inquire.
|
||||
@return 1=burn seems to have went well, 0=burn failed
|
||||
@since 0.2.6
|
||||
@ -1772,6 +1790,58 @@ void burn_source_free(struct burn_source *s);
|
||||
struct burn_source *burn_file_source_new(const char *path,
|
||||
const char *subpath);
|
||||
|
||||
|
||||
/* ts A91122 : An interface to open(O_DIRECT) or similar OS tricks. */
|
||||
|
||||
/** Opens a file with eventual acceleration preparations which may depend
|
||||
on the operating system and on compile time options of libburn.
|
||||
You may use this call instead of open(2) for opening file descriptors
|
||||
which shall be handed to burn_fd_source_new().
|
||||
This should only be done for tracks with BURN_BLOCK_MODE1 (2048 bytes
|
||||
per block).
|
||||
|
||||
If you use this call then you MUST allocate the buffers which you use
|
||||
with read(2) by call burn_os_alloc_buffer(). Read sizes MUST be a multiple
|
||||
of a safe buffer amount. Else you risk that track data get altered during
|
||||
transmission.
|
||||
burn_disk_write() will allocate a suitable read/write buffer for its own
|
||||
operations. A fifo created by burn_fifo_source_new() will allocate
|
||||
suitable memory for its buffer if called with flag bit0 and a multiple
|
||||
of a safe buffer amount.
|
||||
@param path The file address to open
|
||||
@param open_flags The flags as of man 2 open. Normally just O_RDONLY.
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||
@return A file descriptor as of open(2). Finally to be disposed
|
||||
by close(2).
|
||||
-1 indicates failure.
|
||||
@since 0.7.4
|
||||
*/
|
||||
int burn_os_open_track_src(char *path, int open_flags, int flag);
|
||||
|
||||
/** Allocate a memory area that is suitable for reading with a file descriptor
|
||||
opened by burn_os_open_track_src().
|
||||
@param amount Number of bytes to allocate. This should be a multiple
|
||||
of the operating system's i/o block size. 32 KB is
|
||||
guaranteed by libburn to be safe.
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||
@return The address of the allocated memory, or NULL on failure.
|
||||
A non-NULL return value has finally to be disposed via
|
||||
burn_os_free_buffer().
|
||||
@since 0.7.4
|
||||
*/
|
||||
void *burn_os_alloc_buffer(size_t amount, int flag);
|
||||
|
||||
/** Dispose a memory area which was obtained by burn_os_alloc_buffer(),
|
||||
@param buffer Memory address to be freed.
|
||||
@param amount The number of bytes which was allocated at that
|
||||
address.
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||
@return 1 success , <=0 failure
|
||||
@since 0.7.4
|
||||
*/
|
||||
int burn_os_free_buffer(void *buffer, size_t amount, int flag);
|
||||
|
||||
|
||||
/** Creates a data source for an image file (a track) from an open
|
||||
readable filedescriptor, an eventually open readable subcodes file
|
||||
descriptor and eventually a fixed size in bytes.
|
||||
@ -1810,7 +1880,17 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
|
||||
a particular chunksize. E.g. libisofs demands 2048.
|
||||
@param chunks The number of chunks to be allocated in ring buffer.
|
||||
This value must be >= 2.
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||
@param flag Bitfield for control purposes:
|
||||
bit0= The read method of inp is capable of delivering
|
||||
arbitrary amounts of data per call. Not only one
|
||||
sector.
|
||||
Suitable for inp from burn_file_source_new()
|
||||
and burn_fd_source_new() if not the fd has
|
||||
exotic limitations on read size.
|
||||
You MUST use this on inp which uses an fd opened
|
||||
with burn_os_open_track_src().
|
||||
Better do not use with other inp types.
|
||||
@since 0.7.4
|
||||
@return A pointer to the newly created burn_source.
|
||||
Later both burn_sources, inp and the returned fifo, have
|
||||
to be disposed by calling burn_source_free() for each.
|
||||
@ -1843,12 +1923,43 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||
int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
|
||||
int *free_bytes, char **status_text);
|
||||
|
||||
/* ts A91125 */
|
||||
/** Inquire various counters which reflect the fifo operation.
|
||||
@param fifo The fifo object to inquire
|
||||
@param total_min_fill The minimum number of bytes in the fifo. Beginning
|
||||
from the moment when fifo consumption is enabled.
|
||||
@param interval_min_fill The minimum byte number beginning from the moment
|
||||
when fifo consumption is enabled or from the
|
||||
most recent moment when burn_fifo_next_interval()
|
||||
was called.
|
||||
@param put_counter The number of data transactions into the fifo.
|
||||
@param get_counter The number of data transactions out of the fifo.
|
||||
@param empty_counter The number of times the fifo was empty.
|
||||
@param full_counter The number of times the fifo was full.
|
||||
@since 0.7.4
|
||||
*/
|
||||
void burn_fifo_get_statistics(struct burn_source *source,
|
||||
int *total_min_fill, int *interval_min_fill,
|
||||
int *put_counter, int *get_counter,
|
||||
int *empty_counter, int *full_counter);
|
||||
|
||||
/* ts A91125 */
|
||||
/** Inquire the fifo minimum fill counter for intervals and reset that counter.
|
||||
@param fifo The fifo object to inquire
|
||||
@param interval_min_fill The minimum number of bytes in the fifo. Beginning
|
||||
from the moment when fifo consumption is enabled
|
||||
or from the most recent moment when
|
||||
burn_fifo_next_interval() was called.
|
||||
@since 0.7.4
|
||||
*/
|
||||
void burn_fifo_next_interval(struct burn_source *source,
|
||||
int *interval_min_fill);
|
||||
|
||||
/* ts A80713 */
|
||||
/** Obtain a preview of the first input data of a fifo which was created
|
||||
by burn_fifo_source_new(). The data will later be delivered normally to
|
||||
the consumer track of the fifo.
|
||||
bufsize may not be larger than the fifo size (chunk_size * chunks).
|
||||
bufsize may not be larger than the fifo size (chunk_size * chunks) - 32k.
|
||||
This call will succeed only if data consumption by the track has not
|
||||
started yet, i.e. best before the call to burn_disc_write().
|
||||
It will start the worker thread of the fifo with the expectable side
|
||||
@ -1856,9 +1967,9 @@ int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
|
||||
data have arrived or until it becomes clear that this will not happen.
|
||||
The call may be repeated with increased bufsize. It will always yield
|
||||
the bytes beginning from the first one in the fifo.
|
||||
@param fifo The fifo object to inquire
|
||||
@param fifo The fifo object to inquire resp. start
|
||||
@param buf Pointer to memory of at least bufsize bytes where to
|
||||
deliver the peeked data
|
||||
deliver the peeked data.
|
||||
@param bufsize Number of bytes to peek from the start of the fifo data
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0).
|
||||
@return <0 on severe error, 0 if not enough data, 1 if bufsize bytes read
|
||||
@ -1867,6 +1978,22 @@ int burn_fifo_inquire_status(struct burn_source *fifo, int *size,
|
||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||
int flag);
|
||||
|
||||
/* ts A91125 */
|
||||
/** Start the fifo worker thread and wait either until the requested number
|
||||
of bytes have arrived or until it becomes clear that this will not happen.
|
||||
Filling will go on asynchronously after burn_fifo_fill() returned.
|
||||
This call and burn_fifo_peek_data() do not disturb each other.
|
||||
@param fifo The fifo object to start
|
||||
@param fill Number of bytes desired. Expect to get return 1 if
|
||||
at least fifo size - 32k were read.
|
||||
@param flag Bitfield for control purposes.
|
||||
bit0= fill fifo to maximum size
|
||||
@return <0 on severe error, 0 if not enough data,
|
||||
1 if desired amount or fifo full
|
||||
@since 0.7.4
|
||||
*/
|
||||
int burn_fifo_fill(struct burn_source *source, int bufsize, int flag);
|
||||
|
||||
|
||||
/* ts A70328 */
|
||||
/** Sets a fixed track size after the data source object has already been
|
||||
@ -2103,6 +2230,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,
|
||||
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
|
||||
@param opts The read opts to change
|
||||
@ -2449,7 +2602,7 @@ void burn_version(int *major, int *minor, int *micro);
|
||||
*/
|
||||
#define burn_header_version_major 0
|
||||
#define burn_header_version_minor 7
|
||||
#define burn_header_version_micro 2
|
||||
#define burn_header_version_micro 4
|
||||
/** Note:
|
||||
Above version numbers are also recorded in configure.ac because libtool
|
||||
wants them as parameters at build time.
|
||||
@ -2746,4 +2899,38 @@ BURN_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ts A91205 */
|
||||
/* The following experiments may be interesting in future:
|
||||
*/
|
||||
|
||||
/* Perform OPC explicitely.
|
||||
# define Libburn_pioneer_dvr_216d_with_opC 1
|
||||
*/
|
||||
|
||||
/* Load mode page 5 and modify it rather than composing from scratch.
|
||||
# define Libburn_pioneer_dvr_216d_load_mode5 1
|
||||
*/
|
||||
|
||||
/* Inquire drive events and react by reading configuration or starting unit.
|
||||
# define Libburn_pioneer_dvr_216d_get_evenT 1
|
||||
*/
|
||||
|
||||
/* ts A91112 */
|
||||
/* Do not probe CD modes but declare only data and audio modes supported.
|
||||
For other modes resp. real probing one has to call
|
||||
burn_drive_probe_cd_write_modes().
|
||||
|
||||
# define Libburn_pioneer_dvr_216d_dummy_probe_wM 1
|
||||
*/
|
||||
#ifdef Libburn_pioneer_dvr_216d_dummy_probe_wM
|
||||
|
||||
/* Probe available CD write modes and block types.
|
||||
@param drive_info drive object to be inquired
|
||||
*/
|
||||
int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info)
|
||||
|
||||
#endif /* Libburn_pioneer_dvr_216d_dummy_probe_wM */
|
||||
|
||||
|
||||
#endif /*LIBBURN_H*/
|
||||
|
@ -528,7 +528,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
||||
0x0002015a (NOTE,HIGH) = Could not examine busy device
|
||||
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
|
||||
0x0002015c (FAILURE,HIGH) = Fifo size is smaller than desired peek buffer
|
||||
0x0002015c (FAILURE,HIGH) = Fifo size too small for desired peek buffer
|
||||
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
|
||||
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
|
||||
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
|
||||
@ -551,6 +551,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
|
||||
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
||||
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
||||
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
||||
|
||||
|
||||
libdax_audioxtr:
|
||||
|
234
libburn/mmc.c
234
libburn/mmc.c
@ -28,6 +28,8 @@
|
||||
/* ts A70223 : in init.c */
|
||||
extern int burn_support_untested_profiles;
|
||||
|
||||
static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len);
|
||||
|
||||
|
||||
#ifdef Libburn_log_in_and_out_streaM
|
||||
/* <<< ts A61031 */
|
||||
@ -177,7 +179,7 @@ static unsigned char MMC_GET_CONFIGURATION[] =
|
||||
{ 0x46, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||
|
||||
static unsigned char MMC_SYNC_CACHE[] = { 0x35, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static unsigned char MMC_GET_EVENT[] = { 0x4A, 1, 0, 0, 16, 0, 0, 0, 8, 0 };
|
||||
static unsigned char MMC_GET_EVENT[] = { 0x4A, 1, 0, 0, 0x7e, 0, 0, 0, 8, 0 };
|
||||
static unsigned char MMC_CLOSE[] = { 0x5B, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static unsigned char MMC_TRACK_INFO[] = { 0x52, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||
|
||||
@ -243,11 +245,6 @@ int mmc_function_spy(struct burn_drive *d, char * text)
|
||||
d->cancel = 1;
|
||||
return 0;
|
||||
}
|
||||
if (d->is_stopped && strcmp(text, "stop_unit") != 0 &&
|
||||
strcmp(text, "start_unit") != 0) {
|
||||
d->start_unit(d);
|
||||
d->is_stopped = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -276,12 +273,29 @@ int mmc_int_to_four_char(unsigned char *data, int num)
|
||||
}
|
||||
|
||||
|
||||
static int mmc_start_for_bit0 = 0;
|
||||
|
||||
/* @param flag bit0= the calling function should need no START UNIT.
|
||||
(Handling depends on mmc_start_for_bit0)
|
||||
*/
|
||||
int mmc_start_if_needed(struct burn_drive *d, int flag)
|
||||
{
|
||||
if (!d->is_stopped)
|
||||
return 2;
|
||||
if ((flag & 1) && !mmc_start_for_bit0)
|
||||
return 2;
|
||||
d->start_unit(d);
|
||||
d->is_stopped = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
|
||||
{
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
|
||||
return;
|
||||
|
||||
@ -313,6 +327,7 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
|
||||
int lba;
|
||||
char msg[80];
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_reserve_track") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -347,6 +362,7 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
|
||||
{
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_track_info") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -399,6 +415,7 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
||||
int ret, num, alloc_len = 20;
|
||||
unsigned char *data;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_get_nwa") <= 0)
|
||||
return -1;
|
||||
|
||||
@ -409,6 +426,11 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
||||
*lba = mmc_four_char_to_int(data + 8);
|
||||
*nwa = mmc_four_char_to_int(data + 12);
|
||||
num = mmc_four_char_to_int(data + 16);
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_load_mode5
|
||||
/* >>> memorize track mode : data[6] & 0xf */;
|
||||
#endif
|
||||
|
||||
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x12 || d->current_profile == 0x43) {
|
||||
/* overwriteable */
|
||||
@ -519,17 +541,19 @@ void mmc_get_event(struct burn_drive *d)
|
||||
{
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
int alloc_len= 8;
|
||||
int alloc_len = 8, len, evt_code, loops = 0;
|
||||
unsigned char *evt;
|
||||
|
||||
if (mmc_function_spy(d, "mmc_get_event") <= 0)
|
||||
return;
|
||||
|
||||
again:;
|
||||
scsi_init_command(&c, MMC_GET_EVENT, sizeof(MMC_GET_EVENT));
|
||||
/*
|
||||
c.oplen = sizeof(MMC_GET_EVENT);
|
||||
memcpy(c.opcode, MMC_GET_EVENT, sizeof(MMC_GET_EVENT));
|
||||
*/
|
||||
c.dxfer_len = alloc_len;
|
||||
c.dxfer_len = 8;
|
||||
|
||||
/* >>> have a burn_drive element for Notification Class */;
|
||||
c.opcode[4] = 0x7e;
|
||||
|
||||
c.opcode[7] = (c.dxfer_len >> 8) & 0xff;
|
||||
c.opcode[8] = c.dxfer_len & 0xff;
|
||||
c.retry = 1;
|
||||
@ -538,11 +562,66 @@ void mmc_get_event(struct burn_drive *d)
|
||||
c.page->sectors = 0;
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
burn_print(12, "0x%x:0x%x:0x%x:0x%x\n",
|
||||
c.page->data[0], c.page->data[1], c.page->data[2],
|
||||
c.page->data[3]);
|
||||
burn_print(12, "event: %d:%d:%d:%d\n", c.page->data[4],
|
||||
c.page->data[5], c.page->data[6], c.page->data[7]);
|
||||
if (c.error)
|
||||
return;
|
||||
|
||||
evt = c.page->data;
|
||||
len = ((evt[0] << 8) | evt[1]) + 2;
|
||||
if (len < 8)
|
||||
return;
|
||||
|
||||
/* >>> memorize evt[3] in burn_drive element for Notification Class */;
|
||||
if (evt[3] == 0) /* No event */
|
||||
return;
|
||||
|
||||
evt_code = evt[4] & 0xf;
|
||||
if (evt_code == 0) /* No change */
|
||||
return;
|
||||
|
||||
switch (evt[2] & 7) {
|
||||
case 0: /* no events supported */
|
||||
return;
|
||||
case 1: /* Operational change */
|
||||
if (((evt[6] << 8) | evt[7])) {
|
||||
alloc_len = 8;
|
||||
mmc_get_configuration_al(d, &alloc_len);
|
||||
}
|
||||
break;
|
||||
case 2: /* Power Management */
|
||||
if (evt[5] >= 2)
|
||||
d->start_unit(d);
|
||||
break;
|
||||
case 3: /* External request */
|
||||
|
||||
/* >>> report about external request */;
|
||||
|
||||
break;
|
||||
case 4: /* Media */
|
||||
if (evt_code == 2) {
|
||||
d->start_unit(d);
|
||||
alloc_len = 8;
|
||||
mmc_get_configuration_al(d, &alloc_len);
|
||||
}
|
||||
break;
|
||||
case 5: /* Multiple Host Events */
|
||||
|
||||
/* >>> report about foreign host interference */;
|
||||
|
||||
break;
|
||||
|
||||
case 6: /* Device busy */
|
||||
if (evt_code == 1 && evt[5]) {
|
||||
|
||||
/* >>> wait the time announced in evt[6],[7]
|
||||
as 100ms units */;
|
||||
}
|
||||
break;
|
||||
default: /* reserved */
|
||||
break;
|
||||
}
|
||||
loops++;
|
||||
if (loops < 100)
|
||||
goto again;
|
||||
}
|
||||
|
||||
|
||||
@ -687,6 +766,7 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
|
||||
struct command c;
|
||||
int len;
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_write_12") <= 0)
|
||||
return;
|
||||
|
||||
@ -729,6 +809,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
|
||||
#endif /* Libburn_log_in_and_out_streaM */
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_write") <= 0)
|
||||
return BE_CANCELLED;
|
||||
|
||||
@ -1022,6 +1103,7 @@ static int mmc_read_toc_fmt0(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len = 4, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_toc_fmt0") <= 0)
|
||||
return -1;
|
||||
ret = mmc_read_toc_fmt0_al(d, &alloc_len);
|
||||
@ -1404,6 +1486,7 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len = 4, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_toc") <= 0)
|
||||
return;
|
||||
|
||||
@ -1434,6 +1517,7 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||
struct burn_track **tracks;
|
||||
struct burn_toc_entry toc_entry;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_multi_session_c1") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -1631,7 +1715,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
||||
d->disc_info_valid |= (!!(data[7] & 128)) << 1;
|
||||
if (len + 2 > 31 && (data[7] & 64)) {
|
||||
memcpy(d->disc_bar_code, data + 24, 8);
|
||||
d->disc_bar_code[9] = 0;
|
||||
d->disc_bar_code[8] = 0;
|
||||
d->disc_info_valid |= 4;
|
||||
}
|
||||
if (len + 2 > 32 && (data[7] & 16)) {
|
||||
@ -1766,11 +1850,16 @@ regard_as_blank:;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ts A61217 : Note for future
|
||||
/* ts A61217 :
|
||||
growisofs performs OPC if (data[0]<<8)|data[1]<=32
|
||||
which indicates no OPC entries are attached to the
|
||||
reply from the drive.
|
||||
ts A91104 :
|
||||
Actually growisofs performs OPC only on DVD-R[W].
|
||||
*/
|
||||
d->num_opc_tables = 0;
|
||||
if(((data[0] << 8) | data[1]) > 32) /* i.e. > 34 bytes are available */
|
||||
d->num_opc_tables = data[33];
|
||||
|
||||
/* ts A61219 : mmc5r03c.pdf 6.22.3.1.13 BG Format Status
|
||||
0=blank (not yet started)
|
||||
@ -1818,6 +1907,7 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len = 34, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_disc_info") <= 0)
|
||||
return;
|
||||
|
||||
@ -1849,6 +1939,7 @@ void mmc_read_atip(struct burn_drive *d)
|
||||
4234, 5646, 7056, 8468, -12, -13, -14, -15};
|
||||
/* 24, 32, 40, 48, -, -, -, - */
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_atip") <= 0)
|
||||
return;
|
||||
|
||||
@ -2006,6 +2097,7 @@ void mmc_read_sectors(struct burn_drive *d,
|
||||
int errorblock, req;
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_read_sectors") <= 0)
|
||||
return;
|
||||
|
||||
@ -2076,6 +2168,7 @@ void mmc_erase(struct burn_drive *d, int fast)
|
||||
{
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_erase") <= 0)
|
||||
return;
|
||||
|
||||
@ -2097,6 +2190,7 @@ void mmc_read_lead_in(struct burn_drive *d, struct buffer *buf)
|
||||
int len;
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_read_lead_in") <= 0)
|
||||
return;
|
||||
|
||||
@ -2125,6 +2219,7 @@ void mmc_perform_opc(struct burn_drive *d)
|
||||
{
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_perform_opc") <= 0)
|
||||
return;
|
||||
|
||||
@ -2157,14 +2252,11 @@ int mmc_set_streaming(struct burn_drive *d,
|
||||
unsigned char *pd;
|
||||
int key, asc, ascq;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_set_streaming") <= 0)
|
||||
return 0;
|
||||
|
||||
scsi_init_command(&c, MMC_SET_STREAMING, sizeof(MMC_SET_STREAMING));
|
||||
/*
|
||||
c.oplen = sizeof(MMC_SET_STREAMING);
|
||||
memcpy(c.opcode, MMC_SET_STREAMING, sizeof(MMC_SET_STREAMING));
|
||||
*/
|
||||
c.retry = 1;
|
||||
c.page = &buf;
|
||||
c.page->bytes = 28;
|
||||
@ -2218,26 +2310,10 @@ int mmc_set_streaming(struct burn_drive *d,
|
||||
d->issue_command(d, &c);
|
||||
if (c.error) {
|
||||
if (c.sense[2]!=0 && !d->silent_on_scsi_error) {
|
||||
|
||||
#ifdef NIX
|
||||
sprintf(msg,
|
||||
"SCSI error on set_streaming(%d): key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||
w_speed,
|
||||
c.sense[2],c.sense[12],c.sense[13]);
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index,
|
||||
0x00020124,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
#else /* NIX */
|
||||
|
||||
sprintf(msg,
|
||||
"SCSI error on set_streaming(%d): ", w_speed);
|
||||
scsi_error_msg(d, c.sense, 14, msg + strlen(msg),
|
||||
&key, &asc, &ascq);
|
||||
|
||||
#endif /* !NIX */
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2251,6 +2327,7 @@ void mmc_set_speed(struct burn_drive *d, int r, int w)
|
||||
int ret, end_lba = 0;
|
||||
struct burn_speed_descriptor *best_sd = NULL;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_set_speed") <= 0)
|
||||
return;
|
||||
|
||||
@ -2364,7 +2441,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
|
||||
return 0;
|
||||
}
|
||||
old_alloc_len = *alloc_len;
|
||||
*alloc_len = len = mmc_four_char_to_int(c.page->data);
|
||||
*alloc_len = len = mmc_four_char_to_int(c.page->data) + 4;
|
||||
if (len > old_alloc_len)
|
||||
len = old_alloc_len;
|
||||
if (len < 8 || len > 4096)
|
||||
@ -2591,6 +2668,7 @@ void mmc_get_configuration(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len = 8, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_get_configuration") <= 0)
|
||||
return;
|
||||
|
||||
@ -2794,6 +2872,7 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
|
||||
{
|
||||
int alloc_len = 4, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_format_capacities") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -2822,9 +2901,7 @@ void mmc_sync_cache(struct burn_drive *d)
|
||||
c.oplen = sizeof(MMC_SYNC_CACHE);
|
||||
*/
|
||||
c.retry = 1;
|
||||
|
||||
c.opcode[1] |= 2; /* ts A70918 : Immed */
|
||||
|
||||
c.page = NULL;
|
||||
c.dir = NO_TRANSFER;
|
||||
|
||||
@ -2852,6 +2929,7 @@ void mmc_sync_cache(struct burn_drive *d)
|
||||
d->cancel = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (spc_wait_unit_attention(d, 3600, "SYNCHRONIZE CACHE", 0) <= 0)
|
||||
d->cancel = 1;
|
||||
else
|
||||
@ -2874,11 +2952,6 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
|
||||
|
||||
scsi_init_command(&c, MMC_READ_BUFFER_CAPACITY,
|
||||
sizeof(MMC_READ_BUFFER_CAPACITY));
|
||||
/*
|
||||
memcpy(c.opcode, MMC_READ_BUFFER_CAPACITY,
|
||||
sizeof(MMC_READ_BUFFER_CAPACITY));
|
||||
c.oplen = sizeof(MMC_READ_BUFFER_CAPACITY);
|
||||
*/
|
||||
c.dxfer_len = alloc_len;
|
||||
c.opcode[7] = (c.dxfer_len >> 8) & 0xff;
|
||||
c.opcode[8] = c.dxfer_len & 0xff;
|
||||
@ -2946,6 +3019,7 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
|
||||
int key, asc, ascq;
|
||||
int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_format_unit") <= 0)
|
||||
return 0;
|
||||
size_mode = (flag >> 1) & 3;
|
||||
@ -3687,6 +3761,7 @@ int mmc_get_write_performance(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len = 8, max_descr = 0, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_get_write_performance") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -3729,10 +3804,9 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
pd[4] = 8;
|
||||
/* Link size dummy */
|
||||
pd[5] = 0;
|
||||
|
||||
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11 ||
|
||||
d->current_profile == 0x15)
|
||||
&& o->write_type == BURN_WRITE_SAO) {
|
||||
&& o->write_type == BURN_WRITE_SAO) {
|
||||
/* ts A70205 : DVD-R[W][/DL] : Disc-at-once, DAO */
|
||||
/* Learned from dvd+rw-tools and mmc5r03c.pdf .
|
||||
See doc/cookbook.txt for more detailed references. */
|
||||
@ -3741,8 +3815,17 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
pd[2] = ((!!o->underrun_proof) << 6)
|
||||
| ((!!o->simulate) << 4)
|
||||
| 2;
|
||||
/* No multi-session , FP = 0 , Track Mode = 5 */
|
||||
|
||||
/* No multi-session , FP = 0 , Copy = 0, Track Mode = 5 */
|
||||
pd[3] = 5;
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_load_mode5
|
||||
|
||||
/* >>> use track mode from mmc_get_nwa() */
|
||||
/* >>> pd[3] = (pd[3] & ~0xf) | (d->track_inf[5] & 0xf); */
|
||||
|
||||
#endif
|
||||
|
||||
/* Data Block Type = 8 */
|
||||
pd[4] = 8;
|
||||
|
||||
@ -3819,6 +3902,7 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
|
||||
{
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 0);
|
||||
if (mmc_function_spy(d, "mmc_read_10") <= 0)
|
||||
return -1;
|
||||
;
|
||||
@ -3877,6 +3961,7 @@ int mmc_read_capacity(struct burn_drive *d)
|
||||
int alloc_len= 8;
|
||||
|
||||
d->media_read_capacity = 0x7fffffff;
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_capacity") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -3960,7 +4045,9 @@ int mmc_read_disc_structure(struct burn_drive *d,
|
||||
char **reply, int *reply_len, int flag)
|
||||
{
|
||||
int alloc_len = 4, ret;
|
||||
char msg[80];
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_disc_structure") <= 0)
|
||||
return 0;
|
||||
|
||||
@ -3971,7 +4058,49 @@ int mmc_read_disc_structure(struct burn_drive *d,
|
||||
fprintf(stderr,"LIBBURN_DEBUG: ADh alloc_len = %d , ret = %d\n",
|
||||
alloc_len, ret);
|
||||
*/
|
||||
if (alloc_len >= 12 && ret > 0)
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (alloc_len < 12) {
|
||||
sprintf(msg,
|
||||
"READ DISC STRUCTURE announces only %d bytes of reply\n",
|
||||
alloc_len);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg, 0, 0);
|
||||
ret = 0;
|
||||
|
||||
/* ts A91205
|
||||
LG GH22LS30 revision 1.00 returns for DVD-R format
|
||||
code 0x0E an allocation length of 4 (= 0 payload).
|
||||
A MS-Windows tool can inquire media code "RITEKF1",
|
||||
though.
|
||||
This macro causes a try to unconditionally read the
|
||||
desired payload bytes. The drive then returns 35
|
||||
bytes as requested and the media id is "RITEKF1".
|
||||
Nevertheless this is not a generally usable gesture
|
||||
because older Linux USB dislikes requests to fetch
|
||||
more bytes than the drive will deliver.
|
||||
|
||||
# define Libburn_enforce_structure_code_0x0E 1
|
||||
*/
|
||||
|
||||
#ifdef Libburn_enforce_structure_code_0x0E
|
||||
if (format == 0x0E) {
|
||||
alloc_len = min_len + 4;
|
||||
ret = mmc_read_disc_structure_al(d, &alloc_len,
|
||||
media_type, layer_number, format, min_len,
|
||||
reply, reply_len, 0);
|
||||
if (*reply_len < min_len || *reply == NULL)
|
||||
ret = 0;
|
||||
sprintf(msg, "READ DISC STRUCTURE returns %d bytes of required %d\n",
|
||||
*reply_len + 4, min_len + 4);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
} else
|
||||
ret = mmc_read_disc_structure_al(d, &alloc_len,
|
||||
media_type, layer_number, format, min_len,
|
||||
reply, reply_len, 0);
|
||||
@ -4253,6 +4382,7 @@ int mmc_setup_drive(struct burn_drive *d)
|
||||
d->needs_close_session = 0;
|
||||
d->needs_sync_cache = 0;
|
||||
d->bg_format_status = -1;
|
||||
d->num_opc_tables = -1;
|
||||
d->last_lead_in = -2000000000;
|
||||
d->last_lead_out = -2000000000;
|
||||
d->disc_type = 0xff;
|
||||
|
@ -68,6 +68,9 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
const struct burn_write_opts *o,
|
||||
unsigned char *pd);
|
||||
|
||||
/* ts A70201 */
|
||||
int mmc_four_char_to_int(unsigned char *data);
|
||||
|
||||
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
|
||||
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||
struct buffer *buf);
|
||||
@ -90,4 +93,12 @@ int mmc_get_media_product_id(struct burn_drive *d,
|
||||
char **product_id, char **media_code1, char **media_code2,
|
||||
char **book_type, int flag);
|
||||
|
||||
|
||||
/* ts A60910 (estimated) */
|
||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||
|
||||
/* ts A91118 */
|
||||
int mmc_start_if_needed(struct burn_drive *d, int flag);
|
||||
|
||||
|
||||
#endif /*__MMC*/
|
||||
|
@ -39,6 +39,8 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||
opts->fill_up_media = 0;
|
||||
opts->force_is_set = 0;
|
||||
opts->do_stream_recording = 0;
|
||||
opts->dvd_obs_override = 0;
|
||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||
opts->has_mediacatalog = 0;
|
||||
opts->format = BURN_CDROM;
|
||||
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 */
|
||||
|
@ -51,9 +51,19 @@ struct burn_write_opts
|
||||
|
||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
int has_mediacatalog;
|
||||
unsigned char mediacatalog[13];
|
||||
@ -64,6 +74,11 @@ struct burn_write_opts
|
||||
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
|
||||
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||
struct burn_read_opts
|
||||
|
@ -17,7 +17,27 @@
|
||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||
|
||||
|
||||
/* spc command set */
|
||||
/* START STOP UNIT as of SBC-1 and SBC-2
|
||||
0: Opcode 0x1B
|
||||
1: bit0= Immed
|
||||
bit1-7= reserved
|
||||
2: reserved
|
||||
3: reserved
|
||||
4: bit0= Start (else Stop unit)
|
||||
bit1= Load/Eject (according to Start resp. Stop)
|
||||
bit2-3= reserved
|
||||
bit4-7= Power Condition
|
||||
0= Start Valid: process Start and Load/Eject bits
|
||||
1= assume Active state
|
||||
2= assume Idle state
|
||||
3= assume Stanby state
|
||||
(5= SBC-1 only: assume Sleep state)
|
||||
7= transfer control of power conditions to logical unit
|
||||
10= force idle condition timer to 0
|
||||
11= force standby condition timer to 0
|
||||
All others are reserved.
|
||||
5: Control (set to 0)
|
||||
*/
|
||||
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
||||
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
||||
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
||||
@ -31,11 +51,6 @@ void sbc_load(struct burn_drive *d)
|
||||
return;
|
||||
|
||||
scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD));
|
||||
/*
|
||||
memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD));
|
||||
c.oplen = sizeof(SBC_LOAD);
|
||||
c.page = NULL;
|
||||
*/
|
||||
c.retry = 1;
|
||||
|
||||
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
|
||||
@ -59,14 +74,7 @@ void sbc_eject(struct burn_drive *d)
|
||||
return;
|
||||
|
||||
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||
/*
|
||||
memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||
c.oplen = sizeof(SBC_UNLOAD);
|
||||
c.page = NULL;
|
||||
*/
|
||||
|
||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||
|
||||
c.page = NULL;
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
@ -76,8 +84,11 @@ void sbc_eject(struct burn_drive *d)
|
||||
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
||||
}
|
||||
|
||||
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */
|
||||
int sbc_start_unit(struct burn_drive *d)
|
||||
|
||||
/* ts A91112 : Now with flag */
|
||||
/* @param flag bit0= asynchronous waiting
|
||||
*/
|
||||
int sbc_start_unit_flag(struct burn_drive *d, int flag)
|
||||
{
|
||||
struct command c;
|
||||
int ret;
|
||||
@ -87,17 +98,37 @@ int sbc_start_unit(struct burn_drive *d)
|
||||
|
||||
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||
c.retry = 1;
|
||||
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||
c.opcode[1] |= (flag & 1); /* ts A70918 : Immed */
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
if (c.error)
|
||||
return 0;
|
||||
/* ts A70918 : now asynchronous */
|
||||
d->is_stopped = 0;
|
||||
if (!(flag & 1))
|
||||
return 1;
|
||||
/* ts A70918 : asynchronous */
|
||||
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int sbc_start_unit(struct burn_drive *d)
|
||||
{
|
||||
int ret;
|
||||
|
||||
d->is_stopped = 0; /* no endless starting attempts */
|
||||
|
||||
/* Asynchronous, not to block controller by waiting */
|
||||
ret = sbc_start_unit_flag(d, 1);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
/* Synchronous to catch Pioneer DVR-216D which is ready too early.
|
||||
A pending START UNIT can prevent ejecting of the tray.
|
||||
*/
|
||||
ret = sbc_start_unit_flag(d, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A90824 : Trying to reduce drive noise */
|
||||
int sbc_stop_unit(struct burn_drive *d)
|
||||
{
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
#include "ecma130ab.h"
|
||||
|
||||
|
||||
#ifdef Libburn_log_in_and_out_streaM
|
||||
/* <<< ts A61031 */
|
||||
@ -734,6 +736,57 @@ int sector_headers_is_ok(struct burn_write_opts *o, int mode)
|
||||
int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||
int mode, int leadin)
|
||||
{
|
||||
|
||||
#ifdef Libburn_ecma130ab_includeD
|
||||
|
||||
struct burn_drive *d = o->drive;
|
||||
unsigned int crc;
|
||||
int min, sec, frame;
|
||||
int modebyte = -1;
|
||||
int ret;
|
||||
|
||||
ret = sector_headers_is_ok(o, mode);
|
||||
if (ret != 2)
|
||||
return !!ret;
|
||||
modebyte = 1;
|
||||
|
||||
out[0] = 0;
|
||||
memset(out + 1, 0xFF, 10); /* sync */
|
||||
out[11] = 0;
|
||||
|
||||
if (leadin) {
|
||||
burn_lba_to_msf(d->rlba, &min, &sec, &frame);
|
||||
out[12] = dec_to_bcd(min) + 0xA0;
|
||||
out[13] = dec_to_bcd(sec);
|
||||
out[14] = dec_to_bcd(frame);
|
||||
out[15] = modebyte;
|
||||
} else {
|
||||
burn_lba_to_msf(d->alba, &min, &sec, &frame);
|
||||
out[12] = dec_to_bcd(min);
|
||||
out[13] = dec_to_bcd(sec);
|
||||
out[14] = dec_to_bcd(frame);
|
||||
out[15] = modebyte;
|
||||
}
|
||||
if (mode & BURN_MODE1) {
|
||||
crc = crc_32(out, 2064);
|
||||
out[2064] = crc & 0xFF;
|
||||
crc >>= 8;
|
||||
out[2065] = crc & 0xFF;
|
||||
crc >>= 8;
|
||||
out[2066] = crc & 0xFF;
|
||||
crc >>= 8;
|
||||
out[2067] = crc & 0xFF;
|
||||
}
|
||||
if (mode & BURN_MODE1) {
|
||||
memset(out + 2068, 0, 8);
|
||||
burn_rspc_parity_p(out);
|
||||
burn_rspc_parity_q(out);
|
||||
}
|
||||
burn_ecma130_scramble(out);
|
||||
return 1;
|
||||
|
||||
#else /* Libburn_ecma130ab_includeD */
|
||||
|
||||
int ret;
|
||||
|
||||
ret = sector_headers_is_ok(o, mode);
|
||||
@ -750,8 +803,52 @@ int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Raw CD write modes are not supported", 0, 0);
|
||||
return 0;
|
||||
|
||||
#endif /* ! Libburn_ecma130ab_includeD */
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void process_q(struct burn_drive *d, unsigned char *q)
|
||||
{
|
||||
unsigned char i[5];
|
||||
int mode;
|
||||
|
||||
mode = q[0] & 0xF;
|
||||
/* burn_print(12, "mode: %d : ", mode);*/
|
||||
switch (mode) {
|
||||
case 1:
|
||||
/* burn_print(12, "tno = %d : ", q[1]);
|
||||
burn_print(12, "index = %d\n", q[2]);
|
||||
*/
|
||||
/* q[1] is the track number (starting at 1) q[2] is the index
|
||||
number (starting at 0) */
|
||||
#warning this is totally bogus
|
||||
if (q[1] - 1 > 99)
|
||||
break;
|
||||
if (q[2] > d->toc->track[q[1] - 1].indices) {
|
||||
burn_print(12, "new index at %d\n", d->alba);
|
||||
d->toc->track[q[1] - 1].index[q[2]] = d->alba;
|
||||
d->toc->track[q[1] - 1].indices++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* XXX dont ignore these */
|
||||
break;
|
||||
case 3:
|
||||
/* burn_print(12, "ISRC data in mode 3 q\n");*/
|
||||
i[0] = isrc[(q[1] << 2) >> 2];
|
||||
/* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]);
|
||||
burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]);
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
|
||||
/* ts A61009 : if reactivated then witout Assert */
|
||||
a ssert(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* this needs more info. subs in the data? control/adr? */
|
||||
|
||||
@ -766,7 +863,7 @@ int sector_identify(unsigned char *data)
|
||||
{
|
||||
|
||||
/*
|
||||
scramble(data);
|
||||
burn_ecma130_scramble(data);
|
||||
check mode byte for 1 or 2
|
||||
test parity to see if it's a valid sector
|
||||
if invalid, return BURN_MODE_AUDIO;
|
||||
|
@ -19,6 +19,7 @@ Present implementation: default dummy which enables libburn only to work
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef Libburn_os_has_statvfS
|
||||
#include <sys/statvfs.h>
|
||||
@ -227,3 +228,39 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
|
||||
/* No special O_DIRECT-like precautions are implemented here */
|
||||
|
||||
#endif /* Libburn_read_o_direcT */
|
||||
|
||||
|
||||
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(path, open_flags);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||
{
|
||||
void *buf = NULL;
|
||||
|
||||
buf = calloc(1, amount);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -629,3 +629,39 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
|
||||
/* No special O_DIRECT-like precautions are implemented here */
|
||||
|
||||
#endif /* Libburn_read_o_direcT */
|
||||
|
||||
|
||||
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(path, open_flags);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||
{
|
||||
void *buf = NULL;
|
||||
|
||||
buf = calloc(1, amount);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,8 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
|
||||
|
||||
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||
warn("couldn't open %s", XPT_DEVICE);
|
||||
free(idx);
|
||||
idx = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -686,3 +688,39 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
|
||||
/* No special O_DIRECT-like precautions are implemented here */
|
||||
|
||||
#endif /* Libburn_read_o_direcT */
|
||||
|
||||
|
||||
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(path, open_flags);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||
{
|
||||
void *buf = NULL;
|
||||
|
||||
buf = calloc(1, amount);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
|
||||
/* <<< ts A91112 : experiments to get better speed with USB
|
||||
#define Libburn_sgio_as_growisofS 1
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
This is the main operating system dependent SCSI part of libburn. It implements
|
||||
@ -48,8 +54,23 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||
|
||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||
|
||||
|
||||
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||
|
||||
burn_os_open_track_src() opens a disk file in a way that allows best
|
||||
throughput with file reading and/or SCSI write command
|
||||
transmission.
|
||||
|
||||
burn_os_close_track_src() closes a filedescriptor obtained by
|
||||
burn_os_open_track_src().
|
||||
|
||||
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
||||
descriptors issued by burn_os_open_track_src().
|
||||
The buffer size may be rounded up for alignment
|
||||
reasons.
|
||||
|
||||
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
||||
|
||||
|
||||
Porting hints are marked by the text "PORTING:".
|
||||
Send feedback to libburn-hackers@pykix.org .
|
||||
@ -62,6 +83,13 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
||||
|
||||
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
# ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
# endif
|
||||
#endif /* Libburn_read_o_direcT */
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
@ -80,6 +108,9 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
||||
/* for ioctl(BLKGETSIZE) */
|
||||
#include <linux/fs.h>
|
||||
|
||||
/* for mmap() */
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
#include <scsi/sg.h>
|
||||
/* Values within sg_io_hdr_t indicating success after ioctl(SG_IO) : */
|
||||
@ -168,6 +199,7 @@ static int linux_ata_enumerate_verbous = 0;
|
||||
|
||||
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||
|
||||
#include "libburn.h"
|
||||
#include "transport.h"
|
||||
#include "drive.h"
|
||||
#include "sg.h"
|
||||
@ -196,17 +228,25 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||
|
||||
|
||||
/* ts A60813 : storage objects are in libburn/init.c
|
||||
wether to use O_EXCL with open(2) of devices
|
||||
wether to use fcntl(,F_SETLK,) after open(2) of devices
|
||||
whether to use O_EXCL with open(2) of devices
|
||||
whether to use fcntl(,F_SETLK,) after open(2) of devices
|
||||
what device family to use : 0=default, 1=sr, 2=scd, (3=st), 4=sg
|
||||
wether to use O_NOBLOCK with open(2) on devices
|
||||
wether to take O_EXCL rejection as fatal error */
|
||||
whether to use O_NOBLOCK with open(2) on devices
|
||||
whether to take O_EXCL rejection as fatal error
|
||||
*/
|
||||
extern int burn_sg_open_o_excl;
|
||||
extern int burn_sg_fcntl_f_setlk;
|
||||
extern int burn_sg_use_family;
|
||||
extern int burn_sg_open_o_nonblock;
|
||||
extern int burn_sg_open_abort_busy;
|
||||
|
||||
/* ts A91111 :
|
||||
whether to log SCSI commands:
|
||||
bit0= log in /tmp/libburn_sg_command_log
|
||||
bit1= log to stderr
|
||||
bit2= flush every line
|
||||
*/
|
||||
extern int burn_sg_log_scsi;
|
||||
|
||||
/* ts A60821
|
||||
debug: for tracing calls which might use open drive fds
|
||||
@ -1642,6 +1682,7 @@ int sg_release(struct burn_drive *d)
|
||||
}
|
||||
|
||||
|
||||
/* <<< ts A91111: on its way out */
|
||||
/** ts A70518:
|
||||
Debugging log facility. Controlled by existence of macros:
|
||||
Libburn_log_sg_commandS enables logging to file
|
||||
@ -1650,29 +1691,29 @@ int sg_release(struct burn_drive *d)
|
||||
Libburn_log_sg_command_stderR enables additional log to stderr
|
||||
*/
|
||||
/*
|
||||
ts A91111: now enabled by default and controlled burn_sg_log_scsi
|
||||
*/
|
||||
#define Libburn_log_sg_commandS 1
|
||||
#define Libburn_fflush_log_sg_commandS 1
|
||||
#define Libburn_log_sg_command_stderR 1
|
||||
*/
|
||||
|
||||
|
||||
#ifdef Libburn_log_sg_commandS
|
||||
|
||||
/** Logs command (before execution) */
|
||||
static int sg_log_cmd(struct command *c, FILE *fp, int flag)
|
||||
{
|
||||
int i;
|
||||
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||
scsi_show_cmd_text(c, fp, 0);
|
||||
|
||||
if (fp != NULL) {
|
||||
for(i = 0; i < 16 && i < c->oplen; i++)
|
||||
fprintf(fp,"%2.2x ", c->opcode[i]);
|
||||
fprintf(fp, "\n");
|
||||
#ifdef Libburn_fflush_log_sg_commandS
|
||||
fflush(fp);
|
||||
if (burn_sg_log_scsi & 4)
|
||||
fflush(fp);
|
||||
#endif
|
||||
}
|
||||
if (fp == stderr)
|
||||
return 1;
|
||||
#ifdef Libburn_log_sg_command_stderR
|
||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||
return 1;
|
||||
sg_log_cmd(c, stderr, flag);
|
||||
#endif
|
||||
return 1;
|
||||
@ -1684,20 +1725,23 @@ static int sg_log_err(struct command *c, FILE *fp,
|
||||
sg_io_hdr_t *s,
|
||||
int flag)
|
||||
{
|
||||
if(fp!=NULL) {
|
||||
if(flag & 1)
|
||||
if(fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
||||
if(flag & 1) {
|
||||
fprintf(fp,
|
||||
"+++ key=%X asc=%2.2Xh ascq=%2.2Xh (%6d ms)\n",
|
||||
s->sbp[2], s->sbp[12], s->sbp[13],s->duration);
|
||||
else
|
||||
} else {
|
||||
scsi_show_cmd_reply(c, fp, 0);
|
||||
fprintf(fp,"%6d ms\n", s->duration);
|
||||
}
|
||||
#ifdef Libburn_fflush_log_sg_commandS
|
||||
fflush(fp);
|
||||
if (burn_sg_log_scsi & 4)
|
||||
fflush(fp);
|
||||
#endif
|
||||
}
|
||||
if (fp == stderr)
|
||||
return 1;
|
||||
#ifdef Libburn_log_sg_command_stderR
|
||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||
return 1;
|
||||
sg_log_err(c, stderr, s, flag);
|
||||
#endif
|
||||
return 1;
|
||||
@ -1737,11 +1781,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||
|
||||
#ifdef Libburn_log_sg_commandS
|
||||
/* ts A61030 */
|
||||
if(fp==NULL) {
|
||||
fp= fopen("/tmp/libburn_sg_command_log","a");
|
||||
fprintf(fp,"\n-----------------------------------------\n");
|
||||
if (burn_sg_log_scsi & 1) {
|
||||
if (fp == NULL) {
|
||||
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||
fprintf(fp,
|
||||
"\n-----------------------------------------\n");
|
||||
}
|
||||
}
|
||||
sg_log_cmd(c,fp,0);
|
||||
if (burn_sg_log_scsi & 3)
|
||||
sg_log_cmd(c,fp,0);
|
||||
#endif /* Libburn_log_sg_commandS */
|
||||
|
||||
|
||||
@ -1756,6 +1804,13 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||
|
||||
s.interface_id = 'S';
|
||||
|
||||
#ifdef Libburn_sgio_as_growisofS
|
||||
/* ??? ts A91112 : does this speed up USB ? (from growisofs)
|
||||
--- did not help
|
||||
*/
|
||||
s.flags = SG_FLAG_DIRECT_IO;
|
||||
#endif /* Libburn_sgio_as_growisofS */
|
||||
|
||||
if (c->dir == TO_DRIVE)
|
||||
s.dxfer_direction = SG_DXFER_TO_DEV;
|
||||
else if (c->dir == FROM_DRIVE)
|
||||
@ -1878,7 +1933,8 @@ ex:;
|
||||
}
|
||||
|
||||
#ifdef Libburn_log_sg_commandS
|
||||
sg_log_err(c, fp, &s, c->error != 0);
|
||||
if (burn_sg_log_scsi & 3)
|
||||
sg_log_err(c, fp, &s, c->error != 0);
|
||||
#endif /* Libburn_log_sg_commandS */
|
||||
|
||||
return 1;
|
||||
@ -2033,3 +2089,80 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
||||
|
||||
#ifdef PROT_READ
|
||||
#ifdef PROT_WRITE
|
||||
#ifdef MAP_SHARED
|
||||
#ifdef MAP_ANONYMOUS
|
||||
#ifdef MAP_FAILED
|
||||
#define Libburn_linux_do_mmaP 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
#ifdef O_DIRECT
|
||||
#define Libburn_linux_do_o_direcT 1
|
||||
#endif
|
||||
#endif /* Libburn_read_o_direcT */
|
||||
|
||||
|
||||
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#ifdef Libburn_linux_do_o_direcT
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Opening track source with O_DIRECT" , 0, 0);
|
||||
fd = open(path, open_flags | O_DIRECT);
|
||||
#else
|
||||
fd = open(path, open_flags);
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void *burn_os_alloc_buffer(size_t amount, int flag)
|
||||
{
|
||||
void *buf = NULL;
|
||||
|
||||
#ifdef Libburn_linux_do_mmaP
|
||||
|
||||
/* >>> check whether size is suitable */;
|
||||
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Allocating buffer via mmap()" , 0, 0);
|
||||
buf = mmap(NULL, amount, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
|
||||
if (buf == MAP_FAILED)
|
||||
buf = NULL;
|
||||
else
|
||||
memset(buf, 0, amount);
|
||||
#else
|
||||
buf = calloc(1, amount);
|
||||
#endif /* ! Libburn_linux_do_mmaP */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
#ifdef Libburn_linux_do_mmaP
|
||||
ret = munmap(buffer, amount);
|
||||
#else
|
||||
free(buffer);
|
||||
#endif
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
|
172
libburn/spc.c
172
libburn/spc.c
@ -27,11 +27,6 @@
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
/* ts A70910
|
||||
debug: for tracing calls which might use open drive fds
|
||||
or for catching SCSI usage of emulated drives. */
|
||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||
|
||||
|
||||
/* spc command set */
|
||||
/* ts A70519 : allocation length byte 3+4 was 0,255 */
|
||||
@ -98,7 +93,9 @@ int spc_test_unit_ready(struct burn_drive *d)
|
||||
|
||||
|
||||
/* ts A70315 */
|
||||
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready */
|
||||
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready
|
||||
bit1=do not issue success message
|
||||
*/
|
||||
/** Wait until the drive state becomes clear or until max_usec elapsed */
|
||||
int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
int flag)
|
||||
@ -112,13 +109,6 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
usleep(100000);
|
||||
for(i = !(flag & 1); i < max_sec * 10; i++) {
|
||||
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
|
||||
|
||||
/* <<<
|
||||
fprintf(stderr,
|
||||
"libburn_EXPERIMENTAL: i= %d ret= %d key= %X asc= %2.2X ascq= %2.2X\n",
|
||||
i, ret, (unsigned) key, (unsigned) asc, (unsigned) ascq);
|
||||
*/
|
||||
|
||||
if (ret > 0) /* ready */
|
||||
break;
|
||||
if (key!=0x2 || asc!=0x4) {
|
||||
@ -140,24 +130,14 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
/* media change notice = try again */
|
||||
goto slumber;
|
||||
|
||||
#ifdef NIX
|
||||
sprintf(msg,
|
||||
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||
cmd_text, (unsigned) key, (unsigned) asc,
|
||||
(unsigned) ascq);
|
||||
#else
|
||||
|
||||
/* ts A90213 */
|
||||
sprintf(msg,
|
||||
"Asynchromous SCSI error on %s: ", cmd_text);
|
||||
"Asynchronous SCSI error on %s: ", cmd_text);
|
||||
sense[2] = key;
|
||||
sense[12] = asc;
|
||||
sense[13] = ascq;
|
||||
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg),
|
||||
&key, &asc, &ascq);
|
||||
|
||||
#endif /* ! NIX */
|
||||
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002014d,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
@ -168,11 +148,14 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
||||
slumber:;
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
sprintf(msg, "Async %s %s after %d.%d seconds",
|
||||
cmd_text, (ret > 0 ? "succeeded" : "failed"), i / 10, i % 10);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020150,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
||||
if (ret <= 0 || !(flag & 2)) {
|
||||
sprintf(msg, "Async %s %s after %d.%d seconds",
|
||||
cmd_text, (ret > 0 ? "succeeded" : "failed"),
|
||||
i / 10, i % 10);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020150, LIBDAX_MSGS_SEV_DEBUG,
|
||||
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
||||
}
|
||||
|
||||
if (i < max_sec * 10)
|
||||
return (ret > 0);
|
||||
@ -262,14 +245,14 @@ void spc_prevent(struct burn_drive *d)
|
||||
return;
|
||||
|
||||
scsi_init_command(&c, SPC_PREVENT, sizeof(SPC_PREVENT));
|
||||
/*
|
||||
memcpy(c.opcode, SPC_PREVENT, sizeof(SPC_PREVENT));
|
||||
c.oplen = sizeof(SPC_PREVENT);
|
||||
c.page = NULL;
|
||||
*/
|
||||
c.retry = 1;
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_get_evenT
|
||||
mmc_get_event(d);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void spc_allow(struct burn_drive *d)
|
||||
@ -489,6 +472,7 @@ void spc_sense_caps(struct burn_drive *d)
|
||||
{
|
||||
int alloc_len, start_len = 30, ret;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "sense_caps") <= 0)
|
||||
return;
|
||||
|
||||
@ -513,6 +497,7 @@ void spc_sense_error_params(struct burn_drive *d)
|
||||
unsigned char *page;
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "sense_error_params") <= 0)
|
||||
return;
|
||||
|
||||
@ -546,6 +531,7 @@ void spc_select_error_params(struct burn_drive *d,
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "select_error_params") <= 0)
|
||||
return;
|
||||
|
||||
@ -587,6 +573,7 @@ void spc_sense_write_params(struct burn_drive *d)
|
||||
unsigned char *page;
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "sense_write_params") <= 0)
|
||||
return;
|
||||
|
||||
@ -650,7 +637,9 @@ void spc_select_write_params(struct burn_drive *d,
|
||||
{
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
int alloc_len;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "select_write_params") <= 0)
|
||||
return;
|
||||
|
||||
@ -664,13 +653,33 @@ void spc_select_write_params(struct burn_drive *d,
|
||||
o->block_type,spc_block_type(o->block_type));
|
||||
*/
|
||||
|
||||
scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||
/*
|
||||
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||
*/
|
||||
alloc_len = 8 + 2 + d->mdata->write_page_length;
|
||||
memset(&(buf.data), 0, alloc_len);
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_load_mode5
|
||||
|
||||
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||
c.dxfer_len = alloc_len;
|
||||
c.opcode[7] = (alloc_len >> 8) & 0xff;
|
||||
c.opcode[8] = alloc_len & 0xff;
|
||||
c.retry = 1;
|
||||
c.opcode[8] = 8 + 2 + d->mdata->write_page_length;
|
||||
c.opcode[2] = 0x05;
|
||||
c.page = &buf;
|
||||
c.page->bytes = 0;
|
||||
c.page->sectors = 0;
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
|
||||
if (c.error)
|
||||
memset(&(buf.data), 0,
|
||||
8 + 2 + d->mdata->write_page_length);
|
||||
|
||||
#endif /* Libburn_pioneer_dvr_216d_load_mode5 */
|
||||
|
||||
scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||
c.retry = 1;
|
||||
c.opcode[7] = (alloc_len >> 8) & 0xff;
|
||||
c.opcode[8] = alloc_len & 0xff;
|
||||
c.page = &buf;
|
||||
c.page->bytes = 0;
|
||||
c.page->sectors = 0;
|
||||
@ -678,8 +687,7 @@ void spc_select_write_params(struct burn_drive *d,
|
||||
/* ts A61007 : moved up to burn_disc_write() */
|
||||
/* a ssert(d->mdata->valid); */
|
||||
|
||||
memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length);
|
||||
c.page->bytes = 8 + 2 + d->mdata->write_page_length;
|
||||
c.page->bytes = alloc_len;
|
||||
|
||||
burn_print(12, "using write page length %d (valid %d)\n",
|
||||
d->mdata->write_page_length, d->mdata->write_page_valid);
|
||||
@ -716,6 +724,7 @@ void spc_probe_write_modes(struct burn_drive *d)
|
||||
int last_try = 0;
|
||||
struct command c;
|
||||
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
|
||||
return;
|
||||
|
||||
@ -733,11 +742,8 @@ void spc_probe_write_modes(struct burn_drive *d)
|
||||
try_block_type = useable_block_type;
|
||||
last_try= 1;
|
||||
}
|
||||
|
||||
scsi_init_command(&c, SPC_MODE_SELECT,sizeof(SPC_MODE_SELECT));
|
||||
/*
|
||||
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||
*/
|
||||
c.retry = 1;
|
||||
c.opcode[8] = 8 + 2 + 0x32;
|
||||
c.page = &buf;
|
||||
@ -766,7 +772,6 @@ void spc_probe_write_modes(struct burn_drive *d)
|
||||
key = c.sense[2];
|
||||
asc = c.sense[12];
|
||||
ascq = c.sense[13];
|
||||
|
||||
if (key)
|
||||
burn_print(7, "%d not supported\n", try_block_type);
|
||||
else {
|
||||
@ -812,6 +817,7 @@ void spc_probe_write_modes(struct burn_drive *d)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
|
||||
@ -1142,6 +1148,11 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
||||
sprintf(msg, "Medium not present");
|
||||
d->status = BURN_DISC_EMPTY;
|
||||
return FAIL;
|
||||
case 0x57:
|
||||
if (*key != 3 || *ascq != 0)
|
||||
break;
|
||||
sprintf(msg, "Unable to recover Table-of-Content");
|
||||
return FAIL;
|
||||
case 0x63:
|
||||
if (*key != 5)
|
||||
break;
|
||||
@ -1229,6 +1240,8 @@ static char *scsi_command_name(unsigned int c, int flag)
|
||||
return "FORMAT UNIT";
|
||||
case 0x1b:
|
||||
return "START/STOP UNIT";
|
||||
case 0x12:
|
||||
return "INQUIRY";
|
||||
case 0x1e:
|
||||
return "PREVENT/ALLOW MEDIA REMOVAL";
|
||||
case 0x23:
|
||||
@ -1258,7 +1271,7 @@ static char *scsi_command_name(unsigned int c, int flag)
|
||||
case 0x55:
|
||||
return "MODE SELECT";
|
||||
case 0x5a:
|
||||
return "SEND OPC INFORMATION";
|
||||
return "MODE SENSE";
|
||||
case 0x5b:
|
||||
return "CLOSE TRACK/SESSION";
|
||||
case 0x5c:
|
||||
@ -1336,3 +1349,66 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91106 */
|
||||
/* @param flag bit0= do not show eventual data payload sent to the drive
|
||||
(never with WRITE commands)
|
||||
bit1= show write length and target LBA in decimal
|
||||
*/
|
||||
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
|
||||
{
|
||||
int i;
|
||||
FILE *fp = fp_in;
|
||||
|
||||
fprintf(fp, "\n%s\n",
|
||||
scsi_command_name((unsigned int) c->opcode[0], 0));
|
||||
for(i = 0; i < 16 && i < c->oplen; i++)
|
||||
fprintf(fp, "%2.2x ", c->opcode[i]);
|
||||
if (i > 0)
|
||||
fprintf(fp, "\n");
|
||||
if (flag & 1)
|
||||
return 1;
|
||||
if (c->opcode[0] == 0x2A) { /* WRITE 10 */
|
||||
if (flag & 2)
|
||||
fprintf(fp, "%d -> %d\n",
|
||||
(c->opcode[7] << 8) | c->opcode[8],
|
||||
mmc_four_char_to_int(c->opcode + 2));
|
||||
} else if (c->opcode[0] == 0xAA) { /* WRITE 12 */
|
||||
if (flag & 2)
|
||||
fprintf(fp, "%d -> %d\n",
|
||||
mmc_four_char_to_int(c->opcode + 6),
|
||||
mmc_four_char_to_int(c->opcode + 2));
|
||||
} else if (c->dir == TO_DRIVE) {
|
||||
fprintf(fp, "To drive: %db\n", c->page->bytes);
|
||||
for (i = 0; i < c->page->bytes; i++)
|
||||
fprintf(fp, "%2.2x%c", c->page->data[i],
|
||||
((i % 20) == 19 ? '\n' : ' '));
|
||||
if (i % 20)
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ts A91106 */
|
||||
int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
|
||||
{
|
||||
int i;
|
||||
FILE *fp = fp_in;
|
||||
|
||||
if (c->dir != FROM_DRIVE)
|
||||
return 2;
|
||||
if (c->opcode[0] == 0x28 || c->opcode[0] == 0x3C ||
|
||||
c->opcode[0] == 0xA8 || c->opcode[0] == 0xBE) {
|
||||
/* READ commands */
|
||||
/* >>> report amount of data */;
|
||||
|
||||
return 2;
|
||||
}
|
||||
fprintf(fp, "From drive: %db\n", c->dxfer_len);
|
||||
for (i = 0; i < c->dxfer_len; i++)
|
||||
fprintf(fp, "%2.2x%c", c->page->data[i],
|
||||
((i % 20) == 19 ? '\n' : ' '));
|
||||
if (i % 20)
|
||||
fprintf(fp, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -59,4 +59,11 @@ int scsi_notify_error(struct burn_drive *, struct command *c,
|
||||
/* ts A70519 */
|
||||
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
||||
|
||||
/* ts A91106 */
|
||||
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
||||
|
||||
/* ts A91106 */
|
||||
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
|
||||
|
||||
|
||||
#endif /*__SPC*/
|
||||
|
@ -220,6 +220,7 @@ struct burn_drive
|
||||
/* ts A61218 from 51h READ DISC INFORMATION */
|
||||
int last_lead_in;
|
||||
int last_lead_out;
|
||||
int num_opc_tables; /* ts A91104: -1= not yet known */
|
||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||
int disc_type; /* 0="CD-DA or CD-ROM", 0x10="CD-I", 0x20="CD-ROM XA" */
|
||||
unsigned int disc_id; /* a "32 bit binary integer" */
|
||||
|
236
libburn/write.c
236
libburn/write.c
@ -43,11 +43,19 @@
|
||||
#include "options.h"
|
||||
#include "structure.h"
|
||||
#include "source.h"
|
||||
#include "mmc.h"
|
||||
#include "spc.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
|
||||
/* ts A91120 : <<< experimental */
|
||||
#ifdef Libburn_mmap_write_buffeR
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* The maximum output size to be used with CD media. This is also curbed
|
||||
by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
|
||||
*/
|
||||
@ -882,9 +890,14 @@ ex:;
|
||||
next track. cdrecord does not use CLOSE TRACK at all but
|
||||
ends the tracks by SYNCHRONIZE CACHE alone.
|
||||
*/
|
||||
if (!o->simulate)
|
||||
if (burn_write_close_track(o, s, tnum) <= 0)
|
||||
ret = 0;
|
||||
/* ts A91202 :
|
||||
Peng Shao reports that his LG GH22LS30 issues an SCSI error
|
||||
on CLOSE TRACK even in non-dummy mode. So i better give up
|
||||
this gesture which seems not be needed by any drive.
|
||||
if (!o->simulate)
|
||||
if (burn_write_close_track(o, s, tnum) <= 0)
|
||||
ret = 0;
|
||||
*/
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1080,11 +1093,25 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
||||
/* ts A70214 : eventually adjust already expanded size of track */
|
||||
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_with_opC
|
||||
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : num_opc_tables = %d\n", d->num_opc_tables);
|
||||
if (d->num_opc_tables <= 0 && !o->simulate) {
|
||||
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : performing OPC\n");
|
||||
d->perform_opc(d);
|
||||
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : done\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Libburn_pioneer_dvr_216d_get_evenT
|
||||
mmc_get_event(d);
|
||||
#endif
|
||||
|
||||
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
|
||||
/* Round track size up to 32 KiB and reserve track */
|
||||
/* Round track size up to write chunk size and reserve track */
|
||||
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
||||
* (off_t) 2048;
|
||||
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
||||
* (off_t) 2048;
|
||||
if (size % o->obs)
|
||||
size += (off_t) (o->obs - (size % o->obs));
|
||||
ret = d->reserve_track(d, size);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg, "Cannot reserve track of %.f bytes",
|
||||
@ -1122,14 +1149,11 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
||||
|
||||
if (o->write_type == BURN_WRITE_SAO &&
|
||||
! burn_track_is_open_ended(s->track[tnum])) {
|
||||
/* Round track size up to 32 KiB and reserve track */
|
||||
|
||||
/* ts A81208 */
|
||||
/* >>> ??? round to 64 KiB for BD-R ? (It is not mandatory) */
|
||||
|
||||
/* Round track size up to write chunk size and reserve track */
|
||||
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
||||
* (off_t) 2048;
|
||||
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
||||
* (off_t) 2048;
|
||||
if (size % o->obs)
|
||||
size += (off_t) (o->obs - (size % o->obs));
|
||||
ret = d->reserve_track(d, size);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg, "Cannot reserve track of %.f bytes",
|
||||
@ -1231,6 +1255,132 @@ 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.
|
||||
Actually mmap() seems to be the main cause for a positive effect
|
||||
of O_DIRECT.
|
||||
|
||||
This simplified transmission function did not bring visible benefit.
|
||||
So for now it is not worth to teach it all applicable details of old
|
||||
CD sector oriented transmission.
|
||||
|
||||
@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 */
|
||||
int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
struct burn_session *s, int tnum, int is_last_track)
|
||||
@ -1240,6 +1390,7 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
struct buffer *out = d->buffer;
|
||||
int sectors;
|
||||
int i, open_ended = 0, ret= 0, is_flushed = 0;
|
||||
int first_buf_cap = 0, further_cap = 0, buf_cap_step = 1024;
|
||||
|
||||
/* ts A70213 : eventually expand size of track to max */
|
||||
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
|
||||
@ -1250,6 +1401,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
/* Pioneer DVR-216D rev 1.09 hates multiple buffer inquiries
|
||||
before the drive buffer is full.
|
||||
*/
|
||||
first_buf_cap = 0;
|
||||
further_cap = -1;
|
||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||
/* DVD+R , DVD+R/DL */
|
||||
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
||||
@ -1285,12 +1441,30 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
for (i = 0; open_ended || i < sectors; i++) {
|
||||
|
||||
/* From time to time inquire drive buffer */
|
||||
if ((i%256)==0)
|
||||
/* ts A91110: Eventually avoid to do this more than once
|
||||
before the drive buffer is full. See above DVD-
|
||||
*/
|
||||
if (i == first_buf_cap ||
|
||||
((i % buf_cap_step) == 0 &&
|
||||
(i >= further_cap || further_cap < 0))) {
|
||||
d->read_buffer_capacity(d);
|
||||
if (further_cap < 0)
|
||||
further_cap =
|
||||
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 */
|
||||
if (!sector_data(o, t, 0))
|
||||
{ ret = 0; goto ex; }
|
||||
#endif
|
||||
|
||||
if (open_ended) {
|
||||
d->progress.sectors = sectors = i;
|
||||
@ -1751,13 +1925,29 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
||||
}
|
||||
|
||||
#ifdef Libburn_dvd_obs_default_64K
|
||||
o->obs = 64 * 1024;
|
||||
#endif
|
||||
|
||||
/* <<< test only : Does this increase effective speed with USB ?
|
||||
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
|
||||
>>> next try is 128 kB
|
||||
o->obs = 128 * 1024;
|
||||
128kB: glibc complains about double free
|
||||
With BURN_OS_TRANSPORT_BUFFER_SIZE
|
||||
enlarged to 128 MB, the first WRITE fails
|
||||
with an i/o error.
|
||||
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 = 32 * 1024; /* This size is required to work */
|
||||
}
|
||||
|
||||
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
||||
d->current_profile, o->obs, o->obs_pad);
|
||||
@ -2045,8 +2235,9 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
break;
|
||||
}
|
||||
d->progress.sector++;
|
||||
/* Flush to disk after each full MB */
|
||||
if (d->progress.sector - prev_sync_sector >= 512) {
|
||||
/* Flush to disk from time to time */
|
||||
if (d->progress.sector - prev_sync_sector >=
|
||||
o->stdio_fsync_size && o->stdio_fsync_size > 0) {
|
||||
prev_sync_sector = d->progress.sector;
|
||||
if (!o->simulate)
|
||||
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
||||
@ -2129,6 +2320,7 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
off_t default_size;
|
||||
char msg[80];
|
||||
|
||||
|
||||
/* ts A60924 : libburn/message.c gets obsoleted
|
||||
burn_message_clear_queue();
|
||||
*/
|
||||
@ -2143,11 +2335,12 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
||||
else
|
||||
d->stream_recording_start = 0;
|
||||
|
||||
d->buffer = calloc(sizeof(struct buffer), 1);
|
||||
/* ts A91122 : Get buffer suitable for sources made by
|
||||
burn_os_open_track_src() */
|
||||
d->buffer = burn_os_alloc_buffer(sizeof(struct buffer), 0);
|
||||
if (d->buffer == NULL)
|
||||
goto fail_wo_sync;
|
||||
|
||||
|
||||
/* >>> ts A90321
|
||||
|
||||
memset(d->buffer, 0, sizeof(struct buffer));
|
||||
@ -2368,7 +2561,8 @@ fail_wo_sync:;
|
||||
ex:;
|
||||
d->do_stream_recording = 0;
|
||||
if (d->buffer != NULL)
|
||||
free((char *) d->buffer);
|
||||
burn_os_free_buffer((char *) d->buffer,
|
||||
sizeof(struct buffer), 0);
|
||||
d->buffer = buffer_mem;
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user