LCOV - code coverage report
Current view: top level - dom/media - AudioCompactor.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 35 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : #if !defined(AudioCompactor_h)
       7             : #define AudioCompactor_h
       8             : 
       9             : #include "MediaQueue.h"
      10             : #include "MediaData.h"
      11             : #include "VideoUtils.h"
      12             : 
      13             : namespace mozilla {
      14             : 
      15             : class AudioCompactor
      16             : {
      17             : public:
      18           0 :   explicit AudioCompactor(MediaQueue<AudioData>& aQueue)
      19           0 :     : mQueue(aQueue)
      20             :   {
      21             :     // Determine padding size used by AlignedBuffer.
      22           0 :     size_t paddedSize = AlignedAudioBuffer::AlignmentPaddingSize();
      23           0 :     mSamplesPadding = paddedSize / sizeof(AudioDataValue);
      24           0 :     if (mSamplesPadding * sizeof(AudioDataValue) < paddedSize) {
      25             :       // Round up.
      26           0 :       mSamplesPadding++;
      27             :     }
      28           0 :   }
      29             : 
      30             :   // Push audio data into the underlying queue with minimal heap allocation
      31             :   // slop.  This method is responsible for allocating AudioDataValue[] buffers.
      32             :   // The caller must provide a functor to copy the data into the buffers.  The
      33             :   // functor must provide the following signature:
      34             :   //
      35             :   //   uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples);
      36             :   //
      37             :   // The functor must copy as many complete frames as possible to the provided
      38             :   // buffer given its length (in AudioDataValue elements).  The number of frames
      39             :   // copied must be returned.  This copy functor must support being called
      40             :   // multiple times in order to copy the audio data fully.  The copy functor
      41             :   // must copy full frames as partial frames will be ignored.
      42             :   template<typename CopyFunc>
      43           0 :   bool Push(int64_t aOffset, int64_t aTime, int32_t aSampleRate,
      44             :             uint32_t aFrames, uint32_t aChannels, CopyFunc aCopyFunc)
      45             :   {
      46           0 :     auto time = media::TimeUnit::FromMicroseconds(aTime);
      47             : 
      48             :     // If we are losing more than a reasonable amount to padding, try to chunk
      49             :     // the data.
      50           0 :     size_t maxSlop = AudioDataSize(aFrames, aChannels) / MAX_SLOP_DIVISOR;
      51             : 
      52           0 :     while (aFrames > 0) {
      53           0 :       uint32_t samples = GetChunkSamples(aFrames, aChannels, maxSlop);
      54           0 :       if (samples / aChannels > mSamplesPadding / aChannels + 1) {
      55           0 :         samples -= mSamplesPadding;
      56             :       }
      57           0 :       AlignedAudioBuffer buffer(samples);
      58           0 :       if (!buffer) {
      59           0 :         return false;
      60             :       }
      61             : 
      62             :       // Copy audio data to buffer using caller-provided functor.
      63           0 :       uint32_t framesCopied = aCopyFunc(buffer.get(), samples);
      64             : 
      65           0 :       NS_ASSERTION(framesCopied <= aFrames, "functor copied too many frames");
      66           0 :       buffer.SetLength(size_t(framesCopied) * aChannels);
      67             : 
      68           0 :       auto duration = FramesToTimeUnit(framesCopied, aSampleRate);
      69           0 :       if (!duration.IsValid()) {
      70           0 :         return false;
      71             :       }
      72             : 
      73           0 :       mQueue.Push(new AudioData(aOffset,
      74             :                                 time,
      75             :                                 duration,
      76             :                                 framesCopied,
      77             :                                 Move(buffer),
      78             :                                 aChannels,
      79             :                                 aSampleRate));
      80             : 
      81             :       // Remove the frames we just pushed into the queue and loop if there is
      82             :       // more to be done.
      83           0 :       time += duration;
      84           0 :       aFrames -= framesCopied;
      85             : 
      86             :       // NOTE: No need to update aOffset as its only an approximation anyway.
      87             :     }
      88             : 
      89           0 :     return true;
      90             :   }
      91             : 
      92             :   // Copy functor suitable for copying audio samples already in the
      93             :   // AudioDataValue format/layout expected by AudioStream on this platform.
      94             :   class NativeCopy
      95             :   {
      96             :   public:
      97           0 :     NativeCopy(const uint8_t* aSource, size_t aSourceBytes,
      98             :                uint32_t aChannels)
      99           0 :       : mSource(aSource)
     100             :       , mSourceBytes(aSourceBytes)
     101             :       , mChannels(aChannels)
     102           0 :       , mNextByte(0)
     103           0 :     { }
     104             : 
     105             :     uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples);
     106             : 
     107             :   private:
     108             :     const uint8_t* const mSource;
     109             :     const size_t mSourceBytes;
     110             :     const uint32_t mChannels;
     111             :     size_t mNextByte;
     112             :   };
     113             : 
     114             :   // Allow 12.5% slop before chunking kicks in.  Public so that the gtest can
     115             :   // access it.
     116             :   static const size_t MAX_SLOP_DIVISOR = 8;
     117             : 
     118             : private:
     119             :   // Compute the number of AudioDataValue samples that will be fit the most
     120             :   // frames while keeping heap allocation slop less than the given threshold.
     121             :   static uint32_t
     122             :   GetChunkSamples(uint32_t aFrames, uint32_t aChannels, size_t aMaxSlop);
     123             : 
     124           0 :   static size_t BytesPerFrame(uint32_t aChannels)
     125             :   {
     126           0 :     return sizeof(AudioDataValue) * aChannels;
     127             :   }
     128             : 
     129           0 :   static size_t AudioDataSize(uint32_t aFrames, uint32_t aChannels)
     130             :   {
     131           0 :     return aFrames * BytesPerFrame(aChannels);
     132             :   }
     133             : 
     134             :   MediaQueue<AudioData> &mQueue;
     135             :   size_t mSamplesPadding;
     136             : };
     137             : 
     138             : } // namespace mozilla
     139             : 
     140             : #endif // AudioCompactor_h

Generated by: LCOV version 1.13