1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef MEDIAENGINEDEFAULT_H_
6 #define MEDIAENGINEDEFAULT_H_
7 
8 #include "nsITimer.h"
9 
10 #include "nsAutoPtr.h"
11 #include "nsCOMPtr.h"
12 #include "DOMMediaStream.h"
13 #include "nsComponentManagerUtils.h"
14 #include "mozilla/Monitor.h"
15 
16 #include "VideoUtils.h"
17 #include "MediaEngine.h"
18 #include "VideoSegment.h"
19 #include "AudioSegment.h"
20 #include "StreamTracks.h"
21 #ifdef MOZ_WEBRTC
22 #include "MediaEngineCameraVideoSource.h"
23 #endif
24 #include "MediaStreamGraph.h"
25 #include "MediaTrackConstraints.h"
26 
27 namespace mozilla {
28 
29 namespace layers {
30 class ImageContainer;
31 } // namespace layers
32 
33 class MediaEngineDefault;
34 
35 /**
36  * The default implementation of the MediaEngine interface.
37  */
38 class MediaEngineDefaultVideoSource : public nsITimerCallback,
39 #ifdef MOZ_WEBRTC
40                                       public MediaEngineCameraVideoSource
41 #else
42                                       public MediaEngineVideoSource
43 #endif
44 {
45 public:
46   MediaEngineDefaultVideoSource();
47 
48   void GetName(nsAString&) const override;
49   void GetUUID(nsACString&) const override;
50 
51   nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
52                     const MediaEnginePrefs &aPrefs,
53                     const nsString& aDeviceId,
54                     const nsACString& aOrigin,
55                     AllocationHandle** aOutHandle,
56                     const char** aOutBadConstraint) override;
57   nsresult Deallocate(AllocationHandle* aHandle) override;
58   nsresult Start(SourceMediaStream*, TrackID, const PrincipalHandle&) override;
59   nsresult Stop(SourceMediaStream*, TrackID) override;
60   nsresult Restart(AllocationHandle* aHandle,
61                    const dom::MediaTrackConstraints& aConstraints,
62                    const MediaEnginePrefs &aPrefs,
63                    const nsString& aDeviceId,
64                    const char** aOutBadConstraint) override;
SetDirectListeners(bool aHasDirectListeners)65   void SetDirectListeners(bool aHasDirectListeners) override {};
66   void NotifyPull(MediaStreamGraph* aGraph,
67                   SourceMediaStream *aSource,
68                   TrackID aId,
69                   StreamTime aDesiredTime,
70                   const PrincipalHandle& aPrincipalHandle) override;
71   uint32_t GetBestFitnessDistance(
72       const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
73       const nsString& aDeviceId) const override;
74 
IsFake()75   bool IsFake() override {
76     return true;
77   }
78 
GetMediaSource()79   dom::MediaSourceEnum GetMediaSource() const override {
80     return dom::MediaSourceEnum::Camera;
81   }
82 
TakePhoto(MediaEnginePhotoCallback * aCallback)83   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
84   {
85     return NS_ERROR_NOT_IMPLEMENTED;
86   }
87 
88   NS_DECL_THREADSAFE_ISUPPORTS
89   NS_DECL_NSITIMERCALLBACK
90 
91 protected:
92   ~MediaEngineDefaultVideoSource();
93 
94   friend class MediaEngineDefault;
95 
96   TrackID mTrackID;
97   nsCOMPtr<nsITimer> mTimer;
98   // mMonitor protects mImage access/changes, and transitions of mState
99   // from kStarted to kStopped (which are combined with EndTrack() and
100   // image changes).
101   Monitor mMonitor;
102   RefPtr<layers::Image> mImage;
103 
104   RefPtr<layers::ImageContainer> mImageContainer;
105 
106   MediaEnginePrefs mOpts;
107   int mCb;
108   int mCr;
109 };
110 
111 class SineWaveGenerator;
112 
113 class MediaEngineDefaultAudioSource : public MediaEngineAudioSource
114 {
115 public:
116   MediaEngineDefaultAudioSource();
117 
118   void GetName(nsAString&) const override;
119   void GetUUID(nsACString&) const override;
120 
121   nsresult Allocate(const dom::MediaTrackConstraints &aConstraints,
122                     const MediaEnginePrefs &aPrefs,
123                     const nsString& aDeviceId,
124                     const nsACString& aOrigin,
125                     AllocationHandle** aOutHandle,
126                     const char** aOutBadConstraint) override;
127   nsresult Deallocate(AllocationHandle* aHandle) override;
128   nsresult Start(SourceMediaStream*, TrackID, const PrincipalHandle&) override;
129   nsresult Stop(SourceMediaStream*, TrackID) override;
130   nsresult Restart(AllocationHandle* aHandle,
131                    const dom::MediaTrackConstraints& aConstraints,
132                    const MediaEnginePrefs &aPrefs,
133                    const nsString& aDeviceId,
134                    const char** aOutBadConstraint) override;
SetDirectListeners(bool aHasDirectListeners)135   void SetDirectListeners(bool aHasDirectListeners) override {};
136   void inline AppendToSegment(AudioSegment& aSegment,
137                               TrackTicks aSamples,
138                               const PrincipalHandle& aPrincipalHandle);
139   void NotifyPull(MediaStreamGraph* aGraph,
140                   SourceMediaStream *aSource,
141                   TrackID aId,
142                   StreamTime aDesiredTime,
143                   const PrincipalHandle& aPrincipalHandle) override;
144 
NotifyOutputData(MediaStreamGraph * aGraph,AudioDataValue * aBuffer,size_t aFrames,TrackRate aRate,uint32_t aChannels)145   void NotifyOutputData(MediaStreamGraph* aGraph,
146                         AudioDataValue* aBuffer, size_t aFrames,
147                         TrackRate aRate, uint32_t aChannels) override
148   {}
NotifyInputData(MediaStreamGraph * aGraph,const AudioDataValue * aBuffer,size_t aFrames,TrackRate aRate,uint32_t aChannels)149   void NotifyInputData(MediaStreamGraph* aGraph,
150                        const AudioDataValue* aBuffer, size_t aFrames,
151                        TrackRate aRate, uint32_t aChannels) override
152   {}
DeviceChanged()153   void DeviceChanged() override
154   {}
IsFake()155   bool IsFake() override {
156     return true;
157   }
158 
GetMediaSource()159   dom::MediaSourceEnum GetMediaSource() const override {
160     return dom::MediaSourceEnum::Microphone;
161   }
162 
TakePhoto(MediaEnginePhotoCallback * aCallback)163   nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override
164   {
165     return NS_ERROR_NOT_IMPLEMENTED;
166   }
167 
168   uint32_t GetBestFitnessDistance(
169       const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
170       const nsString& aDeviceId) const override;
171 
172   NS_DECL_THREADSAFE_ISUPPORTS
173 
174 protected:
175   ~MediaEngineDefaultAudioSource();
176 
177   TrackID mTrackID;
178 
179   TrackTicks mLastNotify; // Accessed in ::Start(), then on NotifyPull (from MSG thread)
180 
181   // Created on Allocate, then accessed from NotifyPull (MSG thread)
182   nsAutoPtr<SineWaveGenerator> mSineGenerator;
183 };
184 
185 
186 class MediaEngineDefault : public MediaEngine
187 {
188   typedef MediaEngine Super;
189 public:
MediaEngineDefault()190   explicit MediaEngineDefault() : mMutex("mozilla::MediaEngineDefault") {}
191 
192   void EnumerateVideoDevices(dom::MediaSourceEnum,
193                              nsTArray<RefPtr<MediaEngineVideoSource> >*) override;
194   void EnumerateAudioDevices(dom::MediaSourceEnum,
195                              nsTArray<RefPtr<MediaEngineAudioSource> >*) override;
Shutdown()196   void Shutdown() override {
197     MutexAutoLock lock(mMutex);
198 
199     mVSources.Clear();
200     mASources.Clear();
201   };
202 
203 private:
~MediaEngineDefault()204   ~MediaEngineDefault() {}
205 
206   Mutex mMutex;
207   // protected with mMutex:
208 
209   nsTArray<RefPtr<MediaEngineVideoSource> > mVSources;
210   nsTArray<RefPtr<MediaEngineAudioSource> > mASources;
211 };
212 
213 } // namespace mozilla
214 
215 #endif /* NSMEDIAENGINEDEFAULT_H_ */
216