Compare commits

..

4 Commits

35 changed files with 797 additions and 2683 deletions

View File

@ -101,9 +101,9 @@ test_structest_CPPFLAGS = -Ilibburn
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - A70312
## cdrskin construction site - ts A60816 - A70210
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_3_4
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_3_2
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
##

5
README
View File

@ -192,10 +192,7 @@ Project history as far as known to me:
- 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with
multi-session and with DAO.
- 12th March 2007 version 0.3.4 supports DVD+R and thus covers all single layer
DVD media. Code for double layer DVD+/-R is implemented but awaits a tester
yet.
This means all single layer DVD media except DVD+R are supported now.
------------------------------------------------------------------------------

View File

@ -26,12 +26,12 @@ following possible.
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
Integrated sub project of libburnia.pykix.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-0.3.4.pl00.tar.gz
http://scdbackup.sourceforge.net/cdrskin-0.3.2.pl00.tar.gz
Copyright (C) 2006-2007 Thomas Schmitt
------------------------------------------------------------------------------
On top of libburn there is implemented cdrskin 0.3.4, a limited cdrecord
On top of libburn there is implemented cdrskin 0.3.2, a limited cdrecord
compatibility wrapper which allows to use some libburn features from
the command line.
Interested users of cdrecord are invited to participate in the development
@ -59,16 +59,16 @@ systems, including 64 bit systems. (Further reports are welcome.)
Compilation, First Glimpse, Installation
Obtain cdrskin-0.3.4.pl00.tar.gz, take it to a directory of your choice and do:
Obtain cdrskin-0.3.2.pl00.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-0.3.4.pl00.tar.gz
cd cdrskin-0.3.4
tar xzf cdrskin-0.3.2.pl00.tar.gz
cd cdrskin-0.3.2
Or obtain a libburnia.pykix.org SVN snapshot,
go into the toplevel directory of the snapshot (e.g. cd libburn_pykix ),
and execute the autotools script ./bootstrap . Use autools version >= 1.7 .
Within that toplevel directory of either cdrskin-0.3.4 or libburn then execute:
Within that toplevel directory of either cdrskin-0.3.2 or libburn then execute:
./configure
make
@ -174,13 +174,13 @@ Burn image file my_image.iso to media
cdrskin -v dev=0,1,0 speed=12 fs=8m driveropts=burnfree padsize=300k \
-eject my_image.iso
Write multi-session to the same CD , DVD-R[W] or DVD+R
Write several sessions to the same CD or DVD-R[W]
cdrskin dev=/dev/hdc padsize=300k -multi 1.iso
cdrskin dev=/dev/hdc padsize=300k -multi -tao 2.iso
cdrskin dev=/dev/hdc padsize=300k -multi -tao 3.iso
cdrskin dev=/dev/hdc padsize=300k -tao 4.iso
Get multi-session info for option -C of program mkisofs:
Get CD or DVD-R[W] multi-session info for option -C of program mkisofs:
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
mkisofs ... -C "$c_values" ...
@ -223,11 +223,13 @@ Run a backup :
Restrictions
Many cdrecord options are still unsupported.
The major restrictions are lifted now: audio, TAO, multi-session do work.
Many cdrecord options are still unsupported, though.
If you have use cases for them, please report your wishes and expectations.
DVD support is restricted to single layer DVD for now. Double layer media
are implemented but untested.
DVD support is restricted to single layer overwriteable DVD (-RAM, +RW, -RW)
for now.
@ -242,6 +244,9 @@ Do not bother Joerg Schilling with any cdrskin problems.
cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes
have been copied from the message output of cdrecord runs, though. I am
thankful to Joerg Schilling for every single one of them.
Actually i, Thomas Schmitt, am a devoted user of cdrecord via my project
scdbackup which still runs a bit better with cdrecord than with cdrskin. TAO.
I have the hope that Joerg feels more flattered than annoyed by cdrskin.
Many thanks to Andy Polyakov for his dvd+rw-tools
@ -470,13 +475,6 @@ Incremental Streaming afterwards. So blank=fast will do full blanking.
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
DVD+R
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
into an own session, though.
------------------------------------------------------------------------------
Special compilation variations
You may get a (super fat) statically linked binary by :

View File

@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="0.3.4"
skin_release="0.3.2"
patch_level=".pl00"
skin_rev="$skin_release""$patch_level"
@ -201,11 +201,11 @@ tar czf "$cdrskin_tarball" "$target"
cd "$compile_dir" || exit 1
./configure
make
"$compile_cmd" -O2 -do_strip
"$compile_cmd" -do_strip
cp "$compile_result" "../$bintarget_dynamic"
if test -n "$compile_static_opts"
then
"$compile_cmd" $compile_static_opts -O2 -do_strip
"$compile_cmd" $compile_static_opts -do_strip
cp "$compile_result" "../$bintarget_static"
fi
"$man_to_html_cmd"

View File

@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="0.3.5"
skin_release="0.3.3"
patch_level=""
skin_rev="$skin_release""$patch_level"
@ -201,11 +201,11 @@ tar czf "$cdrskin_tarball" "$target"
cd "$compile_dir" || exit 1
./configure
make
"$compile_cmd" -O2 -do_strip
"$compile_cmd" -do_strip
cp "$compile_result" "../$bintarget_dynamic"
if test -n "$compile_static_opts"
then
"$compile_cmd" $compile_static_opts -O2 -do_strip
"$compile_cmd" $compile_static_opts -do_strip
cp "$compile_result" "../$bintarget_static"
fi
"$man_to_html_cmd"

View File

@ -38,9 +38,7 @@
#define Cdrfifo_ffd_maX 100
/* 1= enable , 0= disable status messages to stderr
2= report each
*/
/* 1= enable , 0= disable status messages to stderr */
static int Cdrfifo_debuG= 0;
@ -84,8 +82,6 @@ struct CdrfifO {
/* index of first byte in buffer which does not belong to predecessor fd */
int follow_up_eop[Cdrfifo_ffd_maX];
/* if follow_up_eop[i]==buffer_size : read_idx was 0 when this was set */
int follow_up_was_full_buffer[Cdrfifo_ffd_maX];
/* index of first byte in buffer which belongs to [this] fd pair */
int follow_up_sod[Cdrfifo_ffd_maX];
@ -103,9 +99,6 @@ struct CdrfifO {
/* (simultaneous) peer chaining */
struct CdrfifO *next;
struct CdrfifO *prev;
/* rank in peer chain */
int chain_idx;
};
@ -162,13 +155,11 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
for(i= 0; i<Cdrfifo_ffd_maX; i++) {
o->follow_up_fds[i][0]= o->follow_up_fds[i][1]= -1;
o->follow_up_eop[i]= o->follow_up_sod[i]= -1;
o->follow_up_was_full_buffer[i]= 0;
o->follow_up_in_limits[i]= -1.0;
}
o->follow_up_fd_counter= 0;
o->follow_up_fd_idx= -1;
o->next= o->prev= NULL;
o->chain_idx= 0;
o->buffer= TSOB_FELD(char,buffer_size);
if(o->buffer==NULL)
goto failed;
@ -308,16 +299,10 @@ int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd,
*/
int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag)
{
int idx;
struct CdrfifO *s;
for(s= o;s->prev!=NULL;s= s->prev); /* determine start of o-chain */
for(;o->next!=NULL;o= o->next); /* determine end of o-chain */
for(;next->prev!=NULL;next= next->prev); /* determine start of next-chain */
next->prev= o;
o->next= next;
for(idx= 0;s!=NULL;s= s->next)
s->chain_idx= idx++;
return(1);
}
@ -423,26 +408,10 @@ int Cdrfifo_eop_adjust(struct CdrfifO *o,int *buffer_fill, int *eop_idx,
for(i=0; i<=o->follow_up_fd_idx; i++) {
if(o->follow_up_eop[i]>=0 && o->follow_up_eop[i]>=o->read_idx) {
eop_is_near= 1;
if(o->follow_up_eop[i]<o->buffer_size || o->read_idx>0) {
valid_fill= o->follow_up_eop[i]-o->read_idx;
o->follow_up_was_full_buffer[i]= 0;
} else {
/*
If an input fd change hit exactly the buffer end then follow_up_eop
points to buffer_size and not to 0. So it is time to switch output
pipes unless this is immediately after follow_up_eop was set and
read_idx was 0 (... if this is possible at all while write_idx is 0).
follow_up_was_full_buffer was set in this case and gets invalid as
soon as a non-0 read_idx is detected (see above).
*/
if(o->follow_up_was_full_buffer[i])
valid_fill= o->buffer_size;
else
valid_fill= 0; /* the current pipe is completely served */
}
valid_fill= o->follow_up_eop[i]-o->read_idx;
if(valid_fill==0)
*eop_idx= i;
else if(valid_fill<o->chunk_size)
else if(valid_fill<=o->chunk_size)
eop_is_near= 2; /* for debugging. to carry a break point */
break;
}
@ -467,7 +436,7 @@ static int Cdrfifo_setup_try(struct CdrfifO *o, struct timeval start_tv,
*/
{
int buffer_space,buffer_fill,eop_reached= -1,eop_is_near= 0,was_closed;
int fd_buffer_fill, eop_reached_counter= 0;
int fd_buffer_fill;
struct timeval current_tv;
struct timezone tz;
double diff_time,diff_counter,limit,min_wait_time;
@ -496,26 +465,21 @@ setup_try:;
if(eop_reached>=0) { /* switch to next output fd */
o->dest_fd= o->follow_up_fds[eop_reached][1];
if(Cdrfifo_debuG)
fprintf(stderr,"\ncdrfifo %d: new fifo destination fd : %d\n",
o->chain_idx,o->dest_fd);
o->read_idx= o->follow_up_sod[eop_reached];
o->follow_up_eop[eop_reached]= -1;
eop_is_near= 0;
eop_reached= -1;
eop_reached_counter= 0;
goto setup_try;
} else {
/* work is really done */
if((!was_closed) && ((flag&1)||Cdrfifo_debuG))
fprintf(stderr,
"\ncdrfifo %d: w=%d r=%d | b=%d s=%d | i=%.f o=%.f (done)\n",
o->chain_idx,o->write_idx,o->read_idx,buffer_fill,buffer_space,
"\ncdrfifo_debug: w=%d r=%d | b=%d s=%d | i=%.f o=%.f (done)\n",
o->write_idx,o->read_idx,buffer_fill,buffer_space,
o->in_counter,o->out_counter);
return(2);
}
} else if(eop_reached>=0)
eop_reached_counter++;
}
if(o->interval_counter>0) {
if(o->total_min_fill>buffer_fill && o->source_fd>=0)
o->total_min_fill= buffer_fill;
@ -617,8 +581,7 @@ return: <0 = error , 0 = idle , 1 = did some work
if(ret==-1) {
/* >>> handle broken pipe */;
fprintf(stderr,"\ncdrfifo %d: on write: errno=%d , \"%s\"\n",
o->chain_idx,errno,
fprintf(stderr,"\ncdrfifo: on write: errno=%d , \"%s\"\n",errno,
errno==0?"-no error code available-":strerror(errno));
if(!(flag&4))
@ -650,31 +613,22 @@ after_write:;
if(ret==-1) {
/* >>> handle input error */;
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
o->chain_idx,errno,
fprintf(stderr,"\ncdrfifo: on read: errno=%d , \"%s\"\n",errno,
errno==0?"-no error code available-":strerror(errno));
o->source_fd= -1;
} else if(ret==0) { /* eof */
/* activate eventual follow-up source fd */
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
o->chain_idx,o->source_fd,can_read);
fprintf(stderr,"\ncdrfifo: on read(%d,buffer,%d): eof\n",
o->source_fd,can_read);
if(o->follow_up_fd_idx+1 < o->follow_up_fd_counter) {
idx= ++(o->follow_up_fd_idx);
o->source_fd= o->follow_up_fds[idx][0];
/* End-Of-Previous */
if(o->write_idx==0) {
if(o->write_idx==0)
o->follow_up_eop[idx]= o->buffer_size;
/* A70304 : can this happen ? */
o->follow_up_was_full_buffer[idx]= (o->read_idx==0);
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: write_idx 0 on eop: read_idx= %d\n",
o->chain_idx,o->read_idx);
} else
else
o->follow_up_eop[idx]= o->write_idx;
/* Start-Of-Data . Try to start at next full chunk */
sod= o->write_idx;
@ -690,8 +644,7 @@ after_write:;
o->fd_in_counter= 0;
o->fd_in_limit= o->follow_up_in_limits[idx];
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: new fifo source fd : %d\n",
o->chain_idx,o->source_fd);
fprintf(stderr,"\ncdrfio: new fifo source fd : %d\n",o->source_fd);
} else {
o->source_fd= -1;
}
@ -824,13 +777,13 @@ ex:;
} else
elapsed= wait_usec;
if(elapsed>=wait_usec) {
if((flag&1)||Cdrfifo_debuG>=2) {
if((flag&1)||Cdrfifo_debuG) {
fprintf(stderr,"\n");
for(ff= o; ff!=NULL; ff= ff->next) {
buffer_space= Cdrfifo_tell_buffer_space(ff,0);
fprintf(stderr,
"cdrfifo %d: w=%d r=%d | b=%d s=%d | i=%.f o=%.f\n",
ff->chain_idx,ff->write_idx,ff->read_idx,
"cdrfifo_debug: w=%d r=%d | b=%d s=%d | i=%.f o=%.f\n",
ff->write_idx,ff->read_idx,
ff->buffer_size-buffer_space,buffer_space,
ff->in_counter,ff->out_counter);
}
@ -922,76 +875,6 @@ double Scanf_io_size(char *text, int flag)
}
/* This is a hardcoded test mock-up for two simultaneous fifos of which the
one runs with block size 2048 and feeds the other which runs with 2352.
Both fifos have the same number of follow_up pipes (tracks) which shall
be connected 1-to-1.
*/
int Test_mixed_bs(char **paths, int path_count,
int fs_size, double speed_limit, double interval, int flag)
/*
bit0= debugging verbousity
*/
{
int fd_in[100],fd_out[100],ret,pipe_fds[100][2],real_out[100];
int i,iv,stall_counter= 0,cycle_counter= 0.0;
char buf[10240], target_path[80];
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
struct CdrfifO *ff_in= NULL, *ff_out= NULL;
if(path_count<1)
return(2);
Cdrfifo_new(&ff_in,fd_in[0],fd_out[0],2048,fs_size,0);
for(i= 0; i<path_count; i++) {
fd_in[2*i]= open(paths[i],O_RDONLY);
if(fd_in[2*i]==-1)
return(0);
if(pipe(pipe_fds[2*i])==-1)
return(-1);
fd_out[2*i]= pipe_fds[2*i][1];
if(i==0)
ret= Cdrfifo_new(&ff_in,fd_in[2*i],fd_out[2*i],2048,fs_size,0);
else
ret= Cdrfifo_attach_follow_up_fds(ff_in,fd_in[2*i],fd_out[2*i],0);
if(ret<=0)
return(ret);
fd_in[2*i+1]= pipe_fds[2*i][0];
sprintf(target_path,"/dvdbuffer/fifo_mixed_bs_test_%d",i);
fd_out[2*i+1]= open(target_path,O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if(i==0)
ret= Cdrfifo_new(&ff_out,fd_in[2*i+1],fd_out[2*i+1],2352,fs_size,0);
else
ret= Cdrfifo_attach_follow_up_fds(ff_out,fd_in[2*i+1],fd_out[2*i+1],0);
if(ret<=0)
return(ret);
fprintf(stderr,"test_mixed_bs: %d : %2d fifo %2d pipe %2d fifo %2d : %s\n",
i, fd_in[2*i],fd_out[2*i],fd_in[2*i+1],fd_out[2*i+1], target_path);
}
Cdrfifo_attach_peer(ff_in,ff_out,0);
/* Let the fifos work */
iv= interval*1e6;
while(1) {
ret= Cdrfifo_try_to_work(ff_in,iv,NULL,NULL,flag&1);
if(ret<0 || ret==2) { /* <0 = error , 2 = work is done */
fprintf(stderr,"\ncdrfifo %d: fifo ended work with ret=%d\n",
ff_in->chain_idx,ret);
if(ret<0)
return(-7);
break;
}
cycle_counter++;
Cdrfifo_get_counters(ff_in, &in_counter, &out_counter, 0);
if(prev_in == in_counter && prev_out == out_counter)
stall_counter++;
prev_in= in_counter;
prev_out= out_counter;
}
return(1);
}
/* This is a hardcoded test mock-up for two simultaneous fifos of which the
first one simulates the cdrskin fifo feeding libburn and the second one
simulates libburn and the burner at given speed. Both have two fd pairs
@ -1050,8 +933,7 @@ int Test_multi(int fs_size, double speed_limit, double interval, int flag)
while(1) {
ret= Cdrfifo_try_to_work(ff1,iv,NULL,NULL,flag&1);
if(ret<0 || ret==2) { /* <0 = error , 2 = work is done */
fprintf(stderr,"\ncdrfifo %d: fifo ended work with ret=%d\n",
ff1->chain_idx,ret);
fprintf(stderr,"\ncdrfifo: fifo ended work with ret=%d\n",ret);
if(ret<0)
return(-7);
break;
@ -1110,13 +992,6 @@ int main(int argc, char **argv)
} else if(strncmp(argv[i],"vb=",3)==0) {
sscanf(argv[i]+3,"%d",&verbous);
} else if(strcmp(argv[i],"-mixed_bs_test")==0) {
ret= Test_mixed_bs(argv+i+1,argc-i-1,
(int) fs_value,speed_limit,interval,(verbous>=2));
fprintf(stderr,"Test_mixed_bs(): ret= %d\n",ret);
exit(ret<0);
} else if(strcmp(argv[i],"-multi_test")==0) {
if(speed_limit==0.0)
@ -1160,7 +1035,7 @@ int main(int argc, char **argv)
if(speed_limit!=0.0)
Cdrfifo_set_speed_limit(ff,speed_limit,0);
if(fill_buffer) {
ret= Cdrfifo_fill(ff,0,0);
ret= Cdrfifo_fill(ff,0);
if(ret<=0) {
fprintf(stderr,
"cdrfifo: FATAL : initial filling of fifo buffer failed\n");

View File

@ -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 "March 6, 2007"
.TH CDRSKIN 1 "February 8, 2007"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -16,8 +16,8 @@
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
cdrskin \- burns preformatted data to CD-R[W], DVD-R[W], DVD+R[W], DVD-RAM
via libburn.
cdrskin \- burns preformatted data to CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW,
DVD-RAM via libburn.
.SH SYNOPSIS
.B cdrskin
.RI [ options | track_source_addresses ]
@ -44,7 +44,7 @@ or in Session at Once mode for seamless tracks.
.br
Multi session on CD (follow-up sessions in TAO only)
.br
or on DVD-R[W] (in Incremental mode) or on DVD+R.
and on DVD-RW or DVD-R (in Incremental write mode only).
.br
Single session on DVD-RW or DVD-R (Disk-at-once)
.br
@ -54,20 +54,6 @@ Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
.br
See section EXAMPLES at the end of this text.
.PP
.B General information paragraphs:
.br
Track recording model
.br
Write mode selection
.br
Recordable CD Media
.br
Sequentially Recordable DVD Media
.br
Overwriteable DVD Media
.br
Drive preparation and addressing
.PP
.B Track recording model:
.br
The input-output entities which get processed are called tracks.
@ -110,16 +96,6 @@ have been developed for magnetic tapes. Only formats which mark a detectable
end-of-archive in their data are suitable, though. Well tested are
the archivers afio and star. Not suitable seems GNU tar.
.PP
.B Write mode selection:
.br
If none of the options -dao, -tao or -sao is given then the program will
try to choose a write mode which matches the defined recording job,
the capabilities of the drive and the state of the present media.
.br
So the mentioning of write modes in the following paragraphs and in the
examples is not so much a demand that the user shall choose one explicitely,
but rather an illustration of what to expect with particular media types.
.PP
.B Recordable CD Media:
.br
CD-R can be initially written only once and eventually extended until they
@ -148,34 +124,15 @@ Multiple cycles of blanking and overwriting with random numbers might be.
.PP
.B Sequentially Recordable DVD Media:
.br
Currently DVD-RW, DVD-R and DVD+R can be used for the Sequential recording
model.
.br
Currently only DVD-RW and DVD-R can be used for the Sequential recording model.
DVD-RW must be in state "Sequential Recording".
The media must be either blank or appendable.
Newly purchased DVD-RW and DVD-R media are in this state.
Used DVD-RW get into blank sequential state by option
.B blank=deformat_sequential .
.br
With DVD-R[W] two write modes may be available:
.br
Mode DAO has many restrictions. It does not work with
appendable media, allows no -multi and only a single track. The size of the
track needs to be known in advance. So either its source has to be a disk file
of recognizable size or the size has to be announced explicitely by options
.B tsize=
or
.B tao_to_sao_tsize= .
.br
DAO is the only mode for media which do not offer feature 21h Incremental
Streaming. DAO may also be selected explicitely by option
.B -sao .
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
DVD-ROM/-Video compatibility.
.br
The other mode, Incremental Streaming, is the default write mode if
it is available and if the restrictions of DAO would prevent the job.
Incremental Streaming may be selected explicitely by option
Incremental Streaming is the default write mode if it is offered by the media.
It may be selected explicitely by option
.B -tao
as it resembles much CD TAO by allowing track sources of
unpredicted length and to keep media appendable by option
@ -183,23 +140,24 @@ unpredicted length and to keep media appendable by option
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
Multiple tracks per session are permissible.
.br
The write modes for DVD+R resemble those with DVD-R except that with DVD+R
each track gets wrapped in an own session. There is no -dummy writing with
DVD+R.
The other write mode, DAO, has many restrictions. It does not work with
appendable media, allows no -multi and only a single track. The size of the
track needs to be known in advance. So either its source has to be a disk file
of recognizable size or the size has to be announced explicitely by options
.B tsize=
or
.B tao_to_sao_tsize= .
.br
Quite deliberately write mode -sao insists in the tradition of a predicted
track size and blank media, whereas -tao writes the tracks open ended and
allows appendable media.
DAO is the default mode for media which do not offer feature 21h Incremental
Streaming. It may also be selected explicitely by option
.B -sao .
.br
Currently DVD+R are always kept appendable regardless wether -multi is given
or not. This might change in future so it is strongly advised to already now
use
.B -multi
whenever the disc shall be kept appendable.
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
DVD-ROM/-Video compatibility.
.PP
.B Overwriteable DVD Media:
.br
Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
Currently only types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
.br
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
hold data or not. They need no special initial formatting.
@ -214,8 +172,8 @@ Overwriteable DVD recording model they need to get formatted to state
can be done by option
.B blank=format_overwrite .
.br
Several programs like dvd+rw-format, cdrecord, wodim, or cdrskin
can bring a DVD-RW out of overwriteable state so
Several programs like dvd+rw-format, cdrecord, wodim, or cdrskin option
blank=deformat_sequential can bring a DVD-RW out of overwriteable state so
that it has to be formatted again. If in doubt, just give it a try.
.PP
.B Drive preparation and addressing:
@ -226,9 +184,7 @@ by a run of \fBcdrskin --devices\fP.
.br
On Linux, they are device files which traditionally do not offer
w-permissions for normal users. Because libburn needs rw-permission,
it might be only the
.B superuser
who is able to get this list without further
it might be only the superuser who is able to get this list without further
precautions.
.br
It is consensus that \fBchmod a+rw /dev/sg0\fP or \fBchmod a+rw /dev/hdc\fP
@ -323,9 +279,6 @@ complete "de-icing" so no reader slips on unwritten data areas.
deformat_sequential
Like blank=all but with the additional ability to blank overwriteable DVD-RW.
This will destroy their formatting and make them sequentially recordable.
Another peculiarity is the ability to blank media which appear already blank.
This is similar to option -force but does not try to blank media other than
recognizable CD-RW and DVD-RW.
.br
(Note: blank=deformat_sequential* are not original cdrecord options.)
.TP
@ -383,10 +336,9 @@ insecure about drive or media state. This includes the attempt to blank
media which are classified as unknown or unsuitable, and the attempt to use
write modes which libburn believes they are not supported by the drive.
.br
Another application is to enforce blanking or re-formatting of media
which appear to be in the desired blank or format state already.
Another application is with blank=format_* to enforce re-formatting of media
which appear to be sufficiently formatted already.
.br
.B Caution:
Use this only when in urgent need.
.TP
.BI fs= size
@ -418,8 +370,8 @@ Note: msifile=path is actually an option of wodim and not of cdrecord.
.BI \-msinfo
Retrieve multi-session info for preparing a follow-up session by option -C
of programs mkisofs or genisoimage. Print result to standard output.
This option redirects to stderr all message output except the one of option
--tell_media_space and its own result string, which consists of two numbers.
This option redirects to stderr all
message output besides its own result string, which consists of two numbers.
The result string shall be used as argument of option -C with said programs.
It gives the start address of the most recent session and the predicted
start address of the next session to be appended. The string is empty if
@ -467,8 +419,8 @@ then behave strange or even go bad for the next few attempts to burn a CD.
One should use it only if inavoidable.
.TP
.BI \-sao
Write CD in Session At Once mode, a sequential DVD-R[W] in Disc-at-once
(DAO) mode, or a DVD+R.
Write CD in Session At Once mode, resp. a sequential DVD-R[W] in Disc-at-once
(DAO) mode.
.br
With CD this mode is able to put several audio tracks on media without
producing audible gaps between them.
@ -476,9 +428,6 @@ producing audible gaps between them.
With DVD-R[W] this mode can only write a single track.
No -multi is allowed with DVD-R[W] -sao.
.br
-sao is permissible with overwriteable DVD and with DVD+R but actually only
imposes restrictions without providing known advantages.
.br
-sao can only be used for tracks of fixely predicted size. This implies that
track arguments which depict stdin or named pipes need to be preceeded by
option tsize= or by option tao_to_sao_tsize=.
@ -513,9 +462,8 @@ Less guesswork is needed if track sources are in format MS-WAVE in a file with
suffix ".wav".
.TP
.BI \-tao
Write CD in Track At Once (TAO) mode, sequential DVD-R[W] in Incremental
Streaming mode, or DVD+R without traditional -sao restrictions.
This mode also applies pro-forma to overwriteable DVD media.
Write CD in Track At Once (TAO) mode, resp. sequential DVD-R[W] in Incremental
Streaming mode. This mode also applies pro-forma to overwriteable DVD media.
.br
Mode -tao can be used with track sources of unpredictable size, like standard
input or named pipes. It is also the only mode that can be used for writing
@ -581,20 +529,6 @@ contain a "=" character.
By default such arguments are seen as misspelled options. It is nevertheless
not possible to use one of the options listed with --list_ignored_options.
.TP
.BI assert_write_lba= block_number | byte_address
Abort if the write address given with this option is not the same as predicted
immediately before the write session starts. This option can ensure that a
start address which was presumed by a formatter like mkisofs -C is really used
by the drive for writing.
assert_write_lba=0 effectively demands blank media and excludes appendables.
.br
Block numbering is peculiar: If the last character of the option string is
a letter [a-zA-Z] then the usual unit scaling by "s", "k", "m", etc. applies
and the result is divided by 2048. Else the number value of the string is
taken as plain block number with block size 2048 byte.
(E.g ...=1000 or ...=1000s means block 1000, ...=1m means block
512, ...=4096b means block number 2)
.TP
.BI \--demand_a_drive
Exit with a nonzero value if no drive can be found during a bus scan.
.TP
@ -657,25 +591,6 @@ for best DVD-ROM compatibility.
If the track source delivers less bytes than announced then the missing ones
will be filled with zeros.
.TP
.BI --tell_media_space
Prepare a recording session, do not perform it but rather inquire the
maximum number of 2048 byte data blocks which may be written in
the current state of media with the prepared setup. So this option disables
recording of data. It does allow blanking, though, and will measure space
afterwards.
.br
It is not mandatory to give track sources but their nature may influence
the available capacity. So for most realistic results one may set up
the full burn session and add --tell_media_space. But if one has to expect
a cdrskin version prior to 0.3.3 no track source should be given in order
not to start an involuntary burn session.
In this case set at least -sao or -tao explicitely.
.br
The result gets printed to standard output. It is 0 or empty if no writing
is possible with the given options.
This option redirects to stderr all message output except its own result
string and eventual output of -msinfo.
.TP
.BI write_start_address= byte_offset
Set the address on media where to start writing the track. With DVD+RW or
DVD-RAM byte_offset must be aligned to 2 KB blocks, but better is 32 kB.
@ -692,17 +607,6 @@ but rather to shut it down and to wait until it has ended the final operations.
This option is only needed for revoking eventual --ignore_signals or
--no_abort_handler.
.TP
.BI \--allow_untested_media
Enable the use of media profiles which have been implemented but not yet
tested. Currently this applies to :
.br
Profile 0015h , DVD-R/DL Sequential (will not allow -multi).
.br
Profile 002Bh , DVD+R/DL.
.br
If you really test such media, then please report the outcome on
libburn-hackers@pykix.org
.TP
.BI dev_translation= <sep><from><sep><to>
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
translate cdrecord addresses into cdrskin addresses.
@ -738,18 +642,6 @@ Disable fifo despite any fs=.
.BI \--fifo_per_track
Use a separate fifo for each track.
.TP
.BI \--fill_up_media
Expand the last track of the session to occupy all remaining free space on
the media.
.br
This option overrides option -multi. It will not fill up media if option -sao
is given with CD media.
.br
.B Caution:
This option might increase read compatibility with DVD-ROM drives but
with some DVD recorders and media types it might also fail to produce readable
media at all. "Your mileage may vary".
.TP
.BI grab_drive_and_wait= seconds
Open the addressed drive, wait the given number of seconds, release the drive,
and do normal work as indicated by the other options used. This option helps
@ -824,7 +716,7 @@ cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
.br
-sao -eject padsize=300k my_image.iso
.SS
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW):
.B Write compressed afio archive on-the-fly:
.br
find . | afio -oZ - | \\
.br
@ -832,7 +724,7 @@ cdrskin -v dev=0,1,0 fs=32m speed=8 \\
.br
-tao padsize=300k -
.SS
.B Write multi-session to the same CD, DVD-R[W] or DVD+R:
.B Write several sessions to the same CD or DVD-R[W]:
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso
.br
@ -842,20 +734,12 @@ cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso
.SS
.B Get multi-session info for option -C of program mkisofs:
.B Get CD or DVD-R[W] multi-session info for option -C of program mkisofs:
.br
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)
.br
mkisofs ... -C "$c_values" ...
.SS
.B Inquire free space on media for a -tao -multi run:
.br
x=$(cdrskin dev=/dev/sr0 -tao -multi \\
.br
--tell_media_space 2>/dev/null)
.br
echo "Available: $x blocks of 2048 data bytes"
.SS
.B Write audio tracks to CD:
.br
cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
<HEAD>
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW, DVD+R, cdrecord, compatible, scdbackup">
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, linux, CDR, CD-R, CDRW, CD-RW, cdrecord, compatible, scdbackup, burning">
<META NAME="robots" CONTENT="follow">
<TITLE>cdrskin homepage english</TITLE>
</HEAD>
@ -24,8 +24,9 @@
<P>
<H2>Purpose:</H2>
Burns preformatted data to CD and single layer DVD media:<BR>
CD-R, DVD-R, DVD+R, CD-RW, DVD-RW, DVD-RAM, DVD+RW
<UL>
<LI>Burns preformatted data to CD-R, CD-RW, DVD-R, DVD-RW, DVD-RAM, DVD+RW</LI>
</UL>
</P>
<P>
@ -34,9 +35,8 @@ CD-R, DVD-R, DVD+R, CD-RW, DVD-RW, DVD-RAM, DVD+RW
<P>
<H2>Hardware requirements:</H2>
A CD/DVD recorder suitable for
<A HREF="http://libburnia.pykix.org">libburnia.pykix.org</A> <BR>
(SCSI , ATA , USB , or SATA writers compliant to standard MMC-3 for CD
and to MMC-5 for DVD).
<A HREF="http://libburnia.pykix.org">libburnia.pykix.org</A>
(SCSI or IDE/ATAPI writers compliant to standard MMC-3 or higher).
<BR>
</P>
@ -44,7 +44,7 @@ and to MMC-5 for DVD).
<H2>Software requirements :</H2>
<DL>
<DT>Linux kernel 2.4 or higher</DT>
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.4 the drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
<DT>libpthread</DT>
<DD>is supposed to be a standard system component.</DD>
@ -56,7 +56,7 @@ and to MMC-5 for DVD).
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-0.3.4</DT>
<DT>libburn-0.3.2</DT>
<DD>(by Derek Foreman, Ben Jansens, and team of libburnia.pykix.org)</DD>
<DD>transfers data to CD</DD>
</DL>
@ -94,15 +94,10 @@ can use this write mode, too.<BR>
Further enhancements depend on people who can describe and discuss their
wishes as well as on the development of libburn.</DT>
<BR><BR>
<DT>Get an overview of drives and their addresses</DT>
<DD>#<KBD>&nbsp;cdrskin -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin dev=ATA -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin --devices</KBD></DD>
<DT>Being superuser avoids permission problems with /dev/sgN resp. /dev/hdX .
</DT>
<DT>Ordinary users should then get granted rw access to the /dev files
as listed by option --devices.</DT>
<DT>&nbsp;</DT>
<DT>Get an overview of drives and their addresses:</DT>
<DD>$<KBD>&nbsp;cdrskin -scanbus</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin dev=ATA -scanbus</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin --devices</KBD></DD>
<DT>Get info about a particular drive or loaded media:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=0,1,0 -checkdrive</KBD></DD>
@ -129,7 +124,7 @@ as listed by option --devices.</DT>
<DD><KBD>&nbsp;&nbsp;cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;-tao padsize=300k -</KBD></DD>
<DT>Write several sessions to the same CD, DVD-R[W] or DVD+R:</DT>
<DT>Write several sessions to the same CD or DVD-R[W]:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso</KBD>
@ -138,15 +133,10 @@ as listed by option --devices.</DT>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso</KBD></DD>
<DT>Get multi-session info for option -C of program mkisofs:</DT>
<DT>Get CD or DVD-R[W] multi-session info for option -C of program mkisofs:</DT>
<DD>$<KBD>&nbsp;c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)</KBD></DD>
<DD>$<KBD>&nbsp;mkisofs ... -C "$c_values" ...</KBD></DD>
<DT>Inquire free space on media for a -tao -multi run:</DT>
<DD>$<KBD>&nbsp;x=$(cdrskin dev=/dev/sr0 -tao -multi \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;--tell_media_space 2>/dev/null)</KBD></DD>
<DD>$<KBD>&nbsp;echo "Available: $x blocks of 2048 data bytes"</KBD></DD>
<DT>Write audio tracks to CD:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;track1.wav track2.au -audio -swab track3.raw</KBD></DD>
@ -173,12 +163,34 @@ man cdrecord</A></KBD></DD>
</DL>
</P>
<P>
<H2>Known deficiencies:</H2>
<UL>
<DT></DT>
<LI>
Appending sessions to unclosed media is restricted to write mode TAO.
</LI>
<LI>
cdrskin -scanbus or --devices hangs for quite a while if there is
a CD drive which does not work properly (e.g. because it has individual
problems with DMA).
So if the superuser gets no result with cdrskin --devices then one should
disable DMA with the problematic CD drives
(like: <KBD>hdparm -d0 /dev/hdd</KBD> )
and try again.<BR>
In severe cases it might be necessary to guess the device name /dev/sgN resp.
/dev/hdX of the non-ill burner if it cannot be found otherwise among its
ill peers. Alternatively one can guess the address of the ill device, remove
rw-permissions and retry the bus scan as non-superuser.
</UL>
</P>
<HR>
<P>
<DL>
<DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-0.3.4.pl00.tar.gz">cdrskin-0.3.4.pl00.tar.gz</A>
<DD><A HREF="cdrskin-0.3.2.pl00.tar.gz">cdrskin-0.3.2.pl00.tar.gz</A>
(570 KB).
</DD>
<DD>
@ -189,21 +201,21 @@ cdrskin is part of libburn - full libburn is provided with cdrskin releases.
</DD>
<DD>&nbsp;</DD>
<DT>Download as single x86 binaries (untar and move to /usr/bin/cdrskin):</DT>
<DD><A HREF="cdrskin_0.3.4.pl00-x86-suse9_0.tar.gz">
cdrskin_0.3.4.pl00-x86-suse9_0.tar.gz</A>, (80 KB),
<DD><A HREF="cdrskin_0.3.2.pl00-x86-suse9_0.tar.gz">
cdrskin_0.3.2.pl00-x86-suse9_0.tar.gz</A>, (80 KB),
<DL>
<DD>runs on SuSE 9.0 (2.4.21) , RIP-14.4 (2.6.14) ,
Gentoo (2.6.15 x86_64 Athlon).</DD>
</DL>
<DD><A HREF="cdrskin_0.3.4.pl00-x86-suse9_0-static.tar.gz">
cdrskin_0.3.4.pl00-x86-suse9_0-static.tar.gz</A>, (285 KB), -static compiled,
<DD><A HREF="cdrskin_0.3.2.pl00-x86-suse9_0-static.tar.gz">
cdrskin_0.3.2.pl00-x86-suse9_0-static.tar.gz</A>, (285 KB), -static compiled,
<DL>
<DD>runs on SuSE 7.2 (2.4.4), and on the systems above.</DD>
</DL>
</DD>
</DL>
<DL><DT>Documentation:</DT>
<DD><A HREF="README_cdrskin">README</A> an introduction</DD>
<DD><A HREF="README_cdrskin">README</A> a short introduction</DD>
<DD><A HREF="cdrskin__help">cdrskin --help</A> non-cdrecord options</DD>
<DD><A HREF="cdrskin_help">cdrskin -help</A> cdrecord compatible options</DD>
<DD><A HREF="man_1_cdrskin.html">man cdrskin</A> the manual page</DD>
@ -223,38 +235,32 @@ cdrskin_0.3.4.pl00-x86-suse9_0-static.tar.gz</A>, (285 KB), -static compiled,
<HR>
<P>
Enhancements towards previous stable version cdrskin-0.3.2:
Enhancements towards previous stable version cdrskin-0.3.0:
<UL>
<LI>Multi-session burning to DVD+R</LI>
<LI>New option --tell_media_space tells the maximum size for the next burn</LI>
<LI>New option assert_write_lba= prevents inadverted writing to appendable
<LI>Bug fix: Multi-track runs with fifo could stall in rare cases</LI>
<LI>Burnfree enabled by default</LI>
<LI>Multi-session burning to DVD-R
and sequential (i.e. unformatted) DVD-RW</LI>
<LI>Option -toc with sequential DVD-R[W]</LI>
<LI>Options -msinfo and msifile= with appendable DVD-R[W]</LI>
<LI>Single session DAO write mode with DVD-R[W]</LI>
</UL>
<!--
Bug fixes towards cdrskin-0.3.4.pl00:
<UL>
<LI>none yet</LI>
</UL>
-->
</P>
<HR>
<P>
<DL>
<DT><H3>Development snapshot, version 0.3.5 :</H3></DT>
<DD>Enhancements towards stable version 0.3.4.pl00:
<DT><H3>Development snapshot, version 0.3.3 :</H3></DT>
<DD>Enhancements towards stable version 0.3.2:
<UL>
<LI>none yet</LI>
<LI>- none yet -</LI>
</UL>
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 0.3.5</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.3.5 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.3.5 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.3.5)</A></DD>
<DD><A HREF="README_cdrskin_devel">README 0.3.3</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.3.3 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.3.3 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.3.3)</A></DD>
<DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN of
<A HREF="http://libburnia.pykix.org"> libburnia.pykix.org</A></DT>
@ -274,15 +280,15 @@ admins with full system souvereignty.</DT>
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-0.3.5.tar.gz">cdrskin-0.3.5.tar.gz</A>
<A HREF="cdrskin-0.3.3.tar.gz">cdrskin-0.3.3.tar.gz</A>
(570 KB).
</DD>
<DD>Binary (untar and move to /usr/bin/cdrskin):</DD>
<DD><A HREF="cdrskin_0.3.5-x86-suse9_0.tar.gz">
cdrskin_0.3.5-x86-suse9_0.tar.gz</A>, (80 KB).
<DD><A HREF="cdrskin_0.3.3-x86-suse9_0.tar.gz">
cdrskin_0.3.3-x86-suse9_0.tar.gz</A>, (80 KB).
</DD>
<DD><A HREF="cdrskin_0.3.5-x86-suse9_0-static.tar.gz">
cdrskin_0.3.5-x86-suse9_0-static.tar.gz</A>, (280 KB)
<DD><A HREF="cdrskin_0.3.3-x86-suse9_0-static.tar.gz">
cdrskin_0.3.3-x86-suse9_0-static.tar.gz</A>, (280 KB)
</DD>
</DL>
</P>
@ -353,7 +359,7 @@ is a GUI frontend which uses cdrecord for CD burning.)
<DD>$ <KBD><B>export SCDBACKUP_USE_CDRSKIN=1</B></KBD></DD>
<DD>$ <KBD><B>./CONFIGURE_CD</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>cdrskin 0.3.4 : limited cdrecord compatibility wrapper for libburn</KBD></DD>
<DD><KBD>cdrskin 0.3.2 : limited cdrecord compatibility wrapper for libburn</KBD></DD>
</DL>
If your system is stricken with some ill CD device then this can stall
and you will have to press <KBD>Ctrl+C</KBD> to abort.
@ -412,8 +418,8 @@ Contact me. Let's see what we can achieve.
<BR>
<BR>
libburn and cdrskin are now mature enough to substitute cdrecord in its
major use cases of CD and DVD burning. It is possible to foist cdrskin on
various software packages if it gets falsely named "cdrecord".
major use cases of CD burning. It is possible to foist cdrskin on various
software packages if it gets falsely named "cdrecord".
I do not encourage this approach, but of course such a replacement
opportunity is the goal of a cdrecord compatibility wrapper.
<BR>

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.03.12.110001"
#define Cdrskin_timestamP "2007.02.10.120001"

View File

@ -23,17 +23,13 @@ Deliberate deviations of cdrskin from cdrecord compatibility:
+ DVD track sources get not concateneated to a single track. In general DVD
writing is quite different from cdrecord-ProDVD:
DVD-R[W] "Disc-at-once" (-sao) is nearest to cdrecord-ProDVD's methods.
DVD-R[W] "Incremental Streaming" (-tao) on unformatted media allows
DVD-RW "Disc-at-once" (-sao) is nearest to cdrecord-ProDVD's methods.
DVD-RW "Incremental Streaming" (-tao) on unformatted media allows
multi-session and track sources of unpredictable size.
Writing DVD-RAM, DVD+RW and "Restricted Overwrite" DVD-RW is like single
track -tao on blank CD. Formatting is done via cdrskin-specific
blank=format_overwrite and not with option -format.
+ DVD-RW get blanked fast only with option blank=deformat_sequential_quickest .
Option blank=fast is the same as blank=all in order to achieve media which
are capable of Incremental Streaming.
------------------------------------------------------------------------------
Changelog
@ -2962,14 +2958,14 @@ cdrskin/cdrskin.1
doc/cookbook.txt
Small corrections in documentation
10 Feb 2007 [tag 701] [705]
10 Feb 2007 [tag 701]
- cdrskin/add_ts_changes_to_libburn_0_3_0
- cdrskin/add_ts_changes_to_libburn_0_3_1
+ cdrskin/add_ts_changes_to_libburn_0_3_2
+ cdrskin/add_ts_changes_to_libburn_0_3_3
Updated cdrskin tarball generator
2007.02.10.120001 [tag 702] [704]
2007.02.10.120001 [tag 702]
Makefile.am
configure.ac
README
@ -2981,394 +2977,54 @@ cdrskin/wiki_plain.txt
cdrskin/cdrskin_eng.html
Made number transition and activated development documentation
10 Feb 2007 [tag 703] [707]
[]
cdrskin/changelog.txt
Documented changes and 0.3.2 release timestamp
----------------------------- release - cdrskin-0.3.2.pl00 - 2007.02.10.120001
------------------------------- cycle - cdrskin-0.3.2.pl00 - 2007.02.10.120001
* Burnfree enabled by default
* Multi-session recording on sequential DVD-R[W], including -toc, -msinfo
* DVD-R[W] Disk-at-once recording
10 Feb 2007 [706]
libburn/mmc.c
Added a comment about DVD-R
Bug reports to post after release:
See A70205_to_cdwrite_growisofs_dao_pitfalls
A70208_to_cdwrite_cdrecord_error_messages
A70209_to_cdrskit_error_messages
------------------------------------ cycle - cdrskin-0.3.3 - 2007.02.10.190528
12 Feb 2007 [708]
cdrskin/cdrskin.1
Being exacting about on-the-fly and DVD-RW
12 Feb 2007 [709]
cdrskin/cdrskin_eng.html
Updated list of keywords
2007.02.12.142245 [710]
libburn/mmc.c
Made profile 0010h DVD-ROM suitable,full,not erasable. So it delivers a TOC.
2007.02.13.115459 [711]
libburn/spc.c
Set a suitable page 05h after spc_probe_write_modes()
2007.02.13.143718 [712]
libburn/libburn.h
libburn/transport.h
libburn/mmc.c
libburn/spc.c
libburn/drive.c
Mew API function burn_disc_available_space()
13 Feb 2007 [713]
test/libburner.c
Removed or updated outdated restriction statements
13 Feb 2007 [714]
test/telltoc.c
Applied new API function burn_disc_available_space()
2007.02.14.120213 [715]
libburn/spc.c
Removed outdated ifdef
14 Feb 2007 [716]
test/telltoc.c
Set the advised write mode before inquiring media space
2007.02.14.121440 [717]
libburn/libdax_msgs.h
libburn/mmc.c
Handle eventual ridiculously high d->last_track_no
2007.02.14.122218 [718]
libburn/mmc.h
Forgotten part of revision 718
2007.02.14.202944 [719]
libburn/libburn.h
libburn/options.h
libburn/options.c
libburn/structure.h
libburn/structure.c
libburn/write.c
libburn/drive.c
Optional padding up to full media size when closing (incomplete yet)
2007.02.14.203635 [720]
cdrskin/cdrskin.c
cdrskin/cdrskin.1
New options --fill_up_media and --tell_media_space
2007.02.15.201506 [722]
libburn/options.c
libburn/drive.c
cdrskin/cdrskin.c
libburn/write.c
Took fill_up_media into respect with automatic write mode decisions
2007.02.15.201651 [723]
libburn/transport.h
libburn/mmc.c
libburn/libdax_msgs.h
Installed a guardian for predicted track end
2007.02.15.201757 [724]
libburn/structure.c
Corrected bug about open_ended filluped tracks
15 Feb 2007 [725]
libburn/libburn.h
cdrskin/cdrskin.1
Clarifications about current state of fillup
2007.02.15.203448 [726]
libburn/write.c
Repaired debugging message spoiled by uninitialized variable
2007.02.16.111941 [728]
libburn/write.c
Corrected CD TAO bug introduced with DVD bug fix 724 and CD SAO change 655
2007.02.17.085118 [729]
libburn/structure.c
Another bug fix for revision 724
2007.02.17.085533 [730]
libburn/async.c
cdrskin/cdrskin.c
cdrskin/cdrskin.1
test/libburner.c
Allowed forceful blanking of blank media in burn_disc_erase()
17 Feb 2007 [731]
test/libburner.c
Removed unprecise unnecessary comment
------------------------------------ cycle - cdrskin-0.3.3 - 2007.02.17.121238
* New option --tell_media_space tells the maximum size for the next burn
2007.02.18.094414 [732]
libburn/libburn.h
Clarified usage comment with burn_drive_info_free() (see ticket 98)
18 Feb 2007 [733]
cdrskin/cdrskin.1
cdrskin/cdrskin_eng.html
cdrskin/changelog.txt
Next cdrskin-0.3.3 cycle
2007.02.18.094858 [734]
libburn/mmc.h
Adjusted maximum realistic number of tracks to MMC specs
2007.02.19.184132 [735]
cdrskin/cdrskin.c
Repaired slightly broken pacifier track size display with -audio
2007.02.19.225102 [736]
libburn/libburn.h
libburn/async.c
libburn/structure.h
libburn/structure.c
libburn/write.h
libburn/write.c
libburn/drive.h
libburn/drive.c
libburn/options.c
libburn/libdax_msgs.h
Re-arranged checking and defaulting of write parameters
=
New API function burn_track_set_default_size()
New API function burn_precheck_write()
Make wide use of burn_disc_write_mode_demands()
2007.02.21.205244 [737]
libburn/libburn.h
libburn/async.c
libburn/drive.c
libburn/options.c
libburn/structure.c
libburn/write.c
libburn/libdax_msgs.h
cdrskin/cdrskin.c
Moved tao_to_sao_tsize into libburn, let cdrskin use auto_write_type and precheck
21 Feb 2007 [738]
cdrskin/add_ts_changes_to_libburn_0_3_3
cdrskin/add_ts_changes_to_libburn_0_3_2
Added -O2 to binary production
2007.02.22.072700 [739]
libburn/libburn.h
libburn/drive.c
libburn/options.c
Re-enabled overwriteable pseudo-pseudo-SAO with unpredicted track size
2007.02.22.073157 [740]
libburn/mmc.c
Disabled debugging messages about format descriptors
2007.02.22.094939 [741]
libburn/libburn.h
libburn/options.c
libburn/write.c
libburn/async.c
test/libburner.c
cdrskin/cdrskin.c
Macro for length of rejection reasons string (old size is still safe)
2007.02.22.113016 [742]
libburn/libburn.h
libburn/drive.c
Made burn_disc_available_space() take into respect burn_write_opts_set_start_byte()
2007.02.23.190937 [743]
libburn/libburn.h
libburn/drive.c
libburn/mmc.c
libburn/write.c
doc/cookbook.txt
Enabled DVD-R/DL Sequential via burn_allow_untested_profiles()
2007.02.23.191117 [744]
cdrskin/cdrskin.c
cdrskin/cdrskin.1
Enabled DVD-R/DL Sequential via --allow_untested_media_types
2007.02.23.193427 [745]
libburn/init.c
Forgotten source file for revision 743
------------------------------------ cycle - cdrskin-0.3.3 - 2007.02.24.102731
2007.02.25.112733 [746]
libburn/write.h
libburn/write.c
libburn/drive.c
cdrskin/cdrskin.1
Took into respect deliberate lack of DVD-R/DL multi session capability
2007.03.01.120945 [747]
libburn/drive.c
libburn/mmc.c
libburn/write.c
cdrskin/cdrskin.c
doc/cookbook.txt
Preparations for supporting DVD+R[/DL]
3 Mar 2007 [748]
cdrskin/cdrskin.1
Updated DVD-R[W] write mode description
2007.03.03.141240 [749]
libburn/transport.h
libburn/mmc.c
Determine physical interface SCSI,ATA,SATA,USB,... (for future use)
2007.03.03.141435 [750]
libburn/libburn.h
libburn/write.c
libburn/options.h
libburn/options.c
cdrskin/cdrskin.c
Re-enabled -force with write modes which seem unavailable
2007.03.03.151812 [751]
libburn/options.c
Fixed bug introduced with rev 736ff which prevented audio CD burning
2007.03.04.184720 [752]
cdrskin/cdrskin.c
cdrskin/cdrfifo.c
Fifo got stuck if sum of processed track sizes was exactly aligned to fifo size
------------------------------------ cycle - cdrskin-0.3.3 - 2007.03.04.185202
* Bug fix: Multi-track runs with fifo could stall in rare cases
5 Mar 2007 [753]
cdrskin/cdrskin_eng.html
cdrskin/add_ts_changes_to_libburn_0_3_2
Released cdrskin-0.3.2.pl01
2007.03.06.195203 [754]
libburn/mmc.c
libburn/write.c
Enabled DVD+R, DVD+R DL via --allow_untested_media_types, always -multi for now
2007.03.06.205312 [755]
libburn/mmc.c
cdrskin/cdrskin.1
doc/cookbook.txt
doc/comments
Enabled DVD+R as tested media (-multi is still always on)
2007.03.07.151514 [756]
libburn/write.c
cdrskin/cdrskin.1
cdrskin/README
doc/cookbook.txt
Some adjustments for DVD+R recording
2007.03.07.151514 [756]
cdrskin/cdrskin_eng.html
cdrskin/changelog.txt
Next cdrskin-0.3.3 cycle
------------------------------------ cycle - cdrskin-0.3.3 - 2007.03.07.155750
* Multi-session burning to DVD+R
8 Mar 2007 [757]
cdrskin/cdrskin.1
cdrskin/convert_man_to_html.sh
cdrskin/wiki_plain.txt
Polished documentation
2007.03.09.134622 [758]
cdrskin/cdrskin.c
cdrskin/cdrskin.1
New option assert_write_lba=
10 Mar 2007 [759]
cdrskin/cdrskin.1
cdrskin/wiki_plain.txt
Polished documentation
------------------------------------ cycle - cdrskin-0.3.3 - 2007.03.10.
* New option assert_write_lba=
2007.03.12.110001 [tag 761]
Makefile.am
configure.ac
README
cdrskin/cdrskin.c
cdrskin/README
cdrskin/compile_cdrskin.sh
cdrskin/cdrskin_timestamp.h
cdrskin/cdrskin_eng.html
Made number transition to 0.3.4 and activated development documentation
12 Mar 2007 [tag 762]
- cdrskin/add_ts_changes_to_libburn_0_3_2
- cdrskin/add_ts_changes_to_libburn_0_3_3
+ cdrskin/add_ts_changes_to_libburn_0_3_4
+ cdrskin/add_ts_changes_to_libburn_0_3_5
Updated cdrskin tarball generator
12 Mar 2007 [tag ]
cdrskin/changelog.txt
Documented most recent changes
----------------------------- release - cdrskin-0.3.4.pl00 - 2007.03.12.110001
* Multi-session burning to DVD+R
* New option --tell_media_space tells the maximum size for the next burn
* New option assert_write_lba=
* Bug fix: Multi-track runs with fifo could stall in rare cases
===============================================================================
TODO
===============================================================================
------------------------------------ cycle - cdrskin-0.3.3 -
cdrskin: prevent usage of burn drive as track source
forceful blanking of blank media in burn_disc_erase()
What about minimum track sizes ? (POWER OFF/ON , BUS RESET ?)
How to handle finalizing ?
growisofs does not finalize multi-session DVD[+-]R unless padding up. Why ?
cdrskin: prevent usage of burn drive as track source
move tao_to_sao_tsize into libburn and let cdrskin use auto write mode
Make wide use of mmc_four_char_to_int(), mmc_int_to_four_char()
Make wide use of burn_disc_write_mode_demands()
Remove from README what is also written in the man page.
Think about cdrecord option minbuf= for simultaneous operation on hdc and hdd
After cooking: review of -do_diet ?
growisofs.c : _LINUX_CAPABILITY_VERSION CAP_SYS_RAWIO SYS_capset ?
Questions to post:
A70211_to_cdwrite_growisofs_question_finalizing
Format DVD-RAM ?
Disable error checking with DVD-RAM.
How to handle finalizing ?
Rectify mmc_read_atip speed interpretation. 12x media are reported as 10x. I never heard of 6x media.
@ -3377,6 +3033,8 @@ Sequentially check option list for DVD compliance
----------------------------------------- long term intentions:
http://burbon04.gmxhome.de/linux/CDREncryption.html
[]
Ticket 90: failure on USB
@ -3390,6 +3048,7 @@ Open O_EXCL all devices in address resolution chain
(Might help with non-standard hdX device siblings)
[]
Convert libburn_experimental: into LIBDAX_MSGS_SEV_DEBUG
Convert burn_print() into libdax_msgs_submit()
[]
@ -3399,8 +3058,7 @@ Test unlocking of single drive by burn_drive_grab(), burn_drive_release()
[]
Clear outdated persistent read buffer after small CD image was read (ticket 57)
[]
Enable multi-session for write modes other than TAO
===============================================================================
This is the dirty end of the todo list.
For most recent changelog entries scroll up about 100 lines.
===============================================================================

View File

@ -7,7 +7,7 @@
debug_opts=
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
libvers="-DCdrskin_libburn_0_3_4"
libvers="-DCdrskin_libburn_0_3_2"
cleanup_src_or_obj="libburn/cleanup.o"
libdax_msgs_o="libburn/libdax_msgs.o"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
@ -33,15 +33,15 @@ do
libdax_audioxtr_o=
libdax_msgs_o="libburn/message.o"
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
elif test "$i" = "-libburn_0_3_4"
elif test "$i" = "-libburn_0_3_2"
then
libvers="-DCdrskin_libburn_0_3_4"
libvers="-DCdrskin_libburn_0_3_2"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
libdax_msgs_o="libburn/libdax_msgs.o"
cleanup_src_or_obj="libburn/cleanup.o"
elif test "$i" = "-libburn_svn"
then
libvers="-DCdrskin_libburn_0_3_5"
libvers="-DCdrskin_libburn_0_3_3"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
libdax_msgs_o="libburn/libdax_msgs.o"
cleanup_src_or_obj="libburn/cleanup.o"
@ -79,7 +79,7 @@ do
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006."
echo " -libburn_0_3_4 set macro to match libburn-0.3.4."
echo " -libburn_0_3_2 set macro to match libburn-0.3.2."
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -no_largefile do not use 64 bit off_t (must match libburn)."
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."

View File

@ -43,15 +43,12 @@ then
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
-e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \
-e 's/<b>Overview of features:<\/b>/\&nbsp;<BR><b>Overview of features:<\/b>/' \
-e 's/<b>General information paragraphs:<\/b>/\&nbsp;<BR><b>General information paragraphs:<\/b>/' \
-e 's/<b>Track recording model:<\/b>/\&nbsp;<BR><b>Track recording model:<\/b>/' \
-e 's/In general there are two types of tracks: data and audio./\&nbsp;<BR>In general there are two types of tracks: data and audio./' \
-e 's/While audio tracks just contain a given/\&nbsp;<BR>While audio tracks just contain a given/' \
-e 's/<b>Write mode selection:<\/b>/\&nbsp;<BR><b>Write mode selection:<\/b>/' \
-e 's/<b>Recordable CD Media:<\/b>/\&nbsp;<BR><b>Recordable CD Media:<\/b>/' \
-e 's/<b>Overwriteable DVD Media:<\/b>/\&nbsp;<BR><b>Overwriteable DVD Media:<\/b>/' \
-e 's/<b>Sequentially Recordable DVD Media:<\/b>/\&nbsp;<BR><b>Sequentially Recordable DVD Media:<\/b>/' \
-e 's/The write modes for DVD+R/\&nbsp;<BR>The write modes for DVD+R/' \
-e 's/<b>Drive preparation and addressing:<\/b>/\&nbsp;<BR><b>Drive preparation and addressing:<\/b>/' \
-e 's/If you only got one CD capable drive/\&nbsp;<BR>If you only got one CD capable drive/' \
-e 's/^Alphabetical list of options/\&nbsp;<BR>Alphabetical list of options/' \
@ -63,7 +60,7 @@ then
chmod u+rw,go+r,go-w "$htmlpage"
echo "Emerged file:"
ls -lL "$htmlpage"
ls -l "$htmlpage"
else

View File

@ -10,9 +10,8 @@ Schilling's cdrtools. cdrskin strives to be a second source for the services
traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way.
Overwriteable media DVD-RAM, DVD+RW and DVD-RW are handled differently than
with cdrecord-ProDVD in order to offer TAO-like single track recording.
Sequential DVD-R[W] and DVD+R are handled like CD-R[W] with TAO and
multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
with DVD-R[W].
Sequential DVD-R[W] are handled like CD-R[W] with TAO and multi-session.
Additionally cdrskin offers cdrecord-ProDVD-like mode DAO with DVD-R[W].
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
@ -23,9 +22,13 @@ About libburn API for burning CD: http://libburnia-api.pykix.org
--------------------------------------------------------------------------
For dual layer DVD types and for appending sessions to ISO filesystems on
DVD other than DVD-RW, DVD-R, DVD+R see the advise to use dvd+rw-tools at
the end of this text.
Appending sessions to an unclosed CD or DVD-R[W] is restricted to write mode
TAO. (Users who have a burner which succeeds with a follow-up session on CD via
cdrecord -sao : please contact us.)
For DVD types other than DVD-RAM, DVD+RW, DVD-RW, DVD-R and for appending
sessions to ISO filesystems on DVD other than DVD-RW, DVD-R see the advise
to use dvd+rw-tools at the end of this text.
--------------------------------------------------------------------------
@ -83,9 +86,10 @@ has to offer both, r- and w-permission.
--------------------------------------------------------------------------
The DVD capabilities of cdrskin differ from those of cdrecord-ProDVD. cdrskin
offers TAO-like multi-session with DVD-R[W], DVD+R and TAO-like single session
with overwriteable DVD media. It also offers DAO on DVD-R[W] which is probably
the same as the traditional cdrecord-ProDVD write mode.
lacks of support for DVD+R and for dual layer DVD media. On the other hand it
offers TAO-like multi-session with DVD-R[W] and TAO-like single session with
overwriteable DVD media. It also offers DAO on DVD-R[W] which is probably the
same as the traditional cdrecord-ProDVD write mode.
Non-cdrecord blank mode blank=format_overwrite brings a DVD-RW
disc from its initial profile "Sequential Recording" into profile state
@ -119,29 +123,6 @@ multi-session. (The default behavior of cdrskin deems me to be preferrable.)
--------------------------------------------------------------------------
assert_write_lba=<lba> allows to ensure that the start block address which
was used with the formatter program (e.g. mkisofs -C) matches the start block
address which will be used by the upcoming burn.
E.g. cdrskin aborts with an error message if
{{{
assert_write_lba=0
}}}
is given but an appendable media is to be burned which would start ati
block 68432.
An ISO-9660 file system image must be prepared according to a particular
block address on media. If the prepared address and the real address on media
do not match then the filesystem will not be mountable or may even cause system
trouble.
A sequential archive format like afio or star will not necessarily need such
a coordination of addresses. It might nevertheless be confusing to a reader
if the archive does not start at block 0.
--------------------------------------------------------------------------
fifo_start_at=<num> is a throughput enhancer for unsteady data streams
like they are produced by a compressing archiver program when piping to
CD on-the-fly. It makes better use of the general property of a FIFO
@ -228,10 +209,10 @@ for an illustrated example with K3b 0.10 .
DVD advise:
For burning of DVD media other than DVD-RAM, DVD+RW, DVD+R, DVD-RW, DVD-R,
the cdrskin project currently advises to use Andy Polyakov's dvd+rw-tools
which despite their historic name are capable of all the media above
and also do dual layer and even BD discs.
For burning of DVD media other than DVD-RAM, DVD+RW, DVD-RW, DVD-R, the cdrskin
project currently advises to use Andy Polyakov's dvd+rw-tools which despite
their historic name burn for me on above burner: DVD-RAM, DVD+RW, DVD+R,
DVD-RW, DVD-R and are also capable of dual layer and even BD discs.
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
@ -247,10 +228,9 @@ So for growable ISO filesystems on DVD-RAM or DVD+RW growisofs is the only
choice, currently.
cdrskin can offer DVD multi-session only with sequential DVD-R[W] and with
DVD+R.
Associated options blank=, -multi, -msinfo and -toc are available in this case.
Thus sequential DVD-RW behave much like large CD-RW with possibly more than 99
cdrskin can offer DVD multi-session only with sequential DVD-R[W]. Associated
options blank=, -multi, -msinfo and -toc are available in this case. Thus
sequential DVD-RW behave much like large CD-RW with possibly more than 99
tracks.
--------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [0.3.4], [http://libburnia.pykix.org])
AC_INIT([libburn], [0.3.2], [http://libburnia.pykix.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -19,7 +19,7 @@ dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
dnl
BURN_MAJOR_VERSION=0
BURN_MINOR_VERSION=3
BURN_MICRO_VERSION=4
BURN_MICRO_VERSION=2
BURN_INTERFACE_AGE=0
BURN_BINARY_AGE=0
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION

View File

@ -6,11 +6,9 @@
@section intro Introduction
Libburnia is an open-source project for reading, mastering and writing
optical discs.
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD-RW, DVD-R.
optical discs. For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD-RW, DVD-R.
Not supported yet are dual layer media, HD-DVD, BD (blue ray). Testers for
dual layer DVD+/-R are wanted, though.
Not supported yet are DVD+R, any dual layer media, HD-DVD, BD (blue ray).
The project comprises of several more or less interdependent parts which
together strive to be a usable foundation for application development.
@ -91,7 +89,7 @@ languages and development tools.
libburner is a minimal demo application for the library libburn
(see: libburn/libburn.h) as provided on http://libburn.pykix.org .
It can list the available devices, can blank a CD-RW or DVD-RW and
can burn to recordable CD and recordable single layer DVD.
can burn to CD-R, CD-RW, DVD-RAM, DVD+RW, DVD-RW, DVD-R.
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburnia team as reference application. libburner does indeed

View File

@ -5,7 +5,7 @@ Content:
- SAO CD Cookbook (CD-R, CD-RW, pure audio or pure data only)
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW)
- Sequential DVD-R[W] Cookbook
- DVD+R Cookbook (still emerging)
-------------------------------------------------------------------------------
TAO Multi-Session CD Cookbook
@ -689,7 +689,6 @@ Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
DVD-R 0011h
DVD-RW Restricted Overwrite 0013h
DVD-RW Sequential Recording 0014h
(DVD-R/DL Sequential Recording 0015h untested, might be single-session only)
There are two approaches for writing to sequential DVD-R[W]: DAO and
Incremental. Not all media and drives offer Incremental which allows
@ -702,8 +701,6 @@ track and it demands an exactly predicted track size.
- DAO writing
- Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems
- Obtaining a Table Of Content from DVD-R[W]
- Hearsay about DVD-R/DL (Dual Layer)
-------------------------------------------------------------------------------
About overwriteable, blank, appendable and finalized DVD-R[W] media :
@ -873,7 +870,6 @@ No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
-------------------------------------------------------------------------------
Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems :
(valid for DVD+R too)
Like with CD it is necessary to obtain the two numbers for mkisofs option -C
in order to prepare a ISO-9660 filesystem image which by its inner pointers
@ -926,8 +922,7 @@ Session from 51h READ DISC INFORMATION.
-------------------------------------------------------------------------------
Obtaining a Table Of Content from DVD-R[W]:
(valid for DVD+R too)
Obtaining a Table Of Content from DVD-R[W] :
The raw TOC entries from 43h READ TOC/PMA/ATIP Format 0010b as described with
CD media are not available with non-CD.
@ -967,133 +962,5 @@ model. Their start address is computed from the start and size of the last
track of the session.
-------------------------------------------------------------------------------
Hearsay about DVD-R/DL (Dual Layer) :
DVD-R/DL can assume profile 0015h DVD-R Dual Layer Sequential which is supposed
to behave like DVD-R or 0016h DVD-R Dual Layer Jump which has no counterpart
with DVD-R.
A half-sentence in mmc5r03c.pdf 6.3.3.3.3 might indicate that closing a session
by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits
in mode page 05h.
growisofs applies this function in case of not DAO, though. A comment in
growisofs_mmc.cpp states: "// DVD-R DL Seq has no notion of multi-session".
I am not reading this from the specs - but not explicitely the contrary either.
For now libburn will close the session but there is a macro prepared in
libburn/write.c Libburn_dvd_r_dl_multi_no_close_sessioN which will suppress
close session if multi-session is demanded.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
INCOMPLETE YET
DVD+R Cookbook
-------------------------------------------------------------------------------
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
backed by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
For libburnia.pykix.org by Thomas Schmitt <scdbackup@gmx.net>
-------------------------------------------------------------------------------
Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
(mmc5r03c.pdf 6.6.2.1)
DVD+R 001bh
DVD+R/DL 002bh
- About empty, appendable and finalized DVD+R
- Writing a Pseudo Session to DVD+R
- >>> Hearsay about DVD+R/DL (Dual Layer) :
The following two chapters of the Sequential DVD-R[W] Cookbook are valid for
DVD+R media too:
- Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems
- Obtaining a Table Of Content from DVD-R[W]
-------------------------------------------------------------------------------
About blank, appendable and finalized DVD+R :
In the beginning a DVD+R holds an empty session and the Incomplete Fragment.
From these one may spawn reserved fragments or one may write directly to
the incomplete fragment. As soon as this is done the empty session becomes the
open session which finally needs to get closed. By closing fragments and
session a new empty session with empty Incomplete Fragment gets spawned.
So the disc stays appendable.
A DVD+R may hold 153 closed sessions with a single track each.
The open session may hold up to 15 open fragments. But on closure of the
session those fragments together form a single logical track. So one will
usually only use a single fragment for sequential writing.
(mmc5r03c.pdf 4.3.6.2)
The disc may get finalized by another close command so that no more data can
be written.
(mmc5r03c.pdf 6.3.3.4.4)
-------------------------------------------------------------------------------
Writing a Pseudo Session to DVD+R :
Session writing has to be pseudo because only one logical track per session
can be distinguished. So actually there have to be written multiple sessions
to mark multiple tracks. The pseudo session cannot get marked on disc and thus
the tracks of a pseudo session cannot be grouped accordingly in a TOC.
Speed can be influenced by B6h SET STREAMING , speed capabilities can be
inquired by ACh GET PERFORMANCE. It is advised to set only speeds and sizes
which are returned by ACh.
(mmc5r03c.pdf 6.39 SET STREAMING, 6.8 GET PERFORMANCE)
No mode page 05h is to be sent.
growisofs sends a page but the specs clearly state that one shall not do.
(mmc5r03c.pdf 7.5.3)
It is optional wether a track size is reserved in advance or not. Eventually
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
already be aligned to 32 KiB.
(mmc5r03c.pdf 6.31)
The specs promise to pad up the track if not enough data get written.
(mmc5r03c.pdf 6.3.3.4.2)
Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION
with track number FFh.
(mmc5r03c.pdf 6.27)
Since the fixely set write type is 16-block packet, full 32 kB buffers have
to be transmitted via 2Ah WRITE.
(mmc5r03c.pdf 4.3.6.2.2)
When writing is done, it is mandatory to force the drive's buffer to media by
35h SYNCHRONIZE CACHE.
(mmc5r03c.pdf 6.41)
The written fragment (i.e. track-to-be) has to be closed by 5Bh CLOSE TRACK
SESSION Close Function 001b.
(mmc5r03c.pdf 6.3.3.4.2)
libburn obtains the necessary logical track number from Last Track Number in
Last Session from the reply of 51h READ DISC INFORMATION requesting
Data Type 000b.
(mmc5r03c.pdf 6.22)
After each track 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
Number 0 closes the DVD+R session but keeps the media appendable.
(mmc5r03c.pdf 6.3.3.4.3)
>>> This is not tested yet. growisofs has code for that gesture but explicitly
avoids to use it. Instead it recommends to fill up the media with zeros.
Eventually 5Bh CLOSE TRACK SESSION Close Function 101b is used to finalize
the media with minimal radius. After that the disc is not appendable any more !
(mmc5r03c.pdf 6.3.3.4.4)
-------------------------------------------------------------------------------
Hearsay about DVD+R/DL (Dual Layer) :
>>>
-------------------------------------------------------------------------------

View File

@ -12,7 +12,6 @@
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
#include <a ssert.h>
@ -237,17 +236,10 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
/* ts A70103 moved up from burn_disc_erase_sync() */
/* ts A60825 : allow on parole to blank appendable CDs */
/* ts A70131 : allow blanking of overwriteable DVD-RW (profile 0x13) */
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
and of any kind of full media */
if ((drive->current_profile != 0x0a &&
drive->current_profile != 0x13 &&
drive->current_profile != 0x14 &&
drive->status != BURN_DISC_FULL)
||
(drive->status != BURN_DISC_FULL &&
drive->status != BURN_DISC_APPENDABLE &&
drive->status != BURN_DISC_BLANK)
) {
if ( ! (drive->status == BURN_DISC_FULL ||
(drive->status == BURN_DISC_APPENDABLE &&
! libburn_back_hack_42) ||
drive->current_profile == 0x13 ) ) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020130,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -333,11 +325,7 @@ static void *write_disc_worker_func(struct w_list *w)
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{
struct write_opts o;
char reasons[BURN_REASONS_LEN+80];
#ifndef Libburn_precheck_write_ruleS
int i, j, mode, mixed_mode = 0;
#endif
/* For the next lines any return indicates failure */
opts->drive->cancel = 1;
@ -365,37 +353,10 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
"Drive capabilities not inquired yet", 0, 0);
return;
}
/* ts A70219 : intended to replace all further tests here and many
tests in burn_*_write_sync()
*/
strcpy(reasons, "Write job parameters are unsuitable:\n");
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
== BURN_WRITE_NONE) {
#ifndef Libburn_precheck_write_ruleS
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
#else
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
return;
#endif /* Libburn_precheck_write_ruleS */
}
#ifndef Libburn_precheck_write_ruleS
/* <<< covered burn_precheck_write() */
/* ts A61009 : obsolete Assert in sector_headers() */
if (! burn_disc_write_is_ok(opts, disc, 0)) /* issues own msgs */
if (! burn_disc_write_is_ok(opts, disc)) /* issues own msgs */
return;
/* <<< covered burn_precheck_write() */
/* ts A70122 : libburn SAO code mishandles mode changes */
for (i = 0; i < disc->sessions; i++) {
if (disc->session[i]->tracks <= 0)
@ -412,7 +373,6 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
"Cannot mix data and audio in SAO mode", 0, 0);
return;
}
#endif /* ! Libburn_precheck_write_ruleS */
opts->drive->cancel = 0; /* End of the return = failure area */

View File

@ -29,12 +29,6 @@
/* ts A70107 : to get BE_CANCELLED */
#include "error.h"
/* ts A70219 : for burn_disc_get_write_mode_demands() */
#include "options.h"
/* A70225 : to learn about eventual Libburn_dvd_r_dl_multi_no_close_sessioN */
#include "write.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -1408,7 +1402,7 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
0, 0);
return -1;
}
if (o != NULL)
if (o!=NULL)
d->send_write_parameters(d, o);
ret = d->get_nwa(d, trackno, lba, nwa);
return ret;
@ -1441,29 +1435,6 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start)
}
/* ts A70213 : new API function */
off_t burn_disc_available_space(struct burn_drive *d,
struct burn_write_opts *o)
{
int lba, nwa;
if (burn_drive_is_released(d))
goto ex;
if (d->busy != BURN_DRIVE_IDLE)
goto ex;
if (o != NULL)
d->send_write_parameters(d, o);
d->get_nwa(d, -1, &lba, &nwa);
ex:;
if (o->start_byte > 0) {
if (o->start_byte > d->media_capacity_remaining)
return 0;
return d->media_capacity_remaining - o->start_byte;
}
return d->media_capacity_remaining;
}
/* ts A61202 : New API function */
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
{
@ -1644,19 +1615,14 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
}
if (wt == BURN_WRITE_RAW)
o->multi_session = o->multi_track = 0;
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , sequential DVD-RW , DVD-R/DL Sequential */
} else if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R , sequential DVD-RW */
if (s == BURN_DISC_BLANK) {
o->might_do_sao = 1;
o->advised_write_mode = BURN_WRITE_SAO;
}
if (d->current_has_feat21h) {
#ifndef Libburn_dvd_r_dl_multi_no_close_sessioN
if (d->current_profile != 0x15)
#endif
o->multi_session = 1;
o->multi_track = 1;
o->multi_session = o->multi_track = 1;
o->might_do_tao = 2;
o->advised_write_mode = BURN_WRITE_TAO;
}
@ -1691,15 +1657,8 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
d->best_format_size - 2048;
}
}
o->might_do_sao = 4;
o->might_do_tao = 2;
o->advised_write_mode = BURN_WRITE_TAO;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
o->multi_session = o->multi_track = 1;
o->might_do_tao = 2;
o->might_do_sao = 1;
o->advised_write_mode = BURN_WRITE_TAO;
} else /* unknown media */
return 0;
@ -1727,25 +1686,15 @@ int burn_disc_free_multi_caps(struct burn_multi_caps **caps)
}
/* ts A70207 : evaluate write mode related peculiarities of a disc
@param flag bit0= fill_up_media is active
*/
/* ts A70207 : evaluate write mode related peculiarities of a disc */
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag)
{
struct burn_session *session;
struct burn_track *track;
int i, j, mode, unknown_track_sizes = 0, last_track_is_unknown = 0;
enum burn_disc_status s;
int i, j, mode;
memset((char *) result, 0, sizeof(struct burn_disc_mode_demands));
if (disc == NULL)
return 2;
s = burn_disc_get_status(opts->drive);
if (s == BURN_DISC_APPENDABLE || disc->sessions > 1)
result->will_append = 1;
if (disc->sessions > 1)
result->multi_session = 1;
for (i = 0; i < disc->sessions; i++) {
@ -1757,33 +1706,15 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
result->multi_track = 1;
for (j = 0; j < session->tracks; j++) {
track = session->track[j];
if (burn_track_is_open_ended(track)) {
if (burn_track_get_default_size(track) > 0) {
if (result->unknown_track_size == 0)
result->unknown_track_size = 2;
} else
result->unknown_track_size = 1;
unknown_track_sizes++;
last_track_is_unknown = 1;
} else
last_track_is_unknown = 0;
if (burn_track_is_open_ended(track))
result->unknown_track_size = 1;
if (mode != track->mode)
result->mixed_mode = 1;
if (track->mode == BURN_MODE1) {
result->block_types |= BURN_BLOCK_MODE1;
} else if (track->mode == BURN_AUDIO) {
if (track->mode != BURN_MODE1)
result->exotic_track = 1;
if (track->mode == BURN_AUDIO)
result->audio = 1;
result->block_types |= BURN_BLOCK_RAW0;
result->exotic_track = 1;
} else {
result->block_types |= opts->block_type;
result->exotic_track = 1;
}
}
}
if (flag&1) {/* fill_up_media will define the size of the last track */
if (unknown_track_sizes == 1 && last_track_is_unknown)
result->unknown_track_size = 0;
}
return (disc->sessions > 0);
}

View File

@ -100,15 +100,12 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag);
struct burn_disc_mode_demands {
int multi_session;
int multi_track;
int unknown_track_size; /* 0=known, 1=unknown, 2=unknown+defaulted */
int unknown_track_size;
int mixed_mode;
int audio;
int exotic_track;
int block_types;
int will_append; /* because of media state or multi session disc */
};
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag);
struct burn_disc_mode_demands *result, int flag);
#endif /* __DRIVE */

View File

@ -50,10 +50,6 @@ static char abort_message_prefix[81] = {"libburn : "};
static pid_t abort_control_pid= 0;
/* ts A70223 : wether implemented untested profiles are supported */
int burn_support_untested_profiles = 0;
/* ts A60925 : ticket 74 */
/** Create the messenger object for libburn. */
int burn_msgs_initialize(void)
@ -77,7 +73,6 @@ int burn_initialize(void)
if (burn_running)
return 1;
burn_support_untested_profiles = 0;
ret = burn_msgs_initialize();
if (ret <= 0)
return 0;
@ -279,10 +274,3 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
}
/* ts A70223 : API */
void burn_allow_untested_profiles(int yes)
{
burn_support_untested_profiles = !!yes;
}

View File

@ -589,19 +589,6 @@ void burn_set_verbosity(int level);
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy);
/* ts A70223 */
/** Allows the use of media types which are implemented in libburn but not yet
tested. The list of those untested profiles is subject to change.
Currently it contains: 0x15 "DVD-R/DL Sequential".
If you really test such media, then please report the outcome on
libburn-hackers@pykix.org
If ever then this call should be done soon after burn_initialize() before
any drive scanning.
@param yes 1=allow all implemented profiles, 0=only tested media (default)
*/
void burn_allow_untested_profiles(int yes);
/* ts A60823 */
/** Aquire a drive with known persistent address.This is the sysadmin friendly
way to open one drive and to leave all others untouched. It bundles
@ -687,9 +674,7 @@ int burn_drive_scan(struct burn_drive_info *drive_infos[],
int burn_drive_info_forget(struct burn_drive_info *drive_info, int force);
/** When no longer needed, free a whole burn_drive_info array which was
returned by burn_drive_scan().
For freeing single drive array elements use burn_drive_info_forget().
/** Free a burn_drive_info array returned by burn_drive_scan
*/
void burn_drive_info_free(struct burn_drive_info drive_infos[]);
@ -853,32 +838,11 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
*/
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
/* ts A70213 */
/** Return the best possible estimation of the currently available capacity of
the media. This might depend on particular write option settings. For
inquiring the space with such a set of options, the drive has to be
grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value
from the most recent automatic inquiry (e.g. during last drive grabbing).
An eventual start address from burn_write_opts_set_start_byte() will be
subtracted from the obtained capacity estimation. Negative results get
defaulted to 0.
@param d The drive to query.
@param o If not NULL: write parameters to be set on drive before query
@return number of most probably available free bytes
*/
off_t burn_disc_available_space(struct burn_drive *d,
struct burn_write_opts *o);
/* ts A61202 */
/** Tells the MMC Profile identifier of the loaded media. The drive must be
grabbed in order to get a non-zero result.
libburn currently writes only to profiles 0x09 "CD-R", 0x0a "CD-RW",
0x11 "DVD-R", 0x12 "DVD-RAM", 0x13 "DVD-RW restricted overwrite",
0x14 "DVD-RW Sequential Recording" or 0x1a "DVD+RW".
If enabled by burn_allow_untested_profiles() it also writes to profile
0x15 "DVD-R/DL Sequential Recording".
0x12 "DVD-RAM", 0x13 "DVD-RW restricted overwrite" or 0x1a "DVD+RW".
@param d The drive where the media is inserted.
@param pno Profile Number as of mmc5r03c.pdf, table 89
@param name Profile Name (e.g "CD-RW", unknown profiles have empty name)
@ -931,7 +895,6 @@ void burn_read_opts_free(struct burn_read_opts *opts);
@param drive The drive with which to erase a disc.
@param fast Nonzero to do a fast erase, where only the disc's headers are
erased; zero to erase the entire disc.
With DVD-RW, fast blanking yields media capable only of DAO.
*/
void burn_disc_erase(struct burn_drive *drive, int fast);
@ -1016,35 +979,9 @@ int burn_disc_get_format_descr(struct burn_drive *drive, int index,
*/
void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
/* ts A70222 */
/** The length of a rejection reasons string for burn_precheck_write() and
burn_write_opts_auto_write_type() .
*/
#define BURN_REASONS_LEN 4096
/* ts A70219 */
/** Examines a completed setup for burn_disc_write() wether it is permissible
with drive and media. This function is called by burn_disc_write() but
an application might be interested in this check in advance.
@param o The options for the writing operation.
@param disc The descrition of the disc to be created
@param reasons Eventually returns a list of rejection reason statements
@param silent 1= do not issue error messages , 0= report problems
@return 1 ok, -1= no recordable media detected, 0= other failure
*/
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int silent);
/* <<< enabling switch for internal usage and trust in this function */
#define Libburn_precheck_write_ruleS 1
/** Write a disc in the drive. The drive must be grabbed successfully before
calling this function. Always ensure that the drive reports a status of
BURN_DISC_BLANK ot BURN_DISC_APPENDABLE before calling this function.
BURN_DISC_BLANK before calling this function.
Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
To be set by burn_write_opts_set_write_type().
@ -1222,20 +1159,6 @@ struct burn_disc *burn_drive_get_disc(struct burn_drive *d);
enum burn_source_status burn_track_set_source(struct burn_track *t,
struct burn_source *s);
/* ts A70218 */
/** Set a default track size to be used only if the track turns out to be of
unpredictable length and if the effective write type demands a fixed size.
This can be useful to enable write types CD SAO or DVD DAO together with
a track source like stdin. If the track source delivers fewer bytes than
announced then the track will be padded up with zeros.
@param t The track to change
@param size The size to set
@return 0=failure 1=sucess
*/
int burn_track_set_default_size(struct burn_track *t, off_t size);
/** Free a burn_source (decrease its refcount and maybe free it)
@param s Source to free
*/
@ -1255,7 +1178,6 @@ struct burn_source *burn_file_source_new(const char *path,
*/
struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size);
/** Tells how long a track will be on disc
>>> NOTE: Not reliable with tracks of undefined length
*/
@ -1293,7 +1215,6 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts,
enum burn_write_types write_type,
int block_type);
/* ts A70207 */
/** As an alternative to burn_write_opts_set_write_type() this function tries
to find a suitable write type and block type for a given write job
@ -1302,15 +1223,12 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts,
@param opts The nearly complete write opts to change
@param disc The already composed session and track model
@param reasons This text string collects reasons for decision resp. failure
@param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
(is automatically set with bit0)
@param flag Bitfield for control purposes (unused yet, submit 0)
@return Chosen write type. BURN_WRITE_NONE on failure.
*/
enum burn_write_types burn_write_opts_auto_write_type(
struct burn_write_opts *opts, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int flag);
char reasons[1024], int flag);
/** Supplies toc entries for writing - not normally required for cd mastering
@ -1377,28 +1295,6 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value);
/* ts A70213 */
/** Caution: still immature and likely to change. Problems arose with
sequential DVD-RW on one drive.
Controls wether the whole available space of the media shall be filled up
by the last track of the last session.
@param opts The write opts to change
@param fill_up_media If 1 : fill up by last track, if 0 = do not fill up
*/
void burn_write_opts_set_fillup(struct burn_write_opts *opts,
int fill_up_media);
/* ts A70303 */
/** Eventually makes libburn ignore the failure of some conformance checks:
- the check wether CD write+block type is supported by the drive
@param opts The write opts to change
@param use_force 1=ignore above checks, 0=refuse work on failed check
*/
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force);
/** Sets whether to read in raw mode or not
@param opts The read opts to change
@param raw_mode If non-zero, reading will be done in raw mode, so that everything in the data tracks on the
@ -1518,7 +1414,7 @@ struct burn_multi_caps {
of multi-session by keeping a disc appendable. But .might_do_sao
will be 0 afterwards, when checking the appendable media.)
1= media may be kept appendable by burn_write_opts_set_multi(o,1)
0= media will not be appendable
0= media will not be apendable appendable
*/
int multi_session;
@ -1554,8 +1450,6 @@ struct burn_multi_caps {
off_t start_range_high;
/** Potential availability of write modes
4= needs no size prediction, not to be chosen automatically
3= needs size prediction, not to be chosen automatically
2= available, no size prediction necessary
1= available, needs exact size prediction
0= not available
@ -1566,9 +1460,7 @@ struct burn_multi_caps {
int might_do_sao;
int might_do_raw;
/** Generally advised write mode.
Not necessarily the one chosen by burn_write_opts_auto_write_type()
because the burn_disc structure might impose particular demands.
/** Advised write mode.
*/
enum burn_write_types advised_write_mode;
@ -1600,7 +1492,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
struct burn_multi_caps **caps, int flag);
/** Removes from memory a multi session info structure which was returned by
burn_disc_get_multi_caps(). The pointer *caps gets set to NULL.
burn_disc_get_multi_caps(). The pointer *caps gets set o NULL.
@param caps the info structure to dispose (note: pointer to pointer)
@return 0 : *caps was already NULL, 1 : memory object was disposed
*/

View File

@ -350,21 +350,17 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020129 (SORRY,HIGH) = Will not format media type
0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities
0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job
0x0002012c (SORRY,HIGH) = Too many logical tracks recorded
0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses
0x0002012e (NOTE,HIGH) = Activated track default size
0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session
0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking
0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive
0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn
0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode
0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO
0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO
0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track
0x00020136 (SORRY,HIGH) = DAO Burning restricted to single fixed size track
0x00020137 (HINT,HIGH) = TAO would be possible
0x00020138 (FATAL,HIGH) = Cannot reserve track
0x00020139 (SORRY,HIGH) = Write job parameters are unsuitable
0x0002013a (FATAL,HIGH) = No suitable media detected
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -21,10 +21,6 @@
#include "options.h"
/* ts A70223 : in init.c */
extern int burn_support_untested_profiles;
#ifdef Libburn_log_in_and_out_streaM
/* <<< ts A61031 */
#include <sys/types.h>
@ -47,11 +43,11 @@ extern struct libdax_msgs *libdax_messenger;
/* ts A70112 */
#define Libburn_support_dvd_raM 1
/* ts A70129 */
/* ts A70129 >>> EXPERIMENTAL UNTESTED
*/
#define Libburn_support_dvd_r_seQ 1
/* ts A70306 >>> UNTESTED */
#define Libburn_support_dvd_plus_R 1
/* Progress report:
ts A61219 : It seems to work with a used (i.e. thoroughly formatted) DVD+RW.
@ -87,8 +83,9 @@ extern struct libdax_msgs *libdax_messenger;
with unpredicted size, multi-track, multi-session.
ts A70205 : Beginning to implement DVD-R[W] DAO : single track and session,
size prediction mandatory.
ts A70208 : Finally made tests with DVD-R. Worked exactly as new DVD-RW.
Todo:
Determine first free lba for appending data on overwriteables.
*/
@ -165,7 +162,8 @@ int mmc_function_spy_ctrl(int do_tell)
/* ts A70201 */
int mmc_four_char_to_int(unsigned char *data)
{
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
return (data[0] << 24) | (data[1] << 16) |
(data[2] << 8) | data[3];
}
@ -240,6 +238,7 @@ int mmc_reserve_track(struct burn_drive *d, off_t size)
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf)
{
struct command c;
int i;
mmc_function_spy("mmc_read_track_info");
c.retry = 1;
@ -251,16 +250,14 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf)
d->current_profile == 0x12 )
/* DVD+RW , DVD-RW restricted overwrite , DVD-RAM */
trackno = 1;
else if (d->current_profile == 0x10 ||
d->current_profile == 0x11 ||
d->current_profile == 0x14 ||
d->current_profile == 0x15)
/* DVD-ROM , DVD-R[W] Sequential */
else if (d->current_profile == 0x11 ||
d->current_profile == 0x14) /* DVD-R[W] Sequential */
trackno = d->last_track_no;
else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */
trackno = 0xFF;
}
mmc_int_to_four_char(c.opcode + 2, trackno);
for (i = 0; i < 4; i++)
c.opcode[2 + i] = (trackno >> (24 - 8 * i)) & 0xff;
c.page = buf;
memset(buf->data, 0, BUFFER_SIZE);
c.dir = FROM_DRIVE;
@ -277,22 +274,58 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf)
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
{
struct buffer buf;
int ret, num;
int ret;
#ifdef Libburn_get_nwa_standalonE
struct command c;
int i;
#endif
unsigned char *data;
mmc_function_spy("mmc_get_nwa");
if(trackno<=0) {
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12 )
/* DVD+RW , DVD-RW restricted overwrite , DVD-RAM */
trackno = 1;
else if (d->current_profile == 0x11 ||
d->current_profile == 0x14) /* DVD-R[W] Sequential */
trackno = d->last_track_no;
else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */
trackno = 0xFF;
}
#ifdef Libburn_get_nwa_standalonE
c.retry = 1;
c.oplen = sizeof(MMC_TRACK_INFO);
memcpy(c.opcode, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO));
c.opcode[1] = 1;
for (i = 0; i < 4; i++)
c.opcode[2 + i] = (trackno >> (24 - 8 * i)) & 0xff;
c.page = &buf;
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
data = c.page->data;
#else /* Libburn_get_nwa_standalonE */
ret = mmc_read_track_info(d, trackno, &buf);
if (ret <= 0)
return ret;
data = buf.data;
*lba = mmc_four_char_to_int(data + 8);
*nwa = mmc_four_char_to_int(data + 12);
num = mmc_four_char_to_int(data + 16);
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12) {
/* overwriteable */
*lba = *nwa = num = 0;
#endif /* ! Libburn_get_nwa_standalonE */
*lba = (data[8] << 24) + (data[9] << 16)
+ (data[10] << 8) + data[11];
*nwa = (data[12] << 24) + (data[13] << 16)
+ (data[14] << 8) + data[15];
if (d->current_profile == 0x1a || d->current_profile == 0x13) {
/* DVD+RW or DVD-RW restricted overwrite */
*lba = *nwa = 0;
} else if (!(data[7]&1)) {
/* ts A61106 : MMC-1 Table 142 : NWA_V = NWA Valid Flag */
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
@ -300,17 +333,6 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
"mmc_get_nwa: Track Info Block: NWA_V == 0", 0, 0);
return 0;
}
if (num > 0) {
d->media_capacity_remaining = ((off_t) num) * ((off_t) 2048);
d->media_lba_limit = *nwa + num;
} else
d->media_lba_limit = 0;
/*
fprintf(stderr, "LIBBURN_DEBUG: media_lba_limit= %d\n",
d->media_lba_limit);
*/
return 1;
}
@ -356,11 +378,6 @@ void mmc_close_session(struct burn_write_opts *o)
mmc_close(d, 1, 0);
}
/* ts A70227 : extended meaning of session to address all possible values
of 5Bh CLOSE TRACK SESSION to address any Close Function.
@param session contains the two high bits of Close Function
@param track if not 0: sets the lowest bit of Close Function
*/
void mmc_close(struct burn_drive *d, int session, int track)
{
struct command c;
@ -371,8 +388,8 @@ void mmc_close(struct burn_drive *d, int session, int track)
c.oplen = sizeof(MMC_CLOSE);
memcpy(c.opcode, MMC_CLOSE, sizeof(MMC_CLOSE));
/* (ts A61030 : shifted !!session rather than or-ing plain session ) */
c.opcode[2] = ((session & 3) << 1) | !!track;
/* ts A61030 : shifted !!session rather than or-ing plain session */
c.opcode[2] = ((!!session)<<1) | !!track;
c.opcode[4] = track >> 8;
c.opcode[5] = track & 0xFF;
c.page = NULL;
@ -417,8 +434,14 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
memcpy(c.opcode, MMC_WRITE_12, sizeof(MMC_WRITE_12));
c.retry = 1;
c.oplen = sizeof(MMC_WRITE_12);
mmc_int_to_four_char(c.opcode + 2, start);
mmc_int_to_four_char(c.opcode + 6, len);
c.opcode[2] = start >> 24;
c.opcode[3] = (start >> 16) & 0xFF;
c.opcode[4] = (start >> 8) & 0xFF;
c.opcode[5] = start & 0xFF;
c.opcode[6] = len >> 24;
c.opcode[7] = (len >> 16) & 0xFF;
c.opcode[8] = (len >> 8) & 0xFF;
c.opcode[9] = len & 0xFF;
c.page = buf;
c.dir = TO_DRIVE;
@ -447,21 +470,6 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
if (cancelled)
return BE_CANCELLED;
/* ts A70215 */
if (d->media_lba_limit > 0 && start >= d->media_lba_limit) {
char msg[160];
sprintf(msg,
"Exceeding range of permissible write addresses (%d >= %d)",
start, d->media_lba_limit);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012d,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
d->cancel = 1; /* No need for mutexing because atomic */
return BE_CANCELLED;
}
len = buf->sectors;
/* ts A61009 : buffer fill problems are to be handled by caller */
@ -471,7 +479,10 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
memcpy(c.opcode, MMC_WRITE_10, sizeof(MMC_WRITE_10));
c.retry = 1;
c.oplen = sizeof(MMC_WRITE_10);
mmc_int_to_four_char(c.opcode + 2, start);
c.opcode[2] = start >> 24;
c.opcode[3] = (start >> 16) & 0xFF;
c.opcode[4] = (start >> 8) & 0xFF;
c.opcode[5] = start & 0xFF;
c.opcode[6] = 0;
c.opcode[7] = (len >> 8) & 0xFF;
c.opcode[8] = len & 0xFF;
@ -534,7 +545,8 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->tno = 0;
entry->point = track_number & 0xff;
entry->point_msb = (track_number >> 8) & 0xff;
num = mmc_four_char_to_int(size_data);
num = (size_data[0] << 24) | (size_data[1] << 16) |
(size_data[2] << 8) | size_data[3];
entry->track_blocks = num;
burn_lba_to_msf(num, &min, &sec, &frames);
if (min > 255) {
@ -546,7 +558,8 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
entry->sec = sec;
entry->frame = frames;
entry->zero = 0;
num = mmc_four_char_to_int(start_data);
num = (start_data[0] << 24) | (start_data[1] << 16) |
(start_data[2] << 8) | start_data[3];
entry->start_lba = num;
burn_lba_to_msf(num, &min, &sec, &frames);
if (min > 255) {
@ -571,21 +584,10 @@ int mmc_fake_toc(struct burn_drive *d)
struct buffer buf;
int i, session_number, prev_session = -1, ret, lba;
unsigned char *tdata, size_data[4], start_data[4];
char msg[160];
if (d->last_track_no <= 0 || d->complete_sessions <= 0 ||
d->status == BURN_DISC_BLANK)
return 2;
if (d->last_track_no > BURN_MMC_FAKE_TOC_MAX_SIZE) {
sprintf(msg,
"Too many logical tracks recorded (%d , max. %d)\n",
d->last_track_no, BURN_MMC_FAKE_TOC_MAX_SIZE);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012c,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
return 0;
}
d->disc = burn_disc_create();
if (d->disc == NULL)
return -1;
@ -618,8 +620,10 @@ int mmc_fake_toc(struct burn_drive *d)
*/
for (i = 0; i < d->last_track_no; i++) {
ret = mmc_read_track_info(d, i+1, &buf);
if (ret <= 0)
if (ret < 0)
return ret;
if (ret == 0)
continue;
tdata = buf.data;
session_number = (tdata[33] << 8) | tdata[3];
if (session_number <= 0)
@ -639,16 +643,8 @@ int mmc_fake_toc(struct burn_drive *d)
entry;
}
if (session_number > d->disc->sessions) {
if (i == d->last_track_no - 1) {
/* ts A70212 : Last track field Free Blocks */
d->media_capacity_remaining =
((off_t) mmc_four_char_to_int(tdata + 16)) *
((off_t) 2048);
d->media_lba_limit = 0;
}
if (session_number > d->disc->sessions)
continue;
}
entry = &(d->toc_entry[i + session_number - 1]);
track = burn_track_create();
@ -920,17 +916,13 @@ void mmc_read_disc_info(struct burn_drive *d)
struct command c;
char msg[160];
/* ts A70131 : had to move mmc_read_toc() to end of function */
int do_read_toc = 0, session_state, disc_status;
int do_read_toc = 0, session_state;
/* ts A61020 */
d->start_lba = d->end_lba = -2000000000;
d->erasable = 0;
d->last_track_no = 1;
/* ts A70212 - A70215 */
d->media_capacity_remaining = 0;
d->media_lba_limit = 0;
/* ts A61202 */
d->toc_entries = 0;
if (d->status == BURN_DISC_EMPTY)
@ -956,12 +948,7 @@ void mmc_read_disc_info(struct burn_drive *d)
data = c.page->data;
d->erasable = !!(data[2] & 16);
disc_status = data[2] & 3;
if (d->current_profile == 0x10) { /* DVD-ROM */
disc_status = 2; /* always full and finalized */
d->erasable = 0; /* never erasable */
}
switch (disc_status) {
switch (data[2] & 3) {
case 0:
d->toc_entries = 0;
d->start_lba = burn_msf_to_lba(data[17], data[18], data[19]);
@ -978,8 +965,14 @@ void mmc_read_disc_info(struct burn_drive *d)
case 1:
d->status = BURN_DISC_APPENDABLE;
case 2:
if (disc_status == 2)
if ((data[2] & 3) == 2) {
d->status = BURN_DISC_FULL;
#ifdef Libburn_support_dvd_r_seQ
/* offers no feature 0021h now but might do if blank */
if (d->current_profile == 0x14) /* DVD-RW */
d->current_is_supported_profile = 1;
#endif
}
do_read_toc = 1;
break;
}
@ -1013,15 +1006,6 @@ void mmc_read_disc_info(struct burn_drive *d)
*/
d->bg_format_status = data[7] & 3;
/* Preliminarily declare blank:
ts A61219 : DVD+RW (is not bg_format_status==0 "blank")
ts A61229 : same for DVD-RW Restricted overwrite
ts A70112 : same for DVD-RAM
*/
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12)
d->status = BURN_DISC_BLANK;
if (d->status == BURN_DISC_BLANK) {
d->last_track_no = 1; /* The "incomplete track" */
d->complete_sessions = 0;
@ -1039,6 +1023,15 @@ void mmc_read_disc_info(struct burn_drive *d)
d->last_track_no = (data[11] << 8) | data[6];
}
/* Preliminarily declare blank:
ts A61219 : DVD+RW (is not bg_format_status==0 "blank")
ts A61229 : same for DVD-RW Restricted overwrite
ts A70112 : same for DVD-RAM
*/
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12)
d->status = BURN_DISC_BLANK;
if (do_read_toc)
mmc_read_toc(d);
}
@ -1489,8 +1482,6 @@ void mmc_get_configuration(struct burn_drive *d)
int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1;
unsigned char *descr, *prf, *up_to, *prf_end;
struct command c;
int phys_if_std = 0;
char *phys_name = "";
d->current_profile = 0;
d->current_profile_text[0] = 0;
@ -1512,7 +1503,10 @@ void mmc_get_configuration(struct burn_drive *d)
if (c.error)
return;
len = mmc_four_char_to_int(c.page->data);
len = (c.page->data[0] << 24)
| (c.page->data[1] << 16)
| (c.page->data[2] << 8)
| c.page->data[3];
if (len<8)
return;
@ -1535,14 +1529,7 @@ void mmc_get_configuration(struct burn_drive *d)
d->current_is_supported_profile = 1;
#endif
#ifdef Libburn_support_dvd_r_seQ
if (cp == 0x10 || cp == 0x11 || cp == 0x14) /* DVD-ROM,DVD-R,DVD-RW */
d->current_is_supported_profile = 1;
if (cp == 0x15 && burn_support_untested_profiles) /* DVD-R/DL */
d->current_is_supported_profile = 1;
#endif
#ifdef Libburn_support_dvd_plus_R
if (cp == 0x1b || (cp == 0x2b && burn_support_untested_profiles))
/* DVD+R , DVD+R/DL */
if (cp == 0x11 || cp == 0x14)
d->current_is_supported_profile = 1;
#endif
@ -1621,29 +1608,28 @@ void mmc_get_configuration(struct burn_drive *d)
!!(descr[4] & 2));
#endif /* Libburn_print_feature_descriptorS */
#ifdef Libburn_print_feature_descriptorS
} else if (feature_code == 0x01) {
phys_if_std = (descr[4] << 24) | (descr[5] << 16) |
int pys_if_std = 0;
char *phys_name = "";
pys_if_std = (descr[4] << 24) | (descr[5] << 16) |
(descr[6] << 8) | descr[9];
if (phys_if_std == 1)
if (pys_if_std == 1)
phys_name = "SCSI Family";
else if(phys_if_std == 2)
else if(pys_if_std == 2)
phys_name = "ATAPI";
else if(phys_if_std == 3 || phys_if_std == 4 ||
phys_if_std == 6)
else if(pys_if_std == 3 || pys_if_std == 4 ||
pys_if_std == 6)
phys_name = "IEEE 1394 FireWire";
else if(phys_if_std == 7)
else if(pys_if_std == 7)
phys_name = "Serial ATAPI";
else if(phys_if_std == 8)
else if(pys_if_std == 7)
phys_name = "USB";
d->phys_if_std = phys_if_std;
strcpy(d->phys_if_name, phys_name);
#ifdef Libburn_print_feature_descriptorS
fprintf(stderr,
"LIBBURN_EXPERIMENTAL : Phys. Interface Standard %Xh \"%s\"\n",
phys_if_std, phys_name);
pys_if_std, phys_name);
} else if (feature_code == 0x107) {
@ -1679,12 +1665,10 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
{
struct buffer buf;
int len, type, score, num_descr, max_score = -2000000000, i, sign = 1;
off_t size, num_blocks;
off_t size;
struct command c;
unsigned char *dpt;
/* <<<
char msg[160];
*/
mmc_function_spy("mmc_read_format_capacities");
@ -1720,14 +1704,12 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
+ (dpt[1] << 16) + (dpt[2] << 8) + dpt[3];
d->format_curr_blsas = (dpt[5] << 16) + (dpt[6] << 8) + dpt[7];
/* <<<
sprintf(msg,
"Current/Maximum Capacity Descriptor : type = %d : %.f",
d->format_descr_type, (double) d->format_curr_max_size);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
*/
d->format_curr_max_size *= (off_t) 2048;
@ -1738,8 +1720,9 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
num_descr = (len - 8) / 8;
for (i = 0; i < num_descr; i++) {
dpt = c.page->data + 12 + 8 * i;
num_blocks = mmc_four_char_to_int(dpt);
size = num_blocks * (off_t) 2048;
size = (((off_t) dpt[0]) << 24)
+ (dpt[1] << 16) + (dpt[2] << 8) + dpt[3];
size *= (off_t) 2048;
type = dpt[4] >> 2;
if (i < 32) {
@ -1750,37 +1733,24 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
d->num_format_descr = i + 1;
}
/* <<<
sprintf(msg, "Capacity Descriptor %2.2Xh %.fs = %.1f MB",type,
((double) size)/2048.0, ((double) size)/1024.0/1024.0);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
*/
/* Criterion is proximity to quick intermediate state */
if (type == 0x00) { /* full format (with lead out) */
score = 1 * sign;
if(d->current_profile == 0x12 &&
d->media_capacity_remaining == 0) {
d->media_capacity_remaining = size;
d->media_lba_limit = num_blocks;
}
} else if (type == 0x10) { /* DVD-RW full format */
score = 10 * sign;
} else if(type == 0x13) { /* DVD-RW quick grow last session */
score = 100 * sign;
} else if(type == 0x15) { /* DVD-RW Quick */
score = 50 * sign;
if(d->current_profile == 0x13) {
d->media_capacity_remaining = size;
d->media_lba_limit = num_blocks;
}
} else if(type == 0x26) { /* DVD+RW */
score = 1 * sign;
d->media_capacity_remaining = size;
d->media_lba_limit = num_blocks;
} else {
continue;
}
@ -1793,14 +1763,12 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
}
}
/* <<<
sprintf(msg,
"best_format_type = %2.2Xh , best_format_size = %.f",
d->best_format_type, (double) d->best_format_size);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
*/
return 1;
}
@ -1901,8 +1869,8 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
c.page->data[1] = 0x02; /* Immed */
c.page->data[3] = 8; /* Format descriptor length */
num_of_blocks = size / 2048;
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
for (i = 0; i < 4; i++)
c.page->data[4 + i] = (num_of_blocks >> (24 - 8 * i)) & 0xff;
if (flag & 128) { /* explicitely chosen format descriptor */
/* use case: the app knows what to do */
@ -1932,7 +1900,9 @@ selected_not_suitable:;
if (flag & 4) {
num_of_blocks =
d->format_descriptors[index].size / 2048;
mmc_int_to_four_char(c.page->data + 4, num_of_blocks);
for (i = 0; i < 4; i++)
c.page->data[4 + i] =
(num_of_blocks >> (24 - 8 * i)) & 0xff;
}
if (format_type != 0x26)
for (i = 0; i < 3; i++)
@ -2007,8 +1977,9 @@ selected_not_suitable:;
num_of_blocks = diff;
}
if (num_of_blocks > 0)
mmc_int_to_four_char(c.page->data + 4,
num_of_blocks);
for (i = 0; i < 4; i++)
c.page->data[4 + i] =
(num_of_blocks >> (24 - 8 * i)) & 0xff;
}
/* 6.5.4.2.8 , DVD-RW Quick Grow Last Border */
format_type = 0x13;
@ -2032,8 +2003,9 @@ selected_not_suitable:;
if ((flag & 4)
|| d->best_format_type == full_format_type) {
num_of_blocks = d->best_format_size / 2048;
mmc_int_to_four_char(c.page->data + 4,
num_of_blocks);
for (i = 0; i < 4; i++)
c.page->data[4 + i] =
(num_of_blocks >> (24 - 8 * i)) & 0xff;
}
} else {
@ -2236,16 +2208,11 @@ int mmc_setup_drive(struct burn_drive *d)
d->format_unit = mmc_format_unit;
d->read_format_capacities = mmc_read_format_capacities;
/* ts A70302 */
d->phys_if_std = -1;
d->phys_if_name[0] = 0;
/* ts A61020 */
d->start_lba = -2000000000;
d->end_lba = -2000000000;
/* ts A61201 - A70223*/
/* ts A61201 - A70128 */
d->erasable = 0;
d->current_profile = -1;
d->current_profile_text[0] = 0;
@ -2259,8 +2226,6 @@ int mmc_setup_drive(struct burn_drive *d)
d->num_format_descr = 0;
d->complete_sessions = 0;
d->last_track_no = 1;
d->media_capacity_remaining = 0;
d->media_lba_limit = 0;
return 1;
}
@ -2292,10 +2257,9 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
/* Link size dummy */
pd[5] = 0;
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11 ||
d->current_profile == 0x15)
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11)
&& o->write_type == BURN_WRITE_SAO) {
/* ts A70205 : DVD-R[W][/DL] : Disc-at-once, DAO */
/* ts A70205 : DVD-R[W} : Disc-at-once, DAO */
/* Learned from dvd+rw-tools and mmc5r03c.pdf .
See doc/cookbook.txt for more detailed references. */
@ -2308,9 +2272,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
/* Data Block Type = 8 */
pd[4] = 8;
} else if (d->current_profile == 0x14 || d->current_profile == 0x11 ||
d->current_profile == 0x15) {
/* ts A70128 : DVD-R[W][/DL] Incremental Streaming */
} else if (d->current_profile == 0x14 || d->current_profile == 0x11) {
/* ts A70128 : DVD-R[W] Incremental Streaming */
/* Learned from transport.hxx : page05_setup()
and mmc5r03c.pdf 7.5, 4.2.3.4 Table 17
and spc3r23.pdf 6.8, 7.4.3 */
@ -2342,10 +2305,6 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
/* Packet Size */
pd[13] = 16;
} else if (d->current_profile == 0x1a || d->current_profile == 0x1b ||
d->current_profile == 0x2b || d->current_profile == 0x12) {
/* not with DVD+R[W][/DL] or DVD-RAM */;
return 0;
} else {
/* Traditional setup for CD */

View File

@ -69,7 +69,4 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
unsigned char *pd);
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
#endif /*__MMC*/

View File

@ -36,8 +36,6 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->obs = -1;
opts->obs_pad = 0;
opts->start_byte = -1;
opts->fill_up_media = 0;
opts->force_is_set = 0;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
@ -174,187 +172,92 @@ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
/* ts A70207 API */
/** @param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
*/
enum burn_write_types burn_write_opts_auto_write_type(
struct burn_write_opts *opts, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int flag)
char reasons[1024], int flag)
{
struct burn_multi_caps *caps = NULL;
struct burn_drive *d = opts->drive;
struct burn_disc_mode_demands demands;
enum burn_write_types wt;
int ret, would_do_sao = 0;
int ret;
char *reason_pt;
reasons[0] = 0;
if (d->status != BURN_DISC_BLANK &&
d->status != BURN_DISC_APPENDABLE){
if (d->status == BURN_DISC_FULL)
strcat(reasons, "MEDIA: closed or not recordable, ");
else
strcat(reasons,"MEDIA: no writeable media detected, ");
if (!(flag & 3))
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002013a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"No suitable media detected", 0, 0);
return BURN_WRITE_NONE;
}
ret = burn_disc_get_write_mode_demands(disc, opts, &demands,
!!opts->fill_up_media);
ret = burn_disc_get_write_mode_demands(disc, &demands, 0);
if (ret <= 0) {
strcat(reasons, "cannot recognize job demands, ");
{wt = BURN_WRITE_NONE; goto ex;}
return BURN_WRITE_NONE;
}
if (demands.exotic_track && !d->current_is_cd_profile) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020123,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"DVD Media are unsuitable for desired track type",
0, 0);
if (demands.audio)
strcat(reasons, "audio track prohibited by non-CD, ");
else
strcat(reasons, "exotic track prohibited by non-CD, ");
{wt = BURN_WRITE_NONE; goto ex;}
return BURN_WRITE_NONE;
}
if ((flag & 1) && opts->write_type != BURN_WRITE_SAO)
goto try_tao;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "SAO: ");
if (d->status != BURN_DISC_BLANK) {
strcat(reasons, "write type SAO works only on blank media, ");
goto try_tao;
}
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_SAO, &caps, 0);
if (ret < 0) {
no_caps:;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Cannot inquire write mode capabilities",
0, 0);
strcat(reasons, "cannot inquire write mode capabilities, ");
{wt = BURN_WRITE_NONE; goto ex;}
} else if (ret == 0) {
strcat(reasons, "no SAO offered by drive and media, ");
goto no_sao;
}
if ((opts->multi || demands.multi_session) &&
!caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.will_append)
strcat(reasons, "appended session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.unknown_track_size == 1 &&
(caps->might_do_sao == 1 || caps->might_do_sao == 3))
strcat(reasons, "track size unpredictable, ");
if (demands.mixed_mode)
strcat(reasons, "tracks of different modes mixed, ");
if (demands.exotic_track && !d->current_is_cd_profile)
strcat(reasons, "non-data track on non-cd, ");
else if (d->current_is_cd_profile)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (d->current_is_cd_profile && opts->fill_up_media)
strcat(reasons, "cd sao cannot do media fill up yet, ");
if (strcmp(reason_pt, "SAO: ") != 0)
goto no_sao;
would_do_sao = 1;
if (demands.unknown_track_size == 2 && (!(flag & 1)) &&
(caps->might_do_sao == 1 || caps->might_do_sao == 3)) {
strcat(reasons, "would have to use default track sizes, ");
goto no_sao;
} else if (caps->might_do_sao >= 3 && !(flag & 1))
goto try_tao;
do_sao:;
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_SAO, BURN_BLOCK_SAO);
{wt = BURN_WRITE_SAO; goto ex;}
return BURN_WRITE_NONE;
} if (ret > 0) {
reason_pt = reasons + strlen(reasons);
strcat(reasons, "SAO: ");
if ((opts->multi || demands.multi_session) &&
!caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.unknown_track_size)
strcat(reasons, "track size unpredictable, ");
if (demands.mixed_mode)
strcat(reasons, "tracks of different modes mixed, ");
if (strcmp(reason_pt, "SAO: ") != 0)
goto no_sao;
burn_write_opts_set_write_type(opts,
BURN_WRITE_SAO, BURN_BLOCK_SAO);
return BURN_WRITE_SAO;
} else
strcat(reasons, "SAO: no SAO offered by drive and media, ");
no_sao:;
try_tao:;
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
goto try_raw;
burn_disc_free_multi_caps(&caps);
strcat(reasons, "\n");
reason_pt = reasons + strlen(reasons);
strcat(reasons, "TAO: ");
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0);
if (ret < 0)
goto no_caps;
if (ret == 0) {
strcat(reasons, "no TAO offered by drive and media, ");
goto no_tao;
}
if ((opts->multi || demands.multi_session) && !caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.exotic_track && !d->current_is_cd_profile)
strcat(reasons, "non-data track on non-cd, ");
if (d->current_is_cd_profile && !opts->force_is_set)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "TAO: ") != 0)
goto no_tao;
/* ( TAO data/audio block size will be handled automatically ) */
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1);
{wt = BURN_WRITE_TAO; goto ex;}
no_tao:;
if (would_do_sao && !(flag & 1))
goto do_sao;
if (!d->current_is_cd_profile)
goto no_write_mode;
try_raw:;
if ((flag & 1) && opts->write_type != BURN_WRITE_RAW)
goto no_write_mode;
if (!(flag & 1)) /* For now: no automatic raw write modes */
goto no_write_mode;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "RAW: ");
if (!d->current_is_cd_profile)
strcat(reasons, "write type RAW prohibited by non-cd, ");
else if (d->status != BURN_DISC_BLANK)
strcat(reasons, "write type RAW works only on blank media, ");
else if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "RAW: ") != 0)
goto no_write_mode;
/* For now: no setting of raw write modes */
{wt = BURN_WRITE_RAW; goto ex;}
no_write_mode:;
wt = BURN_WRITE_NONE;
ex:;
burn_disc_free_multi_caps(&caps);
if (wt == BURN_WRITE_NONE && !(flag & 3)) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012b,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive offers no suitable write mode with this job",
0, 0);
return BURN_WRITE_NONE;
}
return wt;
}
/* ts A70213 : new API function */
void burn_write_opts_set_fillup(struct burn_write_opts *opts,int fill_up_media)
{
opts->fill_up_media = !!fill_up_media;
return;
}
/* ts A70303: API */
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
{
opts->force_is_set = !!use_force;
if ((opts->multi || demands.multi_session) && !caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (strcmp(reason_pt, "TAO: ") != 0)
goto no_write_mode;
/* ( TAO data/audio block size will be handled automatically ) */
burn_write_opts_set_write_type(opts,
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
return BURN_WRITE_TAO;
}

View File

@ -41,14 +41,6 @@ struct burn_write_opts
/* ts A61222 : Start address for media which allow a choice */
off_t start_byte;
/* ts A70213 : Wether to fill up the available space on media */
int fill_up_media;
/* ts A70303 : Wether to override conformance checks:
- the check wether CD write+block type is supported by the drive
*/
int force_is_set;
/** A disc can have a media catalog number */
int has_mediacatalog;
unsigned char mediacatalog[13];

View File

@ -318,7 +318,7 @@ void spc_sense_write_params(struct burn_drive *d)
{
struct buffer buf;
struct scsi_mode_data *m;
int size, dummy;
int size;
unsigned char *page;
struct command c;
@ -343,35 +343,26 @@ void spc_sense_write_params(struct burn_drive *d)
m->write_page_length = page[1];
m->write_page_valid = 1;
mmc_read_disc_info(d);
/* ts A70212 : try to setup d->media_capacity_remaining */
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12)
d->read_format_capacities(d, -1);
else if (d->status == BURN_DISC_BLANK ||
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
d->get_nwa(d, -1, &dummy, &dummy);
}
/* others are hopefully up to date from mmc_read_disc_info() */
/*
fprintf(stderr, "LIBBURN_DEBUG: media_capacity_remaining = %.f\n",
(double) d->media_capacity_remaining);
*/
}
/* ts A61229 */
#define Libburn_mmc_compose_mode_page_5 1
/* remark ts A61104 :
Although command MODE SELECT is SPC, the content of the
Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1).
Thus the filling of the mode page is done by mmc_compose_mode_page_5().
Thus the filling of the mode page should be done by a mmc_ function.
*/
void spc_select_write_params(struct burn_drive *d,
const struct burn_write_opts *o)
{
struct buffer buf;
struct command c;
#ifndef Libburn_mmc_compose_mode_page_5
int bufe, sim;
#endif
/* ts A61007 : All current callers are safe. */
/* a ssert(o->drive == d); */
@ -400,10 +391,40 @@ void spc_select_write_params(struct burn_drive *d,
burn_print(12, "using write page length %d (valid %d)\n",
d->mdata->write_page_length, d->mdata->write_page_valid);
#ifdef Libburn_mmc_compose_mode_page_5
/* ts A61229 */
if (mmc_compose_mode_page_5(d, o, c.page->data + 8) <= 0)
return;
#else
c.page->data[8] = 5;
c.page->data[9] = d->mdata->write_page_length;
bufe = o->underrun_proof;
sim = o->simulate;
c.page->data[10] = (bufe << 6)
+ (sim << 4)
+ o->write_type;
/* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */
c.page->data[11] = ((3 * !!o->multi) << 6) | o->control;
c.page->data[12] = spc_block_type(o->block_type);
/* ts A61104 */
if(!(o->control&4)) /* audio (MMC-1 table 61) */
if(o->write_type == BURN_WRITE_TAO) /* ??? for others too ? */
c.page->data[12] = 0; /* Data Block Type: Raw Data */
c.page->data[22] = 0;
c.page->data[23] = 150; /* audio pause length */
/*XXX need session format! */
#endif /* ! Libburn_mmc_compose_mode_page_5 */
c.dir = TO_DRIVE;
d->issue_command(d, &c);
}
@ -413,9 +434,16 @@ void spc_getcaps(struct burn_drive *d)
spc_inquiry(d);
spc_sense_caps(d);
spc_sense_error_params(d);
/* <<< for debugging. >>> ??? to be fixely included here ?
mmc_read_format_capacities(d, -1);
*/
}
/*
only called when a blank is present, so we set type to blank
(on the last pass)
don't check totally stupid modes (raw/raw0)
some drives say they're ok, and they're not.
*/
@ -425,24 +453,12 @@ void spc_probe_write_modes(struct burn_drive *d)
struct buffer buf;
int try_write_type = 1;
int try_block_type = 0;
int key, asc, ascq, useable_write_type = -1, useable_block_type = -1;
int last_try = 0;
int key, asc, ascq;
struct command c;
/* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */
while (try_write_type != 5) {
while (try_write_type != 4) {
burn_print(9, "trying %d, %d\n", try_write_type,
try_block_type);
/* ts A70213 */
if (try_write_type == 4) {
/* Pseudo write type NONE . Set a useable write mode */
if (useable_write_type == -1)
break;
try_write_type = useable_write_type;
try_block_type = useable_block_type;
last_try= 1;
}
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c.retry = 1;
c.oplen = sizeof(SPC_MODE_SELECT);
@ -467,9 +483,6 @@ void spc_probe_write_modes(struct burn_drive *d)
d->issue_command(d, &c);
d->silent_on_scsi_error = 0;
if (last_try)
break;
key = c.sense[2];
asc = c.sense[12];
ascq = c.sense[13];
@ -485,15 +498,6 @@ void spc_probe_write_modes(struct burn_drive *d)
else
d->block_types[try_write_type] |=
1 << try_block_type;
/* ts A70213 */
if ((useable_write_type < 0 && try_write_type > 0) ||
(try_write_type == 1 && try_block_type == 8)) {
/* Packet is not supported yet.
Prefer TAO MODE_1. */
useable_write_type = try_write_type;
useable_block_type = try_block_type;
}
}
switch (try_block_type) {
case 0:

View File

@ -113,12 +113,6 @@ struct burn_track *burn_track_create(void)
t->mode = BURN_MODE1;
t->isrc.has_isrc = 0;
t->pad = 1;
/* ts A70213 */
t->fill_up_media = 0;
/* ts A70218 */
t->default_size = 0;
t->entry = NULL;
t->source = NULL;
t->eos = 0;
@ -348,50 +342,6 @@ int burn_track_set_sectors(struct burn_track *t, int sectors)
if (size < 0)
return 0;
ret = t->source->set_size(t->source, size);
t->open_ended = (t->source->get_size(t->source) <= 0);
return ret;
}
/* ts A70218 */
int burn_track_set_size(struct burn_track *t, off_t size)
{
t->open_ended = (size <= 0);
return t->source->set_size(t->source, size);
}
/* ts A70213 */
int burn_track_set_fillup(struct burn_track *t, int fill_up_media)
{
t->fill_up_media = fill_up_media;
if (fill_up_media)
t->open_ended = 0;
return 1;
}
/* ts A70213 */
/**
@param flag bit0= force new size even if existing track size is larger
*/
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag)
{
int max_sectors, ret = 2;
char msg[160];
if (t->fill_up_media <= 0)
return 2;
max_sectors = max_size / 2048;
if (burn_track_get_sectors(t) < max_sectors || (flag & 1)) {
sprintf(msg, "Setting total track size to %ds (payload %ds)\n",
max_sectors, (int) (t->source->get_size(t->source)/2048));
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
ret = burn_track_set_sectors(t, max_sectors);
t->open_ended = 0;
}
return ret;
}
@ -402,22 +352,6 @@ int burn_track_is_open_ended(struct burn_track *t)
return !!t->open_ended;
}
/* ts A70218 : API */
int burn_track_set_default_size(struct burn_track *t, off_t size)
{
t->default_size = size;
return 1;
}
/* ts A70218 */
off_t burn_track_get_default_size(struct burn_track *t)
{
return t->default_size;
}
/* ts A61101 : API function */
int burn_track_get_counters(struct burn_track *t,
off_t *read_bytes, off_t *written_bytes)

View File

@ -27,13 +27,6 @@ struct burn_track
int tailcount;
/** 1 means Pad with zeros, 0 means start reading the next track */
int pad;
/* ts A70213 : wether to expand this track to full available media */
int fill_up_media;
/* ts A70218 : a track size to use if it is mandarory to have some */
off_t default_size;
/** Data source */
struct burn_source *source;
/** End of Source flag */
@ -95,18 +88,8 @@ int burn_track_get_shortage(struct burn_track *t);
int burn_track_is_open_ended(struct burn_track *t);
int burn_track_is_data_done(struct burn_track *t);
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
/* ts A70125 */
int burn_track_set_sectors(struct burn_track *t, int sectors);
/* ts A70218 : sets the payload size alone */
int burn_track_set_size(struct burn_track *t, off_t size);
/* ts A70213 */
int burn_track_set_fillup(struct burn_track *t, int fill_up_media);
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag);
/* ts A70218 */
off_t burn_track_get_default_size(struct burn_track *t);
#endif /* BURN__STRUCTURE_H */

View File

@ -129,9 +129,6 @@ struct burn_drive
int lun;
char *devname;
/* ts A70302: mmc5r03c.pdf 5.3.2 Physical Interface Standard */
int phys_if_std; /* 1=SCSI, 2=ATAPI, 3,4,6=FireWire, 7=SATA, 8=USB */
char phys_if_name[80]; /* MMC-5 5.3.2 table 91 , e.g. "SCSI Family" */
/* see os.h for name of particular os-*.h where this is defined */
BURN_OS_TRANSPORT_DRIVE_ELEMENTS
@ -209,14 +206,6 @@ struct burn_drive
/* ts A70129 :
from 51h READ DISC INFORMATION Last Track Number in Last Session */
int last_track_no;
/* ts A70212 : from various sources : free space on media (in bytes)
With CD this might change after particular write
parameters have been set and nwa has been inquired.
(e.g. by d->send_write_parameters() ; d->get_nwa()).
*/
off_t media_capacity_remaining;
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
int media_lba_limit;
int toc_temp;

View File

@ -37,7 +37,6 @@
#include "sg.h"
#include "write.h"
#include "options.h"
#include "structure.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -461,7 +460,7 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
track length.
*/
track_length = burn_track_get_sectors(tar[i]);
if (track_length < 300 && !burn_track_is_open_ended(tar[i])) {
if (track_length < 300) {
track_length = 300;
if (!tar[i]->pad)
tar[i]->pad = 1;
@ -707,21 +706,14 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
/* ts A61103 */
ret = d->get_nwa(d, -1, &lba, &nwa);
/* ts A70213: CD-TAO: eventually expand size of track to max */
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
/* <<< */
sprintf(msg,
"TAO pre-track %2.2d : get_nwa(%d)=%d, d=%d , demand=%.f , cap=%.f\n",
tnum+1, nwa, ret, d->nwa, (double) burn_track_get_sectors(t) * 2048.0,
(double) d->media_capacity_remaining);
"pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d\n",
tnum+1, nwa, ret, d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
msg,0,0);
if (nwa > d->nwa)
d->nwa = nwa;
}
/* user data */
@ -820,9 +812,7 @@ ex:;
}
/* ts A61009 */
/* @param flag bit1 = do not libdax_msgs_submit() */
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc,
int flag)
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc)
{
int i, t;
char msg[80];
@ -836,10 +826,9 @@ int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc,
bad_track_mode_found:;
sprintf(msg, "Unsuitable track mode 0x%x in track %d of session %d",
disc->session[i]->track[t]->mode, i+1, t+1);
if (!(flag & 2))
libdax_msgs_submit(libdax_messenger, -1, 0x0002010a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
libdax_msgs_submit(libdax_messenger, -1, 0x0002010a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
@ -849,8 +838,6 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
struct burn_disc *disc)
{
struct burn_drive *d = o->drive;
struct burn_track *t = NULL;
int sx, tx;
d->cancel = 0;
@ -875,99 +862,12 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
d->progress.buffered_bytes = 0;
d->progress.buffer_min_fill = 0xffffffff;
/* Set eventual media fill up for last track only */
for (sx = 0; sx < disc->sessions; sx++)
for (tx = 0 ; tx < disc->session[sx]->tracks; tx++) {
t = disc->session[sx]->track[tx];
burn_track_set_fillup(t, 0);
}
if (o->fill_up_media && t != NULL)
burn_track_set_fillup(t, 1);
d->busy = BURN_DRIVE_WRITING;
return 1;
}
/* ts A70219 : API */
int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int silent)
{
enum burn_write_types wt;
struct burn_drive *d = o->drive;
char msg[160], *reason_pt;
int no_media = 0;
reason_pt= reasons;
reasons[0] = 0;
/* check write mode against write job */
wt = burn_write_opts_auto_write_type(o, disc, reasons, 1);
if (wt == BURN_WRITE_NONE) {
if (strncmp(reasons, "MEDIA: ", 7)==0)
no_media = 1;
goto ex;
}
sprintf(reasons, "%s: ", d->current_profile_text);
reason_pt= reasons + strlen(reasons);
if (d->status == BURN_DISC_UNSUITABLE)
goto unsuitable_profile;
if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
if (!burn_disc_write_is_ok(o, disc, (!!silent) << 1))
strcat(reasons, "unsuitable track mode found, ");
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else if (d->current_profile == 0x1a || d->current_profile == 0x12) {
/* DVD+RW , DVD-RAM */
if (o->start_byte >= 0 && (o->start_byte % 2048))
strcat(reasons,
"write start address not properly aligned to 2048, ");
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
if (o->start_byte >= 0 && (o->start_byte % 32768))
strcat(reasons,
"write start address not properly aligned to 32k, ");
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15 ||
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
/* DVD-R* Sequential , DVD+R[/DL] */
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else {
unsuitable_profile:;
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);
if (!silent)
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
strcat(reasons, "no suitable media profile detected, ");
return 0;
}
ex:;
if (reason_pt[0]) {
if (no_media) {
if (!silent)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002013a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"No suitable media detected", 0, 0);
return -1;
}
if (!silent)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Write job parameters are unsuitable", 0, 0);
return 0;
}
return 1;
}
/* ts A70129 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */
int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
@ -986,8 +886,6 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
if (nwa > d->nwa)
d->nwa = nwa;
/* ts A70214 : eventually adjust already expanded size of track */
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
/* Round track size up to 32 KiB and reserve track */
@ -1001,48 +899,7 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020138,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
}
return 1;
}
/* ts A70226 */
int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
{
struct burn_drive *d = o->drive;
char msg[160];
int ret, lba, nwa;
off_t size;
ret = d->get_nwa(d, -1, &lba, &nwa);
sprintf(msg,
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
tnum+1, nwa, ret, d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
if (nwa > d->nwa)
d->nwa = nwa;
/* ts A70214 : eventually adjust already expanded size of track */
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
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 */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
* (off_t) 2048;
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
ret = d->reserve_track(d, size);
if (ret <= 0) {
sprintf(msg, "Cannot reserve track of %.f bytes",
(double) size);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020138,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
return 0;
}
}
@ -1075,32 +932,6 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
}
/* ts A70226 */
int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum)
{
struct burn_drive *d = o->drive;
char msg[80];
sprintf(msg,
"Closing track %2.2d (absolute track and session number %d)",
tnum + 1, d->last_track_no);
libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
d->busy = BURN_DRIVE_CLOSING_SESSION;
d->close_track_session(d, 0, d->last_track_no); /* CLOSE TRACK, 001b */
/* Each session becomes a single logical track. So to distinguish them,
it is mandatory to close the session together with each track. */
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
d->busy = BURN_DRIVE_WRITING;
d->last_track_no++;
return 1;
}
/* ts A61218 - A70129 */
int burn_dvd_write_track(struct burn_write_opts *o,
struct burn_session *s, int tnum)
@ -1111,41 +942,16 @@ int burn_dvd_write_track(struct burn_write_opts *o,
int sectors;
int i, open_ended = 0, ret= 0, is_flushed = 0;
/* ts A70213 : eventually expand size of track to max */
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
sectors = burn_track_get_sectors(t);
open_ended = burn_track_is_open_ended(t);
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */
if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R, DVD-RW Sequential */
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
if (ret <= 0)
goto ex;
} 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);
if (ret <= 0)
goto ex;
}
sectors = burn_track_get_sectors(t);
open_ended = burn_track_is_open_ended(t);
/* <<< */
{
char msg[160];
sprintf(msg,
"DVD pre-track %2.2d : demand=%.f%s, cap=%.f\n",
tnum+1, (double) sectors * 2048.0,
(open_ended ? " (open ended)" : ""),
(double) d->media_capacity_remaining);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
}
/* >>> ts A70215 : what about offset padding ? */
burn_disc_init_track_status(o, s, tnum, sectors);
for (i = 0; open_ended || i < sectors; i++) {
@ -1167,8 +973,6 @@ int burn_dvd_write_track(struct burn_write_opts *o,
d->progress.sector++;
}
/* >>> ts A70215 : what about tail padding ? */
/* Pad up buffer to next full o->obs (usually 32 kB) */
if (o->obs_pad && out->bytes > 0 && out->bytes < o->obs) {
memset(out->data + out->bytes, 0, o->obs - out->bytes);
@ -1181,16 +985,10 @@ int burn_dvd_write_track(struct burn_write_opts *o,
is_flushed = 1;
/* Eventually finalize track */
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */
if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R, DVD-RW Sequential */
ret = burn_disc_close_track_dvd_minus_r(o, s, tnum);
if (ret <= 0)
goto ex;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
ret = burn_disc_close_track_dvd_plus_r(o, s, tnum);
if (ret <= 0)
if (ret != 2)
goto ex;
}
ret = 1;
@ -1240,7 +1038,7 @@ int burn_disc_close_session_dvd_minus_rw(struct burn_write_opts *o,
}
/* ts A70129 : for profile 0x11 DVD-R, 0x14 DVD-RW Seq, 0x15 DVD-R/DL Seq */
/* ts A70129 : for profile 0x11 DVD-R and 0x14 DVD-RW Sequential */
int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o,
struct burn_session *s)
{
@ -1250,11 +1048,6 @@ int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o,
if (o->write_type != BURN_WRITE_TAO)
return 2;
#ifdef Libburn_dvd_r_dl_multi_no_close_sessioN
if (d->current_profile == 0x15 && o->multi)
return 2;
#endif
libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Closing session", 0, 0);
@ -1280,9 +1073,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
if (ret <= 0)
break;
}
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
if ((d->current_profile == 0x11 || d->current_profile == 0x14)) {
/* DVD-R , DVD-RW Sequential */
ret = burn_disc_close_session_dvd_minus_r(o, s);
if (ret <= 0)
return 0;
@ -1303,8 +1095,6 @@ int burn_dvd_write_session(struct burn_write_opts *o,
if (ret <= 0)
return 0;
}
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL do each track as an own session */;
}
return 1;
}
@ -1335,7 +1125,7 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020127,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
}
/* >>> perform OPC if needed */;
@ -1362,37 +1152,47 @@ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020127,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
d->nwa *= 16; /* convert to 2048 block units */
}
if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */
/* ??? mmc5r03c.pdf 7.5.2 :
"For DVD-RW media ... If a medium is in Restricted overwrite
mode, this mode page shall not be used."
/* ??? mmc5r03c.pdf 7.5.2 :
"For DVD-RW media ... If a medium is in Restricted overwrite
mode, this mode page shall not be used."
But growisofs composes a page 5 and sends it.
mmc5r03c.pdf 5.3.16 , table 127 specifies that mode page 5
shall be supported with feature 0026h Restricted Overwrite.
5.3.22 describes a feature 002Ch Rigid Restrictive Overwrite
which seems to apply to DVD-RW and does not mention page 5.
But growisofs composes a page 5 and sends it.
mmc5r03c.pdf 5.3.16 , table 127 specifies that mode page 5
shall be supported with feature 0026h Restricted Overwrite.
5.3.22 describes a feature 002Ch Rigid Restrictive Overwrite
which seems to apply to DVD-RW and does not mention page 5.
5.4.14 finally states that profile 0013h includes feature
002Ch rather than 0026h.
5.4.14 finally states that profile 0013h includes feature
002Ch rather than 0026h.
d->send_write_parameters(d, o);
*/
*/
d->busy = BURN_DRIVE_FORMATTING;
d->busy = BURN_DRIVE_FORMATTING;
/* "quick grow" to at least byte equivalent of d->nwa */
ret = d->format_unit(d, (off_t) d->nwa * (off_t) 2048,
(d->nwa > 0) << 3);
if (ret <= 0)
/* "quick grow" to at least byte equivalent of d->nwa */
ret = d->format_unit(d, (off_t) d->nwa * (off_t) 2048,
(d->nwa > 0) << 3);
if (ret <= 0)
return 0;
d->busy = BURN_DRIVE_WRITING;
} else {
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
return 0;
d->busy = BURN_DRIVE_WRITING;
}
/* >>> perform OPC if needed */;
@ -1415,55 +1215,15 @@ int burn_disc_setup_dvd_minus_r(struct burn_write_opts *o,
}
/* ts A70226 : for DVD+R , DVD+R/DL */
int burn_disc_setup_dvd_plus_r(struct burn_write_opts *o,
struct burn_disc *disc)
{
struct burn_drive *d = o->drive;
/* most setup is in burn_disc_setup_track_dvd_plus_r() */;
d->nwa = 0;
return 1;
}
/* ts A70229 */
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
{
struct burn_drive *d = o->drive;
/* <<< FOR NOW: avoid finalizing media */
return 3;
if (o->multi)
return 2;
d->busy = BURN_DRIVE_CLOSING_SESSION;
/* CLOSE SESSION, 101b, Finalize with minimal radius */
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
d->busy = BURN_DRIVE_WRITING;
return 1;
}
/* ts A61218 - A70129 */
int burn_dvd_write_sync(struct burn_write_opts *o,
struct burn_disc *disc)
{
int i, ret, o_end;
off_t default_size = 0;
int i, ret, sx, tx, mode, exotic_track = 0, dao_is_ok;
struct burn_drive *d = o->drive;
struct burn_track *t;
char msg[160];
#ifndef Libburn_precheck_write_ruleS
int exotic_track = 0, dao_is_ok, sx, tx, mode;
#endif
d->needs_close_session = 0;
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
for (sx = 0; sx < disc->sessions; sx++)
for (tx = 0 ; tx < disc->session[sx]->tracks; tx++) {
mode = disc->session[sx]->track[tx]->mode;
@ -1475,11 +1235,10 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020123,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
/* <<< covered by burn_precheck_write() */
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12) {
/* DVD+RW , DVD-RW Restricted Overwrite , DVD-RAM */
@ -1491,28 +1250,21 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011f,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
}
#endif /* ! Libburn_precheck_write_ruleS */
if (d->current_profile == 0x1a || d->current_profile == 0x12) {
/* DVD+RW , DVD-RAM */
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
if (o->start_byte >= 0 && (o->start_byte % 2048)) {
sprintf(msg,
"Write start address not properly aligned to 2048");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020125,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
#endif /* ! Libburn_precheck_write_ruleS */
ret = 1;
if (d->current_profile == 0x1a)
ret = burn_disc_setup_dvd_plus_rw(o, disc);
@ -1522,27 +1274,22 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
o->obs_pad = 0; /* no filling-up of track's last 32k buffer */
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
if (o->start_byte >= 0 && (o->start_byte % 32768)) {
sprintf(msg,
"Write start address not properly aligned to 32K");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020125,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
#endif /* ! Libburn_precheck_write_ruleS */
ret = burn_disc_setup_dvd_minus_rw(o, disc);
if (ret <= 0) {
sprintf(msg,
@ -1550,31 +1297,24 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
/* _Rigid_ Restricted Overwrite demands this */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , DVD-RW Sequential , DVD-R/DL Sequential */
t = disc->session[0]->track[0];
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
default_size = burn_track_get_default_size(t);
#ifndef Libburn_precheck_write_ruleS
} else if (d->current_profile == 0x11 || d->current_profile == 0x14) {
/* DVD-R , DVD-RW Sequential */
dao_is_ok =
(disc->sessions == 1 &&
disc->session[0]->tracks == 1 &&
(default_size > 0 || !o_end) &&
(! burn_track_is_open_ended(
disc->session[0]->track[0])) &&
(!o->multi) && d->status == BURN_DISC_BLANK
);
if (o->write_type == BURN_WRITE_TAO &&
!d->current_has_feat21h) {
/* <<< ??? keep this automatic write type change ? */
if (dao_is_ok) {
o->write_type = BURN_WRITE_SAO;
libdax_msgs_submit(libdax_messenger,
@ -1582,8 +1322,6 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Defaulted TAO to DAO (lack of feature 21h)",
0, 0);
/* <<< covered by burn_precheck_write() */
} else {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020135,
@ -1592,49 +1330,29 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
0, 0);
goto early_failure;
}
} else if (o->write_type == BURN_WRITE_SAO && !dao_is_ok) {
/* <<< covered by burn_precheck_write() */
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020136,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"DAO burning is restricted to a single fixed size track and no multi-session",
0, 0);
/* <<< ??? keep this automatic advise ? */
0,0);
if (d->current_has_feat21h)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020137,
LIBDAX_MSGS_SEV_HINT,
LIBDAX_MSGS_PRIO_HIGH,
"TAO would be possible and could do the job",
0, 0);
0,0);
goto early_failure;
}
/* <<< covered by burn_precheck_write() */
if (o->start_byte >= 0) {
sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020124,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
#endif /* ! Libburn_precheck_write_ruleS */
if (o->write_type == BURN_WRITE_SAO && o_end) {
sprintf(msg, "Activated track default size %.f",
(double) default_size);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002012e,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
burn_track_set_size(t, default_size);
}
ret = burn_disc_setup_dvd_minus_r(o, disc);
if (ret <= 0) {
sprintf(msg,
@ -1642,56 +1360,20 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
}
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
t = disc->session[0]->track[0];
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
default_size = burn_track_get_default_size(t);
#ifndef Libburn_precheck_write_ruleS
/* >>> oldfashioned checks hopefully never re-enabled */
#endif /* ! Libburn_precheck_write_ruleS */
if (o->write_type == BURN_WRITE_SAO && o_end) {
sprintf(msg, "Activated track default size %.f",
(double) default_size);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002012e,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
burn_track_set_size(t, default_size);
}
ret = burn_disc_setup_dvd_plus_r(o, disc);
if (ret <= 0) {
sprintf(msg,
"Write preparation setup failed for DVD+R");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto early_failure;
}
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
} else {
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
d->current_profile, d->current_profile_text);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto early_failure;
#endif /* ! Libburn_precheck_write_ruleS */
}
o->obs = 32*1024; /* buffer flush trigger for sector.c:get_sector() */
@ -1710,11 +1392,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
d->progress.sectors = 0;
}
if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
ret = burn_disc_finalize_dvd_plus_r(o);
if (ret <= 0)
goto ex;
}
/* >>> eventual normal finalization measures */
ret = 1;
ex:;
@ -1736,9 +1415,8 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
struct cue_sheet *sheet;
struct burn_drive *d = o->drive;
struct buffer buf;
struct burn_track *lt, *t;
struct burn_track *lt;
int first = 1, i, ret, lba, nwa = 0;
off_t default_size;
char msg[80];
/* ts A60924 : libburn/message.c gets obsoleted
@ -1761,56 +1439,14 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
return;
}
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
if (o->start_byte >= 0) {
sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020124,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
msg, 0,0);
goto fail_wo_sync;
}
#endif /* ! Libburn_precheck_write_ruleS */
/* ts A70218 */
if (o->write_type == BURN_WRITE_SAO) {
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() "appended session" */
if (disc->sessions > 1) {
sao_restriction_violated:;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012f,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"SAO is restricted to a single session with fixed track sizes",
0, 0);
goto fail_wo_sync;
}
#endif /* ! Libburn_precheck_write_ruleS */
for (i = 0 ; i < disc->session[0]->tracks; i++) {
t = disc->session[0]->track[i];
if (burn_track_is_open_ended(t)) {
default_size = burn_track_get_default_size(t);
#ifndef Libburn_precheck_write_ruleS
/* <<< covered by burn_precheck_write() */
if (default_size <= 0)
goto sao_restriction_violated;
#endif /* ! Libburn_precheck_write_ruleS */
sprintf(msg,
"Activated track default size %.f",
(double) default_size);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002012e,
LIBDAX_MSGS_SEV_NOTE,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
burn_track_set_size(t, default_size);
}
}
}
burn_print(1, "sync write of %d CD sessions\n", disc->sessions);
@ -1828,16 +1464,11 @@ return crap. so we send the command, then ignore the result.
d->send_write_parameters(d, o);
ret = d->get_nwa(d, -1, &lba, &nwa);
sprintf(msg,
"SAO|RAW: Inquired nwa: %d , ret= %d , cap=%.f\n",
nwa, ret, (double) d->media_capacity_remaining);
sprintf(msg, "Inquired nwa: %d (ret=%d)", nwa, ret);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg,0, 0);
/* >>> ts A70212 : CD-DAO/SAO : eventually expand size of last track to maximum */;
msg,0,0);
}
for (i = 0; i < disc->sessions; i++) {
@ -1881,7 +1512,7 @@ return crap. so we send the command, then ignore the result.
libdax_msgs_submit(
libdax_messenger, d->global_index, 0x000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0);
msg,0,0);
} else {
d->nwa = -150;

View File

@ -15,8 +15,7 @@ int burn_sector_length(int trackmode);
int burn_subcode_length(int trackmode);
/* ts A61009 */
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc,
int flag);
int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc);
void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc);
int burn_write_leadin(struct burn_write_opts *o,
@ -33,16 +32,4 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
int tnum);
int burn_write_close_session(struct burn_write_opts *o,struct burn_session *s);
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session
"When the recording mode is Incremental Recording,
the disc is single session."
Enable this macro to get away from growisofs which uses Close Session
but also states "// DVD-R DL Seq has no notion of multi-session".
#define Libburn_dvd_r_dl_multi_no_close_sessioN 1
*/
#endif /* BURN__WRITE_H */

View File

@ -9,7 +9,7 @@
libburner is a minimal demo application for the library libburn as provided
on http://libburnia.pykix.org . It can list the available devices, can
blank a CD-RW or DVD-RW, can format a DVD-RW, and can burn to CD-R, CD-RW,
DVD+RW, DVD-RAM or DVD-RW. Not supported yet: DVD+R [DL].
DVD+RW, DVD-RAM or DVD-RW. Not tested: DVD-R. Not supported yet: DVD+R [DL].
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburnia team as reference application. libburner.c does indeed
@ -276,7 +276,7 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
return 2;
} else if (disc_state == BURN_DISC_FULL ||
disc_state == BURN_DISC_APPENDABLE) {
; /* this is what libburner is willing to blank */
; /* this is what libburn is willing to blank */
} else if (disc_state == BURN_DISC_EMPTY) {
fprintf(stderr,"FATAL: No media detected in drive\n");
return 0;
@ -306,9 +306,8 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
}
/** Persistently changes DVD-RW profile 0014h "Sequential Recording" to
profile 0013h "Restricted Overwrite" which needs no blanking for re-use
but is not capable of multi-session.
/** Persistently changes DVD-RW profile 0014h "Sequential Recording"
to profile 0013h "Restricted Overwrite" which is usable with libburner.
Expect a behavior similar to blanking with unusual noises from the drive.
*/
@ -373,7 +372,7 @@ int libburner_payload(struct burn_drive *drive,
time_t start_time;
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
off_t fixed_size;
char *adr, reasons[BURN_REASONS_LEN];
char *adr, reasons[1024];
struct stat stbuf;
if (all_tracks_type != BURN_AUDIO) {
@ -503,6 +502,8 @@ static int all_tracks_type = BURN_MODE1;
/** Converts command line arguments into above setup parameters.
drive_adr[] must provide at least BURN_DRIVE_ADR_LEN bytes.
source_adr[] must provide at least 4096 bytes.
*/
int libburner_setup(int argc, char **argv)
{

View File

@ -200,11 +200,11 @@ int telltoc_aquire_by_driveno(int *driveno, int silent_drive)
}
/** This gesture is necessary to get my NEC DVD_RW ND-4570A out of a state
of noisy overexcitement after its tray was loaded and it then was inquired
for Next Writeable Address.
of noisy overexcitement after it was inquired for Next Writeable Address.
The noise then still lasts 20 seconds. Same with cdrecord -toc, btw.
This opens a small gap for losing the drive to another libburn instance.
It opens a small gap for losing the drive to another libburn instance.
Not a problem in telltoc. This is done as very last drive operation.
Eventually the other libburn instance will have the same sanitizing effect.
*/
@ -226,11 +226,9 @@ int telltoc_media(struct burn_drive *drive)
{
int ret, media_found = 0, profile_no = -1;
double max_speed = 0.0, min_speed = 0.0, speed_conv;
off_t available = 0;
enum burn_disc_status s;
char profile_name[80], speed_unit[40];
struct burn_multi_caps *caps;
struct burn_write_opts *o = NULL;
printf("Media current: ");
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
@ -253,16 +251,16 @@ int telltoc_media(struct burn_drive *drive)
printf("Media status : ");
s = burn_disc_get_status(drive);
if (s == BURN_DISC_FULL) {
if (s==BURN_DISC_FULL) {
printf("is written , is closed\n");
media_found = 1;
} else if (s == BURN_DISC_APPENDABLE) {
} else if (s==BURN_DISC_APPENDABLE) {
printf("is written , is appendable\n");
media_found = 1;
} else if (s == BURN_DISC_BLANK) {
} else if (s==BURN_DISC_BLANK) {
printf("is blank\n");
media_found = 1;
} else if (s == BURN_DISC_EMPTY)
} else if (s==BURN_DISC_EMPTY)
printf("is not present\n");
else
printf("is not recognizable\n");
@ -278,7 +276,6 @@ int telltoc_media(struct burn_drive *drive)
ret = burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
if (ret > 0) {
/* Media appears writeable */
printf("Write multi : ");
printf("%s multi-session , ",
caps->multi_session == 1 ? "allows" : "prohibits");
@ -312,32 +309,12 @@ int telltoc_media(struct burn_drive *drive)
caps->advised_write_mode == BURN_WRITE_RAW ?
" (advised)" : "");
printf("\n");
o= burn_write_opts_new(drive);
if (o != NULL) {
burn_write_opts_set_perform_opc(o, 0);
if(caps->advised_write_mode == BURN_WRITE_TAO)
burn_write_opts_set_write_type(o,
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
else if (caps->advised_write_mode == BURN_WRITE_SAO)
burn_write_opts_set_write_type(o,
BURN_WRITE_SAO, BURN_BLOCK_SAO);
else {
burn_write_opts_free(o);
o = NULL;
}
}
available = burn_disc_available_space(drive, o);
printf("Write space : %.1f MiB (%.fs)\n",
((double) available) / 1024.0 / 1024.0,
((double) available) / 2048.0);
burn_disc_free_multi_caps(&caps);
if (o != NULL)
burn_write_opts_free(o);
}
ret = burn_drive_get_write_speed(drive);
ret= burn_drive_get_write_speed(drive);
max_speed = ((double ) ret) / speed_conv;
ret = burn_drive_get_min_write_speed(drive);
ret= burn_drive_get_min_write_speed(drive);
min_speed = ((double ) ret) / speed_conv;
if (!media_found)
printf("Drive speed : max=%.1f , min=%.1f\n",
@ -348,11 +325,11 @@ int telltoc_media(struct burn_drive *drive)
ret = 0;
if (media_found)
ret = burn_disc_read_atip(drive);
ret= burn_disc_read_atip(drive);
if(ret>0) {
ret = burn_drive_get_min_write_speed(drive);
ret= burn_drive_get_min_write_speed(drive);
min_speed = ((double ) ret) / speed_conv;
ret = burn_drive_get_write_speed(drive);
ret= burn_drive_get_write_speed(drive);
max_speed = ((double ) ret) / speed_conv;
printf("Media speed : max=%.1f , min=%.1f\n",
max_speed, min_speed);
@ -526,7 +503,7 @@ int telltoc_msinfo(struct burn_drive *drive,
/* man mkisofs , option -C :
The second number is the starting sector number of the new session.
*/
/* Set some roughly suitable write opts to be sent to drive. */
/* Set some write opts to be sent to drive. LG GSA-4082B needs it. */
o= burn_write_opts_new(drive);
if(o!=NULL) {
burn_write_opts_set_perform_opc(o, 0);
@ -547,7 +524,7 @@ int telltoc_msinfo(struct burn_drive *drive,
printf("%d,%d\n",lba,nwa);
ret = 1;
ex:;
if (o != NULL)
if (o!=NULL)
burn_write_opts_free(o);
return ret;
}