1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/DOMMediaStream.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,270 @@ 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 NSDOMMEDIASTREAM_H_ 1.10 +#define NSDOMMEDIASTREAM_H_ 1.11 + 1.12 +#include "nsIDOMMediaStream.h" 1.13 +#include "nsCycleCollectionParticipant.h" 1.14 +#include "nsWrapperCache.h" 1.15 +#include "StreamBuffer.h" 1.16 +#include "nsIDOMWindow.h" 1.17 + 1.18 +class nsXPCClassInfo; 1.19 +class nsIPrincipal; 1.20 + 1.21 +// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to 1.22 +// GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing 1.23 +// currentTime getter. 1.24 +#ifdef GetCurrentTime 1.25 +#undef GetCurrentTime 1.26 +#endif 1.27 +// X11 has a #define for CurrentTime. Unbelievable :-(. 1.28 +// See content/media/webaudio/AudioContext.h for more fun! 1.29 +#ifdef CurrentTime 1.30 +#undef CurrentTime 1.31 +#endif 1.32 + 1.33 +namespace mozilla { 1.34 + 1.35 +class MediaStream; 1.36 + 1.37 +namespace dom { 1.38 +class AudioNode; 1.39 +class MediaStreamTrack; 1.40 +class AudioStreamTrack; 1.41 +class VideoStreamTrack; 1.42 +} 1.43 + 1.44 +class MediaStreamDirectListener; 1.45 + 1.46 +/** 1.47 + * DOM wrapper for MediaStreams. 1.48 + */ 1.49 +class DOMMediaStream : public nsIDOMMediaStream, 1.50 + public nsWrapperCache 1.51 +{ 1.52 + friend class DOMLocalMediaStream; 1.53 + typedef dom::MediaStreamTrack MediaStreamTrack; 1.54 + typedef dom::AudioStreamTrack AudioStreamTrack; 1.55 + typedef dom::VideoStreamTrack VideoStreamTrack; 1.56 + 1.57 +public: 1.58 + typedef uint8_t TrackTypeHints; 1.59 + 1.60 + DOMMediaStream(); 1.61 + virtual ~DOMMediaStream(); 1.62 + 1.63 + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMMediaStream) 1.64 + NS_DECL_CYCLE_COLLECTING_ISUPPORTS 1.65 + 1.66 + nsIDOMWindow* GetParentObject() const 1.67 + { 1.68 + return mWindow; 1.69 + } 1.70 + virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; 1.71 + 1.72 + // WebIDL 1.73 + double CurrentTime(); 1.74 + 1.75 + void GetAudioTracks(nsTArray<nsRefPtr<AudioStreamTrack> >& aTracks); 1.76 + void GetVideoTracks(nsTArray<nsRefPtr<VideoStreamTrack> >& aTracks); 1.77 + 1.78 + MediaStream* GetStream() const { return mStream; } 1.79 + 1.80 + /** 1.81 + * Overridden in DOMLocalMediaStreams to allow getUserMedia to pass 1.82 + * data directly to RTCPeerConnection without going through graph queuing. 1.83 + * Returns a bool to let us know if direct data will be delivered. 1.84 + */ 1.85 + virtual bool AddDirectListener(MediaStreamDirectListener *aListener) { return false; } 1.86 + virtual void RemoveDirectListener(MediaStreamDirectListener *aListener) {} 1.87 + 1.88 + /** 1.89 + * Overridden in DOMLocalMediaStreams to allow getUserMedia to disable 1.90 + * media at the SourceMediaStream. 1.91 + */ 1.92 + virtual void SetTrackEnabled(TrackID aTrackID, bool aEnabled); 1.93 + 1.94 + bool IsFinished(); 1.95 + /** 1.96 + * Returns a principal indicating who may access this stream. The stream contents 1.97 + * can only be accessed by principals subsuming this principal. 1.98 + */ 1.99 + nsIPrincipal* GetPrincipal() { return mPrincipal; } 1.100 + 1.101 + /** 1.102 + * Indicate that data will be contributed to this stream from origin aPrincipal. 1.103 + * If aPrincipal is null, this is ignored. Otherwise, from now on the contents 1.104 + * of this stream can only be accessed by principals that subsume aPrincipal. 1.105 + * Returns true if the stream's principal changed. 1.106 + */ 1.107 + bool CombineWithPrincipal(nsIPrincipal* aPrincipal); 1.108 + 1.109 + /** 1.110 + * Called when this stream's MediaStreamGraph has been shut down. Normally 1.111 + * MSGs are only shut down when all streams have been removed, so this 1.112 + * will only be called during a forced shutdown due to application exit. 1.113 + */ 1.114 + void NotifyMediaStreamGraphShutdown(); 1.115 + /** 1.116 + * Called when the main-thread state of the MediaStream changed. 1.117 + */ 1.118 + void NotifyStreamStateChanged(); 1.119 + 1.120 + // Indicate what track types we eventually expect to add to this stream 1.121 + enum { 1.122 + HINT_CONTENTS_AUDIO = 1 << 0, 1.123 + HINT_CONTENTS_VIDEO = 1 << 1 1.124 + }; 1.125 + TrackTypeHints GetHintContents() const { return mHintContents; } 1.126 + void SetHintContents(TrackTypeHints aHintContents) { mHintContents = aHintContents; } 1.127 + 1.128 + /** 1.129 + * Create an nsDOMMediaStream whose underlying stream is a SourceMediaStream. 1.130 + */ 1.131 + static already_AddRefed<DOMMediaStream> 1.132 + CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents); 1.133 + 1.134 + /** 1.135 + * Create an nsDOMMediaStream whose underlying stream is a TrackUnionStream. 1.136 + */ 1.137 + static already_AddRefed<DOMMediaStream> 1.138 + CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0); 1.139 + 1.140 + void SetLogicalStreamStartTime(StreamTime aTime) 1.141 + { 1.142 + mLogicalStreamStartTime = aTime; 1.143 + } 1.144 + 1.145 + // Notifications from StreamListener. 1.146 + // CreateDOMTrack should only be called when it's safe to run script. 1.147 + MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType); 1.148 + MediaStreamTrack* GetDOMTrackFor(TrackID aTrackID); 1.149 + 1.150 + class OnTracksAvailableCallback { 1.151 + public: 1.152 + OnTracksAvailableCallback(uint8_t aExpectedTracks = 0) 1.153 + : mExpectedTracks(aExpectedTracks) {} 1.154 + virtual ~OnTracksAvailableCallback() {} 1.155 + virtual void NotifyTracksAvailable(DOMMediaStream* aStream) = 0; 1.156 + TrackTypeHints GetExpectedTracks() { return mExpectedTracks; } 1.157 + void SetExpectedTracks(TrackTypeHints aExpectedTracks) { mExpectedTracks = aExpectedTracks; } 1.158 + private: 1.159 + TrackTypeHints mExpectedTracks; 1.160 + }; 1.161 + // When one track of the appropriate type has been added for each bit set 1.162 + // in aCallback->GetExpectedTracks(), run aCallback->NotifyTracksAvailable. 1.163 + // It is allowed to do anything, including run script. 1.164 + // aCallback may run immediately during this call if tracks are already 1.165 + // available! 1.166 + // We only care about track additions, we'll fire the notification even if 1.167 + // some of the tracks have been removed. 1.168 + // Takes ownership of aCallback. 1.169 + // If GetExpectedTracks() returns 0, the callback will be fired as soon as there are any tracks. 1.170 + void OnTracksAvailable(OnTracksAvailableCallback* aCallback); 1.171 + 1.172 + /** 1.173 + * Add an nsISupports object that this stream will keep alive as long as 1.174 + * the stream is not finished. 1.175 + */ 1.176 + void AddConsumerToKeepAlive(nsISupports* aConsumer) 1.177 + { 1.178 + if (!IsFinished() && !mNotifiedOfMediaStreamGraphShutdown) { 1.179 + mConsumersToKeepAlive.AppendElement(aConsumer); 1.180 + } 1.181 + } 1.182 + 1.183 +protected: 1.184 + void Destroy(); 1.185 + void InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents); 1.186 + void InitTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents); 1.187 + void InitStreamCommon(MediaStream* aStream); 1.188 + 1.189 + void CheckTracksAvailable(); 1.190 + 1.191 + class StreamListener; 1.192 + friend class StreamListener; 1.193 + 1.194 + // StreamTime at which the currentTime attribute would return 0. 1.195 + StreamTime mLogicalStreamStartTime; 1.196 + 1.197 + // We need this to track our parent object. 1.198 + nsCOMPtr<nsIDOMWindow> mWindow; 1.199 + 1.200 + // MediaStream is owned by the graph, but we tell it when to die, and it won't 1.201 + // die until we let it. 1.202 + MediaStream* mStream; 1.203 + // Principal identifying who may access the contents of this stream. 1.204 + // If null, this stream can be used by anyone because it has no content yet. 1.205 + nsCOMPtr<nsIPrincipal> mPrincipal; 1.206 + 1.207 + nsAutoTArray<nsRefPtr<MediaStreamTrack>,2> mTracks; 1.208 + nsRefPtr<StreamListener> mListener; 1.209 + 1.210 + nsTArray<nsAutoPtr<OnTracksAvailableCallback> > mRunOnTracksAvailable; 1.211 + 1.212 + // Keep these alive until the stream finishes 1.213 + nsTArray<nsCOMPtr<nsISupports> > mConsumersToKeepAlive; 1.214 + 1.215 + // Indicate what track types we eventually expect to add to this stream 1.216 + uint8_t mHintContents; 1.217 + // Indicate what track types have been added to this stream 1.218 + uint8_t mTrackTypesAvailable; 1.219 + bool mNotifiedOfMediaStreamGraphShutdown; 1.220 +}; 1.221 + 1.222 +class DOMLocalMediaStream : public DOMMediaStream, 1.223 + public nsIDOMLocalMediaStream 1.224 +{ 1.225 +public: 1.226 + DOMLocalMediaStream() {} 1.227 + virtual ~DOMLocalMediaStream(); 1.228 + 1.229 + NS_DECL_ISUPPORTS_INHERITED 1.230 + 1.231 + virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; 1.232 + 1.233 + virtual void Stop(); 1.234 + 1.235 + /** 1.236 + * Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream. 1.237 + */ 1.238 + static already_AddRefed<DOMLocalMediaStream> 1.239 + CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents); 1.240 + 1.241 + /** 1.242 + * Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream. 1.243 + */ 1.244 + static already_AddRefed<DOMLocalMediaStream> 1.245 + CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0); 1.246 +}; 1.247 + 1.248 +class DOMAudioNodeMediaStream : public DOMMediaStream 1.249 +{ 1.250 + typedef dom::AudioNode AudioNode; 1.251 +public: 1.252 + DOMAudioNodeMediaStream(AudioNode* aNode); 1.253 + 1.254 + NS_DECL_ISUPPORTS_INHERITED 1.255 + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMAudioNodeMediaStream, DOMMediaStream) 1.256 + 1.257 + /** 1.258 + * Create a DOMAudioNodeMediaStream whose underlying stream is a TrackUnionStream. 1.259 + */ 1.260 + static already_AddRefed<DOMAudioNodeMediaStream> 1.261 + CreateTrackUnionStream(nsIDOMWindow* aWindow, 1.262 + AudioNode* aNode, 1.263 + TrackTypeHints aHintContents = 0); 1.264 + 1.265 +private: 1.266 + // If this object wraps a stream owned by an AudioNode, we need to ensure that 1.267 + // the node isn't cycle-collected too early. 1.268 + nsRefPtr<AudioNode> mStreamNode; 1.269 +}; 1.270 + 1.271 +} 1.272 + 1.273 +#endif /* NSDOMMEDIASTREAM_H_ */