// Copyright 2016 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 "base/logging.h"
#include "services/media/framework_ffmpeg/ffmpeg_audio_decoder.h"

namespace mojo {
namespace media {

FfmpegAudioDecoder::FfmpegAudioDecoder(AvCodecContextPtr av_codec_context)
    : FfmpegDecoderBase(std::move(av_codec_context)) {
  DCHECK(context());
  DCHECK(context()->channels > 0);

  context()->opaque = this;
  context()->get_buffer2 = AllocateBufferForAvFrame;
  context()->refcounted_frames = 1;

  if (av_sample_fmt_is_planar(context()->sample_fmt)) {
    // Prepare for interleaving.
    stream_type_ = output_stream_type();
    lpcm_util_ = LpcmUtil::Create(*stream_type_->lpcm());
  }
}

FfmpegAudioDecoder::~FfmpegAudioDecoder() {}

void FfmpegAudioDecoder::Flush() {
  FfmpegDecoderBase::Flush();
  next_pts_ = Packet::kUnknownPts;
}

int FfmpegAudioDecoder::Decode(const AVPacket& av_packet,
                               const ffmpeg::AvFramePtr& av_frame_ptr,
                               PayloadAllocator* allocator,
                               bool* frame_decoded_out) {
  DCHECK(allocator);
  DCHECK(frame_decoded_out);
  DCHECK(context());
  DCHECK(av_frame_ptr);

  if (next_pts_ == Packet::kUnknownPts) {
    if (av_packet.pts == AV_NOPTS_VALUE) {
      next_pts_ = 0;
    } else {
      next_pts_ = av_packet.pts;
    }
  }

  // Use the provided allocator (for allocations in AllocateBufferForAvFrame)
  // unless we intend to interleave later, in which case use the default
  // allocator. We'll interleave into a buffer from the provided allocator
  // in CreateOutputPacket.
  allocator_ = lpcm_util_ ? PayloadAllocator::GetDefault() : allocator;

  int frame_decoded = 0;
  int input_bytes_used = avcodec_decode_audio4(
      context().get(), av_frame_ptr.get(), &frame_decoded, &av_packet);
  *frame_decoded_out = frame_decoded != 0;

  // We're done with this allocator.
  allocator_ = nullptr;

  return input_bytes_used;
}

PacketPtr FfmpegAudioDecoder::CreateOutputPacket(const AVFrame& av_frame,
                                                 PayloadAllocator* allocator) {
  DCHECK(allocator);

  int64_t pts = av_frame.pts;
  if (pts == AV_NOPTS_VALUE) {
    pts = next_pts_;
    next_pts_ += av_frame.nb_samples;
  }

  uint64_t payload_size;
  void* payload_buffer;

  AvBufferContext* av_buffer_context =
      reinterpret_cast<AvBufferContext*>(av_buffer_get_opaque(av_frame.buf[0]));

  if (lpcm_util_) {
    // We need to interleave. The non-interleaved frames are in a buffer that
    // was allocated from the default allocator. That buffer will get released
    // later in ReleaseBufferForAvFrame. We need a new buffer for the
    // interleaved frames, which we get from the provided allocator.
    DCHECK(stream_type_);
    DCHECK(stream_type_->lpcm());
    payload_size = stream_type_->lpcm()->min_buffer_size(av_frame.nb_samples);
    payload_buffer = allocator->AllocatePayloadBuffer(payload_size);

    lpcm_util_->Interleave(av_buffer_context->buffer(),
                           av_buffer_context->size(), payload_buffer,
                           av_frame.nb_samples);
  } else {
    // We don't need to interleave. The interleaved frames are in a buffer that
    // was allocated from the correct allocator. We take ownership of the buffer
    // by calling Release here so that ReleaseBufferForAvFrame won't release it.
    payload_size = av_buffer_context->size();
    payload_buffer = av_buffer_context->Release();
  }

  return Packet::Create(
      pts,
      false,  // The base class is responsible for end-of-stream.
      payload_size, payload_buffer, allocator);
}

PacketPtr FfmpegAudioDecoder::CreateOutputEndOfStreamPacket() {
  return Packet::CreateEndOfStream(next_pts_);
}

int FfmpegAudioDecoder::AllocateBufferForAvFrame(
    AVCodecContext* av_codec_context,
    AVFrame* av_frame,
    int flags) {
  // CODEC_CAP_DR1 is required in order to do allocation this way.
  DCHECK(av_codec_context->codec->capabilities & CODEC_CAP_DR1);

  FfmpegAudioDecoder* self =
      reinterpret_cast<FfmpegAudioDecoder*>(av_codec_context->opaque);
  DCHECK(self);
  DCHECK(self->allocator_);

  AVSampleFormat av_sample_format =
      static_cast<AVSampleFormat>(av_frame->format);

  int buffer_size = av_samples_get_buffer_size(
      &av_frame->linesize[0], av_codec_context->channels, av_frame->nb_samples,
      av_sample_format, FfmpegAudioDecoder::kChannelAlign);
  if (buffer_size < 0) {
    LOG(WARNING) << "av_samples_get_buffer_size failed";
    return buffer_size;
  }

  AvBufferContext* av_buffer_context =
      new AvBufferContext(buffer_size, self->allocator_);
  uint8_t* buffer = av_buffer_context->buffer();

  if (!av_sample_fmt_is_planar(av_sample_format)) {
    // Samples are interleaved. There's just one buffer.
    av_frame->data[0] = buffer;
  } else {
    // Samples are not interleaved. There's one buffer per channel.
    int channels = av_codec_context->channels;
    int bytes_per_channel = buffer_size / channels;
    uint8_t* channel_buffer = buffer;

    DCHECK(buffer != nullptr || bytes_per_channel == 0);

    if (channels <= AV_NUM_DATA_POINTERS) {
      // The buffer pointers will fit in av_frame->data.
      DCHECK_EQ(av_frame->extended_data, av_frame->data);
      for (int channel = 0; channel < channels; ++channel) {
        av_frame->data[channel] = channel_buffer;
        channel_buffer += bytes_per_channel;
      }
    } else {
      // Too many channels for av_frame->data. We have to use
      // av_frame->extended_data
      av_frame->extended_data = static_cast<uint8_t**>(
          av_malloc(channels * sizeof(*av_frame->extended_data)));

      // The first AV_NUM_DATA_POINTERS go in both data and extended_data.
      int channel = 0;
      for (; channel < AV_NUM_DATA_POINTERS; ++channel) {
        av_frame->extended_data[channel] = av_frame->data[channel] =
            channel_buffer;
        channel_buffer += bytes_per_channel;
      }

      // The rest go only in extended_data.
      for (; channel < channels; ++channel) {
        av_frame->extended_data[channel] = channel_buffer;
        channel_buffer += bytes_per_channel;
      }
    }
  }

  av_frame->buf[0] = av_buffer_create(
      buffer, buffer_size, ReleaseBufferForAvFrame, av_buffer_context,
      0);  // flags

  return 0;
}

void FfmpegAudioDecoder::ReleaseBufferForAvFrame(void* opaque,
                                                 uint8_t* buffer) {
  AvBufferContext* av_buffer_context =
      reinterpret_cast<AvBufferContext*>(opaque);
  DCHECK(av_buffer_context);
  // Either this buffer has already been released to someone else's ownership,
  // or it's the same as the buffer parameter.
  DCHECK(av_buffer_context->buffer() == nullptr ||
         av_buffer_context->buffer() == buffer);
  delete av_buffer_context;
}

}  // namespace media
}  // namespace mojo
