diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index b94253e..9e68fe7 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2012.04.04.183902" +#define Cdrskin_timestamP "2012.04.08.112703" diff --git a/libburn/libburn.h b/libburn/libburn.h index 1d89ba5..9ae18de 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -3079,6 +3079,17 @@ void burn_write_opts_set_stream_recording(struct burn_write_opts *opts, */ void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs); + +/* ts B20406 */ +/** Overrides the automatic decision whether to pad up the last write chunk to + its full size. This applies to DVD, BD and stdio: pseudo-drives. + @param opts The write opts to change + @param pad 1 means to pad up in any case, 0 means automatic decision. + @since 1.2.4 +*/ +void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad); + + /* ts A91115 */ /** Sets the rythm by which stdio pseudo drives force their output data to be consumed by the receiving storage device. This forcing keeps the memory diff --git a/libburn/libburn.ver b/libburn/libburn.ver index 6ce8d23..4af6852 100644 --- a/libburn/libburn.ver +++ b/libburn/libburn.ver @@ -176,6 +176,7 @@ burn_write_opts_set_has_mediacatalog; burn_write_opts_set_leadin_text; burn_write_opts_set_mediacatalog; burn_write_opts_set_multi; +burn_write_opts_set_obs_pad; burn_write_opts_set_perform_opc; burn_write_opts_set_simulate; burn_write_opts_set_start_byte; diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 371cb93..6ac8d17 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -411,6 +411,7 @@ Range "libdax_msgs" : 0x00000000 to 0x0000ffff 0x00000001 (DEBUG,ZERO) = Test error message 0x00000002 (DEBUG,ZERO) = Debugging message 0x00000003 (FATAL,HIGH) = Out of virtual memory + 0x00000004 (FATAL,HIGH) = Generic fatal error ------------------------------------------------------------------------------ diff --git a/libburn/options.c b/libburn/options.c index eeafea2..e4c8356 100644 --- a/libburn/options.c +++ b/libburn/options.c @@ -1,6 +1,6 @@ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2010 Thomas Schmitt + Copyright (c) 2006 - 2012 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -480,6 +480,13 @@ void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs) } +/* ts B20406: API */ +void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad) +{ + opts->obs_pad = 2 * !!pad; +} + + /* ts A91115: API */ void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm) { diff --git a/libburn/options.h b/libburn/options.h index a8f1f53..eb92005 100644 --- a/libburn/options.h +++ b/libburn/options.h @@ -1,6 +1,6 @@ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2010 Thomas Schmitt + Copyright (c) 2006 - 2012 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -42,7 +42,9 @@ struct burn_write_opts /* ts A61219 : Output block size to trigger buffer flush if hit. -1 with CD, 32 kB with DVD */ int obs; - int obs_pad; /* 1=pad up last block to obs */ + int obs_pad; /* >0 pad up last block to obs, 0 do not + 2 indicates burn_write_opts_set_obs_pad(,1) + */ /* ts A61222 : Start address for media which allow a choice */ off_t start_byte; diff --git a/libburn/write.c b/libburn/write.c index 8780ce8..cbf0cb2 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -1597,15 +1597,29 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o, if (o->write_type == BURN_WRITE_SAO && ! burn_track_is_open_ended(s->track[tnum])) { - /* Round track size up to write chunk size and reserve track */ + /* Reserve track */ size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1)) * (off_t) 2048; - /* o->obs should be 32k or 64k already. But 32k alignment - was once performed in d->reserve_track() */ - if (o->obs % 32768) - o->obs += 32768 - (o->obs % 32768); - if (size % o->obs) - size += (off_t) (o->obs - (size % o->obs)); + if (o->obs_pad) { + /* Round track size up to write chunk size */ + /* o->obs should be 32k or 64k already. But 32k + alignment was once performed in d->reserve_track()*/ + if (o->obs % 32768) + o->obs += 32768 - (o->obs % 32768); + if (size % o->obs) + size += (off_t) (o->obs - (size % o->obs)); + } + + /* <<< Only for now until the first DVD+R succeeded */ + if (!o->obs_pad) { + sprintf(msg, "Program error: encountered DVD+R without chunk padding"); + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x00000004, + LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, + msg, 0, 0); + {ret = 0; goto ex;} + } + ret = d->reserve_track(d, size); if (ret <= 0) { sprintf(msg, "Cannot reserve track of %.f bytes", @@ -2280,11 +2294,13 @@ int burn_dvd_write_sync(struct burn_write_opts *o, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } - o->obs_pad = 0; /* no filling-up of track's last 32k buffer */ + if (o->obs_pad < 2) + o->obs_pad = 0; /* no filling-up of last 32k buffer */ if (d->current_profile == 0x43) /* BD-RE */ o->obs = Libburn_bd_re_obS; if (d->do_stream_recording) { - o->obs_pad = 1; + if (o->obs_pad < 2) + o->obs_pad = 1; if (d->current_profile == 0x43) /* BD-RE */ o->obs = Libburn_bd_re_streamed_obS; } @@ -2321,7 +2337,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o, burn_track_set_size(t, default_size); } /* Whether to fill-up last 32k buffer of track. */ - o->obs_pad = (o->write_type != BURN_WRITE_SAO); + if (o->obs_pad < 2) + o->obs_pad = (o->write_type != BURN_WRITE_SAO); ret = burn_disc_setup_dvd_minus_r(o, disc); if (ret <= 0) { sprintf(msg, @@ -2362,7 +2379,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o, goto early_failure; } /* ??? padding needed ??? cowardly doing it for now */ - o->obs_pad = 1; /* fill-up track's last 32k buffer */ + if (o->obs_pad < 2) + o->obs_pad = 1; /* fill-up track's last 32k buffer */ if (d->do_stream_recording) { if (d->current_profile == 0x41) /* BD-R */ o->obs = Libburn_bd_re_streamed_obS; @@ -2777,7 +2795,8 @@ int burn_stdio_write_sync(struct burn_write_opts *o, struct burn_drive *d = o->drive; d->needs_close_session = 0; - o->obs_pad = 0; /* no filling-up of track's last 32k buffer */ + if (o->obs_pad < 2) + o->obs_pad = 0; /* no filling-up of track's last 32k buffer */ o->obs = 32*1024; /* buffer size */ if (disc->sessions != 1)