tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AudioCaptureTrack.cpp (3260B)


      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 #include "AudioCaptureTrack.h"
      7 
      8 #include <algorithm>
      9 
     10 #include "AudioNodeEngine.h"
     11 #include "AudioNodeExternalInputTrack.h"
     12 #include "AudioNodeTrack.h"
     13 #include "AudioSegment.h"
     14 #include "DOMMediaStream.h"
     15 #include "ImageContainer.h"
     16 #include "MediaTrackGraph.h"
     17 #include "MediaTrackListener.h"
     18 #include "mozilla/Logging.h"
     19 #include "webaudio/MediaStreamAudioDestinationNode.h"
     20 
     21 using namespace mozilla::layers;
     22 using namespace mozilla::dom;
     23 using namespace mozilla::gfx;
     24 
     25 namespace mozilla {
     26 
     27 // We are mixing to mono until PeerConnection can accept stereo
     28 static const uint32_t MONO = 1;
     29 
     30 AudioCaptureTrack::AudioCaptureTrack(TrackRate aRate)
     31    : ProcessedMediaTrack(aRate, MediaSegment::AUDIO, new AudioSegment()),
     32      mStarted(false) {
     33  MOZ_ASSERT(NS_IsMainThread());
     34  MOZ_COUNT_CTOR(AudioCaptureTrack);
     35 }
     36 
     37 AudioCaptureTrack::~AudioCaptureTrack() { MOZ_COUNT_DTOR(AudioCaptureTrack); }
     38 
     39 void AudioCaptureTrack::Start() {
     40  QueueControlMessageWithNoShutdown(
     41      [self = RefPtr{this}, this] { mStarted = true; });
     42 }
     43 
     44 void AudioCaptureTrack::ProcessInput(GraphTime aFrom, GraphTime aTo,
     45                                     uint32_t aFlags) {
     46  if (!mStarted) {
     47    return;
     48  }
     49 
     50  uint32_t inputCount = mInputs.Length();
     51 
     52  if (mEnded) {
     53    return;
     54  }
     55 
     56  // If the captured track is connected back to a object on the page (be it an
     57  // HTMLMediaElement with a track as source, or an AudioContext), a cycle
     58  // situation occur. This can work if it's an AudioContext with at least one
     59  // DelayNode, but the MTG will mute the whole cycle otherwise.
     60  if (InMutedCycle() || inputCount == 0) {
     61    GetData<AudioSegment>()->AppendNullData(aTo - aFrom);
     62  } else {
     63    // We mix down all the tracks of all inputs, to a stereo track. Everything
     64    // is {up,down}-mixed to stereo.
     65    mMixer.StartMixing();
     66    AudioSegment output;
     67    for (uint32_t i = 0; i < inputCount; i++) {
     68      MediaTrack* s = mInputs[i]->GetSource();
     69      AudioSegment* inputSegment = s->GetData<AudioSegment>();
     70      TrackTime inputStart = s->GraphTimeToTrackTimeWithBlocking(aFrom);
     71      TrackTime inputEnd = s->GraphTimeToTrackTimeWithBlocking(aTo);
     72      AudioSegment toMix;
     73      if (s->Ended() && inputSegment->GetDuration() <= inputStart) {
     74        toMix.AppendNullData(aTo - aFrom);
     75      } else {
     76        toMix.AppendSlice(*inputSegment, inputStart, inputEnd);
     77        // Care for tracks blocked in the [aTo, aFrom] range.
     78        if (inputEnd - inputStart < aTo - aFrom) {
     79          toMix.AppendNullData((aTo - aFrom) - (inputEnd - inputStart));
     80        }
     81      }
     82      toMix.Mix(mMixer, MONO, Graph()->GraphRate());
     83    }
     84    AudioChunk* mixed = mMixer.MixedChunk();
     85    MOZ_ASSERT(mixed->ChannelCount() == MONO);
     86    // Now we have mixed data, simply append it.
     87    GetData<AudioSegment>()->AppendAndConsumeChunk(std::move(*mixed));
     88  }
     89 }
     90 
     91 uint32_t AudioCaptureTrack::NumberOfChannels() const {
     92  return GetData<AudioSegment>()->MaxChannelCount();
     93 }
     94 
     95 }  // namespace mozilla