Compare commits
70 Commits
ZeroThreeZ
...
ZeroThreeT
Author | SHA1 | Date | |
---|---|---|---|
113a8294ad | |||
86ac7a9754 | |||
537a8ee1d7 | |||
d95f777bd8 | |||
e8d210e15f | |||
6df2745652 | |||
09b5bd2a1f | |||
67ce096aeb | |||
cad7531058 | |||
8dccb584b4 | |||
50eba7ee31 | |||
494693cc63 | |||
05623cffc4 | |||
fed2af8c69 | |||
78f1cf835d | |||
d2283a5b4e | |||
8dd8ee4b9c | |||
6dfbbdf57f | |||
d57166f64b | |||
2799fe1b44 | |||
330e0e2d5f | |||
135d9d5016 | |||
db9f4a1d04 | |||
6b8ab52854 | |||
4e93de2cd2 | |||
a769f8aa87 | |||
e0a38be97b | |||
100de7b160 | |||
9f7e5dd6dd | |||
a9ac7ae480 | |||
2e75680ed7 | |||
c02dbe4eca | |||
f3a08f6812 | |||
e876f90e6c | |||
dde52c1971 | |||
f194aa8d5d | |||
b18b889750 | |||
0aafc18ac7 | |||
fa792f6a67 | |||
53a1e99675 | |||
bda139f390 | |||
ff7028d1fc | |||
fa350edaae | |||
55e6c0ba82 | |||
f5a350f2cc | |||
c079e09860 | |||
99f8e0eec5 | |||
3aec7fdeda | |||
814d8cc83d | |||
bc694d7457 | |||
66d70075ec | |||
8f4dd8580c | |||
7dd845a83b | |||
7b024f4a72 | |||
f1215f3295 | |||
8e17806405 | |||
fb98c0390e | |||
f418c49e63 | |||
a34e872511 | |||
69a07aeec6 | |||
7addf0d5b5 | |||
a001f96b21 | |||
4a26017f2a | |||
0f48910aff | |||
c68efb346c | |||
36f287d569 | |||
4d7e28c09f | |||
c1342195f6 | |||
1fd003c1ec | |||
36d475eaf9 |
@ -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
|
||||
## cdrskin construction site - ts A60816 - A70210
|
||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_2_7
|
||||
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
|
||||
##
|
||||
|
34
README
34
README
@ -54,7 +54,8 @@ See README file there.
|
||||
Overview of libburnia.pykix.org
|
||||
|
||||
libburnia.pykix.org is an open-source software project for reading, mastering
|
||||
and writing optical discs. For now this means only CD-R and CD-RW.
|
||||
and writing optical discs.
|
||||
For now this means only CD media and all single layer DVD media except DVD+R.
|
||||
|
||||
The project comprises of several more or less interdependent parts which
|
||||
together strive to be a usable foundation for application development.
|
||||
@ -66,10 +67,10 @@ we would need : login on a development machine resp. a live OS on CD or DVD,
|
||||
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
||||
volunteers for testing of realistic use cases.
|
||||
|
||||
We do have a workable code base for burning data CDs, though. The burn API is
|
||||
quite comprehensively documented and can be used to build a presentable
|
||||
application.
|
||||
We do have a functional binary which emulates parts of cdrecord in order to
|
||||
We have a workable code base for burning CD and most single layer DVD.
|
||||
The burn API is quite comprehensively documented and can be used to build a
|
||||
presentable application.
|
||||
We have a functional binary which emulates parts of cdrecord in order to
|
||||
prove that usability, and in order to allow you to explore libburnia's scope
|
||||
by help of existing cdrecord frontends.
|
||||
|
||||
@ -78,20 +79,25 @@ The project components (list subject to growth, hopefully):
|
||||
- libburn is the library by which preformatted data get onto optical media.
|
||||
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
|
||||
/dev/hdX (e.g. on kernel 2.6).
|
||||
libburn is the foundation of our cdrecord emulation.
|
||||
libburn is the foundation of our cdrecord emulation. Its code is
|
||||
independent of cdrecord. Its DVD capabilities are learned from
|
||||
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
|
||||
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
|
||||
|
||||
- libisofs is the library to pack up hard disk files and directories into a
|
||||
ISO 9660 disk image. This may then be brought to CD via libburn.
|
||||
ISO 9660 disk image. This may then be brought to media via libburn.
|
||||
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
||||
|
||||
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||
Cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||
Schilling's cdrtools. cdrskin strives to be a second source for
|
||||
the services traditionally provided by cdrecord.
|
||||
the services traditionally provided by cdrecord. Additionally it
|
||||
provides libburn's DVD capabilities, where only -sao is compatible
|
||||
with cdrecord.
|
||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||
Many bytes have been copied from the message output of cdrecord
|
||||
runs, though.
|
||||
See cdrskin/README for more.
|
||||
See cdrskin/README and man cdrskin/cdrskin.1 for more.
|
||||
|
||||
- test is a collection of application gestures and examples given by the
|
||||
authors of the library features. The main API example for libburn
|
||||
@ -178,6 +184,16 @@ Project history as far as known to me:
|
||||
libburn, is now called libburnia. For the origin of this name, see
|
||||
http://en.wikipedia.org/wiki/Liburnians .
|
||||
|
||||
- 16th January 2007 release of libburn-0.3.0 and cdrskin-0.3.0 . Now the scope
|
||||
is widened to a first class of DVD media: overwriteable single layer types
|
||||
DVD-RAM, DVD+RW, DVD-RW. This is not a cdrecord emulation but rather inspired
|
||||
by dvd+rw-tools' "poor man" writing facility for this class of media.
|
||||
Taking a bow towards Andy Polyakov.
|
||||
|
||||
- 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with
|
||||
multi-session and with DAO.
|
||||
This means all single layer DVD media except DVD+R are supported now.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -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.2.7.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.2.7, 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.2.7.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.2.7.tar.gz
|
||||
cd cdrskin-0.2.7
|
||||
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.2.7 or libburn then execute:
|
||||
Within that toplevel directory of either cdrskin-0.3.2 or libburn then execute:
|
||||
|
||||
./configure
|
||||
make
|
||||
@ -143,6 +143,9 @@ It is not checked for the necessary degree of hacker safety.
|
||||
|
||||
Usage examples
|
||||
|
||||
For options and recordable media classes see
|
||||
man 1 cdrskin
|
||||
|
||||
Get an overview of cdrecord style addresses of available devices
|
||||
cdrskin -scanbus
|
||||
cdrskin dev=ATA -scanbus
|
||||
@ -158,21 +161,34 @@ Obtain some info about the drive
|
||||
Obtain some info about the drive and the inserted media
|
||||
cdrskin dev=0,1,0 -atip -v
|
||||
|
||||
Thoroughly blank a CD-RW
|
||||
cdrskin -v dev=0,1,0 blank=all -eject
|
||||
|
||||
Blank CD-RW sufficiently for making it ready for overwrite
|
||||
Make used CD-RW or used unformatted DVD-RW writeable again
|
||||
cdrskin -v dev=0,1,0 blank=fast -eject
|
||||
|
||||
Burn image file my_image.iso to CD or DVD+-RW
|
||||
Format DVD-RW to avoid need for blanking before re-use
|
||||
cdrskin -v dev=0,1,0 blank=format_overwrite
|
||||
|
||||
De-format DVD-RW to make it capable of multi-session again
|
||||
cdrskin -v dev=/dev/sr0 blank=deformat_sequential
|
||||
|
||||
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
|
||||
|
||||
Burn a compressed afio archive to CD or DVD+-RW on-the-fly
|
||||
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 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" ...
|
||||
|
||||
Burn a compressed afio archive to media on-the-fly
|
||||
find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 -tao \
|
||||
driveropts=burnfree padsize=300k -
|
||||
|
||||
Burn 6 audio tracks from files with different formats to CD.
|
||||
Burn 6 audio tracks from files with different formats to CD (not to any DVD).
|
||||
Anything except .wav or .au files has to be converted into raw format first.
|
||||
See below "Audio CD" for specifications.
|
||||
ogg123 -d raw -f track01.cd /path/to/track1.ogg
|
||||
@ -208,11 +224,12 @@ Run a backup :
|
||||
Restrictions
|
||||
|
||||
The major restrictions are lifted now: audio, TAO, multi-session do work.
|
||||
Many cdrecord options are still unsupported, though.
|
||||
|
||||
Many cdrecord options are still unsupported, though.
|
||||
If you have use cases for them, please report your wishes and expectations.
|
||||
|
||||
DVD support is still immature and restricted to DVD+-RW for now.
|
||||
DVD support is restricted to single layer overwriteable DVD (-RAM, +RW, -RW)
|
||||
for now.
|
||||
|
||||
|
||||
|
||||
@ -232,6 +249,10 @@ 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
|
||||
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
|
||||
which provide me with examples and pointers into MMC specs for DVD writing.
|
||||
|
||||
|
||||
Drive Addressing
|
||||
|
||||
@ -399,22 +420,36 @@ into the format of the burned data. Be advised to use growisofs for the
|
||||
task of maintaining extendable ISO-Filesystems on DVD+RW.
|
||||
|
||||
|
||||
DVD-RW
|
||||
DVD-RW and DVD-R
|
||||
|
||||
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
|
||||
"Sequential Recording". DVD-R are always in sequential state.
|
||||
|
||||
DVD-RW are usable if formatted to state "Restricted Overwrite". They then
|
||||
behave much like DVD+RW. See above.
|
||||
DVD-RW in state "Sequential" have first to be formatted by
|
||||
cdrskin dev=... -v blank=format_overwrite
|
||||
"Sequential" is the state of unused media and of media previously blanked
|
||||
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
|
||||
(Command dvd+rw-format -force can achieve "Restricted Overwrite".)
|
||||
|
||||
The according cdrskin option is blank=deformat_sequential .
|
||||
If "Incremental Streaming" is available, then sequential media are capable
|
||||
of multi-session like CD-R[W]. (But not capable of -audio recording.)
|
||||
This means they need option -multi to stay appendable, need to be blanked
|
||||
to be writeable from start, return useable info with -toc and -msinfo,
|
||||
eventually perform appending automatically.
|
||||
Without "Incremental Streaming" offered by the drive, only write mode DAO is
|
||||
available with sequential DVD-R[W]. It only works with blank media, allows only
|
||||
one single track, no -multi, and demands a fixely predicted track size.
|
||||
(growisofs uses it with DVD-R[W] if option -dvd-compat is given.)
|
||||
|
||||
Overwriteable DVD-RW behave much like DVD+RW. "Restricted" refers only to the
|
||||
granularity of random access and block size which have always to be aligned to
|
||||
full 32 kB. Sequential DVD-RW are converted into overwriteable DVD-RW by
|
||||
cdrskin dev=... -v blank=format_overwrite
|
||||
(Command dvd+rw-format -force can achieve "Restricted Overwrite", too.)
|
||||
|
||||
Formatting or first use of freshly formatted DVD-RW can produce unusual noises
|
||||
from the drive and last several minutes. Depending on mutual compatibility of
|
||||
drive and media, formatting can yield unusable media. It seems that those die
|
||||
too on blanking by cdrecord or dvd+rw-format. Perils of DVD-RW, i fear.
|
||||
too on blanking by cdrecord, dvd+rw-format or cdrskin. Perils of DVD-RW.
|
||||
|
||||
There are three formatting variants with cdrskin currently:
|
||||
There are three DVD-RW formatting variants with cdrskin currently:
|
||||
|
||||
blank=format_overwrite uses "DVD-RW Quick" formatting (MMC-type 15h)
|
||||
and writes a first session of 128 MB. This leads to media which are expandable
|
||||
@ -423,12 +458,22 @@ and random addressable by cdrskin.
|
||||
blank=format_overwrite_quickest uses "DVD-RW Quick" formatting (type 15h) too,
|
||||
but leaves the media in "intermediate" state. In the first session of writing
|
||||
one may only write sequentially to such a DVD. After that, it gets random
|
||||
addressable by cdrskin.
|
||||
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
|
||||
|
||||
blank=format_overwrite_full uses preferrably "Full Format" (type 00h).
|
||||
This formatting lasts as long as writing a full DVD. It includes writing of
|
||||
lead-out which is said to be good for DVD ROM compatibility.
|
||||
|
||||
De-formatting options are available to make overwriteable DVD-RW sequential:
|
||||
|
||||
blank=deformat_sequential performs thorough blanking of all states of DVD-RW.
|
||||
blank=all and blank=fast perform the same thorough blanking, but refuse to do
|
||||
this with overwriteable DVD-RW, thus preserving their formatting. The specs
|
||||
allow minimal blanking but the resulting media on my drives offer no
|
||||
Incremental Streaming afterwards. So blank=fast will do full blanking.
|
||||
|
||||
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
|
||||
|
||||
|
||||
Special compilation variations
|
||||
|
||||
|
@ -20,27 +20,28 @@ set -x
|
||||
# The script is to be run in the directory above the toplevel
|
||||
# directory of libburn resp. cdrskin development.
|
||||
#
|
||||
# libburn version used: http://libburn.pykix.org
|
||||
|
||||
# The top level directory in the SVN snapshot is named
|
||||
intermediate="./libburn_pykix"
|
||||
|
||||
# libburn source used: http://libburnia.pykix.org
|
||||
# Downloaded by:
|
||||
# $ svn co http://libburn-svn.pykix.org/trunk libburn_pykix
|
||||
# $ svn co http://libburnia-svn.pykix.org/libburn/tags/... $intermediate
|
||||
# packed up in a tarball just to save it from inadverted changes by
|
||||
# $ tar czf libburn_svn.tgz libburn_pykix
|
||||
original="./libburn_svn.tgz"
|
||||
# $ tar czf libburn_svn.tgz $intermediate
|
||||
original="./libburn_svn_release.tgz"
|
||||
# Historic moments:
|
||||
# original="./libburn_svn_A60815.tgz"
|
||||
# original="./libburn_cdrskin_A60819.tgz"
|
||||
|
||||
# The top level directory in that snapshot is named
|
||||
intermediate="./libburn_pykix"
|
||||
|
||||
# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin
|
||||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-release"
|
||||
|
||||
changes="./libburn-0.2.3.ts.develop"
|
||||
skin_release="0.2.6"
|
||||
patch_level=".pl01"
|
||||
skin_release="0.3.2"
|
||||
patch_level=".pl00"
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
||||
|
||||
# The result directory and the name of the result tarballs
|
||||
target="./cdrskin-${skin_release}"
|
||||
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
|
||||
@ -54,6 +55,9 @@ compile_cmd="./cdrskin/compile_cdrskin.sh"
|
||||
compile_static_opts="-static"
|
||||
compile_result="cdrskin/cdrskin"
|
||||
|
||||
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
|
||||
man_page_html="cdrskin/man_1_cdrskin.html"
|
||||
|
||||
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
||||
bintarget_static="$bintarget_dynamic"-static
|
||||
|
||||
@ -122,6 +126,8 @@ do
|
||||
rm "$cdrskin_target"/cdrskin_"$i"
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove eventual SVN stuff from cdrskin directory
|
||||
for i in .deps .dirstamp .libs
|
||||
do
|
||||
if test -e "$cdrskin_target"/"$i"
|
||||
@ -130,6 +136,23 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove GIFs of cdrskin_eng.html
|
||||
rm "$cdrskin_target"/doener_*.gif
|
||||
|
||||
# Remove automatically generated HTML man page
|
||||
rm "$cdrskin_target"/man_1_cdrskin.html
|
||||
|
||||
# Remove all add_ts_changes_to_libburn besides this one
|
||||
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
|
||||
do
|
||||
if test $(basename "$0") = $(basename "$i")
|
||||
then
|
||||
dummy=dummy
|
||||
else
|
||||
rm $i
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove unwanted SVN stuff (TODO: avoid downloading it)
|
||||
for i in "$target"/.svn "$target"/*/.svn
|
||||
do
|
||||
@ -144,12 +167,6 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
## No more : Add own libburn-README in toplevel
|
||||
# cp -a "$changes"/README "$target"
|
||||
|
||||
## No more : Add modified Makefile.am
|
||||
# cp -a "$changes"/Makefile.am "$target"
|
||||
|
||||
|
||||
# Make SVN state tarball for the libburn team
|
||||
tar czf "$cdrskin_tarball_svn" "$target"
|
||||
@ -179,18 +196,20 @@ done
|
||||
# Pack it up to the new libburn+cdrskin-tarball
|
||||
tar czf "$cdrskin_tarball" "$target"
|
||||
|
||||
# Produce a static and a dynamic binary
|
||||
# Produce a static and a dynamic binary, and a HTML man page
|
||||
(
|
||||
cd "$compile_dir" || exit 1
|
||||
./configure
|
||||
make
|
||||
$compile_cmd -do_strip
|
||||
"$compile_cmd" -do_strip
|
||||
cp "$compile_result" "../$bintarget_dynamic"
|
||||
if test -n "$compile_static_opts"
|
||||
then
|
||||
$compile_cmd $compile_static_opts -do_strip
|
||||
"$compile_cmd" $compile_static_opts -do_strip
|
||||
cp "$compile_result" "../$bintarget_static"
|
||||
fi
|
||||
"$man_to_html_cmd"
|
||||
mv "$man_page_html" ..
|
||||
)
|
||||
|
||||
# Remove the build area
|
||||
@ -203,4 +222,5 @@ rm -rf "$target"
|
||||
ls -l "$cdrskin_tarball"
|
||||
ls -l "$bintarget_dynamic"
|
||||
ls -l "$bintarget_static"
|
||||
ls -l $(basename "$man_page_html")
|
||||
|
@ -20,26 +20,30 @@ set -x
|
||||
# The script is to be run in the directory above the toplevel
|
||||
# directory of libburn resp. cdrskin development.
|
||||
#
|
||||
# libburn version used: http://libburn.pykix.org
|
||||
|
||||
# The top level directory in the SVN snapshot is named
|
||||
intermediate="./libburn_pykix"
|
||||
|
||||
# libburn source used: http://libburnia.pykix.org
|
||||
# Downloaded by:
|
||||
# $ svn co http://libburn-svn.pykix.org/libburn/trunk libburn_pykix
|
||||
# $ svn co http://libburnia-svn.pykix.org/libburn/tags/... $intermediate
|
||||
# packed up in a tarball just to save it from inadverted changes by
|
||||
# $ tar czf libburn_svn.tgz libburn_pykix
|
||||
# $ tar czf libburn_svn.tgz $intermediate
|
||||
original="./libburn_svn.tgz"
|
||||
# Historic moments:
|
||||
# original="./libburn_svn_A60815.tgz"
|
||||
# original="./libburn_cdrskin_A60819.tgz"
|
||||
|
||||
# The top level directory in that snapshot is named
|
||||
intermediate="./libburn_pykix"
|
||||
|
||||
# My changes are in libburn-0.2.3.ts.develop , mainly in ./cdrskin
|
||||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-develop"
|
||||
|
||||
changes="./libburn-0.2.3.ts.develop"
|
||||
skin_rev="0.2.7"
|
||||
skin_release="0.3.3"
|
||||
patch_level=""
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
||||
# The result directory and the name of the result tarballs
|
||||
target="./cdrskin-${skin_rev}"
|
||||
target="./cdrskin-${skin_release}"
|
||||
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
|
||||
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz"
|
||||
|
||||
@ -123,10 +127,7 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove automatically generated HTML man page
|
||||
rm "$cdrskin_target"/man_1_cdrskin.html
|
||||
|
||||
# Remove eventual SVN stuff from cdrskin driectory
|
||||
# Remove eventual SVN stuff from cdrskin directory
|
||||
for i in .deps .dirstamp .libs
|
||||
do
|
||||
if test -e "$cdrskin_target"/"$i"
|
||||
@ -138,6 +139,20 @@ done
|
||||
# Remove GIFs of cdrskin_eng.html
|
||||
rm "$cdrskin_target"/doener_*.gif
|
||||
|
||||
# Remove automatically generated HTML man page
|
||||
rm "$cdrskin_target"/man_1_cdrskin.html
|
||||
|
||||
# Remove all add_ts_changes_to_libburn besides this one
|
||||
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
|
||||
do
|
||||
if test $(basename "$0") = $(basename "$i")
|
||||
then
|
||||
dummy=dummy
|
||||
else
|
||||
rm $i
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove unwanted SVN stuff (TODO: avoid downloading it)
|
||||
for i in "$target"/.svn "$target"/*/.svn
|
||||
do
|
||||
@ -152,12 +167,6 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
## No more : Add own libburn-README in toplevel
|
||||
# cp -a "$changes"/README "$target"
|
||||
|
||||
## No more : Add modified Makefile.am
|
||||
# cp -a "$changes"/Makefile.am "$target"
|
||||
|
||||
|
||||
# Make SVN state tarball for the libburn team
|
||||
tar czf "$cdrskin_tarball_svn" "$target"
|
@ -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 "January 12, 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, CD-RW, DVD+/-RW, 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 ]
|
||||
@ -29,12 +29,12 @@ via libburn.
|
||||
.\" respectively.
|
||||
.PP
|
||||
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
||||
in a compatible way for CD media. With DVD it has its own ways for now.
|
||||
in a compatible way for CD media. With DVD it has its own ways.
|
||||
You do not need to be superuser for its daily usage.
|
||||
.PP
|
||||
.B Overview of features:
|
||||
.br
|
||||
Blanking of CD-RW.
|
||||
Blanking of CD-RW and DVD-RW.
|
||||
.br
|
||||
Burning of data or audio tracks to CD,
|
||||
.br
|
||||
@ -42,12 +42,16 @@ either in versatile Track at Once mode (TAO)
|
||||
.br
|
||||
or in Session at Once mode for seamless tracks.
|
||||
.br
|
||||
Multi session on CD (follow-up sessions in TAO only).
|
||||
Multi session on CD (follow-up sessions in TAO only)
|
||||
.br
|
||||
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
|
||||
or on overwriteable DVD+RW, DVD-RW, DVD-RAM.
|
||||
.br
|
||||
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
|
||||
.br
|
||||
Burning of a single data track to DVD+RW, DVD-RW or DVD-RAM.
|
||||
.br
|
||||
See section EXAMPLES at the end of this text.
|
||||
.PP
|
||||
.B Track recording model:
|
||||
@ -64,7 +68,7 @@ More than one track can be burned by a single run of cdrskin.
|
||||
In the terms of the MMC standard all tracks written by the same run constitute
|
||||
a \fBsession\fP.
|
||||
.br
|
||||
CDs can be kept appendable so that further tracks can
|
||||
Some media types can be kept appendable so that further tracks can
|
||||
be written to them in subsequent runs of cdrskin (see option -multi).
|
||||
Info about the addresses of burned tracks is kept in a table of
|
||||
content (TOC) on media and can be retrieved via cdrskin option -toc.
|
||||
@ -72,7 +76,7 @@ These informations are also used by the operating systems' CD-ROM read drivers.
|
||||
.PP
|
||||
In general there are two types of tracks: data and audio. They differ in
|
||||
sector size, throughput and readability via the systems' CD-ROM drivers
|
||||
resp. by music CD players.
|
||||
resp. by music CD players. With DVD there is only type data.
|
||||
.br
|
||||
If not explicitely option -audio is given, then any track is burned as type
|
||||
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
||||
@ -96,7 +100,19 @@ the archivers afio and star. Not suitable seems GNU tar.
|
||||
.br
|
||||
CD-R can be initially written only once and eventually extended until they
|
||||
get closed (or are spoiled because they are overly full). After that they are
|
||||
read-only.
|
||||
read-only. Closing is done automatically unless option
|
||||
.B -multi
|
||||
is given which keeps the media appendable.
|
||||
.br
|
||||
There are two write modes,
|
||||
.B -tao
|
||||
and
|
||||
.B -sao .
|
||||
.br
|
||||
-tao allows to use track source of unpredictable length (like stdin) and allows
|
||||
to write further sessions to appendable media. -sao produces audio sessions
|
||||
with seamless tracks but needs predicted track sizes and cannot append sessions
|
||||
to media.
|
||||
.br
|
||||
CD-RW media can be blanked to make them re-usable for another
|
||||
round of overwriting. Usually
|
||||
@ -106,24 +122,59 @@ Blanking damages the previous content but does not
|
||||
make it completely unreadable. It is no effective privacy precaution.
|
||||
Multiple cycles of blanking and overwriting with random numbers might be.
|
||||
.PP
|
||||
.B Recordable DVD Media:
|
||||
.B Sequentially Recordable DVD Media:
|
||||
.br
|
||||
Currently only types DVD+RW, DVD-RW and DVD-RAM can be burned via cdrskin.
|
||||
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
|
||||
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
|
||||
.B -multi .
|
||||
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
||||
Multiple tracks per session are permissible.
|
||||
.br
|
||||
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
|
||||
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
|
||||
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
|
||||
DVD-ROM/-Video compatibility.
|
||||
.PP
|
||||
.B Overwriteable DVD Media:
|
||||
.br
|
||||
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.
|
||||
Options -audio and -multi are not allowed. Only one track is allowed.
|
||||
-toc does not return information about the media content.
|
||||
Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second). Currently
|
||||
there is no difference between -sao and -tao. If ever, then -tao will be the
|
||||
mode which preserves the current behavior.
|
||||
Currently there is no difference between -sao and -tao. If ever, then -tao
|
||||
will be the mode which preserves the current behavior.
|
||||
.br
|
||||
DVD-RW need to be formatted to state "Restricted Overwrite". Then they behave
|
||||
much like DVD+RW. This formatting can be done by option
|
||||
.B blank=format_overwrite
|
||||
It is necessary for unused media, for media written or blanked by cdrecord,
|
||||
for media which have been written unformatted by growisofs or blanked by
|
||||
dvd+rw-format -blank. If in doubt, just give it a try.
|
||||
DVD-RW are sold in state "Sequential Recording". To become suitable for the
|
||||
Overwriteable DVD recording model they need to get formatted to state
|
||||
"Restricted Overwrite". Then they behave much like DVD+RW. This formatting
|
||||
can be done by option
|
||||
.B blank=format_overwrite .
|
||||
.br
|
||||
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:
|
||||
.br
|
||||
@ -183,9 +234,11 @@ stereo. For little-endian byte order (which is usual on PCs) use option
|
||||
.wav are examined wether they have a header in MS-WAVE format confirming
|
||||
those parameters and eventually raw audio data get extracted and burned as
|
||||
audio track. Same is done for suffix .au and SUN Audio.
|
||||
.br
|
||||
Option -audio may be used only with CD media and not with DVD.
|
||||
.TP
|
||||
.BI blank= type
|
||||
Blank a CD-RW or format a DVD+/-RW.
|
||||
Blank a CD-RW, a DVD-RW, or format a DVD+/-RW.
|
||||
This is combinable with burning in the same run of cdrskin.
|
||||
The type given with blank= selects the particular behavior:
|
||||
.RS
|
||||
@ -194,14 +247,17 @@ help
|
||||
Print this list of blanking types.
|
||||
.TP
|
||||
all
|
||||
Blank an entire CD.
|
||||
Blank an entire CD-RW or an unformatted DVD-RW.
|
||||
(See also --prodvd_cli_compatible)
|
||||
.TP
|
||||
fast
|
||||
Minimally blank an entire CD.
|
||||
Minimally blank an entire CD-RW or blank an unformatted DVD-RW.
|
||||
(See also --prodvd_cli_compatible)
|
||||
.TP
|
||||
format_overwrite
|
||||
Format a DVD-RW to "Restricted Overwrite". The user should bring some patience.
|
||||
(Note: format_overwrite* are not original cdrecord options.)
|
||||
.br
|
||||
(Note: blank=format_overwrite* are not original cdrecord options.)
|
||||
.TP
|
||||
format_overwrite_quickest
|
||||
Like format_overwrite without creating a 128 MB trailblazer session.
|
||||
@ -215,8 +271,21 @@ rather than just 128 MB.
|
||||
Most traditional formatting is attempted. No data get written.
|
||||
Much patience is required.
|
||||
.br
|
||||
This option treats already formatted media even if not option -force is given.
|
||||
.br
|
||||
For DVD+RW this is the only supported explicit formatting type. It provides
|
||||
complete "de-icing" so no reader slips on unwritten data areas.
|
||||
.TP
|
||||
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.
|
||||
.br
|
||||
(Note: blank=deformat_sequential* are not original cdrecord options.)
|
||||
.TP
|
||||
deformat_sequential_quickest
|
||||
Like blank=deformat_sequential but blanking DVD-RW only minimally.
|
||||
This is faster than full blanking but may yield media incapable of
|
||||
Incremental Streaming (-tao).
|
||||
.RE
|
||||
.TP
|
||||
.BI \-checkdrive
|
||||
@ -224,7 +293,8 @@ Retrieve some info about the addressed drive.
|
||||
Exits with non-zero value if the drive cannot be found and opened.
|
||||
.TP
|
||||
.BI \-dao
|
||||
Alias for option -sao. Write disk in Session at Once mode.
|
||||
Alias for option -sao. Write CD in Session at Once mode
|
||||
or DVD-R[W] in Disc-at-once mode.
|
||||
.TP
|
||||
.BI \-data
|
||||
Subsequent tracks are data tracks. This option is default and only needed
|
||||
@ -247,17 +317,18 @@ Be aware that deprecated option --old_pseudo_scsi_adr may change the meaning
|
||||
of Bus,Target,Lun addresses.
|
||||
.TP
|
||||
.BI driveropts= opt
|
||||
Set "driveropts=burnfree" to enable the drive's eventual protection mechanism
|
||||
against temporary lack of source data (i.e. buffer underrun).
|
||||
It is not an error to do this with a drive that has no such capabilities.
|
||||
Set "driveropts=noburnfree" to disable the drive's eventual protection
|
||||
mechanism against temporary lack of source data (i.e. buffer underrun).
|
||||
A drive that announces no such capabilities will not get them enabled anyway,
|
||||
even if attempted explicitely via "driveropts=burnfree".
|
||||
.TP
|
||||
.BI \-dummy
|
||||
Try to perform the drive operations without actually affecting the inserted
|
||||
media. There is no guarantee that this will work with a particular drive
|
||||
in a particular write mode. Blanking is prevented reliably, though.
|
||||
media. There is no guarantee that this will work with a particular combination
|
||||
of drive, media, and write mode. Blanking is prevented reliably, though.
|
||||
.TP
|
||||
.BI \-eject
|
||||
Eject the disk after work is done.
|
||||
Eject the disc after work is done.
|
||||
.TP
|
||||
.BI \-force
|
||||
Assume that the user knows better in situations when cdrskin or libburn are
|
||||
@ -307,11 +378,15 @@ start address of the next session to be appended. The string is empty if
|
||||
the most recent session was not written with option -multi.
|
||||
.TP
|
||||
.BI \-multi
|
||||
This option keeps the CD appendable after the current session has been written.
|
||||
Without it the disk gets closed and may not be written any more - unless it
|
||||
is a CD-RW and gets blanked which causes loss of its content.
|
||||
This option keeps the CD or unformatted DVD-R[W] appendable after the current
|
||||
session has been written.
|
||||
Without it the disc gets closed and may not be written any more - unless it
|
||||
is a -RW and gets blanked which causes loss of its content.
|
||||
.br
|
||||
The following sessions can only be written in -tao mode.
|
||||
The following sessions can only be written in -tao mode. -multi is prohibited
|
||||
with overwriteable DVD media and with DVD-R[W] DAO write mode.
|
||||
Option --prodvd_cli_compatible eventually makes -multi tolerable but cannot
|
||||
make it work.
|
||||
.br
|
||||
In order to have all filesystem content accessible, the eventual ISO-9660
|
||||
filesystem of a follow-up
|
||||
@ -337,18 +412,27 @@ gets reset to padsize=0 after that next track is written. It may be set
|
||||
again before the next track argument. About size specifiers, see option fs=.
|
||||
.TP
|
||||
.BI \-raw96r
|
||||
Write disk in RAW/RAW96R mode. This mode allows to put more payload bytes
|
||||
Write CD in RAW/RAW96R mode. This mode allows to put more payload bytes
|
||||
into a CD sector but obviously at the cost of error correction. It can only
|
||||
be used for tracks of fixely predicted size. Some drives allow this mode but
|
||||
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 disk in Session At Once mode. This mode is able to put several audio
|
||||
tracks on CD without producing audible gaps between them. It 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=.
|
||||
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.
|
||||
.br
|
||||
With DVD-R[W] this mode can only write a single track.
|
||||
No -multi is allowed with DVD-R[W] -sao.
|
||||
.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=.
|
||||
.br
|
||||
-sao cannot be used on appendable media.
|
||||
.TP
|
||||
.BI \-scanbus
|
||||
Scan the system for drives. On Linux the drives at /dev/s* and at /dev/hd*
|
||||
@ -365,7 +449,8 @@ Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
|
||||
.TP
|
||||
.BI speed= number
|
||||
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
|
||||
150 kB/s. It is not an error to set a speed higher than is suitable for drive
|
||||
150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
|
||||
It is not an error to set a speed higher than is suitable for drive
|
||||
and media. One should stay within a realistic speed range, though.
|
||||
.TP
|
||||
.BI \-swab
|
||||
@ -377,13 +462,16 @@ Less guesswork is needed if track sources are in format MS-WAVE in a file with
|
||||
suffix ".wav".
|
||||
.TP
|
||||
.BI \-tao
|
||||
Write disk in Track At Once (TAO) mode. This mode 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 to appendable CD which
|
||||
already hold data.
|
||||
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
|
||||
to appendable media which already hold data. With unformatted DVD-R[W] it is
|
||||
the only mode which allows -multi.
|
||||
.TP
|
||||
.BI \-toc
|
||||
Print the table of content (TOC) which describes the tracks recorded on CD.
|
||||
Print the table of content (TOC) which describes the tracks recorded on disc.
|
||||
The output contains all info from option -atip plus lines which begin with
|
||||
"track:", the track number, the word "lba:" and a number which gives the
|
||||
start address of the track. Addresses are counted in CD sectors which with
|
||||
@ -416,7 +504,7 @@ About size specifiers, see option fs=.
|
||||
If the track source does not deliver the predicted amount of bytes, the
|
||||
remainder of the track is padded with zeros. This is not considered an error.
|
||||
If on the other hand the track source delivers more than the announced bytes
|
||||
then the track on CD gets truncated to the predicted size and cdrskin exits
|
||||
then the track on media gets truncated to the predicted size and cdrskin exits
|
||||
with non-zero value.
|
||||
.TP
|
||||
.BI \-v
|
||||
@ -465,10 +553,10 @@ fifo_start_at= combine a quick burn start and a large savings buffer to
|
||||
compensate for temporary lack of source data. At the beginning of burning,
|
||||
the software protection against buffer underun is as weak as the size of
|
||||
fifo_start_at= . So it is best if the drive offers hardware protection which
|
||||
has to be enabled by driveropts=burnfree.
|
||||
is enabled automatically if not driveropts=noburnfree is given.
|
||||
.TP
|
||||
.BI \--list_ignored_options
|
||||
List all ignored cdrecord options. The --options cannot be used as addresses
|
||||
List all ignored cdrecord options. The "-" options cannot be used as addresses
|
||||
of track sources. No track source address may begin with a text equal to an
|
||||
option which ends by "=". The list is ended by an empty line.
|
||||
.TP
|
||||
@ -476,8 +564,32 @@ option which ends by "=". The list is ended by an empty line.
|
||||
Only if used as first command line argument this option prevents reading and
|
||||
interpretation of eventual startup files. See section FILES below.
|
||||
.TP
|
||||
.BI \--prodvd_cli_compatible
|
||||
Activates behavior modifications with some DVD situations which bring cdrskin
|
||||
nearer to the behavior of cdrecord-ProDVD:
|
||||
.br
|
||||
Option -multi with unsuitable media is not an error but simply has no effect.
|
||||
.br
|
||||
Options blank=fast and blank=all deformat overwriteable DVD-RW media.
|
||||
.br
|
||||
Option blank=fast does indeed minmal blanking with DVD-RW. This may yield media
|
||||
which can only do DAO but not Incremental Streaming.
|
||||
.TP
|
||||
.BI \--single_track
|
||||
Accept only the last argument of the command line as track source address.
|
||||
.TP
|
||||
.BI tao_to_sao_tsize= size
|
||||
Set an exact fixed size for the next track to be in effect only if the track
|
||||
source cannot deliver a size prediction and no tsize= was specified and an
|
||||
exact track size prediction is demanded by the write mode.
|
||||
.br
|
||||
This was the fallback from bad old times when cdrskin was unable to burn
|
||||
in mode -tao . It came back with minimally blanked DVD-RW which allow no
|
||||
Incremental Streaming (-tao) resp. with explicitly selected write mode -sao
|
||||
for best DVD-ROM compatibility.
|
||||
.br
|
||||
If the track source delivers less bytes than announced then the missing ones
|
||||
will be filled with zeros.
|
||||
.TP
|
||||
.BI write_start_address= byte_offset
|
||||
Set the address on media where to start writing the track. With DVD+RW or
|
||||
@ -547,8 +659,8 @@ On signals exit even if the drive is in busy state. This is not a very good
|
||||
idea. You might end up with a stuck drive that refuses to hand out the media.
|
||||
.TP
|
||||
.BI \--no_blank_appendable
|
||||
Refuse to blank appendable CD-RW. This is a feature that was once builtin with
|
||||
libburn. No information available for what use case it was needed.
|
||||
Refuse to blank appendable CD-RW or DVD-RW. This is a feature that was once
|
||||
builtin with libburn. No information available for what use case it was needed.
|
||||
.TP
|
||||
.BI \--no_convert_fs_adr
|
||||
Do only literal translations of dev=. This prevents cdrskin from test-opening
|
||||
@ -565,16 +677,10 @@ Linux specific:
|
||||
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||
original cdrecord.
|
||||
.TP
|
||||
.BI tao_to_sao_tsize= size
|
||||
Set an exact fixed size for the next track to be in effect only if the track
|
||||
source cannot deliver a size prediction and no tsize= was specified.
|
||||
This is the fallback from bad old times when cdrskin was unable to burn
|
||||
in mode -tao.
|
||||
.br
|
||||
.SH EXAMPLES
|
||||
.SS
|
||||
.B Get an overview of drives:
|
||||
.B Get an overview of drives and their addresses:
|
||||
.br
|
||||
cdrskin -scanbus
|
||||
.br
|
||||
@ -586,47 +692,49 @@ cdrskin --devices
|
||||
.br
|
||||
cdrskin dev=0,1,0 -checkdrive
|
||||
.br
|
||||
cdrskin dev=ATA:1,0,0 -atip
|
||||
cdrskin dev=ATA:1,0,0 -v -atip
|
||||
.br
|
||||
cdrskin dev=/dev/hdc -toc
|
||||
.SS
|
||||
.B Make used CD-RW writable again:
|
||||
.B Make used CD-RW or used unformatted DVD-RW writable again:
|
||||
.br
|
||||
cdrskin -v dev=/dev/sg1 blank=all -eject
|
||||
cdrskin -v dev=/dev/sg1 blank=fast -eject
|
||||
.br
|
||||
cdrskin -v dev=/dev/dvd blank=fast -eject
|
||||
cdrskin -v dev=/dev/dvd blank=all -eject
|
||||
.SS
|
||||
.B Format DVD-RW before first use with cdrskin:
|
||||
.B Format DVD-RW to avoid need for blanking before re-use:
|
||||
.br
|
||||
cdrskin -v dev=/dev/sr0 blank=format_overwrite
|
||||
.SS
|
||||
.B Write ISO-9660 filesystem image:
|
||||
.B De-format DVD-RW to make it capable of multi-session again:
|
||||
.br
|
||||
cdrskin -v dev=/dev/sr0 blank=deformat_sequential
|
||||
.SS
|
||||
.B Write ISO-9660 filesystem image as only one to blank or formatted media:
|
||||
.br
|
||||
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
|
||||
.br
|
||||
driveropts=burnfree -sao -eject \\
|
||||
.br
|
||||
padsize=300k my_image.iso
|
||||
-sao -eject padsize=300k my_image.iso
|
||||
.SS
|
||||
.B Write compressed afio archive on-the-fly:
|
||||
.br
|
||||
find . | afio -oZ - | \\
|
||||
.br
|
||||
cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree \\
|
||||
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
|
||||
.br
|
||||
padsize=300k -tao -
|
||||
-tao padsize=300k -
|
||||
.SS
|
||||
.B Write several sessions to the same CD:
|
||||
.B Write several sessions to the same CD or DVD-R[W]:
|
||||
.br
|
||||
cdrskin dev=/dev/hdc padsize=300k -multi 1.iso
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso
|
||||
.br
|
||||
cdrskin dev=/dev/hdc padsize=300k -multi -tao 2.afio
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso
|
||||
.br
|
||||
cdrskin dev=/dev/hdc padsize=300k -multi -tao 3.afio
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso
|
||||
.br
|
||||
cdrskin dev=/dev/hdc padsize=300k -tao 4.afio
|
||||
cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso
|
||||
.SS
|
||||
.B Get CD 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/sr0 -msinfo 2>/dev/null)
|
||||
.br
|
||||
@ -634,9 +742,7 @@ mkisofs ... -C "$c_values" ...
|
||||
.SS
|
||||
.B Write audio tracks to CD:
|
||||
.br
|
||||
cdrskin -v dev=ATA:1,0,0 speed=48 \\
|
||||
.br
|
||||
driveropts=burnfree -sao \\
|
||||
cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
|
||||
.br
|
||||
track1.wav track2.au -audio -swab track3.raw
|
||||
.br
|
||||
@ -691,7 +797,7 @@ Other CD/DVD burn programs:
|
||||
.BR wodim (1)
|
||||
.br
|
||||
.TP
|
||||
For DVD burning:
|
||||
For DVD burning (also tutor of libburn's DVD capabilities):
|
||||
.br
|
||||
.BR growisofs (1)
|
||||
.br
|
||||
|
@ -7,7 +7,7 @@ A cdrecord compatible command line interface for libburn.
|
||||
|
||||
This project is neither directed against original cdrecord nor does it exploit
|
||||
any source code of said program. It rather tries to be an alternative method
|
||||
to burn CD which is not based on the same code as cdrecord.
|
||||
to burn CD or DVD, which is not based on the same code as cdrecord.
|
||||
See also : http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||
|
||||
Interested users of cdrecord are encouraged to contribute further option
|
||||
@ -33,48 +33,10 @@ The implementation of an option would probably consist of
|
||||
See option blank= for an example.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
About compliance with *strong urge* of API towards burn_drive_scan_and_grab()
|
||||
|
||||
For a more comprehensive example of the advised way to behave with libburn
|
||||
see test/libburner.c .
|
||||
For a more comprehensive example of the advised way to write an application
|
||||
of libburn see test/libburner.c .
|
||||
|
||||
cdrskin was the initiator of the whitelist functionality within libburn.
|
||||
Now it has problems to obviously comply with the new API best practice
|
||||
presciptions literally. Therefore this explanation:
|
||||
|
||||
On start it restricts the library to a single drive if it already knows the
|
||||
persistent address by option dev= . This is done with a combination of
|
||||
burn_drive_add_whitelist() and burn_drive_scan(). Not compliant to the
|
||||
literal strong urge but in fact exactly fulfilling the reason for that
|
||||
urge in the API: any scanned drive might be opened exclusively after
|
||||
burn_drive_scan(). It is kernel dependent wether this behavior is on, off
|
||||
or switchable. The sysdamin will want it on - but only for one drive.
|
||||
|
||||
So with dev=... cdrskin complies to the spirit of the strong urge.
|
||||
Without dev=... it has to leave out the whitelist in order to enable bus
|
||||
scanning and implicit drive address 0. A tradition of 9 months shall not
|
||||
be broken. So burns without dev= will stay possible - but harmless only
|
||||
on single drive systems.
|
||||
|
||||
Burns without dev= resp. with dev=number are harmless on multi-drive systems.
|
||||
|
||||
This is because Cdrskin_grab_drive() either drops the unwanted drives or
|
||||
it enforces a restart of the library with the desired drive's persistent
|
||||
address. This restart then really uses the strongly urged function
|
||||
burn_drive_scan_and_grab().
|
||||
Thus, cdrskin complies with the new spirit of API by closing down libburn
|
||||
or by dropping unused drives as soon as the persistent drive address is
|
||||
known and the drive is to be used with a long running operation. To my
|
||||
knowlege all long running operations in cdrskin need a grabbed drive.
|
||||
|
||||
This spaghetti approach seems necessary to keep small the impact of new API
|
||||
urge on cdrskin's stability. cdrskin suffers from having donated the body
|
||||
parts which have been transplanted to libburn in order to create
|
||||
burn_drive_scan_and_grab() . The desired sysadmin friendlyness was already
|
||||
achieved by most cdrskin runs. The remaining problem situations should now
|
||||
be defused by releasing any short time grabbed flocks of drives during the
|
||||
restart of libburn.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
This program is currently copyright Thomas Schmitt only.
|
||||
The copyrights of several components of libburnia.pykix.org are willfully
|
||||
@ -124,7 +86,7 @@ or
|
||||
|
||||
/** The official program version */
|
||||
#ifndef Cdrskin_prog_versioN
|
||||
#define Cdrskin_prog_versioN "0.2.7"
|
||||
#define Cdrskin_prog_versioN "0.3.2"
|
||||
#endif
|
||||
|
||||
/** The source code release timestamp */
|
||||
@ -157,25 +119,24 @@ or
|
||||
#endif /* Cdrskin_libburn_cvs_A60220_tS */
|
||||
|
||||
|
||||
#ifdef Cdrskin_libburn_0_2_6
|
||||
#define Cdrskin_libburn_versioN "0.2.6"
|
||||
#ifdef Cdrskin_libburn_0_3_2
|
||||
#define Cdrskin_libburn_versioN "0.3.2"
|
||||
#define Cdrskin_libburn_from_pykix_svN 1
|
||||
#endif /* Cdrskin_libburn_0_2_6 */
|
||||
#endif /* Cdrskin_libburn_0_3_2 */
|
||||
|
||||
#ifdef Cdrskin_libburn_0_2_7
|
||||
#define Cdrskin_libburn_versioN "0.2.7"
|
||||
#ifdef Cdrskin_libburn_0_3_3
|
||||
#define Cdrskin_libburn_versioN "0.3.3"
|
||||
#define Cdrskin_libburn_from_pykix_svN 1
|
||||
#define Cdrskin_atip_speed_is_oK 1
|
||||
#define Cdrskin_no_aftergrab_loopS 1
|
||||
#define Cdrskin_libburn_has_get_profilE 1
|
||||
#define Cdrskin_libburn_has_set_start_bytE 1
|
||||
#define Cdrskin_libburn_has_wrote_welL 1
|
||||
#define Cdrskin_libburn_has_bd_formattinG 1
|
||||
#define Cdrskin_libburn_has_burn_disc_formaT 1
|
||||
#endif /* Cdrskin_libburn_0_2_7 */
|
||||
|
||||
/* Place novelty switch macros here.
|
||||
Move them down to Cdrskin_libburn_from_pykix_svN on version leap
|
||||
*/
|
||||
/* no novelties yet */
|
||||
|
||||
#endif /* Cdrskin_libburn_0_3_3 */
|
||||
|
||||
#ifndef Cdrskin_libburn_versioN
|
||||
#define Cdrskin_libburn_versioN "0.2.6"
|
||||
#define Cdrskin_libburn_versioN "0.3.2"
|
||||
#define Cdrskin_libburn_from_pykix_svN 1
|
||||
#endif
|
||||
|
||||
@ -202,6 +163,15 @@ or
|
||||
#define Cdrskin_libburn_has_pretend_fulL 1
|
||||
#define Cdrskin_libburn_has_multI 1
|
||||
#define Cdrskin_libburn_has_buffer_min_filL 1
|
||||
#define Cdrskin_atip_speed_is_oK 1
|
||||
#define Cdrskin_libburn_has_get_profilE 1
|
||||
#define Cdrskin_libburn_has_set_start_bytE 1
|
||||
#define Cdrskin_libburn_has_wrote_welL 1
|
||||
#define Cdrskin_libburn_has_bd_formattinG 1
|
||||
#define Cdrskin_libburn_has_burn_disc_formaT 1
|
||||
#define Cdrskin_libburn_has_get_msc1 1
|
||||
#define Cdrskin_libburn_has_toc_entry_extensionS 1
|
||||
#define Cdrskin_libburn_has_get_multi_capS 1
|
||||
|
||||
#ifdef Cdrskin_new_api_tesT
|
||||
|
||||
@ -776,6 +746,7 @@ struct CdrtracK {
|
||||
int source_fd;
|
||||
int is_from_stdin;
|
||||
double fixed_size;
|
||||
double tao_to_sao_tsize;
|
||||
double padding;
|
||||
int set_by_padsize;
|
||||
int sector_pad_up; /* enforce single sector padding */
|
||||
@ -828,10 +799,10 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss,
|
||||
struct CdrtracK *o;
|
||||
int ret,skin_track_type;
|
||||
int Cdrskin_get_source(struct CdrskiN *skin, char *source_path,
|
||||
double *fixed_size, double *padding,
|
||||
int *set_by_padsize, int *track_type,
|
||||
int *track_type_by_default, int *swap_audio_bytes,
|
||||
int flag);
|
||||
double *fixed_size, double *tao_to_sao_tsize,
|
||||
double *padding, int *set_by_padsize,
|
||||
int *track_type, int *track_type_by_default,
|
||||
int *swap_audio_bytes, int flag);
|
||||
int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled,
|
||||
int *fifo_size, int *fifo_start_at, int flag);
|
||||
|
||||
@ -844,6 +815,7 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss,
|
||||
o->source_fd= -1;
|
||||
o->is_from_stdin= !!(flag&2);
|
||||
o->fixed_size= 0.0;
|
||||
o->tao_to_sao_tsize= 0.0;
|
||||
o->padding= 0.0;
|
||||
o->set_by_padsize= 0;
|
||||
o->sector_pad_up= Cdrskin_all_tracks_with_sector_paD;
|
||||
@ -860,7 +832,8 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss,
|
||||
o->ff_fifo= NULL;
|
||||
o->ff_idx= -1;
|
||||
o->libburn_track= NULL;
|
||||
ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size),&(o->padding),
|
||||
ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size),
|
||||
&(o->tao_to_sao_tsize),&(o->padding),
|
||||
&(o->set_by_padsize),&(skin_track_type),
|
||||
&(o->track_type_by_default),&(o->swap_audio_bytes),
|
||||
0);
|
||||
@ -933,6 +906,7 @@ int Cdrtrack_get_track_type(struct CdrtracK *o, int *track_type,
|
||||
rather than the predicted fixed_size (if available).
|
||||
padding returns the difference from number of written
|
||||
bytes.
|
||||
bit1= size returns fixed_size, padding returns tao_to_sao_tsize
|
||||
*/
|
||||
int Cdrtrack_get_size(struct CdrtracK *track, double *size, double *padding,
|
||||
double *sector_size, int flag)
|
||||
@ -951,7 +925,8 @@ int Cdrtrack_get_size(struct CdrtracK *track, double *size, double *padding,
|
||||
fprintf(stderr,"cdrskin_debug: sizeof(off_t)=%d\n",
|
||||
sizeof(off_t));
|
||||
*/
|
||||
}
|
||||
} else if(flag&2)
|
||||
*padding= track->tao_to_sao_tsize;
|
||||
|
||||
#endif
|
||||
*sector_size= track->sector_size;
|
||||
@ -1324,6 +1299,14 @@ flag:
|
||||
}
|
||||
|
||||
|
||||
int Cdrtrack_activate_tao_tsize(struct CdrtracK *track, int flag)
|
||||
{
|
||||
if(track->fixed_size<=0.0)
|
||||
track->fixed_size= track->tao_to_sao_tsize;
|
||||
return(track->fixed_size>0.0);
|
||||
}
|
||||
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
|
||||
/** Try to read bytes from the track's fifo outlet and eventually discard
|
||||
@ -1834,6 +1817,10 @@ return:
|
||||
"\tformat_overwrite_quickest\tto \"Restricted Overwrite intermediate\"\n");
|
||||
fprintf(stderr,
|
||||
"\tformat_overwrite_full\tfull-size format a DVD-RW or DVD+RW\n");
|
||||
fprintf(stderr,
|
||||
"\tdeformat_sequential\tfully blank, even formatted DVD-RW\n");
|
||||
fprintf(stderr,
|
||||
"\tdeformat_sequential_quickest\tminimally blank, even DVD-RW\n");
|
||||
|
||||
#else /* ! Cdrskin_extra_leaN */
|
||||
|
||||
@ -2029,6 +2016,8 @@ set_dev:;
|
||||
" --no_rc as first argument: do not read startup files\n");
|
||||
printf(" --old_pseudo_scsi_adr use and report literal Bus,Target,Lun\n");
|
||||
printf(" rather than real SCSI and pseudo ATA.\n");
|
||||
printf(" --prodvd_cli_compatible react on some DVD types more like\n");
|
||||
printf(" cdrecord-ProDVD with blank= and -multi\n");
|
||||
printf(
|
||||
" --single_track accept only last argument as source_address\n");
|
||||
|
||||
@ -2366,6 +2355,7 @@ struct CdrskiN {
|
||||
int dummy_mode;
|
||||
int force_is_set;
|
||||
int single_track;
|
||||
int prodvd_cli_compatible;
|
||||
|
||||
int do_devices;
|
||||
|
||||
@ -2389,7 +2379,7 @@ struct CdrskiN {
|
||||
bit8 = write zeros after formatting
|
||||
bit9 = insist in size 0
|
||||
bit10= format to maximum available size
|
||||
2=format_sequential (unimplemented yet)
|
||||
2=deformat_sequential (blank_fast might matter)
|
||||
*/
|
||||
double blank_format_size; /* to be used with burn_disc_format() */
|
||||
|
||||
@ -2505,6 +2495,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
|
||||
o->dummy_mode= 0;
|
||||
o->force_is_set= 0;
|
||||
o->single_track= 0;
|
||||
o->prodvd_cli_compatible= 0;
|
||||
o->do_devices= 0;
|
||||
o->do_scanbus= 0;
|
||||
o->do_checkdrive= 0;
|
||||
@ -2522,7 +2513,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
|
||||
o->block_type= BURN_BLOCK_SAO;
|
||||
o->multi= 0;
|
||||
o->write_start_address= -1.0;
|
||||
o->burnfree= 0;
|
||||
o->burnfree= 1;
|
||||
o->do_eject= 0;
|
||||
o->eject_device[0]= 0;
|
||||
o->source_path[0]= 0;
|
||||
@ -2609,13 +2600,14 @@ int Cdrskin_set_msinfo_fd(struct CdrskiN *skin, int result_fd, int flag)
|
||||
|
||||
/** Return information about current track source */
|
||||
int Cdrskin_get_source(struct CdrskiN *skin, char *source_path,
|
||||
double *fixed_size, double *padding,
|
||||
int *set_by_padsize, int *track_type,
|
||||
int *track_type_by_default, int *swap_audio_bytes,
|
||||
int flag)
|
||||
double *fixed_size, double *tao_to_sao_tsize,
|
||||
double *padding, int *set_by_padsize,
|
||||
int *track_type, int *track_type_by_default,
|
||||
int *swap_audio_bytes, int flag)
|
||||
{
|
||||
strcpy(source_path,skin->source_path);
|
||||
*fixed_size= skin->fixed_size;
|
||||
*tao_to_sao_tsize = skin->tao_to_sao_tsize;
|
||||
*padding= skin->padding;
|
||||
*set_by_padsize= skin->set_by_padsize;
|
||||
*track_type= skin->track_type;
|
||||
@ -3512,7 +3504,7 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
|
||||
enum burn_disc_status s;
|
||||
struct burn_drive *drive;
|
||||
struct burn_disc *disc= NULL;
|
||||
struct burn_session **sessions;
|
||||
struct burn_session **sessions= NULL;
|
||||
struct burn_track **tracks;
|
||||
struct burn_toc_entry toc_entry;
|
||||
|
||||
@ -3520,24 +3512,22 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
drive= skin->drives[skin->driveno].drive;
|
||||
|
||||
#ifndef Cdrskin_no_aftergrab_loopS
|
||||
while(burn_drive_get_status(drive,NULL) != BURN_DRIVE_IDLE)
|
||||
usleep(100002);
|
||||
while ((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
|
||||
usleep(100002);
|
||||
#else
|
||||
s= burn_disc_get_status(drive);
|
||||
#endif /* ! Cdrskin_no_aftergrab_loopS */
|
||||
|
||||
if(s!=BURN_DISC_APPENDABLE) {
|
||||
Cdrskin_report_disc_status(skin,s,0);
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) CD\n");
|
||||
fprintf(stderr,"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) discs\n");
|
||||
{ret= 0; goto ex;}
|
||||
}
|
||||
disc= burn_drive_get_disc(drive);
|
||||
if(disc==NULL) {
|
||||
|
||||
#ifdef Cdrskin_libburn_has_get_msc1
|
||||
/* No TOC available. Try to inquire directly. */
|
||||
ret= burn_disc_get_msc1(drive,&lba);
|
||||
if(ret>0)
|
||||
goto obtain_nwa;
|
||||
#endif /* Cdrskin_libburn_has_get_msc1 */
|
||||
|
||||
fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n");
|
||||
{ret= 0; goto ex;}
|
||||
}
|
||||
@ -3547,19 +3537,42 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
|
||||
if(tracks==NULL || num_tracks<=0)
|
||||
continue;
|
||||
burn_track_get_entry(tracks[0],&toc_entry);
|
||||
lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
#ifdef Cdrskin_libburn_has_toc_entry_extensionS
|
||||
if(toc_entry.extensions_valid&1) { /* DVD extension valid */
|
||||
lba= toc_entry.start_lba;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
|
||||
lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
}
|
||||
}
|
||||
if(lba==-123456789) {
|
||||
fprintf(stderr,"cdrskin: FATAL : Cannot find any track on CD\n");
|
||||
{ret= 0; goto ex;}
|
||||
}
|
||||
|
||||
obtain_nwa:;
|
||||
ret= Cdrskin_obtain_nwa(skin,&nwa,flag);
|
||||
if(ret<=0) {
|
||||
if (sessions == NULL) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : Cannot obtain next writeable address\n");
|
||||
{ret= 0; goto ex;}
|
||||
}
|
||||
fprintf(stderr,
|
||||
"cdrskin: NOTE : Guessing next writeable address from leadout\n");
|
||||
burn_session_get_leadout_entry(sessions[num_sessions-1],&toc_entry);
|
||||
aux_lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
#ifdef Cdrskin_libburn_has_toc_entry_extensionS
|
||||
if(toc_entry.extensions_valid&1) { /* DVD extension valid */
|
||||
aux_lba= toc_entry.start_lba;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
aux_lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
}
|
||||
if(num_sessions>0)
|
||||
nwa= aux_lba+6900;
|
||||
else
|
||||
@ -3607,7 +3620,7 @@ ex:;
|
||||
int Cdrskin_toc(struct CdrskiN *skin, int flag)
|
||||
{
|
||||
int num_sessions= 0,num_tracks= 0,lba= 0,track_count= 0,total_tracks= 0;
|
||||
int session_no, track_no;
|
||||
int session_no, track_no, pmin, psec, pframe;
|
||||
struct burn_drive *drive;
|
||||
struct burn_disc *disc= NULL;
|
||||
struct burn_session **sessions;
|
||||
@ -3636,11 +3649,26 @@ int Cdrskin_toc(struct CdrskiN *skin, int flag)
|
||||
for(track_no= 0; track_no<num_tracks; track_no++) {
|
||||
track_count++;
|
||||
burn_track_get_entry(tracks[track_no], &toc_entry);
|
||||
lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
|
||||
#ifdef Cdrskin_libburn_has_toc_entry_extensionS
|
||||
if(toc_entry.extensions_valid&1) { /* DVD extension valid */
|
||||
lba= toc_entry.start_lba;
|
||||
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
|
||||
pmin= toc_entry.pmin;
|
||||
psec= toc_entry.psec;
|
||||
pframe= toc_entry.pframe;
|
||||
lba= burn_msf_to_lba(pmin,psec,pframe);
|
||||
}
|
||||
|
||||
if(track_no==0 && burn_session_get_hidefirst(sessions[session_no]))
|
||||
printf("cdrskin: NOTE : first track is marked as \"hidden\".\n");
|
||||
printf("track: %2d lba: %9d (%9d) %2.2u:%2.2u:%2.2u",track_count,
|
||||
lba,4*lba,toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
printf("track: %2d lba: %9d (%9d) %2.2d:%2.2d:%2.2d",track_count,
|
||||
lba,4*lba,pmin,psec,pframe);
|
||||
printf(" adr: %d control: %d",toc_entry.adr,toc_entry.control);
|
||||
|
||||
/* >>> From where does cdrecord take "mode" ? */
|
||||
@ -3655,9 +3683,23 @@ int Cdrskin_toc(struct CdrskiN *skin, int flag)
|
||||
if((flag&1) && session_no<num_sessions-1)
|
||||
continue;
|
||||
burn_session_get_leadout_entry(sessions[session_no],&toc_entry);
|
||||
lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
printf("track:lout lba: %9d (%9d) %2.2u:%2.2u:%2.2u",
|
||||
lba,4*lba,toc_entry.pmin,toc_entry.psec,toc_entry.pframe);
|
||||
|
||||
#ifdef Cdrskin_libburn_has_toc_entry_extensionS
|
||||
if(toc_entry.extensions_valid&1) { /* DVD extension valid */
|
||||
lba= toc_entry.start_lba;
|
||||
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
|
||||
pmin= toc_entry.pmin;
|
||||
psec= toc_entry.psec;
|
||||
pframe= toc_entry.pframe;
|
||||
lba= burn_msf_to_lba(pmin,psec,pframe);
|
||||
}
|
||||
printf("track:lout lba: %9d (%9d) %2.2d:%2.2d:%2.2d",
|
||||
lba,4*lba,pmin,psec,pframe);
|
||||
printf(" adr: %d control: %d",toc_entry.adr,toc_entry.control);
|
||||
printf(" mode: -1\n");
|
||||
}
|
||||
@ -3690,16 +3732,7 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
drive= skin->drives[skin->driveno].drive;
|
||||
|
||||
#ifndef Cdrskin_no_aftergrab_loopS
|
||||
while(burn_drive_get_status(drive,NULL) != BURN_DRIVE_IDLE)
|
||||
usleep(100002);
|
||||
while ((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
|
||||
usleep(100002);
|
||||
#else
|
||||
s= burn_disc_get_status(drive);
|
||||
#endif
|
||||
|
||||
Cdrskin_report_disc_status(skin,s,0);
|
||||
if(s==BURN_DISC_APPENDABLE && skin->no_blank_appendable) {
|
||||
is_not_really_erasable= 1;
|
||||
@ -3919,10 +3952,10 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
||||
int ret,loop_counter= 0,hint_force= 0,do_format= 0, profile_number= -1;
|
||||
int wrote_well= 1;
|
||||
double start_time;
|
||||
char *verb= "format", *presperf="blanking", *fmt_text= "format_...";
|
||||
char *verb= "blank", *presperf="blanking", *fmt_text= "...";
|
||||
char profile_name[80];
|
||||
static char fmtp[][40]= {
|
||||
"format_default", "format_overwrite", "format_sequential"};
|
||||
"format_default", "format_overwrite", "deformat_sequential"};
|
||||
static int fmtp_max= 2;
|
||||
|
||||
start_time= Sfile_microtime(0); /* will be refreshed later */
|
||||
@ -3930,16 +3963,7 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
drive= skin->drives[skin->driveno].drive;
|
||||
|
||||
#ifndef Cdrskin_no_aftergrab_loopS
|
||||
while(burn_drive_get_status(drive,NULL) != BURN_DRIVE_IDLE)
|
||||
usleep(100002);
|
||||
while ((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
|
||||
usleep(100002);
|
||||
#else
|
||||
s= burn_disc_get_status(drive);
|
||||
#endif
|
||||
|
||||
profile_name[0]= 0;
|
||||
#ifdef Cdrskin_libburn_has_get_profilE
|
||||
if(skin->grabbed_drive)
|
||||
@ -3949,7 +3973,7 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
Cdrskin_report_disc_status(skin,s,0);
|
||||
do_format= skin->blank_format_type & 0xff;
|
||||
if(do_format) {
|
||||
if(do_format == 1) {
|
||||
verb= "format";
|
||||
presperf= "formatting";
|
||||
}
|
||||
@ -3957,8 +3981,7 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
||||
#ifdef Cdrskin_libburn_has_pretend_fulL
|
||||
if(s==BURN_DISC_UNSUITABLE) {
|
||||
if(skin->force_is_set) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: NOTE : -force blank=... : Treating unsuitable media as burn_disc_full\n");
|
||||
fprintf(stderr,"cdrskin: NOTE : -force blank=... : Treating unsuitable media as burn_disc_full\n");
|
||||
ret= burn_disc_pretend_full(drive);
|
||||
s= burn_disc_get_status(drive);
|
||||
} else
|
||||
@ -3966,29 +3989,24 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
|
||||
}
|
||||
#endif /* Cdrskin_libburn_has_pretend_fulL */
|
||||
|
||||
if(do_format) {
|
||||
if(do_format)
|
||||
if(do_format>=0 && do_format<=fmtp_max)
|
||||
fmt_text= fmtp[do_format];
|
||||
if(do_format!=1) {
|
||||
|
||||
/* >>> other formats to come. At least _sequential */;
|
||||
if(do_format==2) {
|
||||
/* Forceful blanking to Sequential Recording for DVD-R[W] and CD-RW */
|
||||
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : only blank=%s is implemented yet\n",fmtp[1]);
|
||||
return(0);
|
||||
} else if(profile_number == 0x14) { /* DVD-RW sequential */
|
||||
if(do_format!=1)
|
||||
goto unsupported_format_type;
|
||||
} else if(profile_number == 0x13) { /* DVD-RW restricted overwrite */
|
||||
if(do_format==1 && skin->force_is_set) {
|
||||
if(!(profile_number == 0x14 || profile_number == 0x13 ||
|
||||
profile_number == 0x0a))
|
||||
goto unsupported_format_type;
|
||||
|
||||
} else if (do_format==1) {
|
||||
/* Formatting to become overwriteable for DVD-RW and DVD+RW */
|
||||
|
||||
if(profile_number == 0x14) { /* DVD-RW sequential */
|
||||
/* ok */;
|
||||
} else if(do_format!=1) {
|
||||
unsupported_format_type:;
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : blank=%s : unsupported format and/or media type\n",
|
||||
fmt_text);
|
||||
return(0);
|
||||
} else {
|
||||
} else if(profile_number == 0x13) { /* DVD-RW restricted overwrite */
|
||||
if(!(skin->force_is_set || ((skin->blank_format_type>>8)&4))) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: NOTE : blank=format_... : media is already formatted\n");
|
||||
fprintf(stderr,
|
||||
@ -3996,15 +4014,11 @@ unsupported_format_type:;
|
||||
return(2);
|
||||
}
|
||||
} else if(profile_number == 0x1a) { /* DVD+RW */
|
||||
if(do_format!=1)
|
||||
goto unsupported_format_type;
|
||||
if(!((skin->blank_format_type>>8)&4)) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: NOTE : blank=format_... : DVD+RW do not need this\n");
|
||||
fprintf(stderr,
|
||||
"cdrskin: HINT : For de-icing use option blank=format_overwrite_full");
|
||||
fprintf(stderr,
|
||||
"cdrskin: HINT : If you really want to re-format, add option -force\n");
|
||||
return(2);
|
||||
}
|
||||
} else {
|
||||
@ -4017,10 +4031,12 @@ unsupported_format_type:;
|
||||
"cdrskin: NOTE : blank=%s accepted not yet suitable media\n",
|
||||
fmt_text);
|
||||
|
||||
} else { /* do_format */
|
||||
} else if(do_format==0) {
|
||||
/* Classical blanking of erasable media */
|
||||
|
||||
if(s!=BURN_DISC_FULL &&
|
||||
(s!=BURN_DISC_APPENDABLE || skin->no_blank_appendable)) {
|
||||
(s!=BURN_DISC_APPENDABLE || skin->no_blank_appendable) &&
|
||||
!(profile_number == 0x13 && skin->prodvd_cli_compatible)) {
|
||||
Cdrskin_release_drive(skin,0);
|
||||
if(s==BURN_DISC_BLANK) {
|
||||
fprintf(stderr,
|
||||
@ -4042,8 +4058,17 @@ unsupported_format_type:;
|
||||
fprintf(stderr,"cdrskin: FATAL : blank=... : media is not erasable\n");
|
||||
return(0);
|
||||
}
|
||||
if((profile_number == 0x14 || profile_number == 0x13) &&
|
||||
!skin->prodvd_cli_compatible)
|
||||
skin->blank_fast= 0; /* only with deformat_sequential_quickest */
|
||||
|
||||
} /* ! do_format */
|
||||
} else {
|
||||
unsupported_format_type:;
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : blank=%s is unsupported with media type %s\n",
|
||||
fmt_text, profile_name);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(skin->dummy_mode) {
|
||||
fprintf(stderr,
|
||||
@ -4055,11 +4080,11 @@ unsupported_format_type:;
|
||||
Cdrskin_adjust_speed(skin,0);
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
Cdrskin_wait_before_action(skin,1+(!!do_format));
|
||||
Cdrskin_wait_before_action(skin,1+(do_format==1));
|
||||
#endif /* ! Cdrskin_extra_leaN */
|
||||
|
||||
skin->drive_is_busy= 1;
|
||||
if(do_format==0) {
|
||||
if(do_format==0 || do_format==2) {
|
||||
burn_disc_erase(drive,skin->blank_fast);
|
||||
|
||||
#ifdef Cdrskin_libburn_has_burn_disc_formaT
|
||||
@ -4069,10 +4094,6 @@ unsupported_format_type:;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
/* >>> */;
|
||||
|
||||
/* <<< */
|
||||
fprintf(stderr,"cdrskin: SORRY : Format type %d not implemented yet.\n",
|
||||
do_format);
|
||||
ret= 0; goto ex;
|
||||
@ -4102,7 +4123,7 @@ blanking_done:;
|
||||
fprintf(stderr,
|
||||
"\rcdrskin: %s done \n",
|
||||
presperf);
|
||||
printf("%s time: %.3fs\n",(do_format?"Formatting":"Blanking"),
|
||||
printf("%s time: %.3fs\n",(do_format==1?"Formatting":"Blanking"),
|
||||
Sfile_microtime(0)-start_time);
|
||||
}
|
||||
fflush(stdout);
|
||||
@ -4338,16 +4359,16 @@ thank_you_for_patience:;
|
||||
Cdrfifo_get_counters(skin->fifo,&curr_fifo_in,&curr_fifo_out,0);
|
||||
Cdrfifo_get_sizes(skin->fifo,&bs,&fs,0);
|
||||
}
|
||||
}
|
||||
if(skin->fifo_size>0) {
|
||||
sprintf(fifo_text,"(fifo %3d%%) ",fifo_percent);
|
||||
if(skin->verbosity>=Cdrskin_verbose_debug_fifO) {
|
||||
fprintf(stderr,
|
||||
"\ncdrskin_debug: fifo >= %9d / %d : %8.f in, %8.f out\n",
|
||||
fill,(int) buffer_size,
|
||||
curr_fifo_in-last_fifo_in,curr_fifo_out-last_fifo_out);
|
||||
last_fifo_in= curr_fifo_in;
|
||||
last_fifo_out= curr_fifo_out;
|
||||
if(skin->fifo_size>0) {
|
||||
sprintf(fifo_text,"(fifo %3d%%) ",fifo_percent);
|
||||
if(skin->verbosity>=Cdrskin_verbose_debug_fifO) {
|
||||
fprintf(stderr,
|
||||
"\ncdrskin_debug: fifo >= %9d / %d : %8.f in, %8.f out\n",
|
||||
fill,(int) buffer_size,
|
||||
curr_fifo_in-last_fifo_in,curr_fifo_out-last_fifo_out);
|
||||
last_fifo_in= curr_fifo_in;
|
||||
last_fifo_out= curr_fifo_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(skin->supposed_track_idx >= 0 &&
|
||||
@ -4435,9 +4456,14 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
||||
int flag)
|
||||
{
|
||||
int ok, was_still_default= 0, block_type_demand,track_type,sector_size, i;
|
||||
int profile_number= -1;
|
||||
int profile_number= -1, track_type_1= 0, mixed_mode= 0, unpredicted_size= 0;
|
||||
int might_do_tao= 0, might_do_sao= 1, allows_multi= 1, ret;
|
||||
struct burn_drive_info *drive_info = NULL;
|
||||
char profile_name[80];
|
||||
double fixed_size= 0.0, tao_to_sao_tsize= 0.0, dummy;
|
||||
#ifdef Cdrskin_libburn_has_get_multi_capS
|
||||
struct burn_multi_caps *caps = NULL;
|
||||
#endif
|
||||
|
||||
profile_name[0]= 0;
|
||||
#ifdef Cdrskin_libburn_has_get_profilE
|
||||
@ -4445,15 +4471,53 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
||||
burn_disc_get_profile(skin->grabbed_drive,&profile_number,profile_name);
|
||||
#endif
|
||||
|
||||
#ifdef Cdrskin_allow_libburn_taO
|
||||
might_do_tao= 1;
|
||||
#endif
|
||||
#ifdef Cdrskin_libburn_has_get_multi_capS
|
||||
ret = burn_disc_get_multi_caps(skin->grabbed_drive,BURN_WRITE_NONE,&caps,0);
|
||||
if (ret<0) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : Cannot obtain write mode capabilities of drive\n");
|
||||
return(0);
|
||||
} else if(ret==0) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : Cannot find any suitable write mode for this media\n");
|
||||
burn_disc_free_multi_caps(&caps);
|
||||
return(0);
|
||||
}
|
||||
might_do_tao= caps->might_do_tao;
|
||||
might_do_sao= caps->might_do_sao;
|
||||
burn_disc_free_multi_caps(&caps);
|
||||
#endif
|
||||
|
||||
for(i=0;i<skin->track_counter;i++) {
|
||||
Cdrtrack_get_track_type(skin->tracklist[i],&track_type,§or_size,0);
|
||||
if(i==0)
|
||||
track_type_1= track_type;
|
||||
else if(track_type_1!=track_type)
|
||||
mixed_mode= 1;
|
||||
Cdrtrack_get_size(skin->tracklist[i],&fixed_size,
|
||||
&tao_to_sao_tsize,&dummy,2);
|
||||
if(fixed_size<=0)
|
||||
unpredicted_size= 1+(tao_to_sao_tsize<=0);
|
||||
}
|
||||
|
||||
if(strcmp(skin->preskin->write_mode_name,"DEFAULT")==0) {
|
||||
was_still_default= 1;
|
||||
|
||||
if(s == BURN_DISC_APPENDABLE) {
|
||||
if((s == BURN_DISC_APPENDABLE || mixed_mode) && might_do_tao) {
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
was_still_default= 2; /*<<< prevents trying of SAO if drive dislikes TAO*/
|
||||
} else if(profile_number==0x1a || profile_number==0x13 ||
|
||||
profile_number==0x12) {
|
||||
/* DVD+RW , DVD-RW Restricted Overwrite , DVD-RAM */
|
||||
was_still_default= 2; /* prevents trying of SAO if drive dislikes TAO*/
|
||||
} else if(unpredicted_size && might_do_tao) {
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
if(unpredicted_size>1)
|
||||
was_still_default= 2; /* prevents trying of SAO */
|
||||
} else if((profile_number==0x1a || profile_number==0x13 ||
|
||||
profile_number==0x12 ||
|
||||
profile_number==0x11 || profile_number==0x14)
|
||||
&& might_do_tao) {
|
||||
/* DVD+RW, DVD-RW Restr. Overwrite, DVD-RAM, DVD-R, DVD-RW Sequential */
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
} else {
|
||||
strcpy(skin->preskin->write_mode_name,"SAO");
|
||||
@ -4465,7 +4529,6 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
||||
|
||||
#ifdef Cdrskin_allow_libburn_taO
|
||||
} else if(strcmp(skin->preskin->write_mode_name,"TAO")==0) {
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
skin->write_type= BURN_WRITE_TAO;
|
||||
skin->block_type= BURN_BLOCK_MODE1;
|
||||
#endif /* Cdrskin_allow_libburn_taO */
|
||||
@ -4495,10 +4558,14 @@ check_with_drive:;
|
||||
|
||||
/* >>> drive_info does not reflect DVD capabilities yet */
|
||||
|
||||
ok= 1;
|
||||
ok= 0;
|
||||
if(skin->write_type==BURN_WRITE_SAO && might_do_sao)
|
||||
ok= 1;
|
||||
if(skin->write_type==BURN_WRITE_TAO && might_do_tao)
|
||||
ok= 1;
|
||||
} else if(skin->write_type==BURN_WRITE_RAW)
|
||||
ok= !!(drive_info->raw_block_types & BURN_BLOCK_RAW96R);
|
||||
else if(skin->write_type==BURN_WRITE_SAO)
|
||||
else if(skin->write_type==BURN_WRITE_SAO && !mixed_mode)
|
||||
ok= !!(drive_info->sao_block_types & BURN_BLOCK_SAO);
|
||||
else if(skin->write_type==BURN_WRITE_TAO) {
|
||||
block_type_demand= 0;
|
||||
@ -4512,6 +4579,24 @@ check_with_drive:;
|
||||
ok= ((drive_info->tao_block_types & block_type_demand)==block_type_demand);
|
||||
}
|
||||
|
||||
if(skin->write_type==BURN_WRITE_SAO && mixed_mode) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : Cannot write mix of data and audio in SAO mode\n");
|
||||
if(might_do_tao)
|
||||
fprintf(stderr,
|
||||
"cdrskin: HINT : Try with option -tao resp. without -sao\n");
|
||||
return(0);
|
||||
}
|
||||
if(skin->write_type==BURN_WRITE_SAO && unpredicted_size>1) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : At least one track has no predictable size.\n");
|
||||
fprintf(stderr,
|
||||
"cdrskin: HINT : Use tsize= or tao_to_sao_tsize= to announce the track size\n");
|
||||
if(might_do_tao)
|
||||
fprintf(stderr,
|
||||
"cdrskin: HINT : or try with option -tao resp. without -sao\n");
|
||||
return(0);
|
||||
}
|
||||
if(!ok) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: %s : Drive indicated refusal for write mode %s.\n",
|
||||
@ -4519,24 +4604,55 @@ check_with_drive:;
|
||||
skin->preskin->write_mode_name);
|
||||
if(! skin->force_is_set) {
|
||||
if(was_still_default==1) {
|
||||
if(skin->write_type==BURN_WRITE_RAW ||
|
||||
skin->write_type==BURN_WRITE_SAO) {
|
||||
was_still_default= 2; /* do not try more than once */
|
||||
if((skin->write_type==BURN_WRITE_RAW ||
|
||||
skin->write_type==BURN_WRITE_SAO) && might_do_tao) {
|
||||
skin->write_type= BURN_WRITE_TAO;
|
||||
skin->block_type= BURN_BLOCK_MODE1;
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
} else {
|
||||
goto check_with_drive;
|
||||
} else if (might_do_sao) {
|
||||
skin->write_type= BURN_WRITE_SAO;
|
||||
skin->block_type= BURN_BLOCK_SAO;
|
||||
strcpy(skin->preskin->write_mode_name,"SAO");
|
||||
goto check_with_drive;
|
||||
}
|
||||
was_still_default= 2; /* do not try more than once */
|
||||
goto check_with_drive;
|
||||
}
|
||||
fprintf(stderr,"cdrskin: HINT : If you are certain that the drive will do, try option -force\n");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Cdrskin_libburn_has_get_multi_capS
|
||||
ret = burn_disc_get_multi_caps(skin->grabbed_drive,skin->write_type,&caps,0);
|
||||
if (ret>0)
|
||||
allows_multi= caps->multi_session;
|
||||
burn_disc_free_multi_caps(&caps);
|
||||
#endif
|
||||
if(skin->multi && !allows_multi) {
|
||||
if(skin->prodvd_cli_compatible) {
|
||||
skin->multi= 0;
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
fprintf(stderr, "cdrskin: NOTE : Ignored option -multi.\n");
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : Cannot keep this media appendable after write by -multi\n");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
it_is_done:;
|
||||
if(skin->write_type==BURN_WRITE_SAO && unpredicted_size==1)
|
||||
for(i= 0; i<skin->track_counter; i++) {
|
||||
Cdrtrack_get_size(skin->tracklist[i],&fixed_size,
|
||||
&tao_to_sao_tsize,&dummy,2);
|
||||
if(fixed_size<=0.0 && tao_to_sao_tsize>0.0) {
|
||||
printf(
|
||||
"cdrskin: NOTE : augmenting non-tao write mode by tao_to_sao_tsize\n");
|
||||
printf("cdrskin: NOTE : fixed size : %.f\n",tao_to_sao_tsize);
|
||||
Cdrtrack_activate_tao_tsize(skin->tracklist[i],0);
|
||||
}
|
||||
}
|
||||
if(skin->verbosity>=Cdrskin_verbose_cmD)
|
||||
printf("cdrskin: write type : %s\n", skin->preskin->write_mode_name);
|
||||
return(1);
|
||||
@ -4564,14 +4680,41 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
|
||||
|
||||
printf("cdrskin: beginning to burn disk\n");
|
||||
|
||||
ret= Cdrskin_grab_drive(skin,0);
|
||||
if(ret<=0)
|
||||
goto burn_failed;
|
||||
drive= skin->drives[skin->driveno].drive;
|
||||
s= burn_disc_get_status(drive);
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
Cdrskin_report_disc_status(skin,s,0);
|
||||
|
||||
#ifdef Cdrskin_allow_libburn_taO
|
||||
if (s!=BURN_DISC_APPENDABLE && s!=BURN_DISC_BLANK) {
|
||||
#else
|
||||
if (s!=BURN_DISC_BLANK) {
|
||||
#endif
|
||||
Cdrskin_release_drive(skin,0);
|
||||
fprintf(stderr,"cdrskin: FATAL : no writeable media detected.\n");
|
||||
goto burn_failed;
|
||||
}
|
||||
ret= Cdrskin_activate_write_mode(skin,s,0);
|
||||
if(ret<=0) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : Cannot activate the desired write mode\n");
|
||||
goto burn_failed;
|
||||
}
|
||||
|
||||
disc= burn_disc_create();
|
||||
session= burn_session_create();
|
||||
ret= burn_disc_add_session(disc,session,BURN_POS_END);
|
||||
if(ret==0) {
|
||||
fprintf(stderr,"cdrskin: FATAL : cannot add session to disc object.\n");
|
||||
burn_failed:;
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
printf("cdrskin: burning failed\n");
|
||||
fprintf(stderr,"cdrskin: FATAL : burning failed.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
skin->fixed_size= 0.0;
|
||||
for(i=0;i<skin->track_counter;i++) {
|
||||
hflag= (skin->verbosity>=Cdrskin_verbose_debuG);
|
||||
@ -4580,59 +4723,24 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
|
||||
ret= Cdrtrack_add_to_session(skin->tracklist[i],i,session,hflag);
|
||||
if(ret<=0) {
|
||||
fprintf(stderr,"cdrskin: FATAL : cannot add track %d to session.\n",i+1);
|
||||
return(0);
|
||||
goto burn_failed;
|
||||
}
|
||||
Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size,0);
|
||||
if(size>0)
|
||||
skin->fixed_size+= size+padding;
|
||||
}
|
||||
|
||||
ret= Cdrskin_grab_drive(skin,0);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
drive= skin->drives[skin->driveno].drive;
|
||||
|
||||
#ifndef Cdrskin_no_aftergrab_loopS
|
||||
while(burn_drive_get_status(drive, NULL) != BURN_DRIVE_IDLE)
|
||||
usleep(100002); /* >>> ??? add a timeout ? */
|
||||
while((s= burn_disc_get_status(drive)) == BURN_DISC_UNREADY)
|
||||
usleep(100002); /* >>> ??? add a timeout ? */
|
||||
#else
|
||||
s= burn_disc_get_status(drive);
|
||||
#endif
|
||||
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
Cdrskin_report_disc_status(skin,s,0);
|
||||
|
||||
ret= Cdrskin_activate_write_mode(skin,s,0);
|
||||
if(ret<=0) {
|
||||
fprintf(stderr,
|
||||
"cdrskin: FATAL : Cannot activate the desired write mode\n");
|
||||
ret= 0; goto ex;
|
||||
}
|
||||
|
||||
#ifdef Cdrskin_libburn_has_multI
|
||||
if (s == BURN_DISC_APPENDABLE) {
|
||||
|
||||
if (s==BURN_DISC_APPENDABLE) {
|
||||
#ifdef Cdrskin_allow_sao_for_appendablE
|
||||
;
|
||||
#else
|
||||
if(skin->write_type!=BURN_WRITE_TAO) {
|
||||
Cdrskin_release_drive(skin,0);
|
||||
fprintf(stderr,"cdrskin: FATAL : For now only write mode -tao can be used with appendable disks\n");
|
||||
return(0);
|
||||
goto burn_failed;
|
||||
}
|
||||
#endif /* ! Cdrskin_allow_sao_for_appendablE */
|
||||
|
||||
} else if (s != BURN_DISC_BLANK) {
|
||||
#else
|
||||
if (s != BURN_DISC_BLANK) {
|
||||
#endif
|
||||
Cdrskin_release_drive(skin,0);
|
||||
fprintf(stderr,"cdrskin: FATAL : no writeable media detected.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
|
||||
@ -4696,9 +4804,6 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
|
||||
burn_write_opts_set_perform_opc(o, 0);
|
||||
|
||||
#ifdef Cdrskin_libburn_has_multI
|
||||
if(skin->multi)
|
||||
fprintf(stderr,
|
||||
"cdrskin: NOTE : Option -multi set. Media will be appendable.\n");
|
||||
burn_write_opts_set_multi(o,skin->multi);
|
||||
#endif
|
||||
|
||||
@ -4893,13 +4998,14 @@ fifo_full_at_end:;
|
||||
if(wrote_well) {
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
printf("cdrskin: burning done\n");
|
||||
} else {
|
||||
} else
|
||||
ret= 0;
|
||||
ex:;
|
||||
if(ret<=0) {
|
||||
if(skin->verbosity>=Cdrskin_verbose_progresS)
|
||||
printf("cdrskin: burning failed\n");
|
||||
fprintf(stderr,"cdrskin: FATAL : burning failed.\n");
|
||||
ret= 0;
|
||||
}
|
||||
ex:;
|
||||
skin->drive_is_busy= 0;
|
||||
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
||||
ClN(printf("cdrskin_debug: do_eject= %d\n",skin->do_eject));
|
||||
@ -5179,9 +5285,14 @@ set_blank:;
|
||||
skin->do_blank= 1;
|
||||
skin->blank_format_type= 1;
|
||||
skin->blank_format_size= 0;
|
||||
} else if(strcmp(cpt,"format_sequential")==0) {/* >>> not yet supported */
|
||||
} else if(strcmp(cpt,"deformat_sequential")==0) {
|
||||
skin->do_blank= 1;
|
||||
skin->blank_format_type= 2;
|
||||
skin->blank_fast= 0;
|
||||
} else if(strcmp(cpt,"deformat_sequential_quickest")==0) {
|
||||
skin->do_blank= 1;
|
||||
skin->blank_format_type= 2;
|
||||
skin->blank_fast= 1;
|
||||
} else if(strcmp(cpt,"help")==0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
continue;
|
||||
@ -5465,6 +5576,9 @@ set_padsize:;
|
||||
if(skin->verbosity>=Cdrskin_verbose_cmD)
|
||||
printf("cdrskin: padding : %.f\n",skin->padding);
|
||||
|
||||
} else if(strcmp(argv[i],"--prodvd_cli_compatible")==0) {
|
||||
skin->prodvd_cli_compatible= 1;
|
||||
|
||||
} else if(strcmp(argv[i],"-raw96r")==0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
|
||||
@ -5600,33 +5714,7 @@ track_too_large:;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(! source_has_size) {
|
||||
if(skin->fixed_size<=0.0) {
|
||||
if(strcmp(skin->preskin->write_mode_name,"TAO")==0) {
|
||||
/* with TAO it is ok to have an undefined track length */;
|
||||
|
||||
#ifdef Cdrskin_allow_libburn_taO
|
||||
} else if(strcmp(skin->preskin->write_mode_name,"DEFAULT")==0) {
|
||||
strcpy(skin->preskin->write_mode_name,"TAO");
|
||||
#endif
|
||||
|
||||
} else if(skin->tao_to_sao_tsize>0.0) {
|
||||
skin->fixed_size= skin->tao_to_sao_tsize;
|
||||
printf(
|
||||
"cdrskin: NOTE : augmenting non-tao write mode by tao_to_sao_tsize\n");
|
||||
printf("cdrskin: NOTE : fixed size : %.f\n",skin->fixed_size);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
#ifdef Cdrskin_allow_libburn_taO
|
||||
"cdrskin: FATAL : Track source '%s' needs -tao or tsize= or tao_to_sao_tsize=\n",
|
||||
#else
|
||||
"cdrskin: FATAL : Track source '%s' needs a fixed tsize= or tao_to_sao_tsize=\n",
|
||||
#endif
|
||||
skin->source_path);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(skin->track_counter>=Cdrskin_track_maX) {
|
||||
fprintf(stderr,"cdrskin: FATAL : too many tracks given. (max %d)\n",
|
||||
Cdrskin_track_maX);
|
||||
|
@ -25,7 +25,7 @@
|
||||
<P>
|
||||
<H2>Purpose:</H2>
|
||||
<UL>
|
||||
<LI>Burns preformatted data to CD-R or CD-RW</LI>
|
||||
<LI>Burns preformatted data to CD-R, CD-RW, DVD-R, DVD-RW, DVD-RAM, DVD+RW</LI>
|
||||
</UL>
|
||||
</P>
|
||||
<P>
|
||||
@ -34,9 +34,9 @@
|
||||
|
||||
<P>
|
||||
<H2>Hardware requirements:</H2>
|
||||
A CD recorder suitable for
|
||||
A CD/DVD recorder suitable for
|
||||
<A HREF="http://libburnia.pykix.org">libburnia.pykix.org</A>
|
||||
(SCSI or IDE/ATAPI writers compliant to mmc-3 standard).
|
||||
(SCSI or IDE/ATAPI writers compliant to standard MMC-3 or higher).
|
||||
<BR>
|
||||
</P>
|
||||
|
||||
@ -56,7 +56,7 @@ A CD recorder suitable for
|
||||
GPL software included:<BR>
|
||||
</H2>
|
||||
<DL>
|
||||
<DT>libburn-0.2.6</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>
|
||||
@ -88,37 +88,74 @@ and for data CD projects of <A HREF="http://www.k3b.org">K3b</A>
|
||||
(see <A HREF="#examples">examples</A>).
|
||||
Suitability for audio CD frontends has been improved much and is now being
|
||||
evaluated.<BR>
|
||||
Most DVD types are written in pseudo -tao modes which are very different
|
||||
from the write mode DAO used by cdrecord(-ProDVD). With DVD-R[W] cdrskin
|
||||
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:</DT>
|
||||
<DD>$ cdrskin -scanbus</DD>
|
||||
<DD>$ cdrskin dev=ATA -scanbus</DD>
|
||||
<DD>$ cdrskin --devices</DD>
|
||||
<DT>Get an overview of drives and their addresses:</DT>
|
||||
<DD>$<KBD> cdrskin -scanbus</KBD></DD>
|
||||
<DD>$<KBD> cdrskin dev=ATA -scanbus</KBD></DD>
|
||||
<DD>$<KBD> cdrskin --devices</KBD></DD>
|
||||
|
||||
<DT>Get info about a particular drive or loaded media:</DT>
|
||||
<DD>$ cdrskin dev=0,1,0 -checkdrive</DD>
|
||||
<DD>$ cdrskin dev=ATA:1,0,0 -atip</DD>
|
||||
<DD>$ cdrskin dev=/dev/hdc -toc</DD>
|
||||
<DT>Make used CD-RW writable again:</DT>
|
||||
<DD>$ cdrskin -v dev=/dev/sg1 blank=all -eject</DD>
|
||||
<DD>$ cdrskin -v dev=/dev/dvd blank=fast -eject</DD>
|
||||
<DT>Write ISO-9660 filesystem image:</DT>
|
||||
<DD>$ cdrskin -v dev=/dev/hdc speed=12 fs=8m driveropts=burnfree -sao -eject padsize=300k my_image.iso</DD>
|
||||
<DT>Write compressed afio archive on-the-fly :</DT>
|
||||
<DD>$ find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 driveropts=burnfree padsize=300k -tao -</DD>
|
||||
<DT>Write audio tracks:</DT>
|
||||
<DD>$ cdrskin -v dev=ATA:1,0,0 speed=48 driveropts=burnfree -sao track1.wav track2.au -audio -swab track3.raw
|
||||
<DD>
|
||||
<BR>
|
||||
<DD>$<KBD> cdrskin dev=0,1,0 -checkdrive</KBD></DD>
|
||||
<DD>$<KBD> cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -toc</KBD></DD>
|
||||
|
||||
<DT>Make used CD-RW or used unformatted DVD-RW writable again:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=fast -eject</KBD></DD>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/dvd blank=all -eject</KBD></DD>
|
||||
|
||||
<DT>Format DVD-RW to avoid need for blanking before re-use:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/sr0 blank=format_overwrite</KBD></DD>
|
||||
|
||||
<DT>De-format DVD-RW to make it capable of multi-session again:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/sr0 blank=deformat_sequential</KBD></DD>
|
||||
|
||||
<DT>Write ISO-9660 filesystem image as only one to blank or formatted media:
|
||||
</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
|
||||
<DD><KBD> -sao -eject padsize=300k my_image.iso</KBD></DD>
|
||||
|
||||
<DT>Write compressed afio archive on-the-fly:</DT>
|
||||
<DD>$<KBD> find . | afio -oZ - | \</KBD></DD>
|
||||
<DD><KBD> cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
|
||||
<DD><KBD> -tao padsize=300k -</KBD></DD>
|
||||
|
||||
<DT>Write several sessions to the same CD or DVD-R[W]:</DT>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso</KBD>
|
||||
</DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso</KBD>
|
||||
</DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso</KBD>
|
||||
</DD>
|
||||
<DD>$<KBD> cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso</KBD></DD>
|
||||
|
||||
<DT>Get CD or DVD-R[W] multi-session info for option -C of program mkisofs:</DT>
|
||||
<DD>$<KBD> c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)</KBD></DD>
|
||||
<DD>$<KBD> mkisofs ... -C "$c_values" ...</KBD></DD>
|
||||
|
||||
<DT>Write audio tracks to CD:</DT>
|
||||
<DD>$<KBD> cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
|
||||
<DD><KBD> track1.wav track2.au -audio -swab track3.raw</KBD></DD>
|
||||
|
||||
<DT>Get overview of the cdrecord compatible options:</DT>
|
||||
<DD><A HREF="cdrskin_help">$ cdrskin -help</A></DD>
|
||||
<DD>$<KBD> <A HREF="cdrskin_help">cdrskin -help</A></KBD></DD>
|
||||
|
||||
<DT>Get overview of the non-cdrecord options:</DT>
|
||||
<DD><A HREF="cdrskin__help">$ cdrskin --help</A></DD>
|
||||
<DD>$<KBD> <A HREF="cdrskin__help">cdrskin --help</A></KBD></DD>
|
||||
|
||||
<DT>Read the detailed manual page:</DT>
|
||||
<DD><A HREF="man_1_cdrskin.html">$ man cdrskin</A></DD>
|
||||
<DD>$<KBD> <A HREF="man_1_cdrskin.html">man cdrskin</A></KBD></DD>
|
||||
</DL>
|
||||
|
||||
<DL>
|
||||
<DT>Read about the standard for which cdrskin is striving:</DT>
|
||||
<DD><A HREF="http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html">
|
||||
$ man cdrecord</A></DD>
|
||||
<DD>$<KBD>
|
||||
<A HREF="http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html">
|
||||
man cdrecord</A></KBD></DD>
|
||||
<DD><B>Do not bother Joerg Schilling with any cdrskin problems.</B>
|
||||
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding
|
||||
this "don't bother Joerg" demand.)
|
||||
@ -153,10 +190,9 @@ rw-permissions and retry the bus scan as non-superuser.
|
||||
<P>
|
||||
<DL>
|
||||
<DT>Download as source code (see README):</DT>
|
||||
<DD><A HREF="cdrskin-0.2.6.pl02.tar.gz">cdrskin-0.2.6.pl02.tar.gz</A>
|
||||
(510 KB).
|
||||
<DD><A HREF="cdrskin-0.3.2.pl00.tar.gz">cdrskin-0.3.2.pl00.tar.gz</A>
|
||||
(570 KB).
|
||||
</DD>
|
||||
<DD>(Most recent patch: backported man page from cdrskin-0.2.7)</DD>
|
||||
<DD>
|
||||
The "stable" cdrskin tarballs are source code identical with "stable"
|
||||
libburn releases or with "stabilized" libburn SVN snapshots. They get
|
||||
@ -165,14 +201,14 @@ cdrskin is part of libburn - full libburn is provided with cdrskin releases.
|
||||
</DD>
|
||||
<DD> </DD>
|
||||
<DT>Download as single x86 binaries (untar and move to /usr/bin/cdrskin):</DT>
|
||||
<DD><A HREF="cdrskin_0.2.6.pl01-x86-suse9_0.tar.gz">
|
||||
cdrskin_0.2.6.pl01-x86-suse9_0.tar.gz</A>, (60 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.2.6.pl01-x86-suse9_0-static.tar.gz">
|
||||
cdrskin_0.2.6.pl01-x86-suse9_0-static.tar.gz</A>, (260 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>
|
||||
@ -199,23 +235,14 @@ cdrskin_0.2.6.pl01-x86-suse9_0-static.tar.gz</A>, (260 KB), -static compiled,
|
||||
<HR>
|
||||
|
||||
<P>
|
||||
Enhancements towards previous stable version cdrskin-0.2.4:
|
||||
Enhancements towards previous stable version cdrskin-0.3.0:
|
||||
<UL>
|
||||
<LI>Option <KBD><B>-tao</B></KBD> is fully enabled.<BR>
|
||||
SAO is still the preferred default but TAO is default if a track of
|
||||
unpredicted size is present (stdin, named pipe, ...) or if a follow-up
|
||||
session is written to an appendable CD.
|
||||
(This is an intentional deviation from cdrecord defaults which themselves
|
||||
have changed with the newest cdrecord versions.)
|
||||
</LI>
|
||||
<LI>Status report during blank, preparation and finalization improved.</LI>
|
||||
<LI>Bug fixed: Trailing trash appended to .wav files caused error message
|
||||
and, if exceeding fifo size, could even stall a burn.
|
||||
(Workaround: disable fifo by <KBD><B>fs=0</B></KBD>)</LI>
|
||||
<LI>Bug fixed: False speed with first pacifier cycle. Potential program
|
||||
abort by floating point exception (NaN).</LI>
|
||||
<LI>multi-session CDs: <KBD><B>-multi</B></KBD>, <KBD><B>-msinfo</B></KBD>,
|
||||
writing to appendable CDs (for now restricted to write mode TAO).</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>
|
||||
</P>
|
||||
|
||||
@ -223,23 +250,17 @@ Enhancements towards previous stable version cdrskin-0.2.4:
|
||||
|
||||
<P>
|
||||
<DL>
|
||||
<DT><H3>Development snapshot, version 0.2.7 :</H3></DT>
|
||||
<DD>Enhancements towards stable version 0.2.6:
|
||||
<DT><H3>Development snapshot, version 0.3.3 :</H3></DT>
|
||||
<DD>Enhancements towards stable version 0.3.2:
|
||||
<UL>
|
||||
<LI>Improved recognition of unsuitable media types</LI>
|
||||
<LI>Ban of chmod u+s is replaced by a loud warning</LI>
|
||||
<LI>Detailed man page (already backported to cdrskin-0.2.6.pl02)</LI>
|
||||
<LI>Burning to DVD+RW and DVD-RAM as non-multi, non-appending,
|
||||
single-track session</LI>
|
||||
<LI>Formatting and then burning to DVD-RW like to DVD+RW</LI>
|
||||
<LI>Emulation of new wodim option msifile=path</LI>
|
||||
<LI>- none yet -</LI>
|
||||
</UL>
|
||||
</DD>
|
||||
<DD> </DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 0.2.7</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin_0.2.7 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin_0.2.7 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.2.7)</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> </DD>
|
||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||
<A HREF="http://libburnia.pykix.org"> libburnia.pykix.org</A></DT>
|
||||
@ -259,15 +280,15 @@ admins with full system souvereignty.</DT>
|
||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||
</DD>
|
||||
<DD>
|
||||
<A HREF="cdrskin-0.2.7.tar.gz">cdrskin-0.2.7.tar.gz</A>
|
||||
(550 KB).
|
||||
<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.2.7-x86-suse9_0.tar.gz">
|
||||
cdrskin_0.2.7-x86-suse9_0.tar.gz</A>, (75 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.2.7-x86-suse9_0-static.tar.gz">
|
||||
cdrskin_0.2.7-x86-suse9_0-static.tar.gz</A>, (275 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>
|
||||
@ -283,6 +304,10 @@ Historic versions based on Derek's and Ben's
|
||||
<A HREF="http://icculus.org/burn">icculus.org/burn</A> :<BR>
|
||||
<A HREF="cdrskin-0.1.2.0.2.ts.tar.gz">cdrskin-0.1.2.0.2.ts.tar.gz</A><BR>
|
||||
<A HREF="cdrskin-0.1.3.0.2.ts.tar.gz">cdrskin-0.1.3.0.2.ts.tar.gz</A>
|
||||
<BR>
|
||||
Very special thanks to Andy Polyakov whose
|
||||
<A HREF="http://fy.chalmers.se/~appro/linux/DVD+RW/tools">dvd+rw-tools</A>
|
||||
provide libburn with invaluable examples on how to deal with DVD media.
|
||||
</P>
|
||||
|
||||
<HR>
|
||||
@ -325,7 +350,7 @@ is a GUI frontend which uses cdrecord for CD burning.)
|
||||
<DD><KBD>...</KBD></DD>
|
||||
<DD><KBD> 1,0,0 1) 'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM</KBD></DD>
|
||||
<DD>$ <KBD><B>export SCDBACKUP_SCSI_ADR="ATA:1,0,0"</B></KBD></DD>
|
||||
<DD>$ <KBD><B>export SCDBACKUP_CDRECORD="cdrskin -v -v tao_to_sao_tsize=650m"</B></KBD></DD>
|
||||
<DD>$ <KBD><B>export SCDBACKUP_CDRECORD="cdrskin -v -v"</B></KBD></DD>
|
||||
<DD>$ <KBD><B>scdbackup_home</B></KBD></DD>
|
||||
</DL>
|
||||
<DL>
|
||||
@ -334,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.2.6 : 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.
|
||||
|
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.01.14.133951"
|
||||
#define Cdrskin_timestamP "2007.02.10.120001"
|
||||
|
@ -13,17 +13,23 @@ Deliberate deviations of cdrskin from cdrecord compatibility:
|
||||
+ -sao is default where possible, -tao is default where needed
|
||||
(Note: cdrecord write mode defaults have changed in cdrtools-2.01.01a20)
|
||||
|
||||
+ driveropts=burnfree is default if the drive supports buffer underrun
|
||||
protection. If desired, use driveropts=noburnfree to disable this feature.
|
||||
|
||||
+ premature end of source is not an error and leads to full announced tracksize
|
||||
|
||||
+ -msinfo pushes all other messages to stderr. It works independent of
|
||||
other options which would prevent it with cdrecord (-atip, -scanbus, ...)
|
||||
|
||||
+ DVD+RW writing is like -tao on giant blank CD-RW.
|
||||
Same with DVD-RW in mode Restricted Overwrite.
|
||||
+ DVD track sources get not concateneated to a single track. In general DVD
|
||||
writing is quite different from cdrecord-ProDVD:
|
||||
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 "Restricted Overwrite" writing is like DVD+RW (i.e. like -tao).
|
||||
Formatting is done via cdrskin-specific blank=format_overwrite and not
|
||||
with option -format.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Changelog
|
||||
@ -1909,6 +1915,7 @@ Replaced setuid blocker by warning. People must know themselves what they do.
|
||||
------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.09.141837
|
||||
* Replaced ban of chmod u+s by loud warning
|
||||
|
||||
|
||||
11 Dec 2006 [484]
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/changelog.txt
|
||||
@ -1995,6 +2002,7 @@ Took more care for man page
|
||||
------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.13.221921
|
||||
* detailed man page for cdrskin
|
||||
|
||||
|
||||
13 Dec 2006 [503]
|
||||
cdrskin/changelog.txt
|
||||
Next cdrskin-0.2.7 cycle
|
||||
@ -2349,21 +2357,22 @@ Greeting the new year
|
||||
------------------------------------ cycle - cdrskin-0.2.7 - 2007.01.02.101027
|
||||
* Formatting and then burning to DVD-RW like to DVD+RW
|
||||
|
||||
2 Jan 2006 [576]
|
||||
|
||||
2 Jan 2007 [576]
|
||||
cdrskin/changelog.txt
|
||||
Next cdrskin-0.2.7 cycle
|
||||
|
||||
2 Jan 2006 [577]
|
||||
2 Jan 2007 [577]
|
||||
cdrskin/wiki_plain.txt
|
||||
cdrskin/README
|
||||
Some DVD-RW statements
|
||||
|
||||
2 Jan 2006 [578]
|
||||
2 Jan 2007 [578]
|
||||
test/libburner.c
|
||||
doc/comments
|
||||
Made use of formatting of DVD-RW
|
||||
|
||||
2 Jan 2006 [579]
|
||||
2 Jan 2007 [579]
|
||||
cdrskin/cdrskin.1
|
||||
Some DVD-RW statements
|
||||
|
||||
@ -2442,54 +2451,590 @@ Updated size estimation of development downloads
|
||||
cdrskin/changelog.txt
|
||||
Next cdrskin-0.2.7 cycle
|
||||
|
||||
[]
|
||||
2007.01.10.152350 [600]
|
||||
libburn/libburn.h
|
||||
libburn/mmc.c
|
||||
libburn/drive.c
|
||||
libburn/async.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Option -force enables re-formatting
|
||||
|
||||
[]
|
||||
2007.01.10.152520 [601]
|
||||
libburn/mmc.c
|
||||
Switched full formatting from type 10h to 00h which includes lead-out
|
||||
|
||||
[]
|
||||
2007.01.10.152812 [602]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
Removing writing of dummy data with blank=format_overwrite_full
|
||||
Removed writing of dummy data with blank=format_overwrite_full
|
||||
|
||||
2007.01.10.204839 [603]
|
||||
libburn/mmc.c
|
||||
libburn/async.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Enabled explicit full formatting of DVD+RW ("de-icing")
|
||||
|
||||
11 Jan 2007 [604]
|
||||
cdrskin/README
|
||||
Removed outdated option from startup file example
|
||||
|
||||
2007.01.11.131106 [605]
|
||||
libburn/mmc.c
|
||||
With full formatting prefer format 10h over 13h or 15h
|
||||
|
||||
2007.01.11.131302 [606]
|
||||
libburn/os-linux.h
|
||||
libburn/os-freebsd.h
|
||||
libburn/cleanup.c
|
||||
cdrskin/cleanup.c
|
||||
Kept SIGWINCH from spoiling a burn.
|
||||
|
||||
2007.01.11.131615 [607]
|
||||
libburn/init.c
|
||||
Sketched better handling of self-inflicted SIGs
|
||||
|
||||
2007.01.11.131716 [608]
|
||||
libburn/drive.c
|
||||
Removed surplus newlines from messages
|
||||
|
||||
2007.01.12.162239 [609]
|
||||
libburn/write.c
|
||||
libburn/spc.c
|
||||
libburn/mmc.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Enabled writing to DVD-RAM
|
||||
|
||||
2007.01.13.140812 [610] [611]
|
||||
libburn/sg-linux.c
|
||||
Implemented debugging messages for ATA enumeration
|
||||
|
||||
13 Jan 2007 [612]
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/README
|
||||
Documentation updates about DVD-RAM
|
||||
|
||||
2007.01.13.211425 [613]
|
||||
libburn/transport.h
|
||||
libburn/mmc.c
|
||||
Load array of format capacities into struct burn_drive
|
||||
|
||||
2007.01.13.211639 [614]
|
||||
libburn/libburn.h
|
||||
libburn/drive.c
|
||||
libburn/async.c
|
||||
Introduced API for inspection and selection of format capacities
|
||||
|
||||
13 Jan 2007 [615]
|
||||
test/telltoc.c
|
||||
Added printing of list of available formats
|
||||
|
||||
13 Jan 2007 [616]
|
||||
test/libburner.c
|
||||
Mentioned DVD-RAM where appropriate
|
||||
|
||||
2007.01.13.214259 [617]
|
||||
cdrskin/cdrskin.c
|
||||
Shifted fifo reporting to new 4-times -v verbosity level
|
||||
|
||||
2007.01.14.101742 [618]
|
||||
cdrskin/cdrskin.c
|
||||
Corrected bug with debug messages for fifo
|
||||
|
||||
2007.01.14.115347 [619]
|
||||
libburn/write.c
|
||||
Added missing cache sync in case of aborted DVD-RW burns
|
||||
|
||||
2007.01.14.133951 [620]
|
||||
libburn/transport.h
|
||||
libburn/mmc.c
|
||||
libburn/write.c
|
||||
Avoided closing of 0x13-DVD-RW sessions which are not intermediate
|
||||
|
||||
15 Jan 2007 [621]
|
||||
cdrskin/wiki_plain.txt
|
||||
Updated about overwriteable DVD and pointer to dvd+rw-tools
|
||||
|
||||
|
||||
Format DVD+RW ?
|
||||
------------------------------------ cycle - cdrskin-0.2.7 - 2007.01.15.131357
|
||||
* Burning to DVD-RAM
|
||||
|
||||
Format and use DVD-RAM ?
|
||||
|
||||
Load format parameters into struct burn_drive and offer API.
|
||||
With full formatting prefer format 10h over 13h or 15h.
|
||||
15 Jan 2007 [623]
|
||||
cdrskin/changelog.txt
|
||||
Next cdrskin-0.2.7 cycle
|
||||
|
||||
Learn about multi-track with DVD-RW Restricted Overwrite.
|
||||
2007.01.16.120001 [tag 624]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
README
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
cdrskin/changelog.txt
|
||||
Made version number transition to 0.3.0
|
||||
|
||||
15 Jan 2007 [tag 625]
|
||||
- cdrskin/add_ts_changes_to_libburn_0_2_6
|
||||
- cdrskin/add_ts_changes_to_libburn_0_2_7
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_3_0
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
16 Jan 2007 [tag 626]
|
||||
README
|
||||
Corrected statement about restriction to CD
|
||||
|
||||
16 Jan 2007 [tag 627]
|
||||
cdrskin/cdrskin.c
|
||||
Silenced a compiler warning
|
||||
|
||||
16 Jan 2007 [tag 628]
|
||||
cdrskin/README
|
||||
Corrected name of tarball
|
||||
|
||||
16 Jan 2007 [tag 632]
|
||||
test/telltoc.c
|
||||
Corrected old libburn.pykix.org URL
|
||||
|
||||
16 Jan 2007 [tag 634]
|
||||
cdrskin/cdrskin_eng.html
|
||||
Updated web page
|
||||
|
||||
|
||||
------------------------------- cycle - cdrskin-0.3.0.pl00 - 2007.01.16.120001
|
||||
* Improved recognition of unsuitable media types
|
||||
* Replaced ban of chmod u+s by loud warning
|
||||
* detailed man page for cdrskin
|
||||
* Burning of DVD+RW and DVD-RAM media as single-track TAO-like initial session
|
||||
* Formatting and then burning to DVD-RW like to DVD+RW
|
||||
* New option -msifile=path from cdrkit/wodim
|
||||
|
||||
|
||||
16 Jan 2007 [629]
|
||||
- cdrskin/add_ts_changes_to_libburn_0_2_6
|
||||
- cdrskin/add_ts_changes_to_libburn_0_2_7
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_3_0
|
||||
+ cdrskin/add_ts_changes_to_libburn_0_3_1
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
2007.01.16.151041 [630]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
Made version number transition to 0.3.1
|
||||
|
||||
16 Jan 2007 [631]
|
||||
test/telltoc.c
|
||||
Corrected old libburn.pykix.org URL
|
||||
|
||||
16 Jan 2007 [633]
|
||||
cdrskin/cdrskin_eng.html
|
||||
Corrected typo
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.3.1 - 2007.01.16.152345
|
||||
|
||||
|
||||
16 Jan 2007 [635]
|
||||
cdrskin/changelog.txt
|
||||
Next cdrskin-0.3.1 cycle
|
||||
|
||||
17 Jan 2007 [636]
|
||||
cdrskin/wiki_plain.txt
|
||||
Removed paragraph about obsoleted tao_to_sao_tsize=
|
||||
|
||||
18 Jan 2007 [637]
|
||||
+ doc/cookbook.txt
|
||||
Wrote down what i learned from implementing support for overwriteable DVD
|
||||
|
||||
18 Jan 2007 [638]
|
||||
doc/cookbook.txt
|
||||
More info about Current/Maximum Capacity Descriptor
|
||||
|
||||
18 Jan 2007 [639]
|
||||
doc/cookbook.txt
|
||||
Made clarification about formatting state recognition
|
||||
|
||||
2007.01.18.211740 [640]
|
||||
libburn/transport.h
|
||||
libburn/mmc.c
|
||||
libburn/write.c
|
||||
Kept DVD+RW from stopping BG formatting if it was not started at all
|
||||
|
||||
2007.01.19.110510 [641]
|
||||
libburn/mmc.c
|
||||
Removed forgotten debug message printed to stderr
|
||||
|
||||
19 Jan 2007 [642]
|
||||
doc/cookbook.txt
|
||||
Began to describe TAO multi-session CD writing
|
||||
|
||||
20 Jan 2007 [643]
|
||||
doc/cookbook.txt
|
||||
Changes with CD part. Especially explanation of TOC.
|
||||
|
||||
2007.01.21.190928 [644]
|
||||
cdrskin/cdrskin.c
|
||||
Removed unnecessary after-grab loops
|
||||
|
||||
2007.01.21.191058 [645]
|
||||
libburn/write.c
|
||||
Comments learned from studying MMC-3 and MMC-5 for SAO CD cookbook
|
||||
|
||||
21 Jan 2007 [646]
|
||||
doc/cookbook.txt
|
||||
Clarification about TAO and mode page 05h per track
|
||||
|
||||
2007.01.22.114245 [647]
|
||||
libburn/libburn.h
|
||||
libburn/write.c
|
||||
libburn/async.c
|
||||
libburn/libdax_msgs.h
|
||||
cdrskin/cdrskin.c
|
||||
Bug fix: Banned mixed mode SAO (because broken in libburn and unclear in MMC)
|
||||
|
||||
23 Jan 2007 [648]
|
||||
doc/cookbook.txt
|
||||
Added SAO CD Cookbook
|
||||
|
||||
23 Jan 2007 [649]
|
||||
doc/cookbook.txt
|
||||
Corrections of typos and text debris
|
||||
|
||||
2007.01.25.145846 [652]
|
||||
libburn/structure.c
|
||||
Bug fix: DVD tracks of defined size >=2GB suffered 32-bit integer wraparound
|
||||
|
||||
2007.01.25.185214 [655]
|
||||
libburn/libburn.h
|
||||
libburn/write.c
|
||||
libburn/structure.h
|
||||
libburn/structure.c
|
||||
libburn/file.h
|
||||
libburn/file.c
|
||||
Enforce minimum track length with SAO
|
||||
|
||||
2007.01.25.180001 [tag 656]
|
||||
libburn_0_3_0_1/libburn/structure.c
|
||||
libburn_0_3_0_1/cdrskin/cdrskin_timestamp.h
|
||||
libburn_0_3_0_1/cdrskin/README
|
||||
Bug fix: DVD tracks of defined size >=2GB suffered 32-bit integer wraparound
|
||||
|
||||
26 Jan 2007 [tag 657]
|
||||
libburn_0_3_0_1/cdrskin/cdrskin_eng.html
|
||||
Mentioned new cdrskin patch level 01
|
||||
|
||||
26 Jan 2007 [658]
|
||||
cdrskin/cdrskin_eng.html
|
||||
Now offering cdrskin-0.3.0.pl01 for download
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.3.1 - 2007.01.26.111920
|
||||
|
||||
2007.01.26.173236 [659]
|
||||
libburn/file.h
|
||||
libburn/file.c
|
||||
Unified burn_file_source and burn_fd_source
|
||||
|
||||
27 Jan 2007 [660]
|
||||
libburn/null.c
|
||||
Initialized member set_size of burn_source within burn_null_source_new()
|
||||
|
||||
27 Jan 2007 [tag 661]
|
||||
libburn_0_3_0_1/libburn/file.c
|
||||
Removed 1.3 GB curbs for sources created by burn_file_source_new()
|
||||
|
||||
29 Jan 2007 [662]
|
||||
doc/cookbook.txt
|
||||
Added a statement about blanking of DVD-RW
|
||||
|
||||
2007.01.29.175822 [663]
|
||||
libburn/transport.h
|
||||
libburn/drive.c
|
||||
libburn/write.c
|
||||
libburn/mmc.c
|
||||
Experiments about list of features and profiles
|
||||
|
||||
2007.01.30.165317 [664]
|
||||
libburn/write.c
|
||||
libburn/mmc.c
|
||||
Preparations for DVD-R[W] Sequential Recording
|
||||
|
||||
2007.01.30.191740 [665]
|
||||
libburn/write.c
|
||||
libburn/mmc.c
|
||||
First successful multi-session write to a sequential DVD-RW
|
||||
|
||||
30 Jan 2007 [666]
|
||||
doc/cookbook.txt
|
||||
Added snapshot of emerging sequential DVD-R[W] cookbook
|
||||
|
||||
2007.01.30.220220 [667]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Enabled Burnfree buffer underrun protection by default
|
||||
|
||||
2007.01.31.130100 [668]
|
||||
libburn/async.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Blank sequential DVD-RW, deformat overwriteable DVD-RW
|
||||
|
||||
2007.01.31.173611 [669]
|
||||
libburn/libburn.h
|
||||
libburn/transport.h
|
||||
libburn/drive.c
|
||||
libburn/mmc.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Provisorily obtain multi-session -C parameters (violates MMC specs but works)
|
||||
|
||||
2007.02.01.161634 [670]
|
||||
libburn/libburn.h
|
||||
libburn/transport.h
|
||||
libburn/mmc.c
|
||||
test/telltoc.c
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
Obtain TOC from non-CD via 52h READ TRACK INFORMATION
|
||||
|
||||
2007.02.01.163511 [671]
|
||||
cdrskin/cdrskin.c
|
||||
Reacted on justified compiler warning about unitialized sessions variable
|
||||
|
||||
2007.02.01.191638 [672]
|
||||
libburn/mmc.c
|
||||
cdrskin/cdrskin.c
|
||||
Allow blanking of DVD-RW which offer no Incremental Streaming
|
||||
|
||||
1 Feb 2007 [673]
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/README
|
||||
cdrskin/cdrskin.1
|
||||
Prepared next cdrskin-0.3.1 cycle
|
||||
|
||||
1 Feb 2007 [674]
|
||||
cdrskin/changelog.txt
|
||||
Prepared next cdrskin-0.3.1 cycle
|
||||
|
||||
1 Feb 2007 [675] [676]
|
||||
cdrskin/cdrskin.1
|
||||
Mentioned DVD-RW multi-session in overview of features
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.01.203057
|
||||
* Burnfree enabled by default
|
||||
* Multi-session recording on sequential DVD-RW, including -toc, -msinfo
|
||||
|
||||
|
||||
2 Feb 2007 [677]
|
||||
cdrskin/convert_man_to_html.sh
|
||||
Some sed expressions for beautification
|
||||
|
||||
2 Feb 2007 [678]
|
||||
doc/cookbook.txt
|
||||
Updated about DVD-R[W] blanking, multi-session info and TOC
|
||||
|
||||
2007.02.02.151327 [679]
|
||||
libburn/mmc.c
|
||||
test/telltoc.c
|
||||
Make mmc_read_multi_session_c1 use TOC if available
|
||||
|
||||
2007.02.02.173345 [680]
|
||||
libburn/mmc.c
|
||||
cdrskin/cdrskin.c
|
||||
Improved classification and TOC of finalized DVD-R[W] media
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.02.183755
|
||||
|
||||
3 Feb 2007 [681]
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/wiki_plain.txt
|
||||
Mentioned DVD-RW multi-session
|
||||
|
||||
2007.02.03.205526 (comitted 4 Feb 2007) [682]
|
||||
libburn/libburn.h
|
||||
libburn/mmc.c
|
||||
libburn/drive.c
|
||||
libburn/async.c
|
||||
test/telltoc.c
|
||||
New in API : struct burn_multi_caps and burn_disc_get_multi_caps()
|
||||
|
||||
2007.02.05.132335 [683]
|
||||
libburn/transport.h
|
||||
libburn/mmc.c
|
||||
Preparations for DVD-R[W] DAO
|
||||
|
||||
2007.02.06.130410 [684]
|
||||
libburn/libburn.h
|
||||
libburn/mmc.c
|
||||
libburn/write.c
|
||||
libburn/drive.c
|
||||
libburn/libdax_msgs.h
|
||||
Implemented DVD-R[W] DAO as BURN_WRITE_SAO
|
||||
|
||||
2007.02.06.170621 [685]
|
||||
libburn/write.c
|
||||
libburn/mmc.c
|
||||
Beautification of debugging messages
|
||||
|
||||
2007.02.06.174320 [686]
|
||||
cdrskin/cdrskin.c
|
||||
tao_to_sao_tsize= for DVD-R[W] DAO
|
||||
|
||||
2007.02.06.185534 [687]
|
||||
libburn/async.c
|
||||
cdrskin/cdrskin.c
|
||||
Enabled fast blank for DVD-R[W]
|
||||
|
||||
6 Feb 2007 [688]
|
||||
cdrskin/cdrskin.1
|
||||
Clarified CD and DVD peculiarities
|
||||
|
||||
6 Feb 2007 [689]
|
||||
doc/cookbook.txt
|
||||
Described DVD-R[W] DAO mode
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.06.200802
|
||||
* DVD-R[W] Disk-at-once writing
|
||||
|
||||
6 Feb 2007 [690]
|
||||
cdrskin/README
|
||||
cdrskin/changelog.txt
|
||||
cdrskin/cdrskin_eng.html
|
||||
Next cdrskin-0.3.1 cycle
|
||||
|
||||
2007.02.07.162836 [691]
|
||||
libburn/libburn.h
|
||||
libburn/drive.h
|
||||
libburn/drive.c
|
||||
libburn/options.c
|
||||
libburn/libdax_msgs.h
|
||||
New API function burn_write_opts_auto_write_type()
|
||||
|
||||
7 Feb 2007 [692]
|
||||
test/libburner.c
|
||||
Made use of burn_write_opts_auto_write_type()
|
||||
|
||||
7 Feb 2007 [693]
|
||||
test/libburner.c
|
||||
doc/comments
|
||||
Updated documentation aspects
|
||||
|
||||
8 Feb 2007 [694]
|
||||
README
|
||||
doc/comments
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
Finally made tests with DVD-R. They burn indeed like DVD-RW.
|
||||
|
||||
2007.02.08.210744 [695]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
New option --prodvd_cli_compatible
|
||||
|
||||
8 Feb 2007 [696]
|
||||
cdrskin/wiki_plain.txt
|
||||
cdrskin/cdrskin_eng.html
|
||||
Mentioned DVD-R
|
||||
|
||||
2007.02.08.225208 [697]
|
||||
cdrskin/cdrskin.c
|
||||
Silenced compiler warning
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.09.074058
|
||||
|
||||
9 Feb 2006 [698]
|
||||
cdrskin/cdrskin_eng.html
|
||||
Added special thanks towards Andy Polyakov
|
||||
|
||||
9 Feb 2006 [699]
|
||||
cdrskin/cdrskin.1
|
||||
doc/cookbook.txt
|
||||
Small corrections in documentation
|
||||
|
||||
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]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
README
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
cdrskin/wiki_plain.txt
|
||||
cdrskin/cdrskin_eng.html
|
||||
Made number transition and activated development documentation
|
||||
|
||||
[]
|
||||
cdrskin/changelog.txt
|
||||
Documented changes and 0.3.2 release timestamp
|
||||
|
||||
|
||||
------------------------------- 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
|
||||
|
||||
|
||||
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 -
|
||||
|
||||
forceful blanking of blank media in burn_disc_erase()
|
||||
|
||||
What about minimum track sizes ? (POWER OFF/ON , BUS RESET ?)
|
||||
|
||||
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 ?
|
||||
|
||||
|
||||
Format DVD-RAM ?
|
||||
|
||||
How to handle finalizing ?
|
||||
|
||||
Check wether current_profile is kept up to date with each possible media change
|
||||
|
||||
Make drive_info reflect DVD capabilities
|
||||
Make proper use of reflected capabilities (e.g. in burn_drive_inquire_media())
|
||||
|
||||
Rectify mmc_read_atip speed interpretation. 12x media are reported as 10x. I never heard of 6x media.
|
||||
|
||||
|
||||
Sequentially check option list for DVD compliance
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-0.2.7 -
|
||||
|
||||
|
||||
|
||||
----------------------------------------- long term intentions:
|
||||
|
||||
http://burbon04.gmxhome.de/linux/CDREncryption.html
|
||||
|
||||
[]
|
||||
Ticket 90: failure on USB
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
debug_opts=
|
||||
def_opts=
|
||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||
libvers="-DCdrskin_libburn_0_2_7"
|
||||
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_2_6"
|
||||
elif test "$i" = "-libburn_0_3_2"
|
||||
then
|
||||
libvers="-DCdrskin_libburn_0_2_6"
|
||||
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_2_7"
|
||||
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_2_6 set macro to match libburn-0.2.6."
|
||||
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."
|
||||
|
@ -47,7 +47,8 @@ then
|
||||
-e 's/In general there are two types of tracks: data and audio./\ <BR>In general there are two types of tracks: data and audio./' \
|
||||
-e 's/While audio tracks just contain a given/\ <BR>While audio tracks just contain a given/' \
|
||||
-e 's/<b>Recordable CD Media:<\/b>/\ <BR><b>Recordable CD Media:<\/b>/' \
|
||||
-e 's/<b>Recordable DVD Media:<\/b>/\ <BR><b>Recordable DVD Media:<\/b>/' \
|
||||
-e 's/<b>Overwriteable DVD Media:<\/b>/\ <BR><b>Overwriteable DVD Media:<\/b>/' \
|
||||
-e 's/<b>Sequentially Recordable DVD Media:<\/b>/\ <BR><b>Sequentially Recordable DVD Media:<\/b>/' \
|
||||
-e 's/<b>Drive preparation and addressing:<\/b>/\ <BR><b>Drive preparation and addressing:<\/b>/' \
|
||||
-e 's/If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
||||
-e 's/^Alphabetical list of options/\ <BR>Alphabetical list of options/' \
|
||||
|
@ -7,8 +7,11 @@
|
||||
|
||||
Its paragon, cdrecord, is a powerful GPL'ed burn program included in Joerg
|
||||
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.
|
||||
Its future ability to burn DVD media depends on the development of libburn.
|
||||
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] 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
|
||||
@ -19,14 +22,13 @@ About libburn API for burning CD: http://libburnia-api.pykix.org
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Appending sessions to an unclosed CD is restricted to write mode TAO.
|
||||
(Users who have a burner which succeeds with a follow-up session via
|
||||
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.)
|
||||
|
||||
The development version of cdrskin is able to burn a single track to DVD+RW
|
||||
or DVD-RW media.
|
||||
For other DVD types and for appending sessions to ISO filesystems see the
|
||||
advise to use dvd+rw-tools at the end of this text.
|
||||
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,20 +85,42 @@ has to offer both, r- and w-permission.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Non-cdrecord blank mode blank=format_overwrite is needed to bring a DVD-RW
|
||||
The DVD capabilities of cdrskin differ from those of cdrecord-ProDVD. cdrskin
|
||||
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
|
||||
"Restricted Overwrite". The latter is usable with cdrskin.
|
||||
"Restricted Overwrite".
|
||||
{{{
|
||||
cdrskin dev=/dev/sr0 -v blank=format_overwrite
|
||||
}}}
|
||||
|
||||
DVD-RW "Restricted Overwrite" and DVD+RW appear to cdrskin as blank media
|
||||
DVD-RAM, DVD+RW and overwriteable DVD-RW appear to cdrskin as blank media
|
||||
which are capable of taking only a single track. This track may be positioned
|
||||
on a 32KiB aligned address, though.
|
||||
{{{
|
||||
cdrskin ... write_start_address=2412m ...
|
||||
}}}
|
||||
|
||||
Non-cdrecord blank mode blank=deformat_sequential brings an overwriteable
|
||||
DVD-RW back into state "Sequential Recording" with the capability of doing
|
||||
multi-session, if the drive is capable of "Incremental Streaming"
|
||||
(MMC feature 21h).
|
||||
|
||||
Used sequential DVD-RW media may be blanked by blank=fast or blank=all which
|
||||
normally both do full blanking.
|
||||
|
||||
blank=deformat_sequential does minimal blanking of DVD-RW which usually yields
|
||||
media incapable of "Incremental Streaming".
|
||||
|
||||
Option --prodvd_cli_compatible activates blank=fast and blank=all for
|
||||
overwriteable DVD-RW which normally ignore those two options. It also makes
|
||||
option -multi tolerable with media and write modes which are not suitable for
|
||||
multi-session. (The default behavior of cdrskin deems me to be preferrable.)
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
fifo_start_at=<num> is a throughput enhancer for unsteady data streams
|
||||
@ -154,21 +178,6 @@ $HOME/.cdrskinrc
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
tao_to_sao_tsize=<num> allows the - actually unsupported - cdrecord option
|
||||
-tao and defines a default track size to be used if - as custom with -tao -
|
||||
no option tsize=# is given.
|
||||
|
||||
Since -tao is supported in cdrskin-0.2.6 the TAO-to-SAO workaround has become
|
||||
quite obsolete. Nevertheless, tao_to_sao_tsize= allows to preset a default
|
||||
size for SAO mode which is in effect only if no track size is available.
|
||||
|
||||
As in general with cdrskin tsize=# the data source does not have to provide
|
||||
the full annouced amount of data. Missing data will be padded up by 0-bytes.
|
||||
Surplus data is supposed to cause an error, though. The burn will then
|
||||
be a failure in any way.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
dev_translation=<sep><from><sep><to> may be needed to foist cdrskin to
|
||||
frontend programs of cdrecord which do *not* ask cdrecord -scanbus but
|
||||
which make own assumptions and guesses about cdrecord's device addresses.
|
||||
@ -200,9 +209,10 @@ for an illustrated example with K3b 0.10 .
|
||||
|
||||
DVD advise:
|
||||
|
||||
For burning of DVD media 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+RW, DVD+R, DVD-RW, DVD-R .
|
||||
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
|
||||
|
||||
@ -210,21 +220,18 @@ They are not compatible or related to cdrecord resp. cdrecord-ProDVD
|
||||
(now obsoleted by original source cdrtools cdrecord with identical
|
||||
capabilities besides the license key).
|
||||
|
||||
libburn and thus the cdrskin project are currently aquiring own capabilities
|
||||
to burn to DVD media. For now restricted to DVD+RW and DVD-RW and to single
|
||||
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
|
||||
overwriteable media. This is not the same as multi-session writing of cdrskin
|
||||
with CD media, but retrieves additional information from the existing ISO
|
||||
image and finally manipulates the start sectors of this existing image.
|
||||
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]. 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.
|
||||
|
||||
To my knowledge, Linux kernels 2.6 do write to DVD+RW via block devices as
|
||||
they would write to a traditional tape device. Try old tape archiver
|
||||
commands with addresses like /dev/sr0 or /dev/hdc rather than /dev/mt0 .
|
||||
I have heard rumors that DVD-RW in mode "restricted overwrite" would be
|
||||
block device ready, too. My burner is not a real friend of DVD-RW and
|
||||
in an experiment the burn worked fine - but the result was not identical
|
||||
to the stream sent to the device. I had similar failure with DVD-RAM, too.
|
||||
|
||||
Beware of the impact of a slow block device on overall system i/o buffering.
|
||||
It is wise to curb its input to a speed which it is able to deliver to media.
|
||||
Else your i/o dedicated RAM might buffer a big amount of stream data.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
18
configure.ac
18
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libburn], [0.2.7], [http://libburnia.pykix.org])
|
||||
AC_INIT([libburn], [0.3.2], [http://libburnia.pykix.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -7,12 +7,6 @@ AC_CANONICAL_TARGET
|
||||
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
|
||||
dnl A61101 This breaks Linux build (makes 32 bit off_t)
|
||||
dnl http://sourceware.org/autobook/autobook/autobook_96.html says
|
||||
dnl one must include some config.h and this was a pitfall.
|
||||
dnl So why dig the pit at all ?
|
||||
dnl AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Making releases:
|
||||
dnl BURN_MICRO_VERSION += 1;
|
||||
dnl BURN_INTERFACE_AGE += 1;
|
||||
@ -24,8 +18,8 @@ dnl
|
||||
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
||||
dnl
|
||||
BURN_MAJOR_VERSION=0
|
||||
BURN_MINOR_VERSION=2
|
||||
BURN_MICRO_VERSION=7
|
||||
BURN_MINOR_VERSION=3
|
||||
BURN_MICRO_VERSION=2
|
||||
BURN_INTERFACE_AGE=0
|
||||
BURN_BINARY_AGE=0
|
||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
@ -76,12 +70,6 @@ AC_PROG_INSTALL
|
||||
|
||||
AC_CHECK_HEADERS()
|
||||
|
||||
AC_CHECK_MEMBER([struct tm.tm_gmtoff],
|
||||
[AC_DEFINE(HAVE_TM_GMTOFF, 1,
|
||||
[Define this if tm structure includes a tm_gmtoff entry.])],
|
||||
,
|
||||
[#include <time.h>])
|
||||
|
||||
THREAD_LIBS=-lpthread
|
||||
AC_SUBST(THREAD_LIBS)
|
||||
|
||||
|
49
doc/comments
49
doc/comments
@ -6,9 +6,9 @@
|
||||
@section intro Introduction
|
||||
|
||||
Libburnia is an open-source project for reading, mastering and writing
|
||||
optical discs. For now this means only CD-R and CD-RW.
|
||||
Support for DVD+RW and DVD-RW is emerging.
|
||||
optical discs. For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD-RW, DVD-R.
|
||||
|
||||
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.
|
||||
@ -20,9 +20,9 @@ we would need : login on a development machine resp. a live OS on CD or DVD,
|
||||
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
||||
volunteers for testing of realistic use cases.
|
||||
|
||||
We have a workable code base for burning data and audio CDs. The burn API is
|
||||
quite comprehensively documented and can be used to build a presentable
|
||||
application.
|
||||
We have a workable code base for burning data and audio CDs and many DVD types.
|
||||
The burn API is quite comprehensively documented and can be used to build a
|
||||
presentable application.
|
||||
We have a functional binary which emulates the core use cases of cdrecord in
|
||||
order to prove that usability, and in order to allow you to explore libburn's
|
||||
scope by help of existing cdrecord frontends.
|
||||
@ -32,7 +32,10 @@ scope by help of existing cdrecord frontends.
|
||||
- libburn is the library by which preformatted data get onto optical media.
|
||||
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
|
||||
/dev/hdX (e.g. on kernel 2.6).
|
||||
libburn is the foundation of our cdrecord emulation.
|
||||
libburn is the foundation of our cdrecord emulation. Its code is
|
||||
independent of cdrecord. Its DVD capabilities are learned from
|
||||
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
|
||||
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
|
||||
|
||||
- libisofs is the library to pack up hard disk files and directories into a
|
||||
ISO 9660 disk image. This may then be brought to CD via libburn.
|
||||
@ -41,15 +44,18 @@ scope by help of existing cdrecord frontends.
|
||||
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||
cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||
Schilling's cdrtools. cdrskin strives to be a second source for
|
||||
the services traditionally provided by cdrecord.
|
||||
the services traditionally provided by cdrecord. Additionally it
|
||||
provides libburn's DVD capabilities, where only -sao is compatible
|
||||
with cdrecord.
|
||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||
Many bytes have been copied from the message output of cdrecord
|
||||
runs, though.
|
||||
See cdrskin/README for more.
|
||||
|
||||
- "test" is a collection of application gestures and examples given by the
|
||||
authors of the library features. The main API example of libburn
|
||||
is named test/libburner.c .
|
||||
authors of the library features. The burn API example of libburn
|
||||
is named test/libburner.c . The API for media information inquiry is
|
||||
demonstrated in test/telltoc.c .
|
||||
Explore these examples if you look for inspiration.
|
||||
|
||||
We plan to be a responsive upstream. Bear with us.
|
||||
@ -82,9 +88,8 @@ 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 and
|
||||
can burn to CD-R or CD-RW.
|
||||
New: burning to DVD+/-RW (single data track, single session only).
|
||||
It can list the available devices, can blank a CD-RW or DVD-RW and
|
||||
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
|
||||
@ -95,8 +100,9 @@ stay upward compatible for a good while.
|
||||
<pre>
|
||||
Usage: test/libburner
|
||||
[--drive <address>|<driveno>|"-"] [--audio]
|
||||
[--blank_fast|--blank_full] [--try_to_simulate]
|
||||
[--multi] [one or more imagefiles|"-"]
|
||||
[--blank_fast|--blank_full|--format_overwrite]
|
||||
[--try_to_simulate]
|
||||
[--multi] [<one or more imagefiles>|"-"]
|
||||
Examples
|
||||
A bus scan (needs rw-permissions to see a drive):
|
||||
test/libburner --drive -
|
||||
@ -106,22 +112,27 @@ Burn a file to drive chosen by persistent address, close:
|
||||
test/libburner --drive /dev/hdc my_image_file
|
||||
Blank a used CD-RW (is combinable with burning in one run):
|
||||
test/libburner --drive /dev/hdc --blank_fast
|
||||
Burn two audio tracks
|
||||
Blank a used DVD-RW (is combinable with burning in one run):
|
||||
test/libburner --drive /dev/hdc --blank_full
|
||||
Format a DVD-RW to avoid need for blanking before re-use:
|
||||
test/libburner --drive /dev/hdc --format_overwrite
|
||||
Burn two audio tracks (to CD only):
|
||||
lame --decode -t /path/to/track1.mp3 track1.cd
|
||||
test/dewav /path/to/track2.wav -o track2.cd
|
||||
test/libburner --drive /dev/hdc --audio track1.cd track2.cd
|
||||
Burn a compressed afio archive on-the-fly:
|
||||
( cd my_directory ; find . -print | afio -oZ - ) | \
|
||||
test/libburner --drive /dev/hdc -
|
||||
To be read from *not mounted* CD via: afio -tvZ /dev/hdc
|
||||
Program tar would need a clean EOF which our padded CD cannot deliver.
|
||||
To be read from *not mounted* media via: afio -tvZ /dev/hdc
|
||||
</pre>
|
||||
libburner has two companions, telltoc and dewav, which help to perform some
|
||||
peripheral tasks of burning.
|
||||
|
||||
telltoc prints a table of content (sessions, tracks and leadouts), it tells
|
||||
about type and state of CD media, and also is able to provide the necessary
|
||||
multi-session information for program mkisofs option -C.
|
||||
about type and state of media, and also is able to provide the necessary
|
||||
multi-session information for program mkisofs option -C. Especially helpful
|
||||
are its predictions with "Write multi" and "Write modes" where availability
|
||||
of "TAO" indicates that tracks of unpredicted length can be written.
|
||||
See: test/telltoc --help.
|
||||
|
||||
dewav extracts raw byte-swapped audio data from files of format .wav (MS WAVE)
|
||||
|
966
doc/cookbook.txt
Normal file
966
doc/cookbook.txt
Normal file
@ -0,0 +1,966 @@
|
||||
libburnia.pykix.org Optical Media Rotisserie Recipes as of February 2007
|
||||
|
||||
Content:
|
||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||
- 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
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
TAO Multi-Session CD Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Guided by reading mmc-r10a.pdf , O.8 "Write a Track"
|
||||
from http://www.t10.org/ftp/t10/drafts/mmc/
|
||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
by reading spc3r23.pdf from http://www.t10.org/ftp/t10/drafts/spc3/
|
||||
by reading libburn/* from http://icculus.org/burn
|
||||
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S
|
||||
which used in part code from http://icculus.org/burn.
|
||||
|
||||
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)
|
||||
|
||||
CD-R 0009h
|
||||
CD-RW 000ah
|
||||
|
||||
The following topics are covered in this text:
|
||||
- About blank, appendable and finalized CD media
|
||||
- Writing a session to CD in TAO mode
|
||||
- Obtaining CD multi-session info for extending ISO-9660 filesystems
|
||||
- Obtaining a Table Of Content from CD
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
About blank, appendable and finalized CD media :
|
||||
|
||||
CD media have to be blank or appendable in order to be writeable in TAO mode.
|
||||
The according status may be inquired by 51h READ DISC INFORMATION requesting
|
||||
Data Type 000b Standard Disc Information, where reply value Disc Status
|
||||
indicates:
|
||||
00b blank
|
||||
01b appendable
|
||||
10b finalized
|
||||
11b others (unsuitable for this recipe)
|
||||
(mmc5r03c.pdf 6.22.3.1.4)
|
||||
|
||||
CD-RW which are finalized or appendable may be blanked by command A1h BLANK
|
||||
with blanking types 000b "Blank the disc" or 001b "Minimally blank the disc".
|
||||
The Start Address/Track Number will be ignored so it may well be 0.
|
||||
|
||||
Because the operation is long running it is advised to set the Immed bit and to
|
||||
watch the progress by commands 00h TEST UNIT READY and 03h REQUEST SENSE
|
||||
with DESC bit set to 0 for fixed format reply.
|
||||
It is done when 00h succeeds and 03h reports 0 in PROGRESS INDICATION
|
||||
(byte 1+2 in Table 22 = byte 16+17 SENSE KEY SPECIFIC in table 26).
|
||||
(mmc5r03c.pdf 6.2 BLANK)
|
||||
(spc3r23.pdf 4.5.2.4.4 table 22, 4.5.3 table 26,
|
||||
6.27 REQUEST SENSE, 6.33 TEST UNIT READY)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Writing a session to CD in TAO mode :
|
||||
|
||||
The writing method for blank or appendable media is the same. A new session
|
||||
will get created automatically by the first track when it is written. If the
|
||||
media is blank then the new session will be the first and only one in the
|
||||
table of content. If the media is appendable then a new session will be
|
||||
appended to the existing sessions. In any case the new track will be the
|
||||
first one in the new session.
|
||||
|
||||
Speed may be set by BBh SET CD SPEED parameter Drive Write Speed. Note that
|
||||
kbytes/sec means 1000 bytes/sec and not 1024/sec. Rotational control should
|
||||
be set to 00b. 1x CD speed is 176.4 kbytes/sec. Speed is usually set to the
|
||||
next lower possible value by the drive. So it is helpful to add a few
|
||||
kbytes/sec just in case the drive has rounding problems.
|
||||
(mmc5r03c.pdf 6.37)
|
||||
|
||||
Before writing can occur, a Write Parameters mode page 05h has to be composed
|
||||
and transmitted via 55h MODE SELECT. Mode page 05h describes several burn
|
||||
parameters:
|
||||
BUFE Buffer Underrun protection 0=off, 1=on
|
||||
Test Write -dummy mode for writing 0=off, 1=on
|
||||
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
||||
Multi-session Wether to keep appendable 00b = finalize
|
||||
11b = keep appendable
|
||||
Track Mode Describes frame type 4 for data , 0 for audio
|
||||
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
||||
0 for 2352 byte audio blocks
|
||||
Audio Pause Length 150 = 2 seconds
|
||||
Any other parameters may be set to 0.
|
||||
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
||||
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
||||
(mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode)
|
||||
(spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats)
|
||||
|
||||
|
||||
Writing has to begin at the address returned by 52h READ TRACK INFORMATION
|
||||
with Address/Number Type set to 01b and Logical Block Address/Track/Session
|
||||
Number set to FFh. The Next Writeable Address as of table 500 is the number
|
||||
to start writing with.
|
||||
(mmc5r03c.pdf 6.27 )
|
||||
|
||||
Writing is performed by one or more 2Ah WRITE transactions with the Logical
|
||||
Block Address counted up from the initial number in sync with the number of
|
||||
blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be
|
||||
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
|
||||
can be written.
|
||||
(mmc5r03c.pdf, 6.44)
|
||||
When writing is done, it is mandatory to force the drive's buffer to media by
|
||||
35h SYNCHRONIZE CACHE.
|
||||
(mmc5r03c.pdf, 6.41)
|
||||
|
||||
A track must at least contain 300 payload blocks: 4 seconds of audio or
|
||||
600 KiB of data.
|
||||
(mmc5r03c.pdf 6.3.3.1.2)
|
||||
|
||||
The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b.
|
||||
Older MMC specifies a valid Logical Track Number FFh to depict the open track.
|
||||
MMC-5 is quite silent about this. FFh works for my drives.
|
||||
(mmc5r03c.pdf 6.3.3.1.2)
|
||||
|
||||
After that, a new track may be written beginning with sending the mode page 05h
|
||||
again. It is not tested wether 05h can be omitted if Track Mode and Data Block
|
||||
Type are the same as with the previous track.
|
||||
The new track will be added to the session which was opened by the first track.
|
||||
|
||||
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
||||
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
||||
value in mode page 05h wether the disc is finalized or stays appendable.
|
||||
(mmc5r03c.pdf 6.3.3.1.3)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Obtaining CD multi-session info for extending ISO-9660 filesystems :
|
||||
|
||||
Program mkisofs expects two numbers with its option -C which describe the
|
||||
situation on an appendable CD which already contains a ISO-9660 filesystem
|
||||
in the first track of the last session.
|
||||
|
||||
The first number is the Logical Block Address of that track containing the
|
||||
existing ISO-9660 filesystem image. This number is needed for mkisofs option
|
||||
-M to connect to the existing image. The new image will refer to files in
|
||||
the previously existing image. mkisofs option -M needs read access to the
|
||||
CD or a blockwise copy of it on hard disk.
|
||||
The number is gained by 43h READ TOC/PMA/ATIP.
|
||||
(mmc5r03c.pdf 6.26)
|
||||
Untested is Format 0001b which in table 478 promises quick access via
|
||||
Start Address Of First Track In Last Session.
|
||||
(mmc5r03c.pdf 6.26.2.5 table 478, 6.26.3.3.1)
|
||||
libburn gets the number from its Table Of Content model which is obtained
|
||||
by 43h READ TOC/PMA/ATIP, Format 0010b. See below.
|
||||
|
||||
The second number is an exact prediction of the Logical Block Address of the
|
||||
new track which will contain the newly generated ISO-9660 image.
|
||||
Even without mkisofs option -M this second number is still needed to make the
|
||||
inner block address pointers of the image match the Logical Block Addresses
|
||||
on CD. For that one may inquire 52h READ TRACK INFORMATION with
|
||||
Address/Number Type set to 01b and Logical Block Address/Track/Session
|
||||
Number set to FFh. The Next Writeable Address as of table 500 is the number
|
||||
to use.
|
||||
(mmc5r03c.pdf 6.27 )
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Obtaining a Table Of Content from CD :
|
||||
|
||||
The structure of a CD is comprised of sessions. Each session contains one or
|
||||
more tracks and is followed by a lead-out. A track has an address and a length.
|
||||
|
||||
Table of content information is gained by 43h READ TOC/PMA/ATIP, Format 0010b.
|
||||
(mmc5r03c.pdf 6.26.2.5 table 478)
|
||||
|
||||
The number of sessions is given by Last Complete Session Number.
|
||||
The number of TOC Track descriptors is: (TOC Data Length - 2)/11 .
|
||||
|
||||
Each TOC Track Descriptor contains a Session Number.
|
||||
|
||||
If POINT is >= 1 and <= 99 (63h) then the descriptor is about the track of
|
||||
which POINT tells the number.
|
||||
The start address of this track can be read from PMIN, PSEC, PFRAME where
|
||||
it is encoded in MSF format:
|
||||
blocks = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
||||
The length of the track is given by MIN,SEC,FRAME in the same format.
|
||||
|
||||
If POINT = A0h then the descriptor tells in PMIN the first track number of its
|
||||
session.
|
||||
POINT = A1h tells in PMIN the last track number of its session.
|
||||
POINT = A2h describes in PMIN, PSEC, PFRAME the lead-out of a session, i.e the
|
||||
first address after the session's end. (Next writeable address typically is
|
||||
lead-out + 11400 after the first session, lead-out + 6900 after further
|
||||
sessions.)
|
||||
POINT = B0h tells in MIN,SEC,FRAME this next writeable address or FFh,FFh,FFh
|
||||
for finalized disc.
|
||||
(mmc5r03c.pdf 6.26.3.4 table 489, 4.2.3.7 Mode-1 Q, Mode-5 Q)
|
||||
|
||||
|
||||
In libburn the address of the first track in the last session is obtained from
|
||||
the last session's POINT = A0h and from the track descriptor with the POINT
|
||||
value matching the PMIN value of the A0h descriptor.
|
||||
Untested is wether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
||||
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
SAO CD Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Guided by reading libburn/* from http://icculus.org/burn
|
||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S
|
||||
which used in part code from http://icculus.org/burn.
|
||||
|
||||
For libburnia.pykix.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Recognition of media type and state (blank, appendable, finalized) is as
|
||||
described in the TAO Multi-Session CD Cookbook. See there.
|
||||
|
||||
The MMC specs do not give much hint about the combination of SAO and
|
||||
multi-session. My drives refused not only on a few experiments which i did
|
||||
in libburn but also failed with cdrecord -sao on an appendable CD.
|
||||
So for now only blank CD seem to be suitable for SAO writing.
|
||||
|
||||
Different from TAO mode, the whole session layout is announced to the drive by
|
||||
sending a Cue Sheet. This implies that the sizes of the tracks have to be known
|
||||
in advance, which is a heavy drawback when dealing with track data sources like
|
||||
stdin, named pipes or sockets.
|
||||
Nevertheless, SAO seems to be best writing mode for audio purposes, as our
|
||||
audio expert Lorenzo Taylor found out.
|
||||
|
||||
A SAO session in libburn may either consist entirely of audio tracks or
|
||||
entirely of data tracks. For mixed sessions, only TAO is usable yet.
|
||||
|
||||
- Composing a SAO CD Cue Sheet (either audio or data, but not mixed)
|
||||
- Writing the prepared SAO CD session
|
||||
- What is known about mixed mode sessions
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Composing a Cue Sheet (either audio or data, but not mixed) :
|
||||
|
||||
The Cue Sheet will get submitted to the drive by 5Dh SEND CUE SHEET.
|
||||
Each entry of the sheet is of 8 bytes size. Its fields are named
|
||||
CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME .
|
||||
(mmc5r03c.pdf 6.33)
|
||||
|
||||
CTL is 40h for data and 00h for audio.
|
||||
(mmc5r03c.pdf 6.33.3.4)
|
||||
ADR is always 01h.
|
||||
TNO is the track number (1 to 99).
|
||||
INDEX is a subaddress within tracks. This recipe uses only INDEX 01h within
|
||||
tracks.
|
||||
(mmc5r03c.pdf 4.2.3.5.2)
|
||||
DATA FORM is 00h for audio payload , 10h for data. (01h for audio pause is not
|
||||
used in libburn).
|
||||
(mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form)
|
||||
SCMS is always 00h.
|
||||
MIN, SEC, FRAME give the MSF address where the described data entity starts.
|
||||
LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
||||
This address must increase from entry to entry (or at least stay equal).
|
||||
|
||||
|
||||
The first entry describes the Lead-in. Its content is
|
||||
(CTL|ADR ,00h,00h,01h,00h,00h,00h,00h)
|
||||
With the CTL|ADR for the first track: 41h for data, 01h for audio.
|
||||
|
||||
The LBA for the first write is negative: -150. This corresponds to MSF address
|
||||
00h:00h:00h. All addresses are to be given in MSF format.
|
||||
The first information track on disc is preceded by a pause encoding of 2 sec:
|
||||
(CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h)
|
||||
with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF
|
||||
address increases to 00h:02h:00h = LBA 0.
|
||||
|
||||
Each track is represented by an entry
|
||||
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
|
||||
TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes
|
||||
the start address of the track. The MSF address is then increased by the size
|
||||
of the track (to be used with next track or with lead-out).
|
||||
|
||||
A track must at least contain 300 payload blocks: 4 seconds of audio or
|
||||
600 KiB of data.
|
||||
(mmc5r03c.pdf 6.33.3.6)
|
||||
|
||||
At the end of the session there is a lead-out entry
|
||||
(CTL|ADR,AAh,01h,01h,00h,MIN,SEC,FRAME)
|
||||
marking the end of the last track. (With libburn CTL is as of the last track.)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Writing the prepared session :
|
||||
|
||||
Speed may be set by BBh SET CD SPEED parameter Drive Write Speed. Note that
|
||||
kbytes/sec means 1000 bytes/sec and not 1024/sec. Rotational control should
|
||||
be set to 00b. 1x CD speed is 176.4 kbytes/sec. Speed is usually set to the
|
||||
next lower possible value by the drive. So it is helpful to add a few
|
||||
kbytes/sec just in case the drive has rounding problems.
|
||||
(mmc5r03c.pdf 6.37)
|
||||
|
||||
A Write Parameters mode page 05h has to be composed and transmitted via
|
||||
55h MODE SELECT. This page describes the following parameters:
|
||||
BUFE Buffer Underrun protection 0=off, 1=on
|
||||
Test Write -dummy mode for writing 0=off, 1=on
|
||||
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
||||
Multi-session Wether to keep appendable 00b = finalize
|
||||
11b = keep appendable
|
||||
Track Mode Describes frame type 0 (is ignored)
|
||||
Data Block Type Layout of payload blocks 0 (is ignored)
|
||||
Audio Pause Length 150 = 2 seconds (ignored ?)
|
||||
Any other parameters may be set to 0.
|
||||
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
||||
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
||||
(mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode)
|
||||
(spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats)
|
||||
|
||||
The Cue Sheet is submitted to the drive by 5Dh SEND CUE SHEET. Cue Sheet Size
|
||||
is 8 times the number of entries.
|
||||
(mmc5r03c.pdf 6.33)
|
||||
|
||||
Writing is performed by multiple 2Ah WRITE transactions with the Logical
|
||||
Block Address counted up from the initial number in sync with the number of
|
||||
blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be
|
||||
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
|
||||
can be written.
|
||||
(mmc5r03c.pdf, 6.44)
|
||||
Writing begins at LBA -150 which is to be transmitted as 4-byte, Big-endian,
|
||||
two's-complement. E.g: -150 = FFh FFh FFh 6Ah. This is the natural form found
|
||||
with about any 32-bit processor, so only the endianness has to be taken into
|
||||
respect when converting a 32-bit integer into a LBA for command 2Ah WRITE.
|
||||
|
||||
|
||||
At first the mandatory pause preceding the first track has to be written as
|
||||
150 blocks of the matching sector size: 2048 for data, 2352 for audio.
|
||||
By this, the LBA increases from -150 to 0.
|
||||
|
||||
Next the tracks' payload is sent. For each track exactly the number of blocks
|
||||
has to be transmitted as is announced in the Cue Sheet by the difference
|
||||
of the track's own start address and the start address of the next entry in
|
||||
the Cue Sheet. After each write the LBA for the next write has to be increased
|
||||
by the number of blocks transmitted. Just like with TAO writing.
|
||||
|
||||
There is no separator between the tracks of a pure mode SAO session.
|
||||
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
||||
between data mode tracks and audio mode tracks.)
|
||||
(libburn sends its own buffer to the drive at the end of each track but does
|
||||
not sync the drive's chache. It is unclear wether this separation of tracks
|
||||
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
||||
harm in any case and would probably be unavoidable if audio and data tracks
|
||||
were mixed.)
|
||||
|
||||
When writing of all tracks is done, it is mandatory to force the drive's buffer
|
||||
to media by 35h SYNCHRONIZE CACHE.
|
||||
(mmc5r03c.pdf, 6.41)
|
||||
|
||||
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
What is known about mixed mode sessions :
|
||||
|
||||
For now, SAO sessions with a mix of data and audio are not supported in
|
||||
libburn. Here are the reasons why.
|
||||
|
||||
Obviously the code of http://icculus.org/burn is incomplete in this aspect.
|
||||
In mmc5r03c.pdf comparison of table 555 and 6.33.3.18 seems self-contradicting.
|
||||
(The second Pre-gap in table 555 does not match any of the criteria of
|
||||
6.33.3.18. Also, there is no Post-gap shown in table 555 although 6.33.3.19
|
||||
would prescribe some.)
|
||||
|
||||
If a data track follows an audio track then the data track gets a preceding
|
||||
extended Pre-gap:
|
||||
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
|
||||
with TNO already the number of the data track. The MSF address is to be
|
||||
increased by 3 seconds. The first second of the extended Pre-gap needs to be
|
||||
written in the audio track's mode and the other 2 seconds are to be written
|
||||
in the data track's mode.
|
||||
(libburn compares DATA FORM rather than burn_track.mode . Wrong ?)
|
||||
(libburn currently does only 2 seconds and the second part of Pre-gap. There is
|
||||
an issue with burn_track.pregap1 about this. Seems libburn mistakes the pause
|
||||
preceding track 1 for a part 2 of an extended Pre-gap.)
|
||||
|
||||
If a data track is followed by an audio track then it gets a Post-gap of at
|
||||
least two seconds.
|
||||
No example of Post-gap is given for Cue Sheet. Maybe it is to be added to the
|
||||
track, or maybe it gets an own Cue Sheet entry ... who knows ?
|
||||
(libburn contains write code for pregap1, pregap2 and postgap. But only
|
||||
pregap2 ever gets activated. Once hackingly for the first 2 second pause, once
|
||||
incompletely for a change of DATA FORM.)
|
||||
|
||||
Seems nobody ever tested this. Libburnia simply knows no use case where the
|
||||
correctness of Pre-gap and Post-gap would become evident.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Overwriteable DVD Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
and by experiments with drives NEC ND-4570A and LG GSA-4082B.
|
||||
|
||||
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-RAM 0012h
|
||||
DVD-RW Restricted Overwrite 0013h
|
||||
DVD-RW Sequential Recording 0014h (i.e. unformatted)
|
||||
DVD+RW 001Ah
|
||||
|
||||
A short compilation of the write model:
|
||||
- Overwriting in general
|
||||
|
||||
The recipes described here are depending on formatting state:
|
||||
- DVD-RAM, fully formatted DVD+RW or DVD-RW
|
||||
- Unformatted DVD+RW
|
||||
- Partly formatted DVD+RW
|
||||
- Unformatted DVD-RW
|
||||
- Partly formatted DVD-RW
|
||||
- Intermediate state DVD-RW
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Overwriting in general :
|
||||
|
||||
Depending on media type, some kind of formatting has to have happened before
|
||||
data can be written. Formatting may happen separately from writing or
|
||||
simultaneously. See the particular recipes below.
|
||||
|
||||
No Write Parameters mode page 05h is to be sent. 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)
|
||||
Optimal performance is promised without any speed setting. But my experiments
|
||||
showed that SET STREAMING values persist after media change.
|
||||
|
||||
In the formatted area of the media, coarse random access is possible.
|
||||
For DVD-RAM and DVD+RW write addresses and data size need to be aligned
|
||||
to 2 KiB. For DVD-RW alignment has to be 32 KiB. Within these limitations
|
||||
the write address is at the discretion of the sending program.
|
||||
Just use 2Ah WRITE to send data.
|
||||
(mmc5r03c.pdf, 6.44)
|
||||
When writing is done, it is mandatory to force the drive's buffer to media by
|
||||
35h SYNCHRONIZE CACHE.
|
||||
(mmc5r03c.pdf, 6.41)
|
||||
|
||||
The size of the formatted area can be inquired by 23h READ FORMAT CAPACITIES.
|
||||
The Number Of Blocks value in the Current/Maximum Capacity Descriptor gives
|
||||
this size in 2 KiB blocks. But this is true only if Descriptor Type is 10b
|
||||
("Formatted Media").
|
||||
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.2.3)
|
||||
|
||||
Not yet formatted areas may be completely forbidden or they may be allowed for
|
||||
sequential writing (DVD-RW Intermediate state) or they may be allowed for
|
||||
random access only after the necessary waiting time for formatting to reach
|
||||
the desired address (DVD+RW with background formatting active).
|
||||
|
||||
Already written areas can be overwritten without special precaution.
|
||||
Blanking a DVD-RW actually destroys its formatting.
|
||||
|
||||
|
||||
Most of the concepts usually expressed in Write Parameters mode page 05h do not
|
||||
apply to the recipes here: Test-Write, Buffer Underrun protection,
|
||||
Multi-session, Write Type, Block Type, Track Mode, ...
|
||||
There are hints for multi-session formats with DVD-RW but both of my drives
|
||||
do not offer "Add Session" Format Types 12h or 14h.
|
||||
(mmc5r03c.pdf 6.5.4.2.7 , 6.5.4.2.9)
|
||||
|
||||
|
||||
Caution: Drive and media compatibility seems still to be quite an adventure.
|
||||
If you experience problems, especially problems with readability, then try
|
||||
different drives and media brands. Failure does not necessarily mean that the
|
||||
software did anything wrong.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DVD-RAM, fully formatted DVD+RW or DVD-RW :
|
||||
|
||||
Full format is the natural state of DVD-RAM.
|
||||
|
||||
DVD+RW reaches this state if Background Formatting is allowed to finish without
|
||||
being stopped by 5Bh CLOSE TRACK SESSION.
|
||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
||||
The formatting state of a DVD+RW may be inquired by 51h READ DISC INFORMATION
|
||||
requesting Data Type 000b "Standard Disc Information". In the reply,
|
||||
BG Format 3 indicates fully formatted media.
|
||||
(mmc5r03c.pdf 6.22.3.1.13)
|
||||
|
||||
DVD-RW reaches this state either by Format Type 00h (or 10h) with maximum
|
||||
size given as Number Of Blocks, or by writing sequentially until the disc is
|
||||
completely full into an intermediate session opened by format 15h resp. 13h.
|
||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.1, 6.5.4.2.10, 6.5.4.2.8)
|
||||
A fully formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
||||
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
||||
Media") and 0 blocks are offered with Format Types 13h or 11h.
|
||||
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
||||
See also discussion of unformatted or partially formatted DVD-RW below.
|
||||
|
||||
|
||||
In fully formatted state there is no need for any formatting before writing nor
|
||||
for any finalizing other than forcing the drive's buffer to media by
|
||||
35h SYNCHRONIZE CACHE (which is mandatory for writing, anyway).
|
||||
(mmc5r03c.pdf, 6.41)
|
||||
|
||||
(It seems to do no harm to send to DVD+RW or DVD-RW a 5Bh CLOSE TRACK SESSION
|
||||
with Close Function 010b despite there is no session open in this scenario.)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Unformatted DVD+RW
|
||||
|
||||
This is the state of previously unused DVD+RW media.
|
||||
|
||||
The formatting state of a DVD+RW may be inquired by 51h READ DISC INFORMATION
|
||||
requiring Data Type 000b "Standard Disc Information".
|
||||
In the reply, BG Format 0 indicates unformatted media (or unsuitable media).
|
||||
(mmc5r03c.pdf 6.22.3.1.13)
|
||||
|
||||
Formatting has to be started by command 04h FORMAT UNIT, Format Type 26h.
|
||||
Different from other format types, 26h allows to send a fantasy size of
|
||||
0xffffffff blocks and does not require the caller to know the exact maximum
|
||||
size offered with that format.
|
||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
||||
|
||||
As its name suggests, one has not to wait for background formatting to end
|
||||
but may very soon start writing as on formatted media. Random access to
|
||||
yet unformatted areas can last long, though.
|
||||
|
||||
If backup formatting has been started at the beginning of the session, then
|
||||
it may get stopped after the final cache sync by 5Bh CLOSE TRACK SESSION
|
||||
with Close Function 010b.
|
||||
(mmc5r03c.pdf 6.3.3.6)
|
||||
|
||||
Formatting of DVD+RW is called "de-icing" because unformatted areas offer
|
||||
no hold for random access addressing and are thus slippery like ice. One can
|
||||
also see a color change from shiny unformatted to more dull formatted media.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Partly formatted DVD+RW :
|
||||
|
||||
This state is achieved by stopping background formatting before the media
|
||||
was completely formmatted.
|
||||
|
||||
The formatting state of a DVD+RW is obtained by 51h READ DISC INFORMATION
|
||||
requiring Data Type 000b "Standard Disc Information".
|
||||
In the reply, BG Format 1 indicates partly formatted media.
|
||||
(mmc5r03c.pdf 6.22.3.1.13)
|
||||
|
||||
If the data of the session surely fit into the formatted area, then it would
|
||||
be unnecessary to restart background formatting.
|
||||
But in order to make the DVD+RW surely accept its maximum number of bytes,
|
||||
formatting may be restarted by command 04h FORMAT UNIT, Format Type 26h,
|
||||
with the Restart bit set and Number of Blocks set to 0xffffffff.
|
||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
||||
|
||||
From then on, the same rules apply as for previously unformatted DVD+RW.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Unformatted DVD-RW (media profile is 0014h) :
|
||||
|
||||
This state is present with previously unused media. It is also present with
|
||||
media blanked by programs cdrecord, wodim or dvd+rw-format and with media which
|
||||
were sequentially written from blank state.
|
||||
Profile transition from formatted 0013h to unformatted 0014h is done by
|
||||
A1h BLANK.
|
||||
(mmc5r03c.pdf, 6.2)
|
||||
Experiments on my drives indicate that only Blanking Type 000b "Blank the disc"
|
||||
achieves neat media. Media blanked via type 001b offer no feature 0021h and
|
||||
stall cdrecord or libburn already when those media get examined. growisofs can
|
||||
burn them - but only via DAO (feature 002Fh which prescribes Write Type 2).
|
||||
(mmc5r03c.pdf 5.3.11, 5.3.25)
|
||||
|
||||
For becoming overwriteable such media need to be treated by command 04h FORMAT
|
||||
UNIT.
|
||||
(mmc5r03c.pdf, 6.5)
|
||||
The Format Type has to be chosen from the list replied by 23h READ FORMAT
|
||||
CAPACITIES. Suitable are Format Types 00h, 10h, 15h.
|
||||
(mmc5r03c.pdf 6.24)
|
||||
|
||||
Format Types 00h and 10h provide a writeable area of a size given by Number of
|
||||
Blocks. Type 00h seems to be the most traditional and complete one. It needs
|
||||
no closing of a session at the end of writing.
|
||||
The Number Of Blocks may be at most the value reported by 23h READ FORMAT
|
||||
CAPACITIES in the entry for the desired format type. Full format is achieved
|
||||
by sending exactly the reported value.
|
||||
(mmc5r03c.pdf, 6.5.4.2.1 Format Type = 00h, 6.5.4.2.5 Format Type = 10h)
|
||||
|
||||
Format Type 15h provides a writeable area of given size too, but this area can
|
||||
be expanded by sequential writing and afterwards marked as overwriteable by
|
||||
closing the session. It is even allowed to format with size 0 and to leave
|
||||
the size claim entirely to a sequential write process beginning at LBA 0.
|
||||
(mmc5r03c.pdf, 6.5.4.2.10 Format Type = 15h)
|
||||
When writing is done and cache is synced, one should send 5Bh CLOSE TRACK
|
||||
SESSION with Close Function 010b in order to bring the session out of
|
||||
Intermediate state.
|
||||
(mmc5r03c.pdf 6.3.3.2.3)
|
||||
If not written up to the last 32 KiB block, the DVD-RW is only partly formatted
|
||||
after that.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Partly formatted DVD-RW (media profile is 0013h) :
|
||||
|
||||
This state is achieved by formatting a DVD-RW with a number of blocks which
|
||||
is less than offered for the Format Type by the drive's reply to 23h READ
|
||||
FORMAT CAPACITIES. If the media was most recently formatted by Format Types
|
||||
015h or 013h then it must have got written some bytes and afterwards treated
|
||||
by 5Bh CLOSE TRACK SESSION, 010b in order to be partly formatted.
|
||||
(mmc5r03c.pdf 6.3.3.2.3 CLOSE TRACK SESSION 010b, 6.24 READ FORMAT CAPACITIES)
|
||||
Elsewise the media is in Intermediate state. See below.
|
||||
|
||||
A partly formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
||||
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
||||
Media") and the Number Of Blocks with formats 00h, 10h or 15h is larger than the
|
||||
currently formatted size, resp. more than 0 blocks are offered with Format
|
||||
Types 13h or 11h.
|
||||
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
||||
|
||||
If the data of the session surely fit into the formatted area, then it would
|
||||
be unnecessary to do any further formatting.
|
||||
But in order to make the DVD-RW surely accept its maximum number of bytes,
|
||||
partial formatting may be expanded by command 04h FORMAT UNIT, Format Type 13h,
|
||||
which is supposed to be offered by the drive in this state. This brings the
|
||||
session again into Intermediate state and thus allows expansion by sequential
|
||||
writing. As with Format Type 15h it is ok to set Number Of Blocks to 0, so that
|
||||
no fixed size formatting work is done and writing can begin soon after.
|
||||
(mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h)
|
||||
|
||||
When writing is done and cache is synced, one should send 5Bh CLOSE TRACK
|
||||
SESSION with Close Function 010b in order to bring the session out of
|
||||
Intermediate state.
|
||||
(mmc5r03c.pdf 6.3.3.2.3)
|
||||
If not written up to the last 32 KiB block, the DVD-RW is only partly formatted
|
||||
after that.
|
||||
|
||||
Format Type 13h has been tested only with expanding sessions formatted by 15h.
|
||||
Nevertheless it is offered with sessions from 00h and 10h, too.
|
||||
According to the specs, Format Type 11h would expand a session by a fixed
|
||||
size. This has not been tested yet because it is less appealing than 13h.
|
||||
(mmc5r03c.pdf, 6.5.4.2.6 Format Type = 11h)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Intermediate state DVD-RW (media profile is 0013h) :
|
||||
|
||||
This state is achieved by formatting a DVD-RW with Format Type 15h or 13h
|
||||
without subsequentially writing data and sending 5Bh CLOSE TRACK SESSION
|
||||
with Close Function 010b.
|
||||
Such media behave very unpleasing with my DVD-ROM drive under Linux 2.4 ide-cd.
|
||||
One should therefore better avoid to release media in this state.
|
||||
|
||||
This state can be recognized by 23h READ FORMAT CAPACITIES. The Descriptor Type
|
||||
of the Current/Maximum Capacity Descriptor is 11b ("Unknown Capacity") and
|
||||
no formats 13h or 11h are offered.
|
||||
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
||||
|
||||
One may treat such media as if Format Type 15h or 13h had been freshly applied.
|
||||
I.e. sequential writing from LBA 0. After cache sync bring the session out
|
||||
of Intermediate state by 5Bh CLOSE TRACK SESSION with Close Function 010b.
|
||||
(mmc5r03c.pdf 6.3.3.2.3)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Sequential DVD-R[W] Cookbook
|
||||
-------------------------------------------------------------------------------
|
||||
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||
and by experiments with drives NEC ND-4570A and LG GSA-4082B.
|
||||
|
||||
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 0011h
|
||||
DVD-RW Restricted Overwrite 0013h
|
||||
DVD-RW Sequential Recording 0014h
|
||||
|
||||
There are two approaches for writing to sequential DVD-R[W]: DAO and
|
||||
Incremental. Not all media and drives offer Incremental which allows
|
||||
multi-session as with CD media and does not demand a predicted track size.
|
||||
DAO seems to be the older method. It allows only one single session and
|
||||
track and it demands an exactly predicted track size.
|
||||
|
||||
- About overwriteable, blank, appendable and finalized DVD-R[W] media
|
||||
- Incremental writing
|
||||
- DAO writing
|
||||
- Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems
|
||||
- Obtaining a Table Of Content from DVD-R[W]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
About overwriteable, blank, appendable and finalized DVD-R[W] media :
|
||||
|
||||
DVD-RW can be either in formatted state Restricted Overwrite or in unformatted
|
||||
state Sequential Recording. Sequential media can be either blank, appendable
|
||||
or finalized.
|
||||
|
||||
Only blank and appendable media are sequentially writeable. For overwriteable
|
||||
DVD-RW see the Overwriteable DVD Cookbook.
|
||||
|
||||
Overwriteable DVD-RW can be detected by their profile number 0013h in contrast
|
||||
to profile number 0014h for sequential DVD-RW.
|
||||
The status of sequential media can be inquired like with CD by 51h READ DISC
|
||||
INFORMATION requesting Data Type 000b Standard Disc Information, where reply
|
||||
value Disc Status indicates:
|
||||
00b blank
|
||||
01b appendable
|
||||
10b finalized
|
||||
11b others (unsuitable for this recipe)
|
||||
(mmc5r03c.pdf 6.22.3.1.4)
|
||||
|
||||
Finalized, appendable or overwriteable DVD-RW can be brought into blank
|
||||
sequential state by command A1h BLANK with blanking type 000b "Blank the disc".
|
||||
See TAO Multi-Session CD Cookbook for details about blanking.
|
||||
|
||||
After minimal blanking (type 001b) DVD-RW my two drives do not offer the
|
||||
Incremental Streaming feature 0021h the media any more. Full blanking (000b)
|
||||
brings back this feature.
|
||||
(mmc5r03c.pdf 6.2)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Incremental writing :
|
||||
|
||||
Incremental writing allows to produce multi-session DVDs. It is indicated
|
||||
by feature 0021h being marked current in the reply of 46h GET CONFIGURATION.
|
||||
growisofs inquires 0021h by setting Starting Feature Number to 0x21 and
|
||||
Allocation Length to 16 in order to get only this one. The feature descriptor
|
||||
begins at byte 8 of the reply. Its availability is indicated by the Current
|
||||
Bit. libburn obtains the full feature list for this and other info.
|
||||
(mmc5r03c.pdf 5.2.2. Feature Descriptor format, 5.3.11 Feature 0021h,
|
||||
6.2 46h GET CONFIGURATION, )
|
||||
In mode page 05h this method is selected by Write Type 00h.
|
||||
|
||||
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)
|
||||
|
||||
growisofs fetches a mode page 05h template by MODE SENSE and inserts its own
|
||||
parameters. It sets Multi-session to 11b, unless dvd_compat is nonzero.
|
||||
libburn composes its mode page 05h from zero and allows control of
|
||||
Multi-Session by the application.
|
||||
BUFE Buffer Underrun protection 0=off, 1=on
|
||||
LS_V Link size valid 1=true
|
||||
Test Write -dummy mode for writing 0=off, 1=on
|
||||
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
||||
Multi-session Wether to keep appendable 00b = finalize
|
||||
11b = keep appendable
|
||||
Track Mode Describes frame type 5 [*1]
|
||||
Data Block Type Layout of payload blocks 8 [*2]
|
||||
Link Size ??? 16 [*3]
|
||||
FP Fixed Packet Size Bit 1
|
||||
Packet Size 16 [*4]
|
||||
(mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode)
|
||||
(spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats)
|
||||
[*1:]
|
||||
growisofs takes the Track Mode from 52h READ TRACK INFORMATION, Address/Number
|
||||
Type 1, Track 1, Track Information Block byte 5 & 0xf.
|
||||
(mmc5r03.pdf 6.27)
|
||||
The specs predict that this will be Track Mode 4 (6.27.3.8) and also state that
|
||||
default is 5 (7.5.4.12). 4 means: uninterrupted, do not copy. 5 means
|
||||
increment, do not copy.
|
||||
[*2:]
|
||||
8 means: 2048 byte data blocks. growisofs sets this value if Data Mode from
|
||||
above 52h READ TRACK INFORMATION is 1 or Fh, which is predicted by the specs
|
||||
to be always true.
|
||||
(mmc5r03.pdf 6.27.3.10)
|
||||
[*3:]
|
||||
growisofs (transport.hxx) sets Link Size to 16 for profiles 0011h and 0014h.
|
||||
libburn now records the first link size from feature 0021h in its burn_drive
|
||||
structure. If another link size item is 16, then 16 is used.
|
||||
[*4:]
|
||||
growisofs takes Packet Size from 52h. Specs predict it will be 16 (= 32 kB).
|
||||
(mmc5r03.pdf 7.5.4.16)
|
||||
|
||||
The writing process is much like in "Writing a session to CD in TAO mode" :
|
||||
Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION.
|
||||
libburn writes full 32 kB buffers via 2Ah WRITE.
|
||||
(mmc5r03c.pdf, 6.27 READ TRACK INFORMATION, 6.44 WRITE)
|
||||
When writing is done, it is mandatory to force the drive's buffer to media by
|
||||
35h SYNCHRONIZE CACHE.
|
||||
(mmc5r03c.pdf, 6.41)
|
||||
|
||||
The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b.
|
||||
growisofs uses the logical track number for that and not FFh like libburn
|
||||
does with TAO CD. So libburn obtains the Last Track Number in Last Session
|
||||
from the reply of 51h READ DISC INFORMATION requesting Data Type 000b
|
||||
"Standard Disc Information".
|
||||
(mmc5r03c.pdf 6.3.3.2.2 CLOSE TRACK, 6.22.3.1.)
|
||||
|
||||
Multiple tracks are permissible in a single session. After all of them have
|
||||
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
||||
Number 0 closes the session. It depends on the Multi-Session value in mode
|
||||
page 05h wether the disc is finalized or stays appendable.
|
||||
(mmc5r03c.pdf 6.3.3.2.3)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DAO writing :
|
||||
|
||||
DAO is the mode described by feature 002Fh. This feature also gives information
|
||||
about capabilities for Burnfree (BUF), Test Write and DVD-RW.
|
||||
(mmc5r03c.pdf 5.3.25)
|
||||
Experiments with growisofs showed that the track size needs to be predicted
|
||||
and may not be exceeded during the write process. (growisofs ran into SCSI
|
||||
errors with piped non-ISO-9660 images and with piped ISO-9660 which have
|
||||
trailing data.)
|
||||
|
||||
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)
|
||||
|
||||
The mode page 05h to be sent :
|
||||
BUFE Buffer Underrun protection 0=off, 1=on
|
||||
LS_V Link size valid 0=false [*3]
|
||||
Test Write -dummy mode for writing 0=off, 1=on
|
||||
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
||||
Multi-session Wether to keep appendable 00b = finalize
|
||||
Track Mode Describes frame type 5 [*1]
|
||||
Data Block Type Layout of payload blocks 8 [*2]
|
||||
Link Size ??? 0 [*3]
|
||||
FP Fixed Packet Size Bit 0 [*3]
|
||||
Packet Size 0 [*3]
|
||||
(mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode)
|
||||
(spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats)
|
||||
[*1:]
|
||||
growisofs takes the Track Mode from 52h READ TRACK INFORMATION, Address/Number
|
||||
Type 1, Track 1, Track Information Block byte 5 & 0xf.
|
||||
(mmc5r03.pdf 6.27)
|
||||
[*2:]
|
||||
8 means: 2048 byte data blocks. growisofs sets this value if Data Mode from
|
||||
above 52h READ TRACK INFORMATION is 1 or Fh, which is predicted by the specs
|
||||
to be always true. (If not: growisofs aborts.)
|
||||
(mmc5r03.pdf 6.27.3.10)
|
||||
[*3:]
|
||||
Link Size, Packet Size and their companions only apply to Write Type 00h.
|
||||
|
||||
The session layout must be described by 53h RESERVE TRACK, RMZ=ARSV=0.
|
||||
Reservation size should better already be aligned to 32 KiB. It has not been
|
||||
tested yet, what happens if not enough data get written.
|
||||
(mmc5r03c.pdf 6.31)
|
||||
|
||||
Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION.
|
||||
The reply is supposed to be 0. libburn writes full 32 kB buffers via 2Ah WRITE.
|
||||
(mmc5r03c.pdf, 6.27 READ TRACK INFORMATION, 6.44 WRITE)
|
||||
If the track source delivers less than the announced size then libburn pads up
|
||||
by zeros.
|
||||
When writing is done, it is mandatory to force the drive's buffer to media by
|
||||
35h SYNCHRONIZE CACHE.
|
||||
(mmc5r03c.pdf, 6.41)
|
||||
|
||||
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems :
|
||||
|
||||
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
|
||||
matches the block addresses of the future location on media.
|
||||
These are the start address of the first track in the last complete session
|
||||
and the predicted start address of the track which will host the new image.
|
||||
See TAO Multi-Session CD Cookbook for some more info about mkisofs aspects.
|
||||
|
||||
|
||||
The first number may be gained by 43h READ TOC/PMA/ATIP Format 0001b which in
|
||||
table 478 promises quick access via Start Address Of First Track In Last
|
||||
Session.
|
||||
(mmc5r03c.pdf 6.26.2.5 table 478, 6.26.3.3.1)
|
||||
Regrettably the MMC-5 specs still define a useless reply for non-CD media
|
||||
which obviously stems from MMC-3 times when no multi-session was possible
|
||||
with non-CD.
|
||||
(mmc5r03c.pdf 6.26.3.3.3)
|
||||
Both my drives do give a useful reply with the correct number for appendable
|
||||
DVD-RW. But not being backed by the specs this method appears unappealing .
|
||||
|
||||
Another approach would be a formatted Table of Content, obtained by 43h READ
|
||||
TOC/PMA/ATIP Format 0000b. The specs do not totally outrule that this returns
|
||||
useful data with non-CD but they define a crippled TOC for multi-session.
|
||||
(mmc5r03c.pdf 6.26.3.2.4)
|
||||
My LG drive returns a more detailed TOC, my NEC drive stays with the rather
|
||||
suboptimal specs. So one would get different TOCs on different drives.
|
||||
Nevertheless, the MMC-5 compliant TOC would return the desired number in
|
||||
the Track Start address of the track with the highest number before AAh.
|
||||
|
||||
Most stable seems the approach to obtain the desired number from the reply
|
||||
of 52h READ TRACK INFORMATION, Address/Number Type 01b. The field Logical Block
|
||||
Address/Track/Session has to bear the track number of the first track in the
|
||||
last complete session. To determine this number one has to determine the
|
||||
number of the last session and the number of the last track from 51h READ DISC
|
||||
INFORMATION and to iterate over the tracknumber by 52h READ TRACK INFORMATION
|
||||
until the first track with the desired session number appears and reveils
|
||||
its start address.
|
||||
(mmc5r03c.pdf 6.22 51h DISC, 6.27 52h TRACK)
|
||||
This method is very near to fabricating an own TOC. So libburn does this
|
||||
when inspecting the media. If the first number for -C is needed, libburn
|
||||
inquires its TOC model for the address of the first track in the last
|
||||
complete session. See below for a detailed description of TOC fabrication.
|
||||
|
||||
|
||||
The second -C number is the exact prediction of future track start address. It
|
||||
is gained like with CD by 52h READ TRACK INFORMATION Type 01b. Different from
|
||||
CD one may not use track number FFh but has to use the Last Track in Last
|
||||
Session from 51h READ DISC INFORMATION.
|
||||
(mmc5r03c.pdf 6.22 51h DISC, 6.27 52h TRACK)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
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.
|
||||
There is a Format 0000b "Formatted TOC" but this is with non-CD a fictional
|
||||
information much at the discretion of the drive. Two drives with the same disc
|
||||
may well return different Formatted TOC. They are supposed to be consistent
|
||||
only about the last complete session and even there the MMC-5 specification
|
||||
6.26.3.2.5 seems to prescribe a structure which does not match the true
|
||||
structure of incremental writing to sequential DVD-R[W].
|
||||
(mmc5r03c.pdf 6.26.3.2)
|
||||
So i prefer not to use this method of getting a TOC.
|
||||
|
||||
|
||||
The alternative is to produce an own TOC from information gained by 51h READ
|
||||
DISC INFORMATION and by 52h READ TRACK INFORMATION which reveil a CD-like
|
||||
structure of sessions and 1:n related tracks.
|
||||
|
||||
51h READ DISC INFORMATION Data Type 000b, fields Number of Sessions (Least
|
||||
Significant Byte) and Number of Sessions (Most Significant Byte) give the
|
||||
number of sessions. The last complete session number of an appendable disc
|
||||
is one less because there is an incomplete session at its end. libburn only
|
||||
records complete sessions in its TOC model.
|
||||
libburn uses Last Track in Last Session as a hint for the range of track
|
||||
numbers.
|
||||
(mmc5r03c.pdf 6.22)
|
||||
|
||||
Next step is to iterate from 1 up to the last track number and to obtain
|
||||
the according track info by 52h READ TRACK INFORMATION. Each track tells its
|
||||
Session Number (LSB at byte 2, MSB at 33), its Logical Track Start Address,
|
||||
its Logical Track Size, and much more which is not needed for a fake CD TOC.
|
||||
One may analyze the track info more finely but for this special purpose
|
||||
it is enough to discard the tracks which do not belong to complete sessions.
|
||||
(mmc5r03c.pdf 6.27)
|
||||
|
||||
At the end of each session libburn inserts fake leadout entries into its TOC
|
||||
model. Their start address is computed from the start and size of the last
|
||||
track of the session.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -235,9 +235,11 @@ 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) */
|
||||
if ( ! (drive->status == BURN_DISC_FULL ||
|
||||
(drive->status == BURN_DISC_APPENDABLE &&
|
||||
! libburn_back_hack_42) ) ) {
|
||||
! 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,
|
||||
@ -323,6 +325,14 @@ 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;
|
||||
int i, j, mode, mixed_mode = 0;
|
||||
|
||||
/* For the next lines any return indicates failure */
|
||||
opts->drive->cancel = 1;
|
||||
|
||||
/* ts A70203 : people have been warned in API specs */
|
||||
if (opts->write_type == BURN_WRITE_NONE)
|
||||
return;
|
||||
|
||||
/* ts A61006 */
|
||||
/* a ssert(!SCAN_GOING()); */
|
||||
@ -347,6 +357,25 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||
if (! burn_disc_write_is_ok(opts, disc)) /* issues own msgs */
|
||||
return;
|
||||
|
||||
/* ts A70122 : libburn SAO code mishandles mode changes */
|
||||
for (i = 0; i < disc->sessions; i++) {
|
||||
if (disc->session[i]->tracks <= 0)
|
||||
continue;
|
||||
mode = disc->session[i]->track[0]->mode;
|
||||
for (j = 1; j < disc->session[i]->tracks; j++)
|
||||
if (mode != disc->session[i]->track[j]->mode)
|
||||
mixed_mode = 1;
|
||||
}
|
||||
if (mixed_mode && opts->write_type == BURN_WRITE_SAO) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
opts->drive->global_index, 0x00020133,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Cannot mix data and audio in SAO mode", 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
opts->drive->cancel = 0; /* End of the return = failure area */
|
||||
|
||||
o.drive = opts->drive;
|
||||
o.opts = opts;
|
||||
o.disc = disc;
|
||||
|
189
libburn/drive.c
189
libburn/drive.c
@ -347,6 +347,9 @@ int burn_drive_mark_unready(struct burn_drive *d)
|
||||
|
||||
/* ts A61202 */
|
||||
d->current_profile = -1;
|
||||
d->current_has_feat21h = 0;
|
||||
d->current_feat2fh_byte4 = -1;
|
||||
|
||||
d->status = BURN_DISC_UNREADY;
|
||||
if (d->toc_entry != NULL)
|
||||
free(d->toc_entry);
|
||||
@ -1406,6 +1409,32 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||
}
|
||||
|
||||
|
||||
/* ts A70131 : new API function */
|
||||
int burn_disc_get_msc1(struct burn_drive *d, int *start)
|
||||
{
|
||||
int ret, trackno;
|
||||
|
||||
if (burn_drive_is_released(d)) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x0002011b,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Attempt to read track info from ungrabbed drive",
|
||||
0, 0);
|
||||
return -1;
|
||||
}
|
||||
if (d->busy != BURN_DRIVE_IDLE) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x0002011c,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Attempt to read track info from busy drive",
|
||||
0, 0);
|
||||
return -1;
|
||||
}
|
||||
ret = d->read_multi_session_c1(d, &trackno, start);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61202 : New API function */
|
||||
int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
|
||||
{
|
||||
@ -1529,3 +1558,163 @@ int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list)
|
||||
return burn_speed_descriptor_destroy(speed_list, 1);
|
||||
}
|
||||
|
||||
|
||||
/* ts A70203 : API function */
|
||||
int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
||||
struct burn_multi_caps **caps, int flag)
|
||||
{
|
||||
enum burn_disc_status s;
|
||||
struct burn_multi_caps *o;
|
||||
int status, num_formats, ret, type, i;
|
||||
off_t size;
|
||||
unsigned dummy;
|
||||
|
||||
*caps = NULL;
|
||||
s = burn_disc_get_status(d);
|
||||
if(s == BURN_DISC_UNGRABBED)
|
||||
return -1;
|
||||
*caps = o = (struct burn_multi_caps *)
|
||||
malloc(sizeof(struct burn_multi_caps));
|
||||
if(*caps == NULL)
|
||||
return -1;
|
||||
/* Default says nothing is available */
|
||||
o->multi_session = o->multi_track = 0;
|
||||
o-> start_adr = 0;
|
||||
o->start_alignment = o->start_range_low = o->start_range_high = 0;
|
||||
o->might_do_tao = o->might_do_sao = o->might_do_raw = 0;
|
||||
o->advised_write_mode = BURN_WRITE_NONE;
|
||||
o->selected_write_mode = wt;
|
||||
o->current_profile = d->current_profile;
|
||||
o->current_is_cd_profile = d->current_is_cd_profile;
|
||||
|
||||
if (s != BURN_DISC_BLANK && s != BURN_DISC_APPENDABLE) {
|
||||
return 0;
|
||||
} else if (s == BURN_DISC_APPENDABLE &&
|
||||
(wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) {
|
||||
return 0;
|
||||
} else if (wt == BURN_WRITE_RAW && !d->current_is_cd_profile) {
|
||||
return 0;
|
||||
} else if (d->current_profile == 0x09 || d->current_profile == 0x0a) {
|
||||
/* CD-R , CD-RW */
|
||||
if (d->block_types[BURN_WRITE_TAO]) {
|
||||
o->multi_session = o->multi_track = 1;
|
||||
o->might_do_tao = 2;
|
||||
if (o->advised_write_mode == BURN_WRITE_NONE)
|
||||
o->advised_write_mode = BURN_WRITE_TAO;
|
||||
}
|
||||
if (d->block_types[BURN_WRITE_SAO]) {
|
||||
o->multi_session = o->multi_track = 1;
|
||||
o->might_do_sao = 1;
|
||||
if (o->advised_write_mode == BURN_WRITE_NONE)
|
||||
o->advised_write_mode = BURN_WRITE_SAO;
|
||||
}
|
||||
if (d->block_types[BURN_WRITE_RAW]) {
|
||||
o->might_do_raw = 1;
|
||||
if (o->advised_write_mode == BURN_WRITE_NONE)
|
||||
o->advised_write_mode = BURN_WRITE_RAW;
|
||||
}
|
||||
if (wt == BURN_WRITE_RAW)
|
||||
o->multi_session = o->multi_track = 0;
|
||||
} 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) {
|
||||
o->multi_session = o->multi_track = 1;
|
||||
o->might_do_tao = 2;
|
||||
o->advised_write_mode = BURN_WRITE_TAO;
|
||||
}
|
||||
if (wt == BURN_WRITE_SAO)
|
||||
o->multi_session = o->multi_track = 0;
|
||||
} else if (d->current_profile == 0x12 || d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x1a) {
|
||||
/* DVD-RAM, overwriteable DVD-RW, DVD+RW */
|
||||
o->start_adr = 1;
|
||||
ret = burn_disc_get_formats(d, &status, &size, &dummy,
|
||||
&num_formats);
|
||||
if (ret == 1) {
|
||||
if (status == BURN_FORMAT_IS_FORMATTED)
|
||||
o->start_range_high = size;
|
||||
if (d->current_profile == 0x13) {
|
||||
o->start_alignment = 32 * 1024;
|
||||
for (i = 0; i < num_formats; i++) {
|
||||
ret = burn_disc_get_format_descr(d, i,
|
||||
&type, &size, &dummy);
|
||||
if (ret <= 0)
|
||||
continue;
|
||||
if (type == 0x13) /* expandable */
|
||||
break;
|
||||
}
|
||||
if (i >= num_formats) /* not expandable */
|
||||
o->start_range_high -= 32 * 1024;
|
||||
} else {
|
||||
o->start_alignment = 2 * 1024;
|
||||
if (d->best_format_size - 2048 >
|
||||
o->start_range_high)
|
||||
o->start_range_high =
|
||||
d->best_format_size - 2048;
|
||||
}
|
||||
}
|
||||
o->might_do_tao = 2;
|
||||
o->advised_write_mode = BURN_WRITE_TAO;
|
||||
} else /* unknown media */
|
||||
return 0;
|
||||
|
||||
if (s == BURN_DISC_APPENDABLE)
|
||||
o->might_do_sao = o->might_do_raw = 0;
|
||||
|
||||
if (wt == BURN_WRITE_TAO && !o->might_do_tao)
|
||||
return 0;
|
||||
else if (wt == BURN_WRITE_SAO && !o->might_do_sao)
|
||||
return 0;
|
||||
else if (wt == BURN_WRITE_RAW && !o->might_do_raw)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70203 : API function */
|
||||
int burn_disc_free_multi_caps(struct burn_multi_caps **caps)
|
||||
{
|
||||
if (*caps == NULL)
|
||||
return 0;
|
||||
free((char *) *caps);
|
||||
*caps = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70207 : evaluate write mode related peculiarities of a disc */
|
||||
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
|
||||
struct burn_disc_mode_demands *result, int flag)
|
||||
{
|
||||
struct burn_session *session;
|
||||
struct burn_track *track;
|
||||
int i, j, mode;
|
||||
|
||||
memset((char *) result, 0, sizeof(struct burn_disc_mode_demands));
|
||||
if (disc->sessions > 1)
|
||||
result->multi_session = 1;
|
||||
for (i = 0; i < disc->sessions; i++) {
|
||||
session = disc->session[i];
|
||||
if (session->tracks <= 0)
|
||||
continue;
|
||||
mode = session->track[0]->mode;
|
||||
if (session->tracks > 1)
|
||||
result->multi_track = 1;
|
||||
for (j = 0; j < session->tracks; j++) {
|
||||
track = session->track[j];
|
||||
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->exotic_track = 1;
|
||||
if (track->mode == BURN_AUDIO)
|
||||
result->audio = 1;
|
||||
}
|
||||
}
|
||||
return (disc->sessions > 0);
|
||||
}
|
||||
|
@ -95,4 +95,17 @@ int burn_mdata_free_subs(struct scsi_mode_data *m);
|
||||
/* ts A61230 */
|
||||
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag);
|
||||
|
||||
|
||||
/* ts A70207 : evaluate write mode related peculiarities of a disc */
|
||||
struct burn_disc_mode_demands {
|
||||
int multi_session;
|
||||
int multi_track;
|
||||
int unknown_track_size;
|
||||
int mixed_mode;
|
||||
int audio;
|
||||
int exotic_track;
|
||||
};
|
||||
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
|
||||
struct burn_disc_mode_demands *result, int flag);
|
||||
|
||||
#endif /* __DRIVE */
|
||||
|
@ -42,7 +42,7 @@ static int file_read(struct burn_source *source,
|
||||
unsigned char *buffer,
|
||||
int size)
|
||||
{
|
||||
struct burn_source_fd *fs = source->data;
|
||||
struct burn_source_file *fs = source->data;
|
||||
|
||||
return read_full_buffer(fs->datafd, buffer, size);
|
||||
}
|
||||
@ -71,14 +71,24 @@ static off_t file_size(struct burn_source *source)
|
||||
struct stat buf;
|
||||
struct burn_source_file *fs = source->data;
|
||||
|
||||
if (fs->fixed_size > 0)
|
||||
return fs->fixed_size;
|
||||
if (fstat(fs->datafd, &buf) == -1)
|
||||
return (off_t) 0;
|
||||
/* for now we keep it compatible to the old (int) return value */
|
||||
if(buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */
|
||||
return (off_t) 1308622848;
|
||||
return (off_t) buf.st_size;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70125 */
|
||||
static int file_set_size(struct burn_source *source, off_t size)
|
||||
{
|
||||
struct burn_source_file *fs = source->data;
|
||||
|
||||
fs->fixed_size = size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
||||
{
|
||||
struct burn_source_file *fs;
|
||||
@ -103,84 +113,43 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
||||
if (subpath)
|
||||
fs->subfd = fd2;
|
||||
|
||||
/* ts A70125 */
|
||||
fs->fixed_size = 0;
|
||||
|
||||
src = burn_source_new();
|
||||
src->read = file_read;
|
||||
if (subpath)
|
||||
src->read_sub = file_read_sub;
|
||||
|
||||
src->get_size = file_size;
|
||||
src->set_size = file_set_size;
|
||||
src->free_data = file_free;
|
||||
src->data = fs;
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
/* ------ provisory location for the new source subclass fd --------- */
|
||||
|
||||
static off_t fd_get_size(struct burn_source *source)
|
||||
{
|
||||
struct stat buf;
|
||||
struct burn_source_fd *fs = source->data;
|
||||
|
||||
if (fs->fixed_size > 0)
|
||||
return fs->fixed_size;
|
||||
if (fstat(fs->datafd, &buf) == -1)
|
||||
return (off_t) 0;
|
||||
/* for now we keep it compatible to the old (int) return value */
|
||||
if (buf.st_size >= 1308622848) /* 2 GB - 800 MB to prevent rollover */
|
||||
return (off_t) 1308622848;
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
static int fd_read(struct burn_source *source,
|
||||
unsigned char *buffer,
|
||||
int size)
|
||||
{
|
||||
struct burn_source_fd *fs = source->data;
|
||||
|
||||
return read_full_buffer(fs->datafd, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
static int fd_read_sub(struct burn_source *source,
|
||||
unsigned char *buffer,
|
||||
int size)
|
||||
{
|
||||
struct burn_source_fd *fs = source->data;
|
||||
|
||||
return read_full_buffer(fs->subfd, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
static void fd_free_data(struct burn_source *source)
|
||||
{
|
||||
struct burn_source_fd *fs = source->data;
|
||||
|
||||
close(fs->datafd);
|
||||
if (source->read_sub)
|
||||
close(fs->subfd);
|
||||
free(fs);
|
||||
}
|
||||
|
||||
/* ts A70126 : removed class burn_source_fd in favor of burn_source_file */
|
||||
|
||||
struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
||||
{
|
||||
struct burn_source_fd *fs;
|
||||
struct burn_source_file *fs;
|
||||
struct burn_source *src;
|
||||
|
||||
if (datafd == -1)
|
||||
return NULL;
|
||||
fs = malloc(sizeof(struct burn_source_fd));
|
||||
fs = malloc(sizeof(struct burn_source_file));
|
||||
fs->datafd = datafd;
|
||||
fs->subfd = subfd;
|
||||
fs->fixed_size = size;
|
||||
|
||||
src = burn_source_new();
|
||||
src->read = fd_read;
|
||||
src->read = file_read;
|
||||
if(subfd != -1)
|
||||
src->read = fd_read_sub;
|
||||
src->get_size = fd_get_size;
|
||||
src->free_data = fd_free_data;
|
||||
src->read = file_read_sub;
|
||||
src->get_size = file_size;
|
||||
src->set_size = file_set_size;
|
||||
src->free_data = file_free;
|
||||
src->data = fs;
|
||||
return src;
|
||||
}
|
||||
|
@ -4,19 +4,14 @@
|
||||
#define BURN__FILE_H
|
||||
|
||||
struct burn_source_file
|
||||
{
|
||||
int datafd;
|
||||
int subfd;
|
||||
};
|
||||
|
||||
|
||||
/* ------ provisory location for the new source subclass fd --------- */
|
||||
|
||||
struct burn_source_fd
|
||||
{
|
||||
int datafd;
|
||||
int subfd;
|
||||
off_t fixed_size;
|
||||
};
|
||||
|
||||
|
||||
/* ts A70126 : burn_source_file obsoleted burn_source_fd */
|
||||
|
||||
|
||||
#endif /* LIBBURN__FILE_H */
|
||||
|
@ -107,22 +107,40 @@ struct burn_write_opts;
|
||||
enum burn_write_types
|
||||
{
|
||||
/** Packet writing.
|
||||
currently unsupported
|
||||
currently unsupported, (for DVD Incremental Streaming use TAO)
|
||||
*/
|
||||
BURN_WRITE_PACKET,
|
||||
/** Track At Once recording.
|
||||
2s gaps between tracks, no fonky lead-ins
|
||||
|
||||
/** With CD: Track At Once recording
|
||||
2s gaps between tracks, no fonky lead-ins
|
||||
|
||||
With sequential DVD-R[W]: Incremental Streaming
|
||||
With DVD-RAM/+RW: Random Writeable (used sequentially)
|
||||
With overwriteable DVD-RW: Rigid Restricted Overwrite
|
||||
*/
|
||||
BURN_WRITE_TAO,
|
||||
/** Session At Once.
|
||||
block type MUST be BURN_BLOCK_SAO
|
||||
|
||||
/** With CD: Session At Once
|
||||
Block type MUST be BURN_BLOCK_SAO
|
||||
ts A70122: Currently not capable of mixing data and audio tracks.
|
||||
|
||||
With sequential DVD-R[W]: Disc-at-once, DAO
|
||||
Single session, single track, fixed size mandatory, (-dvd-compat)
|
||||
*/
|
||||
BURN_WRITE_SAO,
|
||||
/** Raw disc at once recording.
|
||||
all subcodes must be provided by lib or user
|
||||
only raw block types are supported
|
||||
|
||||
/** With CD: Raw disc at once recording.
|
||||
all subcodes must be provided by lib or user
|
||||
only raw block types are supported
|
||||
*/
|
||||
BURN_WRITE_RAW
|
||||
BURN_WRITE_RAW,
|
||||
|
||||
/** In replies this indicates that not any writing will work.
|
||||
As parameter for inquiries it indicates that no particular write
|
||||
mode shall is specified.
|
||||
Do not use for setting a write mode for burning. It won't work.
|
||||
*/
|
||||
BURN_WRITE_NONE
|
||||
};
|
||||
|
||||
/** Data format to send to the drive */
|
||||
@ -237,9 +255,18 @@ enum burn_drive_status
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Information about a track on a disc - this is from the q sub channel of the
|
||||
lead-in area of a disc. The documentation here is very terse.
|
||||
See a document such as mmc3 for proper information.
|
||||
|
||||
CAUTION : This structure is prone to future extension !
|
||||
|
||||
Do not restrict your application to unsigned char with any counter like
|
||||
"session", "point", "pmin", ...
|
||||
Do not rely on the current size of a burn_toc_entry.
|
||||
|
||||
ts A70201 : DVD extension, see below
|
||||
*/
|
||||
struct burn_toc_entry
|
||||
{
|
||||
@ -263,6 +290,23 @@ struct burn_toc_entry
|
||||
unsigned char psec;
|
||||
/** Track start time frames for normal tracks */
|
||||
unsigned char pframe;
|
||||
|
||||
/* Indicates wether extension data are valid and eventually override
|
||||
older elements in this structure:
|
||||
bit0= DVD extension is valid
|
||||
*/
|
||||
unsigned char extensions_valid;
|
||||
|
||||
/* ts A70201 : DVD extension.
|
||||
If invalid the members are guaranteed to be 0. */
|
||||
/* Tracks and session numbers are 16 bit. Here are the high bytes. */
|
||||
unsigned char session_msb;
|
||||
unsigned char point_msb;
|
||||
/* pmin, psec, and pframe may be too small if DVD extension is valid */
|
||||
int start_lba;
|
||||
/* min, sec, and frame may be too small if DVD extension is valid */
|
||||
int track_blocks;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -286,6 +330,9 @@ struct burn_source {
|
||||
/** Get the size of the source's data */
|
||||
off_t (*get_size)(struct burn_source *);
|
||||
|
||||
/** Set the size of the source's data */
|
||||
int (*set_size)(struct burn_source *source, off_t size);
|
||||
|
||||
/** Clean up the source specific data */
|
||||
void (*free_data)(struct burn_source *);
|
||||
|
||||
@ -781,6 +828,16 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive,
|
||||
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||
int trackno, int *lba, int *nwa);
|
||||
|
||||
/* ts A70131 */
|
||||
/** Read start lba of the first track in the last complete session.
|
||||
This is the first parameter of mkisofs option -C. The second parameter
|
||||
is nwa as obtained by burn_disc_track_lba_nwa() with trackno 0.
|
||||
@param d The drive to query.
|
||||
@param start_lba returns the start address of that track
|
||||
@return <= 0 : failure, 1 = ok
|
||||
*/
|
||||
int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
|
||||
|
||||
/* ts A61202 */
|
||||
/** Tells the MMC Profile identifier of the loaded media. The drive must be
|
||||
grabbed in order to get a non-zero result.
|
||||
@ -925,6 +982,9 @@ void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
|
||||
/** 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 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().
|
||||
@param o The options for the writing operation.
|
||||
@param disc The struct burn_disc * that described the disc to be created
|
||||
*/
|
||||
@ -980,7 +1040,7 @@ int burn_msf_to_lba(int m, int s, int f);
|
||||
*/
|
||||
void burn_lba_to_msf(int lba, int *m, int *s, int *f);
|
||||
|
||||
/** Create a new disc (for DAO recording)*/
|
||||
/** Create a new disc */
|
||||
struct burn_disc *burn_disc_create(void);
|
||||
|
||||
/** Delete disc and decrease the reference count on all its sessions
|
||||
@ -988,9 +1048,7 @@ struct burn_disc *burn_disc_create(void);
|
||||
*/
|
||||
void burn_disc_free(struct burn_disc *d);
|
||||
|
||||
/** Create a new session (For SAO at once recording, or to be added to a
|
||||
disc for DAO)
|
||||
*/
|
||||
/** Create a new session */
|
||||
struct burn_session *burn_session_create(void);
|
||||
|
||||
/** Free a session (and decrease reference count on all tracks inside)
|
||||
@ -1145,7 +1203,9 @@ void burn_structure_print_disc(struct burn_disc *d);
|
||||
void burn_structure_print_session(struct burn_session *s);
|
||||
void burn_structure_print_track(struct burn_track *t);
|
||||
|
||||
/** Sets the write type for the write_opts struct
|
||||
/** Sets the write type for the write_opts struct.
|
||||
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.
|
||||
@param opts The write opts to change
|
||||
@param write_type The write type to use
|
||||
@param block_type The block type to use
|
||||
@ -1155,6 +1215,22 @@ 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
|
||||
described by opts and disc. To be used after all other setups have been
|
||||
made, i.e. immediately before burn_disc_write().
|
||||
@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 (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[1024], int flag);
|
||||
|
||||
|
||||
/** Supplies toc entries for writing - not normally required for cd mastering
|
||||
@param opts The write opts to change
|
||||
@param count The number of entries
|
||||
@ -1208,11 +1284,11 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
|
||||
|
||||
/* ts A61222 */
|
||||
/** Sets a start address for writing to media and write modes which allow to
|
||||
choose this address at all (DVD+RW, DVD-RAM, DVD-RW only for now). The
|
||||
address is given in bytes. If it is not -1 then a write run will fail if
|
||||
choice of start address is not supported or if the block alignment of the
|
||||
address is not suitable for media and write mode. (Alignment to 32 kB
|
||||
blocks is advised with DVD media.)
|
||||
choose this address at all (DVD+RW, DVD-RAM, formatted DVD-RW only for
|
||||
now). The address is given in bytes. If it is not -1 then a write run
|
||||
will fail if choice of start address is not supported or if the block
|
||||
alignment of the address is not suitable for media and write mode.
|
||||
(Alignment to 32 kB blocks is advised with DVD media.)
|
||||
@param opts The write opts to change
|
||||
@param value The address in bytes (-1 = start at default address)
|
||||
*/
|
||||
@ -1324,6 +1400,105 @@ int burn_drive_get_speedlist(struct burn_drive *d,
|
||||
int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list);
|
||||
|
||||
|
||||
/* ts A70203 */
|
||||
/** The reply structure for burn_disc_get_multi_caps()
|
||||
*/
|
||||
struct burn_multi_caps {
|
||||
|
||||
/* Multi-session capability allows to keep the media appendable after
|
||||
writing a session. It also guarantees that the drive will be able
|
||||
to predict and use the appropriate Next Writeable Address to place
|
||||
the next session on the media without overwriting the existing ones.
|
||||
It does not guarantee that the selected write type is able to do
|
||||
an appending session after the next session. (E.g. CD SAO is capable
|
||||
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 apendable appendable
|
||||
*/
|
||||
int multi_session;
|
||||
|
||||
/* Multi-track capability allows to write more than one track source
|
||||
during a single session. The written tracks can later be found in
|
||||
libburn's TOC model with their start addresses and sizes.
|
||||
1= multiple tracks per session are allowed
|
||||
0= only one track per session allowed
|
||||
*/
|
||||
int multi_track;
|
||||
|
||||
/* Start-address capability allows to set a non-zero address with
|
||||
burn_write_opts_set_start_byte(). Eventually this has to respect
|
||||
.start_alignment and .start_range_low, .start_range_high in this
|
||||
structure.
|
||||
1= non-zero start address is allowed
|
||||
0= only start address 0 is allowed (to depict the drive's own idea
|
||||
about the appropriate write start)
|
||||
*/
|
||||
int start_adr;
|
||||
|
||||
/** The alignment for start addresses.
|
||||
( start_address % start_alignment ) must be 0.
|
||||
*/
|
||||
off_t start_alignment;
|
||||
|
||||
/** The lowest permissible start address.
|
||||
*/
|
||||
off_t start_range_low;
|
||||
|
||||
/** The highest addressable start address.
|
||||
*/
|
||||
off_t start_range_high;
|
||||
|
||||
/** Potential availability of write modes
|
||||
2= available, no size prediction necessary
|
||||
1= available, needs exact size prediction
|
||||
0= not available
|
||||
With CD media (profiles 0x09 and 0x0a) check also the elements
|
||||
*_block_types of the according write mode.
|
||||
*/
|
||||
int might_do_tao;
|
||||
int might_do_sao;
|
||||
int might_do_raw;
|
||||
|
||||
/** Advised write mode.
|
||||
*/
|
||||
enum burn_write_types advised_write_mode;
|
||||
|
||||
/** Write mode as given by parameter wt of burn_disc_get_multi_caps().
|
||||
*/
|
||||
enum burn_write_types selected_write_mode;
|
||||
|
||||
/** Profile number which was current when the reply was generated */
|
||||
int current_profile;
|
||||
|
||||
/** Wether the current profile indicates CD media. 1=yes, 0=no */
|
||||
int current_is_cd_profile;
|
||||
};
|
||||
|
||||
/** Allocates a struct burn_multi_caps (see above) and fills it with values
|
||||
which are appropriate for the drive and the loaded media. The drive
|
||||
must be grabbed for this call. The returned structure has to be disposed
|
||||
via burn_disc_free_multi_caps() when no longer needed.
|
||||
@param d The drive to inquire
|
||||
@param wt With BURN_WRITE_NONE the best capabilities of all write modes
|
||||
get returned. If set to a write mode like BURN_WRITE_SAO the
|
||||
capabilities with that particular mode are returned and the
|
||||
return value is 0 if the desired mode is not possible.
|
||||
@param caps returns the info structure
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@return < 0 : error , 0 : writing seems impossible , 1 : writing possible
|
||||
*/
|
||||
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 o NULL.
|
||||
@param caps the info structure to dispose (note: pointer to pointer)
|
||||
@return 0 : *caps was already NULL, 1 : memory object was disposed
|
||||
*/
|
||||
int burn_disc_free_multi_caps(struct burn_multi_caps **caps);
|
||||
|
||||
|
||||
/** Gets a copy of the toc_entry structure associated with a track
|
||||
@param t Track to get the entry from
|
||||
@param entry Struct for the library to fill out
|
||||
|
@ -1,7 +1,8 @@
|
||||
|
||||
/* libdax_msgs
|
||||
Message handling facility of libdax.
|
||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
Copyright (C) 2006-2007 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL
|
||||
*/
|
||||
|
||||
|
||||
@ -347,8 +348,18 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x00020127 (NOTE,HIGH) = Write start address is ...
|
||||
0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance
|
||||
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
|
||||
|
||||
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
|
||||
0x00020137 (HINT,HIGH) = TAO would be possible
|
||||
0x00020138 (FATAL,HIGH) = Cannot reserve track
|
||||
|
||||
|
||||
libdax_audioxtr:
|
||||
|
705
libburn/mmc.c
705
libburn/mmc.c
@ -44,7 +44,12 @@ extern struct libdax_msgs *libdax_messenger;
|
||||
#define Libburn_support_dvd_raM 1
|
||||
|
||||
|
||||
/* Progress report (with Libburn_support_dvd_plus_rW defined):
|
||||
/* ts A70129 >>> EXPERIMENTAL UNTESTED
|
||||
*/
|
||||
#define Libburn_support_dvd_r_seQ 1
|
||||
|
||||
|
||||
/* Progress report:
|
||||
ts A61219 : It seems to work with a used (i.e. thoroughly formatted) DVD+RW.
|
||||
Error messages of class DEBUG appear because of inability to
|
||||
read TOC or track info. Nevertheless, the written images verify.
|
||||
@ -65,12 +70,27 @@ extern struct libdax_msgs *libdax_messenger;
|
||||
ts A70101 : Formatted DVD-RW media. Success is varying with media, but
|
||||
dvd+rw-format does not do better with the same media.
|
||||
ts A70112 : Support for writing to DVD-RAM.
|
||||
ts A70130 : Burned a first non-multi sequential DVD-RW. Feature 0021h
|
||||
Incremental Recording vanishes after that and media thus gets
|
||||
not recognized as suitable any more.
|
||||
After a run with -multi another disc still offers 0021h .
|
||||
dvd+rw-mediainfo shows two tracks. The second, an afio archive
|
||||
is readable by afio. Third and forth veryfy too. Suddenly
|
||||
dvd+rw-mediainfo sees lba 0 with track 2. But #2 still verifies
|
||||
if one knows its address.
|
||||
ts A70203 : DVD-RW need to get blanked fully. Then feature 0021h persists.
|
||||
Meanwhile Incremental streaming is supported like CD TAO:
|
||||
with unpredicted size, multi-track, multi-session.
|
||||
ts A70205 : Beginning to implement DVD-R[W] DAO : single track and session,
|
||||
size prediction mandatory.
|
||||
|
||||
Todo:
|
||||
Determine first free lba for appending data.
|
||||
Determine first free lba for appending data on overwriteables.
|
||||
*/
|
||||
|
||||
|
||||
static unsigned char MMC_GET_MSINFO[] =
|
||||
{ 0x43, 0, 1, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
|
||||
static unsigned char MMC_GET_DISC_INFO[] =
|
||||
@ -116,6 +136,10 @@ static unsigned char MMC_GET_PERFORMANCE[] =
|
||||
static unsigned char MMC_READ_FORMAT_CAPACITIES[] =
|
||||
{ 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
/* ts A70205 : To describe the layout of a DVD-R[W] DAO session */
|
||||
static unsigned char MMC_RESERVE_TRACK[] =
|
||||
{ 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
|
||||
static int mmc_function_spy_do_tell = 0;
|
||||
|
||||
@ -135,6 +159,25 @@ 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];
|
||||
}
|
||||
|
||||
|
||||
/* ts A70201 */
|
||||
int mmc_int_to_four_char(unsigned char *data, int num)
|
||||
{
|
||||
data[0] = (num >> 24) & 0xff;
|
||||
data[1] = (num >> 16) & 0xff;
|
||||
data[2] = (num >> 8) & 0xff;
|
||||
data[3] = num & 0xff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
|
||||
{
|
||||
struct buffer buf;
|
||||
@ -156,15 +199,48 @@ void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
|
||||
d->issue_command(d, &c);
|
||||
}
|
||||
|
||||
/* ts A61110 : added parameters trackno, lba, nwa. Redefined return value.
|
||||
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
|
||||
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
||||
{
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
unsigned char *data;
|
||||
|
||||
mmc_function_spy("mmc_get_nwa");
|
||||
/* ts A70205 : Announce size of a DVD-R[W] DAO session.
|
||||
@param size The size in bytes to be announced to the drive.
|
||||
It will get rounded up to align to 32 KiB.
|
||||
*/
|
||||
int mmc_reserve_track(struct burn_drive *d, off_t size)
|
||||
{
|
||||
struct command c;
|
||||
int lba;
|
||||
char msg[80];
|
||||
|
||||
mmc_function_spy("mmc_reserve_track");
|
||||
c.retry = 1;
|
||||
c.oplen = sizeof(MMC_RESERVE_TRACK);
|
||||
memcpy(c.opcode, MMC_RESERVE_TRACK, sizeof(MMC_RESERVE_TRACK));
|
||||
|
||||
/* Round to 32 KiB and divide by 2048
|
||||
(by nice binary rounding trick learned from dvd+rw-tools) */
|
||||
lba = ((size + (off_t) 0x7fff) >> 11) & ~0xf;
|
||||
mmc_int_to_four_char(c.opcode+5, lba);
|
||||
|
||||
sprintf(msg, "reserving track of %d blocks", lba);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg, 0, 0);
|
||||
|
||||
c.page = NULL;
|
||||
c.dir = NO_TRANSFER;
|
||||
d->issue_command(d, &c);
|
||||
return !c.error;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70201 :
|
||||
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
|
||||
*/
|
||||
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;
|
||||
c.oplen = sizeof(MMC_TRACK_INFO);
|
||||
memcpy(c.opcode, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO));
|
||||
@ -173,16 +249,76 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
||||
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x12 )
|
||||
/* DVD+RW , DVD-RW restricted overwrite , DVD-RAM */
|
||||
c.opcode[5] = 1;
|
||||
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 */
|
||||
c.opcode[5] = 0xFF;
|
||||
} else
|
||||
c.opcode[5] = trackno;
|
||||
trackno = 0xFF;
|
||||
}
|
||||
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;
|
||||
d->issue_command(d, &c);
|
||||
if (c.error)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61110 : added parameters trackno, lba, nwa. Redefined return value.
|
||||
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
|
||||
/* ts A70201 : outsourced 52h READ TRACK INFO command */
|
||||
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
||||
{
|
||||
struct buffer buf;
|
||||
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;
|
||||
|
||||
#endif /* ! Libburn_get_nwa_standalonE */
|
||||
|
||||
|
||||
*lba = (data[8] << 24) + (data[9] << 16)
|
||||
+ (data[10] << 8) + data[11];
|
||||
*nwa = (data[12] << 24) + (data[13] << 16)
|
||||
@ -254,7 +390,6 @@ void mmc_close(struct burn_drive *d, int session, int 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;
|
||||
@ -391,9 +526,166 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70201 : Set up an entry for mmc_fake_toc() */
|
||||
int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
||||
int track_number,
|
||||
unsigned char *size_data, unsigned char *start_data)
|
||||
{
|
||||
int min, sec, frames, num;
|
||||
|
||||
/* mark DVD extensions as valid */
|
||||
entry->extensions_valid |= 1;
|
||||
|
||||
/* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
|
||||
entry->session = session_number & 0xff;
|
||||
entry->session_msb = (session_number >> 8) & 0xff;
|
||||
entry->adr = 1;
|
||||
entry->control = 4;
|
||||
entry->tno = 0;
|
||||
entry->point = track_number & 0xff;
|
||||
entry->point_msb = (track_number >> 8) & 0xff;
|
||||
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) {
|
||||
min = 255;
|
||||
sec = 255;
|
||||
frames = 255;
|
||||
}
|
||||
entry->min = min;
|
||||
entry->sec = sec;
|
||||
entry->frame = frames;
|
||||
entry->zero = 0;
|
||||
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) {
|
||||
min = 255;
|
||||
sec = 255;
|
||||
frames = 255;
|
||||
}
|
||||
entry->pmin = min;
|
||||
entry->psec = sec;
|
||||
entry->pframe = frames;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70131 : compose a disc TOC structure from d->complete_sessions
|
||||
and 52h READ TRACK INFORMATION */
|
||||
int mmc_fake_toc(struct burn_drive *d)
|
||||
{
|
||||
struct burn_track *track;
|
||||
struct burn_session *session;
|
||||
struct burn_toc_entry *entry;
|
||||
struct buffer buf;
|
||||
int i, session_number, prev_session = -1, ret, lba;
|
||||
unsigned char *tdata, size_data[4], start_data[4];
|
||||
|
||||
if (d->last_track_no <= 0 || d->complete_sessions <= 0 ||
|
||||
d->status == BURN_DISC_BLANK)
|
||||
return 2;
|
||||
d->disc = burn_disc_create();
|
||||
if (d->disc == NULL)
|
||||
return -1;
|
||||
d->toc_entries = d->last_track_no + d->complete_sessions;
|
||||
d->toc_entry = malloc(d->toc_entries * sizeof(struct burn_toc_entry));
|
||||
if (d->toc_entry == NULL)
|
||||
return -1;
|
||||
memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry));
|
||||
for (i = 0; i < d->complete_sessions; i++) {
|
||||
session = burn_session_create();
|
||||
burn_disc_add_session(d->disc, session, BURN_POS_END);
|
||||
burn_session_free(session);
|
||||
}
|
||||
memset(size_data, 0, 4);
|
||||
memset(start_data, 0, 4);
|
||||
|
||||
/* Entry Layout :
|
||||
session 1 track 1 entry 0
|
||||
...
|
||||
session 1 track N entry N-1
|
||||
leadout 1 entry N
|
||||
session 2 track N+1 entry N+1
|
||||
...
|
||||
session 2 track M+1 entry M+1
|
||||
leadout 2 entry M+2
|
||||
session X track K entry (K-1)+(X-1)
|
||||
...
|
||||
session X track i+1 entry i+(X-1)
|
||||
leadout X entry i+X
|
||||
*/
|
||||
for (i = 0; i < d->last_track_no; i++) {
|
||||
ret = mmc_read_track_info(d, i+1, &buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
continue;
|
||||
tdata = buf.data;
|
||||
session_number = (tdata[33] << 8) | tdata[3];
|
||||
if (session_number <= 0)
|
||||
continue;
|
||||
|
||||
if (session_number != prev_session && prev_session > 0) {
|
||||
/* leadout entry previous session */
|
||||
entry = &(d->toc_entry[(i - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
d->disc->session[prev_session - 1]->leadout_entry =
|
||||
entry;
|
||||
}
|
||||
|
||||
if (session_number > d->disc->sessions)
|
||||
continue;
|
||||
|
||||
entry = &(d->toc_entry[i + session_number - 1]);
|
||||
track = burn_track_create();
|
||||
if (track == NULL)
|
||||
return -1;
|
||||
burn_session_add_track(
|
||||
d->disc->session[session_number - 1],
|
||||
track, BURN_POS_END);
|
||||
track->entry = entry;
|
||||
burn_track_free(track);
|
||||
|
||||
memcpy(size_data, tdata + 24, 4);
|
||||
memcpy(start_data, tdata + 8, 4);
|
||||
mmc_fake_toc_entry(entry, session_number, i + 1,
|
||||
size_data, start_data);
|
||||
|
||||
if (prev_session != session_number)
|
||||
d->disc->session[session_number - 1]->firsttrack = i+1;
|
||||
d->disc->session[session_number - 1]->lasttrack = i+1;
|
||||
prev_session = session_number;
|
||||
}
|
||||
if (prev_session > 0 && prev_session <= d->disc->sessions) {
|
||||
/* leadout entry of last session of closed disc */
|
||||
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
d->disc->session[prev_session - 1]->leadout_entry = entry;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void mmc_read_toc(struct burn_drive *d)
|
||||
{
|
||||
/* read full toc, all sessions, in m/s/f form, 4k buffer */
|
||||
/* ts A70201 : or fake a toc from track information */
|
||||
struct burn_track *track;
|
||||
struct burn_session *session;
|
||||
struct buffer buf;
|
||||
@ -403,6 +695,23 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
unsigned char *tdata;
|
||||
|
||||
mmc_function_spy("mmc_read_toc");
|
||||
if (!(d->current_profile == -1 || d->current_is_cd_profile)) {
|
||||
/* ts A70131 : MMC_GET_TOC uses Response Format 2
|
||||
For DVD this fails with 5,24,00 */
|
||||
/* One could try Response Format 0: mmc5r03.pdf 6.26.3.2
|
||||
which does not yield the same result wit the same disc
|
||||
on different drives.
|
||||
*/
|
||||
/* ts A70201 :
|
||||
This uses the session count from 51h READ DISC INFORMATION
|
||||
and the track records from 52h READ TRACK INFORMATION
|
||||
*/
|
||||
mmc_fake_toc(d);
|
||||
|
||||
if (d->status == BURN_DISC_UNREADY)
|
||||
d->status = BURN_DISC_FULL;
|
||||
return;
|
||||
}
|
||||
memcpy(c.opcode, MMC_GET_TOC, sizeof(MMC_GET_TOC));
|
||||
c.retry = 1;
|
||||
c.oplen = sizeof(MMC_GET_TOC);
|
||||
@ -425,11 +734,12 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002010d,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Could not inquire TOC (non-blank DVD media ?)", 0,0);
|
||||
"Could not inquire TOC", 0,0);
|
||||
d->status = BURN_DISC_UNSUITABLE;
|
||||
d->toc_entries = 0;
|
||||
/* Prefering memory leaks over fandangos */
|
||||
d->toc_entry = malloc(sizeof(struct burn_toc_entry));
|
||||
memset(&(d->toc_entry[0]), 0, sizeof(struct burn_toc_entry));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -443,6 +753,8 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
a ssert(((dlen - 2) % 11) == 0);
|
||||
*/
|
||||
d->toc_entry = malloc(d->toc_entries * sizeof(struct burn_toc_entry));
|
||||
for (i = 0; i < d->toc_entries; i++)
|
||||
memset(&(d->toc_entry[i]), 0, sizeof(struct burn_toc_entry));
|
||||
tdata = c.page->data + 4;
|
||||
|
||||
burn_print(12, "TOC:\n");
|
||||
@ -466,8 +778,7 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
burn_print(bpl, " MSF(%d:%d:%d)", tdata[4],tdata[5],tdata[6]);
|
||||
burn_print(bpl, " PMSF(%d:%d:%d %d)",
|
||||
tdata[8], tdata[9], tdata[10],
|
||||
burn_msf_to_lba(tdata[8], tdata[9], tdata[10])
|
||||
);
|
||||
burn_msf_to_lba(tdata[8], tdata[9], tdata[10]));
|
||||
burn_print(bpl, " - control %d, adr %d\n", tdata[1] & 0xF,
|
||||
tdata[1] >> 4);
|
||||
|
||||
@ -519,21 +830,98 @@ void mmc_read_toc(struct burn_drive *d)
|
||||
/* ts A61022 */
|
||||
burn_print(bpl, "-----------------------------------\n");
|
||||
|
||||
if (d->status != BURN_DISC_APPENDABLE)
|
||||
/* ts A70131 : was (d->status != BURN_DISC_BLANK) */
|
||||
if (d->status == BURN_DISC_UNREADY)
|
||||
d->status = BURN_DISC_FULL;
|
||||
toc_find_modes(d);
|
||||
}
|
||||
|
||||
|
||||
/* ts A70131 : This tries to get the start of the last complete session */
|
||||
/* man mkisofs , option -C :
|
||||
The first number is the sector number of the first sector in
|
||||
the last session of the disk that should be appended to.
|
||||
*/
|
||||
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||
{
|
||||
struct buffer buf;
|
||||
struct command c;
|
||||
unsigned char *tdata;
|
||||
int num_sessions, session_no, num_tracks;
|
||||
struct burn_disc *disc;
|
||||
struct burn_session **sessions;
|
||||
struct burn_track **tracks;
|
||||
struct burn_toc_entry toc_entry;
|
||||
|
||||
mmc_function_spy("mmc_read_multi_session_c1");
|
||||
|
||||
/* First try to evaluate the eventually loaded TOC before issueing
|
||||
a MMC command. This search obtains the first track of the last
|
||||
complete session which has a track.
|
||||
*/
|
||||
*trackno = 0;
|
||||
disc = burn_drive_get_disc(d);
|
||||
if (disc == NULL)
|
||||
goto inquire_drive;
|
||||
sessions = burn_disc_get_sessions(disc, &num_sessions);
|
||||
for (session_no = 0; session_no<num_sessions; session_no++) {
|
||||
tracks = burn_session_get_tracks(sessions[session_no],
|
||||
&num_tracks);
|
||||
if (tracks == NULL || num_tracks <= 0)
|
||||
continue;
|
||||
burn_track_get_entry(tracks[0], &toc_entry);
|
||||
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
|
||||
*start = toc_entry.start_lba;
|
||||
*trackno = (toc_entry.point_msb << 8)| toc_entry.point;
|
||||
} else {
|
||||
*start = burn_msf_to_lba(toc_entry.pmin,
|
||||
toc_entry.psec, toc_entry.pframe);
|
||||
*trackno = toc_entry.point;
|
||||
}
|
||||
}
|
||||
burn_disc_free(disc);
|
||||
if(*trackno > 0)
|
||||
return 1;
|
||||
|
||||
inquire_drive:;
|
||||
/* mmc5r03.pdf 6.26.3.3.3 states that with non-CD this would
|
||||
be a useless fake always starting at track 1, lba 0.
|
||||
My drives return useful data, though.
|
||||
MMC-3 states that DVD had no tracks. So maybe this mandatory fake
|
||||
is a forgotten legacy ?
|
||||
*/
|
||||
memcpy(c.opcode, MMC_GET_MSINFO, sizeof(MMC_GET_MSINFO));
|
||||
c.retry = 1;
|
||||
c.oplen = sizeof(MMC_GET_MSINFO);
|
||||
c.page = &buf;
|
||||
c.page->bytes = 0;
|
||||
c.page->sectors = 0;
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
|
||||
if (c.error)
|
||||
return 0;
|
||||
|
||||
tdata = c.page->data + 4;
|
||||
*trackno = tdata[2];
|
||||
*start = mmc_four_char_to_int(tdata + 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void mmc_read_disc_info(struct burn_drive *d)
|
||||
{
|
||||
struct buffer buf;
|
||||
unsigned char *data;
|
||||
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;
|
||||
|
||||
/* ts A61020 */
|
||||
d->start_lba = d->end_lba = -2000000000;
|
||||
d->erasable = 0;
|
||||
d->last_track_no = 1;
|
||||
|
||||
/* ts A61202 */
|
||||
d->toc_entries = 0;
|
||||
@ -541,20 +929,6 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
return;
|
||||
|
||||
mmc_get_configuration(d);
|
||||
if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY)
|
||||
&& ! d->current_is_supported_profile) {
|
||||
if (!d->silent_on_scsi_error) {
|
||||
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);
|
||||
}
|
||||
d->status = BURN_DISC_UNSUITABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
mmc_function_spy("mmc_read_disc_info");
|
||||
memcpy(c.opcode, MMC_GET_DISC_INFO, sizeof(MMC_GET_DISC_INFO));
|
||||
@ -574,10 +948,6 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
data = c.page->data;
|
||||
d->erasable = !!(data[2] & 16);
|
||||
|
||||
/*
|
||||
fprintf(stderr, "libburn_experimental: data[2]= %d 0x%x\n",
|
||||
(unsigned) data[2], (unsigned) data[2]);
|
||||
*/
|
||||
switch (data[2] & 3) {
|
||||
case 0:
|
||||
d->toc_entries = 0;
|
||||
@ -595,11 +965,33 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
case 1:
|
||||
d->status = BURN_DISC_APPENDABLE;
|
||||
case 2:
|
||||
if (d->current_profile == -1 || d->current_is_cd_profile)
|
||||
mmc_read_toc(d);
|
||||
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;
|
||||
}
|
||||
|
||||
if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY)
|
||||
&& ! d->current_is_supported_profile) {
|
||||
if (!d->silent_on_scsi_error) {
|
||||
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);
|
||||
}
|
||||
d->status = BURN_DISC_UNSUITABLE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* >>> ts A61217 : Note for future
|
||||
growisofs performs OPC if (data[0]<<8)|data[1]<=32
|
||||
which indicates no OPC entries are attached to the
|
||||
@ -614,6 +1006,23 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
*/
|
||||
d->bg_format_status = data[7] & 3;
|
||||
|
||||
if (d->status == BURN_DISC_BLANK) {
|
||||
d->last_track_no = 1; /* The "incomplete track" */
|
||||
d->complete_sessions = 0;
|
||||
} else {
|
||||
/* ts A70131 : number of non-empty sessions */
|
||||
d->complete_sessions = (data[9] << 8) | data[4];
|
||||
session_state = (data[2] >> 2) & 3;
|
||||
/* mmc5r03c.pdf 6.22.3.1.3 State of Last Session: 3=complete */
|
||||
if (session_state != 3 && d->complete_sessions >= 1)
|
||||
d->complete_sessions--;
|
||||
|
||||
/* ts A70129 : mmc5r03c.pdf 6.22.3.1.7
|
||||
This includes the "incomplete track" if the disk is
|
||||
appendable. I.e number of complete tracks + 1. */
|
||||
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
|
||||
@ -622,6 +1031,9 @@ void mmc_read_disc_info(struct burn_drive *d)
|
||||
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);
|
||||
}
|
||||
|
||||
void mmc_read_atip(struct burn_drive *d)
|
||||
@ -1067,13 +1479,17 @@ static char *mmc_obtain_profile_name(int profile_number)
|
||||
void mmc_get_configuration(struct burn_drive *d)
|
||||
{
|
||||
struct buffer buf;
|
||||
int len, cp;
|
||||
int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1;
|
||||
unsigned char *descr, *prf, *up_to, *prf_end;
|
||||
struct command c;
|
||||
|
||||
d->current_profile = 0;
|
||||
d->current_profile_text[0] = 0;
|
||||
d->current_is_cd_profile = 0;
|
||||
d->current_is_supported_profile = 0;
|
||||
d->current_has_feat21h = 0;
|
||||
d->current_feat21h_link_size = -1;
|
||||
d->current_feat2fh_byte4 = -1;
|
||||
|
||||
mmc_function_spy("mmc_get_configuration");
|
||||
memcpy(c.opcode, MMC_GET_CONFIGURATION, sizeof(MMC_GET_CONFIGURATION));
|
||||
@ -1088,9 +1504,9 @@ void mmc_get_configuration(struct burn_drive *d)
|
||||
if (c.error)
|
||||
return;
|
||||
len = (c.page->data[0] << 24)
|
||||
+ (c.page->data[1] << 16)
|
||||
+ (c.page->data[2] << 8)
|
||||
+ c.page->data[3];
|
||||
| (c.page->data[1] << 16)
|
||||
| (c.page->data[2] << 8)
|
||||
| c.page->data[3];
|
||||
|
||||
if (len<8)
|
||||
return;
|
||||
@ -1112,11 +1528,134 @@ void mmc_get_configuration(struct burn_drive *d)
|
||||
if (cp == 0x12)
|
||||
d->current_is_supported_profile = 1;
|
||||
#endif
|
||||
#ifdef Libburn_support_dvd_r_seQ
|
||||
if (cp == 0x11 || cp == 0x14)
|
||||
d->current_is_supported_profile = 1;
|
||||
#endif
|
||||
|
||||
/* >>> see mmc5r03c.pdf 5.2
|
||||
Interpret list of profile and feature descriptors.
|
||||
/* Enable this to get loud and repeated reports about the feature set :
|
||||
#define Libburn_print_feature_descriptorS 1
|
||||
*/
|
||||
/* ts A70127 : Interpret list of profile and feature descriptors.
|
||||
see mmc5r03c.pdf 5.2
|
||||
>>> Ouch: What to do if list is larger than buffer size.
|
||||
Specs state that the call has to be repeated.
|
||||
*/
|
||||
up_to = c.page->data + (len < BUFFER_SIZE ? len : BUFFER_SIZE);
|
||||
|
||||
#ifdef Libburn_print_feature_descriptorS
|
||||
fprintf(stderr,
|
||||
"-----------------------------------------------------------------\n");
|
||||
fprintf(stderr,
|
||||
"LIBBURN_EXPERIMENTAL : feature list length = %d , shown = %d\n",
|
||||
len, up_to - c.page->data);
|
||||
#endif /* Libburn_print_feature_descriptorS */
|
||||
|
||||
for (descr = c.page->data + 8; descr + 3 < up_to; descr += descr_len) {
|
||||
descr_len = 4 + descr[3];
|
||||
feature_code = (descr[0] << 8) | descr[1];
|
||||
if (only_current && !(descr[2] & 1))
|
||||
continue;
|
||||
|
||||
#ifdef Libburn_print_feature_descriptorS
|
||||
fprintf(stderr,
|
||||
"LIBBURN_EXPERIMENTAL : %s feature %4.4Xh\n",
|
||||
descr[2] & 1 ? "+" : "-",
|
||||
feature_code);
|
||||
#endif /* Libburn_print_feature_descriptorS */
|
||||
|
||||
if (feature_code == 0x0) {
|
||||
prf_end = descr + 4 + descr[3];
|
||||
for (prf = descr + 4; prf + 2 < prf_end; prf += 4) {
|
||||
if (only_current && !(prf[2] & 1))
|
||||
continue;
|
||||
prf_number = (prf[0] << 8) | prf[1];
|
||||
|
||||
#ifdef Libburn_print_feature_descriptorS
|
||||
fprintf(stderr,
|
||||
"LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n",
|
||||
prf[2] & 1 ? "+" : "-",
|
||||
prf_number,
|
||||
mmc_obtain_profile_name(prf_number));
|
||||
#endif /* Libburn_print_feature_descriptorS */
|
||||
|
||||
}
|
||||
|
||||
} else if (feature_code == 0x21) {
|
||||
int i;
|
||||
|
||||
d->current_has_feat21h = (descr[2] & 1);
|
||||
for (i = 0; i < descr[7]; i++) {
|
||||
if (i == 0 || descr[8 + i] == 16)
|
||||
d->current_feat21h_link_size =
|
||||
descr[8 + i];
|
||||
|
||||
#ifdef Libburn_print_feature_descriptorS
|
||||
fprintf(stderr,
|
||||
"LIBBURN_EXPERIMENTAL : + Link Size = %d\n",
|
||||
descr[8 + i]);
|
||||
#endif /* Libburn_print_feature_descriptorS */
|
||||
|
||||
}
|
||||
|
||||
} else if (feature_code == 0x2F) {
|
||||
if (descr[2] & 1)
|
||||
d->current_feat2fh_byte4 = descr[4];
|
||||
|
||||
#ifdef Libburn_print_feature_descriptorS
|
||||
fprintf(stderr, "LIBBURN_EXPERIMENTAL : BUF = %d , Test Write = %d , DVD-RW = %d\n",
|
||||
!!(descr[4] & 64), !!(descr[4] & 4),
|
||||
!!(descr[4] & 2));
|
||||
#endif /* Libburn_print_feature_descriptorS */
|
||||
|
||||
#ifdef Libburn_print_feature_descriptorS
|
||||
} else if (feature_code == 0x01) {
|
||||
int pys_if_std = 0;
|
||||
char *phys_name = "";
|
||||
|
||||
pys_if_std = (descr[4] << 24) | (descr[5] << 16) |
|
||||
(descr[6] << 8) | descr[9];
|
||||
if (pys_if_std == 1)
|
||||
phys_name = "SCSI Family";
|
||||
else if(pys_if_std == 2)
|
||||
phys_name = "ATAPI";
|
||||
else if(pys_if_std == 3 || pys_if_std == 4 ||
|
||||
pys_if_std == 6)
|
||||
phys_name = "IEEE 1394 FireWire";
|
||||
else if(pys_if_std == 7)
|
||||
phys_name = "Serial ATAPI";
|
||||
else if(pys_if_std == 7)
|
||||
phys_name = "USB";
|
||||
|
||||
fprintf(stderr,
|
||||
"LIBBURN_EXPERIMENTAL : Phys. Interface Standard %Xh \"%s\"\n",
|
||||
pys_if_std, phys_name);
|
||||
|
||||
} else if (feature_code == 0x107) {
|
||||
|
||||
fprintf(stderr, "LIBBURN_EXPERIMENTAL : CD SPEED = %d , page 2Ah = %d , SET STREAMING = %d\n",
|
||||
!!(descr[4] & 8), !!(descr[4] & 4),
|
||||
!!(descr[4] & 2));
|
||||
|
||||
} else if (feature_code == 0x108 || feature_code == 0x10c) {
|
||||
int i, c_limit;
|
||||
|
||||
fprintf(stderr, "LIBBURN_EXPERIMENTAL : %s = ",
|
||||
feature_code == 0x108 ?
|
||||
"Drive Serial Number" : "Drive Firmware Date");
|
||||
c_limit = descr[3] - 2 * (feature_code == 0x10c);
|
||||
for (i = 0; i < c_limit; i++)
|
||||
if (descr[4 + i] < 0x20 || descr[4 + i] > 0x7e
|
||||
|| descr[4 + i] == '\\')
|
||||
fprintf(stderr,"\\%2.2X",descr[4 + i]);
|
||||
else
|
||||
fprintf(stderr, "%c", descr[4 + i]);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
#endif /* Libburn_print_feature_descriptorS */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1210,6 +1749,8 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
|
||||
score = 100 * sign;
|
||||
} else if(type == 0x15) { /* DVD-RW Quick */
|
||||
score = 50 * sign;
|
||||
} else if(type == 0x26) { /* DVD+RW */
|
||||
score = 1 * sign;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@ -1243,6 +1784,11 @@ void mmc_sync_cache(struct burn_drive *d)
|
||||
c.oplen = sizeof(MMC_SYNC_CACHE);
|
||||
c.page = NULL;
|
||||
c.dir = NO_TRANSFER;
|
||||
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
"syncing cache", 0, 0);
|
||||
|
||||
d->issue_command(d, &c);
|
||||
}
|
||||
|
||||
@ -1412,7 +1958,7 @@ selected_not_suitable:;
|
||||
if (d->format_descr_type == 2) /* formatted */
|
||||
return 1;
|
||||
if (d->format_descr_type == 3){/*intermediate*/
|
||||
d->dvd_minus_rw_incomplete = 1;
|
||||
d->needs_close_session = 1;
|
||||
return 1;
|
||||
}
|
||||
/* does trying make sense at all ? */
|
||||
@ -1510,7 +2056,7 @@ unsuitable_media:;
|
||||
}
|
||||
return 0;
|
||||
} else if ((!c.error) && (format_type == 0x13 || format_type == 0x15))
|
||||
d->dvd_minus_rw_incomplete = 1;
|
||||
d->needs_close_session = 1;
|
||||
if (return_immediately)
|
||||
return 1;
|
||||
usleep(1000000); /* there seems to be a little race condition */
|
||||
@ -1651,8 +2197,10 @@ int mmc_setup_drive(struct burn_drive *d)
|
||||
d->perform_opc = mmc_perform_opc;
|
||||
d->set_speed = mmc_set_speed;
|
||||
d->send_cue_sheet = mmc_send_cue_sheet;
|
||||
d->reserve_track = mmc_reserve_track;
|
||||
d->sync_cache = mmc_sync_cache;
|
||||
d->get_nwa = mmc_get_nwa;
|
||||
d->read_multi_session_c1 = mmc_read_multi_session_c1;
|
||||
d->close_disc = mmc_close_disc;
|
||||
d->close_session = mmc_close_session;
|
||||
d->close_track_session = mmc_close;
|
||||
@ -1664,15 +2212,20 @@ int mmc_setup_drive(struct burn_drive *d)
|
||||
d->start_lba = -2000000000;
|
||||
d->end_lba = -2000000000;
|
||||
|
||||
/* ts A61201 */
|
||||
/* ts A61201 - A70128 */
|
||||
d->erasable = 0;
|
||||
d->current_profile = -1;
|
||||
d->current_profile_text[0] = 0;
|
||||
d->current_is_cd_profile = 0;
|
||||
d->current_is_supported_profile = 0;
|
||||
d->dvd_minus_rw_incomplete = 0;
|
||||
d->current_has_feat21h = 0;
|
||||
d->current_feat21h_link_size = -1;
|
||||
d->current_feat2fh_byte4 = -1;
|
||||
d->needs_close_session = 0;
|
||||
d->bg_format_status = -1;
|
||||
d->num_format_descr = 0;
|
||||
d->complete_sessions = 0;
|
||||
d->last_track_no = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1690,8 +2243,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
pd[0] = 5;
|
||||
pd[1] = d->mdata->write_page_length;
|
||||
|
||||
/* ts A61229 */
|
||||
if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */
|
||||
if (d->current_profile == 0x13) {
|
||||
/* A61229 : DVD-RW restricted overwrite */
|
||||
/* learned from transport.hxx : page05_setup()
|
||||
and mmc3r10g.pdf table 347 */
|
||||
/* BUFE (burnproof), no LS_V (i.e. default Link Size, i hope),
|
||||
@ -1703,8 +2256,58 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||
pd[4] = 8;
|
||||
/* Link size dummy */
|
||||
pd[5] = 0;
|
||||
|
||||
} else if ((d->current_profile == 0x14 || d->current_profile == 0x11)
|
||||
&& o->write_type == BURN_WRITE_SAO) {
|
||||
/* 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. */
|
||||
|
||||
/* BUFE , LS_V = 0, Test Write, Write Type = 2 SAO (DAO) */
|
||||
pd[2] = ((!!o->underrun_proof) << 6)
|
||||
| ((!!o->simulate) << 4)
|
||||
| 2;
|
||||
/* No multi-session , FP = 0 , Track Mode = 5 */
|
||||
pd[3] = 5;
|
||||
/* Data Block Type = 8 */
|
||||
pd[4] = 8;
|
||||
|
||||
} 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 */
|
||||
|
||||
/* BUFE , LS_V = 1, Test Write,
|
||||
Write Type = 0 Packet/Incremental */
|
||||
pd[2] = ((!!o->underrun_proof) << 6)
|
||||
| (1 << 5)
|
||||
| ((!!o->simulate) << 4);
|
||||
/* Multi-session , FP = 1 , Track Mode = 5 */
|
||||
pd[3] = ((3 * !!o->multi) << 6) | (1 << 5) | 5;
|
||||
/* Data Block Type = 8 */
|
||||
pd[4] = 8;
|
||||
/* Link Size */
|
||||
if (d->current_feat21h_link_size >= 0)
|
||||
pd[5] = d->current_feat21h_link_size;
|
||||
else
|
||||
pd[5] = 16;
|
||||
if (d->current_feat21h_link_size != 16) {
|
||||
char msg[80];
|
||||
|
||||
sprintf(msg,
|
||||
"Feature 21h Link Size = %d (expected 16)\n",
|
||||
d->current_feat21h_link_size);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg, 0, 0);
|
||||
}
|
||||
/* Packet Size */
|
||||
pd[13] = 16;
|
||||
|
||||
} else {
|
||||
/* Traditional setup for CD */
|
||||
|
||||
pd[2] = ((!!o->underrun_proof) << 6)
|
||||
| ((!!o->simulate) << 4)
|
||||
| (o->write_type & 0x0f);
|
||||
|
@ -21,6 +21,10 @@ struct burn_source *burn_null_source_new(void)
|
||||
src->read_sub = NULL;
|
||||
|
||||
src->get_size = 0;
|
||||
|
||||
/* ts A70126 */
|
||||
src->set_size = NULL;
|
||||
|
||||
src->free_data = NULL;
|
||||
src->data = NULL;
|
||||
return src;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "libburn.h"
|
||||
#include "options.h"
|
||||
#include "drive.h"
|
||||
#include "transport.h"
|
||||
|
||||
/* ts A61007 */
|
||||
@ -170,6 +171,96 @@ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
|
||||
}
|
||||
|
||||
|
||||
/* ts A70207 API */
|
||||
enum burn_write_types burn_write_opts_auto_write_type(
|
||||
struct burn_write_opts *opts, struct burn_disc *disc,
|
||||
char reasons[1024], int flag)
|
||||
{
|
||||
struct burn_multi_caps *caps = NULL;
|
||||
struct burn_drive *d = opts->drive;
|
||||
struct burn_disc_mode_demands demands;
|
||||
int ret;
|
||||
char *reason_pt;
|
||||
|
||||
reasons[0] = 0;
|
||||
ret = burn_disc_get_write_mode_demands(disc, &demands, 0);
|
||||
if (ret <= 0) {
|
||||
strcat(reasons, "cannot recognize job demands, ");
|
||||
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, ");
|
||||
return BURN_WRITE_NONE;
|
||||
}
|
||||
|
||||
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, ");
|
||||
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:;
|
||||
burn_disc_free_multi_caps(&caps);
|
||||
strcat(reasons, "\n");
|
||||
reason_pt = reasons + strlen(reasons);
|
||||
strcat(reasons, "TAO: ");
|
||||
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, ");
|
||||
no_write_mode:;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw)
|
||||
{
|
||||
opts->raw = raw;
|
||||
|
@ -7,10 +7,6 @@
|
||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||
*/
|
||||
|
||||
#ifndef BURN_OS_H_INCLUDED
|
||||
#define BURN_OS_H_INCLUDED 1
|
||||
|
||||
|
||||
/** List of all signals which shall be caught by signal handlers and trigger
|
||||
a graceful abort of libburn. (See man 7 signal.)
|
||||
*/
|
||||
@ -52,14 +48,9 @@ SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
|
||||
which are now local in sg_enumerate() . So that sg_give_next_adr()
|
||||
can work in BSD and sg_enumerate() can use it.
|
||||
*/
|
||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||
struct burn_drive_enumeration_state { \
|
||||
union ccb ccb; \
|
||||
int bufsize, fd; \
|
||||
unsigned int i; \
|
||||
int skip_device; \
|
||||
}; \
|
||||
typedef struct burn_drive_enumeration_state burn_drive_enumerator_t;
|
||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
||||
struct burn_drive_enumeration_state; \
|
||||
typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
|
||||
|
||||
|
||||
/* The list of operating system dependent elements in struct burn_drive.
|
||||
@ -68,6 +59,3 @@ typedef struct burn_drive_enumeration_state burn_drive_enumerator_t;
|
||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||
struct cam_device* cam;
|
||||
|
||||
|
||||
#endif /* ! BURN_OS_H_INCLUDED */
|
||||
|
||||
|
@ -1,19 +1,5 @@
|
||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
|
||||
|
||||
/* Revives old enumerate_common(). New version delegates much work
|
||||
to methods in drive, mmc, spc, and sbc .
|
||||
*/
|
||||
#define Scsi_freebsd_make_own_enumeratE 1
|
||||
|
||||
|
||||
/* Revives old scsi_enumerate_drives(). New version delegates most work to
|
||||
sg_give_next_adr().
|
||||
*/
|
||||
#define Scsi_freebsd_old_scsi_enumeratE 1
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
@ -45,6 +31,13 @@
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
||||
struct burn_drive_enumeration_state {
|
||||
int fd;
|
||||
union ccb ccb;
|
||||
unsigned int i;
|
||||
int skip_device;
|
||||
};
|
||||
|
||||
static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||
int channel_no, int target_no, int lun_no);
|
||||
|
||||
@ -57,33 +50,20 @@ int burn_drive_is_banned(char *device_address);
|
||||
int mmc_function_spy(char * text);
|
||||
|
||||
|
||||
#ifdef Scsi_freebsd_old_scsi_enumeratE
|
||||
|
||||
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||
char adr[], int adr_size, int initialize)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int sg_is_enumerable_adr(char* adr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||
int *target_no, int *lun_no)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* Scsi_freebsd_old_scsi_enumeratE */
|
||||
|
||||
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
||||
sg_give_next_adr() */
|
||||
/* Some helper functions for scsi_give_next_adr() */
|
||||
|
||||
static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||
static int sg_init_enumerator(burn_drive_enumerator_t *idx_)
|
||||
{
|
||||
struct burn_drive_enumeration_state *idx;
|
||||
int bufsize;
|
||||
|
||||
idx = malloc(sizeof(*idx));
|
||||
if (idx == NULL) {
|
||||
warnx("can't malloc memory for enumerator");
|
||||
return -1;
|
||||
}
|
||||
idx->skip_device = 0;
|
||||
|
||||
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||
@ -98,12 +78,13 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||
idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
|
||||
|
||||
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||
idx->bufsize = sizeof(struct dev_match_result) * 100;
|
||||
idx->ccb.cdm.match_buf_len = idx->bufsize;
|
||||
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
||||
bufsize = sizeof(struct dev_match_result) * 100;
|
||||
idx->ccb.cdm.match_buf_len = bufsize;
|
||||
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
|
||||
if (idx->ccb.cdm.matches == NULL) {
|
||||
warnx("can't malloc memory for matches");
|
||||
close(idx->fd);
|
||||
free(idx);
|
||||
return -1;
|
||||
}
|
||||
idx->ccb.cdm.num_matches = 0;
|
||||
@ -116,12 +97,28 @@ static int sg_init_enumerator(burn_drive_enumerator_t *idx)
|
||||
idx->ccb.cdm.num_patterns = 0;
|
||||
idx->ccb.cdm.pattern_buf_len = 0;
|
||||
|
||||
*idx_ = idx;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
|
||||
static void sg_destroy_enumerator(burn_drive_enumerator_t *idx_)
|
||||
{
|
||||
struct burn_drive_enumeration_state *idx = *idx_;
|
||||
|
||||
if(idx->fd != -1)
|
||||
close(idx->fd);
|
||||
|
||||
free(idx->ccb.cdm.matches);
|
||||
free(idx);
|
||||
|
||||
*idx_ = NULL;
|
||||
}
|
||||
|
||||
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
|
||||
{
|
||||
struct burn_drive_enumeration_state *idx = *idx_;
|
||||
|
||||
/*
|
||||
* We do the ioctl multiple times if necessary, in case there are
|
||||
* more than 100 nodes in the EDT.
|
||||
@ -152,95 +149,94 @@ static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
|
||||
@return 1 = reply is a valid address , 0 = no further address available
|
||||
-1 = severe error (e.g. adr_size too small)
|
||||
*/
|
||||
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||
int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
||||
char adr[], int adr_size, int initialize)
|
||||
{
|
||||
struct burn_drive_enumeration_state *idx;
|
||||
int ret;
|
||||
|
||||
if (initialize == 1) {
|
||||
ret = sg_init_enumerator(idx);
|
||||
ret = sg_init_enumerator(idx_);
|
||||
if (ret<=0)
|
||||
return ret;
|
||||
} else if (initialize == -1) {
|
||||
if(idx->fd != -1)
|
||||
close(idx->fd);
|
||||
idx->fd = -1;
|
||||
sg_destroy_enumerator(idx_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx = *idx_;
|
||||
|
||||
try_item:; /* This spaghetti loop keeps the number of tabs small */
|
||||
do {
|
||||
if (idx->i >= idx->ccb.cdm.num_matches) {
|
||||
ret = sg_next_enumeration_buffer(idx_);
|
||||
if (ret<=0)
|
||||
return -1;
|
||||
idx->i = 0;
|
||||
} else
|
||||
(idx->i)++;
|
||||
|
||||
/* Loop content from old scsi_enumerate_drives() */
|
||||
while (idx->i < idx->ccb.cdm.num_matches) {
|
||||
switch (idx->ccb.cdm.matches[idx->i].type) {
|
||||
case DEV_MATCH_BUS:
|
||||
break;
|
||||
case DEV_MATCH_DEVICE: {
|
||||
struct device_match_result* result;
|
||||
|
||||
while (idx->i >= idx->ccb.cdm.num_matches) {
|
||||
ret = sg_next_enumeration_buffer(idx);
|
||||
if (ret<=0)
|
||||
return -1;
|
||||
if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP)
|
||||
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) )
|
||||
return 0;
|
||||
idx->i = 0;
|
||||
}
|
||||
result = &(idx->ccb.cdm.matches[idx->i].result.device_result);
|
||||
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||
idx->skip_device = 1;
|
||||
else
|
||||
idx->skip_device = 0;
|
||||
break;
|
||||
}
|
||||
case DEV_MATCH_PERIPH: {
|
||||
struct periph_match_result* result;
|
||||
|
||||
switch (idx->ccb.cdm.matches[idx->i].type) {
|
||||
case DEV_MATCH_BUS:
|
||||
break;
|
||||
case DEV_MATCH_DEVICE: {
|
||||
struct device_match_result* result;
|
||||
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
||||
if (idx->skip_device ||
|
||||
strcmp(result->periph_name, "pass") == 0)
|
||||
break;
|
||||
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
||||
result->periph_name, result->unit_number);
|
||||
if(ret >= adr_size)
|
||||
return -1;
|
||||
|
||||
result = &(idx->ccb.cdm.matches[i].result.device_result);
|
||||
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||
idx->skip_device = 1;
|
||||
else
|
||||
idx->skip_device = 0;
|
||||
break;
|
||||
}
|
||||
case DEV_MATCH_PERIPH: {
|
||||
struct periph_match_result* result;
|
||||
char buf[64];
|
||||
/* Found next enumerable address */
|
||||
return 1;
|
||||
|
||||
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||
if (idx->skip_device ||
|
||||
strcmp(result->periph_name, "pass") == 0)
|
||||
break;
|
||||
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||
result->periph_name, result->unit_number);
|
||||
if(adr_size <= strlen(buf)
|
||||
return -1;
|
||||
strcpy(adr, buf);
|
||||
}
|
||||
default:
|
||||
/* printf(stderr, "unknown match type\n"); */
|
||||
break;
|
||||
}
|
||||
(idx->i)++;
|
||||
}
|
||||
} while ((idx->ccb.ccb_h.status == CAM_REQ_CMP)
|
||||
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE));
|
||||
|
||||
/* Found next enumerable address */
|
||||
return 1;
|
||||
|
||||
}
|
||||
default:
|
||||
/* printf(stderr, "unknown match type\n"); */
|
||||
break;
|
||||
}
|
||||
|
||||
(idx->i)++;
|
||||
goto try_item; /* Regular function exit is return 1 above */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int sg_is_enumerable_adr(char* adr)
|
||||
{
|
||||
burn_drive_enumerator_t idx;
|
||||
int initialize = 1;
|
||||
int ret;
|
||||
char buf[64];
|
||||
|
||||
ret = sg_init_enumerator(&idx);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
while(1) {
|
||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||
initialize = 0;
|
||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
break;
|
||||
if (strcmp(adr, buf) == 0) {
|
||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||
sg_destroy_enumerator(&idx);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||
sg_destroy_enumerator(&idx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -252,32 +248,32 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||
int *target_no, int *lun_no)
|
||||
{
|
||||
burn_drive_enumerator_t idx;
|
||||
int initialize = 1;
|
||||
int ret;
|
||||
char buf[64];
|
||||
struct periph_match_result* result;
|
||||
|
||||
ret = sg_init_enumerator(&idx);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
while(1) {
|
||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||
initialize = 0;
|
||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
if (strcmp(adr, buf) != 0)
|
||||
continue;
|
||||
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||
*bus_no = result->path_id;
|
||||
*host_no = result->path_id;
|
||||
*channel_no = 0;
|
||||
*target_no = result->target_id
|
||||
*lun_no = result->target_lun;
|
||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||
return 1;
|
||||
break;
|
||||
if (strcmp(path, buf) == 0) {
|
||||
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
||||
*bus_no = result->path_id;
|
||||
*host_no = result->path_id;
|
||||
*channel_no = 0;
|
||||
*target_no = result->target_id;
|
||||
*lun_no = result->target_lun;
|
||||
sg_destroy_enumerator(&idx);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||
sg_destroy_enumerator(&idx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* ! Scsi_freebsd_old_scsi_enumeratE */
|
||||
|
||||
|
||||
int sg_close_drive(struct burn_drive * d)
|
||||
{
|
||||
@ -295,125 +291,28 @@ int sg_drive_is_open(struct burn_drive * d)
|
||||
|
||||
int scsi_enumerate_drives(void)
|
||||
{
|
||||
|
||||
#ifdef Scsi_freebsd_old_scsi_enumeratE
|
||||
|
||||
union ccb ccb;
|
||||
int bufsize, fd;
|
||||
unsigned int i;
|
||||
int skip_device = 0;
|
||||
|
||||
if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
|
||||
warn("couldn't open %s", XPT_DEVICE);
|
||||
return;
|
||||
}
|
||||
|
||||
bzero(&ccb, sizeof(union ccb));
|
||||
|
||||
ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
|
||||
ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
|
||||
ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
|
||||
|
||||
ccb.ccb_h.func_code = XPT_DEV_MATCH;
|
||||
bufsize = sizeof(struct dev_match_result) * 100;
|
||||
ccb.cdm.match_buf_len = bufsize;
|
||||
ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
|
||||
if (ccb.cdm.matches == NULL) {
|
||||
warnx("can't malloc memory for matches");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
ccb.cdm.num_matches = 0;
|
||||
|
||||
/*
|
||||
* We fetch all nodes, since we display most of them in the default
|
||||
* case, and all in the verbose case.
|
||||
*/
|
||||
ccb.cdm.num_patterns = 0;
|
||||
ccb.cdm.pattern_buf_len = 0;
|
||||
|
||||
/*
|
||||
* We do the ioctl multiple times if necessary, in case there are
|
||||
* more than 100 nodes in the EDT.
|
||||
*/
|
||||
do {
|
||||
if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
|
||||
warn("error sending CAMIOCOMMAND ioctl");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ccb.ccb_h.status != CAM_REQ_CMP)
|
||||
|| ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
|
||||
&& (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
|
||||
warnx("got CAM error %#x, CDM error %d\n",
|
||||
ccb.ccb_h.status, ccb.cdm.status);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < ccb.cdm.num_matches; i++) {
|
||||
switch (ccb.cdm.matches[i].type) {
|
||||
case DEV_MATCH_BUS:
|
||||
break;
|
||||
case DEV_MATCH_DEVICE: {
|
||||
struct device_match_result* result;
|
||||
|
||||
result = &ccb.cdm.matches[i].result.device_result;
|
||||
|
||||
if (result->flags & DEV_RESULT_UNCONFIGURED)
|
||||
skip_device = 1;
|
||||
else
|
||||
skip_device = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
case DEV_MATCH_PERIPH: {
|
||||
struct periph_match_result* result;
|
||||
char buf[64];
|
||||
|
||||
result = &ccb.cdm.matches[i].result.periph_result;
|
||||
if (skip_device || strcmp(result->periph_name, "pass") == 0)
|
||||
break;
|
||||
snprintf(buf, sizeof (buf), "/dev/%s%d", result->periph_name, result->unit_number);
|
||||
/* ts A51221 */
|
||||
if (burn_drive_is_banned(buf))
|
||||
break;
|
||||
|
||||
enumerate_common(buf, result->path_id, result->path_id, 0,
|
||||
result->target_id, result->target_lun);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stdout, "unknown match type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while ((ccb.ccb_h.status == CAM_REQ_CMP)
|
||||
&& (ccb.cdm.status == CAM_DEV_MATCH_MORE));
|
||||
|
||||
close(fd);
|
||||
|
||||
#else /* Scsi_freebsd_old_scsi_enumeratE */
|
||||
|
||||
burn_drive_enumerator_t idx;
|
||||
int initialize = 1;
|
||||
int ret;
|
||||
char buf[64];
|
||||
struct periph_match_result* result;
|
||||
|
||||
ret = sg_init_enumerator(&idx);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
while(1) {
|
||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
||||
initialize = 0;
|
||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
break;
|
||||
if (burn_drive_is_banned(buf))
|
||||
continue;
|
||||
enumerate_common(buf, idx.result->path_id, idx.result->path_id,
|
||||
0, idx.result->target_id,
|
||||
idx.result->target_lun);
|
||||
continue;
|
||||
result = &idx->ccb.cdm.matches[idx->i].result.periph_result;
|
||||
enumerate_common(buf, result->path_id, result->path_id,
|
||||
0, result->target_id,
|
||||
result->target_lun);
|
||||
}
|
||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||
|
||||
#endif /* ! Scsi_freebsd_old_scsi_enumeratE */
|
||||
sg_destroy_enumerator(&idx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -551,7 +450,10 @@ int sg_grab(struct burn_drive *d)
|
||||
|
||||
mmc_function_spy("sg_grab");
|
||||
|
||||
assert(d->cam == NULL);
|
||||
if (burn_drive_is_open(d)) {
|
||||
d->released = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
cam = cam_open_device(d->devname, O_RDWR);
|
||||
if (cam == NULL) {
|
||||
@ -591,6 +493,7 @@ int sg_release(struct burn_drive *d)
|
||||
mmc_function_spy("sg_release ----------- closing.");
|
||||
|
||||
sg_close_drive(d);
|
||||
d->released = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,8 @@ void burn_track_clear_isrc(struct burn_track *t)
|
||||
|
||||
int burn_track_get_sectors(struct burn_track *t)
|
||||
{
|
||||
int size;
|
||||
/* ts A70125 : was int */
|
||||
off_t size;
|
||||
int sectors, seclen;
|
||||
|
||||
seclen = burn_sector_length(t->mode);
|
||||
@ -329,6 +330,22 @@ int burn_track_get_sectors(struct burn_track *t)
|
||||
return sectors;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70125 */
|
||||
int burn_track_set_sectors(struct burn_track *t, int sectors)
|
||||
{
|
||||
off_t size, seclen;
|
||||
int ret;
|
||||
|
||||
seclen = burn_sector_length(t->mode);
|
||||
size = seclen * (off_t) sectors - (off_t) t->offset - (off_t) t->tail;
|
||||
if (size < 0)
|
||||
return 0;
|
||||
ret = t->source->set_size(t->source, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61031 */
|
||||
int burn_track_is_open_ended(struct burn_track *t)
|
||||
{
|
||||
|
@ -88,5 +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 */
|
||||
int burn_track_set_sectors(struct burn_track *t, int sectors);
|
||||
|
||||
|
||||
#endif /* BURN__STRUCTURE_H */
|
||||
|
@ -152,11 +152,29 @@ struct burn_drive
|
||||
int current_is_cd_profile;
|
||||
int current_is_supported_profile;
|
||||
|
||||
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
||||
Quite internal. Regard as opaque :)
|
||||
*/
|
||||
/* 1 = incremental recording available, 0 = not available */
|
||||
int current_has_feat21h;
|
||||
|
||||
/* Link Size item number 0 from feature 0021h descriptor */
|
||||
int current_feat21h_link_size;
|
||||
|
||||
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
|
||||
bit1= DVD-RW supported
|
||||
bit2= Test Write available
|
||||
bit3= DVD-R DL supported
|
||||
bit6= Buffer Under-run Free recording available (page 05h BUFE)
|
||||
Value -1 indicates that no 002Fh was current in the features list.
|
||||
*/
|
||||
int current_feat2fh_byte4;
|
||||
|
||||
/* ts A70114 : wether a DVD-RW media holds an incomplete session
|
||||
(which could need closing after write) */
|
||||
int dvd_minus_rw_incomplete;
|
||||
int needs_close_session;
|
||||
|
||||
/* ts A61218 from 46h GET CONFIGURATION */
|
||||
/* ts A61218 from 51h READ DISC INFORMATION */
|
||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||
|
||||
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
|
||||
@ -181,6 +199,15 @@ struct burn_drive
|
||||
int rlba; /* relative lba in section */
|
||||
int start_lba;
|
||||
int end_lba;
|
||||
|
||||
|
||||
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
||||
int complete_sessions;
|
||||
/* ts A70129 :
|
||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||
int last_track_no;
|
||||
|
||||
|
||||
int toc_temp;
|
||||
struct burn_disc *disc; /* disc structure */
|
||||
int block_types[4];
|
||||
@ -224,10 +251,19 @@ struct burn_drive
|
||||
void (*send_write_parameters) (struct burn_drive *,
|
||||
const struct burn_write_opts *);
|
||||
void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
|
||||
|
||||
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
|
||||
int (*reserve_track) (struct burn_drive *d, off_t size);
|
||||
|
||||
void (*sync_cache) (struct burn_drive *);
|
||||
int (*get_erase_progress) (struct burn_drive *);
|
||||
int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa);
|
||||
|
||||
/* ts A70131 : obtain (possibly fake) TOC number and start lba of
|
||||
first track in last complete session */
|
||||
int (*read_multi_session_c1)(struct burn_drive *d,
|
||||
int *trackno, int *start);
|
||||
|
||||
/* ts A61009 : removed d in favor of o->drive */
|
||||
/* void (*close_disc) (struct burn_drive * d,
|
||||
struct burn_write_opts * o);
|
||||
|
290
libburn/write.c
290
libburn/write.c
@ -195,7 +195,10 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
/* MMC-1 mentions track number 0xFF for "the incomplete track",
|
||||
MMC-3 does not. I tried both. 0xFF was in effect when other
|
||||
bugs finally gave up and made way for readable tracks. */
|
||||
d->close_track_session(o->drive, 0, 0xff); /* tnum+1); */
|
||||
/* ts A70129
|
||||
Probably the right value for appendables is d->last_track_no
|
||||
*/
|
||||
d->close_track_session(o->drive, 0, 0xff);
|
||||
|
||||
/* ts A61102 */
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
@ -298,7 +301,7 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
||||
struct burn_session *session,
|
||||
int nwa)
|
||||
{
|
||||
int i, m, s, f, form, pform, runtime = -150, ret;
|
||||
int i, m, s, f, form, pform, runtime = -150, ret, track_length;
|
||||
unsigned char ctladr;
|
||||
struct burn_drive *d;
|
||||
struct burn_toc_entry *e;
|
||||
@ -386,10 +389,22 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
||||
e[2].control = e[1].control;
|
||||
e[2].adr = 1;
|
||||
|
||||
/* ts A70121 : The pause before the first track is not a Pre-gap.
|
||||
To count it as part 2 of a Pre-gap is a dirty hack. It also seems
|
||||
to have caused confusion in dealing with part 1 of an eventual
|
||||
real Pre-gap. mmc5r03c.pdf 6.33.3.2, 6.33.3.18 .
|
||||
*/
|
||||
tar[0]->pregap2 = 1;
|
||||
|
||||
pform = form;
|
||||
for (i = 0; i < ntr; i++) {
|
||||
type_to_form(tar[i]->mode, &ctladr, &form);
|
||||
|
||||
|
||||
/* ts A70121 : This seems to be thw wrong test. Correct would
|
||||
be to compare tar[]->mode or bit2 of ctladr.
|
||||
*/
|
||||
|
||||
if (pform != form) {
|
||||
|
||||
ret = add_cue(sheet, ctladr | 1, i + 1, 0, form, 0,
|
||||
@ -405,6 +420,21 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
||||
/ / if (!(form & BURN_AUDIO))
|
||||
/ / tar[i]->pregap1 = 1;
|
||||
*/
|
||||
/* ts A70121 : it is unclear why (form & BURN_AUDIO) should prevent pregap1.
|
||||
I believe, correct would be:
|
||||
runtime += 75;
|
||||
tar[i]->pregap1 = 1;
|
||||
|
||||
The test for pform != form is wrong anyway.
|
||||
|
||||
Next one has to care for Post-gap: table 555 in mmc5r03c.pdf does not
|
||||
show any although 6.33.3.19 would prescribe some.
|
||||
|
||||
Nobody seems to have ever tested this situation, up to now.
|
||||
It is banned for now in burn_disc_write().
|
||||
Warning have been placed in libburn.h .
|
||||
*/
|
||||
|
||||
tar[i]->pregap2 = 1;
|
||||
}
|
||||
/* XXX HERE IS WHERE WE DO INDICES IN THE CUE SHEET */
|
||||
@ -424,7 +454,20 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
||||
if (ret <= 0)
|
||||
goto failed;
|
||||
|
||||
runtime += burn_track_get_sectors(tar[i]);
|
||||
/* ts A70125 :
|
||||
Still not understanding the sense behind linking tracks,
|
||||
i decided to at least enforce the MMC specs' minimum
|
||||
track length.
|
||||
*/
|
||||
track_length = burn_track_get_sectors(tar[i]);
|
||||
if (track_length < 300) {
|
||||
track_length = 300;
|
||||
if (!tar[i]->pad)
|
||||
tar[i]->pad = 1;
|
||||
burn_track_set_sectors(tar[i], track_length);
|
||||
}
|
||||
runtime += track_length;
|
||||
|
||||
/* if we're padding, we'll clear any current shortage.
|
||||
if we're not, we'll slip toc entries by a sector every time our
|
||||
shortage is more than a sector
|
||||
@ -626,12 +669,27 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
d->rlba += 150;
|
||||
|
||||
if (t->pregap1) {
|
||||
struct burn_track *pt = s->track[tnum - 1];
|
||||
|
||||
struct burn_track *pt;
|
||||
/* ts A70121 : Removed pseudo suicidal initializer
|
||||
= s->track[tnum - 1];
|
||||
*/
|
||||
|
||||
if (tnum == 0) {
|
||||
|
||||
/* ts A70121 : This is not possible because
|
||||
track 1 cannot have a pregap at all.
|
||||
MMC-5 6.33.3.2 precribes a mandatory pause
|
||||
prior to any track 1. Pre-gap is prescribed
|
||||
for mode changes like audio-to-data.
|
||||
To set burn_track.pregap1 for track 1 is
|
||||
kindof a dirty hack.
|
||||
*/
|
||||
|
||||
printf("first track should not have a pregap1\n");
|
||||
pt = t;
|
||||
}
|
||||
} else
|
||||
pt = s->track[tnum - 1]; /* ts A70121 */
|
||||
for (i = 0; i < 75; i++)
|
||||
if (!sector_pregap(o, t->entry->point,
|
||||
pt->entry->control, pt->mode))
|
||||
@ -810,7 +868,71 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 */
|
||||
/* 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)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
char msg[160];
|
||||
int ret, lba, nwa;
|
||||
off_t size;
|
||||
|
||||
d->send_write_parameters(d, o);
|
||||
ret = d->get_nwa(d, -1, &lba, &nwa);
|
||||
sprintf(msg,
|
||||
"DVD 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;
|
||||
|
||||
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
|
||||
/* 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);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A70129 */
|
||||
int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
|
||||
struct burn_session *s, int tnum)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
char msg[80];
|
||||
|
||||
/* only with Incremental writing */
|
||||
if (o->write_type != BURN_WRITE_TAO)
|
||||
return 2;
|
||||
|
||||
sprintf(msg, "Closing track %2.2d (absolute track 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;
|
||||
/* Ignoring tnum here and hoping that d->last_track_no is correct */
|
||||
d->close_track_session(d, 0, d->last_track_no); /* CLOSE TRACK, 001b */
|
||||
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)
|
||||
{
|
||||
@ -818,12 +940,17 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
struct burn_drive *d = o->drive;
|
||||
struct buffer *out = d->buffer;
|
||||
int sectors;
|
||||
int i, open_ended = 0, ret= 0;
|
||||
int i, open_ended = 0, ret= 0, is_flushed = 0;
|
||||
|
||||
sectors = burn_track_get_sectors(t);
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
/* >>> any type specific track preparations */;
|
||||
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;
|
||||
}
|
||||
|
||||
burn_disc_init_track_status(o, s, tnum, sectors);
|
||||
for (i = 0; open_ended || i < sectors; i++) {
|
||||
@ -846,7 +973,7 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
d->progress.sector++;
|
||||
}
|
||||
|
||||
/* Pad up buffer to next full 32 kB */
|
||||
/* 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);
|
||||
out->sectors += (o->obs - out->bytes) / 2048;
|
||||
@ -855,14 +982,19 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
||||
ret = burn_write_flush(o, t);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
is_flushed = 1;
|
||||
|
||||
/* >>> any other normal track finalizing */;
|
||||
|
||||
/* Eventually finalize track */
|
||||
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 != 2)
|
||||
goto ex;
|
||||
}
|
||||
ret = 1;
|
||||
ex:;
|
||||
if (ret<=0) {
|
||||
if (!is_flushed)
|
||||
d->sync_cache(d); /* burn_write_flush() was not called */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -906,6 +1038,27 @@ int burn_disc_close_session_dvd_minus_rw(struct burn_write_opts *o,
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
|
||||
/* only for Incremental writing */
|
||||
if (o->write_type != BURN_WRITE_TAO)
|
||||
return 2;
|
||||
|
||||
libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Closing session", 0, 0);
|
||||
|
||||
d->busy = BURN_DRIVE_CLOSING_SESSION;
|
||||
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 */
|
||||
int burn_dvd_write_session(struct burn_write_opts *o,
|
||||
struct burn_session *s)
|
||||
@ -913,26 +1066,35 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
||||
int i,ret;
|
||||
struct burn_drive *d = o->drive;
|
||||
|
||||
/* >>> open_session ? */
|
||||
|
||||
for (i = 0; i < s->tracks; i++) {
|
||||
ret = burn_dvd_write_track(o, s, i);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
}
|
||||
if (d->current_profile == 0x1a) {
|
||||
/* DVD+RW */
|
||||
ret = burn_disc_close_session_dvd_plus_rw(o, s);
|
||||
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;
|
||||
} else if (d->current_profile == 0x12) {
|
||||
/* DVD-RAM */
|
||||
/* ??? any finalization needed ? */;
|
||||
} else if (d->current_profile == 0x13) {
|
||||
/* DVD-RW restricted overwrite */
|
||||
if (d->dvd_minus_rw_incomplete) {
|
||||
if (d->needs_close_session) {
|
||||
ret = burn_disc_close_session_dvd_minus_rw(o, s);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
}
|
||||
} else if (d->current_profile == 0x12) {
|
||||
/* DVD-RAM */
|
||||
/* ??? any finalization needed ? */;
|
||||
} else if (d->current_profile == 0x1a) {
|
||||
/* DVD+RW */
|
||||
if (d->needs_close_session) {
|
||||
ret = burn_disc_close_session_dvd_plus_rw(o, s);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -953,6 +1115,7 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
d->busy = BURN_DRIVE_WRITING;
|
||||
d->needs_close_session = 1;
|
||||
}
|
||||
d->nwa = 0;
|
||||
if (o->start_byte >= 0) {
|
||||
@ -1009,7 +1172,7 @@ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
|
||||
5.4.14 finally states that profile 0013h includes feature
|
||||
002Ch rather than 0026h.
|
||||
|
||||
d->send_write_parameters(d, o);
|
||||
d->send_write_parameters(d, o);
|
||||
*/
|
||||
|
||||
d->busy = BURN_DRIVE_FORMATTING;
|
||||
@ -1039,14 +1202,28 @@ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 */
|
||||
/* ts A70129 : for DVD-R[W] Sequential Recoding */
|
||||
int burn_disc_setup_dvd_minus_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_minus_r() */;
|
||||
|
||||
d->nwa = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61218 - A70129 */
|
||||
int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
struct burn_disc *disc)
|
||||
{
|
||||
int i, ret, sx, tx, mode, exotic_track = 0;
|
||||
int i, ret, sx, tx, mode, exotic_track = 0, dao_is_ok;
|
||||
struct burn_drive *d = o->drive;
|
||||
char msg[160];
|
||||
|
||||
d->needs_close_session = 0;
|
||||
for (sx = 0; sx < disc->sessions; sx++)
|
||||
for (tx = 0 ; tx < disc->session[sx]->tracks; tx++) {
|
||||
mode = disc->session[sx]->track[tx]->mode;
|
||||
@ -1102,7 +1279,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
}
|
||||
o->obs_pad = 0; /* no filling-up of track's last 32k buffer */
|
||||
|
||||
} else if (d->current_profile == 0x13) { /* DVD-RW Rest. Overwrite */
|
||||
} else if (d->current_profile == 0x13) {
|
||||
/* DVD-RW Restricted Overwrite */
|
||||
if (o->start_byte >= 0 && (o->start_byte % 32768)) {
|
||||
sprintf(msg,
|
||||
"Write start address not properly aligned to 32K");
|
||||
@ -1123,9 +1301,71 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
||||
goto early_failure;
|
||||
}
|
||||
|
||||
/* ??? is this necessary ? */
|
||||
/* _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) {
|
||||
/* DVD-R , DVD-RW Sequential */
|
||||
dao_is_ok =
|
||||
(disc->sessions == 1 &&
|
||||
disc->session[0]->tracks == 1 &&
|
||||
(! 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) {
|
||||
if (dao_is_ok) {
|
||||
o->write_type = BURN_WRITE_SAO;
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x00020134,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Defaulted TAO to DAO (lack of feature 21h)",
|
||||
0, 0);
|
||||
} else {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x00020135,
|
||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Cannot perform TAO (lack of feature 21h), job unsuitable for DAO",
|
||||
0, 0);
|
||||
goto early_failure;
|
||||
}
|
||||
} else if (o->write_type == BURN_WRITE_SAO && !dao_is_ok) {
|
||||
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);
|
||||
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);
|
||||
goto early_failure;
|
||||
}
|
||||
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);
|
||||
goto early_failure;
|
||||
}
|
||||
ret = burn_disc_setup_dvd_minus_r(o, disc);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg,
|
||||
"Write preparation setup failed for DVD-R[W]");
|
||||
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 */
|
||||
|
||||
} else {
|
||||
sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
|
||||
d->current_profile, d->current_profile_text);
|
||||
|
@ -8,8 +8,9 @@
|
||||
|
||||
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, can format a DVD-RW, and can burn to CD-R, CD-RW, DVD+RW,
|
||||
DVD-RAM or DVD-RW.
|
||||
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 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
|
||||
define the standard way how above three gestures can be implemented and
|
||||
@ -261,13 +262,15 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||
{
|
||||
enum burn_disc_status disc_state;
|
||||
struct burn_progress p;
|
||||
int percent = 1;
|
||||
double percent = 1.0;
|
||||
|
||||
disc_state = burn_disc_get_status(drive);
|
||||
printf(
|
||||
"Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n",
|
||||
disc_state);
|
||||
if (disc_state == BURN_DISC_BLANK) {
|
||||
if (current_profile == 0x13) {
|
||||
; /* formatted DVD-RW will get blanked to sequential state */
|
||||
} else if (disc_state == BURN_DISC_BLANK) {
|
||||
fprintf(stderr,
|
||||
"IDLE: Blank media detected. Will leave it untouched\n");
|
||||
return 2;
|
||||
@ -295,7 +298,7 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||
percent = 1.0 + ((double) p.sector+1.0)
|
||||
/ ((double) p.sectors) * 98.0;
|
||||
printf("Blanking ( %d%% done )\n", percent);
|
||||
printf("Blanking ( %.1f%% done )\n", percent);
|
||||
sleep(1);
|
||||
}
|
||||
printf("Done\n");
|
||||
@ -311,7 +314,7 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
||||
int libburner_format_row(struct burn_drive *drive)
|
||||
{
|
||||
struct burn_progress p;
|
||||
int percent = 1;
|
||||
double percent = 1.0;
|
||||
|
||||
if (current_profile == 0x13) {
|
||||
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
|
||||
@ -328,7 +331,7 @@ int libburner_format_row(struct burn_drive *drive)
|
||||
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||
percent = 1.0 + ((double) p.sector+1.0)
|
||||
/ ((double) p.sectors) * 98.0;
|
||||
printf("Formatting ( %d%% done )\n", percent);
|
||||
printf("Formatting ( %.1f%% done )\n", percent);
|
||||
sleep(1);
|
||||
}
|
||||
burn_disc_get_profile(drive_list[0].drive, ¤t_profile,
|
||||
@ -351,6 +354,9 @@ int libburner_format_row(struct burn_drive *drive)
|
||||
|
||||
In case of external signals expect abort handling of an ongoing burn to
|
||||
last up to a minute. Wait the normal burning timespan before any kill -9.
|
||||
|
||||
For simplicity, this function allows memory leaks in case of failure.
|
||||
In apps which do not abort immediately, one should clean up better.
|
||||
*/
|
||||
int libburner_payload(struct burn_drive *drive,
|
||||
char source_adr[][4096], int source_adr_count,
|
||||
@ -364,9 +370,9 @@ int libburner_payload(struct burn_drive *drive,
|
||||
struct burn_track *track, *tracklist[99];
|
||||
struct burn_progress progress;
|
||||
time_t start_time;
|
||||
int last_sector = 0, padding = 0, trackno, write_mode_tao = 0, fd;
|
||||
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
|
||||
off_t fixed_size;
|
||||
char *adr;
|
||||
char *adr, reasons[1024];
|
||||
struct stat stbuf;
|
||||
|
||||
if (all_tracks_type != BURN_AUDIO) {
|
||||
@ -395,7 +401,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||
fixed_size = stbuf.st_size;
|
||||
}
|
||||
if (fixed_size==0)
|
||||
write_mode_tao = 1;
|
||||
unpredicted_size = 1;
|
||||
data_src = NULL;
|
||||
if (fd>=0)
|
||||
data_src = burn_fd_source_new(fd, -1, fixed_size);
|
||||
@ -419,9 +425,8 @@ int libburner_payload(struct burn_drive *drive,
|
||||
|
||||
/* Evaluate drive and media */
|
||||
disc_state = burn_disc_get_status(drive);
|
||||
if (disc_state == BURN_DISC_APPENDABLE) {
|
||||
write_mode_tao = 1;
|
||||
} else if (disc_state != BURN_DISC_BLANK) {
|
||||
if (disc_state != BURN_DISC_BLANK &&
|
||||
disc_state != BURN_DISC_APPENDABLE) {
|
||||
if (disc_state == BURN_DISC_FULL) {
|
||||
fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n");
|
||||
if (burn_disc_erasable(drive))
|
||||
@ -437,18 +442,17 @@ int libburner_payload(struct burn_drive *drive,
|
||||
burn_options = burn_write_opts_new(drive);
|
||||
burn_write_opts_set_perform_opc(burn_options, 0);
|
||||
burn_write_opts_set_multi(burn_options, !!multi);
|
||||
if (write_mode_tao)
|
||||
burn_write_opts_set_write_type(burn_options,
|
||||
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
|
||||
else
|
||||
burn_write_opts_set_write_type(burn_options,
|
||||
BURN_WRITE_SAO, BURN_BLOCK_SAO);
|
||||
if(simulate_burn)
|
||||
printf("\n*** Will TRY to SIMULATE burning ***\n\n");
|
||||
burn_write_opts_set_simulate(burn_options, simulate_burn);
|
||||
burn_structure_print_disc(target_disc);
|
||||
burn_drive_set_speed(drive, 0, 0);
|
||||
burn_write_opts_set_underrun_proof(burn_options, 1);
|
||||
if (burn_write_opts_auto_write_type(burn_options, target_disc,
|
||||
reasons, 0) == BURN_WRITE_NONE) {
|
||||
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
|
||||
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
||||
start_time = time(0);
|
||||
@ -462,7 +466,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||
printf(
|
||||
"Thank you for being patient since %d seconds.\n",
|
||||
(int) (time(0) - start_time));
|
||||
else if(write_mode_tao)
|
||||
else if(unpredicted_size)
|
||||
printf("Track %d : sector %d\n", progress.track+1,
|
||||
progress.sector);
|
||||
else
|
||||
@ -590,9 +594,11 @@ int libburner_setup(int argc, char **argv)
|
||||
printf(" %s --drive /dev/hdc my_image_file\n", argv[0]);
|
||||
printf("Blank a used CD-RW (is combinable with burning in one run):\n");
|
||||
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
|
||||
printf("Format a DVD-RW once before first use with libburner:\n");
|
||||
printf("Blank a used DVD-RW (is combinable with burning in one run):\n");
|
||||
printf(" %s --drive /dev/hdc --blank_full\n",argv[0]);
|
||||
printf("Format a DVD-RW to avoid need for blanking before re-use:\n");
|
||||
printf(" %s --drive /dev/hdc --format_overwrite\n", argv[0]);
|
||||
printf("Burn two audio tracks:\n");
|
||||
printf("Burn two audio tracks (to CD only):\n");
|
||||
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
||||
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
||||
printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]);
|
||||
|
128
test/telltoc.c
128
test/telltoc.c
@ -5,9 +5,9 @@
|
||||
/** Overview
|
||||
|
||||
telltoc is a minimal demo application for the library libburn as provided
|
||||
on http://libburn.pykix.org . It can list the available devices, can display
|
||||
some drive properties, the type of media, eventual table of content and
|
||||
multisession info for mkisofs option -C .
|
||||
on http://libburnia.pykix.org . It can list the available devices, can
|
||||
display some drive properties, the type of media, eventual table of content
|
||||
and multisession info for mkisofs option -C .
|
||||
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||
to serve the libburn team as reference application. telltoc.c does indeed
|
||||
define the standard way how above gestures can be implemented and stay upward
|
||||
@ -228,6 +228,7 @@ int telltoc_media(struct burn_drive *drive)
|
||||
double max_speed = 0.0, min_speed = 0.0, speed_conv;
|
||||
enum burn_disc_status s;
|
||||
char profile_name[80], speed_unit[40];
|
||||
struct burn_multi_caps *caps;
|
||||
|
||||
printf("Media current: ");
|
||||
ret = burn_disc_get_profile(drive, &profile_no, profile_name);
|
||||
@ -273,6 +274,44 @@ int telltoc_media(struct burn_drive *drive)
|
||||
} else
|
||||
printf("is not recognizable\n");
|
||||
|
||||
ret = burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
|
||||
if (ret > 0) {
|
||||
printf("Write multi : ");
|
||||
printf("%s multi-session , ",
|
||||
caps->multi_session == 1 ? "allows" : "prohibits");
|
||||
if (caps->multi_track)
|
||||
printf("allows multiple tracks\n");
|
||||
else
|
||||
printf("enforces single track\n");
|
||||
printf("Write start : ");
|
||||
if (caps->start_adr == 1)
|
||||
printf(
|
||||
"allows addresses [%.f , %.f]s , alignment=%.fs\n",
|
||||
(double) caps->start_range_low / 2048 ,
|
||||
(double) caps->start_range_high / 2048 ,
|
||||
(double) caps->start_alignment / 2048 );
|
||||
else
|
||||
printf("prohibits write start addressing\n");
|
||||
printf("Write modes : ");
|
||||
if (caps->might_do_tao)
|
||||
printf("TAO%s",
|
||||
caps->advised_write_mode == BURN_WRITE_TAO ?
|
||||
" (advised)" : "");
|
||||
if (caps->might_do_sao)
|
||||
printf("%sSAO%s",
|
||||
caps->might_do_tao ? " , " : "",
|
||||
caps->advised_write_mode == BURN_WRITE_SAO ?
|
||||
" (advised)" : "");
|
||||
if (caps->might_do_raw)
|
||||
printf("%sRAW%s",
|
||||
caps->might_do_tao | caps->might_do_sao ?
|
||||
" , " : "",
|
||||
caps->advised_write_mode == BURN_WRITE_RAW ?
|
||||
" (advised)" : "");
|
||||
printf("\n");
|
||||
burn_disc_free_multi_caps(&caps);
|
||||
}
|
||||
|
||||
ret= burn_drive_get_write_speed(drive);
|
||||
max_speed = ((double ) ret) / speed_conv;
|
||||
ret= burn_drive_get_min_write_speed(drive);
|
||||
@ -375,7 +414,7 @@ int telltoc_formatlist(struct burn_drive *drive)
|
||||
|
||||
int telltoc_toc(struct burn_drive *drive)
|
||||
{
|
||||
int num_sessions = 0 , num_tracks = 0 , lba = 0;
|
||||
int num_sessions = 0 , num_tracks = 0 , lba = 0, pmin, psec, pframe;
|
||||
int track_count = 0;
|
||||
int session_no, track_no;
|
||||
struct burn_disc *disc= NULL;
|
||||
@ -397,27 +436,36 @@ int telltoc_toc(struct burn_drive *drive)
|
||||
for(track_no= 0; track_no<num_tracks; track_no++) {
|
||||
track_count++;
|
||||
burn_track_get_entry(tracks[track_no], &toc_entry);
|
||||
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
|
||||
toc_entry.pframe);
|
||||
if (toc_entry.extensions_valid & 1) {
|
||||
/* DVD extension valid */
|
||||
lba = toc_entry.start_lba;
|
||||
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
|
||||
} else {
|
||||
pmin = toc_entry.pmin;
|
||||
psec = toc_entry.psec;
|
||||
pframe = toc_entry.pframe;
|
||||
lba= burn_msf_to_lba(pmin, psec, pframe);
|
||||
}
|
||||
printf("Media content: session %2d ", session_no+1);
|
||||
printf("track %2d %s lba: %9d %2.2u:%2.2u:%2.2u\n",
|
||||
printf("track %2d %s lba: %9d %4.2d:%2.2d:%2.2d\n",
|
||||
track_count,
|
||||
((toc_entry.control&7)<4?"audio":"data "),
|
||||
lba,
|
||||
toc_entry.pmin,
|
||||
toc_entry.psec,
|
||||
toc_entry.pframe);
|
||||
lba, pmin, psec, pframe);
|
||||
}
|
||||
burn_session_get_leadout_entry(sessions[session_no],
|
||||
&toc_entry);
|
||||
lba = burn_msf_to_lba(toc_entry.pmin,
|
||||
toc_entry.psec, toc_entry.pframe);
|
||||
if (toc_entry.extensions_valid & 1) {
|
||||
lba = toc_entry.start_lba;
|
||||
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
|
||||
} else {
|
||||
pmin = toc_entry.pmin;
|
||||
psec = toc_entry.psec;
|
||||
pframe = toc_entry.pframe;
|
||||
lba= burn_msf_to_lba(pmin, psec, pframe);
|
||||
}
|
||||
printf("Media content: session %2d ", session_no+1);
|
||||
printf("leadout lba: %9d %2.2u:%2.2u:%2.2u\n",
|
||||
lba,
|
||||
toc_entry.pmin,
|
||||
toc_entry.psec,
|
||||
toc_entry.pframe);
|
||||
printf("leadout lba: %9d %4.2d:%2.2d:%2.2d\n",
|
||||
lba, pmin, psec, pframe);
|
||||
}
|
||||
if (disc!=NULL)
|
||||
burn_disc_free(disc);
|
||||
@ -428,13 +476,8 @@ int telltoc_toc(struct burn_drive *drive)
|
||||
int telltoc_msinfo(struct burn_drive *drive,
|
||||
int msinfo_explicit, int msinfo_alone)
|
||||
{
|
||||
int num_sessions, session_no, ret, num_tracks;
|
||||
int nwa = -123456789, lba = -123456789, aux_lba, lout_lba;
|
||||
int ret, lba, nwa = -123456789, aux_lba;
|
||||
enum burn_disc_status s;
|
||||
struct burn_disc *disc= NULL;
|
||||
struct burn_session **sessions;
|
||||
struct burn_track **tracks;
|
||||
struct burn_toc_entry toc_entry;
|
||||
struct burn_write_opts *o= NULL;
|
||||
|
||||
s = burn_disc_get_status(drive);
|
||||
@ -450,29 +493,12 @@ int telltoc_msinfo(struct burn_drive *drive,
|
||||
The first number is the sector number of the first sector in
|
||||
the last session of the disk that should be appended to.
|
||||
*/
|
||||
disc = burn_drive_get_disc(drive);
|
||||
if (disc==NULL) {
|
||||
fprintf(stderr,"SORRY: Cannot obtain info about CD content\n");
|
||||
return 2;
|
||||
}
|
||||
sessions = burn_disc_get_sessions(disc, &num_sessions);
|
||||
for (session_no = 0; session_no<num_sessions; session_no++) {
|
||||
tracks = burn_session_get_tracks(sessions[session_no],
|
||||
&num_tracks);
|
||||
if (tracks==NULL || num_tracks<=0)
|
||||
continue;
|
||||
burn_track_get_entry(tracks[0], &toc_entry);
|
||||
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
|
||||
toc_entry.pframe);
|
||||
}
|
||||
if(lba==-123456789) {
|
||||
fprintf(stderr,"SORRY: Cannot find any track on media\n");
|
||||
ret = burn_disc_get_msc1(drive, &lba);
|
||||
if (ret <= 0) {
|
||||
fprintf(stderr,
|
||||
"SORRY: Cannot obtain start address of last session\n");
|
||||
{ ret = 0; goto ex; }
|
||||
}
|
||||
/* Prepare a qualified guess as fallback for nwa inquiry */
|
||||
burn_session_get_leadout_entry(sessions[num_sessions-1], &toc_entry);
|
||||
lout_lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,
|
||||
toc_entry.pframe);
|
||||
|
||||
/* man mkisofs , option -C :
|
||||
The second number is the starting sector number of the new session.
|
||||
@ -489,21 +515,15 @@ int telltoc_msinfo(struct burn_drive *drive,
|
||||
telltoc_regrab(drive); /* necessary to calm down my NEC drive */
|
||||
if(ret<=0) {
|
||||
fprintf(stderr,
|
||||
"NOTE: Guessing next writeable address from leadout\n");
|
||||
if(num_sessions>0)
|
||||
nwa= lout_lba+6900;
|
||||
else
|
||||
nwa= lout_lba+11400;
|
||||
"SORRY: Cannot obtain next writeable address\n");
|
||||
{ ret = 0; goto ex; }
|
||||
}
|
||||
|
||||
if (!msinfo_alone)
|
||||
printf("Media msinfo : mkisofs ... -C ");
|
||||
printf("%d,%d\n",lba,nwa);
|
||||
|
||||
ret = 1;
|
||||
ex:;
|
||||
if (disc!=NULL)
|
||||
burn_disc_free(disc);
|
||||
if (o!=NULL)
|
||||
burn_write_opts_free(o);
|
||||
return ret;
|
||||
@ -615,7 +635,7 @@ int main(int argc, char **argv)
|
||||
full_default = do_media = do_msinfo = do_capacities= do_toc = 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Initializing libburn.pykix.org ...\n");
|
||||
fprintf(stderr, "Initializing libburnia.pykix.org ...\n");
|
||||
if (burn_initialize())
|
||||
fprintf(stderr, "Done\n");
|
||||
else {
|
||||
|
Reference in New Issue
Block a user