MediaStreamAudioSourceNode.h (4983B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MediaStreamAudioSourceNode_h_ 8 #define MediaStreamAudioSourceNode_h_ 9 10 #include "AudioNode.h" 11 #include "AudioNodeEngine.h" 12 #include "DOMMediaStream.h" 13 #include "PrincipalChangeObserver.h" 14 15 namespace mozilla::dom { 16 17 class AudioContext; 18 struct MediaStreamAudioSourceOptions; 19 20 class MediaStreamAudioSourceNodeEngine final : public AudioNodeEngine { 21 public: 22 explicit MediaStreamAudioSourceNodeEngine(AudioNode* aNode) 23 : AudioNodeEngine(aNode), mEnabled(false) {} 24 25 bool IsEnabled() const { return mEnabled; } 26 enum Parameters { ENABLE }; 27 void SetInt32Parameter(uint32_t aIndex, int32_t aValue) override { 28 switch (aIndex) { 29 case ENABLE: 30 mEnabled = !!aValue; 31 break; 32 default: 33 NS_ERROR("MediaStreamAudioSourceNodeEngine bad parameter index"); 34 } 35 } 36 37 private: 38 bool mEnabled; 39 }; 40 41 class MediaStreamAudioSourceNode 42 : public AudioNode, 43 public PrincipalChangeObserver<MediaStreamTrack> { 44 public: 45 static already_AddRefed<MediaStreamAudioSourceNode> Create( 46 AudioContext& aContext, const MediaStreamAudioSourceOptions& aOptions, 47 ErrorResult& aRv); 48 49 NS_DECL_ISUPPORTS_INHERITED 50 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamAudioSourceNode, 51 AudioNode) 52 53 static already_AddRefed<MediaStreamAudioSourceNode> Constructor( 54 const GlobalObject& aGlobal, AudioContext& aAudioContext, 55 const MediaStreamAudioSourceOptions& aOptions, ErrorResult& aRv) { 56 return Create(aAudioContext, aOptions, aRv); 57 } 58 59 JSObject* WrapObject(JSContext* aCx, 60 JS::Handle<JSObject*> aGivenProto) override; 61 62 void DestroyMediaTrack() override; 63 64 uint16_t NumberOfInputs() const override { return 0; } 65 66 DOMMediaStream* GetMediaStream() { return mInputStream; } 67 68 const char* NodeType() const override { return "MediaStreamAudioSourceNode"; } 69 70 virtual const char* CrossOriginErrorString() const { 71 return "MediaStreamAudioSourceNodeCrossOrigin"; 72 } 73 74 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override; 75 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override; 76 77 // Attaches to aTrack so that its audio content will be used as input. 78 void AttachToTrack(AudioStreamTrack* aTrack); 79 80 // Detaches from the currently attached track if there is one. 81 void DetachFromTrack(); 82 83 // Attaches to the first audio track in the MediaStream, when the tracks are 84 // ordered by id. 85 void AttachToRightTrack(const RefPtr<DOMMediaStream>& aMediaStream, 86 ErrorResult& aRv); 87 88 // From DOMMediaStream::TrackListener. 89 void NotifyTrackAdded(const RefPtr<MediaStreamTrack>& aTrack); 90 void NotifyTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack); 91 void NotifyAudible(); 92 93 class TrackListener final : public DOMMediaStream::TrackListener { 94 public: 95 NS_DECL_ISUPPORTS_INHERITED 96 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TrackListener, 97 DOMMediaStream::TrackListener) 98 explicit TrackListener(MediaStreamAudioSourceNode* aNode) : mNode(aNode) {} 99 void NotifyTrackAdded(const RefPtr<MediaStreamTrack>& aTrack) override { 100 mNode->NotifyTrackAdded(aTrack); 101 } 102 void NotifyTrackRemoved(const RefPtr<MediaStreamTrack>& aTrack) override { 103 mNode->NotifyTrackRemoved(aTrack); 104 } 105 void NotifyAudible() override { mNode->NotifyAudible(); } 106 107 private: 108 virtual ~TrackListener() = default; 109 RefPtr<MediaStreamAudioSourceNode> mNode; 110 }; 111 112 // From PrincipalChangeObserver<MediaStreamTrack>. 113 void PrincipalChanged(MediaStreamTrack* aMediaStreamTrack) override; 114 115 // This allows implementing the correct behaviour for both 116 // MediaElementAudioSourceNode and MediaStreamAudioSourceNode, that have most 117 // of their behaviour shared. 118 enum TrackChangeBehavior { 119 // MediaStreamAudioSourceNode locks on the track it picked, and never 120 // changes. 121 LockOnTrackPicked, 122 // MediaElementAudioSourceNode can change track, depending on what the 123 // HTMLMediaElement does. 124 FollowChanges 125 }; 126 127 protected: 128 MediaStreamAudioSourceNode(AudioContext* aContext, 129 TrackChangeBehavior aBehavior); 130 void Init(DOMMediaStream& aMediaStream, ErrorResult& aRv); 131 virtual void Destroy(); 132 virtual ~MediaStreamAudioSourceNode(); 133 134 private: 135 const TrackChangeBehavior mBehavior; 136 RefPtr<MediaInputPort> mInputPort; 137 RefPtr<DOMMediaStream> mInputStream; 138 139 // On construction we set this to the first audio track of mInputStream. 140 RefPtr<AudioStreamTrack> mInputTrack; 141 RefPtr<TrackListener> mListener; 142 }; 143 144 } // namespace mozilla::dom 145 146 #endif