diff --git a/configure.ac b/configure.ac index a506a76f..28dc0908 100644 --- a/configure.ac +++ b/configure.ac @@ -10,8 +10,8 @@ AC_PREREQ(2.57) dnl ############# Initialisation -AC_INIT([mpg123], [1.1.0+dev], [mpg123-devel@lists.sourceforge.net]) -LIBMPG123_VERSION=0:0:0 +AC_INIT([mpg123], [1.1.0], [mpg123-devel@lists.sourceforge.net]) +LIBMPG123_VERSION=1:0:1 AC_SUBST( LIBMPG123_VERSION ) AC_CONFIG_SRCDIR(src/mpg123.c) diff --git a/doc/examples/scan.c b/doc/examples/scan.c index fcdf9b0c..0f0cdb47 100644 --- a/doc/examples/scan.c +++ b/doc/examples/scan.c @@ -25,6 +25,7 @@ int main(int argc, char **argv) } mpg123_init(); m = mpg123_new(NULL, NULL); + mpg123_param(m, MPG123_RESYNC_LIMIT, -1, 0); /* New in library version 0.0.1 . */ for(i = 1; i < argc; ++i) { off_t a, b; diff --git a/src/libmpg123/Makefile.am b/src/libmpg123/Makefile.am index ccfc2e74..2a3bc46e 100644 --- a/src/libmpg123/Makefile.am +++ b/src/libmpg123/Makefile.am @@ -6,7 +6,7 @@ #AM_CFLAGS = @AUDIO_CFLAGS@ #AM_LDFLAGS = -INCLUDES = $(LTDLINCL) -I$(top_srcdir)/src -I$(top_srcdir)/src/libmpg123 +INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/libmpg123 EXTRA_DIST = mpg123.h.in diff --git a/src/libmpg123/frame.c b/src/libmpg123/frame.c index df723f6b..8b0577b5 100644 --- a/src/libmpg123/frame.c +++ b/src/libmpg123/frame.c @@ -37,6 +37,7 @@ void frame_default_pars(mpg123_pars *mp) #ifndef WIN32 mp->timeout = 0; #endif + mp->resync_limit = 1024; mpg123_fmt_all(mp); } @@ -293,6 +294,7 @@ static void frame_fixed_reset(mpg123_handle *fr) fr->abr_rate = 0; fr->track_frames = 0; fr->track_samples = -1; + fr->framesize=0; fr->mean_frames = 0; fr->mean_framesize = 0; fr->freesize = 0; diff --git a/src/libmpg123/frame.h b/src/libmpg123/frame.h index b50ebf21..e7fed108 100644 --- a/src/libmpg123/frame.h +++ b/src/libmpg123/frame.h @@ -124,6 +124,7 @@ struct mpg123_pars_struct /* long frame_number;*/ /* number of frames to decode */ long icy_interval; scale_t outscale; + long resync_limit; }; /* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */ diff --git a/src/libmpg123/libmpg123.c b/src/libmpg123/libmpg123.c index 3e1a4578..3220e0d0 100644 --- a/src/libmpg123/libmpg123.c +++ b/src/libmpg123/libmpg123.c @@ -237,6 +237,9 @@ int mpg123_par(mpg123_pars *mp, enum mpg123_parms key, long val, double fval) ret = MPG123_NO_TIMEOUT; #endif break; + case MPG123_RESYNC_LIMIT: + mp->resync_limit = val; + break; default: ret = MPG123_BAD_PARAM; } @@ -290,6 +293,9 @@ int mpg123_getpar(mpg123_pars *mp, enum mpg123_parms key, long *val, double *fva if(val) *val = mp->outscale; #endif break; + case MPG123_RESYNC_LIMIT: + if(val) *val = mp->resync_limit; + break; default: ret = MPG123_BAD_PARAM; } @@ -982,7 +988,9 @@ static const char *mpg123_error[] = "Seek not supported by stream. (code 23)", "No stream opened. (code 24)", "Bad parameter handle. (code 25)", - "Invalid parameter addresses for index retrieval. (code 26)" + "Invalid parameter addresses for index retrieval. (code 26)", + "Lost track in the bytestream and did not attempt resync. (code 27)", + "Failed to find valid MPEG data within limit on resync. (code 28)" }; const char* mpg123_plain_strerror(int errcode) diff --git a/src/libmpg123/mpg123.h.in b/src/libmpg123/mpg123.h.in index 84aace3c..10f58ec1 100644 --- a/src/libmpg123/mpg123.h.in +++ b/src/libmpg123/mpg123.h.in @@ -87,7 +87,8 @@ enum mpg123_parms MPG123_ICY_INTERVAL, /**< stream contains ICY metadata with this interval */ MPG123_OUTSCALE, /**< the scale for output samples (amplitude) */ MPG123_TIMEOUT, /**< timeout for reading from a stream (not supported on win32) */ - MPG123_REMOVE_FLAGS /**< remove some flags (inverse of MPG123_ADD_FLAGS) */ + MPG123_REMOVE_FLAGS, /**< remove some flags (inverse of MPG123_ADD_FLAGS) */ + MPG123_RESYNC_LIMIT /**< Try resync on frame parsing for that many bytes or until end of stream (<0). */ }; /** Flag bits for MPG123_FLAGS, use the usual binary or to combine. */ @@ -171,7 +172,9 @@ enum mpg123_errors MPG123_NO_SEEK, /**< Seek not supported by stream. */ MPG123_NO_READER, /**< No stream opened. */ MPG123_BAD_PARS, /**< Bad parameter handle. */ - MPG123_BAD_INDEX_PAR /** Bad parameters to mpg123_index() */ + MPG123_BAD_INDEX_PAR, /**< Bad parameters to mpg123_index() */ + MPG123_OUT_OF_SYNC, /**< Lost track in bytestream and did not try to resync. */ + MPG123_RESYNC_FAIL /**< Resync failed to find valid MPEG data. */ }; /** Return a string describing that error errcode means. */ diff --git a/src/libmpg123/parse.c b/src/libmpg123/parse.c index b3900b22..a4814220 100644 --- a/src/libmpg123/parse.c +++ b/src/libmpg123/parse.c @@ -78,8 +78,6 @@ const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 #endif #define TRACK_MAX_FRAMES ULONG_MAX/4/1152 -#define RESYNC_LIMIT 1024 - #ifdef VARMODESUPPORT /* * This is a dirty hack! It might burn your PC and kill your cat! @@ -600,7 +598,8 @@ init_resync: if(give_note && NOQUIET && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n"); if (!(fr->p.flags & MPG123_NO_RESYNC) || fr->do_recover) { - int try = 0; + long try = 0; + long limit = fr->p.resync_limit; /* TODO: make this more robust, I'd like to cat two mp3 fragments together (in a dirty way) and still have mpg123 beign able to decode all it somehow. */ if(give_note && NOQUIET) fprintf(stderr, "Note: Trying to resync...\n"); /* Read more bytes until we find something that looks @@ -609,7 +608,14 @@ init_resync: track within a short time (and hopefully without too much distortion in the audio output). */ do { - if((ret=fr->rd->head_shift(fr,&newhead)) <= 0){ debug("need more?"); goto read_frame_bad; } + ++try; + if(limit >= 0 && try >= limit) break; + if((ret=fr->rd->head_shift(fr,&newhead)) <= 0) + { + debug("need more?"); + if(give_note && NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n"); + goto read_frame_bad; + } debug3("resync try %i at 0x%lx, got newhead 0x%08lx", try, (unsigned long)fr->rd->tell(fr), newhead); if (!fr->oldhead) { @@ -620,24 +626,25 @@ init_resync: /* Michael's new resync routine seems to work better with the one frame readahead (and some input buffering?) */ } while ( - ++try < RESYNC_LIMIT - && (newhead & HDRCMPMASK) != (fr->oldhead & HDRCMPMASK) + (newhead & HDRCMPMASK) != (fr->oldhead & HDRCMPMASK) && (newhead & HDRCMPMASK) != (fr->firsthead & HDRCMPMASK) ); /* too many false positives }while (!(head_check(newhead) && decode_header(fr, newhead))); */ - if(try == RESYNC_LIMIT) + if(limit >= 0 && try >= limit) { - if(NOQUIET) error("giving up resync - your stream is not nice... perhaps an improved routine could catch up"); - return 0; + if(NOQUIET) error1("Giving up resync after %li bytes - your stream is not nice... (maybe increasing resync limit could help).", try); + fr->err = MPG123_RESYNC_FAIL; + return READER_ERROR; } - if(give_note && NOQUIET) fprintf (stderr, "Note: Skipped %d bytes in input.\n", try); + if(give_note && NOQUIET) fprintf (stderr, "Note: Skipped %li bytes in input.\n", try); } else { if(NOQUIET) error("not attempting to resync..."); - return (0); + fr->err = MPG123_OUT_OF_SYNC; + return READER_ERROR; } } diff --git a/src/mpg123.c b/src/mpg123.c index 57d80d01..2408b417 100644 --- a/src/mpg123.c +++ b/src/mpg123.c @@ -102,6 +102,7 @@ struct parameter param = { ,0 /* flags */ ,0 /* force_rate */ ,1 /* ICY */ + ,1024 /* resync_limit */ }; int utf8env = 0; @@ -420,6 +421,7 @@ topt opts[] = { {0, "loop", GLO_ARG | GLO_LONG, 0, ¶m.loop, 0}, {'i', "index", GLO_INT, 0, ¶m.index, 1}, {'D', "delay", GLO_ARG | GLO_INT, 0, ¶m.delay, 0}, + {0, "resync-limit", GLO_ARG | GLO_LONG, 0, ¶m.resync_limit, 0}, {0, 0, 0, 0, 0, 0} }; @@ -636,6 +638,7 @@ int main(int argc, char *argv[]) #endif mpg123_getpar(mp, MPG123_FLAGS, &parr, NULL); param.flags = (int) parr; + mpg123_getpar(mp, MPG123_RESYNC_LIMIT, ¶m.resync_limit, NULL); #ifdef OS2 _wildcard(&argc,&argv); @@ -716,6 +719,7 @@ int main(int argc, char *argv[]) && MPG123_OK == (result = mpg123_par(mp, MPG123_DOWNSPEED, param.halfspeed, 0)) && MPG123_OK == (result = mpg123_par(mp, MPG123_UPSPEED, param.doublespeed, 0)) && MPG123_OK == (result = mpg123_par(mp, MPG123_ICY_INTERVAL, 0, 0)) + && MPG123_OK == (result = mpg123_par(mp, MPG123_RESYNC_LIMIT, param.resync_limit, 0)) #ifndef WIN32 && MPG123_OK == (result = mpg123_par(mp, MPG123_TIMEOUT, param.timeout, 0)) #endif @@ -1077,6 +1081,7 @@ static void long_usage(int err) fprintf(o," -Z --random full random play\n"); fprintf(o," --no-icy-meta Do not accept ICY meta data\n"); fprintf(o," -i --index index / scan through the track before playback\n"); + fprintf(o," --resync-limit Set number of bytes to search for valid MPEG data; <0 means search whole stream.\n"); fprintf(o,"\noutput/processing options\n\n"); fprintf(o," -o --output select audio output module\n"); fprintf(o," --list-modules list the available modules\n"); diff --git a/src/mpg123app.h b/src/mpg123app.h index 0582e84c..d3b4811c 100644 --- a/src/mpg123app.h +++ b/src/mpg123app.h @@ -140,6 +140,7 @@ struct parameter int flags; long force_rate; int talk_icy; + long resync_limit; }; extern char *equalfile;