gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-


From: Bastiaan Jacques
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-2138-ga9f7f74
Date: Sun, 15 Jun 2014 19:56:39 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  a9f7f743c66f2f36d81c348da238d94877473372 (commit)
       via  b7a877c2e78868fcf2febe1fbefa06794e08a65b (commit)
      from  62c8f58d25b441afcb6e4466dbf2234d5894a4f5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=a9f7f743c66f2f36d81c348da238d94877473372


commit a9f7f743c66f2f36d81c348da238d94877473372
Author: Bastiaan Jacques <address@hidden>
Date:   Sun Jun 15 20:09:12 2014 +0200

    Reduce malloc() churn for SWF-embedded audio.
    
    Decoded data from audio sources stored inside SWFs are decoded and
    stored in a growing buffer. This buffer is appended to as small
    chunks of data become available. In order to store the additional
    data, a new buffer big enough to contain all the data is allocated.
    A minute of audio corresponds to about 10MB of decoded data. The
    ensuing (re)allocation of such a large buffer adds significantly to
    the resource pressure on the system.
    
    This change alters the situation so that instead of allocating a new
    buffer, each buffer is added to a list as-is, at the cost of having
    to keep track of reads in more detail.

diff --git a/libbase/SimpleBuffer.h b/libbase/SimpleBuffer.h
index 2c21bd2..b2645cd 100644
--- a/libbase/SimpleBuffer.h
+++ b/libbase/SimpleBuffer.h
@@ -57,6 +57,17 @@ public:
                }
        }
 
+        /// Construct a SimpleBuffer by taking ownership of an existing buffer.
+        //
+        /// @param size the size of the buffer.
+        /// @param buffer a pointer a a new[]-allocated buffer.
+        SimpleBuffer(size_t size, std::uint8_t* buffer)
+            : _size(size),
+              _capacity(size),
+              _data(buffer)
+        {
+        }
+
         /// Move constructor.
         SimpleBuffer(SimpleBuffer&& b) = default;
 
diff --git a/libsound/EmbedSoundInst.cpp b/libsound/EmbedSoundInst.cpp
index 3f5e2f0..9ef4b05 100644
--- a/libsound/EmbedSoundInst.cpp
+++ b/libsound/EmbedSoundInst.cpp
@@ -144,7 +144,7 @@ EmbedSoundInst::decodeNextBlock()
 
 
     // decodedData ownership transferred here
-    appendDecodedData(decodedData, decodedDataSize);
+    appendDecodedData(SimpleBuffer(decodedDataSize, decodedData));
 }
 
 void
diff --git a/libsound/LiveSound.cpp b/libsound/LiveSound.cpp
index 843d719..83df3ef 100644
--- a/libsound/LiveSound.cpp
+++ b/libsound/LiveSound.cpp
@@ -33,9 +33,8 @@ namespace sound {
 LiveSound::LiveSound(media::MediaHandler& mh, const media::SoundInfo& info,
         size_t inPoint)
     :
-    _inPoint(inPoint * 4),
-    _playbackPosition(_inPoint),
-    _samplesFetched(0)
+    _samplesFetched(0),
+    _decodedBuffers(inPoint * 4)
 {
     createDecoder(mh, info);
 }
@@ -59,26 +58,16 @@ LiveSound::fetchSamples(std::int16_t* to, unsigned int 
nSamples)
         unsigned int availableSamples = decodedSamplesAhead();
 
         if (availableSamples) {
-            const std::int16_t* data = getDecodedData(_playbackPosition);
+            size_t bytesCopied = _decodedBuffers.copy(
+                reinterpret_cast<std::uint8_t*>(to), nSamples * 2);
 
-            if (availableSamples >= nSamples) {
-                std::copy(data, data + nSamples, to);
-                fetchedSamples += nSamples;
-
-                // Update playback position (samples are 16bit)
-                _playbackPosition += nSamples * 2;
+            fetchedSamples += bytesCopied / 2;
 
+            if (availableSamples >= nSamples) {
                 break; // fetched all
-            }
-            else {
+            } else {
                 // not enough decoded samples available:
                 // copy what we have and go on
-                std::copy(data, data + availableSamples, to);
-                fetchedSamples += availableSamples;
-
-                // Update playback position (samples are 16bit)
-                _playbackPosition += availableSamples * 2;
-
                 to += availableSamples;
                 nSamples -= availableSamples;
                 assert(nSamples);
diff --git a/libsound/LiveSound.h b/libsound/LiveSound.h
index 82df6a5..8551297 100644
--- a/libsound/LiveSound.h
+++ b/libsound/LiveSound.h
@@ -23,6 +23,7 @@
 #include <memory>
 #include <cassert>
 #include <cstdint> // For C99 int types
+#include <iostream>
 
 #include "InputStream.h" 
 #include "AudioDecoder.h" 
@@ -39,6 +40,121 @@ namespace gnash {
 namespace gnash {
 namespace sound {
 
+
+/// Maintains a collection of SimpleBuffers, providing stateful sequential
+/// read access to the data contained therein.
+//
+// TODO: this shares some functionality with CursoredBuffer, and the two
+// classes might be merged.
+class Buffers {
+public:
+    Buffers(size_t in_point)
+    : _buffers(),
+      _index(0),
+      _pos(0),
+      _consumed(0),
+      _in_point(in_point)
+    {}
+
+    Buffers(const Buffers&) = delete;
+    Buffers& operator=(const Buffers&) = delete;
+
+    /// Append a buffer of data to be read by the consumer later.
+    void append(SimpleBuffer buf) {
+        _buffers.push_back(std::move(buf));
+        consumeInPoint();
+    }
+
+    void restart()
+    {
+        _index = 0;
+        _consumed = 0;
+        consumeInPoint();
+    }
+
+    /// Copy up to the given number of bytes to the given buffer.
+    //
+    /// @to points to a buffer to be written to.
+    /// @bytes number of bytes to be written.
+    /// @return number of bytes actually written.
+    size_t copy(std::uint8_t* to, size_t bytes) {
+        assert(_consumed >= _in_point);
+
+        size_t bytes_remaining = bytes;
+
+        for (; _index < _buffers.size(); ++_index) {
+            const SimpleBuffer& buffer = _buffers[_index];
+
+            size_t to_copy = std::min(bytes_remaining, buffer.size() - _pos);
+
+            std::copy(buffer.data() + _pos, buffer.data() + _pos + to_copy, 
to);
+            to += to_copy;
+            bytes_remaining -= to_copy;
+            _pos += to_copy;
+
+            if (_pos == buffer.size()) {
+                ++_index;
+                _pos = 0;
+                break;
+            }
+
+            if (bytes_remaining == 0) {
+                break;
+            }
+        }
+
+        size_t written = bytes - bytes_remaining;
+        _consumed += written;
+        return written;
+    }
+
+    /// @return total number of bytes contained.
+    std::uint64_t countBytes() const
+    {
+        std::uint64_t bytes = 0;
+        for (const SimpleBuffer& buffer : _buffers) {
+            bytes += buffer.size();
+        }
+        return bytes;
+    }
+
+    /// @return number of bytes previously copied by calls to copy().
+    std::uint64_t consumed() const
+    {
+        return std::max(_consumed, _in_point);
+    }
+
+private:
+    void consumeInPoint() {
+        if (_consumed >= _in_point) {
+            return;
+        }
+        size_t inPoint = _in_point;
+
+        for (const SimpleBuffer& buffer : _buffers) {
+            size_t advance = std::min(inPoint, buffer.size());
+            if (advance == buffer.size()) {
+                ++_index;
+                inPoint -= advance;
+            } else {
+                _pos = advance;
+                break;
+            }
+        }
+        _consumed = _in_point;
+    }
+
+    std::vector<SimpleBuffer> _buffers;
+    /// Zero-based index of the buffer currently being indicated.
+    size_t _index;
+    /// Current position inside the current buffer.
+    size_t _pos;
+    /// Total bytes consumed by calls to copy().
+    std::uint64_t _consumed;
+    /// Number of bytes to skip from the input.
+    size_t _in_point;
+};
+
 /// Instance of a defined %sound (LiveSoundData)
 //
 /// This class contains a pointer to the LiveSoundData used for playing
@@ -57,13 +173,6 @@ protected:
     LiveSound(media::MediaHandler& mh, const media::SoundInfo& info,
             size_t inPoint);
 
-    // Pointer handling and checking functions
-    const std::int16_t* getDecodedData(unsigned long int pos) const {
-        assert(pos < _decodedData.size());
-        return reinterpret_cast<const std::int16_t*>(
-                _decodedData.data() + pos);
-    }
-
     /// Called when more decoded sound data is required.
     //
     /// This will be called whenever no more decoded data is available
@@ -77,8 +186,8 @@ protected:
 
     /// Start from the beginning again.
     void restart() {
-        _playbackPosition = _inPoint;
         _samplesFetched = 0;
+        _decodedBuffers.restart();
     }
 
     /// How many samples have been fetched since the beginning
@@ -88,28 +197,27 @@ protected:
         return _samplesFetched;
     }
 
-    size_t playbackPosition() const {
-        return _playbackPosition;
+    std::uint64_t playbackPosition() const {
+        return _decodedBuffers.consumed();
     }
 
     media::AudioDecoder& decoder() const {
         return *_decoder;
     }
 
-    void appendDecodedData(std::uint8_t* data, unsigned int size) {
-        _decodedData.append(data, size);
-        delete [] data;
+    void appendDecodedData(SimpleBuffer data) {
+        _decodedBuffers.append(std::move(data));
     }
 
     /// Return number of already-decoded samples available
     /// from playback position on
     unsigned int decodedSamplesAhead() const {
 
-        const unsigned int dds = _decodedData.size();
-        if (dds <= _playbackPosition) return 0; 
+        const unsigned int dds = _decodedBuffers.countBytes();
+        if (dds <= playbackPosition()) return 0;
 
-        size_t bytesAhead = dds - _playbackPosition;
-        bytesAhead = checkEarlierEnd(bytesAhead, _playbackPosition);
+        size_t bytesAhead = dds - playbackPosition();
+        bytesAhead = checkEarlierEnd(bytesAhead, playbackPosition());
 
         assert(!(bytesAhead % 2));
 
@@ -135,18 +243,13 @@ private:
 
     virtual bool decodingCompleted() const = 0;
 
-    const size_t _inPoint;
-
-    /// Current playback position in the decoded stream
-    size_t _playbackPosition;
-
     /// Number of samples fetched so far.
     unsigned long _samplesFetched;
 
     std::unique_ptr<media::AudioDecoder> _decoder;
 
-    /// The decoded buffer
-    SimpleBuffer _decodedData;
+    /// The decoded buffers
+    Buffers _decodedBuffers;
 
 };
 
diff --git a/libsound/StreamingSound.cpp b/libsound/StreamingSound.cpp
index 1284ac5..4b56f5f 100644
--- a/libsound/StreamingSound.cpp
+++ b/libsound/StreamingSound.cpp
@@ -99,7 +99,7 @@ StreamingSound::decodeNextBlock()
         }
 
         // decodedData ownership transferred here
-        appendDecodedData(decodedData, decodedDataSize);
+        appendDecodedData(SimpleBuffer(decodedDataSize, decodedData));
     }
 
     // Check if the entire block was consumed.

http://git.savannah.gnu.org/cgit//commit/?id=b7a877c2e78868fcf2febe1fbefa06794e08a65b


commit b7a877c2e78868fcf2febe1fbefa06794e08a65b
Author: Bastiaan Jacques <address@hidden>
Date:   Sat Jun 14 02:04:17 2014 +0200

    Drop SimpleBuffer's copy constructor and assignment operators and define a 
move constructor.
    
    The dropped code is not being used anywhere, and this allows
    SimpleBuffers to be used in standard containers without copies
    being made implicitly.

diff --git a/libbase/SimpleBuffer.h b/libbase/SimpleBuffer.h
index a4b0ac3..2c21bd2 100644
--- a/libbase/SimpleBuffer.h
+++ b/libbase/SimpleBuffer.h
@@ -57,37 +57,13 @@ public:
                }
        }
 
-       /// Copy constructor
-       //
-       /// The copy ctor will set capacity to be
-       /// as small as required to hold the size of the
-       /// model buffer.
-       ///
-       SimpleBuffer(const SimpleBuffer& b)
-               :
-               _size(b._size),
-               _capacity(b._size)
-       {
-               if ( _size )
-               {
-                       _data.reset(new std::uint8_t[_size]);
-                       std::copy(b.data(), b.data()+b.size(), _data.get());
-               }
-       }
+        /// Move constructor.
+        SimpleBuffer(SimpleBuffer&& b) = default;
+
+        /// Copy (construction) not allowed.
+        SimpleBuffer(const SimpleBuffer& b) = delete;
+        SimpleBuffer& operator= (const SimpleBuffer& b) = delete;
 
-       /// Assignment operator
-       //
-       /// The assignment op will not reset capacity
-       ///
-       SimpleBuffer& operator= (const SimpleBuffer& b)
-       {
-               if ( this != &b )  // don't waste time on self-assignment
-               {
-                       resize(0); // shouldn't deallocate memory
-                       append(b);
-               }
-               return *this;
-       }
 
        /// Return true if buffer is empty
        bool empty() const { return _size==0; }

-----------------------------------------------------------------------

Summary of changes:
 libbase/SimpleBuffer.h      |   47 +++++---------
 libsound/EmbedSoundInst.cpp |    2 +-
 libsound/LiveSound.cpp      |   25 ++-----
 libsound/LiveSound.h        |  151 ++++++++++++++++++++++++++++++++++++-------
 libsound/StreamingSound.cpp |    2 +-
 5 files changed, 153 insertions(+), 74 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

[Prev in Thread] Current Thread [Next in Thread]