// Copyright 2013 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.

#ifndef MEDIA_BASE_AUDIO_BUFFER_H_
#define MEDIA_BASE_AUDIO_BUFFER_H_

#include <stddef.h>
#include <stdint.h>

#include <list>
#include <memory>
#include <utility>
#include <vector>

#include "base/macros.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "media/base/channel_layout.h"
#include "media/base/media_export.h"
#include "media/base/sample_format.h"

namespace mojo {
template <typename T, typename U>
struct TypeConverter;
template <typename T>
class StructPtr;
}  // namespace mojo

namespace media {
class AudioBus;
class AudioBufferMemoryPool;

namespace mojom {
class AudioBuffer;
}

// An audio buffer that takes a copy of the data passed to it, holds it, and
// copies it into an AudioBus when needed. Also supports an end of stream
// marker.
class MEDIA_EXPORT AudioBuffer
    : public base::RefCountedThreadSafe<AudioBuffer> {
 public:
  // Alignment of each channel's data; this must match what ffmpeg expects
  // (which may be 0, 16, or 32, depending on the processor). Selecting 32 in
  // order to work on all processors.
  enum { kChannelAlignment = 32 };

  // Create an AudioBuffer whose channel data is copied from |data|. For
  // interleaved data, only the first buffer is used. For planar data, the
  // number of buffers must be equal to |channel_count|. |frame_count| is the
  // number of frames in each buffer. |data| must not be null and |frame_count|
  // must be >= 0. For optimal efficiency when many buffers are being created, a
  // AudioBufferMemoryPool can be provided to avoid thrashing memory.
  static scoped_refptr<AudioBuffer> CopyFrom(
      SampleFormat sample_format,
      ChannelLayout channel_layout,
      int channel_count,
      int sample_rate,
      int frame_count,
      const uint8_t* const* data,
      const base::TimeDelta timestamp,
      scoped_refptr<AudioBufferMemoryPool> pool = nullptr);

  // Create an AudioBuffer from a copy of the data in |audio_bus|.
  // For optimal efficiency when many buffers are being created, a
  // AudioBufferMemoryPool can be provided to avoid thrashing memory.
  static scoped_refptr<AudioBuffer> CopyFrom(
      int sample_rate,
      const base::TimeDelta timestamp,
      const AudioBus* audio_bus,
      scoped_refptr<AudioBufferMemoryPool> pool = nullptr);

  // Create an AudioBuffer for compressed bitstream. Its channel data is copied
  // from |data|, and the size is |data_size|. |data| must not be null and
  // |frame_count| must be >= 0.
  static scoped_refptr<AudioBuffer> CopyBitstreamFrom(
      SampleFormat sample_format,
      ChannelLayout channel_layout,
      int channel_count,
      int sample_rate,
      int frame_count,
      const uint8_t* const* data,
      const size_t data_size,
      const base::TimeDelta timestamp,
      scoped_refptr<AudioBufferMemoryPool> pool = nullptr);

  // Create an AudioBuffer with |frame_count| frames. Buffer is allocated, but
  // not initialized. Timestamp and duration are set to kNoTimestamp. For
  // optimal efficiency when many buffers are being created, a
  // AudioBufferMemoryPool can be provided to avoid thrashing memory.
  static scoped_refptr<AudioBuffer> CreateBuffer(
      SampleFormat sample_format,
      ChannelLayout channel_layout,
      int channel_count,
      int sample_rate,
      int frame_count,
      scoped_refptr<AudioBufferMemoryPool> pool = nullptr);

  // Create an AudioBuffer for compressed bitstream. Buffer is allocated, but
  // not initialized. Timestamp and duration are set to kNoTimestamp.
  static scoped_refptr<AudioBuffer> CreateBitstreamBuffer(
      SampleFormat sample_format,
      ChannelLayout channel_layout,
      int channel_count,
      int sample_rate,
      int frame_count,
      size_t data_size,
      scoped_refptr<AudioBufferMemoryPool> pool = nullptr);

  // Create an empty AudioBuffer with |frame_count| frames.
  static scoped_refptr<AudioBuffer> CreateEmptyBuffer(
      ChannelLayout channel_layout,
      int channel_count,
      int sample_rate,
      int frame_count,
      const base::TimeDelta timestamp);

  // Helper function that creates a new AudioBus which wraps |audio_buffer| and
  // takes a reference on it, if the memory layout (e.g. |sample_format_|) is
  // compatible with wrapping. Otherwise, this copies |audio_buffer| to a new
  // AudioBus, using ReadFrames().
  static std::unique_ptr<AudioBus> WrapOrCopyToAudioBus(
      scoped_refptr<AudioBuffer> audio_buffer);

  // Create a AudioBuffer indicating we've reached end of stream.
  // Calling any method other than end_of_stream() on the resulting buffer
  // is disallowed.
  static scoped_refptr<AudioBuffer> CreateEOSBuffer();

  // Update sample rate and computed duration.
  // TODO(chcunningham): Remove this upon patching FFmpeg's AAC decoder to
  // provide the correct sample rate at the boundary of an implicit config
  // change.
  void AdjustSampleRate(int sample_rate);

  // Copy frames into |dest|. |frames_to_copy| is the number of frames to copy.
  // |source_frame_offset| specifies how many frames in the buffer to skip
  // first. |dest_frame_offset| is the frame offset in |dest|. The frames are
  // converted and clipped from their source format into planar float32 data
  // (which is all that AudioBus handles).
  void ReadFrames(int frames_to_copy,
                  int source_frame_offset,
                  int dest_frame_offset,
                  AudioBus* dest) const;

  // Trim an AudioBuffer by removing |frames_to_trim| frames from the start.
  // Timestamp and duration are adjusted to reflect the fewer frames.
  // Note that repeated calls to TrimStart() may result in timestamp() and
  // duration() being off by a few microseconds due to rounding issues.
  void TrimStart(int frames_to_trim);

  // Trim an AudioBuffer by removing |frames_to_trim| frames from the end.
  // Duration is adjusted to reflect the fewer frames.
  void TrimEnd(int frames_to_trim);

  // Trim an AudioBuffer by removing |end - start| frames from [|start|, |end|).
  // Even if |start| is zero, timestamp() is not adjusted, only duration().
  void TrimRange(int start, int end);

  // Return true if the buffer contains compressed bitstream.
  bool IsBitstreamFormat() const;

  // Return the number of channels.
  int channel_count() const { return channel_count_; }

  // Return the number of frames held.
  int frame_count() const { return adjusted_frame_count_; }

  // Return the sample rate.
  int sample_rate() const { return sample_rate_; }

  // Return the sample format of the internal buffer, not that of what is
  // returned by ReadFrames().
  SampleFormat sample_format() const { return sample_format_; }

  // Return the channel layout.
  ChannelLayout channel_layout() const { return channel_layout_; }

  base::TimeDelta timestamp() const { return timestamp_; }
  base::TimeDelta duration() const { return duration_; }
  void set_timestamp(base::TimeDelta timestamp) { timestamp_ = timestamp; }

  // If there's no data in this buffer, it represents end of stream.
  bool end_of_stream() const { return end_of_stream_; }

  // Access to the raw buffer for ffmpeg and Android MediaCodec decoders to
  // write directly to. For planar formats the vector elements correspond to
  // the channels. For interleaved formats the resulting vector has exactly
  // one element which contains the buffer pointer.
  const std::vector<uint8_t*>& channel_data() const { return channel_data_; }

  // The size of allocated data memory block. For planar formats channels go
  // sequentially in this block.
  size_t data_size() const { return data_size_; }

 private:
  friend class base::RefCountedThreadSafe<AudioBuffer>;

  // mojo::TypeConverter added as a friend so that AudioBuffer can be
  // transferred across a mojo connection.
  friend struct mojo::TypeConverter<mojo::StructPtr<mojom::AudioBuffer>,
                                    AudioBuffer>;

  // Allocates aligned contiguous buffer to hold all channel data (1 block for
  // interleaved data, |channel_count| blocks for planar data), copies
  // [data,data+data_size) to the allocated buffer(s). If |data| is null, no
  // data is copied. If |create_buffer| is false, no data buffer is created (or
  // copied to).
  AudioBuffer(SampleFormat sample_format,
              ChannelLayout channel_layout,
              int channel_count,
              int sample_rate,
              int frame_count,
              bool create_buffer,
              const uint8_t* const* data,
              const size_t data_size,
              const base::TimeDelta timestamp,
              scoped_refptr<AudioBufferMemoryPool> pool);

  virtual ~AudioBuffer();

  const SampleFormat sample_format_;
  const ChannelLayout channel_layout_;
  const int channel_count_;
  int sample_rate_;
  int adjusted_frame_count_;
  const bool end_of_stream_;
  base::TimeDelta timestamp_;
  base::TimeDelta duration_;

  // Contiguous block of channel data.
  std::unique_ptr<uint8_t, base::AlignedFreeDeleter> data_;
  size_t data_size_;

  // For planar data, points to each channels data.
  std::vector<uint8_t*> channel_data_;

  // Allows recycling of memory data to avoid repeated allocations.
  scoped_refptr<AudioBufferMemoryPool> pool_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(AudioBuffer);
};

// Basic memory pool for reusing AudioBuffer internal memory to avoid thrashing.
//
// The pool is managed in a last-in-first-out manner, returned buffers are put
// at the back of the queue. When a new buffer is requested by AudioBuffer, we
// will scan from the front to find a matching buffer. All non-matching buffers
// are dropped. The assumption is that when we reach steady-state all buffers
// will have the same sized allocation. At most the pool will be equal in size
// to the maximum number of concurrent AudioBuffer instances.
//
// Each AudioBuffer instance created with an AudioBufferMemoryPool will take a
// ref on the pool instance so that it may return buffers in the future.
class MEDIA_EXPORT AudioBufferMemoryPool
    : public base::RefCountedThreadSafe<AudioBufferMemoryPool> {
 public:
  AudioBufferMemoryPool();

  size_t GetPoolSizeForTesting();

 private:
  friend class AudioBuffer;
  friend class base::RefCountedThreadSafe<AudioBufferMemoryPool>;

  ~AudioBufferMemoryPool();

  using AudioMemory = std::unique_ptr<uint8_t, base::AlignedFreeDeleter>;
  AudioMemory CreateBuffer(size_t size);
  void ReturnBuffer(AudioMemory memory, size_t size);

  base::Lock entry_lock_;
  using MemoryEntry = std::pair<AudioMemory, size_t>;
  std::list<MemoryEntry> entries_ GUARDED_BY(entry_lock_);

  DISALLOW_COPY_AND_ASSIGN(AudioBufferMemoryPool);
};

}  // namespace media

#endif  // MEDIA_BASE_AUDIO_BUFFER_H_
