// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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/macros.h"
#include "base/timer/timer.h"
#include "media/audio/audio_io.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:
  // |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() 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;

  // 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<AudioOutputStream*> 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*, AudioOutputStream*> 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_;
  DISALLOW_COPY_AND_ASSIGN(AudioOutputDispatcherImpl);
};

}  // namespace media

#endif  // MEDIA_AUDIO_AUDIO_OUTPUT_DISPATCHER_IMPL_H_
