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

#include "media/base/audio_buffer.h"

#include <cmath>

#include "base/logging.h"
#include "base/notreached.h"
#include "media/base/audio_bus.h"
#include "media/base/limits.h"
#include "media/base/timestamp_constants.h"

namespace media {

namespace {

// TODO(https://crbug.com/619628): Use vector instructions to speed this up.
template <class SourceSampleTypeTraits>
void CopyConvertFromInterleaved(
    const typename SourceSampleTypeTraits::ValueType* source_buffer,
    int num_frames_to_write,
    const std::vector<float*> dest) {
  const int channels = dest.size();
  for (int ch = 0; ch < channels; ++ch) {
    float* dest_data = dest[ch];
    for (int target_frame_index = 0, read_pos_in_source = ch;
         target_frame_index < num_frames_to_write;
         ++target_frame_index, read_pos_in_source += channels) {
      auto source_value = source_buffer[read_pos_in_source];
      dest_data[target_frame_index] =
          SourceSampleTypeTraits::ToFloat(source_value);
    }
  }
}

}  // namespace

static base::TimeDelta CalculateDuration(int frames, double sample_rate) {
  DCHECK_GT(sample_rate, 0);
  return base::Microseconds(frames * base::Time::kMicrosecondsPerSecond /
                            sample_rate);
}

AudioBufferMemoryPool::AudioBufferMemoryPool() = default;
AudioBufferMemoryPool::~AudioBufferMemoryPool() = default;

size_t AudioBufferMemoryPool::GetPoolSizeForTesting() {
  base::AutoLock al(entry_lock_);
  return entries_.size();
}

AudioBufferMemoryPool::AudioMemory AudioBufferMemoryPool::CreateBuffer(
    size_t size) {
  base::AutoLock al(entry_lock_);
  while (!entries_.empty()) {
    MemoryEntry& front = entries_.front();
    MemoryEntry entry(std::move(front.first), front.second);
    entries_.pop_front();
    if (entry.second == size)
      return std::move(entry.first);
  }

  // FFmpeg may not always initialize the entire output memory, so just like
  // for VideoFrames we need to zero out the memory. https://crbug.com/1144070.
  auto memory = AudioMemory(static_cast<uint8_t*>(
      base::AlignedAlloc(size, AudioBuffer::kChannelAlignment)));
  memset(memory.get(), 0, size);
  return memory;
}

void AudioBufferMemoryPool::ReturnBuffer(AudioMemory memory, size_t size) {
  base::AutoLock al(entry_lock_);
  entries_.emplace_back(std::move(memory), size);
}

AudioBuffer::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)
    : sample_format_(sample_format),
      channel_layout_(channel_layout),
      channel_count_(channel_count),
      sample_rate_(sample_rate),
      adjusted_frame_count_(frame_count),
      end_of_stream_(!create_buffer && !data && !frame_count),
      timestamp_(timestamp),
      duration_(end_of_stream_
                    ? base::TimeDelta()
                    : CalculateDuration(adjusted_frame_count_, sample_rate_)),
      data_size_(data_size),
      pool_(std::move(pool)) {
  CHECK_GE(channel_count_, 0);
  CHECK_LE(channel_count_, limits::kMaxChannels);
  CHECK_GE(frame_count, 0);
  DCHECK(channel_layout == CHANNEL_LAYOUT_DISCRETE ||
         ChannelLayoutToChannelCount(channel_layout) == channel_count);

  int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
  DCHECK_LE(bytes_per_channel, kChannelAlignment);

  // Empty buffer?
  if (!create_buffer)
    return;

  CHECK_NE(sample_format, kUnknownSampleFormat);

  int data_size_per_channel = frame_count * bytes_per_channel;
  if (IsPlanar(sample_format)) {
    DCHECK(!IsBitstreamFormat()) << sample_format_;
    // Planar data, so need to allocate buffer for each channel.
    // Determine per channel data size, taking into account alignment.
    int block_size_per_channel =
        (data_size_per_channel + kChannelAlignment - 1) &
        ~(kChannelAlignment - 1);
    DCHECK_GE(block_size_per_channel, data_size_per_channel);

    // Allocate a contiguous buffer for all the channel data.
    data_size_ = channel_count_ * block_size_per_channel;
    if (pool_) {
      data_ = pool_->CreateBuffer(data_size_);
    } else {
      data_.reset(static_cast<uint8_t*>(
          base::AlignedAlloc(data_size_, kChannelAlignment)));
    }
    channel_data_.reserve(channel_count_);

    // Copy each channel's data into the appropriate spot.
    for (int i = 0; i < channel_count_; ++i) {
      channel_data_.push_back(data_.get() + i * block_size_per_channel);
      if (data)
        memcpy(channel_data_[i], data[i], data_size_per_channel);
    }
    return;
  }

  // Remaining formats are interleaved data.
  DCHECK(IsInterleaved(sample_format)) << sample_format_;
  // Allocate our own buffer and copy the supplied data into it. Buffer must
  // contain the data for all channels.
  if (!IsBitstreamFormat())
    data_size_ = data_size_per_channel * channel_count_;
  else
    DCHECK(data_size_ > 0);

  if (pool_) {
    data_ = pool_->CreateBuffer(data_size_);
  } else {
    data_.reset(static_cast<uint8_t*>(
        base::AlignedAlloc(data_size_, kChannelAlignment)));
  }

  channel_data_.reserve(1);
  channel_data_.push_back(data_.get());
  if (data)
    memcpy(data_.get(), data[0], data_size_);
}

AudioBuffer::~AudioBuffer() {
  if (pool_)
    pool_->ReturnBuffer(std::move(data_), data_size_);
}

// static
scoped_refptr<AudioBuffer> 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) {
  // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
  CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
  CHECK(data[0]);
  return base::WrapRefCounted(
      new AudioBuffer(sample_format, channel_layout, channel_count, sample_rate,
                      frame_count, true, data, 0, timestamp, std::move(pool)));
}

// static
scoped_refptr<AudioBuffer> AudioBuffer::CopyFrom(
    int sample_rate,
    const base::TimeDelta timestamp,
    const AudioBus* audio_bus,
    scoped_refptr<AudioBufferMemoryPool> pool) {
  DCHECK(audio_bus->frames());

  const int channel_count = audio_bus->channels();
  DCHECK(channel_count);

  std::vector<const uint8_t*> data(channel_count);
  for (int ch = 0; ch < channel_count; ch++)
    data[ch] = reinterpret_cast<const uint8_t*>(audio_bus->channel(ch));

  return CopyFrom(kSampleFormatPlanarF32, GuessChannelLayout(channel_count),
                  channel_count, sample_rate, audio_bus->frames(), data.data(),
                  timestamp, std::move(pool));
}

// static
scoped_refptr<AudioBuffer> 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) {
  // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
  CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
  CHECK(data[0]);
  return base::WrapRefCounted(new AudioBuffer(
      sample_format, channel_layout, channel_count, sample_rate, frame_count,
      true, data, data_size, timestamp, std::move(pool)));
}

// static
scoped_refptr<AudioBuffer> AudioBuffer::CreateBuffer(
    SampleFormat sample_format,
    ChannelLayout channel_layout,
    int channel_count,
    int sample_rate,
    int frame_count,
    scoped_refptr<AudioBufferMemoryPool> pool) {
  CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
  return base::WrapRefCounted(new AudioBuffer(
      sample_format, channel_layout, channel_count, sample_rate, frame_count,
      true, nullptr, 0, kNoTimestamp, std::move(pool)));
}

// static
scoped_refptr<AudioBuffer> 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) {
  CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
  return base::WrapRefCounted(new AudioBuffer(
      sample_format, channel_layout, channel_count, sample_rate, frame_count,
      true, nullptr, data_size, kNoTimestamp, std::move(pool)));
}

// static
scoped_refptr<AudioBuffer> AudioBuffer::CreateEmptyBuffer(
    ChannelLayout channel_layout,
    int channel_count,
    int sample_rate,
    int frame_count,
    const base::TimeDelta timestamp) {
  CHECK_GT(frame_count, 0);  // Otherwise looks like an EOF buffer.
  // Since data == nullptr, format doesn't matter.
  return base::WrapRefCounted(new AudioBuffer(
      kSampleFormatF32, channel_layout, channel_count, sample_rate, frame_count,
      false, nullptr, 0, timestamp, nullptr));
}

// static
scoped_refptr<AudioBuffer> AudioBuffer::CreateEOSBuffer() {
  return base::WrapRefCounted(
      new AudioBuffer(kUnknownSampleFormat, CHANNEL_LAYOUT_NONE, 0, 0, 0, false,
                      nullptr, 0, kNoTimestamp, nullptr));
}

// static
std::unique_ptr<AudioBus> AudioBuffer::WrapOrCopyToAudioBus(
    scoped_refptr<AudioBuffer> buffer) {
  DCHECK(buffer);

  const int channels = buffer->channel_count();
  const int frames = buffer->frame_count();

  DCHECK(channels);
  DCHECK(frames);

  // |buffer| might already have the right memory layout. Prevent a data copy
  // by wrapping it instead.
  if (buffer->sample_format() == SampleFormat::kSampleFormatPlanarF32) {
    auto audio_bus = AudioBus::CreateWrapper(channels);

    for (int ch = 0; ch < channels; ++ch) {
      audio_bus->SetChannelData(
          ch, reinterpret_cast<float*>(buffer->channel_data()[ch]));
    }

    audio_bus->set_frames(frames);

    // Keep |buffer| alive as long as |audio_bus|.
    audio_bus->SetWrappedDataDeleter(
        base::BindOnce([](scoped_refptr<AudioBuffer>) {}, std::move(buffer)));

    return audio_bus;
  }

  // |buffer|'s memory can't be wrapped directly. Convert and copy it instead.
  auto audio_bus = AudioBus::Create(channels, frames);
  buffer->ReadFrames(frames, 0, 0, audio_bus.get());

  return audio_bus;
}

void AudioBuffer::AdjustSampleRate(int sample_rate) {
  DCHECK(!end_of_stream_);
  sample_rate_ = sample_rate;
  duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
}

void AudioBuffer::ReadFrames(int frames_to_copy,
                             int source_frame_offset,
                             int dest_frame_offset,
                             AudioBus* dest) const {
  // Deinterleave each channel (if necessary) and convert to 32bit
  // floating-point with nominal range -1.0 -> +1.0 (if necessary).

  // |dest| must have the same number of channels, and the number of frames
  // specified must be in range.
  DCHECK(!end_of_stream());
  CHECK_EQ(dest->channels(), channel_count_);
  CHECK_LE(source_frame_offset + frames_to_copy, adjusted_frame_count_);
  CHECK_LE(dest_frame_offset + frames_to_copy, dest->frames());

  dest->set_is_bitstream_format(IsBitstreamFormat());

  if (IsBitstreamFormat()) {
    // For bitstream formats, we only support 2 modes: 1) Overwrite the data to
    // the beginning of the destination buffer. 2) Append new data to the end of
    // the existing data.
    DCHECK(!source_frame_offset);
    DCHECK(!dest_frame_offset ||
           dest_frame_offset == dest->GetBitstreamFrames());

    size_t bitstream_size =
        dest_frame_offset ? dest->GetBitstreamDataSize() : 0;
    uint8_t* dest_data =
        reinterpret_cast<uint8_t*>(dest->channel(0)) + bitstream_size;

    memcpy(dest_data, channel_data_[0], data_size());
    dest->SetBitstreamDataSize(bitstream_size + data_size());
    dest->SetBitstreamFrames(dest_frame_offset + frame_count());
    return;
  }

  if (!data_) {
    // Special case for an empty buffer.
    dest->ZeroFramesPartial(dest_frame_offset, frames_to_copy);
    return;
  }

  // Note: The conversion steps below will clip values to [1.0, -1.0f].

  if (sample_format_ == kSampleFormatPlanarF32) {
    for (int ch = 0; ch < channel_count_; ++ch) {
      float* dest_data = dest->channel(ch) + dest_frame_offset;
      const float* source_data =
          reinterpret_cast<const float*>(channel_data_[ch]) +
          source_frame_offset;
      for (int i = 0; i < frames_to_copy; ++i)
        dest_data[i] = Float32SampleTypeTraits::FromFloat(source_data[i]);
    }
    return;
  }
  if (sample_format_ == kSampleFormatPlanarU8) {
    // Format is planar unsigned 8. Convert each value into float and insert
    // into output channel data.
    for (int ch = 0; ch < channel_count_; ++ch) {
      const uint8_t* source_data = channel_data_[ch] + source_frame_offset;
      float* dest_data = dest->channel(ch) + dest_frame_offset;
      for (int i = 0; i < frames_to_copy; ++i)
        dest_data[i] = UnsignedInt8SampleTypeTraits::ToFloat(source_data[i]);
    }
    return;
  }

  if (sample_format_ == kSampleFormatPlanarS16) {
    // Format is planar signed16. Convert each value into float and insert into
    // output channel data.
    for (int ch = 0; ch < channel_count_; ++ch) {
      const int16_t* source_data =
          reinterpret_cast<const int16_t*>(channel_data_[ch]) +
          source_frame_offset;
      float* dest_data = dest->channel(ch) + dest_frame_offset;
      for (int i = 0; i < frames_to_copy; ++i)
        dest_data[i] = SignedInt16SampleTypeTraits::ToFloat(source_data[i]);
    }
    return;
  }

  if (sample_format_ == kSampleFormatPlanarS32) {
    // Format is planar signed32. Convert each value into float and insert into
    // output channel data.
    for (int ch = 0; ch < channel_count_; ++ch) {
      const int32_t* source_data =
          reinterpret_cast<const int32_t*>(channel_data_[ch]) +
          source_frame_offset;
      float* dest_data = dest->channel(ch) + dest_frame_offset;
      for (int i = 0; i < frames_to_copy; ++i)
        dest_data[i] = SignedInt32SampleTypeTraits::ToFloat(source_data[i]);
    }
    return;
  }

  const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
  const int frame_size = channel_count_ * bytes_per_channel;
  const uint8_t* source_data = data_.get() + source_frame_offset * frame_size;

  if (sample_format_ == kSampleFormatF32) {
    dest->FromInterleavedPartial<Float32SampleTypeTraits>(
        reinterpret_cast<const float*>(source_data), dest_frame_offset,
        frames_to_copy);
  } else if (sample_format_ == kSampleFormatU8) {
    dest->FromInterleavedPartial<UnsignedInt8SampleTypeTraits>(
        source_data, dest_frame_offset, frames_to_copy);
  } else if (sample_format_ == kSampleFormatS16) {
    dest->FromInterleavedPartial<SignedInt16SampleTypeTraits>(
        reinterpret_cast<const int16_t*>(source_data), dest_frame_offset,
        frames_to_copy);
  } else if (sample_format_ == kSampleFormatS24 ||
             sample_format_ == kSampleFormatS32) {
    dest->FromInterleavedPartial<SignedInt32SampleTypeTraits>(
        reinterpret_cast<const int32_t*>(source_data), dest_frame_offset,
        frames_to_copy);
  } else {
    NOTREACHED() << "Unsupported audio sample type: " << sample_format_;
  }
}

void AudioBuffer::TrimStart(int frames_to_trim) {
  CHECK_GE(frames_to_trim, 0);
  CHECK_LE(frames_to_trim, adjusted_frame_count_);

  if (IsBitstreamFormat()) {
    LOG(ERROR) << "Not allowed to trim an audio bitstream buffer.";
    return;
  }

  TrimRange(0, frames_to_trim);
}

void AudioBuffer::TrimEnd(int frames_to_trim) {
  CHECK_GE(frames_to_trim, 0);
  CHECK_LE(frames_to_trim, adjusted_frame_count_);

  if (IsBitstreamFormat()) {
    LOG(ERROR) << "Not allowed to trim an audio bitstream buffer.";
    return;
  }

  // Adjust the number of frames and duration for this buffer.
  adjusted_frame_count_ -= frames_to_trim;
  duration_ = CalculateDuration(adjusted_frame_count_, sample_rate_);
}

void AudioBuffer::TrimRange(int start, int end) {
  CHECK_GE(start, 0);
  CHECK_LE(end, adjusted_frame_count_);

  if (IsBitstreamFormat()) {
    LOG(ERROR) << "Not allowed to trim an audio bitstream buffer.";
    return;
  }

  const int frames_to_trim = end - start;
  CHECK_GE(frames_to_trim, 0);
  CHECK_LE(frames_to_trim, adjusted_frame_count_);

  const int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format_);
  // Empty buffers do not have frames to copy backed by data_.
  const int frames_to_copy = data_ ? adjusted_frame_count_ - end : 0;
  if (frames_to_copy > 0) {
    switch (sample_format_) {
      case kSampleFormatPlanarU8:
      case kSampleFormatPlanarS16:
      case kSampleFormatPlanarF32:
      case kSampleFormatPlanarS32:
        // Planar data must be shifted per channel.
        for (int ch = 0; ch < channel_count_; ++ch) {
          memmove(channel_data_[ch] + start * bytes_per_channel,
                  channel_data_[ch] + end * bytes_per_channel,
                  bytes_per_channel * frames_to_copy);
        }
        break;
      case kSampleFormatU8:
      case kSampleFormatS16:
      case kSampleFormatS24:
      case kSampleFormatS32:
      case kSampleFormatF32: {
        // Interleaved data can be shifted all at once.
        const int frame_size = channel_count_ * bytes_per_channel;
        memmove(channel_data_[0] + start * frame_size,
                channel_data_[0] + end * frame_size,
                frame_size * frames_to_copy);
        break;
      }
      case kUnknownSampleFormat:
      case kSampleFormatAc3:
      case kSampleFormatEac3:
      case kSampleFormatMpegHAudio:
        NOTREACHED() << "Invalid sample format!";
    }
  } else {
    CHECK_EQ(frames_to_copy, 0);
  }

  // Trim the leftover data off the end of the buffer and update duration.
  TrimEnd(frames_to_trim);
}

bool AudioBuffer::IsBitstreamFormat() const {
  return IsBitstream(sample_format_);
}

}  // namespace media
