content/media/encoder/MediaEncoder.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/encoder/MediaEncoder.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,164 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef MediaEncoder_h_
    1.10 +#define MediaEncoder_h_
    1.11 +
    1.12 +#include "mozilla/DebugOnly.h"
    1.13 +#include "TrackEncoder.h"
    1.14 +#include "ContainerWriter.h"
    1.15 +#include "MediaStreamGraph.h"
    1.16 +
    1.17 +namespace mozilla {
    1.18 +
    1.19 +/**
    1.20 + * MediaEncoder is the framework of encoding module, it controls and manages
    1.21 + * procedures between ContainerWriter and TrackEncoder. ContainerWriter packs
    1.22 + * the encoded track data with a specific container (e.g. ogg, mp4).
    1.23 + * AudioTrackEncoder and VideoTrackEncoder are subclasses of TrackEncoder, and
    1.24 + * are responsible for encoding raw data coming from MediaStreamGraph.
    1.25 + *
    1.26 + * Also, MediaEncoder is a type of MediaStreamListener, it starts to receive raw
    1.27 + * segments after itself is added to the source stream. In the mean time,
    1.28 + * encoded track data is pulled by its owner periodically on a worker thread. A
    1.29 + * reentrant monitor is used to protect the push and pull of resource.
    1.30 + *
    1.31 + * MediaEncoder is designed to be a passive component, neither it owns nor in
    1.32 + * charge of managing threads. However, a monitor is used in function
    1.33 + * TrackEncoder::GetEncodedTrack() for the purpose of thread safety (e.g.
    1.34 + * between callbacks of MediaStreamListener and others), a call to this function
    1.35 + * might block. Therefore, MediaEncoder should not run on threads that forbid
    1.36 + * blocking, such as main thread or I/O thread.
    1.37 + *
    1.38 + * For example, an usage from MediaRecorder of this component would be:
    1.39 + * 1) Create an encoder with a valid MIME type.
    1.40 + *    => encoder = MediaEncoder::CreateEncoder(aMIMEType);
    1.41 + *    It then generate a ContainerWriter according to the MIME type, and an
    1.42 + *    AudioTrackEncoder (or a VideoTrackEncoder too) associated with the media
    1.43 + *    type.
    1.44 + *
    1.45 + * 2) Dispatch the task GetEncodedData() to a worker thread.
    1.46 + *
    1.47 + * 3) To start encoding, add this component to its source stream.
    1.48 + *    => sourceStream->AddListener(encoder);
    1.49 + *
    1.50 + * 4) To stop encoding, remove this component from its source stream.
    1.51 + *    => sourceStream->RemoveListener(encoder);
    1.52 + */
    1.53 +class MediaEncoder : public MediaStreamListener
    1.54 +{
    1.55 +public :
    1.56 +  enum {
    1.57 +    ENCODE_METADDATA,
    1.58 +    ENCODE_TRACK,
    1.59 +    ENCODE_DONE,
    1.60 +    ENCODE_ERROR,
    1.61 +  };
    1.62 +
    1.63 +  MediaEncoder(ContainerWriter* aWriter,
    1.64 +               AudioTrackEncoder* aAudioEncoder,
    1.65 +               VideoTrackEncoder* aVideoEncoder,
    1.66 +               const nsAString& aMIMEType)
    1.67 +    : mWriter(aWriter)
    1.68 +    , mAudioEncoder(aAudioEncoder)
    1.69 +    , mVideoEncoder(aVideoEncoder)
    1.70 +    , mStartTime(TimeStamp::Now())
    1.71 +    , mMIMEType(aMIMEType)
    1.72 +    , mState(MediaEncoder::ENCODE_METADDATA)
    1.73 +    , mShutdown(false)
    1.74 +  {}
    1.75 +
    1.76 +  ~MediaEncoder() {};
    1.77 +
    1.78 +  /**
    1.79 +   * Notified by the control loop of MediaStreamGraph; aQueueMedia is the raw
    1.80 +   * track data in form of MediaSegment.
    1.81 +   */
    1.82 +  virtual void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
    1.83 +                                        TrackRate aTrackRate,
    1.84 +                                        TrackTicks aTrackOffset,
    1.85 +                                        uint32_t aTrackEvents,
    1.86 +                                        const MediaSegment& aQueuedMedia);
    1.87 +
    1.88 +  /**
    1.89 +   * Notified the stream is being removed.
    1.90 +   */
    1.91 +  virtual void NotifyRemoved(MediaStreamGraph* aGraph);
    1.92 +
    1.93 +  /**
    1.94 +   * Creates an encoder with a given MIME type. Returns null if we are unable
    1.95 +   * to create the encoder. For now, default aMIMEType to "audio/ogg" and use
    1.96 +   * Ogg+Opus if it is empty.
    1.97 +   */
    1.98 +  static already_AddRefed<MediaEncoder> CreateEncoder(const nsAString& aMIMEType,
    1.99 +                                                      uint8_t aTrackTypes = ContainerWriter::CREATE_AUDIO_TRACK);
   1.100 +  /**
   1.101 +   * Encodes the raw track data and returns the final container data. Assuming
   1.102 +   * it is called on a single worker thread. The buffer of container data is
   1.103 +   * allocated in ContainerWriter::GetContainerData(), and is appended to
   1.104 +   * aOutputBufs. aMIMEType is the valid mime-type of this returned container
   1.105 +   * data.
   1.106 +   */
   1.107 +  void GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
   1.108 +                      nsAString& aMIMEType);
   1.109 +
   1.110 +  /**
   1.111 +   * Return true if MediaEncoder has been shutdown. Reasons are encoding
   1.112 +   * complete, encounter an error, or being canceled by its caller.
   1.113 +   */
   1.114 +  bool IsShutdown()
   1.115 +  {
   1.116 +    return mShutdown;
   1.117 +  }
   1.118 +
   1.119 +  /**
   1.120 +   * Cancel the encoding, and wakes up the lock of reentrant monitor in encoder.
   1.121 +   */
   1.122 +  void Cancel()
   1.123 +  {
   1.124 +    if (mAudioEncoder) {
   1.125 +      mAudioEncoder->NotifyCancel();
   1.126 +    }
   1.127 +    if (mVideoEncoder) {
   1.128 +      mVideoEncoder->NotifyCancel();
   1.129 +    }
   1.130 +  }
   1.131 +
   1.132 +  bool HasError()
   1.133 +  {
   1.134 +    return mState == ENCODE_ERROR;
   1.135 +  }
   1.136 +
   1.137 +#ifdef MOZ_WEBM_ENCODER
   1.138 +  static bool IsWebMEncoderEnabled();
   1.139 +#endif
   1.140 +
   1.141 +#ifdef MOZ_OMX_ENCODER
   1.142 +  static bool IsOMXEncoderEnabled();
   1.143 +#endif
   1.144 +
   1.145 +private:
   1.146 +  // Get encoded data from trackEncoder and write to muxer
   1.147 +  nsresult WriteEncodedDataToMuxer(TrackEncoder *aTrackEncoder);
   1.148 +  // Get metadata from trackEncoder and copy to muxer
   1.149 +  nsresult CopyMetadataToMuxer(TrackEncoder* aTrackEncoder);
   1.150 +  nsAutoPtr<ContainerWriter> mWriter;
   1.151 +  nsAutoPtr<AudioTrackEncoder> mAudioEncoder;
   1.152 +  nsAutoPtr<VideoTrackEncoder> mVideoEncoder;
   1.153 +  TimeStamp mStartTime;
   1.154 +  nsString mMIMEType;
   1.155 +  int mState;
   1.156 +  bool mShutdown;
   1.157 +  // Get duration from create encoder, for logging purpose
   1.158 +  double GetEncodeTimeStamp()
   1.159 +  {
   1.160 +    TimeDuration decodeTime;
   1.161 +    decodeTime = TimeStamp::Now() - mStartTime;
   1.162 +    return decodeTime.ToMilliseconds();
   1.163 +  }
   1.164 +};
   1.165 +
   1.166 +}
   1.167 +#endif

mercurial