content/media/fmp4/PlatformDecoderModule.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #if !defined(PlatformDecoderModule_h_)
michael@0 8 #define PlatformDecoderModule_h_
michael@0 9
michael@0 10 #include "MediaDecoderReader.h"
michael@0 11 #include "mozilla/layers/LayersTypes.h"
michael@0 12 #include "nsTArray.h"
michael@0 13 #include "mozilla/RefPtr.h"
michael@0 14 #include <queue>
michael@0 15
michael@0 16 namespace mp4_demuxer {
michael@0 17 class VideoDecoderConfig;
michael@0 18 class AudioDecoderConfig;
michael@0 19 struct MP4Sample;
michael@0 20 }
michael@0 21
michael@0 22 class nsIThreadPool;
michael@0 23
michael@0 24 namespace mozilla {
michael@0 25
michael@0 26 namespace layers {
michael@0 27 class ImageContainer;
michael@0 28 }
michael@0 29
michael@0 30 class MediaDataDecoder;
michael@0 31 class MediaDataDecoderCallback;
michael@0 32 class MediaInputQueue;
michael@0 33 class MediaTaskQueue;
michael@0 34 typedef int64_t Microseconds;
michael@0 35
michael@0 36 // The PlatformDecoderModule interface is used by the MP4Reader to abstract
michael@0 37 // access to the H264 and AAC decoders provided by various platforms. It
michael@0 38 // may be extended to support other codecs in future. Each platform (Windows,
michael@0 39 // MacOSX, Linux, B2G etc) must implement a PlatformDecoderModule to provide
michael@0 40 // access to its decoders in order to get decompressed H.264/AAC from the
michael@0 41 // MP4Reader.
michael@0 42 //
michael@0 43 // Video decoding is asynchronous, and should be performed on the task queue
michael@0 44 // provided if the underlying platform isn't already exposing an async API.
michael@0 45 //
michael@0 46 // Platforms that don't have a corresponding PlatformDecoderModule won't be
michael@0 47 // able to play the H.264/AAC data output by the MP4Reader. In practice this
michael@0 48 // means that we won't have fragmented MP4 supported in Media Source
michael@0 49 // Extensions.
michael@0 50 //
michael@0 51 // A cross-platform decoder module that discards input and produces "blank"
michael@0 52 // output samples exists for testing, and is created when the pref
michael@0 53 // "media.fragmented-mp4.use-blank-decoder" is true.
michael@0 54 class PlatformDecoderModule {
michael@0 55 public:
michael@0 56 // Call on the main thread to initialize the static state
michael@0 57 // needed by Create().
michael@0 58 static void Init();
michael@0 59
michael@0 60 // Factory method that creates the appropriate PlatformDecoderModule for
michael@0 61 // the platform we're running on. Caller is responsible for deleting this
michael@0 62 // instance. It's expected that there will be multiple
michael@0 63 // PlatformDecoderModules alive at the same time. There is one
michael@0 64 // PlatformDecoderModule created per MP4Reader.
michael@0 65 // This is called on the decode thread.
michael@0 66 static PlatformDecoderModule* Create();
michael@0 67
michael@0 68 // Called to shutdown the decoder module and cleanup state. This should
michael@0 69 // block until shutdown is complete. This is called after Shutdown() has
michael@0 70 // been called on all MediaDataDecoders created from this
michael@0 71 // PlatformDecoderModule.
michael@0 72 // Called on the main thread only.
michael@0 73 virtual nsresult Shutdown() = 0;
michael@0 74
michael@0 75 // Creates an H.264 decoder. The layers backend is passed in so that
michael@0 76 // decoders can determine whether hardware accelerated decoding can be used.
michael@0 77 // Asynchronous decoding of video should be done in runnables dispatched
michael@0 78 // to aVideoTaskQueue. If the task queue isn't needed, the decoder should
michael@0 79 // not hold a reference to it.
michael@0 80 // Output and errors should be returned to the reader via aCallback.
michael@0 81 // On Windows the task queue's threads in have MSCOM initialized with
michael@0 82 // COINIT_MULTITHREADED.
michael@0 83 // Returns nullptr if the decoder can't be created.
michael@0 84 // It is safe to store a reference to aConfig.
michael@0 85 // Called on decode thread.
michael@0 86 virtual MediaDataDecoder* CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig,
michael@0 87 layers::LayersBackend aLayersBackend,
michael@0 88 layers::ImageContainer* aImageContainer,
michael@0 89 MediaTaskQueue* aVideoTaskQueue,
michael@0 90 MediaDataDecoderCallback* aCallback) = 0;
michael@0 91
michael@0 92 // Creates an AAC decoder with the specified properties.
michael@0 93 // Asynchronous decoding of audio should be done in runnables dispatched to
michael@0 94 // aAudioTaskQueue. If the task queue isn't needed, the decoder should
michael@0 95 // not hold a reference to it.
michael@0 96 // Output and errors should be returned to the reader via aCallback.
michael@0 97 // Returns nullptr if the decoder can't be created.
michael@0 98 // On Windows the task queue's threads in have MSCOM initialized with
michael@0 99 // COINIT_MULTITHREADED.
michael@0 100 // It is safe to store a reference to aConfig.
michael@0 101 // Called on decode thread.
michael@0 102 virtual MediaDataDecoder* CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
michael@0 103 MediaTaskQueue* aAudioTaskQueue,
michael@0 104 MediaDataDecoderCallback* aCallback) = 0;
michael@0 105
michael@0 106 virtual ~PlatformDecoderModule() {}
michael@0 107
michael@0 108 protected:
michael@0 109 PlatformDecoderModule() {}
michael@0 110 // Caches pref media.fragmented-mp4.use-blank-decoder
michael@0 111 static bool sUseBlankDecoder;
michael@0 112 static bool sFFmpegDecoderEnabled;
michael@0 113 };
michael@0 114
michael@0 115 // A callback used by MediaDataDecoder to return output/errors to the
michael@0 116 // MP4Reader. Implementation is threadsafe, and can be called on any thread.
michael@0 117 class MediaDataDecoderCallback {
michael@0 118 public:
michael@0 119 virtual ~MediaDataDecoderCallback() {}
michael@0 120
michael@0 121 // Called by MediaDataDecoder when a sample has been decoded. Callee is
michael@0 122 // responsibile for deleting aData.
michael@0 123 virtual void Output(MediaData* aData) = 0;
michael@0 124
michael@0 125 // Denotes an error in the decoding process. The reader will stop calling
michael@0 126 // the decoder.
michael@0 127 virtual void Error() = 0;
michael@0 128
michael@0 129 // Denotes that the last input sample has been inserted into the decoder,
michael@0 130 // and no more output can be produced unless more input is sent.
michael@0 131 virtual void InputExhausted() = 0;
michael@0 132 };
michael@0 133
michael@0 134 // MediaDataDecoder is the interface exposed by decoders created by the
michael@0 135 // PlatformDecoderModule's Create*Decoder() functions. The type of
michael@0 136 // media data that the decoder accepts as valid input and produces as
michael@0 137 // output is determined when the MediaDataDecoder is created.
michael@0 138 //
michael@0 139 // All functions must be threadsafe, and be able to be called on an
michael@0 140 // arbitrary thread.
michael@0 141 //
michael@0 142 // Decoding is done asynchronously. Any async work can be done on the
michael@0 143 // MediaTaskQueue passed into the PlatformDecoderModules's Create*Decoder()
michael@0 144 // function. This may not be necessary for platforms with async APIs
michael@0 145 // for decoding.
michael@0 146 class MediaDataDecoder {
michael@0 147 protected:
michael@0 148 virtual ~MediaDataDecoder() {};
michael@0 149
michael@0 150 public:
michael@0 151 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDataDecoder)
michael@0 152
michael@0 153 // Initialize the decoder. The decoder should be ready to decode after
michael@0 154 // this returns. The decoder should do any initialization here, rather
michael@0 155 // than in its constructor or PlatformDecoderModule::Create*Decoder(),
michael@0 156 // so that if the MP4Reader needs to shutdown during initialization,
michael@0 157 // it can call Shutdown() to cancel this operation. Any initialization
michael@0 158 // that requires blocking the calling thread in this function *must*
michael@0 159 // be done here so that it can be canceled by calling Shutdown()!
michael@0 160 virtual nsresult Init() = 0;
michael@0 161
michael@0 162 // Inserts a sample into the decoder's decode pipeline. The decoder must
michael@0 163 // delete the sample once its been decoded. If Input() returns an error,
michael@0 164 // aSample will be deleted by the caller.
michael@0 165 virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) = 0;
michael@0 166
michael@0 167 // Causes all samples in the decoding pipeline to be discarded. When
michael@0 168 // this function returns, the decoder must be ready to accept new input
michael@0 169 // for decoding. This function is called when the demuxer seeks, before
michael@0 170 // decoding resumes after the seek.
michael@0 171 // While the reader calls Flush(), it ignores all output sent to it;
michael@0 172 // it is safe (but pointless) to send output while Flush is called.
michael@0 173 // The MP4Reader will not call Input() while it's calling Flush().
michael@0 174 virtual nsresult Flush() = 0;
michael@0 175
michael@0 176 // Causes all complete samples in the pipeline that can be decoded to be
michael@0 177 // output. If the decoder can't produce samples from the current output,
michael@0 178 // it drops the input samples. The decoder may be holding onto samples
michael@0 179 // that are required to decode samples that it expects to get in future.
michael@0 180 // This is called when the demuxer reaches end of stream.
michael@0 181 // The MP4Reader will not call Input() while it's calling Drain().
michael@0 182 virtual nsresult Drain() = 0;
michael@0 183
michael@0 184 // Cancels all init/input/drain operations, and shuts down the
michael@0 185 // decoder. The platform decoder should clean up any resources it's using
michael@0 186 // and release memory etc. Shutdown() must block until the decoder has
michael@0 187 // completed shutdown. The reader calls Flush() before calling Shutdown().
michael@0 188 // The reader will delete the decoder once Shutdown() returns.
michael@0 189 // The MediaDataDecoderCallback *must* not be called after Shutdown() has
michael@0 190 // returned.
michael@0 191 virtual nsresult Shutdown() = 0;
michael@0 192
michael@0 193 };
michael@0 194
michael@0 195 } // namespace mozilla
michael@0 196
michael@0 197 #endif

mercurial