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