[Libburn] TAO writing

Tiago Cogumbreiro cogumbreiro@linus.uac.pt
Mon, 15 Dec 2003 12:48:59 -0100


--=-13QlrmtUF2rSj7KTLPw3
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hello there,
I've been trying to implement TAO writing but apparently my drive isn't
working well with it (the red light never blinks) i am assuming the
write commands are returning an error.
I implemented TAO by doing the follwoing, skipping leads then adding a
SYNC CACHE at the end of each track (it marks the end, thus drive gens
leadout).
When writing with TAO i had the following segfault:

0x0804cd84 in sector_subcodes (d=0x8053dc0, subcodes=0xbf5ef964 "", 
    t=0x8065e18, prelout=0) at libburn/sector.c:224
224             if ((t->entry->point == 1) && (d->rlba == -150))
(gdb) bt
#0  0x0804cd84 in sector_subcodes (d=0x8053dc0, subcodes=0xbf5ef964 "", 
    t=0x8065e18, prelout=0) at libburn/sector.c:224
#1  0x0804d32e in sector_data (d=0x8053dc0, t=0x8065e18, prelout=0)
    at libburn/sector.c:356
#2  0x080503d5 in burn_write_track (d=0x8053dc0, o=0x8066018,
t=0x8065e18, 
    pt=0x0, nt=0x0) at libburn/write.c:297
#3  0x08050218 in burn_write_session (d=0x8053dc0, o=0x8066018,
s=0x8063d18)
    at libburn/write.c:243
#4  0x08050677 in burn_disc_write_sync (d=0x8053dc0, disc=0x8065df8, 
    o=0x8066018) at libburn/write.c:375
#5  0x080496c3 in write_disc_worker_func (w=0x8066050) at
libburn/async.c:156
#6  0x40029e31 in pthread_start_thread () from /lib/libpthread.so.0

The problem is that track.entry is NULL. I did a "grep entry libburn/*"
and found no entry doing "track->entry = foo" so i assum that this is a
bug or an unimplemented feature.
I don't understand where burn_toc_entry should be created but this
prevents TAO from working, i've did a quick hack just to check what
would happen if sector_subcodes wasn't called and the result was what
i've said before, nothing happens in what concerns to writing.
I have 2 questions hardcoded on the sourcecode:
1. In TAO mode when i finish burning a session and have another one to
create should i call CLOSE SESSION?
2. Shouldn't it be SUBCODE_SIZE instead of 96? can't we have 16 bytes
buffer?
	if(t->source->read_sub)
		t->source->read_sub(t->source, data + 2352, 96);
	else
		sector_subcodes(d, data + 2352, t, prelout);

Also the progress wasn't updating track number (my fault) so i've
corrected that too.

I tried running burniso to burn raw audio to a cd (multiple tracks) but
i had no success too. The tracks are added corrrectly because hey appear
in the progress.
I added each track with the following code:
burn_track_define_data(tr, 0, 0, 0, BURN_SECTORS | BURN_AUDIO);

And with the following burn options:
o->perform_opc = 1;
o->write_type = BURN_WRITE_RAW;
o->block_type = BURN_BLOCK_RAW0;
o->simulate = 0;
o->underrun_proof = 0;

Also the type of drive.write_type and drive.block_type was an int
instead of the enum, i've also changed that.

Happy coding ;)

Tiago Cogumbreiro

--=-13QlrmtUF2rSj7KTLPw3
Content-Disposition: attachment; filename=tao.diff
Content-Type: text/x-patch; name=tao.diff; charset=
Content-Transfer-Encoding: 7bit

? libburn/.libburn.h.swp
? libburn/.sector.c.swp
? libburn/.structure.h.swp
? libburn/.write.c.swp
? test/.burniso.c.swp
? test/track1.cdr
? test/track2.cdr
Index: libburn/sector.c
===================================================================
RCS file: /cvs/burn/burn/libburn/sector.c,v
retrieving revision 1.73
diff -p -u -r1.73 sector.c
--- libburn/sector.c	15 Dec 2003 04:52:51 -0000	1.73
+++ libburn/sector.c	15 Dec 2003 13:44:00 -0000
@@ -221,11 +221,14 @@ void sector_subcodes(struct burn_drive *
 	memset(subcodes, 0, 96);
 
 	p = subcodes;
-	if ((t->entry->point == 1) && (d->rlba == -150))
-		memset(p, 0xFF, 12);
+	/* TAO doesn't write leads nor pre-leads */
+	if (d->write_type != BURN_WRITE_TAO) {
+		if ((t->entry->point == 1) && (d->rlba == -150))
+			memset(p, 0xFF, 12);
 
-	if (prelout)
-		memset(p, 0xFF, 12);
+		if (prelout)
+			memset(p, 0xFF, 12);
+	}
 	q = subcodes + 12;
 
 	qmode = 1;
@@ -350,6 +353,7 @@ void sector_data(struct burn_drive *d, s
 	}
 /* XXX - use the sub modifier stuff here */
 	if (t->source->read_sub)
+		/* shouldn't it be SUBCODE_SIZE instead of 96? can't we have 16 bytes buffer? */
 		t->source->read_sub(t->source, data + 2352, 96);
 	else
 		sector_subcodes(d, data + 2352, t, prelout);
Index: libburn/transport.h
===================================================================
RCS file: /cvs/burn/burn/libburn/transport.h,v
retrieving revision 1.97
diff -p -u -r1.97 transport.h
--- libburn/transport.h	15 Dec 2003 04:52:51 -0000	1.97
+++ libburn/transport.h	15 Dec 2003 13:44:01 -0000
@@ -102,8 +102,8 @@ unsigned char mediacatalog[13];
 	int toc_temp;
 	struct burn_disc *disc; /* disc structure */
 	int block_types[4];
-	int write_type;
-	int block_type;
+	enum burn_write_types write_type;
+	enum burn_block_types block_type;
 	struct buffer *buffer;
 	struct burn_progress progress;
 
Index: libburn/write.c
===================================================================
RCS file: /cvs/burn/burn/libburn/write.c,v
retrieving revision 1.34
diff -p -u -r1.34 write.c
--- libburn/write.c	15 Dec 2003 04:52:51 -0000	1.34
+++ libburn/write.c	15 Dec 2003 13:44:02 -0000
@@ -239,9 +239,12 @@ void burn_write_session(struct burn_driv
 		if (i + 1 < s->tracks)
 			next = s->track[i+1];
 		else next = NULL;
-				
+		d->progress.track = i;
 		burn_write_track(d, o, s->track[i],
                                     prev, next);
+		if (o->write_type == BURN_WRITE_TAO) {
+			burn_write_flush(d);
+		}
 	}
 }
 
@@ -249,30 +252,33 @@ void burn_write_track(struct burn_drive 
                          struct burn_track *t, struct burn_track *pt,
                          struct burn_track *nt)
 {
-#warning XXX if track is not an even sector size we barf
+	#warning XXX if track is not an even sector size we barf
 	int i, tmp = 0;
 	int sectors;
 	d->rlba = 0;
-	printf("        pre-gap\n");
+	if (o->write_type != BURN_WRITE_TAO) {
+		printf("        pre-gap\n");
 
-/* pregap interval 1 */
-/* is RAW gonna be a problem? */
-	if (pt && (t->mode != pt->mode)) {
-		for (i = 0; i < 75; i++)
-			sector_pregap(d, t->entry->point, pt->entry->control,
-                                      pt->mode);
+		/* pregap interval 1 */
+		/* is RAW gonna be a problem? */
+		if (pt && (t->mode != pt->mode)) {
+			for (i = 0; i < 75; i++)
+				sector_pregap(d, t->entry->point, pt->entry->control,
+        	                              pt->mode);
+		}
+		/* pregap interval 2 */
+		#warning make the first clause match toc control/mode
+		if (t->entry->point == 1)
+			for (i = 0; i < 150; i++)
+				sector_pregap(d, t->entry->point, t->entry->control,
+	                                      t->mode);
+		else if (pt && (t->mode != pt->mode))
+			for (i = 0; i < 150; i++)
+				sector_pregap(d, t->entry->point, t->entry->control,
+	                                       t->mode);
 	}
-/* pregap interval 2 */
-#warning make the first clause match toc control/mode
-	if (t->entry->point == 1)
-		for (i = 0; i < 150; i++)
-			sector_pregap(d, t->entry->point, t->entry->control,
-                                      t->mode);
-	else if (pt && (t->mode != pt->mode))
-		for (i = 0; i < 150; i++)
-			sector_pregap(d, t->entry->point, t->entry->control,
-                                       t->mode);
-/* user data */
+	
+	/* user data */
 	sectors = burn_track_get_sectors(t);
 	
 	/* Update progress */
@@ -284,27 +290,33 @@ printf("track is %d sectors long\n", sec
 
 	if (!nt)
 		tmp = sectors > 150 ? 150 : sectors;
+	
 printf("cutting short by %d sectors\n", tmp);
+	
 	for (i = 0; i < sectors - tmp; i++) {
 		sector_data(d, t, 0);
 		
 		/* update current progress */
 		d->progress.current_sector++;
 	}
-	for (; i < sectors; i++) {
-		printf("last track, leadout prep\n");
-		sector_data(d, t, 1);
-
-		/* update progress */
-		d->progress.current_sector++;
-	}
-/* post gap */
-	if (nt && !(t->mode & BURN_AUDIO) &&
-            (nt->mode & BURN_AUDIO)) {
-		printf("        postgap\n");
-		for (i = 0; i < 150; i++)
-			sector_postgap(d, t->entry->point, t->entry->control,
-                                   t->mode);
+	
+	if (o->write_type != BURN_WRITE_TAO) {
+		for (; i < sectors; i++) {
+			printf("last track, leadout prep\n");
+			sector_data(d, t, 1);
+
+			/* update progress */
+			d->progress.current_sector++;
+		}
+		
+		/* post gap */
+		if (nt && !(t->mode & BURN_AUDIO) &&
+	            (nt->mode & BURN_AUDIO)) {
+			printf("        postgap\n");
+			for (i = 0; i < 150; i++)
+				sector_postgap(d, t->entry->point, t->entry->control,
+	                                   t->mode);
+		}
 	}
 	i = t->offset;
 }
@@ -357,11 +369,21 @@ void burn_disc_write_sync(struct burn_dr
 		d->progress.session = i;
 		d->progress.tracks = disc->session[i]->tracks;
 		
-		burn_write_leadin(d, disc->session[i], o, first);
+		if (o->write_type != BURN_WRITE_TAO)
+			burn_write_leadin(d, disc->session[i], o, first);
+		
 		burn_write_session(d, o, disc->session[i]);
-		lt = disc->session[i]->track[disc->session[i]->tracks-1];
-		burn_write_leadout(d, o, first, lt->entry->control,
-                                      lt->mode);
+		
+		if (o->write_type == BURN_WRITE_TAO) {
+			/*TODO: we need to create a new session
+			 * should we call CLOSE SESSION?*/
+		
+		} else {
+			lt = disc->session[i]->track[disc->session[i]->tracks-1];
+			burn_write_leadout(d, o, first, lt->entry->control,
+	                                      lt->mode);
+		}
+		
 		if (first)
 			first = 0;
 		
Index: test/burniso.c
===================================================================
RCS file: /cvs/burn/burn/test/burniso.c,v
retrieving revision 1.46
diff -p -u -r1.46 burniso.c
--- test/burniso.c	15 Dec 2003 04:52:51 -0000	1.46
+++ test/burniso.c	15 Dec 2003 13:44:02 -0000
@@ -28,7 +28,7 @@ void burn_iso(struct burn_drive *drive, 
 	session = burn_session_create();
 	burn_disc_add_session(disc, session, BURN_POS_END);
 	tr = burn_track_create();
-	burn_track_define_data(tr, 0, 0, 0, BURN_BYTES | BURN_MODE1);
+	burn_track_define_data(tr, 0, 0, 0, BURN_SECTORS | BURN_MODE1);
 	src = burn_file_source_new(path, NULL);
 	assert(src);
 
@@ -56,8 +56,8 @@ void burn_iso(struct burn_drive *drive, 
 	}
 	o = burn_write_opts_new();
 	o->perform_opc = 1;
-	o->write_type = BURN_WRITE_RAW;
-	o->block_type = BURN_BLOCK_RAW16;
+	o->write_type = BURN_WRITE_TAO;
+	o->block_type = BURN_BLOCK_MODE1;
 	o->simulate = 1;
 	o->underrun_proof = 0;
 

--=-13QlrmtUF2rSj7KTLPw3--