1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef MOZILLA_CROSS_GRAPH_TRACK_H_ 7 #define MOZILLA_CROSS_GRAPH_TRACK_H_ 8 9 #include "AudioDriftCorrection.h" 10 #include "AudioSegment.h" 11 #include "ForwardedInputTrack.h" 12 #include "mozilla/SPSCQueue.h" 13 #include "mozilla/UniquePtr.h" 14 15 namespace mozilla { 16 class CrossGraphReceiver; 17 } 18 19 namespace mozilla::dom { 20 class AudioStreamTrack; 21 } 22 23 namespace mozilla { 24 25 /** 26 * See MediaTrackGraph::CreateCrossGraphTransmitter() 27 */ 28 class CrossGraphTransmitter : public ProcessedMediaTrack { 29 public: 30 CrossGraphTransmitter(TrackRate aSampleRate, 31 RefPtr<CrossGraphReceiver> aReceiver); AsCrossGraphTransmitter()32 CrossGraphTransmitter* AsCrossGraphTransmitter() override { return this; } 33 NumberOfChannels()34 uint32_t NumberOfChannels() const override { 35 MOZ_CRASH("CrossGraphTransmitter has no segment. It cannot be played out."); 36 } 37 void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) override; 38 39 private: 40 const RefPtr<CrossGraphReceiver> mReceiver; 41 }; 42 43 /** 44 * See MediaTrackGraph::CreateCrossGraphReceiver() 45 */ 46 class CrossGraphReceiver : public ProcessedMediaTrack { 47 public: 48 CrossGraphReceiver(TrackRate aSampleRate, TrackRate aTransmitterRate); AsCrossGraphReceiver()49 CrossGraphReceiver* AsCrossGraphReceiver() override { return this; } 50 51 uint32_t NumberOfChannels() const override; 52 void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) override; 53 54 int EnqueueAudio(AudioChunk& aChunk); 55 56 private: 57 SPSCQueue<AudioChunk> mCrossThreadFIFO{30}; 58 // Indicates that tre CrossGraphTransmitter has started sending frames. It 59 // is false untill the point, transmitter has sent the first valid frame. 60 // Accessed in GraphThread only. 61 bool mTransmitterHasStarted = false; 62 // Correct the drift between transmitter and receiver. Reciever (this class) 63 // is considered as the master clock. 64 // Accessed in GraphThread only. 65 AudioDriftCorrection mDriftCorrection; 66 }; 67 68 class CrossGraphPort final { 69 public: 70 static UniquePtr<CrossGraphPort> Connect( 71 const RefPtr<dom::AudioStreamTrack>& aStreamTrack, 72 MediaTrackGraph* aPartnerGraph); 73 static UniquePtr<CrossGraphPort> Connect( 74 const RefPtr<dom::AudioStreamTrack>& aStreamTrack, AudioDeviceInfo* aSink, 75 nsPIDOMWindowInner* aWindow); 76 ~CrossGraphPort() = default; 77 78 void AddAudioOutput(void* aKey); 79 void RemoveAudioOutput(void* aKey); 80 void SetAudioOutputVolume(void* aKey, float aVolume); 81 void Destroy(); 82 83 RefPtr<GenericPromise> EnsureConnected(); 84 85 const RefPtr<CrossGraphTransmitter> mTransmitter; 86 const RefPtr<CrossGraphReceiver> mReceiver; 87 88 private: CrossGraphPort(RefPtr<MediaInputPort> aTransmitterPort,RefPtr<CrossGraphTransmitter> aTransmitter,RefPtr<CrossGraphReceiver> aReceiver)89 explicit CrossGraphPort(RefPtr<MediaInputPort> aTransmitterPort, 90 RefPtr<CrossGraphTransmitter> aTransmitter, 91 RefPtr<CrossGraphReceiver> aReceiver) 92 : mTransmitter(std::move(aTransmitter)), 93 mReceiver(std::move(aReceiver)), 94 mTransmitterPort(std::move(aTransmitterPort)) { 95 MOZ_ASSERT(mTransmitter); 96 MOZ_ASSERT(mReceiver); 97 MOZ_ASSERT(mTransmitterPort); 98 } 99 100 // The port that connects the input track to the transmitter. 101 const RefPtr<MediaInputPort> mTransmitterPort; 102 }; 103 104 } // namespace mozilla 105 106 #endif /* MOZILLA_CROSS_GRAPH_TRACK_H_ */ 107