Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > by-pkgid > 0a90919b61859a90da060685ee09fe54 > files > 5

lastfm-player-1.3.2.13-1mdv2008.1.src.rpm

--- a/src/mp3transcode/mp3transcode.cpp
+++ b/src/mp3transcode/mp3transcode.cpp
@@ -41,10 +41,28 @@
             " God knows what. Chris can read the \"best documentation "
             " there is\" to find out. :P" );
     }
+
+    // Maybe give these a good start value?  They'll grow as needed anyway.
+    m_decBufSize = 1; // On my machine this grows to about 120K
+    m_encBufSize = 1; // And this grows to about 6K or so.
+    m_encBufReadIndex = m_encBufWriteIndex = 0;
+    m_decBufReadIndex = m_decBufWriteIndex = 0;
+    m_decodedBuffer = (char*)malloc( m_decBufSize );
+    m_encodedBuffer = (char*)malloc( m_encBufSize );
 }
 
 MP3Transcode::~MP3Transcode()
 {
+    if ( m_decodedBuffer )
+    {
+        free( m_decodedBuffer);
+        m_decodedBuffer = NULL;
+    }
+    if ( m_encodedBuffer )
+    {
+        free( m_encodedBuffer);
+        m_encodedBuffer = NULL;
+    }
     ExitMP3( &mpeg );
 }
 
@@ -61,24 +79,84 @@
     return QStringList( "mp3" );
 }
 
+void
+MP3Transcode::expandRingBuffer( char** buffer, int& bufSize, int& readIndex, int& writeIndex, int growSize )
+{
+    //qDebug() << "resizing buffer from" << bufSize
+    //         << "to" << bufSize + growSize;
+    char* tmp;
+    tmp = (char*)realloc( *buffer, sizeof(char) * ( bufSize + growSize ) );
+    if ( tmp == NULL )
+    {
+        Q_ASSERT( !"Could not reallocate buffer!" );
+        return;
+    }
+    else
+        *buffer = tmp;
+
+    // Don't screw up the read order or ugly noises will ensue
+    if ( readIndex > writeIndex )
+    {
+        memmove( *buffer + readIndex + growSize,
+                 *buffer + readIndex,
+                 bufSize - readIndex );
+        readIndex += growSize;
+    }
+    bufSize += growSize;
+}
+
+
 bool
 MP3Transcode::processData( const QByteArray &buffer )
 {
-    m_encodedBuffer.append( buffer );
+    int length = buffer.size();
+    int cnt;
+    const char* src = buffer.data();
+    int neededSize = getEncodedBufferFilled() + buffer.size();
+
+    if ( neededSize >= m_encBufSize )
+        expandRingBuffer( &m_encodedBuffer, m_encBufSize,
+                          m_encBufReadIndex, m_encBufWriteIndex,
+                          neededSize - m_encBufSize + 1 );
+
+    while ( length > 0 )
+    {
+        int wr;
+        cnt = qMin( length, m_encBufSize - m_encBufWriteIndex );
+        memcpy( m_encodedBuffer + m_encBufWriteIndex, src, cnt );
+        wr = (m_encBufWriteIndex + cnt) % m_encBufSize;
+        m_encBufWriteIndex = wr;
+        length -= cnt;
+        src += cnt;
+    }
 
     // wait till we got a minimal buffer of data, which we need for mpglib
     // being able to properly read the audio metadata (samplerate, channels...)
-    if ( m_encodedBuffer.size() <= MP3_MIN_BUFFER_SIZE )
+    if ( getEncodedBufferFilled() <= MP3_MIN_BUFFER_SIZE )
     {
         return true;
     }
 
     char tempBuffer[16384];
     int size;
+    unsigned char inTemp[MP3_MIN_BUFFER_SIZE];
+    length = MP3_MIN_BUFFER_SIZE;
+    int outLen = 0;
+    while ( length > 0 )
+    {
+        int rd;
+        cnt = qMin(length, m_encBufSize - m_encBufReadIndex);
+        memcpy( inTemp + outLen, m_encodedBuffer + m_encBufReadIndex, cnt);
+        rd = (m_encBufReadIndex + cnt) % m_encBufSize;
+        m_encBufReadIndex = rd;
+        length -= cnt;
+        outLen += cnt;
+    }
+
 
     int result = decodeMP3(
         &mpeg, // handle
-        (unsigned char*)m_encodedBuffer.data(), // in-data
+        inTemp, // in-data
         MP3_MIN_BUFFER_SIZE, // size of in-data
         tempBuffer, // out-data
         sizeof( tempBuffer ), // size of out-data
@@ -111,11 +189,29 @@
         emit streamInitialized( sampleRate, channels );
     }
 
-    m_encodedBuffer.remove( 0, MP3_MIN_BUFFER_SIZE );
     while ( result == MP3_OK )
     {
-        m_decodedBuffer.append( QByteArray::fromRawData( tempBuffer, size ) );
-        
+        int length = size;
+        int cnt;
+        const char* src = tempBuffer;
+        int neededSize = getDecodedBufferFilled() + size;
+
+        if ( neededSize >= m_decBufSize )
+            expandRingBuffer( &m_decodedBuffer, m_decBufSize,
+                              m_decBufReadIndex, m_decBufWriteIndex,
+                              ( neededSize - m_decBufSize + 1 ) );
+
+        while (length > 0)
+        {
+            int wr;
+            cnt = qMin(length, m_decBufSize - m_decBufWriteIndex);
+            memcpy( m_decodedBuffer + m_decBufWriteIndex, src, cnt);
+            wr = (m_decBufWriteIndex + cnt) % m_decBufSize;
+            m_decBufWriteIndex = wr;
+            length -= cnt;
+            src += cnt;
+        }
+
         result = decodeMP3( &mpeg, NULL, 0, tempBuffer, sizeof( tempBuffer ), &size );
 
         if ( result == MP3_ERR )
@@ -134,8 +230,8 @@
 {
     ExitMP3( &mpeg );
 
-    m_encodedBuffer.clear();
-    m_decodedBuffer.clear();
+    m_decBufReadIndex = m_decBufWriteIndex = 0;
+    m_encBufReadIndex = m_encBufWriteIndex = 0;
     m_mpegInitialised = false;
 
     if ( !InitMP3( &mpeg ) )
@@ -146,26 +242,56 @@
     }
 }
 
+int
+MP3Transcode::getEncodedBufferFilled()
+{
+    if ( m_encBufWriteIndex >= m_encBufReadIndex )
+    {
+        return m_encBufWriteIndex - m_encBufReadIndex;
+    }
+    return ( m_encBufSize - ( m_encBufReadIndex - m_encBufWriteIndex ) );
+}
+
+int
+MP3Transcode::getDecodedBufferFilled()
+{
+    if ( m_decBufWriteIndex >= m_decBufReadIndex )
+    {
+        return m_decBufWriteIndex - m_decBufReadIndex;
+    }
+    return ( m_decBufSize - ( m_decBufReadIndex - m_decBufWriteIndex ) );
+}
 
 bool
 MP3Transcode::needsData()
 {
-    return m_decodedBuffer.size() < m_decodedBufferCapacity;
+    return getDecodedBufferFilled() < m_decodedBufferCapacity;
 }
 
 
 bool
 MP3Transcode::hasData()
 {
-    return !m_decodedBuffer.isEmpty();
+    return ( getDecodedBufferFilled() > 0 );
 }
 
 
 void
 MP3Transcode::data( QByteArray& fillMe, int numBytes )
 {
-    fillMe = m_decodedBuffer.left( numBytes );
-    m_decodedBuffer.remove( 0, numBytes );
+    int length;
+    int cnt;
+    length = qMin( numBytes, getDecodedBufferFilled() );
+
+    while (length > 0)
+    {
+        int rd;
+        cnt = qMin (length, m_decBufSize - m_decBufReadIndex );
+        fillMe.append( QByteArray::fromRawData( m_decodedBuffer + m_decBufReadIndex, cnt ) );
+        rd = ( m_decBufReadIndex + cnt ) % m_decBufSize;
+        m_decBufReadIndex = rd;
+        length -= cnt;
+    }
 }
 
 
--- a/src/mp3transcode/mp3transcode.h
+++ b/src/mp3transcode/mp3transcode.h
@@ -26,8 +26,6 @@
 #include "mpglib/interface.h"
 #include <QByteArray>
 #include <QObject>
-#include <QMutex>
-#include <QFile>
 
 
 /*************************************************************************/ /**
@@ -64,7 +62,7 @@
         setBufferCapacity( int bytes ) { m_decodedBufferCapacity = bytes; }
 
         int
-        bufferSize() { return m_decodedBuffer.size(); }
+        bufferSize() { return getDecodedBufferFilled(); }
 
     public slots:
         virtual void clearBuffers();
@@ -74,12 +72,20 @@
         void streamInitialized( long sampleRate, int channels );
 
     private:
-        QByteArray m_encodedBuffer;
-        QByteArray m_decodedBuffer;
-        
+        char* m_encodedBuffer;
+        char* m_decodedBuffer;
+        int m_decBufSize, m_decBufWriteIndex, m_decBufReadIndex;
+        int m_encBufSize, m_encBufWriteIndex, m_encBufReadIndex;
+
         int m_decodedBufferCapacity;
 
         bool m_mpegInitialised;
+
+        int getDecodedBufferFilled();
+        int getEncodedBufferFilled();
+        void expandRingBuffer( char** buffer, int& bufSize,
+                               int& readIndex, int& writeIndex,
+                               int growSize );
 };
 
 #endif