From 2945ab61d7ef4a387c33147b73bd2a8ba89144a2 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 26 Nov 2009 21:12:57 +0000 Subject: [PATCH] Compiler option -use_libburn_fifo to switch non-CD from cdrfifo to libburn fifo --- cdrskin/cdrskin.c | 339 +++++++++++++++++++++++++++++++----- cdrskin/cdrskin_timestamp.h | 2 +- cdrskin/compile_cdrskin.sh | 11 +- 3 files changed, 305 insertions(+), 47 deletions(-) diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index 3a71471..d11f2a7 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -329,10 +329,15 @@ or /** A macro which is able to eat up a function call like printf() */ #ifdef Cdrskin_extra_leaN #define ClN(x) +#define Cdrskin_no_cdrfifO 1 #else #define ClN(x) x +#ifdef Cdrskin_use_libburn_fifO +/* + # define Cdrskin_no_cdrfifO 1 +*/ +#endif #endif - /** Verbosity level for pacifying progress messages */ #define Cdrskin_verbose_progresS 1 @@ -872,12 +877,12 @@ backward:; /* --------------------------------------------------------------------- */ -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO /* Program is to be linked with cdrfifo.c */ #include "cdrfifo.h" -#else /* ! Cdrskin_extra_leaN */ +#else /* ! Cdrskin_no_cdrfifO */ /* Dummy */ @@ -885,7 +890,7 @@ struct CdrfifO { int dummy; }; -#endif /* Cdrskin_extra_leaN */ +#endif /* Cdrskin_no_cdrfifO */ /* --------------------------------------------------------------------- */ @@ -948,6 +953,10 @@ struct CdrtracK { struct burn_track *libburn_track; +#ifdef Cdrskin_use_libburn_fifO + struct burn_source *libburn_fifo; +#endif /* Cdrskin_use_libburn_fifO */ + }; int Cdrtrack_destroy(struct CdrtracK **o, int flag); @@ -1005,6 +1014,9 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss, o->ff_fifo= NULL; o->ff_idx= -1; o->libburn_track= NULL; +#ifdef Cdrskin_use_libburn_fifO + o->libburn_fifo= NULL; +#endif /* Cdrskin_use_libburn_fifO */ ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size), &(o->tao_to_sao_tsize),&(o->use_data_image_size), @@ -1041,7 +1053,7 @@ int Cdrtrack_destroy(struct CdrtracK **o, int flag) if(track==NULL) return(0); -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO Cdrfifo_destroy(&(track->fifo),0); #endif @@ -1127,6 +1139,61 @@ int Cdrtrack_get_source_path(struct CdrtracK *track, } +#ifdef Cdrskin_use_libburn_fifO + +int Cdrtrack_get_libburn_fifo(struct CdrtracK *track, + struct burn_source **fifo, int flag) +{ + *fifo= track->libburn_fifo; + return(1); +} + + +int Cdrtrack_report_fifo(struct CdrtracK *track, int flag) +{ + int size, free_bytes, ret; + int total_min_fill, interval_min_fill, put_counter, get_counter; + int empty_counter, full_counter; + double fifo_percent; + char *status_text; + + if(track->libburn_fifo == NULL) + return(0); + + /* Check for open input or leftover bytes in liburn fifo */ + ret = burn_fifo_inquire_status(track->libburn_fifo, &size, &free_bytes, + &status_text); + if(ret >= 0 && size - free_bytes > 1) { + /* not clear why free_bytes is reduced by 1 */ + fprintf(stderr, + "cdrskin: FATAL : Fifo still contains data after burning has ended.\n"); + fprintf(stderr, + "cdrskin: FATAL : %d bytes left.\n", size - free_bytes - 1); + fprintf(stderr, + "cdrskin: FATAL : This indicates an overflow of the last track.\n"); + fprintf(stderr, + "cdrskin: NOTE : The media might appear ok but is probably truncated.\n"); + return(-1); + } + + burn_fifo_get_statistics(track->libburn_fifo, &total_min_fill, + &interval_min_fill, &put_counter, &get_counter, + &empty_counter, &full_counter); + fifo_percent= 100.0*((double) total_min_fill)/(double) size; + if(fifo_percent==0 && total_min_fill>0) + fifo_percent= 1; + fflush(stdout); + fprintf(stderr,"Cdrskin: fifo had %d puts and %d gets.\n", + put_counter,get_counter); + fprintf(stderr, + "Cdrskin: fifo was %d times empty and %d times full, min fill was %.f%%.\n", + empty_counter, full_counter, fifo_percent); + return(1); +} + +#endif /* Cdrskin_use_libburn_fifO */ + + int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag) { *fifo= track->fifo; @@ -1241,7 +1308,7 @@ int Cdrtrack_activate_image_size(struct CdrtracK *track, double *size_used, } track->extracting_container= 1; -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO if(track->ff_fifo!=NULL) Cdrfifo_set_fd_in_limit(track->ff_fifo,track->fixed_size,track->ff_idx,0); #endif @@ -1397,6 +1464,9 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag) return(0); if(is_wav==0) { #ifdef Libburn_has_open_trac_srC + if(track->track_type != BURN_MODE1 || + (track->cdxa_conversion & 0x7fffffff)) + flag&= ~4; /* Better avoid O_DIRECT with odd sectors */ if(flag & 4) *fd= burn_os_open_track_src(track->source_path, O_RDONLY, 0); else @@ -1466,7 +1536,7 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag) } -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO /** Install a fifo object between data source and libburn. Its parameters are known to track. @@ -1529,18 +1599,100 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd, return(1); } +#endif /* ! Cdrskin_no_cdrfifO */ -/** Read data into the fifo until either it is full or the data source is - exhausted. + +#ifndef Cdrskin_extra_leaN + +#ifdef Cdrskin_use_libburn_fifO + +/** Read data into the eventual libburn fifo until either fifo_start_at bytes + are read (-1 = no limit), it is full or or the data source is exhausted. @return <=0 error, 1 success */ +int Cdrtrack_fill_libburn_fifo(struct CdrtracK *track, int fifo_start_at, + int flag) +{ + int ret, bs= 32 * 1024; + int buffer_size, buffer_free; + double data_image_size; + char buf[64 * 1024], *buffer_text; + + if(fifo_start_at == 0) + return(2); + if(track->libburn_fifo == NULL) + return(2); + + if(fifo_start_at>0 && fifo_start_atfifo_size) + printf( + "cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n", + fifo_start_at); + printf("Waiting for reader process to fill input buffer ... "); + fflush(stdout); + ret= burn_fifo_fill(track->libburn_fifo, fifo_start_at, + (fifo_start_at == -1)); + if(ret < 0) + return(0); + +/** Ticket 55: check fifos for input, throw error on 0-bytes from stdin + @return <=0 abort run, 1 go on with burning +*/ + ret= burn_fifo_inquire_status(track->libburn_fifo, &buffer_size, + &buffer_free, &buffer_text); + if(track->is_from_stdin) { + if(ret<0 || buffer_size <= buffer_free) { + fprintf(stderr,"\ncdrskin: FATAL : (First track) fifo did not read a single byte from stdin\n"); + return(0); + } + } + + /* Try to obtain ISO 9660 Volume Descriptors and size from fifo. + Not an error if there is no ISO 9660. */ + if(track->iso_fs_descr != NULL) + free(track->iso_fs_descr); + track->iso_fs_descr = NULL; + if(buffer_size - buffer_free >= 64 * 1024) { + ret= burn_fifo_peek_data(track->libburn_fifo, buf, 64 * 1024, 0); + if(ret == 1) { + track->iso_fs_descr = calloc(1, bs); + if(track->iso_fs_descr == NULL) + return(-1); + memcpy(track->iso_fs_descr, buf + bs, bs); + ret= Scan_for_iso_size((unsigned char *) buf + bs, &data_image_size, 0); + if(ret > 0) + track->data_image_size= data_image_size; + } + } + return(1); +} + +#endif /* Cdrskin_use_libburn_fifO */ + + +#ifdef Cdrskin_no_cdrfifO + +int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag) +{ + return(Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0)); +} + +#else /* Cdrskin_no_cdrfifO */ + int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag) { int ret,buffer_fill,buffer_space; double data_image_size; - if(track->fifo==NULL || fifo_start_at==0) + if(fifo_start_at==0) return(2); + if(track->fifo==NULL) { +#ifdef Cdrskin_use_libburn_fifO + ret= Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0); + return(ret); +#else + return(2); +#endif + } if(fifo_start_at>0 && fifo_start_atfifo_size) printf( "cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n", @@ -1570,6 +1722,7 @@ int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag) return(1); } +#endif /* ! Cdrskin_no_cdrfifO */ #endif /* ! Cdrskin_extra_leaN */ @@ -1642,32 +1795,40 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno, } src= burn_fd_source_new(track->source_fd,-1,(off_t) fixed_size); -/* -#define Cdrskin_try_libburn_fifO 1 -*/ +#ifdef Cdrskin_use_libburn_fifO -#ifdef Cdrskin_try_libburn_fifO - - if(src != NULL) { - int fifo_enabled, fifo_size, fifo_start_at; + if(src != NULL && track->fifo == NULL) { + int fifo_enabled, fifo_size, fifo_start_at, chunksize, chunks; int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled, int *fifo_size, int *fifo_start_at, int flag); Cdrskin_get_fifo_par(track->boss, &fifo_enabled, &fifo_size, &fifo_start_at, 0); - if(fifo_size <= 0) { /* currently: hardcoded 32m if fs=0 */ - fd_src= src; + fd_src= src; - /* >>> ??? will chunksize 2048 work with audio ? */ - - src= burn_fifo_source_new(fd_src, 2048, 16384, 1); - - fprintf(stderr, "cdrskin_DEBUG: %s 32m libburn fifo\n", - src != NULL ? "installed" : "failed to install"); + if(track->track_type == BURN_AUDIO) + chunksize= 2352; + else if (track->cdxa_conversion == 1) + chunksize= 2056; + else + chunksize= 2048; + chunks= fifo_size / chunksize; + if(chunks > 1 && fifo_enabled) { + src= burn_fifo_source_new(fd_src, chunksize, chunks, + (chunksize * chunks >= 128 * 1024)); + if((flag & 1) || src == NULL) + fprintf(stderr, "cdrskin_DEBUG: %s libburn fifo of %d bytes\n", + src != NULL ? "installed" : "failed to install", + chunksize * chunks); + track->libburn_fifo= src; + if(src == NULL) { + src= fd_src; + fd_src= NULL; + } } } -#endif +#endif /* Cdrskin_use_libburn_fifO */ if(src==NULL) { fprintf(stderr, @@ -1733,7 +1894,7 @@ int Cdrtrack_get_sectors(struct CdrtracK *track, int flag) } -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO /** Try to read bytes from the track's fifo outlet and eventually discard them. Not to be called unless the track is completely written. @@ -1754,7 +1915,7 @@ int Cdrtrack_has_input_left(struct CdrtracK *track, int flag) return(0); } -#endif /* ! Cdrskin_extra_leaN */ +#endif /* ! Cdrskin_no_cdrfifO */ /* --------------------------------------------------------------------- */ @@ -3166,19 +3327,10 @@ ex:; /** List of furter wishes towards libburn: - - write mode which does not demand a track size in advance - - obtain minimum drive speed (for cdrskin -atip) - - obtain MMC profile of inserted media (for cdrskin -v -atip) - - a possibility to implement cdrskin -multi - a possibilty to implement cdrskin -reset */ -/** <<< Hopefully obsolete: - Limit to prevent int rollovers within libburn as long as not everything is - changed to 64 bit off_t : 2 GB minus 800 MB for eventual computations. -#define Cdrskin_tracksize_maX 1308622848 -*/ #define Cdrskin_tracksize_maX 1024.0*1024.0*1024.0*1024.0 @@ -3623,6 +3775,8 @@ int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled, } +#ifndef Cdrskin_no_cdrfifO + /** Create and install fifo objects between track data sources and libburn. The sources and parameters are known to skin. @return <=0 error, 1 success @@ -3632,6 +3786,20 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag) struct CdrfifO *ff= NULL; int ret,i,hflag; +#ifdef Cdrskin_use_libburn_fifO + + int profile_number; + char profile_name[80]; + + /* Refuse here and thus use libburn fifo only with single track, non-CD */ + ret= burn_disc_get_profile(skin->drives[skin->driveno].drive, + &profile_number, profile_name); + if(profile_number != 0x09 && profile_number != 0x0a && + skin->track_counter == 1) + return(1); + +#endif /* Cdrskin_use_libburn_fifO */ + skin->fifo= NULL; for(i=0;itrack_counter;i++) { hflag= (skin->verbosity>=Cdrskin_verbose_debuG); @@ -3663,6 +3831,8 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag) return(1); } +#endif /* ! Cdrskin_no_cdrfifO */ + /** Read data into the track fifos until either #1 is full or its data source is exhausted. @@ -4005,7 +4175,7 @@ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag) if(skin->preskin->abort_handler==3) fprintf(stderr,"cdrskin: ABORT : Trying to ignore any further signals\n"); -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO if(skin->fifo!=NULL) Cdrfifo_close_all(skin->fifo,0); #endif @@ -5901,16 +6071,27 @@ int Cdrskin_burn_pacifier(struct CdrskiN *skin, */ { double bytes_to_write= 0.0; - double written_bytes= 0.0,written_total_bytes= 0.0,buffer_size; + double written_bytes= 0.0,written_total_bytes= 0.0; double fixed_size,padding,sector_size,speed_factor; double measured_total_speed,measured_speed; 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,buffer_fill,formatting= 0,use_data_image_size; + int ret,fifo_percent,fill,advance_interval=0,new_mb,old_mb,time_to_tell; + int old_track_idx,buffer_fill,formatting= 0,use_data_image_size; char fifo_text[80],mb_text[40], pending[40]; char *debug_mark= ""; /* use this to prepend a marker text for experiments */ +#ifndef Cdrskin_no_cdrfifO + double buffer_size; + int fs, bs, space; +#endif + +#ifdef Cdrskin_use_libburn_fifO + struct burn_source *current_fifo= NULL; + int size, free_space; + char *status_text= ""; +#endif /* Cdrskin_use_libburn_fifO */ + /* for debugging */ static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out; @@ -6086,6 +6267,37 @@ thank_you_for_patience:; fifo_text[0]= 0; curr_fifo_in= last_fifo_in; curr_fifo_out= last_fifo_out; + +#ifdef Cdrskin_use_libburn_fifO + + /* Inquire fifo fill and format fifo pacifier text */ + if(skin->fifo == NULL && skin->supposed_track_idx >= 0 && + skin->supposed_track_idx < skin->track_counter && + skin->fifo_size > 0) { + Cdrtrack_get_libburn_fifo(skin->tracklist[skin->supposed_track_idx], + ¤t_fifo, 0); + if(current_fifo != NULL) { + ret= burn_fifo_inquire_status(current_fifo, &size, &free_space, + &status_text); + if(ret <= 0 || ret >= 4) { + strcpy(fifo_text, "(fifo 0%) "); + } else if(ret == 1) { + burn_fifo_next_interval(current_fifo, &fill); + fifo_percent= 100.0 * ((double) fill) / (double) size; + if(fifo_percent<100 && fill>0) + fifo_percent++; + sprintf(fifo_text, "(fifo %3d%%) ", fifo_percent); + } else + strcpy(fifo_text, "(fifo 100%) "); + } else if(skin->fifo_size > 0) { + strcpy(fifo_text, "(fifo 100%) "); + } + } + +#endif /* Cdrskin_use_libburn_fifO */ + +#ifndef Cdrskin_no_cdrfifO + if(skin->fifo!=NULL) { ret= Cdrfifo_get_buffer_state(skin->fifo,&fill,&space,0); buffer_size= fill+space; @@ -6114,6 +6326,9 @@ thank_you_for_patience:; } } } + +#endif /* ! Cdrskin_no_cdrfifO */ + if(skin->supposed_track_idx >= 0 && skin->supposed_track_idx < skin->track_counter) { /* fixed_size,padding are fetched above via Cdrtrack_get_size() */; @@ -6792,15 +7007,19 @@ 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,nwa,num, wrote_well= 2; - int fifo_disabled= 0,fifo_percent,total_min_fill,min_buffer_fill= 101; + int fifo_disabled= 0, min_buffer_fill= 101; int use_data_image_size, needs_early_fifo_fill= 0,iso_size= -1; - 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; char *doing; char *source_path; int source_fd, is_from_stdin; +#ifndef Cdrskin_no_cdrfifO + double put_counter, get_counter, empty_counter, full_counter; + int total_min_fill, fifo_percent; +#endif + if(skin->tell_media_space) doing= "estimating"; else @@ -7131,6 +7350,14 @@ fifo_filling_failed:; if(skin->fifo==NULL || fifo_disabled) { usleep(20000); } else { + +#ifdef Cdrskin_no_cdrfifO + + /* Should never happen as skin->fifo should be NULL */ + usleep(20000); + +#else /* Cdrskin_no_cdrfifO */ + ret= Cdrfifo_try_to_work(skin->fifo,20000,NULL,NULL,0); if(ret<0) { int abh; @@ -7156,7 +7383,11 @@ fifo_filling_failed:; fprintf(stderr,"\ncdrskin_debug: fifo ended work with ret=%d\n",ret); fifo_disabled= 1; } + +#endif /* ! Cdrskin_no_cdrfifO */ + } + #else /* ! Cdrskin_extra_leaN */ usleep(20000); #endif /* Cdrskin_extra_leaN */ @@ -7196,6 +7427,19 @@ fifo_filling_failed:; #ifndef Cdrskin_extra_leaN +#ifdef Cdrskin_use_libburn_fifO + + if(skin->fifo == NULL && skin->verbosity>=Cdrskin_verbose_progresS) { + /* >>> this should rather be done for each track + (for now this libburn_fifo should only be used with single track) + */ + Cdrtrack_report_fifo(skin->tracklist[skin->track_counter - 1], 0); + } + +#endif /* Cdrskin_use_libburn_fifO */ + +#ifndef Cdrskin_no_cdrfifO + if(skin->fifo!=NULL && skin->fifo_size>0 && wrote_well) { int dummy,final_fill; Cdrfifo_get_buffer_state(skin->fifo,&final_fill,&dummy,0); @@ -7243,6 +7487,11 @@ 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); } + } + +#endif /* ! Cdrskin_no_cdrfifO */ + + if(skin->verbosity>=Cdrskin_verbose_progresS) { drive_status= burn_drive_get_status(drive, &p); #ifdef Cdrskin_libburn_has_buffer_min_filL @@ -8579,13 +8828,13 @@ ignore_unknown:; if(skin->track_counter>0) { skin->do_burn= 1; -#ifndef Cdrskin_extra_leaN +#ifndef Cdrskin_no_cdrfifO if(!skin->do_direct_write) { ret= Cdrskin_attach_fifo(skin,0); if(ret<=0) return(ret); } -#endif /* ! Cdrskin_extra_leaN */ +#endif /* ! Cdrskin_no_cdrfifO */ } return(1); diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index a70a88c..0a06232 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2009.11.26.144452" +#define Cdrskin_timestamP "2009.11.26.211418" diff --git a/cdrskin/compile_cdrskin.sh b/cdrskin/compile_cdrskin.sh index 3a95989..f179471 100755 --- a/cdrskin/compile_cdrskin.sh +++ b/cdrskin/compile_cdrskin.sh @@ -74,6 +74,13 @@ do elif test "$i" = "-do_strip" then do_strip=1 + elif test "$i" = "-use_libburn_fifo" + then + def_opts="$def_opts -DCdrskin_use_libburn_fifO" + elif test "$i" = "-use_no_cdrfifo" + then + fifo_source= + def_opts="$def_opts -DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO" elif test "$i" = "-g" then debug_opts="-g" @@ -87,6 +94,8 @@ do echo " -libburn_svn set macro to match current libburn-SVN." echo " -dvd_obs_64k 64 KB default size for DVD/BD writing." echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin." + echo " -use_libburn_fifo use fifo of libburn for single track non-CD" + echo " -use_no_cdrfifo use fifo of libburn and never cdrfifo" echo " -experimental use newly introduced libburn features." echo " -oldfashioned use pre-0.2.2 libburn features only." echo " -do_diet produce capability reduced lean version." @@ -107,7 +116,7 @@ echo "Build timestamp : $timestamp" if test "$compile_cdrskin" then - echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj" + echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj" cc -I. \ $warn_opts \ $static_opts \