Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
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 "TrackUnionStream.h"
15 namespace mozilla {
16 namespace dom {
18 NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaStreamAudioDestinationNode, AudioNode, mDOMStream)
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaStreamAudioDestinationNode)
21 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
23 NS_IMPL_ADDREF_INHERITED(MediaStreamAudioDestinationNode, AudioNode)
24 NS_IMPL_RELEASE_INHERITED(MediaStreamAudioDestinationNode, AudioNode)
26 static const int MEDIA_STREAM_DEST_TRACK_ID = 2;
27 static_assert(MEDIA_STREAM_DEST_TRACK_ID != AudioNodeStream::AUDIO_TRACK,
28 "MediaStreamAudioDestinationNode::MEDIA_STREAM_DEST_TRACK_ID must be a different value than AudioNodeStream::AUDIO_TRACK");
30 class MediaStreamDestinationEngine : public AudioNodeEngine {
31 public:
32 MediaStreamDestinationEngine(AudioNode* aNode, ProcessedMediaStream* aOutputStream)
33 : AudioNodeEngine(aNode)
34 , mOutputStream(aOutputStream)
35 {
36 MOZ_ASSERT(mOutputStream);
37 }
39 virtual void ProcessBlock(AudioNodeStream* aStream,
40 const AudioChunk& aInput,
41 AudioChunk* aOutput,
42 bool* aFinished) MOZ_OVERRIDE
43 {
44 *aOutput = aInput;
45 StreamBuffer::Track* track = mOutputStream->EnsureTrack(MEDIA_STREAM_DEST_TRACK_ID,
46 aStream->SampleRate());
47 AudioSegment* segment = track->Get<AudioSegment>();
48 segment->AppendAndConsumeChunk(aOutput);
49 }
51 virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
52 {
53 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
54 }
56 private:
57 ProcessedMediaStream* mOutputStream;
58 };
60 // This callback is used to ensure that only the audio data for this track is audible
61 static bool FilterAudioNodeStreamTrack(StreamBuffer::Track* aTrack)
62 {
63 return aTrack->GetID() == MEDIA_STREAM_DEST_TRACK_ID;
64 }
66 MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* aContext)
67 : AudioNode(aContext,
68 2,
69 ChannelCountMode::Explicit,
70 ChannelInterpretation::Speakers)
71 , mDOMStream(DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(),
72 MOZ_THIS_IN_INITIALIZER_LIST(),
73 DOMMediaStream::HINT_CONTENTS_AUDIO))
74 {
75 TrackUnionStream* tus = static_cast<TrackUnionStream*>(mDOMStream->GetStream());
76 MOZ_ASSERT(tus == mDOMStream->GetStream()->AsProcessedStream());
77 tus->SetTrackIDFilter(FilterAudioNodeStreamTrack);
79 MediaStreamDestinationEngine* engine = new MediaStreamDestinationEngine(this, tus);
80 mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
81 mPort = tus->AllocateInputPort(mStream, 0);
83 nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc();
84 if (doc) {
85 mDOMStream->CombineWithPrincipal(doc->NodePrincipal());
86 }
87 }
89 size_t
90 MediaStreamAudioDestinationNode::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
91 {
92 // Future:
93 // - mDOMStream
94 size_t amount = AudioNode::SizeOfExcludingThis(aMallocSizeOf);
95 amount += mPort->SizeOfIncludingThis(aMallocSizeOf);
96 return amount;
97 }
99 size_t
100 MediaStreamAudioDestinationNode::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
101 {
102 return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
103 }
105 void
106 MediaStreamAudioDestinationNode::DestroyMediaStream()
107 {
108 AudioNode::DestroyMediaStream();
109 if (mPort) {
110 mPort->Destroy();
111 mPort = nullptr;
112 }
113 }
115 JSObject*
116 MediaStreamAudioDestinationNode::WrapObject(JSContext* aCx)
117 {
118 return MediaStreamAudioDestinationNodeBinding::Wrap(aCx, this);
119 }
121 }
122 }