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

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       4             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef TrackEncoder_h_
       7             : #define TrackEncoder_h_
       8             : 
       9             : #include "mozilla/ReentrantMonitor.h"
      10             : 
      11             : #include "AudioSegment.h"
      12             : #include "EncodedFrameContainer.h"
      13             : #include "StreamTracks.h"
      14             : #include "TrackMetadataBase.h"
      15             : #include "VideoSegment.h"
      16             : #include "MediaStreamGraph.h"
      17             : 
      18             : namespace mozilla {
      19             : 
      20             : /**
      21             :  * Base class of AudioTrackEncoder and VideoTrackEncoder. Lifetimes managed by
      22             :  * MediaEncoder. Most methods can only be called on the MediaEncoder's thread,
      23             :  * but some subclass methods can be called on other threads when noted.
      24             :  *
      25             :  * NotifyQueuedTrackChanges is called on subclasses of this class from the
      26             :  * MediaStreamGraph thread, and AppendAudioSegment/AppendVideoSegment is then
      27             :  * called to store media data in the TrackEncoder. Later on, GetEncodedTrack is
      28             :  * called on MediaEncoder's thread to encode and retrieve the encoded data.
      29             :  */
      30             : class TrackEncoder
      31             : {
      32             : public:
      33             :   TrackEncoder();
      34             : 
      35           0 :   virtual ~TrackEncoder() {}
      36             : 
      37             :   /**
      38             :    * Notified by the same callbcak of MediaEncoder when it has received a track
      39             :    * change from MediaStreamGraph. Called on the MediaStreamGraph thread.
      40             :    */
      41             :   virtual void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
      42             :                                         StreamTime aTrackOffset,
      43             :                                         uint32_t aTrackEvents,
      44             :                                         const MediaSegment& aQueuedMedia) = 0;
      45             : 
      46             :   /**
      47             :    * Notified by the same callback of MediaEncoder when it has been removed from
      48             :    * MediaStreamGraph. Called on the MediaStreamGraph thread.
      49             :    */
      50             :   void NotifyEvent(MediaStreamGraph* aGraph,
      51             :                    MediaStreamGraphEvent event);
      52             : 
      53             :   /**
      54             :    * Creates and sets up meta data for a specific codec, called on the worker
      55             :    * thread.
      56             :    */
      57             :   virtual already_AddRefed<TrackMetadataBase> GetMetadata() = 0;
      58             : 
      59             :   /**
      60             :    * Encodes raw segments. Result data is returned in aData, and called on the
      61             :    * worker thread.
      62             :    */
      63             :   virtual nsresult GetEncodedTrack(EncodedFrameContainer& aData) = 0;
      64             : 
      65             :   /**
      66             :    * True if the track encoder has encoded all source segments coming from
      67             :    * MediaStreamGraph. Call on the worker thread.
      68             :    */
      69           0 :   bool IsEncodingComplete() { return mEncodingComplete; }
      70             : 
      71             :   /**
      72             :    * Notifies from MediaEncoder to cancel the encoding, and wakes up
      73             :    * mReentrantMonitor if encoder is waiting on it.
      74             :    */
      75           0 :   void NotifyCancel()
      76             :   {
      77           0 :     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
      78           0 :     mCanceled = true;
      79           0 :     NotifyEndOfStream();
      80           0 :   }
      81             : 
      82           0 :   virtual void SetBitrate(const uint32_t aBitrate) {}
      83             : 
      84             : protected:
      85             :   /**
      86             :    * Notifies track encoder that we have reached the end of source stream, and
      87             :    * wakes up mReentrantMonitor if encoder is waiting for any source data.
      88             :    */
      89             :   virtual void NotifyEndOfStream() = 0;
      90             : 
      91             :   /**
      92             :    * A ReentrantMonitor to protect the pushing and pulling of mRawSegment which
      93             :    * is declared in its subclasses, and the following flags: mInitialized,
      94             :    * EndOfStream and mCanceled. The control of protection is managed by its
      95             :    * subclasses.
      96             :    */
      97             :   ReentrantMonitor mReentrantMonitor;
      98             : 
      99             :   /**
     100             :    * True if the track encoder has encoded all source data.
     101             :    */
     102             :   bool mEncodingComplete;
     103             : 
     104             :   /**
     105             :    * True if flag of EOS or any form of indicating EOS has set in the codec-
     106             :    * encoder.
     107             :    */
     108             :   bool mEosSetInEncoder;
     109             : 
     110             :   /**
     111             :    * True if the track encoder has initialized successfully, protected by
     112             :    * mReentrantMonitor.
     113             :    */
     114             :   bool mInitialized;
     115             : 
     116             :   /**
     117             :    * True if the TrackEncoder has received an event of TRACK_EVENT_ENDED from
     118             :    * MediaStreamGraph, or the MediaEncoder is removed from its source stream,
     119             :    * protected by mReentrantMonitor.
     120             :    */
     121             :   bool mEndOfStream;
     122             : 
     123             :   /**
     124             :    * True if a cancellation of encoding is sent from MediaEncoder, protected by
     125             :    * mReentrantMonitor.
     126             :    */
     127             :   bool mCanceled;
     128             : 
     129             :   // How many times we have tried to initialize the encoder.
     130             :   uint32_t mInitCounter;
     131             :   StreamTime mNotInitDuration;
     132             : };
     133             : 
     134           0 : class AudioTrackEncoder : public TrackEncoder
     135             : {
     136             : public:
     137           0 :   AudioTrackEncoder()
     138           0 :     : TrackEncoder()
     139             :     , mChannels(0)
     140             :     , mSamplingRate(0)
     141           0 :     , mAudioBitrate(0)
     142           0 :   {}
     143             : 
     144             :   void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
     145             :                                 StreamTime aTrackOffset,
     146             :                                 uint32_t aTrackEvents,
     147             :                                 const MediaSegment& aQueuedMedia) override;
     148             : 
     149             :   template<typename T>
     150             :   static
     151           0 :   void InterleaveTrackData(nsTArray<const T*>& aInput,
     152             :                            int32_t aDuration,
     153             :                            uint32_t aOutputChannels,
     154             :                            AudioDataValue* aOutput,
     155             :                            float aVolume)
     156             :   {
     157           0 :     if (aInput.Length() < aOutputChannels) {
     158             :       // Up-mix. This might make the mChannelData have more than aChannels.
     159           0 :       AudioChannelsUpMix(&aInput, aOutputChannels, SilentChannel::ZeroChannel<T>());
     160             :     }
     161             : 
     162           0 :     if (aInput.Length() > aOutputChannels) {
     163           0 :       DownmixAndInterleave(aInput, aDuration,
     164             :                            aVolume, aOutputChannels, aOutput);
     165             :     } else {
     166           0 :       InterleaveAndConvertBuffer(aInput.Elements(), aDuration, aVolume,
     167             :                                  aOutputChannels, aOutput);
     168             :     }
     169           0 :   }
     170             : 
     171             :   /**
     172             :    * Interleaves the track data and stores the result into aOutput. Might need
     173             :    * to up-mix or down-mix the channel data if the channels number of this chunk
     174             :    * is different from aOutputChannels. The channel data from aChunk might be
     175             :    * modified by up-mixing.
     176             :    */
     177             :   static void InterleaveTrackData(AudioChunk& aChunk, int32_t aDuration,
     178             :                                   uint32_t aOutputChannels,
     179             :                                   AudioDataValue* aOutput);
     180             : 
     181             :   /**
     182             :    * De-interleaves the aInput data and stores the result into aOutput.
     183             :    * No up-mix or down-mix operations inside.
     184             :    */
     185             :   static void DeInterleaveTrackData(AudioDataValue* aInput, int32_t aDuration,
     186             :                                     int32_t aChannels, AudioDataValue* aOutput);
     187             :   /**
     188             :   * Measure size of mRawSegment
     189             :   */
     190             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     191             : 
     192           0 :   void SetBitrate(const uint32_t aBitrate) override
     193             :   {
     194           0 :     mAudioBitrate = aBitrate;
     195           0 :   }
     196             : protected:
     197             :   /**
     198             :    * Number of samples per channel in a pcm buffer. This is also the value of
     199             :    * frame size required by audio encoder, and mReentrantMonitor will be
     200             :    * notified when at least this much data has been added to mRawSegment.
     201             :    */
     202           0 :   virtual int GetPacketDuration() { return 0; }
     203             : 
     204             :   /**
     205             :    * Initializes the audio encoder. The call of this method is delayed until we
     206             :    * have received the first valid track from MediaStreamGraph, and the
     207             :    * mReentrantMonitor will be notified if other methods is waiting for encoder
     208             :    * to be completely initialized. This method is called on the MediaStreamGraph
     209             :    * thread.
     210             :    */
     211             :   virtual nsresult Init(int aChannels, int aSamplingRate) = 0;
     212             : 
     213             :   /**
     214             :    * Appends and consumes track data from aSegment, this method is called on
     215             :    * the MediaStreamGraph thread. mReentrantMonitor will be notified when at
     216             :    * least GetPacketDuration() data has been added to mRawSegment, wake up other
     217             :    * method which is waiting for more data from mRawSegment.
     218             :    */
     219             :   nsresult AppendAudioSegment(const AudioSegment& aSegment);
     220             : 
     221             :   /**
     222             :    * Notifies the audio encoder that we have reached the end of source stream,
     223             :    * and wakes up mReentrantMonitor if encoder is waiting for more track data.
     224             :    */
     225             :   void NotifyEndOfStream() override;
     226             : 
     227             :   /**
     228             :    * The number of channels are used for processing PCM data in the audio encoder.
     229             :    * This value comes from the first valid audio chunk. If encoder can't support
     230             :    * the channels in the chunk, downmix PCM stream can be performed.
     231             :    * This value also be used to initialize the audio encoder.
     232             :    */
     233             :   int mChannels;
     234             : 
     235             :   /**
     236             :    * The sampling rate of source audio data.
     237             :    */
     238             :   int mSamplingRate;
     239             : 
     240             :   /**
     241             :    * A segment queue of audio track data, protected by mReentrantMonitor.
     242             :    */
     243             :   AudioSegment mRawSegment;
     244             : 
     245             :   uint32_t mAudioBitrate;
     246             : };
     247             : 
     248           0 : class VideoTrackEncoder : public TrackEncoder
     249             : {
     250             : public:
     251           0 :   explicit VideoTrackEncoder(TrackRate aTrackRate)
     252           0 :     : TrackEncoder()
     253             :     , mFrameWidth(0)
     254             :     , mFrameHeight(0)
     255             :     , mDisplayWidth(0)
     256             :     , mDisplayHeight(0)
     257             :     , mTrackRate(aTrackRate)
     258             :     , mEncodedTicks(0)
     259           0 :     , mVideoBitrate(0)
     260             :   {
     261           0 :     mLastChunk.mDuration = 0;
     262           0 :   }
     263             : 
     264             :   /**
     265             :    * Notified by the same callback of MediaEncoder when it has received a track
     266             :    * change from MediaStreamGraph. Called on the MediaStreamGraph thread.
     267             :    */
     268             :   void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
     269             :                                 StreamTime aTrackOffset,
     270             :                                 uint32_t aTrackEvents,
     271             :                                 const MediaSegment& aQueuedMedia) override;
     272             :   /**
     273             :   * Measure size of mRawSegment
     274             :   */
     275             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     276             : 
     277           0 :   void SetBitrate(const uint32_t aBitrate) override
     278             :   {
     279           0 :     mVideoBitrate = aBitrate;
     280           0 :   }
     281             : 
     282             :   void Init(const VideoSegment& aSegment);
     283             : 
     284             :   void SetCurrentFrames(const VideoSegment& aSegment);
     285             : 
     286             :   StreamTime SecondsToMediaTime(double aS) const
     287             :   {
     288             :     NS_ASSERTION(0 <= aS && aS <= TRACK_TICKS_MAX/TRACK_RATE_MAX,
     289             :                  "Bad seconds");
     290             :     return mTrackRate * aS;
     291             :   }
     292             : 
     293             : protected:
     294             :   /**
     295             :    * Initialized the video encoder. In order to collect the value of width and
     296             :    * height of source frames, this initialization is delayed until we have
     297             :    * received the first valid video frame from MediaStreamGraph;
     298             :    * mReentrantMonitor will be notified after it has successfully initialized,
     299             :    * and this method is called on the MediaStramGraph thread.
     300             :    */
     301             :   virtual nsresult Init(int aWidth, int aHeight, int aDisplayWidth,
     302             :                         int aDisplayHeight) = 0;
     303             : 
     304             :   /**
     305             :    * Appends source video frames to mRawSegment. We only append the source chunk
     306             :    * if it is unique to mLastChunk. Called on the MediaStreamGraph thread.
     307             :    */
     308             :   nsresult AppendVideoSegment(const VideoSegment& aSegment);
     309             : 
     310             :   /**
     311             :    * Tells the video track encoder that we've reached the end of source stream,
     312             :    * and wakes up mReentrantMonitor if encoder is waiting for more track data.
     313             :    * Called on the MediaStreamGraph thread.
     314             :    */
     315             :   void NotifyEndOfStream() override;
     316             : 
     317             :   /**
     318             :    * The width of source video frame, ceiled if the source width is odd.
     319             :    */
     320             :   int mFrameWidth;
     321             : 
     322             :   /**
     323             :    * The height of source video frame, ceiled if the source height is odd.
     324             :    */
     325             :   int mFrameHeight;
     326             : 
     327             :   /**
     328             :    * The display width of source video frame.
     329             :    */
     330             :   int mDisplayWidth;
     331             : 
     332             :   /**
     333             :    * The display height of source video frame.
     334             :    */
     335             :   int mDisplayHeight;
     336             : 
     337             :   /**
     338             :    * The track rate of source video.
     339             :    */
     340             :   TrackRate mTrackRate;
     341             : 
     342             :   /**
     343             :    * The last unique frame and duration we've sent to track encoder,
     344             :    * kept track of in subclasses.
     345             :    */
     346             :   VideoChunk mLastChunk;
     347             : 
     348             :   /**
     349             :    * A segment queue of audio track data, protected by mReentrantMonitor.
     350             :    */
     351             :   VideoSegment mRawSegment;
     352             : 
     353             :   /**
     354             :    * The number of mTrackRate ticks we have passed to the encoder.
     355             :    * Only accessed in AppendVideoSegment().
     356             :    */
     357             :   StreamTime mEncodedTicks;
     358             : 
     359             :   /**
     360             :    * The time of the first real video frame passed to the encoder.
     361             :    * Only accessed in AppendVideoSegment().
     362             :    */
     363             :   TimeStamp mStartOffset;
     364             : 
     365             :   uint32_t mVideoBitrate;
     366             : };
     367             : 
     368             : } // namespace mozilla
     369             : 
     370             : #endif

Generated by: LCOV version 1.13