/src/mozilla-central/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "MediaStreamAudioDestinationNode.h" |
8 | | #include "nsIDocument.h" |
9 | | #include "mozilla/dom/MediaStreamAudioDestinationNodeBinding.h" |
10 | | #include "AudioNodeEngine.h" |
11 | | #include "AudioNodeStream.h" |
12 | | #include "DOMMediaStream.h" |
13 | | #include "MediaStreamTrack.h" |
14 | | #include "TrackUnionStream.h" |
15 | | |
16 | | namespace mozilla { |
17 | | namespace dom { |
18 | | |
19 | | class AudioDestinationTrackSource final : |
20 | | public MediaStreamTrackSource |
21 | | { |
22 | | public: |
23 | | NS_DECL_ISUPPORTS_INHERITED |
24 | | NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioDestinationTrackSource, |
25 | | MediaStreamTrackSource) |
26 | | |
27 | | AudioDestinationTrackSource(MediaStreamAudioDestinationNode* aNode, |
28 | | nsIPrincipal* aPrincipal) |
29 | | : MediaStreamTrackSource(aPrincipal, nsString()) |
30 | | , mNode(aNode) |
31 | 0 | { |
32 | 0 | } |
33 | | |
34 | | void Destroy() override |
35 | 0 | { |
36 | 0 | if (mNode) { |
37 | 0 | mNode->DestroyMediaStream(); |
38 | 0 | mNode = nullptr; |
39 | 0 | } |
40 | 0 | } |
41 | | |
42 | | MediaSourceEnum GetMediaSource() const override |
43 | 0 | { |
44 | 0 | return MediaSourceEnum::AudioCapture; |
45 | 0 | } |
46 | | |
47 | | void Stop() override |
48 | 0 | { |
49 | 0 | Destroy(); |
50 | 0 | } |
51 | | |
52 | | void Disable() override |
53 | 0 | { |
54 | 0 | } |
55 | | |
56 | | void Enable() override |
57 | 0 | { |
58 | 0 | } |
59 | | |
60 | | private: |
61 | 0 | ~AudioDestinationTrackSource() = default; |
62 | | |
63 | | RefPtr<MediaStreamAudioDestinationNode> mNode; |
64 | | }; |
65 | | |
66 | | NS_IMPL_ADDREF_INHERITED(AudioDestinationTrackSource, |
67 | | MediaStreamTrackSource) |
68 | | NS_IMPL_RELEASE_INHERITED(AudioDestinationTrackSource, |
69 | | MediaStreamTrackSource) |
70 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioDestinationTrackSource) |
71 | 0 | NS_INTERFACE_MAP_END_INHERITING(MediaStreamTrackSource) |
72 | | NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioDestinationTrackSource, |
73 | | MediaStreamTrackSource, |
74 | | mNode) |
75 | | |
76 | | NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaStreamAudioDestinationNode, AudioNode, mDOMStream) |
77 | | |
78 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaStreamAudioDestinationNode) |
79 | 0 | NS_INTERFACE_MAP_END_INHERITING(AudioNode) |
80 | | |
81 | | NS_IMPL_ADDREF_INHERITED(MediaStreamAudioDestinationNode, AudioNode) |
82 | | NS_IMPL_RELEASE_INHERITED(MediaStreamAudioDestinationNode, AudioNode) |
83 | | |
84 | | MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* aContext) |
85 | | : AudioNode(aContext, |
86 | | 2, |
87 | | ChannelCountMode::Explicit, |
88 | | ChannelInterpretation::Speakers) |
89 | | , mDOMStream( |
90 | | DOMAudioNodeMediaStream::CreateTrackUnionStreamAsInput(GetOwner(), |
91 | | this, |
92 | | aContext->Graph())) |
93 | 0 | { |
94 | 0 | // Ensure an audio track with the correct ID is exposed to JS |
95 | 0 | nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc(); |
96 | 0 | RefPtr<MediaStreamTrackSource> source = |
97 | 0 | new AudioDestinationTrackSource(this, doc->NodePrincipal()); |
98 | 0 | RefPtr<MediaStreamTrack> track = |
99 | 0 | mDOMStream->CreateDOMTrack(AudioNodeStream::AUDIO_TRACK, |
100 | 0 | MediaSegment::AUDIO, source, |
101 | 0 | MediaTrackConstraints()); |
102 | 0 | mDOMStream->AddTrackInternal(track); |
103 | 0 |
|
104 | 0 | ProcessedMediaStream* outputStream = mDOMStream->GetInputStream()->AsProcessedStream(); |
105 | 0 | MOZ_ASSERT(!!outputStream); |
106 | 0 | AudioNodeEngine* engine = new AudioNodeEngine(this); |
107 | 0 | mStream = AudioNodeStream::Create(aContext, engine, |
108 | 0 | AudioNodeStream::EXTERNAL_OUTPUT, |
109 | 0 | aContext->Graph()); |
110 | 0 | mPort = outputStream->AllocateInputPort(mStream, AudioNodeStream::AUDIO_TRACK); |
111 | 0 | } |
112 | | |
113 | | /* static */ already_AddRefed<MediaStreamAudioDestinationNode> |
114 | | MediaStreamAudioDestinationNode::Create(AudioContext& aAudioContext, |
115 | | const AudioNodeOptions& aOptions, |
116 | | ErrorResult& aRv) |
117 | 0 | { |
118 | 0 | if (aAudioContext.IsOffline()) { |
119 | 0 | aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); |
120 | 0 | return nullptr; |
121 | 0 | } |
122 | 0 | |
123 | 0 | if (aAudioContext.CheckClosed(aRv)) { |
124 | 0 | return nullptr; |
125 | 0 | } |
126 | 0 | |
127 | 0 | RefPtr<MediaStreamAudioDestinationNode> audioNode = |
128 | 0 | new MediaStreamAudioDestinationNode(&aAudioContext); |
129 | 0 |
|
130 | 0 | audioNode->Initialize(aOptions, aRv); |
131 | 0 | if (NS_WARN_IF(aRv.Failed())) { |
132 | 0 | return nullptr; |
133 | 0 | } |
134 | 0 | |
135 | 0 | return audioNode.forget(); |
136 | 0 | } |
137 | | |
138 | | size_t |
139 | | MediaStreamAudioDestinationNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const |
140 | 0 | { |
141 | 0 | // Future: |
142 | 0 | // - mDOMStream |
143 | 0 | size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf); |
144 | 0 | amount += mPort->SizeOfIncludingThis(aMallocSizeOf); |
145 | 0 | return amount; |
146 | 0 | } |
147 | | |
148 | | size_t |
149 | | MediaStreamAudioDestinationNode::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
150 | 0 | { |
151 | 0 | return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); |
152 | 0 | } |
153 | | |
154 | | void |
155 | | MediaStreamAudioDestinationNode::DestroyMediaStream() |
156 | 0 | { |
157 | 0 | AudioNode::DestroyMediaStream(); |
158 | 0 | if (mPort) { |
159 | 0 | mPort->Destroy(); |
160 | 0 | mPort = nullptr; |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | | JSObject* |
165 | | MediaStreamAudioDestinationNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) |
166 | 0 | { |
167 | 0 | return MediaStreamAudioDestinationNode_Binding::Wrap(aCx, this, aGivenProto); |
168 | 0 | } |
169 | | |
170 | | } // namespace dom |
171 | | } // namespace mozilla |