📄 parse.c
字号:
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] = ((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! */ } } } return 0; /* no lame tag */}/* 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 */ unsigned long newhead; off_t framepos; int ret; int give_note = VERBOSE2 ? 1 : (fr->do_recover ? 0 : 1 ); /* stuff that needs resetting if complete frame reading fails */ int oldsize = fr->framesize; int oldphase = fr->halfphase; fr->fsizeold=fr->framesize; /* for Layer3 */ /* Hm, I never tested this...*/ if (fr->p.halfspeed) { if(fr->halfphase) /* repeat last frame */ { debug("repeat!"); fr->to_decode = fr->to_ignore = TRUE; --fr->halfphase; fr->bitindex = 0; fr->wordpointer = (unsigned char *) fr->bsbuf; if(fr->lay == 3) memcpy (fr->bsbuf, fr->ssave, fr->ssize); if(fr->error_protection) fr->crc = getbits(fr, 16); /* skip crc */ return 1; } else { 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;} /* this if wrap looks like dead code... */ if(1 || fr->oldhead != newhead || !fr->oldhead) {init_resync: fr->header_change = 2; /* output format change is possible... */ if(fr->oldhead) /* check a following header for change */ { /* 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... */ if( (fr->oldhead & HDRCHANMASK) == 0 && (newhead & HDRCHANMASK) == 0) fr->header_change = 1; /* ...or stereo (of sorts), then we have a small header change */ else if( (fr->oldhead & HDRCHANMASK) > 0 && (newhead & HDRCHANMASK) > 0) 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) && !free_format_header(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; } else if(id3ret > 0){ debug("got ID3v2"); fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; } else debug("no useful ID3v2"); fr->oldhead = 0; goto read_again; /* Also in case of invalid ID3 tag (ret==0), try to get on track again. */ } else if(VERBOSE2) 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) 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) 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. */ }#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)) { 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; } } } /* why has this head check been avoided here before? */ if(!head_check(newhead)) { if(!fr->firsthead && free_format_header(newhead)) { if(NOQUIET) error1("Header 0x%08lx seems to indicate a free format stream; I do not handle that yet", newhead); goto read_again; return 0; } /* 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; } fr->metaflags |= MPG123_NEW_ID3|MPG123_ID3; goto read_again; } else if (give_note && NOQUIET) { fprintf(stderr,"Note: Illegal Audio-MPEG-Header 0x%08lx at offset 0x%lx.\n", newhead, (long unsigned int)fr->rd->tell(fr)-4); } if(give_note && NOQUIET && (newhead & 0xffffff00) == ('b'<<24)+('m'<<16)+('p'<<8)) fprintf(stderr,"Note: Could be a BMP album art.\n"); /* Do resync if forced from outside or not forbidden by flag. Also, don't try to resync on ICY streams - that won't work! */ if( (!(fr->p.flags & MPG123_NO_RESYNC)|| fr->do_recover) && fr->p.icy_interval == 0 ) { long try = 0; long limit = fr->p.resync_limit; /* TODO: make this more robust, I'd like to cat two mp3 fragments together (in a dirty way) and still have mpg123 beign able to decode all it somehow. */ if(give_note && NOQUIET) fprintf(stderr, "Note: Trying to resync...\n"); /* Read more bytes until we find something that looks 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(give_note && NOQUIET) fprintf (stderr, "Note: Hit end of (available) data during resync.\n"); goto read_frame_bad; } debug3("resync try %li at 0x%lx, got newhead 0x%08lx", try, (unsigned long)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(give_note && NOQUIET) 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; } } 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; } } else if(!decode_header(fr,newhead)) { if(NOQUIET) error("decode header failed - goto resync"); /* return 0; */ goto init_resync; } } else fr->header_change = 0; /* if filepos is invalid, so is framepos */ framepos = fr->rd->tell(fr) - 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -