Experiment for TOC on overwriteables: Keep a target_head copy of session #1
This commit is contained in:
parent
f830c30196
commit
3eae8634cd
@ -213,7 +213,27 @@ int isoburn_libburn_req(int *major, int *minor, int *micro)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Examine the media and sets appropriate emulation if needed.
|
int isoburn_is_intermediate_dvd_rw(struct burn_drive *d, int flag)
|
||||||
|
{
|
||||||
|
int profile, ret= 0, format_status, num_formats;
|
||||||
|
char profile_name[80];
|
||||||
|
enum burn_disc_status s;
|
||||||
|
off_t format_size= -1;
|
||||||
|
unsigned bl_sas;
|
||||||
|
|
||||||
|
s= isoburn_disc_get_status(d);
|
||||||
|
ret= burn_disc_get_profile(d, &profile, profile_name);
|
||||||
|
if(ret>0 && profile==0x13)
|
||||||
|
ret= burn_disc_get_formats(d, &format_status, &format_size,
|
||||||
|
&bl_sas, &num_formats);
|
||||||
|
if(ret>0 && profile==0x13 && s==BURN_DISC_BLANK &&
|
||||||
|
format_status==BURN_FORMAT_IS_UNKNOWN)
|
||||||
|
return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Examines the media and sets appropriate emulation if needed.
|
||||||
@param flag bit0= pretent blank on overwriteable media
|
@param flag bit0= pretent blank on overwriteable media
|
||||||
*/
|
*/
|
||||||
static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d,
|
static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d,
|
||||||
@ -238,9 +258,14 @@ static int isoburn_welcome_media(struct isoburn **o, struct burn_drive *d,
|
|||||||
|
|
||||||
if(caps->start_adr) { /* set emulation to overwriteable */
|
if(caps->start_adr) { /* set emulation to overwriteable */
|
||||||
(*o)->emulation_mode= 1;
|
(*o)->emulation_mode= 1;
|
||||||
|
ret= isoburn_is_intermediate_dvd_rw(d, 0);
|
||||||
if(flag&1) {
|
if(ret>0) {
|
||||||
|
(*o)->min_start_byte= 0;
|
||||||
(*o)->nwa= 0;
|
(*o)->nwa= 0;
|
||||||
|
(*o)->zero_nwa= 0;
|
||||||
|
}
|
||||||
|
if(flag&1) {
|
||||||
|
(*o)->nwa= (*o)->zero_nwa;
|
||||||
(*o)->fabricated_disc_status= BURN_DISC_BLANK;
|
(*o)->fabricated_disc_status= BURN_DISC_BLANK;
|
||||||
} else {
|
} else {
|
||||||
ret= isoburn_start_emulation(*o, 0);
|
ret= isoburn_start_emulation(*o, 0);
|
||||||
@ -386,7 +411,7 @@ enum burn_disc_status isoburn_disc_get_status(struct burn_drive *drive)
|
|||||||
/* emulated status */
|
/* emulated status */
|
||||||
if(o->emulation_mode==-1)
|
if(o->emulation_mode==-1)
|
||||||
return(BURN_DISC_UNSUITABLE);
|
return(BURN_DISC_UNSUITABLE);
|
||||||
if(o->nwa>0)
|
if(o->nwa>o->zero_nwa)
|
||||||
return(BURN_DISC_APPENDABLE);
|
return(BURN_DISC_APPENDABLE);
|
||||||
return(BURN_DISC_BLANK);
|
return(BURN_DISC_BLANK);
|
||||||
}
|
}
|
||||||
@ -520,6 +545,16 @@ void isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
enum burn_write_types write_type;
|
enum burn_write_types write_type;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
|
/* <<< now in isoburn_is_intermediate_dvd_rw()
|
||||||
|
*/
|
||||||
|
int profile, format_status, num_formats;
|
||||||
|
unsigned bl_sas;
|
||||||
|
off_t format_size= -1;
|
||||||
|
char profile_name[80];
|
||||||
|
enum burn_disc_status s;
|
||||||
|
#endif
|
||||||
|
|
||||||
drive= burn_write_opts_get_drive(opts);
|
drive= burn_write_opts_get_drive(opts);
|
||||||
ret= isoburn_find_emulator(&o, drive, 0);
|
ret= isoburn_find_emulator(&o, drive, 0);
|
||||||
if(ret<0)
|
if(ret<0)
|
||||||
@ -529,8 +564,52 @@ void isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
if(o->emulation_mode!=0) {
|
if(o->emulation_mode!=0) {
|
||||||
burn_write_opts_set_multi(opts, 0);
|
burn_write_opts_set_multi(opts, 0);
|
||||||
if(o->emulation_mode>0 && o->nwa >= 0) {
|
if(o->emulation_mode>0 && o->nwa >= 0) {
|
||||||
burn_write_opts_set_start_byte(opts, ((off_t) o->nwa) * (off_t) 2048);
|
|
||||||
nwa= o->nwa;
|
nwa= o->nwa;
|
||||||
|
|
||||||
|
/* This caters for unwritten formatted DVD-RW. They need to be written
|
||||||
|
sequentially on the first use. Only written areas are random access.
|
||||||
|
If the first session is not written to LBA 0, then re-opening of
|
||||||
|
formatting and padding is needed.
|
||||||
|
This can be done. But when the track gets closed after padding,
|
||||||
|
this lasts a long time. There is a high risk that an app will not
|
||||||
|
poll the message queue while waiting for isoburn_disc_write() to
|
||||||
|
return. The pacifier loop usually happens only afterwards.
|
||||||
|
So automatic formatting might cause a nervous clueless user.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
|
/* <<< now in isoburn_is_intermediate_dvd_rw()
|
||||||
|
*/
|
||||||
|
s= isoburn_disc_get_status(drive);
|
||||||
|
ret= burn_disc_get_profile(drive, &profile, profile_name);
|
||||||
|
if(ret>0 && profile==0x13)
|
||||||
|
ret= burn_disc_get_formats(drive, &format_status, &format_size,
|
||||||
|
&bl_sas, &num_formats);
|
||||||
|
if(ret>0 && profile==0x13 && s==BURN_DISC_BLANK && nwa>0 &&
|
||||||
|
nwa <= o->zero_nwa && format_status==BURN_FORMAT_IS_UNKNOWN) {
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
ret= isoburn_is_intermediate_dvd_rw(drive, 0);
|
||||||
|
if(ret>0 && nwa>0 && nwa <= o->zero_nwa) {
|
||||||
|
|
||||||
|
#endif /* ! NIX */
|
||||||
|
|
||||||
|
/* actually this should not happen since such media get recognized
|
||||||
|
by isoburn_welcome_media and o->zero_nwa gets set to 0
|
||||||
|
*/
|
||||||
|
sprintf(msg,
|
||||||
|
"DVD-RW insufficiently formatted. (Intermediate State, size unknown)");
|
||||||
|
burn_msgs_submit(0x00060000, msg, 0, "FAILURE", NULL);
|
||||||
|
sprintf(msg,
|
||||||
|
"It might help to first deformat it and then format it again");
|
||||||
|
burn_msgs_submit(0x00060000, msg, 0, "HINT", NULL);
|
||||||
|
burn_drive_cancel(drive); /* mark run as failure */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* end of DVD-RW oriented check */
|
||||||
|
|
||||||
|
burn_write_opts_set_start_byte(opts, nwa * (off_t) 2048);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -546,12 +625,11 @@ void isoburn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
sprintf(reasons, "%d", (int) write_type);
|
sprintf(reasons, "%d", (int) write_type);
|
||||||
fprintf(stderr, "isoburn_EXPERIMENTAL: write_type = %s\n",
|
sprintf(msg, "Write_type = %s\n",
|
||||||
(write_type == BURN_WRITE_SAO ? "SAO" :
|
(write_type == BURN_WRITE_SAO ? "SAO" :
|
||||||
(write_type == BURN_WRITE_TAO ? "TAO" : reasons)));
|
(write_type == BURN_WRITE_TAO ? "TAO" : reasons)));
|
||||||
*/
|
burn_msgs_submit(0x00060000, msg, 0, "DEBUG", NULL);
|
||||||
|
|
||||||
#ifdef Hardcoded_cd_rW
|
#ifdef Hardcoded_cd_rW
|
||||||
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */
|
/* <<< A70929 : hardcoded CD-RW with fabricated -msinfo */
|
||||||
@ -638,9 +716,10 @@ int isoburn_set_start_byte(struct isoburn *o, off_t value, int flag)
|
|||||||
if(value % caps->start_alignment)
|
if(value % caps->start_alignment)
|
||||||
value+= caps->start_alignment - (value % caps->start_alignment);
|
value+= caps->start_alignment - (value % caps->start_alignment);
|
||||||
o->nwa= value/2048;
|
o->nwa= value/2048;
|
||||||
/* If suitable for alignment, round up to full 16 sector addresses */
|
/* If suitable for media alignment, round up to Libisoburn_nwa_alignemenT */
|
||||||
if((o->nwa%16) && ((16*2048) % caps->start_alignment)==0 )
|
if((o->nwa % Libisoburn_nwa_alignemenT) &&
|
||||||
o->nwa+= 16 - (o->nwa%16);
|
((Libisoburn_nwa_alignemenT*2048) % caps->start_alignment)==0 )
|
||||||
|
o->nwa+= Libisoburn_nwa_alignemenT - (o->nwa % Libisoburn_nwa_alignemenT);
|
||||||
ret= 1;
|
ret= 1;
|
||||||
ex:
|
ex:
|
||||||
if(caps!=NULL)
|
if(caps!=NULL)
|
||||||
|
@ -42,6 +42,51 @@
|
|||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* ----------------------- isoburn_toc_entry ---------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
int isoburn_toc_entry_new(struct isoburn_toc_entry **objpt,
|
||||||
|
struct isoburn_toc_entry *boss, int flag)
|
||||||
|
{
|
||||||
|
struct isoburn_toc_entry *o, *s;
|
||||||
|
|
||||||
|
*objpt= o= (struct isoburn_toc_entry *)
|
||||||
|
malloc(sizeof(struct isoburn_toc_entry));
|
||||||
|
if(o==NULL) {
|
||||||
|
burn_msgs_submit(0x00060000,
|
||||||
|
"Cannot allocate memory for isoburn toc entry",
|
||||||
|
0, "FATAL", NULL);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
o->session= 0;
|
||||||
|
o->track_no= 0;
|
||||||
|
o->start_lba= -1;
|
||||||
|
o->track_blocks= 0;
|
||||||
|
o->next= NULL;
|
||||||
|
if(boss!=NULL) {
|
||||||
|
for(s= boss; s->next!=NULL; s= s->next);
|
||||||
|
s->next= o;
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @param flag bit0= delete all subordinates too
|
||||||
|
*/
|
||||||
|
int isoburn_toc_entry_destroy(struct isoburn_toc_entry **o, int flag)
|
||||||
|
{
|
||||||
|
if(*o==NULL)
|
||||||
|
return(0);
|
||||||
|
if(flag&1)
|
||||||
|
isoburn_toc_entry_destroy(&((*o)->next), flag);
|
||||||
|
free((char *) (*o));
|
||||||
|
*o= NULL;
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------------- end isoburn_toc_entry -------------------- */
|
||||||
|
|
||||||
/* -------------------------- isoburn ----------------------- */
|
/* -------------------------- isoburn ----------------------- */
|
||||||
|
|
||||||
|
|
||||||
@ -67,8 +112,9 @@ int isoburn_new(struct isoburn **objpt, int flag)
|
|||||||
|
|
||||||
o->drive= NULL;
|
o->drive= NULL;
|
||||||
o->emulation_mode= 0;
|
o->emulation_mode= 0;
|
||||||
o->min_start_byte= 0;
|
o->zero_nwa= Libisoburn_overwriteable_starT;
|
||||||
o->nwa= 0;
|
o->min_start_byte= o->zero_nwa * 2048;
|
||||||
|
o->nwa= o->zero_nwa;
|
||||||
o->truncate= 0;
|
o->truncate= 0;
|
||||||
|
|
||||||
#ifdef Libisoburn_no_fifO
|
#ifdef Libisoburn_no_fifO
|
||||||
@ -77,8 +123,9 @@ int isoburn_new(struct isoburn **objpt, int flag)
|
|||||||
o->fifo= NULL;
|
o->fifo= NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
o->wrote_well= -1;
|
|
||||||
o->fabricated_disc_status= BURN_DISC_UNREADY;
|
o->fabricated_disc_status= BURN_DISC_UNREADY;
|
||||||
|
o->toc= NULL;
|
||||||
|
o->wrote_well= -1;
|
||||||
for(i=0;i<65536;i++)
|
for(i=0;i<65536;i++)
|
||||||
o->target_iso_head[i]= 0;
|
o->target_iso_head[i]= 0;
|
||||||
o->image= NULL;
|
o->image= NULL;
|
||||||
@ -121,6 +168,8 @@ int isoburn_destroy(struct isoburn **objpt, int flag)
|
|||||||
if(o->image!=NULL)
|
if(o->image!=NULL)
|
||||||
iso_image_unref(o->image);
|
iso_image_unref(o->image);
|
||||||
|
|
||||||
|
if(o->toc!=NULL)
|
||||||
|
isoburn_toc_entry_destroy(&(o->toc), 1); /* all */
|
||||||
#ifdef Libisoburn_no_fifO
|
#ifdef Libisoburn_no_fifO
|
||||||
if(o->iso_source!=NULL)
|
if(o->iso_source!=NULL)
|
||||||
burn_source_free(o->iso_source);
|
burn_source_free(o->iso_source);
|
||||||
@ -339,8 +388,9 @@ int isoburn_prepare_disc_aux(struct burn_drive *d, struct burn_disc **disc,
|
|||||||
}
|
}
|
||||||
if (nwa == 0 && state == BURN_DISC_APPENDABLE) {
|
if (nwa == 0 && state == BURN_DISC_APPENDABLE) {
|
||||||
/* invalid nwa */
|
/* invalid nwa */
|
||||||
burn_msgs_submit(0x00060000, "Encountered 0 as next writeable address", 0,
|
burn_msgs_submit(0x00060000,
|
||||||
"FAILURE", NULL);
|
"Encountered 0 as next writeable address of appendable",
|
||||||
|
0, "FAILURE", NULL);
|
||||||
{ret= -4; goto ex;}
|
{ret= -4; goto ex;}
|
||||||
}
|
}
|
||||||
iso_write_opts_set_ms_block(wopts, nwa);
|
iso_write_opts_set_ms_block(wopts, nwa);
|
||||||
|
@ -17,6 +17,18 @@
|
|||||||
/* for uint8_t */
|
/* for uint8_t */
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* For emulated TOC of overwriteable media.
|
||||||
|
Provides minimal info for faking a struct burn_toc_entry.
|
||||||
|
*/
|
||||||
|
struct isoburn_toc_entry {
|
||||||
|
int session;
|
||||||
|
int track_no; /* point */
|
||||||
|
int start_lba;
|
||||||
|
int track_blocks;
|
||||||
|
|
||||||
|
struct isoburn_toc_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct isoburn {
|
struct isoburn {
|
||||||
|
|
||||||
@ -36,6 +48,11 @@ struct isoburn {
|
|||||||
struct isoburn *next;
|
struct isoburn *next;
|
||||||
|
|
||||||
|
|
||||||
|
/* The nwa to be used for a first session on the present kind of overwriteable
|
||||||
|
media (usually Libisoburn_overwriteable_starT, but might be forced to 0)
|
||||||
|
*/
|
||||||
|
int zero_nwa;
|
||||||
|
|
||||||
/* Start address as given by image examination (bytes, not blocks) */
|
/* Start address as given by image examination (bytes, not blocks) */
|
||||||
off_t min_start_byte;
|
off_t min_start_byte;
|
||||||
|
|
||||||
@ -51,6 +68,11 @@ struct isoburn {
|
|||||||
*/
|
*/
|
||||||
enum burn_disc_status fabricated_disc_status;
|
enum burn_disc_status fabricated_disc_status;
|
||||||
|
|
||||||
|
/* Eventual emulated table of content read from the chain of ISO headers
|
||||||
|
on overwriteable media.
|
||||||
|
*/
|
||||||
|
struct isoburn_toc_entry *toc;
|
||||||
|
|
||||||
#ifndef Libisoburn_no_fifO
|
#ifndef Libisoburn_no_fifO
|
||||||
/* The fifo which is installed between track and libisofs burn_source
|
/* The fifo which is installed between track and libisofs burn_source
|
||||||
*/
|
*/
|
||||||
@ -328,5 +350,34 @@ struct isoburn_imgen_opts {
|
|||||||
int effective_lba;
|
int effective_lba;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Alignment for session starts on overwriteable media.
|
||||||
|
(Increased from 16 to 32 blocks for aligning to BD-RE clusters.)
|
||||||
|
*/
|
||||||
|
#define Libisoburn_nwa_alignemenT 32
|
||||||
|
|
||||||
|
/* Size of target_iso_head which is to be written during
|
||||||
|
isoburn_activate_session()
|
||||||
|
*/
|
||||||
|
#define Libisoburn_target_head_sizE (32*2048)
|
||||||
|
|
||||||
|
/* >>> Experiment to create a chain of image headers which form a TOC:
|
||||||
|
|
||||||
|
The header of the first session is written after the LBA 0 header.
|
||||||
|
So it persists and can give the end of its session. By help of
|
||||||
|
Libisoburn_nwa_alignemenT it should be possible to predict the start
|
||||||
|
of the next session header.
|
||||||
|
The LBA 0 header is written by isoburn_activate_session() already
|
||||||
|
with the first session. So the media is mountable.
|
||||||
|
A problem arises with DVD-RW in Intermediate State. They cannot be
|
||||||
|
written by random access before they were written sequentially.
|
||||||
|
In this case, no copy of the session 1 header is maintained and no TOC
|
||||||
|
will be possible. Thus writing begins sequentially at LBA 0.
|
||||||
|
*/
|
||||||
|
#define Libisoburn_overwriteable_starT \
|
||||||
|
((off_t) (Libisoburn_target_head_sizE/2048))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* Isoburn_includeD */
|
#endif /* Isoburn_includeD */
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#endif /* Xorriso_standalonE */
|
#endif /* Xorriso_standalonE */
|
||||||
|
|
||||||
|
|
||||||
#include "isoburn.h"
|
#include "isoburn.h"
|
||||||
#include "libisoburn.h"
|
#include "libisoburn.h"
|
||||||
|
|
||||||
@ -281,11 +280,13 @@ int isoburn_activate_session(struct burn_drive *drive)
|
|||||||
if (o->emulation_mode != 1)
|
if (o->emulation_mode != 1)
|
||||||
return 1; /* don't need to activate session */
|
return 1; /* don't need to activate session */
|
||||||
|
|
||||||
if (o->fabricated_disc_status != BURN_DISC_APPENDABLE)
|
if (!(o->fabricated_disc_status == BURN_DISC_APPENDABLE ||
|
||||||
|
(o->fabricated_disc_status == BURN_DISC_BLANK &&
|
||||||
|
o->zero_nwa > 0)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
ret = burn_random_access_write(drive, 0, (char*)o->target_iso_head,
|
ret = burn_random_access_write(drive, 0, (char*)o->target_iso_head,
|
||||||
32*2048, 1);
|
Libisoburn_target_head_sizE, 1);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -356,7 +357,7 @@ int isoburn_start_emulation(struct isoburn *o, int flag)
|
|||||||
} else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) {
|
} else if (!strncmp((char*)pvm->std_identifier, "CDXX1", 5)) {
|
||||||
|
|
||||||
/* empty image */
|
/* empty image */
|
||||||
isoburn_set_start_byte(o, (off_t) 0, 0);
|
isoburn_set_start_byte(o, o->zero_nwa * 2048, 0);
|
||||||
o->fabricated_disc_status= BURN_DISC_BLANK;
|
o->fabricated_disc_status= BURN_DISC_BLANK;
|
||||||
} else {
|
} else {
|
||||||
/* treat any disc in an unknown format as full */
|
/* treat any disc in an unknown format as full */
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Xorriso_timestamP "2008.05.06.084439"
|
#define Xorriso_timestamP "2008.05.06.144606"
|
||||||
|
Loading…
Reference in New Issue
Block a user