2 * MP3/MPlayer plugin to VDR (C++)
4 * (C) 2001-2009 Stefan Huelswitt <s.huelswitt@gmx.de>
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.
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.
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
27 #include "decoder-mp3.h"
30 #define MAX_FRAME_ERR 10
32 // ----------------------------------------------------------------
34 int MadStream(struct mad_stream *stream, cStream *str)
38 if(str->Stream(data,len,stream->next_frame)) {
39 if(len>0) mad_stream_buffer(stream, data, len);
45 // --- cMP3Decoder -------------------------------------------------------------
47 cMP3Decoder::cMP3Decoder(const char *Filename, bool preinit)
50 str=0; scan=0; isStream=false;
52 //d(printf("mp3: preinit\n"))
53 str=new cStream(filename);
54 scan=new cScanID3(str,&urgentLock);
56 fi=0; stream=0; frame=0; synth=0;
59 cMP3Decoder::~cMP3Decoder()
66 bool cMP3Decoder::Valid(void)
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()) {
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;
82 else if(!MAD_RECOVERABLE(stream.error)) break;
88 mad_header_finish(&header);
89 mad_stream_finish(&stream);
96 cFileInfo *cMP3Decoder::FileInfo(void)
99 if(str->HasInfo()) fi=str;
101 if(str->Open()) { fi=str; str->Close(); }
107 cSongInfo *cMP3Decoder::SongInfo(bool get)
110 if(scan->HasInfo()) si=scan;
111 else if(get && TryLock()) {
112 if(scan->DoScan()) si=scan;
118 cPlayInfo *cMP3Decoder::PlayInfo(void)
121 pi.Index=mad_timer_count(playtime,MAD_UNITS_SECONDS);
122 pi.Total=scan->Total;
128 void cMP3Decoder::Init(void)
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;
142 void cMP3Decoder::Clean(void)
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; }
151 bool cMP3Decoder::Start(void)
154 Init(); playing=true;
155 if(str->Open() && scan->DoScan(true)) {
158 framemax=scan->Frames+20;
159 fi=new struct FrameInfo[framemax];
160 if(!fi) esyslog("ERROR: no memory for frame index, rewinding disabled");
171 bool cMP3Decoder::Stop(void)
182 struct Decode *cMP3Decoder::Done(eDecodeStatus status)
185 ds.index=mad_timer_count(playtime,MAD_UNITS_MILLISECONDS);
187 Unlock(); // release the lock from Decode()
191 eDecodeStatus cMP3Decoder::DecodeError(bool hdr)
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;
198 else if(!MAD_RECOVERABLE(stream->error)) {
199 d(printf("mad: decode %sfailed, frame=%d: %s\n",hdr?"hdr ":"",framenum,mad_stream_errorstr(stream)))
203 if(stream->error==MAD_ERROR_LOSTSYNC) { // check for ID3 tags
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);
211 id3_length_t count=stream->bufend-stream->this_frame;
212 id3_length_t tagsize=id3_tag_query(stream->this_frame,count);
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;
220 if(!str->Stream(sdata,slen)) return dsError;
221 if(slen<=0) return dsEof;
222 unsigned long len=min(tagsize-count,slen);
224 sdata+=len; slen-=len;
225 if(slen>0) mad_stream_buffer(stream,sdata,slen);
231 d(printf("mad: decode %serror, frame=%d count=%d: %s\n",hdr?"hdr ":"",framenum,errcount,mad_stream_errorstr(stream)))
236 struct Decode *cMP3Decoder::Decode(void)
238 Lock(); // this is released in Done()
241 if(errcount>=MAX_FRAME_ERR*100) {
242 esyslog("ERROR: excessive decoding errors, aborting file %s",filename);
243 return Done(dsError);
246 if(mad_header_decode(&frame->header,stream)<0) {
247 if((r=DecodeError(true))) return Done(r);
252 if(framenum>=framemax) printf("mp3: framenum >= framemax!!!!\n");
254 if(fi && framenum<framemax) {
255 fi[framenum].Pos=str->BufferPos() + (stream->this_frame-stream->buffer);
256 fi[framenum].Time=playtime;
260 mad_timer_add(&playtime,frame->header.duration); framenum++;
262 if(mad_timer_compare(playtime,skiptime)>=0) skiptime=mad_timer_zero;
263 else return Done(dsSkip); // skipping, decode next header
265 if(mad_frame_decode(frame,stream)<0) {
266 if((r=DecodeError(false))) return Done(r);
270 scan->InfoHook(&frame->header);
271 mad_synth_frame(synth,frame);
272 if(mute) { mute--; return Done(dsSkip); }
277 return Done(dsError);
280 void cMP3Decoder::MakeSkipTime(mad_timer_t *skiptime, mad_timer_t playtime, int secs, float bsecs)
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)))
295 bool cMP3Decoder::Skip(int Seconds, float bsecs)
299 if(playing && !isStream) {
300 if(!mad_timer_compare(skiptime,mad_timer_zero)) { // allow only one skip at any time
302 MakeSkipTime(&time,playtime,Seconds,bsecs);
304 if(mad_timer_compare(playtime,time)<=0) { // forward skip
306 int i=mad_timer_count(time,MAD_UNITS_SECONDS);
307 printf("mp3: forward skipping to %02d:%02d\n",i/60,i%60);
309 skiptime=time; mute=1;
312 else { // backward skip
315 int i=mad_timer_count(time,MAD_UNITS_SECONDS);
316 printf("mp3: rewinding to %02d:%02d\n",i/60,i%60);
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);
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);
337 // --- cScanID3 ----------------------------------------------------------------
339 // This function was adapted from mad_timer, from the
340 // libmad distribution
342 #define MIN_SCAN_FRAMES 200 // min. number of frames to scan
344 cScanID3::cScanID3(cStream *Str, bool *Urgent)
350 bool cScanID3::Abort(bool result)
352 if(!keepOpen) str->Close();
356 bool cScanID3::DoScan(bool KeepOpen)
358 mad_timer_t duration=mad_timer_zero;
359 unsigned int bitrate=0, minrate=~0, maxrate=0;
361 unsigned int id3_vers=0;
362 bool is_vbr=false, has_id3=false;
365 if(!str->Open()) return Abort(false);
366 if(HasInfo()) return Abort(true);
368 // check the infocache
369 cCacheData *dat=InfoCache.Search(str);
371 Set(dat); dat->Unlock();
375 InfoCache.Cache(this,str);
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)) {
387 if(str->Stream(data,len)) {
388 struct id3_tag *tag=id3_tag_parse(data,len);
390 d(printf("id3-scan: initialy found ID3 V1 tag at EOF\n"))
392 has_id3=true; id3_vers=tag->version;
397 if(!str->Seek()) return Abort(false);
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
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.
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);
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
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);
430 else if(stream.error==MAD_ERROR_LOSTSYNC) { // check for ID3 tags
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);
438 id3_length_t tagsize=id3_tag_query(stream.this_frame,stream.bufend-stream.this_frame);
440 struct id3_tag *tag=GetID3(&stream,tagsize);
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) {
446 has_id3=true; id3_vers=vers;
454 d(printf("id3-scan: decode header error (frame %d): %s\n",Frames,mad_stream_errorstr(&stream)))
456 if(errcount<MAX_FRAME_ERR*100 && MAD_RECOVERABLE(stream.error)) continue;
461 if(header.bitrate>maxrate) maxrate=header.bitrate;
462 if(header.bitrate<minrate) minrate=header.bitrate;
464 // Limit xing testing to the first frame header
466 if((xframes=ParseXing(&stream.anc_ptr, stream.anc_bitlen))>=0) {
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;
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)
483 mad_timer_add(&duration,header.duration);
485 mad_header_finish(&header);
486 mad_stream_finish(&stream);
489 d(printf("mad: scanned %d frames%s\n",Frames,Frames?"":"(is this really a mp3?)"))
491 SampleFreq=header.samplerate;
492 Channels=MAD_NCHANNELS(&header);
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
502 Frames = (long)(time * header.samplerate / nsamples);
504 Bitrate= (int)bitrate;
507 d(printf("mad: vbr, but has Xing frame\n"))
508 mad_timer_multiply(&header.duration, xframes);
510 Total = mad_timer_count(header.duration,MAD_UNITS_SECONDS);
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;
520 if(!has_id3 || !Title) FakeTitle(str->Filename,".mp3");
521 InfoCache.Cache(this,str);
528 // This function was adapted from player.c, from the
529 // libmad distribution
531 struct id3_tag *cScanID3::GetID3(struct mad_stream *stream, id3_length_t tagsize) const
533 struct id3_tag *tag=0;
534 const id3_byte_t *data;
535 id3_byte_t *allocated=0;
537 id3_length_t count=stream->bufend-stream->this_frame;
540 data=stream->this_frame;
541 mad_stream_skip(stream,tagsize);
544 if(!(allocated=(id3_byte_t *)malloc(tagsize))) {
545 esyslog("ERROR: not enough memory for id3 tag buffer");
548 memcpy(allocated,stream->this_frame,count);
549 mad_stream_skip(stream,count);
551 while(count<tagsize) {
552 unsigned char *sdata;
553 unsigned long len, slen;
555 if(!str->Stream(sdata,slen) || !slen) {
556 d(printf("mad: error or eof on ID3 tag parse\n"))
560 len=tagsize-count; if(len>slen) len=slen;
561 memcpy(allocated+count,sdata,len);
563 sdata+=len; slen-=len;
564 if(slen) mad_stream_buffer(stream,sdata,slen);
569 tag=id3_tag_parse(data,tagsize);
570 if(allocated) free(allocated);
574 void cScanID3::ParseID3(const struct id3_tag *tag)
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);
581 ParseStr(tag,ID3_FRAME_YEAR,data);
582 if(data) Year=atol(data);
584 //ParseStr(tag,ID3_FRAME_TRACK,Track);
585 //ParseStr(tag,ID3_FRAME_GENRE,Genre);
589 void cScanID3::ParsePic(const struct id3_tag *tag, const char *id, char * &name)
591 const struct id3_frame *frame=id3_tag_findframe(tag,id,0);
594 const id3_byte_t *data=id3_field_getbinarydata(&frame->fields[1],&len);
596 static const char salt[] = { "$1$id3__pic$" };
603 // This function was adapted from player.c, from the
604 // libmad distribution
606 void cScanID3::ParseStr(const struct id3_tag *tag, const char *id, char * &data)
608 const struct id3_frame *frame=id3_tag_findframe(tag,id,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);
616 if(!strcmp(id,ID3_FRAME_GENRE)) ucs4=id3_genre_name(ucs4);
617 data=(char *)id3_ucs4_utf8duplicate(ucs4);
621 // XING parsing was adapted from the MAD winamp input plugin,
622 // from the libmad distribution
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
630 int cScanID3::ParseXing(struct mad_bitptr *ptr, unsigned int bitlen) const
632 if(bitlen>=64 && mad_bit_read(ptr,32)==XING_MAGIC) {
633 int flags=mad_bit_read(ptr, 32);
635 return (bitlen>=32 && (flags & XING_FRAMES)) ? mad_bit_read(ptr,32) : 0;