Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1905 → Rev 3960

/programs/develop/libraries/libmpg123/parse.c
1,7 → 1,7
/*
parse: spawned from common; clustering around stream/frame parsing
 
copyright ?-2009 by the mpg123 project - free software under the terms of the LGPL 2.1
copyright ?-2012 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written by Michael Hipp & Thomas Orgis
*/
13,6 → 13,10
 
#include "getbits.h"
 
#if defined (WANT_WIN32_SOCKETS)
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
 
/* a limit for number of frames in a track; beyond that unsigned long may not be enough to hold byte addresses */
#ifdef HAVE_LIMITS_H
24,44 → 28,24
#endif
#define TRACK_MAX_FRAMES ULONG_MAX/4/1152
 
#include "mpeghead.h"
 
#include "debug.h"
 
#define bsbufid(fr) (fr)->bsbuf==(fr)->bsspace[0] ? 0 : ((fr)->bsbuf==fr->bsspace[1] ? 1 : ( (fr)->bsbuf==(fr)->bsspace[0]+512 ? 2 : ((fr)->bsbuf==fr->bsspace[1]+512 ? 3 : -1) ) )
 
/*
AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
A: sync
B: mpeg version
C: layer
D: CRC
E: bitrate
F:sampling rate
G: padding
H: private
I: channel mode
J: mode ext
K: copyright
L: original
M: emphasis
/* PARSE_GOOD and PARSE_BAD have to be 1 and 0 (TRUE and FALSE), others can vary. */
enum parse_codes
{
PARSE_MORE = MPG123_NEED_MORE
,PARSE_ERR = MPG123_ERR
,PARSE_END = 10 /* No more audio data to find. */
,PARSE_GOOD = 1 /* Everything's fine. */
,PARSE_BAD = 0 /* Not fine (invalid data). */
,PARSE_RESYNC = 2 /* Header not good, go into resync. */
,PARSE_AGAIN = 3 /* Really start over, throw away and read a new header, again. */
};
 
old compare mask 0xfffffd00:
11111111 11111111 11111101 00000000
 
means: everything must match excluding padding and channel mode, ext mode, ...
But a vbr stream's headers will differ in bitrate!
We are already strict in allowing only frames of same type in stream, we should at least watch out for VBR while being strict.
 
So a better mask is:
11111111 11111111 00001101 00000000
 
Even more, I'll allow varying crc bit.
11111111 11111110 00001101 00000000
 
(still unsure about this private bit)
*/
#define HDRCMPMASK 0xfffe0d00
#define HDRSAMPMASK 0xc00 /* 1100 00000000, FF bits (sample rate) */
 
/* bitrates for [mpeg1/2][layer] */
static const int tabsel_123[2][3][16] =
{
77,17 → 61,15
}
};
 
const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
static const long freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
 
static int decode_header(mpg123_handle *fr,unsigned long newhead);
static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count);
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount);
static int do_readahead(mpg123_handle *fr, unsigned long newhead);
static int wetwork(mpg123_handle *fr, unsigned long *newheadp);
 
int read_frame_init(mpg123_handle* fr)
{
if(frame_reset(fr) != 0) return -1;
return 0;
}
 
/* These two are to be replaced by one function that gives all the frame parameters (for outsiders).*/
/* Those functions are unsafe regarding bad arguments (inside the mpg123_handle), but just returning anything would also be unsafe, the caller code has to be trusted. */
 
int frame_bitrate(mpg123_handle *fr)
{
99,24 → 81,21
return freqs[fr->sampling_frequency];
}
 
#define free_format_header(head) ( ((head & 0xffe00000) == 0xffe00000) && ((head>>17)&3) && (((head>>12)&0xf) == 0x0) && (((head>>10)&0x3) != 0x3 ))
 
/* compiler is smart enought to inline this one or should I really do it as macro...? */
int head_check(unsigned long head)
static int head_check(unsigned long head)
{
if
(
/* first 11 bits are set to 1 for frame sync */
((head & 0xffe00000) != 0xffe00000)
((head & HDR_SYNC) != HDR_SYNC)
||
/* layer: 01,10,11 is 1,2,3; 00 is reserved */
(!((head>>17)&3))
(!(HDR_LAYER_VAL(head)))
||
/* 1111 means bad bitrate */
(((head>>12)&0xf) == 0xf)
(HDR_BITRATE_VAL(head) == 0xf)
||
/* sampling freq: 11 is reserved */
(((head>>10)&0x3) == 0x3 )
(HDR_SAMPLERATE_VAL(head) == 0x3)
/* here used to be a mpeg 2.5 check... re-enabled 2.5 decoding due to lack of evidence that it is really not good */
)
{
141,11 → 120,10
I hope that ensuring all zeros until tag start is enough.
*/
int lame_offset = (fr->stereo == 2) ? (fr->lsf ? 17 : 32 ) : (fr->lsf ? 9 : 17);
/* At least skip the decoder delay. */
#ifdef GAPLESS
if(fr->begin_s == 0) frame_gapless_init(fr, GAPLESS_DELAY, 0);
#endif
 
if(fr->p.flags & MPG123_IGNORE_INFOFRAME) return 0;
 
/* Note: CRC or not, that does not matter here. */
if(fr->framesize >= 120+lame_offset) /* traditional Xing header is 120 bytes */
{
int i;
195,28 → 173,34
debug1("Xing: flags 0x%08lx", xing_flags);
if(xing_flags & 1) /* frames */
{
/*
In theory, one should use that value for skipping...
When I know the exact number of samples I could simply count in flush_output,
but that's problematic with seeking and such.
I still miss the real solution for detecting the end.
*/
if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
{
if(VERBOSE3)
fprintf(stderr, "Note: Ignoring Xing frames because of MPG123_IGNORE_STREAMLENGTH\n");
}
else
{
fr->track_frames = (off_t) make_long(fr->bsbuf, lame_offset);
if(fr->track_frames > TRACK_MAX_FRAMES) fr->track_frames = 0; /* endless stream? */
#ifdef GAPLESS
/* if no further info there, remove/add at least the decoder delay */
/* All or nothing: Only if encoder delay/padding is known we'll cut samples for gapless. */
if(fr->p.flags & MPG123_GAPLESS)
{
off_t length = fr->track_frames * spf(fr);
if(length > 1)
frame_gapless_init(fr, GAPLESS_DELAY, length+GAPLESS_DELAY);
}
frame_gapless_init(fr, fr->track_frames, 0, 0);
#endif
if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu frames\n", (long unsigned)fr->track_frames);
}
 
lame_offset += 4;
}
if(xing_flags & 0x2) /* bytes */
{
if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
{
if(VERBOSE3)
fprintf(stderr, "Note: Ignoring Xing bytes because of MPG123_IGNORE_STREAMLENGTH\n");
}
else
{
unsigned long xing_bytes = make_long(fr->bsbuf, lame_offset); /* We assume that this is the _total_ size of the file, including Xing frame ... and ID3 frames...
It's not that clearly documented... */
if(fr->rdat.filelen < 1)
238,6 → 222,7
 
if(VERBOSE3)
fprintf(stderr, "Note: Xing: %lu bytes\n", (long unsigned)xing_bytes);
}
 
lame_offset += 4;
}
256,7 → 241,6
lame_offset += 4;
}
/* I guess that either 0 or LAME extra data follows */
/* there may this crc16 be floating around... (?) */
if(fr->bsbuf[lame_offset] != 0)
{
unsigned char lame_vbr;
269,9 → 253,24
if(VERBOSE3) fprintf(stderr, "Note: Info: Encoder: %s\n", nb);
if(!strncmp("LAME", nb, 4))
{
/* Lame versions before 3.95.1 used 83 dB reference level, later versions 89 dB.
We stick with 89 dB as being "normal", adding 6 dB. */
unsigned int major, minor;
char rest[6];
rest[0] = 0;
if(sscanf(nb+4, "%u.%u%s", &major, &minor, rest) >= 2)
{
debug3("LAME: %u/%u/%s", major, minor, rest);
/* We cannot detect LAME 3.95 reliably (same version string as 3.95.1), so this is a blind spot.
Everything < 3.95 is safe, though. */
if(major < 3 || (major == 3 && minor < 95)) /* || (major == 3 && minor == 95 && rest[0] == 0)) */
{
gain_offset = 6;
debug("TODO: finish lame detetcion...");
if(VERBOSE3) fprintf(stderr, "Note: Info: Old LAME detected, using ReplayGain preamp of %f dB.\n", gain_offset);
}
}
else if(VERBOSE3) fprintf(stderr, "Note: Info: Cannot determine LAME version.\n");
}
lame_offset += 9;
/* the 4 big bits are tag revision, the small bits vbr method */
lame_vbr = fr->bsbuf[lame_offset] & 15;
330,7 → 329,10
else if(gt == 2) gt = 1; /* audiophile */
else continue;
/* get the 9 bits into a number, divide by 10, multiply sign... happy bit banging */
replay_gain[0] = (float) ((fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1) * (make_short(fr->bsbuf, lame_offset) & 0x1f);
replay_gain[gt] = (float) ((fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1) * (make_short(fr->bsbuf, lame_offset) & 0x1ff);
/* If this is an automatic value from LAME (or whatever), the automatic gain offset applies.
If a user or whoever set the value, do not touch it! 011 is automatic origin. */
if(origin == 3) replay_gain[gt] += gain_offset;
}
lame_offset += 2;
}
363,13 → 365,9
#ifdef GAPLESS
if(fr->p.flags & MPG123_GAPLESS)
{
off_t length = fr->track_frames * spf(fr);
off_t skipbegin = GAPLESS_DELAY + ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4));
off_t skipend = -GAPLESS_DELAY + (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff);
debug3("preparing gapless mode for layer3: length %lu, skipbegin %lu, skipend %lu",
(long unsigned)length, (long unsigned)skipbegin, (long unsigned)skipend);
if(length > 1)
frame_gapless_init(fr, skipbegin, (skipend < length) ? length-skipend : length);
off_t skipbegin = ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4));
off_t skipend = (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff);
frame_gapless_init(fr, fr->track_frames, skipbegin, skipend);
}
#endif
}
386,24 → 384,29
/* Just tell if the header is some mono. */
static int header_mono(unsigned long newhead)
{
return ((newhead>>6)&0x3) == MPG_MD_MONO ? TRUE : FALSE;
return HDR_CHANNEL_VAL(newhead) == MPG_MD_MONO ? TRUE : FALSE;
}
 
/*
That's a big one: read the next frame. 1 is success, <= 0 is some error
Special error READER_MORE means: Please feed more data and try again.
*/
int read_frame(mpg123_handle *fr)
/* true if the two headers will work with the same decoding routines */
static int head_compatible(unsigned long fred, unsigned long bret)
{
/* TODO: rework this thing */
unsigned long newhead;
off_t framepos;
int ret;
/* stuff that needs resetting if complete frame reading fails */
int oldsize = fr->framesize;
int oldphase = fr->halfphase;
fr->fsizeold=fr->framesize; /* for Layer3 */
return ( (fred & HDR_CMPMASK) == (bret & HDR_CMPMASK)
&& header_mono(fred) == header_mono(bret) );
}
 
static void halfspeed_prepare(mpg123_handle *fr)
{
/* save for repetition */
if(fr->p.halfspeed && fr->lay == 3)
{
debug("halfspeed - reusing old bsbuf ");
memcpy (fr->ssave, fr->bsbuf, fr->ssize);
}
}
 
/* If this returns 1, the next frame is the repetition. */
static int halfspeed_do(mpg123_handle *fr)
{
/* Speed-down hack: Play it again, Sam (the frame, I mean). */
if (fr->p.halfspeed)
{
423,259 → 426,97
fr->halfphase = fr->p.halfspeed - 1;
}
}
 
read_again:
debug2("trying to get frame %li at 0x%lx", (long)fr->num+1, (unsigned long)fr->rd->tell(fr));
if((ret = fr->rd->head_read(fr,&newhead)) <= 0){ debug("need more?"); goto read_frame_bad;}
 
init_resync:
 
fr->header_change = 2; /* output format change is possible... */
if(fr->oldhead) /* check a following header for change */
{
if(fr->oldhead == newhead) fr->header_change = 0;
else
/* If they have the same sample rate. Note that only is _not_ the case for the first header, as we enforce sample rate match for following frames.
So, during one stream, only change of stereoness is possible and indicated by header_change == 2. */
if((fr->oldhead & HDRSAMPMASK) == (newhead & HDRSAMPMASK))
{
/* Now if both channel modes are mono or both stereo, it's no big deal. */
if( header_mono(fr->oldhead) == header_mono(newhead))
fr->header_change = 1;
return 0;
}
}
 
#ifdef SKIP_JUNK
/* watch out for junk/tags on beginning of stream by invalid header */
if(!fr->firsthead && !head_check(newhead)) {
int i;
 
/* check for id3v2; first three bytes (of 4) are "ID3" */
if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
{
int id3ret = 0;
id3ret = parse_new_id3(fr, newhead);
if (id3ret < 0){ debug("need more?"); ret = id3ret; goto read_frame_bad; }
#ifndef NO_ID3V2
else if(id3ret > 0){ debug("got ID3v2"); fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; }
else debug("no useful ID3v2");
#endif
 
fr->oldhead = 0;
goto read_again; /* Also in case of invalid ID3 tag (ret==0), try to get on track again. */
/*
Temporary macro until we got this worked out.
Idea is to filter out special return values that shall trigger direct jumps to end / resync / read again.
Particularily, the generic ret==PARSE_BAD==0 and ret==PARSE_GOOD==1 are not affected.
*/
#define JUMP_CONCLUSION(ret) \
{ \
if(ret < 0){ debug1("%s", ret == MPG123_NEED_MORE ? "need more" : "read error"); goto read_frame_bad; } \
else if(ret == PARSE_AGAIN) goto read_again; \
else if(ret == PARSE_RESYNC) goto init_resync; \
else if(ret == PARSE_END) goto read_frame_bad; \
}
else if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Junk at the beginning (0x%08lx)\n",newhead);
 
/* I even saw RIFF headers at the beginning of MPEG streams ;( */
if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F') {
if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr, "Note: Looks like a RIFF header.\n");
 
if((ret=fr->rd->head_read(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
 
while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a')
{
if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
}
if((ret=fr->rd->head_read(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
 
if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Skipped RIFF header!\n");
 
fr->oldhead = 0;
goto read_again;
}
/* unhandled junk... just continue search for a header */
/* step in byte steps through next 64K */
debug("searching for header...");
for(i=0;i<65536;i++) {
if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
/* if(head_check(newhead)) */
if(head_check(newhead) && decode_header(fr, newhead))
break;
}
if(i == 65536)
{
if(NOQUIET) error("Giving up searching valid MPEG header after 64K of junk.");
return 0;
}
else debug("hopefully found one...");
/*
* should we additionaly check, whether a new frame starts at
* the next expected position? (some kind of read ahead)
* We could implement this easily, at least for files.
That's a big one: read the next frame. 1 is success, <= 0 is some error
Special error READER_MORE means: Please feed more data and try again.
*/
}
#endif
 
/* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
/* for now, a spurious first free format header screws up here; need free format support for detecting false free format headers... */
if(!fr->firsthead && fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED) && head_check(newhead) && decode_header(fr, newhead))
int read_frame(mpg123_handle *fr)
{
unsigned long nexthead = 0;
int hd = 0;
off_t start = fr->rd->tell(fr);
debug2("doing ahead check with BPF %d at %li", fr->framesize+4, (long)start);
/* step framesize bytes forward and read next possible header*/
if((ret=fr->rd->skip_bytes(fr, fr->framesize))<0)
{
if(ret==READER_ERROR && NOQUIET) error("cannot seek!");
goto read_frame_bad;
}
hd = fr->rd->head_read(fr,&nexthead);
if(hd==MPG123_NEED_MORE){ debug("need more?"); ret = hd; goto read_frame_bad; }
if((ret=fr->rd->back_bytes(fr, fr->rd->tell(fr)-start))<0)
{
if(ret==READER_ERROR && NOQUIET) error("cannot seek!");
else debug("need more?");
goto read_frame_bad;
}
debug1("After fetching next header, at %li", (long)fr->rd->tell(fr));
if(!hd)
{
if(NOQUIET) warning("cannot read next header, a one-frame stream? Duh...");
}
else
{
debug2("does next header 0x%08lx match first 0x%08lx?", nexthead, newhead);
/* not allowing free format yet */
if(!head_check(nexthead) || (nexthead & HDRCMPMASK) != (newhead & HDRCMPMASK))
{
debug("No, the header was not valid, start from beginning...");
fr->oldhead = 0; /* start over */
/* try next byte for valid header */
if((ret=fr->rd->back_bytes(fr, 3))<0)
{
if(NOQUIET) error("cannot seek!");
else debug("need more?");
goto read_frame_bad;
}
goto read_again;
}
}
}
/* TODO: rework this thing */
int freeformat_count = 0;
unsigned long newhead;
off_t framepos;
int ret;
/* stuff that needs resetting if complete frame reading fails */
int oldsize = fr->framesize;
int oldphase = fr->halfphase;
 
/* why has this head check been avoided here before? */
if(!head_check(newhead))
{
/* and those ugly ID3 tags */
if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8))
{
fr->id3buf[0] = (unsigned char) ((newhead >> 24) & 0xff);
fr->id3buf[1] = (unsigned char) ((newhead >> 16) & 0xff);
fr->id3buf[2] = (unsigned char) ((newhead >> 8) & 0xff);
fr->id3buf[3] = (unsigned char) ( newhead & 0xff);
if((ret=fr->rd->fullread(fr,fr->id3buf+4,124)) < 0){ debug("need more?"); goto read_frame_bad; }
fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3;
fr->rdat.flags |= READER_ID3TAG; /* that marks id3v1 */
if (VERBOSE2) fprintf(stderr,"Note: Skipped ID3 Tag!\n");
goto read_again;
}
/* duplicated code from above! */
/* check for id3v2; first three bytes (of 4) are "ID3" */
if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
{
int id3length = 0;
id3length = parse_new_id3(fr, newhead);
if(id3length < 0){ debug("need more?"); ret = id3length; goto read_frame_bad; }
/* The counter for the search-first-header loop.
It is persistent outside the loop to prevent seemingly endless loops
when repeatedly headers are found that do not have valid followup headers. */
long headcount = 0;
 
fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3;
goto read_again;
}
else if(NOQUIET && fr->silent_resync == 0)
{
fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n",
newhead, (long unsigned int)fr->rd->tell(fr)-4);
}
fr->fsizeold=fr->framesize; /* for Layer3 */
 
if(NOQUIET && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n");
/* Do resync if not forbidden by flag.
I used to have a check for not-icy-meta here, but concluded that the desync issues came from a reader bug, not the stream. */
if( !(fr->p.flags & MPG123_NO_RESYNC) )
{
long try = 0;
long limit = fr->p.resync_limit;
if(halfspeed_do(fr) == 1) return 1;
/* If a resync is needed the bitreservoir of previous frames is no longer valid */
fr->bitreservoir = 0;
read_again:
/* In case we are looping to find a valid frame, discard any buffered data before the current position.
This is essential to prevent endless looping, always going back to the beginning when feeder buffer is exhausted. */
if(fr->rd->forget != NULL) fr->rd->forget(fr);
 
/* 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(NOQUIET && fr->silent_resync == 0) fprintf(stderr, "Note: Trying to resync...\n");
/* Read more bytes until we find something that looks
reasonably like a valid header. This is not a
perfect strategy, but it should get us back on the
track within a short time (and hopefully without
too much distortion in the audio output). */
do
{
++try;
if(limit >= 0 && try >= limit) break;
debug2("trying to get frame %"OFF_P" at %"OFF_P, (off_p)fr->num+1, (off_p)fr->rd->tell(fr));
if((ret = fr->rd->head_read(fr,&newhead)) <= 0){ debug1("need more? (%i)", ret); goto read_frame_bad;}
 
if((ret=fr->rd->head_shift(fr,&newhead)) <= 0)
init_resync:
 
fr->header_change = 2; /* output format change is possible... */
if(fr->oldhead) /* check a following header for change */
{
debug("need more?");
if(NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n");
 
goto read_frame_bad;
if(fr->oldhead == newhead) fr->header_change = 0;
else
/* Headers that match in this test behave the same for the outside world.
namely: same decoding routines, same amount of decoded data. */
if(head_compatible(fr->oldhead, newhead))
fr->header_change = 1;
}
if(VERBOSE3) debug3("resync try %li at 0x%lx, got newhead 0x%08lx", try, (unsigned long)fr->rd->tell(fr), newhead);
 
if(!fr->oldhead)
#ifdef SKIP_JUNK
if(!fr->firsthead && !head_check(newhead))
{
debug("going to init_resync...");
goto init_resync; /* "considered harmful", eh? */
ret = skip_junk(fr, &newhead, &headcount);
JUMP_CONCLUSION(ret);
}
/* we should perhaps collect a list of valid headers that occured in file... there can be more */
/* Michael's new resync routine seems to work better with the one frame readahead (and some input buffering?) */
} while
(
!head_check(newhead) /* Simply check for any valid header... we have the readahead to get it straight now(?) */
/* (newhead & HDRCMPMASK) != (fr->oldhead & HDRCMPMASK)
&& (newhead & HDRCMPMASK) != (fr->firsthead & HDRCMPMASK)*/
);
/* too many false positives
}while (!(head_check(newhead) && decode_header(fr, newhead))); */
if(NOQUIET && fr->silent_resync == 0) fprintf (stderr, "Note: Skipped %li bytes in input.\n", try);
#endif
 
if(limit >= 0 && try >= limit)
{
if(NOQUIET)
error1("Giving up resync after %li bytes - your stream is not nice... (maybe increasing resync limit could help).", try);
ret = head_check(newhead);
if(ret) ret = decode_header(fr, newhead, &freeformat_count);
 
fr->err = MPG123_RESYNC_FAIL;
return READER_ERROR;
JUMP_CONCLUSION(ret); /* That only continues for ret == PARSE_BAD or PARSE_GOOD. */
if(ret == PARSE_BAD)
{ /* Header was not good. */
ret = wetwork(fr, &newhead); /* Messy stuff, handle junk, resync ... */
JUMP_CONCLUSION(ret);
/* Normally, we jumped already. If for some reason everything's fine to continue, do continue. */
if(ret != PARSE_GOOD) goto read_frame_bad;
}
else
{
debug1("Found valid header 0x%lx... unsetting firsthead to reinit stream.", newhead);
fr->firsthead = 0;
goto init_resync;
}
}
else
{
if(NOQUIET) error("not attempting to resync...");
 
fr->err = MPG123_OUT_OF_SYNC;
return READER_ERROR;
}
}
 
if (!fr->firsthead)
{
if(!decode_header(fr,newhead))
{
if(NOQUIET) error("decode header failed before first valid one, going to read again");
 
goto read_again;
ret = do_readahead(fr, newhead);
/* readahead can fail mit NEED_MORE, in which case we must also make the just read header available again for next go */
if(ret < 0) fr->rd->back_bytes(fr, 4);
JUMP_CONCLUSION(ret);
}
}
else
if(!decode_header(fr,newhead))
{
if(NOQUIET) error("decode header failed - goto resync");
/* return 0; */
goto init_resync;
}
 
/* Now we should have our valid header and proceed to reading the frame. */
 
/* if filepos is invalid, so is framepos */
framepos = fr->rd->tell(fr) - 4;
/* flip/init buffer for Layer 3 */
727,20 → 568,31
fr->mean_framesize = ((fr->mean_frames-1)*fr->mean_framesize+compute_bpf(fr)) / fr->mean_frames ;
}
++fr->num; /* 0 for first frame! */
debug4("Frame %li %08lx %i, next filepos=0x%lx",
(long)fr->num, newhead, fr->framesize, (long unsigned)fr->rd->tell(fr));
/* save for repetition */
if(fr->p.halfspeed && fr->lay == 3)
debug4("Frame %"OFF_P" %08lx %i, next filepos=%"OFF_P,
(off_p)fr->num, newhead, fr->framesize, (off_p)fr->rd->tell(fr));
if(!(fr->state_flags & FRAME_FRANKENSTEIN) && (
(fr->track_frames > 0 && fr->num >= fr->track_frames)
#ifdef GAPLESS
|| (fr->gapless_frames > 0 && fr->num >= fr->gapless_frames)
#endif
))
{
debug("halfspeed - reusing old bsbuf ");
memcpy (fr->ssave, fr->bsbuf, fr->ssize);
fr->state_flags |= FRAME_FRANKENSTEIN;
if(NOQUIET) fprintf(stderr, "\nWarning: Encountered more data after announced end of track (frame %"OFF_P"/%"OFF_P"). Frankenstein!\n", (off_p)fr->num,
#ifdef GAPLESS
fr->gapless_frames > 0 ? (off_p)fr->gapless_frames :
#endif
(off_p)fr->track_frames);
}
 
halfspeed_prepare(fr);
 
/* index the position */
fr->input_offset = framepos;
#ifdef FRAME_INDEX
/* Keep track of true frame positions in our frame index.
but only do so when we are sure that the frame number is accurate... */
if(fr->accurate && FI_NEXT(fr->index, fr->num))
if((fr->state_flags & FRAME_ACCURATE) && FI_NEXT(fr->index, fr->num))
fi_add(&fr->index, framepos);
#endif
 
751,12 → 603,19
fr->to_decode = fr->to_ignore = TRUE;
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */
 
fr->oldhead = newhead;
 
return 1;
read_frame_bad:
/* Also if we searched for valid data in vein, we can forget skipped data.
Otherwise, the feeder would hold every dead old byte in memory until the first valid frame! */
if(fr->rd->forget != NULL) fr->rd->forget(fr);
 
fr->silent_resync = 0;
if(fr->err == MPG123_OK) fr->err = MPG123_ERR_READER;
fr->framesize = oldsize;
fr->halfphase = oldphase;
/* That return code might be inherited from some feeder action, or reader error. */
return ret;
}
 
763,9 → 622,12
 
/*
* read ahead and find the next MPEG header, to guess framesize
* return value: guessed framesize
* return value: success code
* PARSE_GOOD: found a valid frame size (stored in the handle).
* <0: error codes, possibly from feeder buffer (NEED_MORE)
* PARSE_BAD: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...)
*/
static long guess_freeformat_framesize(mpg123_handle *fr)
static int guess_freeformat_framesize(mpg123_handle *fr)
{
long i;
int ret;
773,47 → 635,27
if(!(fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED)))
{
if(NOQUIET) error("Cannot look for freeformat frame size with non-seekable and non-buffered stream!");
return -1;
 
return PARSE_BAD;
}
/* FIXME: We need proper handling/passing of MPG123_NEED_MORE! */
if((ret=fr->rd->head_read(fr,&head))<=0)
return -1;
return ret;
 
/* We are already 4 bytes into it */
for(i=4;i<65536;i++) {
if((ret=fr->rd->head_shift(fr,&head))<=0)
for(i=4;i<MAXFRAMESIZE+4;i++)
{
return -1;
}
if(head_check(head))
{
int sampling_frequency,mpeg25,lsf;
if((ret=fr->rd->head_shift(fr,&head))<=0) return ret;
if(head & (1<<20))
/* No head_check needed, the mask contains all relevant bits. */
if((head & HDR_SAMEMASK) == (fr->oldhead & HDR_SAMEMASK))
{
lsf = (head & (1<<19)) ? 0x0 : 0x1;
mpeg25 = 0;
}
else
{
lsf = 1;
mpeg25 = 1;
}
if(mpeg25)
sampling_frequency = 6 + ((head>>10)&0x3);
else
sampling_frequency = ((head>>10)&0x3) + (lsf*3);
if((lsf==fr->lsf) && (mpeg25==fr->mpeg25) && (sampling_frequency == fr->sampling_frequency))
{
fr->rd->back_bytes(fr,i+1);
return i-3;
fr->framesize = i-3;
return PARSE_GOOD; /* Success! */
}
}
}
fr->rd->back_bytes(fr,i);
return -1;
return PARSE_BAD;
}
 
 
820,18 → 662,23
/*
* decode a header and write the information
* into the frame structure
* Return values are compatible with those of read_frame, namely:
* 1: success
* 0: no valid header
* <0: some error
* You are required to do a head_check() before calling!
*/
static int decode_header(mpg123_handle *fr,unsigned long newhead)
static int decode_header(mpg123_handle *fr,unsigned long newhead, int *freeformat_count)
{
#ifdef DEBUG /* Do not waste cycles checking the header twice all the time. */
if(!head_check(newhead))
{
if(NOQUIET) error("tried to decode obviously invalid header");
 
return 0;
error1("trying to decode obviously invalid header 0x%08lx", newhead);
}
if( newhead & (1<<20) )
#endif
if(HDR_VERSION_VAL(newhead) & 0x2)
{
fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
fr->lsf = (HDR_VERSION_VAL(newhead) & 0x1) ? 0 : 1;
fr->mpeg25 = 0;
}
else
841,59 → 688,64
}
 
if( (fr->p.flags & MPG123_NO_RESYNC) || !fr->oldhead
|| (((fr->oldhead>>19)&0x3) ^ ((newhead>>19)&0x3)) )
|| (HDR_VERSION_VAL(fr->oldhead) != HDR_VERSION_VAL(newhead)) )
{
/* If "tryresync" is false, assume that certain
parameters do not change within the stream!
Force an update if lsf or mpeg25 settings
have changed. */
fr->lay = 4-((newhead>>17)&3);
if( ((newhead>>10)&0x3) == 0x3)
{
if(NOQUIET) error("Stream error");
 
return 0; /* exit() here really is too much, isn't it? */
}
fr->lay = 4 - HDR_LAYER_VAL(newhead);
if(fr->mpeg25)
fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
fr->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead);
else
fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
fr->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fr->lsf*3);
}
 
#ifdef DEBUG
if((((newhead>>16)&0x1)^0x1) != fr->error_protection) debug("changed crc bit!");
/* seen a file where this varies (old lame tag without crc, track with crc) */
if((HDR_CRC_VAL(newhead)^0x1) != fr->error_protection) debug("changed crc bit!");
#endif
fr->error_protection = ((newhead>>16)&0x1)^0x1; /* seen a file where this varies (old lame tag without crc, track with crc) */
fr->bitrate_index = ((newhead>>12)&0xf);
fr->padding = ((newhead>>9)&0x1);
fr->extension = ((newhead>>8)&0x1);
fr->mode = ((newhead>>6)&0x3);
fr->mode_ext = ((newhead>>4)&0x3);
fr->copyright = ((newhead>>3)&0x1);
fr->original = ((newhead>>2)&0x1);
fr->emphasis = newhead & 0x3;
fr->freeformat = free_format_header(newhead);
fr->error_protection = HDR_CRC_VAL(newhead)^0x1;
fr->bitrate_index = HDR_BITRATE_VAL(newhead);
fr->padding = HDR_PADDING_VAL(newhead);
fr->extension = HDR_PRIVATE_VAL(newhead);
fr->mode = HDR_CHANNEL_VAL(newhead);
fr->mode_ext = HDR_CHANEX_VAL(newhead);
fr->copyright = HDR_COPYRIGHT_VAL(newhead);
fr->original = HDR_ORIGINAL_VAL(newhead);
fr->emphasis = HDR_EMPHASIS_VAL(newhead);
fr->freeformat = !(newhead & HDR_BITRATE);
 
fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
 
fr->oldhead = newhead;
/* we can't use tabsel_123 for freeformat, so trying to guess framesize... */
/* FIXME: We need proper handling/passing of MPG123_NEED_MORE! */
if(fr->freeformat)
{
/* when we first encounter the frame with freeformat, guess framesize */
if(fr->freeformat_framesize < 0)
{
fr->framesize = guess_freeformat_framesize(fr);
if(fr->framesize > 0)
int ret;
*freeformat_count += 1;
if(*freeformat_count > 5)
{
if(VERBOSE3) error("You fooled me too often. Refusing to guess free format frame size _again_.");
return PARSE_BAD;
}
ret = guess_freeformat_framesize(fr);
if(ret == PARSE_GOOD)
{
fr->freeformat_framesize = fr->framesize - fr->padding;
if(VERBOSE2)
fprintf(stderr, "Note: free format frame size %li\n", fr->freeformat_framesize);
}
else
{
error("encountered free format header, but failed to guess framesize");
return 0;
if(ret == MPG123_NEED_MORE)
debug("Need more data to guess free format frame size.");
else if(VERBOSE3)
error("Encountered free format header, but failed to guess frame size.");
 
return ret;
}
}
/* freeformat should be CBR, so the same framesize can be used at the 2nd reading or later */
950,15 → 802,15
default:
if(NOQUIET) error1("Layer type %i not supported in this build!", fr->lay);
 
return 0;
return PARSE_BAD;
}
if (fr->framesize > MAXFRAMESIZE)
{
if(NOQUIET) error1("Frame size too big: %d", fr->framesize+4-fr->padding);
 
return (0);
return PARSE_BAD;
}
return 1;
return PARSE_GOOD;
}
 
void set_pointer(mpg123_handle *fr, long backstep)
996,6 → 848,13
return bpf;
}
 
int attribute_align_arg mpg123_spf(mpg123_handle *mh)
{
if(mh == NULL) return MPG123_ERR;
 
return spf(mh);
}
 
double attribute_align_arg mpg123_tpf(mpg123_handle *fr)
{
static int bs[4] = { 0,384,1152,1152 };
1089,3 → 948,236
tpf = mpg123_tpf(fr);
return (int) (no*tpf);
}
 
/* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
static int do_readahead(mpg123_handle *fr, unsigned long newhead)
{
unsigned long nexthead = 0;
int hd = 0;
off_t start, oret;
int ret;
 
if( ! (!fr->firsthead && fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED)) )
return PARSE_GOOD;
 
start = fr->rd->tell(fr);
 
debug2("doing ahead check with BPF %d at %"OFF_P, fr->framesize+4, (off_p)start);
/* step framesize bytes forward and read next possible header*/
if((oret=fr->rd->skip_bytes(fr, fr->framesize))<0)
{
if(oret==READER_ERROR && NOQUIET) error("cannot seek!");
 
return oret == MPG123_NEED_MORE ? PARSE_MORE : PARSE_ERR;
}
 
/* Read header, seek back. */
hd = fr->rd->head_read(fr,&nexthead);
if( fr->rd->back_bytes(fr, fr->rd->tell(fr)-start) < 0 )
{
if(NOQUIET) error("Cannot seek back!");
 
return PARSE_ERR;
}
if(hd == MPG123_NEED_MORE) return PARSE_MORE;
 
debug1("After fetching next header, at %"OFF_P, (off_p)fr->rd->tell(fr));
if(!hd)
{
if(NOQUIET) warning("Cannot read next header, a one-frame stream? Duh...");
return PARSE_END;
}
 
debug2("does next header 0x%08lx match first 0x%08lx?", nexthead, newhead);
if(!head_check(nexthead) || !head_compatible(newhead, nexthead))
{
debug("No, the header was not valid, start from beginning...");
fr->oldhead = 0; /* start over */
/* try next byte for valid header */
if((ret=fr->rd->back_bytes(fr, 3))<0)
{
if(NOQUIET) error("Cannot seek 3 bytes back!");
 
return PARSE_ERR;
}
return PARSE_AGAIN;
}
else return PARSE_GOOD;
}
 
static int handle_id3v2(mpg123_handle *fr, unsigned long newhead)
{
int ret;
fr->oldhead = 0; /* Think about that. Used to be present only for skipping of junk, not resync-style wetwork. */
ret = parse_new_id3(fr, newhead);
if (ret < 0) return ret;
#ifndef NO_ID3V2
else if(ret > 0){ debug("got ID3v2"); fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; }
else debug("no useful ID3v2");
#endif
return PARSE_AGAIN;
}
 
/* watch out for junk/tags on beginning of stream by invalid header */
static int skip_junk(mpg123_handle *fr, unsigned long *newheadp, long *headcount)
{
int ret;
int freeformat_count = 0;
long limit = 65536;
unsigned long newhead = *newheadp;
/* check for id3v2; first three bytes (of 4) are "ID3" */
if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
{
return handle_id3v2(fr, newhead);
}
else if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Junk at the beginning (0x%08lx)\n",newhead);
 
/* I even saw RIFF headers at the beginning of MPEG streams ;( */
if(newhead == ('R'<<24)+('I'<<16)+('F'<<8)+'F')
{
if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr, "Note: Looks like a RIFF header.\n");
 
if((ret=fr->rd->head_read(fr,&newhead))<=0) return ret;
 
while(newhead != ('d'<<24)+('a'<<16)+('t'<<8)+'a')
{
if((ret=fr->rd->head_shift(fr,&newhead))<=0) return ret;
}
if((ret=fr->rd->head_read(fr,&newhead))<=0) return ret;
 
if(VERBOSE2 && fr->silent_resync == 0) fprintf(stderr,"Note: Skipped RIFF header!\n");
 
fr->oldhead = 0;
*newheadp = newhead;
return PARSE_AGAIN;
}
 
/*
Unhandled junk... just continue search for a header, stepping in single bytes through next 64K.
This is rather identical to the resync loop.
*/
debug("searching for header...");
*newheadp = 0; /* Invalidate the external value. */
ret = 0; /* We will check the value after the loop. */
 
/* We prepare for at least the 64K bytes as usual, unless
user explicitly wanted more (even infinity). Never less. */
if(fr->p.resync_limit < 0 || fr->p.resync_limit > limit)
limit = fr->p.resync_limit;
 
do
{
++(*headcount);
if(limit >= 0 && *headcount >= limit) break;
 
if((ret=fr->rd->head_shift(fr,&newhead))<=0) return ret;
 
if(head_check(newhead) && (ret=decode_header(fr, newhead, &freeformat_count))) break;
} while(1);
if(ret<0) return ret;
 
if(limit >= 0 && *headcount >= limit)
{
if(NOQUIET) error1("Giving up searching valid MPEG header after %li bytes of junk.", *headcount);
return PARSE_END;
}
else debug1("hopefully found one at %"OFF_P, (off_p)fr->rd->tell(fr));
 
/* If the new header ist good, it is already decoded. */
*newheadp = newhead;
return PARSE_GOOD;
}
 
/* The newhead is bad, so let's check if it is something special, otherwise just resync. */
static int wetwork(mpg123_handle *fr, unsigned long *newheadp)
{
int ret = PARSE_ERR;
unsigned long newhead = *newheadp;
*newheadp = 0;
 
/* Classic ID3 tags. Read, then start parsing again. */
if((newhead & 0xffffff00) == ('T'<<24)+('A'<<16)+('G'<<8))
{
fr->id3buf[0] = (unsigned char) ((newhead >> 24) & 0xff);
fr->id3buf[1] = (unsigned char) ((newhead >> 16) & 0xff);
fr->id3buf[2] = (unsigned char) ((newhead >> 8) & 0xff);
fr->id3buf[3] = (unsigned char) ( newhead & 0xff);
 
if((ret=fr->rd->fullread(fr,fr->id3buf+4,124)) < 0) return ret;
 
fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3;
fr->rdat.flags |= READER_ID3TAG; /* that marks id3v1 */
if(VERBOSE3) fprintf(stderr,"Note: Skipped ID3v1 tag.\n");
 
return PARSE_AGAIN;
}
/* This is similar to initial junk skipping code... */
/* Check for id3v2; first three bytes (of 4) are "ID3" */
if((newhead & (unsigned long) 0xffffff00) == (unsigned long) 0x49443300)
{
return handle_id3v2(fr, newhead);
}
else if(NOQUIET && fr->silent_resync == 0)
{
fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset %"OFF_P".\n",
newhead, (off_p)fr->rd->tell(fr)-4);
}
 
/* Now we got something bad at hand, try to recover. */
 
if(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) )
{
long try = 0;
long limit = fr->p.resync_limit;
 
/* If a resync is needed the bitreservoir of previous frames is no longer valid */
fr->bitreservoir = 0;
 
if(NOQUIET && fr->silent_resync == 0) fprintf(stderr, "Note: Trying to resync...\n");
 
do /* ... shift the header with additional single bytes until be found something that could be a header. */
{
++try;
if(limit >= 0 && try >= limit) break;
 
if((ret=fr->rd->head_shift(fr,&newhead)) <= 0)
{
*newheadp = newhead;
if(NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n");
 
return ret ? ret : PARSE_END;
}
if(VERBOSE3) debug3("resync try %li at %"OFF_P", got newhead 0x%08lx", try, (off_p)fr->rd->tell(fr), newhead);
} while(!head_check(newhead));
 
*newheadp = newhead;
if(NOQUIET && fr->silent_resync == 0) fprintf (stderr, "Note: Skipped %li bytes in input.\n", try);
 
/* Now we either got something that could be a header, or we gave up. */
if(limit >= 0 && try >= limit)
{
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 PARSE_ERR;
}
else
{
debug1("Found possibly valid header 0x%lx... unsetting firsthead to reinit stream.", newhead);
fr->firsthead = 0;
fr->oldhead = 0;
return PARSE_RESYNC;
}
}
else
{
if(NOQUIET) error("not attempting to resync...");
 
fr->err = MPG123_OUT_OF_SYNC;
return PARSE_ERR;
}
/* Control never goes here... we return before that. */
}