]> git.vomp.tv Git - vompclient.git/blob - demuxeraudio.cc
0.2.7 readiness patches for Windows
[vompclient.git] / demuxeraudio.cc
1 /*
2     Copyright 2006 Mark Calderbank, Andreas Vogel
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP 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 VOMP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "demuxeraudio.h"
22 #include "audio.h"
23 #include "i18n.h"
24
25 #define HDRBYTE1 0xff
26 #define HDRBYTE2 0xe0
27 #define HDRBYTE2MASK 0xe0
28
29
30
31 class PacketBuffer {
32   
33   public:
34     PacketBuffer(Stream *as,UCHAR strtype) {
35       log=Log::getInstance();
36       audio=as;
37       streamtype=strtype;
38       newStream();
39     }
40     //just handle the data (do not deal with headers)
41     int putInternal(UCHAR* buf,int len);
42     void reset(){
43       partPacket=0;
44       bytesWritten=0;
45       framelen=DemuxerAudio::PACKET_SIZE;
46     }
47     void newStream() {
48       reset();
49       numpackets=0;
50       numbytes=0;
51                         skipfactor=0;
52                         numskip=0;
53     }
54     bool bufferFull() {
55       return (partPacket>=framelen);
56     }
57     //can we write a new packet?
58     bool bufferEmpty() {
59       return partPacket==0;
60     }
61     //only set this, if buffer empty
62     //otherwise ignored!
63     bool setFramelen(int len) {
64       if (! bufferEmpty() ) return false;
65       if (len > (int)DemuxerAudio::PACKET_SIZE) return false;
66       framelen=len;
67       return true;
68     }
69     //how much bytes do we need to fill the packet?
70     int bytesMissing() {
71       return framelen-partPacket;
72     }
73     int getFramelen() {
74       return framelen;
75     }
76                 void setSkipFactor(int factor) {
77                         skipfactor=factor;
78                         numskip=0;
79                 }
80   private:
81     void packetWritten() {
82       numbytes+=framelen;
83       //log->log("DemuxerAudio::PacketBuffer",Log::DEBUG,"written packet %ld l=%d, bytes %ld",numpackets,framelen,numbytes);
84       numpackets++;
85       reset();
86     }
87                 bool doSkip();
88     UCHAR store[DemuxerAudio::PACKET_SIZE]; // Storage for partial packets
89     int partPacket;    // Length of partial packet stored from previous put()
90     int bytesWritten;  //if they are !=0 and != framelength the stream is full...
91     int framelen;
92     Log * log;
93     Stream * audio;
94     UCHAR streamtype;
95     //global counters
96     ULONG numpackets;
97     ULONG numbytes;
98                 int skipfactor;
99                 int numskip;
100 };
101
102
103 DemuxerAudio::DemuxerAudio(int p_vID, int p_aID)
104 {
105   inSync=false;
106   isStarting=true;
107   log=Log::getInstance();
108   readHeaders=0;
109   streamtype=Audio::MP3;
110   buffer=new PacketBuffer(&audiostream,streamtype);
111 //  buffer=new PacketBuffer(&teststream,streamtype);
112   globalBytesWritten=0;
113   id3=NULL;
114   info=NULL;
115         vbr=NULL;
116   reset();
117 }
118
119 DemuxerAudio::~DemuxerAudio() {
120   delete buffer;
121   if(info) delete info;
122   if(id3) delete id3;
123         if (vbr) delete vbr;
124 }
125
126 void DemuxerAudio::flush()
127 {
128   Demuxer::flushAudio();
129   buffer->newStream();
130   tmpFill=0;
131 }
132
133 void DemuxerAudio::reset() {
134   buffer->newStream();
135   tmpFill=0;
136   readHeaders=0;
137   outOfSync=0;
138   globalBytesWritten=0;
139   if (id3) delete id3;
140   id3=NULL;
141   if (info) delete info;
142   info=NULL;
143         if (vbr) delete vbr;
144         vbr=NULL;
145   inSync=false;
146   hasHdrInfo=false;
147   hasVBRInfo=false;
148   isStarting=true;
149   hdrBitrate=128000;
150   hdrSamplingRate=44100;
151   avrBitrate=0;
152   hdrFramelen=0;
153   isStarting=true;
154 }
155
156 int DemuxerAudio::scan(UCHAR *buf, int len)
157 {
158   //no differend pids here
159   return 0;
160 }
161
162 void DemuxerAudio::setVID(int p_vID)
163 {
164 }
165
166 void DemuxerAudio::setAID(int p_aID)
167 {
168 }
169
170 static char * id3_1_genre[] = {
171   "Blueshhh",
172   "Classic Rock",
173   "Country",
174   "Dance",
175   "Disco",
176   "Funk",
177   "Grunge",
178   "Hip-Hop",
179   "Jazz",
180   "Metal",
181   "New Age",
182   "Oldies",
183   "Other",
184   "Pop",
185   "R&B",
186   "Rap",
187   "Reggae",
188   "Rock",
189   "Techno",
190   "Industrial",
191   "Alternative",
192   "Ska",
193   "Death Metal",
194   "Pranks",
195   "Soundtrack",
196   "Euro-Techno",
197   "Ambient",
198   "Trip-Hop",
199   "Vocal",
200   "Jazz+Funk",
201   "Fusion",
202   "Trance",
203   "Classical",
204   "Instrumental",
205   "Acid",
206   "House",
207   "Game",
208   "Sound Clip",
209   "Gospel",
210   "Noise",
211   "AlternRock",
212   "Bass",
213   "Soul",
214   "Punk",
215   "Space",
216   "Meditative",
217   "Instrumental Pop",
218   "Instrumental Rock",
219   "Ethnic",
220   "Gothic",
221   "Darkwave",
222   "Techno-Industrial",
223   "Electronic",
224   "Pop-Folk",
225   "Eurodance",
226   "Dream",
227   "Southern Rock",
228   "Comedy",
229   "Cult",
230   "Gangsta",
231   "Top 40",
232   "Christian Rap",
233   "Pop/Funk",
234   "Jungle",
235   "Native American",
236   "Cabaret",
237   "New Wave",
238   "Psychadelic",
239   "Rave",
240   "Showtunes",
241   "Trailer",
242   "Lo-Fi",
243   "Tribal",
244   "Acid Punk",
245   "Acid Jazz",
246   "Polka",
247   "Retro",
248   "Musical",
249   "Rock & Roll",
250   "Hard Rock"
251 };
252
253
254
255 static int bitrateTable[16][5]={
256 /*        L1,L2,L3,2L1,2L2 */
257 /*0000*/ {-1,-1,-1,-1,-1},
258 /*0001*/ {32,32,32,32,8},
259 /*0010*/ {64,48,40,48,16},
260 /*0011*/ {96,56,48,56,24},
261 /*0100*/ {128,64,56,64,32},
262 /*0101*/ {160,80,64,80,40},
263 /*0110*/ {192,96,80,96,48},
264 /*0111*/ {224,112,96,112,56},
265 /*1000*/ {256,128,112,128,64},
266 /*1001*/ {288,160,128,144,80},
267 /*1010*/ {320,192,160,160,96},
268 /*1011*/ {352,224,192,176,112},
269 /*1100*/ {384,256,224,192,128},
270 /*1101*/ {416,320,256,224,144},
271 /*1110*/ {448,384,320,256,160},
272 /*1111*/ {-1,-1,-1,-1,-1} };
273
274 static int  samplingRateTable[4][3]={
275 /*00*/ {44100,22050,11025},
276 /*01*/ {48000,24000,12000},
277 /*10*/ {32000,16000,8000},
278 /*11*/ {-1,-1,-1}};
279
280 //max 7 char!
281 static const char * mpegString(UCHAR code) {
282   switch(code) {
283     case 0:
284       return "MPEG2.5";
285     case 1:
286       return "RESERV";
287     case 2:
288       return "MPEG 2";
289     case 3:
290       return "MPEG 1";
291   }
292   return "UNKNOWN";
293 }
294
295 static const char * layerString(UCHAR code) {
296   switch(code) {
297     case 0:
298       return "Layer reserved";
299     case 1:
300       return "Layer III";
301     case 2:
302       return "Layer II";
303     case 3:
304       return "Layer I";
305   }
306   return "Layer UNKNOWN";
307 }
308 /**
309   * parse an id3 Header
310   * provided by Brian Walton
311   * @returns -1 of nothing found
312   */
313   
314 int DemuxerAudio::id3_2_3_FrameParse(unsigned char buf[], id3_frame *frame)
315 {
316   if (buf[0] < 0x20 || buf[1] < 0x20 || buf [2] < 0x20 ) return -1;
317   frame->size = (buf[4] & 0x7F) << 21 | (buf[5] & 0x7F) << 14 |  (buf[6] & 0x7F) << 7 | (buf[7] & 0x7F);
318   if (frame->size == 0) return -1;
319   //TODO. clearify flags against:
320   //http://id3.org/id3v2.3.0#head-697d09c50ed7fa96fb66c6b0a9d93585e2652b0b
321   frame->flags.tagAlterPreserv = (buf[8] & 0x80) >> 7;
322   frame->flags.filelterPreserv = (buf[8] & 0x40) >> 6;
323   frame->flags.readOnly = (buf[8] & 0x20) >> 5;
324   frame->flags.groupId = (buf[9] & 0x20) >> 5;
325   frame->flags.compression = (buf[9] & 0x80) >> 7;
326   frame->flags.encryption = (buf[9] & 0x40) >> 6;
327   frame->flags.unsync = 0;
328   frame->flags.dataLen = 0;
329   return 0;
330 }
331
332  /**
333   * parse an id3 Header
334   * provided by Brian Walton
335   * @returns -1 of nothing found
336   */
337   
338 int DemuxerAudio::id3_2_2_FrameParse(unsigned char buf[], id3_frame *frame)
339 {
340   if (buf[0] < 0x20 || buf[1] < 0x20 || buf[2] < 0x20) return -1;
341   frame->size = (buf[3] & 0x7F) << 14 |  (buf[4] & 0x7F) << 7 | (buf[5] & 0x7F);
342   if (frame->size == 0) return -1;
343   return 0;
344 }
345
346
347 //fill an id3tag from a frame payload
348 //http://id3.org/id3v2.3.0#head-697d09c50ed7fa96fb66c6b0a9d93585e2652b0b
349 //http://id3.org/id3v2-00
350 static struct tagid {
351   const char * bytes;
352   int index;
353 } knownFrames[]= {
354   //ID3V2.3
355   {"TIT2",1}, //title
356   {"TPE1",2}, //artist
357   {"TCON",3}, //genre
358   {"TRCK",6}, //track
359   {"TYER",4}, //year
360   {"TALB",5}, //album
361   {"TCOM",7}, //composer
362   {"COMM",8}, //comment
363               //Text encoding           $xx
364               //Language                $xx xx xx
365               //Short content descrip.  <text string according to encoding> $00 (00)
366               //The actual text         <full text string according to encoding>
367   //ID3V2.0
368   {"TT2",1 },
369   {"TP1",2 },
370   {"TCM",7 },
371   {"TCO",3 }, //(genreNumber)
372   {"TAL",5 },
373   {"TRK",6 },
374   {"TYE",4 },
375   {"COM",8 }
376 };
377 #define NUMKNOWN (sizeof(knownFrames)/sizeof(knownFrames[0]))
378
379 /*fill in infos
380   from an ID3 V2.x, V2.3 frame into the tags structure
381   frameData must point to the header
382   framelen is the len without header (10 Bytes for V23, 6 Bytes for v2x)
383   */
384
385 #define MAXLEN(tagtype) ((UINT)frameLen<sizeof(tag->tagtype)-1?(UINT)frameLen:sizeof(tag->tagtype)-1)
386 bool DemuxerAudio::fillId3Tag(id3_tag * tag,UCHAR * frameData, int frameLen, int dataOffset, bool v23) {
387   int tl=v23?4:3;
388   int tagIndex=-1;
389   if (tag == NULL) return false;
390   if (frameLen < 2) return false;
391   for (UINT i=0;i< NUMKNOWN;i++) {
392     if(strncmp((char *)frameData,knownFrames[i].bytes,tl) == 0) {
393       tagIndex=knownFrames[i].index;
394       break;
395     }
396   }
397   if (tagIndex < 0) return false;
398   UCHAR encoding=*(frameData+dataOffset);
399   dataOffset++;
400   frameLen--;
401   if (encoding != 0) {
402     log->log("DemuxerAudio",Log::DEBUG,"unknown encoding for tag %d, tagid %s",encoding,
403         knownFrames[tagIndex].bytes);
404     return false;
405   }
406   switch(tagIndex) {
407     case 1:  //title
408       strncpy(tag->title,(char*)(frameData+dataOffset),MAXLEN(title));
409       tag->title[MAXLEN(title)]=0;
410       break;
411     case 2:  //artist
412       strncpy(tag->artist,(char*)(frameData+dataOffset),MAXLEN(artist));
413       tag->artist[MAXLEN(artist)]=0;
414       break;
415     case 3:  //genre
416       {
417       UCHAR * st=frameData+dataOffset;
418       int genre=0;
419       if (*st=='(') {
420         genre=atoi((const char *)(st+1)) && 31;
421         st=(UCHAR *)id3_1_genre[genre];
422       }
423       strncpy(tag->genre,(char*)st,MAXLEN(genre));
424       tag->genre[MAXLEN(genre)]=0;
425       break;
426       }
427     case 4:  //year
428       strncpy(tag->year,(char *)(frameData+dataOffset),MAXLEN(year));
429       tag->year[MAXLEN(year)]=0;
430       break;
431     case 5:  //album
432       strncpy(tag->album,(char *)(frameData+dataOffset),MAXLEN(album));
433       tag->album[MAXLEN(album)]=0;
434       break;
435     case 6:  //track
436       strncpy(tag->track,(char *)(frameData+dataOffset),MAXLEN(track));
437       tag->track[MAXLEN(track)]=0;
438       break;
439     case 7:  //composer
440       strncpy(tag->composer,(char *)(frameData+dataOffset),MAXLEN(composer));
441       tag->composer[MAXLEN(composer)]=0;
442       break;
443     case 8:  //comment
444       strncpy(tag->comment,(char *)(frameData+dataOffset),MAXLEN(comment));
445       tag->comment[MAXLEN(comment)]=0;
446       break;
447     default:
448       return false;
449   }
450
451   return true;
452 }
453
454 /**
455   * parse an id3 Header
456   * based on code provided by Brian Walton
457   * @returns -1 of nothing found
458   *  otherwise the id3 info is filled
459   */
460
461 int DemuxerAudio::parseID3V2(UCHAR *data, int len) {
462   int debug=0;
463   UCHAR * start=data;
464   id3_header id3header;
465   id3_frame id3frame;
466   id3_tag * id3tag=NULL;
467   //len = read(fd, data, 10);
468   if (len < 10) {
469     delete id3tag;
470     return -1;
471   }
472   len-=10;
473   if(data[0]=='I' && data[1]=='D' && data[2]=='3')
474   {
475     id3tag=new id3_tag();
476     id3header.major = data[3];
477     id3header.minor = data[4];
478     if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"ID3 V2.%d.%d found\n", id3header.major, id3header.minor);
479     id3header.flags.unsynchronisation = (data[5] & 0x80)>>7;
480     id3header.flags.extended_header = (data[5] & 0x40)>>6;
481     id3header.flags.experimental = (data[5] & 0x20)>>5;
482     id3header.flags.footer = (data[5] & 0x10)>>4;
483     if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Unsynchronisation flag: %d\n", id3header.flags.unsynchronisation);
484     if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Extended header flag: %d\n", id3header.flags.extended_header);
485     if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Experimental indicator flag: %d\n", id3header.flags.experimental);
486     if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Footer present flag: %d\n", id3header.flags.footer);
487     id3header.size = (data[6] & 0x7F) << 21 | (data[7] & 0x7F) << 14 |  (data[8] & 0x7F) << 7 | (data[9] & 0x7F);
488     if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"ID3 Size: %d\n", id3header.size);
489     data=start+10;
490     if (len <= id3header.size) {
491       if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"header size to big %d, only %d bytes available\n",id3header.size,len);
492       delete id3tag;
493       return -1;
494     }
495     if (id3header.flags.extended_header)
496     {
497       int extended_hdr_hdr=4;  //still to be discussed (id3.org...)
498       //read extended header size
499       if (len < extended_hdr_hdr) {
500         if (debug) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"extended header found but cannot read\n");
501         delete id3tag;
502         return -1;
503       }
504       if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"remaining %d chars after extended hdr hdr\n", len);
505       id3header.extended_header.size = (data[0] & 0x7F) << 21 | (data[1] & 0x7F) << 14 |  (data[2] & 0x7F) << 7 | (data[3] & 0x7F);
506       if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Extended header size: %d\n", id3header.extended_header.size);
507       if (len <= id3header.extended_header.size+extended_hdr_hdr) {
508       if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"extended Header to big, only %d bytes available\n",len);
509         delete id3tag;
510         return -1;
511       }
512       //lseek(fd, id3header.extended_header.size - 6, SEEK_CUR);
513       data+=id3header.extended_header.size+extended_hdr_hdr;
514       len-=id3header.extended_header.size+extended_hdr_hdr;
515     }
516     //set the end of the header
517     UCHAR * eob=start+id3header.size+10;
518     bool readNext=true;
519     while (data < eob && readNext)
520     {
521       //skip over some padding - found this in lame MCDI tag...
522       if (*data == 0) {
523         data++;
524         continue;
525       }
526       readNext=false;
527       switch(id3header.major)
528       {
529         case 2: //ID3 V2.2.x
530           if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"version 2.2 frame, %d : %c %c %c\n", data-start,*data,*(data+1),*(data+2));
531           if (data + 6 >= eob)
532           {
533             break;
534           }
535           if (id3_2_2_FrameParse(data, &id3frame) < 0)
536           {
537             break;
538           }
539           if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"frame size: %d\n", id3frame.size);
540           fillId3Tag(id3tag,data,id3frame.size,6,false);
541           if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"frame payload: %s\n", data + 6 +1);
542           data+=6+id3frame.size;
543           readNext=true;
544           break;
545         case 3: //ID3 V2.3.x
546           {
547           if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"version 2.3 frame, %d : %c %c %c %c\n", data-start,
548               *data,*(data+1),*(data+2),*(data+3));
549           if (data + 10 >= eob)
550           {
551             break;
552           }
553           if (id3_2_3_FrameParse(data, &id3frame) <0)
554           {
555             break;
556           }
557           if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Frame size: %d\n", id3frame.size);
558           int dataOffset=10;
559           if (id3frame.flags.groupId)
560           {
561             dataOffset++;
562             if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Frame group: %d\n", data[dataOffset]);
563           }
564           if (id3frame.flags.compression)
565           {
566             if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Frame compressed: %d\n", id3frame.flags.compression);
567           }
568           if (id3frame.flags.encryption)
569           {
570             dataOffset+=1;
571             if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"Frame encryption method: %d\n", data[dataOffset]);
572           }
573           fillId3Tag(id3tag,data,id3frame.size-dataOffset+10,dataOffset,true);
574           if (debug != 0) log->log("DemuxerAudio::parseID3V2",Log::DEBUG,"frame payload: %s\n", data + dataOffset +1);
575           data+=10+id3frame.size;
576           readNext=true;
577           break;
578           }
579         default:
580           //don't support this version
581           delete id3tag;
582           return -1;
583       }
584     }
585
586     data=eob;
587     //store the found tag
588     if (id3) delete id3;
589     id3=id3tag;
590     return data-start;
591   }
592   return -1;
593 }
594
595 /**
596   * parse an id3v1 Header
597   * based on code provided by Brian Walton
598   * @returns -1 of nothing found
599   *  otherwise the id3 info is filled
600   */
601 #define MEMCPY(type,len,offset) {int type##max=sizeof(tag->type)-1<len?sizeof(tag->type)-1:len;strncpy(tag->type,(char*)&data[offset],type##max);tag->type[type##max]=0;}
602
603 int DemuxerAudio::parseID3V1(UCHAR *data, int len) {
604   int debug=1;
605   if (len < 128) return -1;
606   if(data[0]=='T' && data[1]=='A' && data[2]=='G')
607   {
608     id3_tag * tag=new id3_tag();
609     if (debug != 0)log->log("DemuxerAudio::parseID3V1",Log::DEBUG,"ID3 V1 tag found\n");
610     MEMCPY(title,30,3);
611     MEMCPY(artist,30,33);
612     MEMCPY(album,30,63);
613     MEMCPY(year,4,93);
614     if (data[125]==0 && data[126]!=0)
615     { //ID3 V1.1
616       if (debug != 0)log->log("DemuxerAudio::parseID3V1",Log::DEBUG,"ID3 V1.1 tag\n");
617       MEMCPY(comment,29,97);
618       sprintf(tag->track, "%d", data[126]);
619     } else {
620       if (debug != 0)log->log("DemuxerAudio::parseID3V1",Log::DEBUG,"ID3 V1.0 tag\n");
621       MEMCPY(comment,30,97);
622     }
623     if (data[127] < sizeof(id3_1_genre)/sizeof(id3_1_genre[0]))
624     {
625       sprintf(tag->genre, id3_1_genre[data[127]]);
626     }
627     if (id3) delete id3;
628     id3=tag;
629     return 0;
630   }
631   return -1;
632 }
633
634 //infos from http://www.multiweb.cz/twoinches/MP3inside.htm
635 int DemuxerAudio::parseVBR(UCHAR *data, int len) {
636         UCHAR *hdr=findHeader(data,len);
637         //we expect the header exactly here
638         if (hdr != data) return -1;
639         const static char * VBRHDR="Xing";
640         int vbridpos=36;
641   UCHAR mpgtype=(data[1] & 0x18)>>3;
642   UCHAR chmode=(data[2] & 0xc0) >> 6;
643   UCHAR layer=(data[2] & 0x06) >>1;
644         if ( mpgtype == 3 && chmode == 11) vbridpos=21;
645         if ( mpgtype != 3 && chmode != 11) vbridpos=21;
646         if ( mpgtype != 3 && chmode == 11) vbridpos=13;
647         //check for the header ID
648         if (vbridpos+(int)strlen(VBRHDR)+4 >= len) {
649                 Log::getInstance()->log("DemuxerAudio::parseVBR",Log::DEBUG,"frame to short for VBR header %d",len);
650                 return -1;
651         }
652         for (int i=4;i<vbridpos;i++) {
653                 if (data[i] != 0) {
654                   Log::getInstance()->log("DemuxerAudio::parseVBR",Log::DEBUG,"garbage when searching VBR header at pos %d",i);
655                         return -1;
656                 }
657         }
658         if ( strncmp((char *)&data[vbridpos],VBRHDR,strlen(VBRHDR)) != 0) {
659                 Log::getInstance()->log("DemuxerAudio::parseVBR",Log::DEBUG,"no VBR header at pos %d",vbridpos);
660                 return -1;
661         }
662         int framedata=vbridpos+strlen(VBRHDR);
663         int expectedLen=0;
664         //OK we should now have a valid vbr header
665         bool hasFramenum=data[framedata+3] & 1;
666         bool hasBytes=data[framedata+3] & 0x2;
667         bool hasTOC=data[framedata+3] & 0x4;
668         expectedLen+=8;
669         if (hasTOC) expectedLen+=100;
670         if (framedata+expectedLen > len) {
671                 Log::getInstance()->log("DemuxerAudio::parseVBR",Log::DEBUG,"frame to short for VBR header data %d, expected %d",
672                                 len,framedata+expectedLen);
673                 return -1;
674         }
675         if (!hasFramenum || ! hasBytes || ! hasTOC) {
676                 //not usefull for us..
677                 Log::getInstance()->log("DemuxerAudio::parseVBR",Log::DEBUG,"not all parts in VBR header - ignore");
678                 return -1;
679         }
680         framedata+=4;
681         if (vbr) delete vbr;
682         vbr=new vbrInfo();
683         vbr->numFrames=data[framedata] << 24 | data[framedata+1]<<16|
684                         data[framedata+2]<<8 |data[framedata+3];
685         framedata+=4;
686         vbr->numBytes=data[framedata] << 24 | data[framedata+1]<<16|
687                         data[framedata+2]<<8 |data[framedata+3];
688         framedata+=4;
689         for (int ti=0;ti<100;ti++) {
690                 vbr->table[ti]=data[framedata+ti];
691         }
692         //compute file size in seconds
693         //should be (#of frames -1) *samplesPerFrame / sampleRate
694         //TODO: difference for Mono?
695         ULONG samplesPerFrame=384; //layer1
696         if (layer != 3) samplesPerFrame=1152;
697         vbr->fileSeconds=(vbr->numFrames-1)*samplesPerFrame/hdrSamplingRate;
698         Log::getInstance()->log("DemuxerAudio::parseVBR",Log::DEBUG,"successfully read VBR %ldbytes, %ld frames, %ldsec",
699                         vbr->numBytes,vbr->numFrames,vbr->fileSeconds);
700         return hdrFramelen;
701 }
702
703
704
705
706
707
708
709 UCHAR * DemuxerAudio::findHeader(UCHAR *buf, int len, bool writeInfo) {
710   while (len >= 3) //assume hdr+crc
711   {
712     UCHAR pattern=*buf;
713     buf++; len--;
714     if (pattern != HDRBYTE1 ) continue;
715     if ((*buf & HDRBYTE2MASK) != HDRBYTE2) continue;
716     if (readHeader((buf-1),4,writeInfo) != 0) continue;
717     return buf-1;
718   }
719   return NULL;
720 }
721
722
723
724 int DemuxerAudio::readHeader(UCHAR * hbuf,int len,bool writeInfo) {
725   int curFramelen=0;
726   int curBitrate=0;
727   int curSamplingRate=0;
728   if (*hbuf != HDRBYTE1) return -1;
729   hbuf++;
730   if ((*hbuf & HDRBYTE2MASK) != HDRBYTE2) return -1;
731   UCHAR mpgtype=(*hbuf & 0x18)>>3;
732   if (mpgtype == 1) {
733     log->log("DemuxerAudio",Log::DEBUG,"header invalid mpgtype %s %i %i %i",
734         mpegString(mpgtype),*hbuf,*(hbuf+1),*(hbuf+2));
735     return 1;
736   }
737   UCHAR layer=(*hbuf & 0x06) >>1;
738   //bool hasCRC=!(*hbuf & 1);
739   hbuf++;
740   UCHAR bitrateCode=(*hbuf & 0xf0) >>4;
741   UCHAR samplingCode=(*hbuf & 0x0c) >> 2;
742   bool padding=*hbuf & 0x02;
743   hbuf++;
744   //0 Stereo, 1 JointStereo, 2 Dual, 3 Mono
745   UCHAR chmode=(*hbuf & 0xc0) >> 6;
746   //UCHAR extension=(*hbuf & 0x30) >> 4;
747
748   //layercode: 1-L3, 2-L2, 3-L1
749   //columns 0,1,2 for MPEG1
750   UCHAR bitrateColumn=3-layer;
751   if (bitrateColumn > 2) {
752     log->log("DemuxerAudio",Log::DEBUG,"header invalid layer %s %i %i %i",
753         layerString(layer),*(hbuf-2),*(hbuf-1),*hbuf);
754     return 1;
755   }
756   if (mpgtype != 3) bitrateColumn+=3;
757   if (bitrateColumn>4) bitrateColumn=4;
758   curBitrate=1000*bitrateTable[bitrateCode][bitrateColumn];
759   UCHAR sampleRateColumn=0;
760   if (mpgtype == 10) sampleRateColumn=1;
761   if (mpgtype == 0) sampleRateColumn=2;
762   curSamplingRate=samplingRateTable[samplingCode][sampleRateColumn];
763   if (curSamplingRate < 0 || curBitrate < 0) {
764     log->log("DemuxerAudio",Log::DEBUG,"header invalid rates br=%d sr=%d %i %i %i",
765         curBitrate,curSamplingRate,*(hbuf-2),*(hbuf-1),*hbuf);
766     return 1;
767   }
768   int padbytes=0;
769   if (padding) {
770     if (layer == 3) padbytes=4;
771     else padbytes=1;
772   }
773   if (layer == 3) {
774     //Layer 1
775     //FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4
776     curFramelen=(12*curBitrate/curSamplingRate+padbytes) * 4;
777   }
778   else {
779     //Layer 2/3
780     //FrameLengthInBytes = 144 * BitRate / SampleRate + Padding
781     curFramelen=144*curBitrate/curSamplingRate+padbytes;
782   }
783   //the header itself
784   if (curFramelen < 32) {
785   log->log("DemuxerAudio",Log::DEBUG,"read header %ld mpgv=%s lc=%s br=%d sr=%d, fl=%d-invalid %i %i %i",
786       readHeaders,mpegString(mpgtype),layerString(layer),
787       curBitrate,curSamplingRate,curFramelen,*(hbuf-2),*(hbuf-1),*hbuf);
788       return 1;
789   }
790   if (writeInfo || isStarting){
791   log->log("DemuxerAudio",Log::DEBUG,"read header %ld mpgv=%s lc=%s br=%d sr=%d, fl=%d %i %i %i",
792       readHeaders,mpegString(mpgtype),layerString(layer),
793       curBitrate,curSamplingRate,curFramelen,*(hbuf-2),*(hbuf-1),*hbuf);
794     if (info) delete info;
795     info=new mpegInfo();
796     strcpy(info->mpegVersion,mpegString(mpgtype));
797     info->mpegLayer=4-layer;
798     info->bitRate=curBitrate;
799     info->avrBitrate=curBitrate;
800     info->sampleRate=curSamplingRate;
801     const char *chmodStr=tr("Stereo");
802     switch (chmode) {
803       case 1: chmodStr=tr("JointStero");break;
804       case 2: chmodStr=tr("Dual");break;
805       case 3: chmodStr=tr("Mono");break;
806     }
807     SNPRINTF(info->info,sizeof(info->info)-1,"%s",chmodStr);
808   }
809         if (isStarting) avrBitrate=curBitrate;
810   isStarting=false;
811   readHeaders++;
812   //moving average F=0.005
813   avrBitrate=avrBitrate+((5*(curBitrate-avrBitrate))/1024);
814   hdrBitrate=curBitrate;
815   hdrFramelen=curFramelen;
816   hdrSamplingRate=curSamplingRate;
817         hasHdrInfo=true;
818   return 0;
819 }
820
821 int DemuxerAudio::findPTS(UCHAR* buf, int len, ULLONG* dest)
822 {
823   //we have no PTS number ...
824   *dest=0;
825   return (findHeader(buf,len) != NULL)?1:0;
826 }
827
828 bool PacketBuffer::doSkip() {
829         if (!bufferFull()) return false;
830         if (skipfactor == 0) return false;
831         numskip++;
832         if (numskip >= skipfactor) {
833                 //sent at least always 2 packets
834                 if (numskip > skipfactor) numskip=0;
835                 return false;
836         }
837         packetWritten();
838         return true;
839 }
840         
841 // just handle the real stream without dealing with the header
842 int PacketBuffer::putInternal(UCHAR * wbuf, int len)
843 {
844    /* Important, the type passed to stream must be a mediapacket type as defined in 
845        Draintarget.h and not the device setting of the mvp, so we have to translate it here,
846        in order to get it working on windows
847        --MR */
848   UCHAR mptype=0;
849   switch (streamtype) {
850         case Audio::MPEG1_PES: //?
851         case Audio::MPEG2_PES: //Important, this must be a PES !
852             mptype=MPTYPE_MPEG_AUDIO; break;
853         default:
854         case Audio::MP3: //this can be any Mpeg1 Audio not only layer 3 not packed into PES
855            mptype=MPTYPE_MPEG_AUDIO_LAYER3;break;
856   };
857   if (bufferFull()) {
858 #ifndef WIN32
859                 if (doSkip()) return 0;//NoSkip on Windows
860 #endif
861     //we are still full - so try to write
862     int sent=audio->put(store+bytesWritten,framelen-bytesWritten,/*streamtype*/mptype);
863     //log->log("DemuxerAudio::PacketBuffer",Log::DEBUG,"written %d bytes to stream (still full) pp=%d, framelen=%d, written=%d",sent,partPacket,framelen, bytesWritten );
864     if (sent < (framelen - bytesWritten)) {
865       //packet still not written
866       bytesWritten+=sent;
867       return 0;
868     }
869     packetWritten();
870     //let the demuxer come back with the rest - need to check header first
871     return 0;
872   }
873   if (partPacket+len >= framelen) {
874     //now we have at least a complete packet
875     int bytesConsumed=framelen-partPacket;
876     memcpy(store+partPacket,wbuf,bytesConsumed);
877     partPacket=framelen;
878     //log->log("DemuxerAudio::PacketBuffer",Log::DEBUG,"stored packet %ld, length %d (last %d) for stream %p",numpackets,framelen,bytesConsumed,audio );
879 #ifndef WIN32 //No Skip on Windows
880                 if (doSkip()) return bytesConsumed;
881 #endif
882     int sent=audio->put(store,framelen,mptype);
883     bytesWritten+=sent;
884     //log->log("DemuxerAudio::PacketBuffer",Log::DEBUG,"written %d bytes to stream",sent );
885     if (bytesWritten < framelen) {
886       //still not completely written
887       return bytesConsumed;
888     }
889     packetWritten();
890     //let the player come back...
891     return bytesConsumed;
892   }
893   //OK packet still not complete
894   if (len == 0) return 0;
895   int bytesConsumed=len;
896   memcpy(store+partPacket,wbuf,bytesConsumed);
897   partPacket+=bytesConsumed;
898   return bytesConsumed;
899 }
900
901 /**
902   major entry for data from a player
903   the demuxer is either in the state headerSearch (packet written or
904   just at the beginning), writing garbage (inSync=false) or
905   handling data (none set)
906   A header is expected at the first byte after the previous packet -
907   otherwise we switch to garbage where we always search for a header
908   (but anyway provide the data to the underlying device - it's probably
909   more intelligent then we are...
910   We only loose a correct position display.
911   */
912 int DemuxerAudio::put(UCHAR* wbuf, int len)
913 {
914   //return audiostream.put(wbuf,len,streamtype);
915   int framelen=PACKET_SIZE;
916   UCHAR *hdr;
917   int bytesConsumed=0;
918   int oldBytes=0;
919   if (tmpFill != 0 || (buffer->bufferEmpty() && len < HDRLEN)) {
920     //OK we have to copy everything to the tmp buffer
921     int cp=(UINT)len<(PACKET_SIZE-tmpFill)?(UINT)len:(PACKET_SIZE-tmpFill);
922     memcpy(&tmpBuffer[tmpFill],wbuf,cp);
923     oldBytes=tmpFill;
924     tmpFill+=cp;
925     wbuf=tmpBuffer;
926     len=tmpFill;
927     //if there is no header here and our buffer
928     //is empty - just wait for the next header
929     if (len < HDRLEN && buffer->bufferEmpty()) {
930       log->log("DemuxerAudio",Log::DEBUG,"len to small for header %d at bytes %ld",len,globalBytesWritten);
931       return cp;
932     }
933   }
934   while (bytesConsumed < len ) {
935     if (buffer->bufferFull()) {
936       //if this is the first part of the loop, try to write to the stream
937       if (bytesConsumed == 0) buffer->putInternal(wbuf,0);
938       //if the buffer is full, no need to continue
939       if (buffer->bufferFull()) break;
940     }
941     //either we are in a packet (buffer != full && buffer != empty)
942     //or we are searching a header
943     if (buffer->bufferEmpty()) {
944       if (len-bytesConsumed < HDRLEN) {
945         // we cannot  still search
946         if (tmpFill != 0) {
947           //we are already working at the buffer
948           break;
949         }
950         memcpy(tmpBuffer,wbuf,len-bytesConsumed);
951         tmpFill=len-bytesConsumed;
952         log->log("DemuxerAudio",Log::DEBUG,"len to small for header %d at bytes %ld",len,globalBytesWritten);
953         return len;
954       }
955
956       int lastFramelen=hdrFramelen;
957       //if the header has been valid before and we are searching
958       //it should be here
959       int maxsearch=((len-bytesConsumed) < (int)PACKET_SIZE)?len-bytesConsumed:(int)PACKET_SIZE;
960       hdr=findHeader(wbuf,maxsearch);
961       if (hdr != NULL) {
962         //log->log("DemuxerAudio",Log::DEBUG,"header found at offset %d",hdr-wbuf);
963         }
964       //hdr now points to the new header
965       if (hdr !=  wbuf) {
966         //still at least bytes before the header
967         inSync=false;
968         outOfSync++;
969         int garbageBytes=(hdr!=NULL)?(hdr-wbuf):maxsearch;
970         //we consider the garbage now as an own packet
971         //we can consume at most our buffer
972         //basically the buffer should be empty here (we are
973         //in header search - and we fill up each garbage
974
975         int nframesize=garbageBytes;
976         if (nframesize > (int)PACKET_SIZE) {
977           nframesize=(int)PACKET_SIZE;
978         }
979         if (! buffer->bufferEmpty()) {
980            log->log("DemuxerAudio",Log::WARN,"buffer not empty when having garbage to store");
981            //at the end no big problem, we only write the remaining bytes that we have...
982         }
983         else {
984           buffer->setFramelen(nframesize);
985         }
986         log->log("DemuxerAudio",Log::DEBUG,"garbage found at packet %ld (bytes %ld) of length %d, "
987             "framelen set to %d (last fl=%d)",
988             readHeaders,globalBytesWritten,garbageBytes,buffer->getFramelen(),lastFramelen);
989 #ifndef WIN32        
990         //hmm - we assume that he low level driver is more intelligent
991         //and give him the data "as is"
992         int written=buffer->putInternal(wbuf,garbageBytes);
993         globalBytesWritten+=written;
994         bytesConsumed+=written;
995         if (written != garbageBytes || hdr == NULL ) {
996           break;
997         }
998 #else //DS is not intelligent
999         globalBytesWritten+=garbageBytes;
1000         bytesConsumed+=garbageBytes;
1001 #endif
1002         //OK either all the "garbage" is written  or
1003         //we found the next header as expected
1004         //continue with the next package
1005         wbuf=hdr;
1006       }
1007       //we have to wait now until the buffer is 
1008       //free for the next package
1009       if ( ! buffer->bufferEmpty()) return bytesConsumed;
1010       //this is the place where we start a new packet
1011       framelen=hdrFramelen;
1012       if ( !buffer->setFramelen(framelen) ) {
1013         log->log("DemuxerAudio",Log::DEBUG,"unable to set framelen should=%d, current=%d",
1014             framelen,buffer->getFramelen());
1015             }
1016       inSync=true;
1017     }
1018     //now we are surely within a packet
1019     int written=buffer->putInternal(wbuf,len-bytesConsumed);
1020     //update the status
1021     globalBytesWritten+=written;
1022     wbuf+=written;
1023     bytesConsumed+=written;
1024     if (written == 0) {
1025       //stream is full
1026       break;
1027     }
1028     //OK - handle the rest
1029   }
1030   if (bytesConsumed >= oldBytes) {
1031     //if we consumed more than the old bytes - OK the buffer
1032     //can be thrown away
1033     tmpFill=0;
1034     return bytesConsumed-oldBytes;
1035   }
1036   else {
1037     //only consumed bytes from the buffer
1038     if (bytesConsumed == 0) {
1039       //restore the buffer
1040       tmpFill=oldBytes;
1041       return 0;
1042     }
1043     //shift bytes in buffer
1044     for (int i=0;i<oldBytes-bytesConsumed;i++) {
1045       tmpBuffer[i]=tmpBuffer[i+bytesConsumed];
1046     }
1047     tmpFill=oldBytes-bytesConsumed;
1048     return 0;
1049   }
1050 }
1051
1052 //info functions
1053 const id3_tag * DemuxerAudio::getId3Tag() {
1054   return id3;
1055
1056 }
1057 const DemuxerAudio::mpegInfo * DemuxerAudio::getMpegInfo() {
1058   if (! hasHdrInfo) return NULL;
1059         info->avrBitrate=avrBitrate;
1060         info->bitRate=hdrBitrate;
1061   return info;
1062 }
1063
1064 const DemuxerAudio::vbrInfo * DemuxerAudio::getVBRINfo() {
1065         return vbr;
1066 }
1067
1068 int DemuxerAudio::checkStart(UCHAR *b, int len) {
1069   UCHAR *start=b;
1070   int id3len=parseID3V2(b,len);
1071   if (id3len > 0) {
1072     char * str=id3->toString();
1073     log->log("DemuxerAudio",Log::DEBUG,"parseID3V2 %d bytes of %d",id3len,len);
1074     log->log("DemuxerAudio",Log::DEBUG,"parseID3V2 found:%s",str);
1075     delete str;
1076     b+=id3len;
1077     len-=id3len;
1078   }
1079         int vbrlen=parseVBR(b,len);
1080         if (vbrlen > 0 ) {
1081                 hasVBRInfo=true;
1082                 b+=vbrlen;
1083                 len-=vbrlen;
1084         }
1085   UCHAR * hdr=findHeader(b,len,true);
1086   if (hdr == NULL) return -1;
1087   return hdr-start;
1088 }
1089
1090 int DemuxerAudio::checkID3(UCHAR *b, int len) {
1091   if (len != 128) return -1;
1092   int rt=parseID3V1(b,len);
1093   if (rt >= 0) {
1094     char * str=id3->toString();
1095     log->log("DemuxerAudio",Log::DEBUG,"parseID3V1 found:%s",str);
1096     delete str;
1097   }
1098   return rt;
1099 }
1100
1101 bool DemuxerAudio::isSync() {
1102   return inSync;
1103 }
1104
1105 UINT DemuxerAudio::getSyncErrors() {
1106   return outOfSync;
1107 }
1108
1109 ULONG DemuxerAudio::getBytesPerSecond()
1110 {
1111   ULONG bps=hdrBitrate;
1112   if (! hasHdrInfo) return 0;
1113   if (hdrBitrate != avrBitrate) {
1114     //we seem to have vbr
1115     if (hasVBRInfo) {
1116       //vbr stuff TODO
1117       bps=avrBitrate;
1118     }
1119     else {
1120       //some guessing
1121       bps=avrBitrate;
1122     }
1123   }
1124   bps=bps/8;
1125   return bps;
1126 }
1127
1128 ULONG DemuxerAudio::getSecondsFromLen(ULONG len) {
1129   if (! hasHdrInfo) return 0;
1130         if (vbr) {
1131                 //first find the index where we are between
1132                 //rough starting point:
1133                 ULONG idx=100*len/vbr->numBytes;
1134                 if (idx >= 100) idx=99;
1135                 ULONG idxPos=(vbr->table[idx]) * vbr->numBytes/256;
1136                 ULONG pbefore=idxPos;
1137                 ULONG pafter=idxPos;
1138                 //OK now we know whether we have to go up or down
1139                 if (idxPos > len) {
1140                         //down
1141                         while (idxPos > len && idx > 0) {
1142                                 pafter=idxPos;
1143                                 idx--;
1144                                 idxPos=(vbr->table[idx]) * vbr->numBytes/256;
1145                                 pbefore=idxPos;
1146                         }
1147                         //OK we are now before our postion
1148                 }
1149                 else {
1150                         //up
1151                         while (idxPos < len && idx < 100 ) {
1152                                 pbefore=idxPos;
1153                                 idx++;
1154                                 idxPos=(vbr->table[idx]) * vbr->numBytes/256;
1155                                 pafter=idxPos;
1156                         }
1157                         //after our position
1158                         if (idx > 0) idx --;
1159                 }
1160                 //idx is now the index before our position
1161                 //approximate between the 2 points
1162                 ULONG idxTime=idx * vbr->fileSeconds/100;
1163                 if (pafter == pbefore) return idxTime;
1164                 ULONG rt=idxTime+ (len-pbefore)* vbr->fileSeconds/(100 * (pafter-pbefore)) ;
1165                 if (rt > vbr -> fileSeconds) return vbr->fileSeconds;
1166                 if (rt < idxTime) return idxTime;
1167                 return rt;
1168         }
1169         else {
1170                 ULONG bps=getBytesPerSecond();
1171                 if (bps == 0) return 0;
1172                 return len/bps;
1173         }
1174 }
1175   
1176 ULONG DemuxerAudio::positionFromSeconds(ULONG seconds) {
1177   if (! hasHdrInfo) return 0;
1178         if (vbr) {
1179                 ULONG idx=seconds*100/vbr->fileSeconds;
1180                 if (idx > 99) idx=99;
1181                 ULONG idxPos=vbr->table[idx] * vbr->numBytes/256;
1182                 ULONG idx2=idx;
1183                 if (idx < 99) idx2++;
1184                 ULONG nextPos=vbr->table[idx] * vbr->numBytes/256;
1185                 ULONG rt=idxPos+(nextPos-idxPos) * (seconds - idx * vbr->fileSeconds /256);
1186                 if (rt < idxPos) return idxPos;
1187                 if ( rt > vbr->numBytes) return vbr->numBytes;
1188                 return rt;
1189         }
1190         else {
1191                 ULONG bps=getBytesPerSecond();
1192                 return bps*seconds;
1193         }
1194 }
1195
1196 int id3_tag::stringlen(bool withTitle) const {
1197         if (!withTitle)
1198    return strlen(artist)+strlen(genre)+strlen(year)+strlen(album)+
1199     strlen(track)+strlen(composer)+strlen(comment)+8+3+
1200     90; //30 chars for each name...
1201         else
1202    return strlen(title)+strlen(artist)+strlen(genre)+strlen(year)+strlen(album)+
1203     strlen(track)+strlen(composer)+strlen(comment)+8+3+
1204     120; //30 chars for each name...
1205 }
1206 //create a string out of the id3 tag info
1207 //delete this string afterwards if you did not provide the buffer
1208 char * id3_tag::toString(char *b, int len, bool withTitle) const {
1209   const char *ta=tr("Artist");
1210 //char *tg=tr("Genre");
1211 //char *ty=tr("Year");
1212   const char *tx=tr("Album");
1213 //char *to=tr("Composer");
1214 //char *tc=tr("Comment");
1215   const char *tn=tr("Track");
1216   /* in the moment:
1217      Title: 
1218      Artist:
1219      Album: year - name
1220      Track:
1221      */
1222   if (b == NULL) {
1223     len=stringlen(withTitle);
1224     b=new char[len];
1225   }
1226         const char * del=" - ";
1227         if (strlen(year) == 0) del="";
1228         if (withTitle){
1229  const char *tt=tr("Title");
1230                 SNPRINTF(b,len-1,"%s: %s\n%s: %s\n%s: %s%s%s\n%s: %s",
1231                                 tt,title,ta,artist,tx,year,del,album,tn,track);
1232         }
1233         else {
1234 SNPRINTF(b,len-1,"%s: %s\n%s: %s%s%s\n%s: %s",
1235                                 ta,artist,tx,year,del,album,tn,track);
1236         }
1237   b[len-1]=0;
1238   return b;
1239 }
1240
1241 void DemuxerAudio::setSkipFactor(int factor) {
1242         Log::getInstance()->log("DemuxerAudio",Log::DEBUG,"set skipfactor %d\n",factor);
1243         buffer->setSkipFactor(factor);
1244 }
1245