1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109

media / audio / audio_output_dispatcher_impl.h [blame]

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// AudioOutputDispatcherImpl is an implementation of AudioOutputDispatcher.
//
// To avoid opening and closing audio devices more frequently than necessary,
// each dispatcher has a pool of inactive physical streams. A stream is closed
// only if it hasn't been used for a certain period of time (specified via the
// constructor).
//

#ifndef MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_
#define MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_

#include <stddef.h>

#include <memory>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/timer/timer.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/audio/audio_output_dispatcher.h"
#include "media/base/audio_parameters.h"

namespace media {
class AudioLog;

class MEDIA_EXPORT AudioOutputDispatcherImpl
    : public AudioOutputDispatcher,
      public AudioManager::AudioDeviceListener {
 public:
  // |close_delay| specifies delay after the stream is idle until the audio
  // device is closed.
  AudioOutputDispatcherImpl(AudioManager* audio_manager,
                            const AudioParameters& params,
                            const std::string& output_device_id,
                            base::TimeDelta close_delay);

  AudioOutputDispatcherImpl(const AudioOutputDispatcherImpl&) = delete;
  AudioOutputDispatcherImpl& operator=(const AudioOutputDispatcherImpl&) =
      delete;

  ~AudioOutputDispatcherImpl() override;

  // AudioOutputDispatcher implementation.
  AudioOutputProxy* CreateStreamProxy() override;
  bool OpenStream() override;
  bool StartStream(AudioOutputStream::AudioSourceCallback* callback,
                   AudioOutputProxy* stream_proxy) override;
  void StopStream(AudioOutputProxy* stream_proxy) override;
  void StreamVolumeSet(AudioOutputProxy* stream_proxy, double volume) override;
  void CloseStream(AudioOutputProxy* stream_proxy) override;
  void FlushStream(AudioOutputProxy* stream_proxy) override;

  // AudioDeviceListener implementation.
  void OnDeviceChange() override;

  // Returns true if there are any open AudioOutputProxy objects.
  bool HasOutputProxies() const;

  // Closes all |idle_streams_|.
  void CloseAllIdleStreams();

 private:
  // Creates a new physical output stream, opens it and pushes to
  // |idle_streams_|.  Returns false if the stream couldn't be created or
  // opened.
  bool CreateAndOpenStream();

  // Similar to CloseAllIdleStreams(), but keeps |keep_alive| streams alive.
  void CloseIdleStreams(size_t keep_alive);

  void StopPhysicalStream(AudioOutputStream* stream);

  // Output parameters.
  const AudioParameters params_;

  // Output device id.
  const std::string device_id_;

  size_t idle_proxies_;
  std::vector<raw_ptr<AudioOutputStream, VectorExperimental>> idle_streams_;

  // When streams are stopped they're added to |idle_streams_|, if no stream is
  // reused before |close_delay_| elapses |close_timer_| will run
  // CloseIdleStreams().
  base::DelayTimer close_timer_;

  typedef base::flat_map<AudioOutputProxy*,
                         raw_ptr<AudioOutputStream, CtnExperimental>>
      AudioStreamMap;
  AudioStreamMap proxy_to_physical_map_;

  using AudioLogMap =
      base::flat_map<AudioOutputStream*, std::unique_ptr<media::AudioLog>>;
  AudioLogMap audio_logs_;
  int audio_stream_id_;

  base::WeakPtrFactory<AudioOutputDispatcherImpl> weak_factory_{this};
};

}  // namespace media

#endif  // MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_