Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #ifndef MEDIAENGINE_H_ |
michael@0 | 6 | #define MEDIAENGINE_H_ |
michael@0 | 7 | |
michael@0 | 8 | #include "mozilla/RefPtr.h" |
michael@0 | 9 | #include "nsIDOMFile.h" |
michael@0 | 10 | #include "DOMMediaStream.h" |
michael@0 | 11 | #include "MediaStreamGraph.h" |
michael@0 | 12 | |
michael@0 | 13 | namespace mozilla { |
michael@0 | 14 | |
michael@0 | 15 | class VideoTrackConstraintsN; |
michael@0 | 16 | class AudioTrackConstraintsN; |
michael@0 | 17 | |
michael@0 | 18 | /** |
michael@0 | 19 | * Abstract interface for managing audio and video devices. Each platform |
michael@0 | 20 | * must implement a concrete class that will map these classes and methods |
michael@0 | 21 | * to the appropriate backend. For example, on Desktop platforms, these will |
michael@0 | 22 | * correspond to equivalent webrtc (GIPS) calls, and on B2G they will map to |
michael@0 | 23 | * a Gonk interface. |
michael@0 | 24 | */ |
michael@0 | 25 | class MediaEngineVideoSource; |
michael@0 | 26 | class MediaEngineAudioSource; |
michael@0 | 27 | struct MediaEnginePrefs; |
michael@0 | 28 | |
michael@0 | 29 | enum MediaEngineState { |
michael@0 | 30 | kAllocated, |
michael@0 | 31 | kStarted, |
michael@0 | 32 | kStopped, |
michael@0 | 33 | kReleased |
michael@0 | 34 | }; |
michael@0 | 35 | |
michael@0 | 36 | // We only support 1 audio and 1 video track for now. |
michael@0 | 37 | enum { |
michael@0 | 38 | kVideoTrack = 1, |
michael@0 | 39 | kAudioTrack = 2 |
michael@0 | 40 | }; |
michael@0 | 41 | |
michael@0 | 42 | class MediaEngine |
michael@0 | 43 | { |
michael@0 | 44 | public: |
michael@0 | 45 | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngine) |
michael@0 | 46 | |
michael@0 | 47 | static const int DEFAULT_VIDEO_FPS = 30; |
michael@0 | 48 | static const int DEFAULT_VIDEO_MIN_FPS = 10; |
michael@0 | 49 | static const int DEFAULT_43_VIDEO_WIDTH = 640; |
michael@0 | 50 | static const int DEFAULT_43_VIDEO_HEIGHT = 480; |
michael@0 | 51 | static const int DEFAULT_169_VIDEO_WIDTH = 1280; |
michael@0 | 52 | static const int DEFAULT_169_VIDEO_HEIGHT = 720; |
michael@0 | 53 | static const int DEFAULT_AUDIO_TIMER_MS = 10; |
michael@0 | 54 | |
michael@0 | 55 | /* Populate an array of video sources in the nsTArray. Also include devices |
michael@0 | 56 | * that are currently unavailable. */ |
michael@0 | 57 | virtual void EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSource> >*) = 0; |
michael@0 | 58 | |
michael@0 | 59 | /* Populate an array of audio sources in the nsTArray. Also include devices |
michael@0 | 60 | * that are currently unavailable. */ |
michael@0 | 61 | virtual void EnumerateAudioDevices(nsTArray<nsRefPtr<MediaEngineAudioSource> >*) = 0; |
michael@0 | 62 | |
michael@0 | 63 | protected: |
michael@0 | 64 | virtual ~MediaEngine() {} |
michael@0 | 65 | }; |
michael@0 | 66 | |
michael@0 | 67 | /** |
michael@0 | 68 | * Common abstract base class for audio and video sources. |
michael@0 | 69 | */ |
michael@0 | 70 | class MediaEngineSource : public nsISupports |
michael@0 | 71 | { |
michael@0 | 72 | public: |
michael@0 | 73 | virtual ~MediaEngineSource() {} |
michael@0 | 74 | |
michael@0 | 75 | /* Populate the human readable name of this device in the nsAString */ |
michael@0 | 76 | virtual void GetName(nsAString&) = 0; |
michael@0 | 77 | |
michael@0 | 78 | /* Populate the UUID of this device in the nsAString */ |
michael@0 | 79 | virtual void GetUUID(nsAString&) = 0; |
michael@0 | 80 | |
michael@0 | 81 | /* Release the device back to the system. */ |
michael@0 | 82 | virtual nsresult Deallocate() = 0; |
michael@0 | 83 | |
michael@0 | 84 | /* Start the device and add the track to the provided SourceMediaStream, with |
michael@0 | 85 | * the provided TrackID. You may start appending data to the track |
michael@0 | 86 | * immediately after. */ |
michael@0 | 87 | virtual nsresult Start(SourceMediaStream*, TrackID) = 0; |
michael@0 | 88 | |
michael@0 | 89 | /* Take a snapshot from this source. In the case of video this is a single |
michael@0 | 90 | * image, and for audio, it is a snippet lasting aDuration milliseconds. The |
michael@0 | 91 | * duration argument is ignored for a MediaEngineVideoSource. |
michael@0 | 92 | */ |
michael@0 | 93 | virtual nsresult Snapshot(uint32_t aDuration, nsIDOMFile** aFile) = 0; |
michael@0 | 94 | |
michael@0 | 95 | /* Called when the stream wants more data */ |
michael@0 | 96 | virtual void NotifyPull(MediaStreamGraph* aGraph, |
michael@0 | 97 | SourceMediaStream *aSource, |
michael@0 | 98 | TrackID aId, |
michael@0 | 99 | StreamTime aDesiredTime, |
michael@0 | 100 | TrackTicks &aLastEndTime) = 0; |
michael@0 | 101 | |
michael@0 | 102 | /* Stop the device and release the corresponding MediaStream */ |
michael@0 | 103 | virtual nsresult Stop(SourceMediaStream *aSource, TrackID aID) = 0; |
michael@0 | 104 | |
michael@0 | 105 | /* Change device configuration. */ |
michael@0 | 106 | virtual nsresult Config(bool aEchoOn, uint32_t aEcho, |
michael@0 | 107 | bool aAgcOn, uint32_t aAGC, |
michael@0 | 108 | bool aNoiseOn, uint32_t aNoise, |
michael@0 | 109 | int32_t aPlayoutDelay) = 0; |
michael@0 | 110 | |
michael@0 | 111 | /* Returns true if a source represents a fake capture device and |
michael@0 | 112 | * false otherwise |
michael@0 | 113 | */ |
michael@0 | 114 | virtual bool IsFake() = 0; |
michael@0 | 115 | |
michael@0 | 116 | /* Return false if device is currently allocated or started */ |
michael@0 | 117 | bool IsAvailable() { |
michael@0 | 118 | if (mState == kAllocated || mState == kStarted) { |
michael@0 | 119 | return false; |
michael@0 | 120 | } else { |
michael@0 | 121 | return true; |
michael@0 | 122 | } |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | /* It is an error to call Start() before an Allocate(), and Stop() before |
michael@0 | 126 | * a Start(). Only Allocate() may be called after a Deallocate(). */ |
michael@0 | 127 | |
michael@0 | 128 | protected: |
michael@0 | 129 | MediaEngineState mState; |
michael@0 | 130 | }; |
michael@0 | 131 | |
michael@0 | 132 | /** |
michael@0 | 133 | * Video source and friends. |
michael@0 | 134 | */ |
michael@0 | 135 | class MediaEnginePrefs { |
michael@0 | 136 | public: |
michael@0 | 137 | int32_t mWidth; |
michael@0 | 138 | int32_t mHeight; |
michael@0 | 139 | int32_t mFPS; |
michael@0 | 140 | int32_t mMinFPS; |
michael@0 | 141 | |
michael@0 | 142 | // mWidth and/or mHeight may be zero (=adaptive default), so use functions. |
michael@0 | 143 | |
michael@0 | 144 | int32_t GetWidth(bool aHD = false) const { |
michael@0 | 145 | return mWidth? mWidth : (mHeight? |
michael@0 | 146 | (mHeight * GetDefWidth(aHD)) / GetDefHeight(aHD) : |
michael@0 | 147 | GetDefWidth(aHD)); |
michael@0 | 148 | } |
michael@0 | 149 | |
michael@0 | 150 | int32_t GetHeight(bool aHD = false) const { |
michael@0 | 151 | return mHeight? mHeight : (mWidth? |
michael@0 | 152 | (mWidth * GetDefHeight(aHD)) / GetDefWidth(aHD) : |
michael@0 | 153 | GetDefHeight(aHD)); |
michael@0 | 154 | } |
michael@0 | 155 | private: |
michael@0 | 156 | static int32_t GetDefWidth(bool aHD = false) { |
michael@0 | 157 | return aHD ? MediaEngine::DEFAULT_169_VIDEO_WIDTH : |
michael@0 | 158 | MediaEngine::DEFAULT_43_VIDEO_WIDTH; |
michael@0 | 159 | } |
michael@0 | 160 | |
michael@0 | 161 | static int32_t GetDefHeight(bool aHD = false) { |
michael@0 | 162 | return aHD ? MediaEngine::DEFAULT_169_VIDEO_HEIGHT : |
michael@0 | 163 | MediaEngine::DEFAULT_43_VIDEO_HEIGHT; |
michael@0 | 164 | } |
michael@0 | 165 | }; |
michael@0 | 166 | |
michael@0 | 167 | class MediaEngineVideoSource : public MediaEngineSource |
michael@0 | 168 | { |
michael@0 | 169 | public: |
michael@0 | 170 | virtual ~MediaEngineVideoSource() {} |
michael@0 | 171 | |
michael@0 | 172 | /* This call reserves but does not start the device. */ |
michael@0 | 173 | virtual nsresult Allocate(const VideoTrackConstraintsN &aConstraints, |
michael@0 | 174 | const MediaEnginePrefs &aPrefs) = 0; |
michael@0 | 175 | }; |
michael@0 | 176 | |
michael@0 | 177 | /** |
michael@0 | 178 | * Audio source and friends. |
michael@0 | 179 | */ |
michael@0 | 180 | class MediaEngineAudioSource : public MediaEngineSource |
michael@0 | 181 | { |
michael@0 | 182 | public: |
michael@0 | 183 | virtual ~MediaEngineAudioSource() {} |
michael@0 | 184 | |
michael@0 | 185 | /* This call reserves but does not start the device. */ |
michael@0 | 186 | virtual nsresult Allocate(const AudioTrackConstraintsN &aConstraints, |
michael@0 | 187 | const MediaEnginePrefs &aPrefs) = 0; |
michael@0 | 188 | |
michael@0 | 189 | }; |
michael@0 | 190 | |
michael@0 | 191 | } |
michael@0 | 192 | |
michael@0 | 193 | #endif /* MEDIAENGINE_H_ */ |