/*
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 ?-2014 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
*/
#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
-
- 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) */
+/* 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. */
+};
/* bitrates for [mpeg1/2][layer] */
static const int tabsel_123[2][3][16] =
}
};
-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);
/* 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)
{
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 */
)
{
}
}
+/* This is moderately sized buffers. Int offset is enough. */
+static unsigned long bit_read_long(unsigned char *buf, int *offset)
+{
+ unsigned long val = /* 32 bit value */
+ (((unsigned long) buf[*offset]) << 24)
+ | (((unsigned long) buf[*offset+1]) << 16)
+ | (((unsigned long) buf[*offset+2]) << 8)
+ | ((unsigned long) buf[*offset+3]);
+ *offset += 4;
+ return val;
+}
+
+static unsigned short bit_read_short(unsigned char *buf, int *offset)
+{
+ unsigned short val = /* 16 bit value */
+ (((unsigned short) buf[*offset] ) << 8)
+ | ((unsigned short) buf[*offset+1]);
+ *offset += 2;
+ return val;
+}
+
static int check_lame_tag(mpg123_handle *fr)
{
+ int i;
+ unsigned long xing_flags;
+ unsigned long long_tmp;
/*
going to look for Xing or Info at some position after the header
MPEG 1 MPEG 2/2.5 (LSF)
Stereo, Joint Stereo, Dual Channel 32 17
Mono 17 9
+ */
+ int lame_offset = (fr->stereo == 2)
+ ? (fr->lsf ? 17 : 32)
+ : (fr->lsf ? 9 : 17);
- Also, how to avoid false positives? I guess I should interpret more of the header to rule that out(?).
- I hope that ensuring all zeros until tag start is enough.
+ if(fr->p.flags & MPG123_IGNORE_INFOFRAME) goto check_lame_tag_no;
+
+ debug("do we have lame tag?");
+ /*
+ Note: CRC or not, that does not matter here.
+ But, there is any combination of Xing flags in the wild. There are headers
+ without the search index table! I cannot assume a reasonable minimal size
+ for the actual data, have to check if each byte of information is present.
+ But: 4 B Info/Xing + 4 B flags is bare minimum.
*/
- int lame_offset = (fr->stereo == 2) ? (fr->lsf ? 17 : 32 ) : (fr->lsf ? 9 : 17);
- /* At least skip the decoder delay. */
-#ifdef GAPLESS
- if(fr->p.flags & MPG123_GAPLESS)
+ if(fr->framesize < lame_offset+8) goto check_lame_tag_no;
+
+ /* only search for tag when all zero before it (apart from checksum) */
+ for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) goto check_lame_tag_no;
+
+ debug("possibly...");
+ if
+ (
+ (fr->bsbuf[lame_offset] == 'I')
+ && (fr->bsbuf[lame_offset+1] == 'n')
+ && (fr->bsbuf[lame_offset+2] == 'f')
+ && (fr->bsbuf[lame_offset+3] == 'o')
+ )
+ {
+ /* We still have to see what there is */
+ }
+ else if
+ (
+ (fr->bsbuf[lame_offset] == 'X')
+ && (fr->bsbuf[lame_offset+1] == 'i')
+ && (fr->bsbuf[lame_offset+2] == 'n')
+ && (fr->bsbuf[lame_offset+3] == 'g')
+ )
{
- if(fr->begin_s == 0) frame_gapless_init(fr, GAPLESS_DELAY, 0);
+ fr->vbr = MPG123_VBR; /* Xing header means always VBR */
}
+ else goto check_lame_tag_no;
+
+ /* we have one of these headers... */
+ if(VERBOSE2) fprintf(stderr, "Note: Xing/Lame/Info header detected\n");
+ lame_offset += 4;
+ xing_flags = bit_read_long(fr->bsbuf, &lame_offset);
+ debug1("Xing: flags 0x%08lx", xing_flags);
+
+ /* From now on, I have to carefully check if the announced data is actually
+ there! I'm always returning 'yes', though. */
+ #define check_bytes_left(n) if(fr->framesize < lame_offset+n) \
+ goto check_lame_tag_yes
+ if(xing_flags & 1) /* total bitstream frames */
+ {
+ check_bytes_left(4); long_tmp = bit_read_long(fr->bsbuf, &lame_offset);
+ if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
+ {
+ if(VERBOSE3) fprintf(stderr
+ , "Note: Ignoring Xing frames because of MPG123_IGNORE_STREAMLENGTH\n");
+ }
+ else
+ {
+ /* Check for endless stream, but: TRACK_MAX_FRAMES sensible at all? */
+ fr->track_frames = long_tmp > TRACK_MAX_FRAMES ? 0 : (off_t) long_tmp;
+#ifdef GAPLESS
+ /* All or nothing: Only if encoder delay/padding is known, we'll cut
+ samples for gapless. */
+ if(fr->p.flags & MPG123_GAPLESS)
+ frame_gapless_init(fr, fr->track_frames, 0, 0);
#endif
-
- if(fr->framesize >= 120+lame_offset) /* traditional Xing header is 120 bytes */
+ if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu frames\n", long_tmp);
+ }
+ }
+ if(xing_flags & 0x2) /* total bitstream bytes */
{
- int i;
- int lame_type = 0;
- debug("do we have lame tag?");
- /* only search for tag when all zero before it (apart from checksum) */
- for(i=2; i < lame_offset; ++i) if(fr->bsbuf[i] != 0) break;
- if(i == lame_offset)
+ check_bytes_left(4); long_tmp = bit_read_long(fr->bsbuf, &lame_offset);
+ if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
{
- debug("possibly...");
- if
- (
- (fr->bsbuf[lame_offset] == 'I')
- && (fr->bsbuf[lame_offset+1] == 'n')
- && (fr->bsbuf[lame_offset+2] == 'f')
- && (fr->bsbuf[lame_offset+3] == 'o')
- )
- {
- lame_type = 1; /* We still have to see what there is */
- }
- else if
- (
- (fr->bsbuf[lame_offset] == 'X')
- && (fr->bsbuf[lame_offset+1] == 'i')
- && (fr->bsbuf[lame_offset+2] == 'n')
- && (fr->bsbuf[lame_offset+3] == 'g')
- )
+ if(VERBOSE3) fprintf(stderr
+ , "Note: Ignoring Xing bytes because of MPG123_IGNORE_STREAMLENGTH\n");
+ }
+ else
+ {
+ /* The Xing bitstream length, at least as interpreted by the Lame
+ encoder, encompasses all data from the Xing header frame on,
+ ignoring leading ID3v2 data. Trailing tags (ID3v1) seem to be
+ included, though. */
+ if(fr->rdat.filelen < 1)
+ fr->rdat.filelen = (off_t) long_tmp + fr->audio_start; /* Overflow? */
+ else
{
- lame_type = 2;
- fr->vbr = MPG123_VBR; /* Xing header means always VBR */
+ if((off_t)long_tmp != fr->rdat.filelen - fr->audio_start && NOQUIET)
+ { /* 1/filelen instead of 1/(filelen-start), my decision */
+ double diff = 100.0/fr->rdat.filelen
+ * ( fr->rdat.filelen - fr->audio_start
+ - (off_t)long_tmp );
+ if(diff < 0.) diff = -diff;
+
+ if(VERBOSE3) fprintf(stderr
+ , "Note: Xing stream size %lu differs by %f%% from determined/given file size!\n"
+ , long_tmp, diff);
+
+ if(diff > 1. && NOQUIET) fprintf(stderr
+ , "Warning: Xing stream size off by more than 1%%, fuzzy seeking may be even more fuzzy than by design!\n");
+ }
}
- if(lame_type)
+
+ if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu bytes\n", long_tmp);
+ }
+ }
+ if(xing_flags & 0x4) /* TOC */
+ {
+ check_bytes_left(100);
+ frame_fill_toc(fr, fr->bsbuf+lame_offset);
+ lame_offset += 100;
+ }
+ if(xing_flags & 0x8) /* VBR quality */
+ {
+ check_bytes_left(4); long_tmp = bit_read_long(fr->bsbuf, &lame_offset);
+ if(VERBOSE3) fprintf(stderr, "Note: Xing: quality = %lu\n", long_tmp);
+ }
+ /*
+ Either zeros/nothing, or:
+ 0-8: LAME3.90a
+ 9: revision/VBR method
+ 10: lowpass
+ 11-18: ReplayGain
+ 19: encoder flags
+ 20: ABR
+ 21-23: encoder delays
+ */
+ check_bytes_left(24); /* I'm interested in 24 B of extra info. */
+ if(fr->bsbuf[lame_offset] != 0)
+ {
+ unsigned char lame_vbr;
+ float replay_gain[2] = {0,0};
+ float peak = 0;
+ float gain_offset = 0; /* going to be +6 for old lame that used 83dB */
+ char nb[10];
+ off_t pad_in;
+ off_t pad_out;
+ memcpy(nb, fr->bsbuf+lame_offset, 9);
+ nb[9] = 0;
+ 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)
{
- unsigned long xing_flags;
-
- /* we have one of these headers... */
- if(VERBOSE2) fprintf(stderr, "Note: Xing/Lame/Info header detected\n");
- /* now interpret the Xing part, I have 120 bytes total for sure */
- /* there are 4 bytes for flags, but only the last byte contains known ones */
- lame_offset += 4; /* now first byte after Xing/Name */
- /* 4 bytes dword for flags */
- #define make_long(a, o) ((((unsigned long) a[o]) << 24) | (((unsigned long) a[o+1]) << 16) | (((unsigned long) a[o+2]) << 8) | ((unsigned long) a[o+3]))
- /* 16 bit */
- #define make_short(a,o) ((((unsigned short) a[o]) << 8) | ((unsigned short) a[o+1]))
- xing_flags = make_long(fr->bsbuf, lame_offset);
- lame_offset += 4;
- debug1("Xing: flags 0x%08lx", xing_flags);
- if(xing_flags & 1) /* frames */
- {
- if(fr->p.flags & MPG123_IGNORE_STREAMLENGTH)
- {
- if(VERBOSE3)
- fprintf(stderr, "Note: Ignoring Xing frames because of MPG123_IGNORE_STREAMLENGTH\n");
- }
- else
- {
- /*
- 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.
- */
- 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 */
- 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);
- }
- #endif
- if(VERBOSE3) fprintf(stderr, "Note: Xing: %lu frames\n", (long unsigned)fr->track_frames);
- }
-
- lame_offset += 4;
- }
- if(xing_flags & 0x2) /* bytes */
+ 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))
{
- 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)
- fr->rdat.filelen = (off_t) xing_bytes; /* One could start caring for overflow here. */
- else
- {
- if((off_t) xing_bytes != fr->rdat.filelen && NOQUIET)
- {
- double diff = 1.0/fr->rdat.filelen * (fr->rdat.filelen - (off_t)xing_bytes);
- if(diff < 0.) diff = -diff;
-
- if(VERBOSE3)
- fprintf(stderr, "Note: Xing stream size %lu differs by %f%% from determined/given file size!\n", xing_bytes, diff);
-
- if(diff > 1.)
- fprintf(stderr, "Warning: Xing stream size off by more than 1%%, fuzzy seeking may be even more fuzzy than by design!\n");
- }
- }
-
- if(VERBOSE3)
- fprintf(stderr, "Note: Xing: %lu bytes\n", (long unsigned)xing_bytes);
- }
-
- lame_offset += 4;
+ gain_offset = 6;
+ if(VERBOSE3) fprintf(stderr
+ , "Note: Info: Old LAME detected, using ReplayGain preamp of %f dB.\n"
+ , gain_offset);
}
- if(xing_flags & 0x4) /* TOC */
- {
- frame_fill_toc(fr, fr->bsbuf+lame_offset);
- lame_offset += 100; /* just skip */
- }
- if(xing_flags & 0x8) /* VBR quality */
- {
- if(VERBOSE3)
- {
- unsigned long xing_quality = make_long(fr->bsbuf, lame_offset);
- fprintf(stderr, "Note: Xing: quality = %lu\n", (long unsigned)xing_quality);
- }
- 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;
- float replay_gain[2] = {0,0};
- float peak = 0;
- float gain_offset = 0; /* going to be +6 for old lame that used 83dB */
- char nb[10];
- memcpy(nb, fr->bsbuf+lame_offset, 9);
- nb[9] = 0;
- if(VERBOSE3) fprintf(stderr, "Note: Info: Encoder: %s\n", nb);
- if(!strncmp("LAME", nb, 4))
- {
- gain_offset = 6;
- debug("TODO: finish lame detetcion...");
- }
- lame_offset += 9;
- /* the 4 big bits are tag revision, the small bits vbr method */
- lame_vbr = fr->bsbuf[lame_offset] & 15;
- if(VERBOSE3)
- {
- fprintf(stderr, "Note: Info: rev %u\n", fr->bsbuf[lame_offset] >> 4);
- fprintf(stderr, "Note: Info: vbr mode %u\n", lame_vbr);
- }
- lame_offset += 1;
- switch(lame_vbr)
- {
- /* from rev1 proposal... not sure if all good in practice */
- case 1:
- case 8: fr->vbr = MPG123_CBR; break;
- case 2:
- case 9: fr->vbr = MPG123_ABR; break;
- default: fr->vbr = MPG123_VBR; /* 00==unknown is taken as VBR */
- }
- /* skipping: lowpass filter value */
- lame_offset += 1;
- /* replaygain */
- /* 32bit float: peak amplitude -- why did I parse it as int before??*/
- /* Ah, yes, lame seems to store it as int since some day in 2003; I've only seen zeros anyway until now, bah! */
- if
- (
- (fr->bsbuf[lame_offset] != 0)
- || (fr->bsbuf[lame_offset+1] != 0)
- || (fr->bsbuf[lame_offset+2] != 0)
- || (fr->bsbuf[lame_offset+3] != 0)
- )
- {
- debug("Wow! Is there _really_ a non-zero peak value? Now is it stored as float or int - how should I know?");
- /* byte*peak_bytes = (byte*) &peak;
- ... endianess ... just copy bytes to avoid floating point operation on unaligned memory?
- peak_bytes[0] = ...
- peak = *(float*) (fr->bsbuf+lame_offset); */
- }
- if(VERBOSE3) fprintf(stderr, "Note: Info: peak = %f (I won't use this)\n", peak);
- peak = 0; /* until better times arrived */
- lame_offset += 4;
- /*
- ReplayGain values - lame only writes radio mode gain...
- 16bit gain, 3 bits name, 3 bits originator, sign (1=-, 0=+), dB value*10 in 9 bits (fixed point)
- ignore the setting if name or originator == 000!
- radio 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1
- audiophile 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0
- */
-
- for(i =0; i < 2; ++i)
- {
- unsigned char origin = (fr->bsbuf[lame_offset] >> 2) & 0x7; /* the 3 bits after that... */
- if(origin != 0)
- {
- unsigned char gt = fr->bsbuf[lame_offset] >> 5; /* only first 3 bits */
- if(gt == 1) gt = 0; /* radio */
- 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);
- }
- lame_offset += 2;
- }
- if(VERBOSE3)
- {
- fprintf(stderr, "Note: Info: Radio Gain = %03.1fdB\n", replay_gain[0]);
- fprintf(stderr, "Note: Info: Audiophile Gain = %03.1fdB\n", replay_gain[1]);
- }
- for(i=0; i < 2; ++i)
- {
- if(fr->rva.level[i] <= 0)
- {
- fr->rva.peak[i] = 0; /* at some time the parsed peak should be used */
- fr->rva.gain[i] = replay_gain[i];
- fr->rva.level[i] = 0;
- }
- }
- lame_offset += 1; /* skipping encoding flags byte */
- if(fr->vbr == MPG123_ABR)
- {
- fr->abr_rate = fr->bsbuf[lame_offset];
- if(VERBOSE3) fprintf(stderr, "Note: Info: ABR rate = %u\n", fr->abr_rate);
- }
- lame_offset += 1;
- /* encoder delay and padding, two 12 bit values... lame does write them from int ...*/
- if(VERBOSE3)
- fprintf(stderr, "Note: Encoder delay = %i; padding = %i\n",
- ((((int) fr->bsbuf[lame_offset]) << 4) | (((int) fr->bsbuf[lame_offset+1]) >> 4)),
- (((((int) fr->bsbuf[lame_offset+1]) << 8) | (((int) fr->bsbuf[lame_offset+2]))) & 0xfff) );
- #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);
- }
- #endif
- }
- /* switch buffer back ... */
- fr->bsbuf = fr->bsspace[fr->bsnum]+512;
- fr->bsnum = (fr->bsnum + 1) & 1;
- return 1; /* got it! */
+ }
+ else if(VERBOSE3) fprintf(stderr
+ , "Note: Info: Cannot determine LAME version.\n");
+ }
+ lame_offset += 9; /* 9 in */
+
+ /* The 4 big bits are tag revision, the small bits vbr method. */
+ lame_vbr = fr->bsbuf[lame_offset] & 15;
+ lame_offset += 1; /* 10 in */
+ if(VERBOSE3)
+ {
+ fprintf(stderr, "Note: Info: rev %u\n", fr->bsbuf[lame_offset] >> 4);
+ fprintf(stderr, "Note: Info: vbr mode %u\n", lame_vbr);
+ }
+ switch(lame_vbr)
+ {
+ /* from rev1 proposal... not sure if all good in practice */
+ case 1:
+ case 8: fr->vbr = MPG123_CBR; break;
+ case 2:
+ case 9: fr->vbr = MPG123_ABR; break;
+ default: fr->vbr = MPG123_VBR; /* 00==unknown is taken as VBR */
+ }
+ lame_offset += 1; /* 11 in, skipping lowpass filter value */
+
+ /* ReplayGain peak ampitude, 32 bit float -- why did I parse it as int
+ before?? Ah, yes, Lame seems to store it as int since some day in 2003;
+ I've only seen zeros anyway until now, bah! */
+ if
+ (
+ (fr->bsbuf[lame_offset] != 0)
+ || (fr->bsbuf[lame_offset+1] != 0)
+ || (fr->bsbuf[lame_offset+2] != 0)
+ || (fr->bsbuf[lame_offset+3] != 0)
+ )
+ {
+ debug("Wow! Is there _really_ a non-zero peak value? Now is it stored as float or int - how should I know?");
+ /* byte*peak_bytes = (byte*) &peak;
+ ... endianess ... just copy bytes to avoid floating point operation on unaligned memory?
+ peak_bytes[0] = ...
+ peak = *(float*) (fr->bsbuf+lame_offset); */
+ }
+ if(VERBOSE3) fprintf(stderr
+ , "Note: Info: peak = %f (I won't use this)\n", peak);
+ peak = 0; /* until better times arrived */
+ lame_offset += 4; /* 15 in */
+
+ /* ReplayGain values - lame only writes radio mode gain...
+ 16bit gain, 3 bits name, 3 bits originator, sign (1=-, 0=+),
+ dB value*10 in 9 bits (fixed point) ignore the setting if name or
+ originator == 000!
+ radio 0 0 1 0 1 1 1 0 0 1 1 1 1 1 0 1
+ audiophile 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 */
+ for(i =0; i < 2; ++i)
+ {
+ unsigned char gt = fr->bsbuf[lame_offset] >> 5;
+ unsigned char origin = (fr->bsbuf[lame_offset] >> 2) & 0x7;
+ float factor = (fr->bsbuf[lame_offset] & 0x2) ? -0.1 : 0.1;
+ unsigned short gain = bit_read_short(fr->bsbuf, &lame_offset) & 0x1ff; /* 19 in (2 cycles) */
+ if(origin == 0 || gt < 1 || gt > 2) continue;
+
+ --gt;
+ replay_gain[gt] = factor * (float) gain;
+ /* Apply gain offset for automatic origin. */
+ if(origin == 3) replay_gain[gt] += gain_offset;
+ }
+ if(VERBOSE3)
+ {
+ fprintf(stderr, "Note: Info: Radio Gain = %03.1fdB\n"
+ , replay_gain[0]);
+ fprintf(stderr, "Note: Info: Audiophile Gain = %03.1fdB\n"
+ , replay_gain[1]);
+ }
+ for(i=0; i < 2; ++i)
+ {
+ if(fr->rva.level[i] <= 0)
+ {
+ fr->rva.peak[i] = 0; /* TODO: use parsed peak? */
+ fr->rva.gain[i] = replay_gain[i];
+ fr->rva.level[i] = 0;
}
}
+
+ lame_offset += 1; /* 20 in, skipping encoding flags byte */
+
+ /* ABR rate */
+ if(fr->vbr == MPG123_ABR)
+ {
+ fr->abr_rate = fr->bsbuf[lame_offset];
+ if(VERBOSE3) fprintf(stderr, "Note: Info: ABR rate = %u\n"
+ , fr->abr_rate);
+ }
+ lame_offset += 1; /* 21 in */
+
+ /* Encoder delay and padding, two 12 bit values
+ ... lame does write them from int. */
+ pad_in = ( (((int) fr->bsbuf[lame_offset]) << 4)
+ | (((int) fr->bsbuf[lame_offset+1]) >> 4) );
+ pad_out = ( (((int) fr->bsbuf[lame_offset+1]) << 8)
+ | ((int) fr->bsbuf[lame_offset+2]) ) & 0xfff;
+ lame_offset += 3; /* 24 in */
+ if(VERBOSE3) fprintf(stderr, "Note: Encoder delay = %i; padding = %i\n"
+ , (int)pad_in, (int)pad_out);
+ #ifdef GAPLESS
+ if(fr->p.flags & MPG123_GAPLESS)
+ frame_gapless_init(fr, fr->track_frames, pad_in, pad_out);
+ #endif
+ /* final: 24 B LAME data */
}
- return 0; /* no lame tag */
+
+check_lame_tag_yes:
+ /* switch buffer back ... */
+ fr->bsbuf = fr->bsspace[fr->bsnum]+512;
+ fr->bsnum = (fr->bsnum + 1) & 1;
+ return 1;
+check_lame_tag_no:
+ return 0;
}
/* 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;
-
- /* 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. */
- int headcount = 0;
+ return ( (fred & HDR_CMPMASK) == (bret & HDR_CMPMASK)
+ && header_mono(fred) == header_mono(bret) );
+}
- fr->fsizeold=fr->framesize; /* for Layer3 */
+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)
{
fr->halfphase = fr->p.halfspeed - 1;
}
}
+ return 0;
+}
+
+/*
+ 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){ ret=0; goto read_frame_bad; } \
+}
+
+/*
+ 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)
+{
+ /* 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;
+
+ /* 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->fsizeold=fr->framesize; /* for Layer3 */
+
+ if(halfspeed_do(fr) == 1) return 1;
read_again:
/* In case we are looping to find a valid frame, discard any buffered data before the current position.
if(fr->rd->forget != NULL) fr->rd->forget(fr);
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){ debug("need more?"); goto read_frame_bad;}
+ if((ret = fr->rd->head_read(fr,&newhead)) <= 0){ debug1("need more? (%i)", ret); 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;
- }
- }
-
#ifdef SKIP_JUNK
- /* watch out for junk/tags on beginning of stream by invalid header */
- if(!fr->firsthead && !head_check(newhead)) {
-
- /* 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. */
- }
- 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...");
-
- ret = 0; /* We will check the value after the loop. */
- for(; headcount<65536; headcount++)
- {
- if((ret=fr->rd->head_shift(fr,&newhead))<=0){ debug("need more?"); goto read_frame_bad; }
- /* if(head_check(newhead)) */
- if(head_check(newhead) && (ret=decode_header(fr, newhead)))
- break;
- }
- if(ret<0){ debug("need more?"); goto read_frame_bad; }
-
- if(headcount == 65536)
- {
- if(NOQUIET) error("Giving up searching valid MPEG header after (over) 64K of junk.");
- return 0;
- }
- else debug1("hopefully found one at %"OFF_P, (off_p)fr->rd->tell(fr));
- /*
- * 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.
- */
- }
-#endif
-
- /* first attempt of read ahead check to find the real first header; cannot believe what junk is out there! */
- if(!fr->firsthead && fr->rdat.flags & (READER_SEEKABLE|READER_BUFFERED) && head_check(newhead) && (ret=decode_header(fr, newhead)))
+ if(!fr->firsthead && !head_check(newhead))
{
- unsigned long nexthead = 0;
- int hd = 0;
- off_t start = fr->rd->tell(fr);
- if(ret<0){ debug("need more?"); goto read_frame_bad; }
-
- 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((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 %"OFF_P, (off_p)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;
- }
- }
+ ret = skip_junk(fr, &newhead, &headcount);
+ JUMP_CONCLUSION(ret);
}
+#endif
- /* 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 (VERBOSE3) fprintf(stderr,"Note: Skipped ID3v1 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; }
-
- 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 %"OFF_P".\n",
- newhead, (off_p)fr->rd->tell(fr)-4);
- }
-
- 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 a resync is needed the bitreservoir of previous frames is no longer valid */
- fr->bitreservoir = 0;
-
- /* 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;
-
- if((ret=fr->rd->head_shift(fr,&newhead)) <= 0)
- {
- debug("need more?");
- if(NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n");
+ ret = head_check(newhead);
+ if(ret) ret = decode_header(fr, newhead, &freeformat_count);
- goto read_frame_bad;
- }
- if(VERBOSE3) debug3("resync try %li at %"OFF_P", got newhead 0x%08lx", try, (off_p)fr->rd->tell(fr), newhead);
-
- if(!fr->oldhead)
- {
- debug("going to init_resync...");
- goto init_resync; /* "considered harmful", eh? */
- }
- /* 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);
-
- 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 READER_ERROR;
- }
- 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;
- }
+ 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;
}
- /* Man, that code looks awfully redundant...
- I need to untangle the spaghetti here in a future version. */
if(!fr->firsthead)
{
- ret=decode_header(fr,newhead);
- if(ret == 0)
- {
- if(NOQUIET) error("decode header failed before first valid one, going to read again");
-
- goto read_again;
- }
- else if(ret < 0){ debug("need more?"); goto read_frame_bad; }
- }
- else
- {
- ret=decode_header(fr,newhead);
- if(ret == 0)
- {
- if(NOQUIET) error("decode header failed - goto resync");
- /* return 0; */
- goto init_resync;
- }
- else if(ret < 0){ debug("need more?"); goto read_frame_bad; }
+ 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);
}
+ /* 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 */
++fr->num; /* 0 for first frame! */
debug4("Frame %"OFF_P" %08lx %i, next filepos=%"OFF_P,
(off_p)fr->num, newhead, fr->framesize, (off_p)fr->rd->tell(fr));
-
- /* save for repetition */
- if(fr->p.halfspeed && fr->lay == 3)
+ 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
fr->to_decode = fr->to_ignore = TRUE;
if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */
+ /*
+ Let's check for header change after deciding that the new one is good
+ and actually having read a frame.
+
+ header_change > 1: decoder structure has to be updated
+ Preserve header_change value from previous runs if it is serious.
+ If we still have a big change pending, it should be dealt with outside,
+ fr->header_change set to zero afterwards.
+ */
+ if(fr->header_change < 2)
+ {
+ 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
+ /* 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;
+ else
+ {
+ fr->state_flags |= FRAME_FRANKENSTEIN;
+ if(NOQUIET)
+ fprintf(stderr, "\nWarning: Big change (MPEG version, layer, rate). Frankenstein stream?\n");
+ }
+ }
+ else if(fr->firsthead && !head_compatible(fr->firsthead, newhead))
+ {
+ fr->state_flags |= FRAME_FRANKENSTEIN;
+ if(NOQUIET)
+ fprintf(stderr, "\nWarning: Big change from first (MPEG version, layer, rate). Frankenstein stream?\n");
+ }
+ }
+
+ fr->oldhead = newhead;
+
return 1;
read_frame_bad:
- /* Also if we searched for valid data in vain, we can forget skipped data.
+ /* 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);
/*
* read ahead and find the next MPEG header, to guess framesize
* return value: success code
- * 1: found a valid frame size (stored in the handle).
+ * PARSE_GOOD: found a valid frame size (stored in the handle).
* <0: error codes, possibly from feeder buffer (NEED_MORE)
- * 0: cannot get the framesize for some reason and shall silentry try the next possible header (if this is no free format stream after all...)
+ * 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 int guess_freeformat_framesize(mpg123_handle *fr)
+static int guess_freeformat_framesize(mpg123_handle *fr, unsigned long oldhead)
{
long i;
int ret;
{
if(NOQUIET) error("Cannot look for freeformat frame size with non-seekable and non-buffered stream!");
- return 0;
+ return PARSE_BAD;
}
if((ret=fr->rd->head_read(fr,&head))<=0)
return ret;
/* We are already 4 bytes into it */
-/* fix that limit to be absolute for the first header search! */
- for(i=4;i<65536;i++) {
- if((ret=fr->rd->head_shift(fr,&head))<=0)
+ for(i=4;i<MAXFRAMESIZE+4;i++)
+ {
+ if((ret=fr->rd->head_shift(fr,&head))<=0) return ret;
+
+ /* No head_check needed, the mask contains all relevant bits. */
+ if((head & HDR_SAMEMASK) == (oldhead & HDR_SAMEMASK))
{
- return ret;
- }
- if(head_check(head))
- {
- int sampling_frequency,mpeg25,lsf;
-
- if(head & (1<<20))
- {
- 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);
- fr->framesize = i-3;
- return 1; /* Success! */
- }
+ fr->rd->back_bytes(fr,i+1);
+ fr->framesize = i-3;
+ return PARSE_GOOD; /* Success! */
}
}
fr->rd->back_bytes(fr,i);
- return 0;
+ return PARSE_BAD;
}
* 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
+ /* For some reason, the layer and sampling freq settings used to be wrapped
+ in a weird conditional including MPG123_NO_RESYNC. What was I thinking?
+ This information has to be consistent. */
+ fr->lay = 4 - HDR_LAYER_VAL(newhead);
+
+ 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;
+ fr->sampling_frequency = HDR_SAMPLERATE_VAL(newhead) + (fr->lsf*3);
}
else
{
fr->lsf = 1;
fr->mpeg25 = 1;
- }
-
- if( (fr->p.flags & MPG123_NO_RESYNC) || !fr->oldhead
- || (((fr->oldhead>>19)&0x3) ^ ((newhead>>19)&0x3)) )
- {
- /* 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? */
- }
- if(fr->mpeg25)
- fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
- else
- fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
+ fr->sampling_frequency = 6 + HDR_SAMPLERATE_VAL(newhead);
}
#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->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+ 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... */
if(fr->freeformat)
{
if(fr->freeformat_framesize < 0)
{
int ret;
- ret = guess_freeformat_framesize(fr);
- if(ret>0)
+ *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, newhead);
+ if(ret == PARSE_GOOD)
{
fr->freeformat_framesize = fr->framesize - fr->padding;
if(VERBOSE2)
{
if(ret == MPG123_NEED_MORE)
debug("Need more data to guess free format frame size.");
- else
+ else if(VERBOSE3)
error("Encountered free format header, but failed to guess frame size.");
+
return ret;
}
}
{
#ifndef NO_LAYER1
case 1:
+ fr->spf = 384;
fr->do_layer = do_layer1;
if(!fr->freeformat)
{
#endif
#ifndef NO_LAYER2
case 2:
+ fr->spf = 1152;
fr->do_layer = do_layer2;
if(!fr->freeformat)
{
#endif
#ifndef NO_LAYER3
case 3:
+ fr->spf = fr->lsf ? 576 : 1152; /* MPEG 2.5 implies LSF.*/
fr->do_layer = do_layer3;
if(fr->lsf)
fr->ssize = (fr->stereo == 1) ? 9 : 17;
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)
return bpf;
}
+int attribute_align_arg mpg123_spf(mpg123_handle *mh)
+{
+ if(mh == NULL) return MPG123_ERR;
+
+ return mh->firsthead ? mh->spf : MPG123_ERR;
+}
+
double attribute_align_arg mpg123_tpf(mpg123_handle *fr)
{
static int bs[4] = { 0,384,1152,1152 };
double tpf;
- if(fr == NULL) return -1;
+ if(fr == NULL || !fr->firsthead) return MPG123_ERR;
tpf = (double) bs[fr->lay];
tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
off_t cur, left;
double curs, lefts;
- if(!fr || !fr->rd) /* Isn't this too paranoid? */
- {
- debug("reader troubles!");
- return MPG123_ERR;
- }
+ if(!fr || !fr->rd) return MPG123_ERR;
no += fr->num; /* no starts out as offset */
cur = no;
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;
+}
+
+/* Advance a byte in stream to get next possible header and forget
+ buffered data if possible (for feed reader). */
+#define FORGET_INTERVAL 1024 /* Used by callers to set forget flag each <n> bytes. */
+static int forget_head_shift(mpg123_handle *fr, unsigned long *newheadp, int forget)
+{
+ int ret;
+ if((ret=fr->rd->head_shift(fr,newheadp))<=0) return ret;
+ /* Try to forget buffered data as early as possible to speed up parsing where
+ new data needs to be added for resync (and things would be re-parsed again
+ and again because of the start from beginning after hitting end). */
+ if(forget && fr->rd->forget != NULL)
+ {
+ /* Ensure that the last 4 bytes stay in buffers for reading the header
+ anew. */
+ if(!fr->rd->back_bytes(fr, 4))
+ {
+ fr->rd->forget(fr);
+ fr->rd->back_bytes(fr, -4);
+ }
+ }
+ return ret; /* No surprise here, error already triggered early return. */
+}
+
+/* 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;
+ unsigned int forgetcount = 0;
+ /* 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(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
+ if((ret=forget_head_shift(fr,&newhead,!forgetcount))<=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(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
+ if((ret=forget_head_shift(fr, &newhead, !forgetcount))<=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;
+ unsigned int forgetcount = 0;
+
+ /* 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(++forgetcount > FORGET_INTERVAL) forgetcount = 0;
+ if((ret=forget_head_shift(fr,&newhead,!forgetcount)) <= 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 oldhead to reinit stream.", newhead);
+ 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. */
+}