aboutsummaryrefslogtreecommitdiff
path: root/sysutils/k3b-kde4/files/patch-src-audiodecoding-mp3-k3bmaddecoder.cpp
blob: ab64d2773e8cf86174ef9b28d1d53e5190b4e497 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
--- src/audiodecoding/mp3/k3bmaddecoder.cpp.orig	Mon Sep  1 12:14:10 2003
+++ src/audiodecoding/mp3/k3bmaddecoder.cpp	Fri Nov  7 12:35:44 2003
@@ -37,6 +37,8 @@
 #include <stdlib.h>
 #include <cmath>
 #include <cstdlib>
+#include <sys/types.h>
+#include <sys/mman.h>
 
 #include <config.h>
 
@@ -716,23 +718,24 @@
     return false;
   }
 
-  // there seem to be mp3 files starting with a lot of zeros
-  // we try to skip these.
-  // there might still be files with more than bufLen zeros...
-  const int bufLen = 4096;
-  char buf[bufLen];
-  if( f.readBlock( buf, bufLen ) < bufLen ) {
-    kdDebug() << "(K3bMadDecoder) unable to read " << bufLen << " bytes from " << url.path() << endl;
+  // EXPERIMENTAL!!!!!!!!
+  
+  const int bufLen = f.size();
+  const char * buf = (const char *)mmap(0, bufLen, PROT_READ, MAP_SHARED, f.handle(), 0);
+  if (buf == MAP_FAILED)
+  {
+    kdDebug() << "(K3bMp3Module) unable to read from " << url.path() << endl;
     f.close();
     return false;
   }
-  f.close();
 
   // skip any 0
   int i = 0;
   while( i < bufLen && buf[i] == '\0' ) i++;
   if( i == bufLen ) {
     kdDebug() << "(K3bMadDecoder) only zeros found in the beginning of " << url.path() << endl;
+    munmap((void *)buf, bufLen);
+    f.close();
     return false;
   }
 
@@ -744,6 +747,8 @@
       ( (unsigned short)buf[i+3] < 0xff && (unsigned short)buf[i+4] < 0xff ) ) {
     kdDebug() << "(K3bMadDecoder) found id3 magic: ID3 " 
 	      << (unsigned short)buf[i+3] << "." << (unsigned short)buf[i+4] << endl;
+    munmap((void *)buf, bufLen);
+    f.close();
     return true;
   }
 
@@ -756,15 +761,22 @@
     short m = (short)( buf[i+20] | (buf[i+21]<<8) );
     if( m == 80 ) {
       kdDebug() << "(K3bMadDecoder) found RIFF MPEG magic." << endl;
+      munmap((void *)buf, bufLen);
+      f.close();
       return true;
     }
     else if( m == 85 ) {
       kdDebug() << "(K3bMadDecoder) found RIFF MPEG III magic." << endl;
+      munmap((void *)buf, bufLen);
+      f.close();
       return true;
     }
-    else
+    else {
+      munmap((void *)buf, bufLen);
+      f.close();
       return false;
   }
+  }
       
 
 
@@ -775,16 +787,41 @@
   mad_stream_init( &stream );
   mad_header_init( &header );
 
-  mad_stream_buffer( &stream, (unsigned char*)&buf[i], bufLen-i );
-  stream.error = MAD_ERROR_NONE;
+  mad_stream_buffer( &stream, (unsigned char*)buf, bufLen );
+  unsigned long bitrate, kbps, count;
+  int vbr;
+  bitrate = kbps = count = vbr = 0;
+  mad_timer_t duration = mad_timer_zero;
   bool success = true;
-  if( mad_header_decode( &header, &stream ) ) {
+  while (1) {
+    if (mad_header_decode(&header, &stream) == -1) {
+      if (MAD_RECOVERABLE(stream.error))
+	continue;
+      else
+      {
+        break;
+      }
+    }
+    if (bitrate && header.bitrate != bitrate)
+      vbr = 1;
+
+    bitrate = header.bitrate;
+
+    kbps += bitrate / 1000;
+    ++count;
+
+    mad_timer_add(&duration, header.duration);
+  }
+  kbps = count?((kbps * 2) / count + 1) / 2 * (vbr ? -1 : 1):0;
+  kdDebug() << "(K3bMp3Module) File: " << url.path() << ", bitrate: " << kbps << ", duration: " << duration.seconds << "." << duration.fraction << endl;
+  if (duration.seconds == 0 || kbps == 0)
+  {
     kdDebug() << "(K3bMadDecoder) could not find mpeg header." << endl;
     success = false;
   }
 
-  mad_header_finish( &header );
-  mad_stream_finish( &stream );
+  munmap((void *)buf, bufLen);
+  f.close();
   
   return success;
 }