content/media/encoder/MediaEncoder.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 #ifndef MediaEncoder_h_
     7 #define MediaEncoder_h_
     9 #include "mozilla/DebugOnly.h"
    10 #include "TrackEncoder.h"
    11 #include "ContainerWriter.h"
    12 #include "MediaStreamGraph.h"
    14 namespace mozilla {
    16 /**
    17  * MediaEncoder is the framework of encoding module, it controls and manages
    18  * procedures between ContainerWriter and TrackEncoder. ContainerWriter packs
    19  * the encoded track data with a specific container (e.g. ogg, mp4).
    20  * AudioTrackEncoder and VideoTrackEncoder are subclasses of TrackEncoder, and
    21  * are responsible for encoding raw data coming from MediaStreamGraph.
    22  *
    23  * Also, MediaEncoder is a type of MediaStreamListener, it starts to receive raw
    24  * segments after itself is added to the source stream. In the mean time,
    25  * encoded track data is pulled by its owner periodically on a worker thread. A
    26  * reentrant monitor is used to protect the push and pull of resource.
    27  *
    28  * MediaEncoder is designed to be a passive component, neither it owns nor in
    29  * charge of managing threads. However, a monitor is used in function
    30  * TrackEncoder::GetEncodedTrack() for the purpose of thread safety (e.g.
    31  * between callbacks of MediaStreamListener and others), a call to this function
    32  * might block. Therefore, MediaEncoder should not run on threads that forbid
    33  * blocking, such as main thread or I/O thread.
    34  *
    35  * For example, an usage from MediaRecorder of this component would be:
    36  * 1) Create an encoder with a valid MIME type.
    37  *    => encoder = MediaEncoder::CreateEncoder(aMIMEType);
    38  *    It then generate a ContainerWriter according to the MIME type, and an
    39  *    AudioTrackEncoder (or a VideoTrackEncoder too) associated with the media
    40  *    type.
    41  *
    42  * 2) Dispatch the task GetEncodedData() to a worker thread.
    43  *
    44  * 3) To start encoding, add this component to its source stream.
    45  *    => sourceStream->AddListener(encoder);
    46  *
    47  * 4) To stop encoding, remove this component from its source stream.
    48  *    => sourceStream->RemoveListener(encoder);
    49  */
    50 class MediaEncoder : public MediaStreamListener
    51 {
    52 public :
    53   enum {
    54     ENCODE_METADDATA,
    55     ENCODE_TRACK,
    56     ENCODE_DONE,
    57     ENCODE_ERROR,
    58   };
    60   MediaEncoder(ContainerWriter* aWriter,
    61                AudioTrackEncoder* aAudioEncoder,
    62                VideoTrackEncoder* aVideoEncoder,
    63                const nsAString& aMIMEType)
    64     : mWriter(aWriter)
    65     , mAudioEncoder(aAudioEncoder)
    66     , mVideoEncoder(aVideoEncoder)
    67     , mStartTime(TimeStamp::Now())
    68     , mMIMEType(aMIMEType)
    69     , mState(MediaEncoder::ENCODE_METADDATA)
    70     , mShutdown(false)
    71   {}
    73   ~MediaEncoder() {};
    75   /**
    76    * Notified by the control loop of MediaStreamGraph; aQueueMedia is the raw
    77    * track data in form of MediaSegment.
    78    */
    79   virtual void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
    80                                         TrackRate aTrackRate,
    81                                         TrackTicks aTrackOffset,
    82                                         uint32_t aTrackEvents,
    83                                         const MediaSegment& aQueuedMedia);
    85   /**
    86    * Notified the stream is being removed.
    87    */
    88   virtual void NotifyRemoved(MediaStreamGraph* aGraph);
    90   /**
    91    * Creates an encoder with a given MIME type. Returns null if we are unable
    92    * to create the encoder. For now, default aMIMEType to "audio/ogg" and use
    93    * Ogg+Opus if it is empty.
    94    */
    95   static already_AddRefed<MediaEncoder> CreateEncoder(const nsAString& aMIMEType,
    96                                                       uint8_t aTrackTypes = ContainerWriter::CREATE_AUDIO_TRACK);
    97   /**
    98    * Encodes the raw track data and returns the final container data. Assuming
    99    * it is called on a single worker thread. The buffer of container data is
   100    * allocated in ContainerWriter::GetContainerData(), and is appended to
   101    * aOutputBufs. aMIMEType is the valid mime-type of this returned container
   102    * data.
   103    */
   104   void GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
   105                       nsAString& aMIMEType);
   107   /**
   108    * Return true if MediaEncoder has been shutdown. Reasons are encoding
   109    * complete, encounter an error, or being canceled by its caller.
   110    */
   111   bool IsShutdown()
   112   {
   113     return mShutdown;
   114   }
   116   /**
   117    * Cancel the encoding, and wakes up the lock of reentrant monitor in encoder.
   118    */
   119   void Cancel()
   120   {
   121     if (mAudioEncoder) {
   122       mAudioEncoder->NotifyCancel();
   123     }
   124     if (mVideoEncoder) {
   125       mVideoEncoder->NotifyCancel();
   126     }
   127   }
   129   bool HasError()
   130   {
   131     return mState == ENCODE_ERROR;
   132   }
   134 #ifdef MOZ_WEBM_ENCODER
   135   static bool IsWebMEncoderEnabled();
   136 #endif
   138 #ifdef MOZ_OMX_ENCODER
   139   static bool IsOMXEncoderEnabled();
   140 #endif
   142 private:
   143   // Get encoded data from trackEncoder and write to muxer
   144   nsresult WriteEncodedDataToMuxer(TrackEncoder *aTrackEncoder);
   145   // Get metadata from trackEncoder and copy to muxer
   146   nsresult CopyMetadataToMuxer(TrackEncoder* aTrackEncoder);
   147   nsAutoPtr<ContainerWriter> mWriter;
   148   nsAutoPtr<AudioTrackEncoder> mAudioEncoder;
   149   nsAutoPtr<VideoTrackEncoder> mVideoEncoder;
   150   TimeStamp mStartTime;
   151   nsString mMIMEType;
   152   int mState;
   153   bool mShutdown;
   154   // Get duration from create encoder, for logging purpose
   155   double GetEncodeTimeStamp()
   156   {
   157     TimeDuration decodeTime;
   158     decodeTime = TimeStamp::Now() - mStartTime;
   159     return decodeTime.ToMilliseconds();
   160   }
   161 };
   163 }
   164 #endif

mercurial