// Copyright 2016 The Fuchsia 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 "src/media/playback/mediaplayer/ffmpeg/ffmpeg_decoder_base.h"

#include <lib/async/cpp/task.h>
#include <trace/event.h>

#include "src/lib/fxl/logging.h"
#include "src/media/playback/mediaplayer/ffmpeg/av_codec_context.h"
#include "src/media/playback/mediaplayer/graph/formatting.h"
extern "C" {
#include "libavutil/buffer_internal.h"
}

namespace media_player {
namespace {

// Creates an opaque reference to an object from an |fbl::RefPtr|. The original
// pointer is 'copied' in the sense that a refcount is added for the new opaque
// reference.
template <typename T>
void* CopyRefPtrToOpaque(fbl::RefPtr<T> t) {
  FXL_DCHECK(t);

  // Increment the refcount to account for the opaque reference we're returning.
  t->AddRef();
  return t.get();
}

// Copies an opaque reference created with |CopyRefPtrToOpaque| to create a
// new |fbl::RefPtr|. The opaque reference is 'copied' in the sense that a
// refcount is added for the new |fbl::RefPtr|.
template <typename T>
fbl::RefPtr<T> CopyOpaqueRefPtr(void* opaque) {
  T* t_raw_ptr = reinterpret_cast<T*>(opaque);

  // Increment the refcount to account for the |fbl::RefPtr| we're about to
  // create. |MakeRefPtrNoAdopt| doesn't increment the refcount.
  t_raw_ptr->AddRef();
  return fbl::internal::MakeRefPtrNoAdopt(t_raw_ptr);
}

// Releases an opaque reference created with |CopyRefPtrToOpaque|. |opaque| is
// passed by value, so the caller must be careful not to use |opaque| as an
// opaque RefPtr after calling this function.
template <typename T>
void ReleaseOpaqueRefPtr(void* opaque) {
  // |MakeRefPtrNoAdopt| doesn't increment the refcount. When the |fbl::RefPtr|
  // we've created here is dropped, the refcount in decremented, and the |T|
  // may be deleted/recycled.
  fbl::internal::MakeRefPtrNoAdopt(reinterpret_cast<T*>(opaque));
}

}  // namespace

FfmpegDecoderBase::FfmpegDecoderBase(AvCodecContextPtr av_codec_context)
    : av_codec_context_(std::move(av_codec_context)),
      av_frame_ptr_(ffmpeg::AvFrame::Create()) {
  FXL_DCHECK(av_codec_context_);

  av_codec_context_->opaque = this;
  av_codec_context_->get_buffer2 = AllocateBufferForAvFrame;
  av_codec_context_->refcounted_frames = 1;
}

FfmpegDecoderBase::~FfmpegDecoderBase() {}

std::unique_ptr<StreamType> FfmpegDecoderBase::output_stream_type() const {
  return AvCodecContext::GetStreamType(*av_codec_context_);
}

void FfmpegDecoderBase::Flush() {
  FXL_DCHECK(is_worker_thread());
  avcodec_flush_buffers(av_codec_context_.get());
  next_pts_ = Packet::kNoPts;
}

bool FfmpegDecoderBase::TransformPacket(const PacketPtr& input, bool new_input,
                                        PacketPtr* output) {
  FXL_DCHECK(is_worker_thread());
  FXL_DCHECK(input);
  FXL_DCHECK(output);

  TRACE_DURATION(
      "motown", "DecodePacket", "type",
      (av_codec_context_->codec_type == AVMEDIA_TYPE_VIDEO ? "video"
                                                           : "audio"));

  *output = nullptr;

  if (new_input) {
    if (input->size() == 0 && !input->end_of_stream()) {
      // This packet isn't end-of-stream, but it has size zero. The underlying
      // decoder interprets an empty input packet as end-of-stream, so we
      // we refrain from decoding this packet and return true to indicate we're
      // done with it.
      //
      // The underlying decoder gets its end-of-stream indication in one of
      // two ways:
      // 1) If the end-of-stream packet is empty, it will get past this check
      //    and be submitted to the decoder, indicating end-of-stream.
      // 2) If the end-of-stream packet is not empty, we let it through and
      //    follow it with an empty end-of-stream packet that we create for
      //    that purpose.
      return true;
    }

    OnNewInputPacket(input);

    // Send the packet to the ffmpeg decoder. If it fails, return true to
    // indicate we're done with the packet.
    if (SendPacket(input) != 0) {
      if (input->end_of_stream()) {
        // The input packet was end-of-stream. We won't get called again before
        // a flush, so make sure the output gets an end-of-stream packet.
        *output = CreateEndOfStreamPacket();
      }

      return true;
    }
  }

  int result =
      avcodec_receive_frame(av_codec_context_.get(), av_frame_ptr_.get());

  switch (result) {
    case 0:
      // Succeeded, frame produced. We're not done with the input packet.
      //
      // We use |CopyOpaqueRefPtr| here to create a real |fbl:RefPtr| to the
      // |PayloadBuffer| attached to the frame's |AVBuffer| in |CreateAVBuffer|.
      *output = CreateOutputPacket(*av_frame_ptr_,
                                   CopyOpaqueRefPtr<PayloadBuffer>(
                                       av_frame_ptr_->buf[0]->buffer->opaque));

      // Release the frame returned by |avcodec_receive_frame|.
      av_frame_unref(av_frame_ptr_.get());
      return false;

    case AVERROR(EAGAIN):
      // Succeeded, no frame produced.
      if (input->end_of_stream() && input->size() != 0) {
        // The input packet is an end-of-stream packet, and it has payload. The
        // underlying decoder interprets an empty packet as end-of-stream, so
        // we need to send it an empty packet.
        if (SendPacket(CreateEndOfStreamPacket()) == 0) {
          // |SendPacket| succeeded. We return false to indicate we're not done
          // with the original end-of-stream packet. We'll get called again with
          // the same end-of-stream packet and |new_input| set to false. That
          // will continue until we've extracted all the output packets the
          // decoder has to give us. Note that we won't end up here again,
          // because |avcodec_receive_frame| will return either 0 or
          // |AVERROR_EOF|, not |AVERROR(EAGAIN)|.
          return false;
        }

        // |SendPacket| failed. We return true to indicate we're done with the
        // input packet. We also output an end-of-stream packet to terminate
        // the output stream.
        *output = CreateEndOfStreamPacket();
      }

      // Indicate we're done with the input packet.
      return true;

    case AVERROR_EOF:
      // Succeeded, no frame produced, end-of-stream sequence complete.
      // Produce an end-of-stream packet.
      FXL_DCHECK(input->end_of_stream());
      *output = CreateEndOfStreamPacket();
      return true;

    default:
      FXL_DLOG(ERROR) << "avcodec_receive_frame failed " << result;
      if (input->end_of_stream()) {
        // The input packet was end-of-stream. We won't get called again before
        // a flush, so make sure the output gets an end-of-stream packet.
        *output = CreateEndOfStreamPacket();
      }

      return true;
  }
}

int FfmpegDecoderBase::SendPacket(const PacketPtr& input) {
  FXL_DCHECK(input);

  AVPacket av_packet;
  av_init_packet(&av_packet);
  av_packet.data = reinterpret_cast<uint8_t*>(input->payload());
  av_packet.size = input->size();
  av_packet.pts = input->pts();
  if (input->keyframe()) {
    av_packet.flags |= AV_PKT_FLAG_KEY;
  }

  int result = avcodec_send_packet(av_codec_context_.get(), &av_packet);

  if (result != 0) {
    FXL_DLOG(ERROR) << "avcodec_send_packet failed " << result;
  }

  return result;
}

void FfmpegDecoderBase::OnNewInputPacket(const PacketPtr& packet) {}

AVBufferRef* FfmpegDecoderBase::CreateAVBuffer(
    fbl::RefPtr<PayloadBuffer> payload_buffer) {
  FXL_DCHECK(payload_buffer);
  FXL_DCHECK(payload_buffer->size() <=
             static_cast<uint64_t>(std::numeric_limits<int>::max()));
  return av_buffer_create(reinterpret_cast<uint8_t*>(payload_buffer->data()),
                          static_cast<int>(payload_buffer->size()),
                          ReleaseBufferForAvFrame,
                          CopyRefPtrToOpaque(payload_buffer),
                          /* flags */ 0);
}

// static
int FfmpegDecoderBase::AllocateBufferForAvFrame(
    AVCodecContext* av_codec_context, AVFrame* av_frame, int flags) {
  // It's important to use av_codec_context here rather than context(),
  // because av_codec_context is different for different threads when we're
  // decoding on multiple threads. Be sure to avoid using self->context() or
  // self->av_codec_context_.

  // AV_CODEC_CAP_DR1 is required in order to do allocation this way.
  FXL_DCHECK(av_codec_context->codec->capabilities & AV_CODEC_CAP_DR1);

  FfmpegDecoderBase* self =
      reinterpret_cast<FfmpegDecoderBase*>(av_codec_context->opaque);
  FXL_DCHECK(self);

  return self->BuildAVFrame(*av_codec_context, av_frame);
}

// static
void FfmpegDecoderBase::ReleaseBufferForAvFrame(void* opaque, uint8_t* buffer) {
  FXL_DCHECK(opaque);
  FXL_DCHECK(buffer);
  FXL_DCHECK(buffer == CopyOpaqueRefPtr<PayloadBuffer>(opaque)->data());

  ReleaseOpaqueRefPtr<PayloadBuffer>(opaque);
}

PacketPtr FfmpegDecoderBase::CreateEndOfStreamPacket() {
  return Packet::CreateEndOfStream(next_pts_, pts_rate_);
}

void FfmpegDecoderBase::Dump(std::ostream& os) const {
  SoftwareDecoder::Dump(os);

  os << fostr::Indent;
  os << fostr::NewLine << "next pts:          " << AsNs(next_pts_) << "@"
     << pts_rate_;
  os << fostr::Outdent;
}

}  // namespace media_player
