From 404067bfda4dc999bd8e3cf2b8b552c956ecb20c Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 23 Oct 2006 11:31:37 +0000 Subject: [PATCH] Made available drive buffer fill during write --- cdrskin/README | 35 ++++++++++++++++++++++++--------- cdrskin/cdrskin.c | 29 ++++++++++++++++++++------- cdrskin/cdrskin_eng.html | 2 ++ cdrskin/cdrskin_timestamp.h | 2 +- libburn/libburn.h | 8 +++++++- libburn/mmc.c | 39 +++++++++++++++++++++++++++++++++++++ libburn/mmc.h | 3 +++ libburn/transport.h | 4 ++++ libburn/write.c | 16 +++++++++++++++ 9 files changed, 120 insertions(+), 18 deletions(-) diff --git a/cdrskin/README b/cdrskin/README index f9a7872..ccc2d7b 100644 --- a/cdrskin/README +++ b/cdrskin/README @@ -145,13 +145,14 @@ Get an overview of cdrecord style addresses of available devices cdrskin -scanbus cdrskin dev=ATA -scanbus -Note: Adresses reported with dev=ATA are to be used with prefix "ATA:". - Like "ATA:2,2,0" . Their numbers are not cdrecord compatible. See - "Pseudo-SCSI Adresses". It is well possible to use IDE device file - paths like "/dev/hdc" rather than "ATA:2,2,0". - With SCSI devices it is possible to use "/dev/sg1" or "/dev/scd0". -Note: Address numbers have changed since cdrskin-0.2.2. To get the old number - scheme, use option --old_pseudo_scsi_adr . Sorry for any inconvenience. +Note: Adresses reported with dev=ATA are to be used with prefix "ATA:". You may + well use device file addresses as reported with --devices. Examples: + dev=1,1,0 dev=ATA:1,0,0 dev=/dev/hdc dev=/dev/sg1 + See also "Drive Addressing". +Note: Address numbers have changed since cdrskin-0.2.2 in order to become + compatible with cdrecord numbers. To get the old number scheme, use + option --old_pseudo_scsi_adr . See also "Pseudo-SCSI Adresses". + Sorry for any inconvenience. Obtain some info about the drive @@ -182,7 +183,7 @@ Anything except .wav files has to be converted into raw format first madplay -o raw:track04.cd /path/to/track4.mp3 mppdec --raw-le /path/to/track5.mpc track05.cd - cdrskin dev=/dev/hdc blank=fast fs=0 -eject \ + cdrskin dev=1,1,0 blank=fast fs=0 -eject \ -audio track0[1-5].cd /path/to/track6.wav @@ -238,9 +239,25 @@ 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. + Drive Addressing + +Drives get addressed either via their cdrecord-style addresses as listed +with option -scanbus (see below "Pseudo-SCSI Adresses") or via the paths +of device files. +Not only device files listed by --devices may be used but also device files +which via their major,minor numbers point to the same device driver as +a listed device file. + +Helpful with Linux kernel 2.4 is a special SCSI feature: +It is possible to address a scsi(-emulated) drive via associated device files +which are not listed by option --devices but point to the same SCSI addresses +as listed device files. This addressing via e.g. /dev/sr0 or /dev/scd1 is +compatible with generic read programs like dd and with write program growisofs. + + Pseudo-SCSI Adresses -cdrecord and cdrskin share the syntax of addresses but not necessarily +cdrecord and cdrskin share the syntax of SCSI addresses but not necessarily the meaning of the components. A cdrecord-style address for cdrskin [prefix:]scsibus,target,lun can be interpreted in two different modes. diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index 7a8c358..28a5a31 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -173,6 +173,7 @@ or #define Cdrskin_libburn_has_get_start_end_lbA 1 #define Cdrskin_libburn_has_burn_disc_unsuitablE 1 #define Cdrskin_libburn_has_read_atiP 1 +#define Cdrskin_libburn_has_buffer_progresS 1 #endif #ifndef Cdrskin_libburn_versioN @@ -3662,7 +3663,8 @@ int Cdrskin_burn_pacifier(struct CdrskiN *skin, enum burn_drive_status drive_status, struct burn_progress *p, double start_time, double *last_time, - double *total_count, double *last_count, int flag) + double *total_count, double *last_count, + int *min_buffer_fill, int flag) /* bit0= growisofs style */ @@ -3673,7 +3675,7 @@ int Cdrskin_burn_pacifier(struct CdrskiN *skin, double elapsed_time,elapsed_total_time,current_time; double estim_time,estim_minutes,estim_seconds,percent; int ret,fifo_percent,fill,space,advance_interval=0,new_mb,old_mb,time_to_tell; - int fs,bs,old_track_idx; + int fs,bs,old_track_idx,buffer_fill; char fifo_text[80],mb_text[40]; char *debug_mark= ""; /* use this to prepend a marker text for experiments */ @@ -3860,9 +3862,20 @@ thank_you_for_patience:; } else sprintf(mb_text,"%4d",(int) (written_total_bytes/1024.0/1024.0)); speed_factor= Cdrskin_cd_speed_factoR*sector_size/2048; - printf("\r%sTrack %-2.2d: %s MB written %s[buf 50%%] %4.1fx.", + + buffer_fill= 50; +#ifdef Cdrskin_libburn_has_buffer_progresS + if(p->buffer_capacity>0) + buffer_fill= (double) (p->buffer_capacity - p->buffer_available)*100.0 + / (double) p->buffer_capacity; + +#endif /* Cdrskin_libburn_has_buffer_progresS */ + if(buffer_fill<*min_buffer_fill) + *min_buffer_fill= buffer_fill; + + printf("\r%sTrack %-2.2d: %s MB written %s[buf %3d%%] %4.1fx.", debug_mark,skin->supposed_track_idx+1,mb_text,fifo_text, - measured_speed/speed_factor); + buffer_fill,measured_speed/speed_factor); fflush(stdout); } if(skin->is_writing==0) { @@ -3923,7 +3936,7 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag) struct burn_progress p; struct burn_drive *drive; int ret,loop_counter= 0,max_track= -1,i,hflag; - int fifo_disabled= 0,fifo_percent,total_min_fill,mb; + int fifo_disabled= 0,fifo_percent,total_min_fill,mb,min_buffer_fill= 101; double put_counter,get_counter,empty_counter,full_counter; double start_time,last_time; double total_count= 0.0,last_count= 0.0,size,padding,sector_size= 2048.0; @@ -4066,7 +4079,7 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag) if(loop_counter>0) Cdrskin_burn_pacifier(skin,drive_status,&p,start_time,&last_time, - &total_count,&last_count,0); + &total_count,&last_count,&min_buffer_fill,0); /* <<< debugging : artificial abort without a previous signal */; @@ -4187,7 +4200,9 @@ fifo_full_at_end:; "Cdrskin: fifo was %.f times empty and %.f times full, min fill was %d%%.\n", empty_counter,full_counter,fifo_percent); } - printf("Min drive buffer fill was 50%%\n"); + if(min_buffer_fill>100) + min_buffer_fill= 50; + printf("Min drive buffer fill was %d%%\n", min_buffer_fill); } #endif /* ! Cdrskin_extra_leaN */ diff --git a/cdrskin/cdrskin_eng.html b/cdrskin/cdrskin_eng.html index f3ae357..073423c 100644 --- a/cdrskin/cdrskin_eng.html +++ b/cdrskin/cdrskin_eng.html @@ -201,6 +201,8 @@ cdrskin_0.2.2-x86-suse9_0-static.tar.gz, (250 KB), -static compiled,
  • Track source files with ending .wav are checked for compliance and extracted automatically.
  • +
  • Drive buffer fill indicator reports are realistic percentage numbers.
  • +
  • Option -toc is supported, drive firmware revision gets displayed.
  •  
    README 0.2.3 diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index e4644c9..e705fba 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2006.10.23.074430" +#define Cdrskin_timestamP "2006.10.23.113116" diff --git a/libburn/libburn.h b/libburn/libburn.h index 1319344..559a3be 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -295,7 +295,7 @@ struct burn_drive_info /** This is currently the string which is used as persistent drive address. But be warned: there is NO GUARANTEE that this will stay so. Always use function burn_drive_get_adr() to - inquire a persisten address. ^^^^^^ ALWAYS ^^^^^^ */ + inquire a persistent address. ^^^^^^ ALWAYS ^^^^^^ */ /** Can the drive read DVD-RAM discs */ unsigned int read_dvdram:1; @@ -378,6 +378,12 @@ struct burn_progress { int sectors; /** The current sector being processed */ int sector; + + /* ts A61023 */ + /** The capacity of the drive buffer */ + unsigned buffer_capacity; + /** The free space in the drive buffer (might be slightly outdated) */ + unsigned buffer_available; }; /** Initialize the library. diff --git a/libburn/mmc.c b/libburn/mmc.c index cf0b07a..d3bd5f2 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -47,6 +47,9 @@ static unsigned char MMC_TRACK_INFO[] = { 0x52, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_SEND_CUE_SHEET[] = { 0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +/* ts A61023 : get size and free space of drive buffer */ +static unsigned char MMC_READ_BUFFER_CAPACITY[] = { 0x5C, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; + static int mmc_function_spy_do_tell = 0; @@ -771,6 +774,40 @@ void mmc_sync_cache(struct burn_drive *d) d->issue_command(d, &c); } + +/* ts A61023 : http://libburn.pykix.org/ticket/14 + get size and free space of drive buffer +*/ +int mmc_read_buffer_capacity(struct burn_drive *d) +{ + struct buffer buf; + struct command c; + unsigned char *data; + + mmc_function_spy("mmc_read_buffer_capacity"); + memcpy(c.opcode, MMC_READ_BUFFER_CAPACITY, + sizeof(MMC_READ_BUFFER_CAPACITY)); + c.retry = 1; + c.oplen = sizeof(MMC_READ_BUFFER_CAPACITY); + c.page = &buf; + c.page->bytes = 0; + c.page->sectors = 0; + + c.dir = FROM_DRIVE; + d->issue_command(d, &c); + + /* >>> ??? error diagnostics */ + + data = c.page->data; + + d->progress.buffer_capacity = + (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7]; + d->progress.buffer_available = + (data[8]<<24)|(data[9]<<16)|(data[10]<<8)|data[11]; + return 1; +} + + /* ts A61021 : the mmc specific part of sg.c:enumerate_common() */ int mmc_setup_drive(struct burn_drive *d) @@ -787,6 +824,7 @@ int mmc_setup_drive(struct burn_drive *d) d->get_nwa = mmc_get_nwa; d->close_disc = mmc_close_disc; d->close_session = mmc_close_session; + d->read_buffer_capacity = mmc_read_buffer_capacity; /* ts A61020 */ d->start_lba= -2000000000; @@ -794,3 +832,4 @@ int mmc_setup_drive(struct burn_drive *d) return 1; } + diff --git a/libburn/mmc.h b/libburn/mmc.h index 74999eb..02a0332 100644 --- a/libburn/mmc.h +++ b/libburn/mmc.h @@ -40,6 +40,9 @@ void mmc_get_configuration(struct burn_drive *); int mmc_get_nwa(struct burn_drive *); void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *); +/* ts A61023 : get size and free space of drive buffer */ +int mmc_read_buffer_capacity(struct burn_drive *d); + /* ts A61021 : the mmc specific part of sg.c:enumerate_common() */ int mmc_setup_drive(struct burn_drive *d); diff --git a/libburn/transport.h b/libburn/transport.h index 2e78861..fa55030 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -196,6 +196,10 @@ struct burn_drive struct scsi_mode_data *mdata; int toc_entries; struct burn_toc_entry *toc_entry; + + /* ts A61023 : get size and free space of drive buffer */ + int (*read_buffer_capacity) (struct burn_drive *d); + }; /* end of generic 'drive' data structures */ diff --git a/libburn/write.c b/libburn/write.c index 23939db..6793721 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -485,12 +485,19 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, /* ts A60831: added tnum-line, extended print message on proposal by bonfire-app@wanadoo.fr in http://libburn.pykix.org/ticket/58 */ d->progress.track = tnum; + burn_print(12, "track %d is %d sectors long\n", tnum, sectors); if (tnum == s->tracks) tmp = sectors > 150 ? 150 : sectors; for (i = 0; i < sectors - tmp; i++) { + + /* ts A61023 : http://libburn.pykix.org/ticket/14 + From time to time inquire drive buffer */ + if ((i%64)==0) + d->read_buffer_capacity(d); + if (!sector_data(o, t, 0)) return 0; @@ -499,6 +506,11 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, } for (; i < sectors; i++) { burn_print(1, "last track, leadout prep\n"); + + /* ts A61023 */ + if ((i%64)==0) + d->read_buffer_capacity(d); + if (!sector_data(o, t, 1)) return 0; @@ -597,6 +609,10 @@ return crap. so we send the command, then ignore the result. d->progress.sectors = 0; d->progress.sector = 0; + /* ts A61023 */ + d->progress.buffer_capacity = 0; + d->progress.buffer_available = 0; + d->busy = BURN_DRIVE_WRITING; for (i = 0; i < disc->sessions; i++) {