decoder-mp3.c
author nathan
Sun, 06 Dec 2009 08:48:57 +0800
branchtrunk
changeset 34 afc13760179b
parent 25 887faebaba0a
permissions -rw-r--r--
fixed gcc 4.4.1 const errors
     1 /*
     2  * MP3/MPlayer plugin to VDR (C++)
     3  *
     4  * (C) 2001-2009 Stefan Huelswitt <s.huelswitt@gmx.de>
     5  *
     6  * This code is free software; you can redistribute it and/or
     7  * modify it under the terms of the GNU General Public License
     8  * as published by the Free Software Foundation; either version 2
     9  * of the License, or (at your option) any later version.
    10  *
    11  * This code is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License
    17  * along with this program; if not, write to the Free Software
    18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    19  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
    20  */
    21 
    22 #include <stdlib.h>
    23 #include <stdio.h>
    24 
    25 #include "common.h"
    26 #include "data-mp3.h"
    27 #include "decoder-mp3.h"
    28 #include "stream.h"
    29 
    30 #define MAX_FRAME_ERR 10
    31 
    32 // ----------------------------------------------------------------
    33 
    34 int MadStream(struct mad_stream *stream, cStream *str)
    35 {
    36   unsigned char *data;
    37   unsigned long len;
    38   if(str->Stream(data,len,stream->next_frame)) {
    39     if(len>0) mad_stream_buffer(stream, data, len);
    40     return len;
    41     }
    42   return -1;
    43 }
    44 
    45 // --- cMP3Decoder -------------------------------------------------------------
    46 
    47 cMP3Decoder::cMP3Decoder(const char *Filename, bool preinit)
    48 :cDecoder(Filename)
    49 {
    50   str=0; scan=0; isStream=false;
    51   if(preinit) {
    52     //d(printf("mp3: preinit\n"))
    53     str=new cStream(filename);
    54     scan=new cScanID3(str,&urgentLock);
    55     }
    56   fi=0; stream=0; frame=0; synth=0;
    57 }
    58 
    59 cMP3Decoder::~cMP3Decoder()
    60 {
    61   Clean();
    62   delete scan;
    63   delete str;
    64 }
    65 
    66 bool cMP3Decoder::Valid(void)
    67 {
    68   bool res=false;
    69   if(TryLock()) {
    70     struct mad_stream stream;
    71     struct mad_header header;
    72     mad_stream_init(&stream);
    73     mad_stream_options(&stream,MAD_OPTION_IGNORECRC);
    74     mad_header_init(&header);
    75     if(str->Open() && str->Seek()) {
    76       int count=10;
    77       do {
    78         if(mad_header_decode(&header,&stream)<0) {
    79           if(stream.error==MAD_ERROR_BUFLEN || stream.error==MAD_ERROR_BUFPTR) {
    80             if(MadStream(&stream,str)<=0) break;
    81             }
    82           else if(!MAD_RECOVERABLE(stream.error)) break;
    83           count++;
    84           }
    85         } while(--count);
    86       if(!count) res=true;
    87       }
    88     mad_header_finish(&header);
    89     mad_stream_finish(&stream);
    90     str->Close();
    91     Unlock();
    92     }
    93   return res;
    94 }
    95 
    96 cFileInfo *cMP3Decoder::FileInfo(void)
    97 {
    98   cFileInfo *fi=0;
    99   if(str->HasInfo()) fi=str;
   100   else if(TryLock()){
   101     if(str->Open()) { fi=str; str->Close(); }
   102     Unlock();
   103     }
   104   return fi;
   105 }
   106 
   107 cSongInfo *cMP3Decoder::SongInfo(bool get)
   108 {
   109   cSongInfo *si=0;
   110   if(scan->HasInfo()) si=scan;
   111   else if(get && TryLock()) {
   112     if(scan->DoScan()) si=scan;
   113     Unlock();
   114     }
   115   return si;
   116 }
   117 
   118 cPlayInfo *cMP3Decoder::PlayInfo(void)
   119 {
   120   if(playing) {
   121     pi.Index=mad_timer_count(playtime,MAD_UNITS_SECONDS);
   122     pi.Total=scan->Total;
   123     return &pi;
   124     }
   125   return 0;
   126 }
   127 
   128 void cMP3Decoder::Init(void)
   129 {
   130   Clean();
   131   stream=new struct mad_stream;
   132   mad_stream_init(stream);
   133   mad_stream_options(stream,MAD_OPTION_IGNORECRC);
   134   frame=new struct mad_frame;
   135   mad_frame_init(frame);
   136   synth=new struct mad_synth;
   137   mad_synth_init(synth);
   138   playtime=mad_timer_zero; skiptime=mad_timer_zero;
   139   framenum=framemax=0; mute=errcount=0;
   140 }
   141 
   142 void cMP3Decoder::Clean(void)
   143 {
   144   playing=false;
   145   if(synth) { mad_synth_finish(synth); delete synth; synth=0; }
   146   if(frame) { mad_frame_finish(frame); delete frame; frame=0; }
   147   if(stream) { mad_stream_finish(stream); delete stream; stream=0; }
   148   delete[] fi; fi=0;
   149 }
   150 
   151 bool cMP3Decoder::Start(void)
   152 {
   153   Lock(true);
   154   Init(); playing=true;
   155   if(str->Open() && scan->DoScan(true)) {
   156     if(!isStream) {
   157       str->Seek();
   158       framemax=scan->Frames+20;
   159       fi=new struct FrameInfo[framemax];
   160       if(!fi) esyslog("ERROR: no memory for frame index, rewinding disabled");
   161       }
   162     Unlock();
   163     return true;
   164     }
   165   str->Close();
   166   Clean();
   167   Unlock();
   168   return false;
   169 }
   170 
   171 bool cMP3Decoder::Stop(void)
   172 {
   173   Lock();
   174   if(playing) {
   175     str->Close();
   176     Clean();
   177     }
   178   Unlock();
   179   return true;
   180 }
   181 
   182 struct Decode *cMP3Decoder::Done(eDecodeStatus status)
   183 {
   184   ds.status=status;
   185   ds.index=mad_timer_count(playtime,MAD_UNITS_MILLISECONDS);
   186   ds.pcm=&synth->pcm;
   187   Unlock(); // release the lock from Decode()
   188   return &ds;
   189 }
   190 
   191 eDecodeStatus cMP3Decoder::DecodeError(bool hdr)
   192 {
   193   if(stream->error==MAD_ERROR_BUFLEN || stream->error==MAD_ERROR_BUFPTR) {
   194     int s=MadStream(stream,str);
   195     if(s<0) return dsError;
   196     if(s==0) return dsEof;
   197     }
   198   else if(!MAD_RECOVERABLE(stream->error)) {
   199     d(printf("mad: decode %sfailed, frame=%d: %s\n",hdr?"hdr ":"",framenum,mad_stream_errorstr(stream)))
   200     return dsError;
   201     }
   202   else { 
   203     if(stream->error==MAD_ERROR_LOSTSYNC) { // check for ID3 tags
   204 #ifdef DEBUG
   205       char buf[10];
   206       int buf2[3];
   207       memcpy(buf,stream->this_frame,8); buf[8]=0;
   208       memcpy(buf2,stream->this_frame,8);
   209       printf("mad: lost sync %08x %08x %s\n",buf2[0],buf2[1],buf);
   210 #endif
   211       id3_length_t count=stream->bufend-stream->this_frame;
   212       id3_length_t tagsize=id3_tag_query(stream->this_frame,count);
   213       if(tagsize>0) {
   214         d(printf("mad: skipping over ID3 tag\n"))
   215         if(count>tagsize) count=tagsize;
   216         mad_stream_skip(stream,count);
   217         while(count<tagsize) {
   218           unsigned char *sdata;
   219           unsigned long slen;
   220           if(!str->Stream(sdata,slen)) return dsError;
   221           if(slen<=0) return dsEof;
   222           unsigned long len=min(tagsize-count,slen);
   223           count+=len;
   224           sdata+=len; slen-=len;
   225           if(slen>0) mad_stream_buffer(stream,sdata,slen);
   226           }
   227         return dsOK;
   228         }
   229       }
   230     errcount+=hdr?1:100;
   231     d(printf("mad: decode %serror, frame=%d count=%d: %s\n",hdr?"hdr ":"",framenum,errcount,mad_stream_errorstr(stream)))
   232     }
   233   return dsOK;
   234 }
   235 
   236 struct Decode *cMP3Decoder::Decode(void)
   237 {
   238   Lock(); // this is released in Done()
   239   eDecodeStatus r;
   240   while(playing) {
   241     if(errcount>=MAX_FRAME_ERR*100) {
   242       esyslog("ERROR: excessive decoding errors, aborting file %s",filename);
   243       return Done(dsError);
   244       }
   245 
   246     if(mad_header_decode(&frame->header,stream)<0) {
   247       if((r=DecodeError(true))) return Done(r);
   248       }
   249     else {
   250       if(!isStream) {
   251 #ifdef DEBUG
   252         if(framenum>=framemax) printf("mp3: framenum >= framemax!!!!\n");
   253 #endif
   254         if(fi && framenum<framemax) {
   255           fi[framenum].Pos=str->BufferPos() + (stream->this_frame-stream->buffer);
   256           fi[framenum].Time=playtime;
   257           }
   258         }
   259 
   260       mad_timer_add(&playtime,frame->header.duration); framenum++;
   261 
   262       if(mad_timer_compare(playtime,skiptime)>=0) skiptime=mad_timer_zero;
   263       else return Done(dsSkip);  // skipping, decode next header
   264 
   265       if(mad_frame_decode(frame,stream)<0) {
   266         if((r=DecodeError(false))) return Done(r);
   267         }
   268       else {
   269         errcount=0;
   270         scan->InfoHook(&frame->header);
   271         mad_synth_frame(synth,frame);
   272         if(mute) { mute--; return Done(dsSkip); }
   273         return Done(dsPlay);
   274         }
   275       }
   276     }
   277   return Done(dsError);
   278 }
   279 
   280 void cMP3Decoder::MakeSkipTime(mad_timer_t *skiptime, mad_timer_t playtime, int secs, float bsecs)
   281 {
   282   mad_timer_t time;
   283   *skiptime=playtime;
   284   mad_timer_set(&time,abs(secs),0,0);
   285   if(secs<0) mad_timer_negate(&time);
   286   mad_timer_add(skiptime,time);
   287   int full=(int)bsecs; bsecs-=(float)full;
   288   mad_timer_set(&time,full,(int)(bsecs*1000.0),1000);
   289   mad_timer_negate(&time);
   290   mad_timer_add(skiptime,time);
   291   d(printf("mp3: skip: playtime=%ld secs=%d full=%d bsecs=%f skiptime=%ld\n",
   292            mad_timer_count(playtime,MAD_UNITS_MILLISECONDS),secs,full,bsecs,mad_timer_count(*skiptime,MAD_UNITS_MILLISECONDS)))
   293 }
   294 
   295 bool cMP3Decoder::Skip(int Seconds, float bsecs)
   296 {
   297   Lock();
   298   bool res=false;
   299   if(playing && !isStream) {
   300     if(!mad_timer_compare(skiptime,mad_timer_zero)) { // allow only one skip at any time
   301       mad_timer_t time;
   302       MakeSkipTime(&time,playtime,Seconds,bsecs);
   303 
   304       if(mad_timer_compare(playtime,time)<=0) { // forward skip
   305 #ifdef DEBUG
   306         int i=mad_timer_count(time,MAD_UNITS_SECONDS);
   307         printf("mp3: forward skipping to %02d:%02d\n",i/60,i%60);
   308 #endif
   309         skiptime=time; mute=1;
   310         res=true;
   311         }
   312       else {                                    // backward skip
   313         if(fi) {
   314 #ifdef DEBUG
   315           int i=mad_timer_count(time,MAD_UNITS_SECONDS);
   316           printf("mp3: rewinding to %02d:%02d\n",i/60,i%60);
   317 #endif
   318           while(framenum && mad_timer_compare(time,fi[--framenum].Time)<0) ;
   319           mute=2; if(framenum>=2) framenum-=2;
   320           playtime=fi[framenum].Time;
   321           str->Seek(fi[framenum].Pos);
   322           mad_stream_finish(stream); // reset stream buffer
   323           mad_stream_init(stream);
   324 #ifdef DEBUG
   325           i=mad_timer_count(playtime,MAD_UNITS_MILLISECONDS);
   326           printf("mp3: new playtime=%d framenum=%d filepos=%lld\n",i,framenum,fi[framenum].Pos);
   327 #endif
   328           res=true;
   329           }
   330         }
   331       }
   332     }
   333   Unlock();
   334   return res;
   335 }
   336 
   337 // --- cScanID3 ----------------------------------------------------------------
   338 
   339 // This function was adapted from mad_timer, from the 
   340 // libmad distribution
   341 
   342 #define MIN_SCAN_FRAMES 200 // min. number of frames to scan
   343 
   344 cScanID3::cScanID3(cStream *Str, bool *Urgent)
   345 {
   346   str=Str;
   347   urgent=Urgent;
   348 }
   349 
   350 bool cScanID3::Abort(bool result)
   351 {
   352   if(!keepOpen) str->Close();
   353   return result;
   354 }
   355 
   356 bool cScanID3::DoScan(bool KeepOpen)
   357 {
   358   mad_timer_t duration=mad_timer_zero;
   359   unsigned int bitrate=0, minrate=~0, maxrate=0;
   360   int xframes=0;
   361   unsigned int id3_vers=0;
   362   bool is_vbr=false, has_id3=false;
   363 
   364   keepOpen=KeepOpen;
   365   if(!str->Open()) return Abort(false);
   366   if(HasInfo()) return Abort(true);
   367 
   368   // check the infocache
   369   cCacheData *dat=InfoCache.Search(str);
   370   if(dat) {
   371     Set(dat); dat->Unlock();
   372     ConvertToSys();
   373     if(!DecoderID) {
   374       DecoderID=DEC_MP3;
   375       InfoCache.Cache(this,str);
   376       }
   377     return Abort(true);
   378     }
   379 
   380   Clear();
   381 
   382   // do a initial check for a ID3v1 tag at the end of the file
   383   // to speed up the following scan
   384   if(str->Filesize>=128 && str->Seek(str->Filesize-128)) {
   385     unsigned char *data;
   386     unsigned long len;
   387     if(str->Stream(data,len)) {
   388       struct id3_tag *tag=id3_tag_parse(data,len);
   389       if(tag) {
   390         d(printf("id3-scan: initialy found ID3 V1 tag at EOF\n"))
   391         ParseID3(tag);
   392         has_id3=true; id3_vers=tag->version;
   393         id3_tag_delete(tag);
   394         }
   395       }
   396     }
   397   if(!str->Seek()) return Abort(false);
   398 
   399   // There are three ways of calculating the length of an mp3:
   400   // 1) Constant bitrate: One frame can provide the information
   401   //    needed: # of frames and duration. Just see how long it
   402   //    is and do the division.
   403   // 2) Variable bitrate: Xing tag. It provides the number of 
   404   //    frames. Each frame has the same number of samples, so
   405   //    just use that.
   406   // 3) All: Count up the frames and duration of each frames
   407   //    by decoding each one. We do this if we've no other
   408   //    choice, i.e. if it's a VBR file with no Xing tag.
   409 
   410   struct mad_stream stream;
   411   struct mad_header header;
   412   mad_stream_init(&stream);
   413   mad_stream_options(&stream,MAD_OPTION_IGNORECRC);
   414   mad_header_init(&header);
   415   bool res=true;
   416   int errcount=0;
   417   while(1) {
   418     if(*urgent) {
   419       d(printf("id3-scan: urgent request, aborting!\n"))
   420       res=false; break; // abort scan if there is an urgent request for the decoder lock
   421       }
   422 
   423     if(mad_header_decode(&header,&stream)<0) {
   424       if(stream.error==MAD_ERROR_BUFLEN || stream.error==MAD_ERROR_BUFPTR) {
   425         int s=MadStream(&stream,str);
   426         if(s>0) continue;
   427         if(s<0) res=false;
   428         break;
   429         }
   430       else if(stream.error==MAD_ERROR_LOSTSYNC) { // check for ID3 tags
   431 #ifdef DEBUG
   432         char buf[10];
   433         int buf2[3];
   434         memcpy(buf,stream.this_frame,8); buf[8]=0;
   435         memcpy(buf2,stream.this_frame,8);
   436         printf("id3-scan: lost sync %08x %08x %s\n",buf2[0],buf2[1],buf);
   437 #endif
   438         id3_length_t tagsize=id3_tag_query(stream.this_frame,stream.bufend-stream.this_frame);
   439         if(tagsize>0) {
   440 	  struct id3_tag *tag=GetID3(&stream,tagsize);
   441 	  if(tag) {
   442             unsigned int vers=id3_tag_version(tag);
   443             d(printf("id3-scan: found ID3 %s tag (%d.%d)\n",vers==0x100?"V1":"V2",ID3_TAG_VERSION_MAJOR(vers),ID3_TAG_VERSION_MINOR(vers)))
   444             if(!has_id3 || vers>id3_vers) {
   445               ParseID3(tag);
   446               has_id3=true; id3_vers=vers;
   447               }
   448 	    id3_tag_delete(tag);
   449 	    }
   450           }
   451         continue;
   452         }
   453       else {
   454         d(printf("id3-scan: decode header error (frame %d): %s\n",Frames,mad_stream_errorstr(&stream)))
   455         errcount++;
   456         if(errcount<MAX_FRAME_ERR*100 && MAD_RECOVERABLE(stream.error)) continue;
   457         res=false; break;
   458         }
   459       }
   460     errcount=0;
   461     if(header.bitrate>maxrate) maxrate=header.bitrate;
   462     if(header.bitrate<minrate) minrate=header.bitrate;
   463 
   464     // Limit xing testing to the first frame header
   465     if(!Frames) {
   466       if((xframes=ParseXing(&stream.anc_ptr, stream.anc_bitlen))>=0) {
   467         is_vbr=true;
   468         }
   469       }                
   470     // Test the first n frames to see if this is a VBR file
   471     if(!is_vbr && Frames<MIN_SCAN_FRAMES) {
   472       if(bitrate && header.bitrate!=bitrate) is_vbr=true;
   473       else bitrate=header.bitrate;
   474       }
   475     // We have to assume it's not a VBR file if it hasn't already been
   476     // marked as one and we've checked n frames for different bitrates
   477     else if(!is_vbr && has_id3)
   478       {
   479       break;
   480       }
   481 
   482     Frames++;
   483     mad_timer_add(&duration,header.duration);
   484     }
   485   mad_header_finish(&header);
   486   mad_stream_finish(&stream);
   487 
   488   if(res) {
   489     d(printf("mad: scanned %d frames%s\n",Frames,Frames?"":"(is this really a mp3?)"))
   490     if(Frames) {
   491       SampleFreq=header.samplerate;
   492       Channels=MAD_NCHANNELS(&header);
   493       ChMode=header.mode;
   494       DecoderID=DEC_MP3;
   495       InfoDone();
   496 
   497       if(!is_vbr) {
   498         d(printf("mad: constant birate\n"))
   499         double time = (str->Filesize * 8.0) / (header.bitrate);  // time in seconds
   500         long nsamples = 32 * MAD_NSBSAMPLES(&header);   // samples per frame
   501 
   502         Frames = (long)(time * header.samplerate / nsamples);
   503         Total  = (long)time;
   504         Bitrate= (int)bitrate;
   505         }
   506       else if(xframes>0) {
   507         d(printf("mad: vbr, but has Xing frame\n"))
   508         mad_timer_multiply(&header.duration, xframes);
   509         Frames = xframes;
   510         Total  = mad_timer_count(header.duration,MAD_UNITS_SECONDS);
   511         }
   512       else {
   513         // the durations have been added up, and the number of frames counted. We do nothing here.
   514         d(printf("mad: vbr detected\n"))
   515         Total      = mad_timer_count(duration,MAD_UNITS_SECONDS);
   516         Bitrate    = (int)minrate;
   517         MaxBitrate = (int)maxrate;
   518         }
   519 
   520       if(!has_id3 || !Title) FakeTitle(str->Filename,".mp3");
   521       InfoCache.Cache(this,str);
   522       ConvertToSys();
   523       }
   524     }
   525   return Abort(res);
   526 }
   527 
   528 // This function was adapted from player.c, from the 
   529 // libmad distribution
   530 
   531 struct id3_tag *cScanID3::GetID3(struct mad_stream *stream, id3_length_t tagsize) const
   532 {
   533   struct id3_tag *tag=0;
   534   const id3_byte_t *data;
   535   id3_byte_t *allocated=0;
   536 
   537   id3_length_t count=stream->bufend-stream->this_frame;
   538 
   539   if(count>=tagsize) {
   540     data=stream->this_frame;
   541     mad_stream_skip(stream,tagsize);
   542     }
   543   else {
   544     if(!(allocated=(id3_byte_t *)malloc(tagsize))) {
   545       esyslog("ERROR: not enough memory for id3 tag buffer");
   546       return 0;
   547       }
   548     memcpy(allocated,stream->this_frame,count);
   549     mad_stream_skip(stream,count);
   550 
   551     while(count<tagsize) {
   552       unsigned char *sdata;
   553       unsigned long len, slen;
   554 
   555       if(!str->Stream(sdata,slen) || !slen) {
   556          d(printf("mad: error or eof on ID3 tag parse\n"))
   557          free(allocated);
   558          return 0;
   559          }
   560       len=tagsize-count; if(len>slen) len=slen;
   561       memcpy(allocated+count,sdata,len);
   562       count+=len;
   563       sdata+=len; slen-=len;
   564       if(slen) mad_stream_buffer(stream,sdata,slen);
   565       }
   566     data=allocated;
   567     }
   568 
   569   tag=id3_tag_parse(data,tagsize);
   570   if(allocated) free(allocated);
   571   return tag;
   572 }
   573 
   574 void cScanID3::ParseID3(const struct id3_tag *tag)
   575 {
   576   d(printf("id3-scan: parsing ID3 tag\n"))
   577   ParseStr(tag,ID3_FRAME_TITLE,Title);
   578   ParseStr(tag,ID3_FRAME_ARTIST,Artist);
   579   ParseStr(tag,ID3_FRAME_ALBUM,Album);
   580   char *data=0;
   581   ParseStr(tag,ID3_FRAME_YEAR,data);
   582   if(data) Year=atol(data);
   583   free(data);
   584   //ParseStr(tag,ID3_FRAME_TRACK,Track);
   585   //ParseStr(tag,ID3_FRAME_GENRE,Genre);
   586 }
   587 
   588 /*
   589 void cScanID3::ParsePic(const struct id3_tag *tag, const char *id, char * &name)
   590 {
   591   const struct id3_frame *frame=id3_tag_findframe(tag,id,0);
   592   if(frame) {
   593     id3_length_t len;
   594     const id3_byte_t *data=id3_field_getbinarydata(&frame->fields[1],&len);
   595     if(data && len>0) {
   596       static const char salt[] = { "$1$id3__pic$" };
   597       
   598       }
   599     }
   600 }
   601 */
   602 
   603 // This function was adapted from player.c, from the 
   604 // libmad distribution 
   605 
   606 void cScanID3::ParseStr(const struct id3_tag *tag, const char *id, char * &data)
   607 {
   608   const struct id3_frame *frame=id3_tag_findframe(tag,id,0);
   609   if(!frame) return;
   610 
   611   free(data); data=0;
   612   const union id3_field *field=&frame->fields[1];
   613   if(id3_field_getnstrings(field)>0) {
   614     const id3_ucs4_t *ucs4=id3_field_getstrings(field,0);
   615     if(!ucs4) return;
   616     if(!strcmp(id,ID3_FRAME_GENRE)) ucs4=id3_genre_name(ucs4);
   617     data=(char *)id3_ucs4_utf8duplicate(ucs4);
   618     }
   619 }
   620 
   621 // XING parsing was adapted from the MAD winamp input plugin,
   622 // from the libmad distribution
   623 
   624 #define XING_MAGIC (('X'<<24) | ('i'<<16) | ('n'<<8) | 'g')
   625 #define XING_FRAMES 0x0001
   626 // #define XING_BYTES  0x0002
   627 // #define XING_TOC    0x0004
   628 // #define XING_SCALE  0x0008
   629 
   630 int cScanID3::ParseXing(struct mad_bitptr *ptr, unsigned int bitlen) const
   631 {
   632   if(bitlen>=64 && mad_bit_read(ptr,32)==XING_MAGIC) {
   633     int flags=mad_bit_read(ptr, 32);
   634     bitlen-=64;
   635     return (bitlen>=32 && (flags & XING_FRAMES)) ? mad_bit_read(ptr,32) : 0;
   636     }
   637   return -1;
   638 }