// 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 "media/mojo/clients/mojo_video_decoder.h"

#include <atomic>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/decoder_buffer.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_switches.h"
#include "media/base/overlay_info.h"
#include "media/base/video_frame.h"
#include "media/media_buildflags.h"
#include "media/mojo/clients/mojo_media_log_service.h"
#include "media/mojo/common/media_type_converters.h"
#include "media/mojo/common/mojo_decoder_buffer_converter.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "media/video/video_decode_accelerator.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/bindings/shared_remote.h"

namespace media {

namespace {
// Number of functional instances of MojoVideoDecoder in the current process.
std::atomic<int>& get_mojo_instance_counter() {
  static std::atomic<int> instance_counter(0);
  return instance_counter;
}
}  // namespace

const char kMojoVideoDecoderInitialPlaybackSuccessCodecCounterUMA[] =
    "Media.MojoVideoDecoder.InitialPlaybackSuccessCodecCounter";

const char kMojoVideoDecoderInitialPlaybackErrorCodecCounterUMA[] =
    "Media.MojoVideoDecoder.InitialPlaybackErrorCodecCounter";

const int kMojoDecoderInitialPlaybackFrameCount = 150;

// Provides a thread-safe channel for VideoFrame destruction events.
class MojoVideoFrameHandleReleaser
    : public base::RefCountedThreadSafe<MojoVideoFrameHandleReleaser> {
 public:
  REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();

  MojoVideoFrameHandleReleaser(
      mojo::PendingRemote<mojom::VideoFrameHandleReleaser>
          video_frame_handle_releaser_remote,
      scoped_refptr<base::SequencedTaskRunner> task_runner) {
    // Connection errors are not handled because we wouldn't do anything
    // differently. ("If a tree falls in a forest...")
    video_frame_handle_releaser_ =
        mojo::SharedRemote<mojom::VideoFrameHandleReleaser>(
            std::move(video_frame_handle_releaser_remote),
            std::move(task_runner));
  }

  void ReleaseVideoFrame(const base::UnguessableToken& release_token,
                         const gpu::SyncToken& release_sync_token) {
    DVLOG(3) << __func__ << "(" << release_token << ")";
    video_frame_handle_releaser_->ReleaseVideoFrame(release_token,
                                                    release_sync_token);
  }

  // Create a ReleaseMailboxCB that calls Release(). Since the callback holds a
  // reference to |this|, |this| will remain alive as long as there are
  // outstanding VideoFrames.
  VideoFrame::ReleaseMailboxCB CreateReleaseMailboxCB(
      const base::UnguessableToken& release_token) {
    DVLOG(3) << __func__ << "(" << release_token.ToString() << ")";
    return base::BindOnce(&MojoVideoFrameHandleReleaser::ReleaseVideoFrame,
                          this, release_token);
  }

 private:
  friend class base::RefCountedThreadSafe<MojoVideoFrameHandleReleaser>;
  ~MojoVideoFrameHandleReleaser() {}

  mojo::SharedRemote<mojom::VideoFrameHandleReleaser>
      video_frame_handle_releaser_;

  DISALLOW_COPY_AND_ASSIGN(MojoVideoFrameHandleReleaser);
};

MojoVideoDecoder::MojoVideoDecoder(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    GpuVideoAcceleratorFactories* gpu_factories,
    MediaLog* media_log,
    mojo::PendingRemote<mojom::VideoDecoder> pending_remote_decoder,
    RequestOverlayInfoCB request_overlay_info_cb,
    const gfx::ColorSpace& target_color_space)
    : task_runner_(task_runner),
      pending_remote_decoder_(std::move(pending_remote_decoder)),
      gpu_factories_(gpu_factories),
      media_log_(media_log),
      timestamps_(128),
      writer_capacity_(
          GetDefaultDecoderBufferConverterCapacity(DemuxerStream::VIDEO)),
      request_overlay_info_cb_(std::move(request_overlay_info_cb)),
      target_color_space_(target_color_space) {
  DVLOG(1) << __func__;
  DETACH_FROM_SEQUENCE(sequence_checker_);
  weak_this_ = weak_factory_.GetWeakPtr();
}

MojoVideoDecoder::~MojoVideoDecoder() {
  DVLOG(1) << __func__;
  if (remote_decoder_bound_)
    get_mojo_instance_counter()--;
  if (request_overlay_info_cb_ && overlay_info_requested_)
    request_overlay_info_cb_.Run(false, base::NullCallback());
}

bool MojoVideoDecoder::IsPlatformDecoder() const {
  return true;
}

bool MojoVideoDecoder::SupportsDecryption() const {
  // Currently only the Android backends and specific ChromeOS configurations
  // support decryption.
#if defined(OS_ANDROID) || BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
#if BUILDFLAG(IS_CHROMEOS_LACROS)
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kLacrosUseChromeosProtectedMedia)) {
    return false;
  }
#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
  return true;
#else
  return false;
#endif
}

VideoDecoderType MojoVideoDecoder::GetDecoderType() const {
  return decoder_type_;
}

void MojoVideoDecoder::FailInit(InitCB init_cb, Status err) {
  task_runner_->PostTask(FROM_HERE,
                         base::BindOnce(std::move(init_cb), std::move(err)));
}

void MojoVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                  bool low_delay,
                                  CdmContext* cdm_context,
                                  InitCB init_cb,
                                  const OutputCB& output_cb,
                                  const WaitingCB& waiting_cb) {
  DVLOG(1) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (gpu_factories_)
    decoder_type_ = gpu_factories_->GetDecoderType();

  // Fail immediately if we know that the remote side cannot support |config|.
  if (gpu_factories_ && gpu_factories_->IsDecoderConfigSupported(config) ==
                            GpuVideoAcceleratorFactories::Supported::kFalse) {
    FailInit(std::move(init_cb), StatusCode::kDecoderUnsupportedConfig);
    return;
  }

  absl::optional<base::UnguessableToken> cdm_id =
      cdm_context ? cdm_context->GetCdmId() : absl::nullopt;

  // Fail immediately if the stream is encrypted but |cdm_id| is invalid.
  // This check is needed to avoid unnecessary IPC to the remote process.
  // Note that we do not support unsetting a CDM, so it should never happen
  // that a valid CDM ID is available on first initialization but an invalid
  // is passed for reinitialization.
  if (config.is_encrypted() && !cdm_id) {
    DVLOG(1) << __func__ << ": Invalid CdmContext.";
    FailInit(std::move(init_cb),
             StatusCode::kDecoderMissingCdmForEncryptedContent);
    return;
  }

  initialized_ = false;
  init_cb_ = std::move(init_cb);
  output_cb_ = output_cb;
  waiting_cb_ = waiting_cb;

  if (!remote_decoder_bound_) {
    InitAndBindRemoteDecoder(
        base::BindOnce(&MojoVideoDecoder::InitializeRemoteDecoder, weak_this_,
                       config, low_delay, std::move(cdm_id)));
    return;
  }

  InitializeRemoteDecoder(config, low_delay, std::move(cdm_id));
}

void MojoVideoDecoder::InitializeRemoteDecoder(
    const VideoDecoderConfig& config,
    bool low_delay,
    absl::optional<base::UnguessableToken> cdm_id) {
  if (has_connection_error_) {
    DCHECK(init_cb_);
    FailInit(std::move(init_cb_), StatusCode::kMojoDecoderNoConnection);
    return;
  }

  remote_decoder_->Initialize(
      config, low_delay, cdm_id,
      base::BindOnce(&MojoVideoDecoder::OnInitializeDone,
                     base::Unretained(this)));
}

void MojoVideoDecoder::OnInitializeDone(const Status& status,
                                        bool needs_bitstream_conversion,
                                        int32_t max_decode_requests,
                                        VideoDecoderType decoder_type) {
  DVLOG(1) << __func__ << ": status = " << std::hex << status.code();
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  initialized_ = status.is_ok();
  needs_bitstream_conversion_ = needs_bitstream_conversion;
  max_decode_requests_ = max_decode_requests;
  decoder_type_ = decoder_type;
  std::move(init_cb_).Run(status);
}

void MojoVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
                              DecodeCB decode_cb) {
  DVLOG(3) << __func__ << ": " << buffer->AsHumanReadableString();
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (has_connection_error_) {
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR));
    return;
  }

  if (!buffer->end_of_stream()) {
    timestamps_.Put(buffer->timestamp().InMilliseconds(),
                    base::TimeTicks::Now());
  }

  mojom::DecoderBufferPtr mojo_buffer =
      mojo_decoder_buffer_writer_->WriteDecoderBuffer(std::move(buffer));
  if (!mojo_buffer) {
    ReportInitialPlaybackErrorUMA();
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(decode_cb), DecodeStatus::DECODE_ERROR));
    return;
  }

  uint64_t decode_id = decode_counter_++;
  pending_decodes_[decode_id] = std::move(decode_cb);
  remote_decoder_->Decode(std::move(mojo_buffer),
                          base::BindOnce(&MojoVideoDecoder::OnDecodeDone,
                                         base::Unretained(this), decode_id));
}

void MojoVideoDecoder::OnVideoFrameDecoded(
    const scoped_refptr<VideoFrame>& frame,
    bool can_read_without_stalling,
    const absl::optional<base::UnguessableToken>& release_token) {
  DVLOG(3) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // TODO(sandersd): Prove that all paths read this value again after running
  // |output_cb_|. In practice this isn't very important, since all decoders
  // running via MojoVideoDecoder currently use a static value.
  can_read_without_stalling_ = can_read_without_stalling;

  if (release_token) {
    frame->SetReleaseMailboxCB(
        mojo_video_frame_handle_releaser_->CreateReleaseMailboxCB(
            release_token.value()));
  }
  const int64_t timestamp = frame->timestamp().InMilliseconds();
  const auto timestamp_it = timestamps_.Peek(timestamp);
  if (timestamp_it != timestamps_.end()) {
    const auto decode_start_time = timestamp_it->second;
    const auto decode_end_time = base::TimeTicks::Now();

    TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
        "media", "MojoVideoDecoder::Decode", timestamp, decode_start_time);
    TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1(
        "media", "MojoVideoDecoder::Decode", timestamp, decode_end_time,
        "timestamp", timestamp);
    UMA_HISTOGRAM_TIMES("Media.MojoVideoDecoder.Decode",
                        decode_end_time - decode_start_time);
  }

  output_cb_.Run(frame);
  total_frames_decoded_++;
  if (!initial_playback_outcome_reported_ &&
      total_frames_decoded_ >= kMojoDecoderInitialPlaybackFrameCount) {
    initial_playback_outcome_reported_ = true;
    UMA_HISTOGRAM_COUNTS_100(
        kMojoVideoDecoderInitialPlaybackSuccessCodecCounterUMA,
        get_mojo_instance_counter());
    DVLOG(3)
        << "Report Media.MojoVideoDecoder.InitialPlaybackSuccessCodecCounter:"
        << get_mojo_instance_counter();
  }
}

void MojoVideoDecoder::OnDecodeDone(uint64_t decode_id, const Status& status) {
  DVLOG(3) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  auto it = pending_decodes_.find(decode_id);
  if (it == pending_decodes_.end()) {
    DLOG(ERROR) << "Decode request " << decode_id << " not found";
    Stop();
    return;
  }

  if (!status.is_ok() && status.code() != StatusCode::kAborted)
    ReportInitialPlaybackErrorUMA();

  DecodeCB decode_cb = std::move(it->second);
  pending_decodes_.erase(it);
  std::move(decode_cb).Run(status);
}

void MojoVideoDecoder::Reset(base::OnceClosure reset_cb) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (has_connection_error_) {
    task_runner_->PostTask(FROM_HERE, std::move(reset_cb));
    return;
  }

  reset_cb_ = std::move(reset_cb);
  remote_decoder_->Reset(
      base::BindOnce(&MojoVideoDecoder::OnResetDone, base::Unretained(this)));
}

void MojoVideoDecoder::OnResetDone() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  std::move(reset_cb_).Run();
}

bool MojoVideoDecoder::NeedsBitstreamConversion() const {
  DVLOG(3) << __func__;
  DCHECK(initialized_);
  return needs_bitstream_conversion_;
}

bool MojoVideoDecoder::CanReadWithoutStalling() const {
  DVLOG(3) << __func__;
  return can_read_without_stalling_;
}

int MojoVideoDecoder::GetMaxDecodeRequests() const {
  DVLOG(3) << __func__;
  DCHECK(initialized_);
  return max_decode_requests_;
}

bool MojoVideoDecoder::IsOptimizedForRTC() const {
  DVLOG(3) << __func__;
  return true;
}

void MojoVideoDecoder::InitAndBindRemoteDecoder(base::OnceClosure complete_cb) {
  DVLOG(3) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!remote_decoder_bound_);

  remote_decoder_.Bind(std::move(pending_remote_decoder_));
  remote_decoder_bound_ = true;

  remote_decoder_.set_disconnect_handler(
      base::BindOnce(&MojoVideoDecoder::Stop, base::Unretained(this)));

  // Generate |command_buffer_id|.
  media::mojom::CommandBufferIdPtr command_buffer_id;

  if (gpu_factories_) {
    DCHECK(complete_cb);
    gpu_factories_->GetChannelToken(
        base::BindOnce(&MojoVideoDecoder::OnChannelTokenReady, weak_this_,
                       std::move(command_buffer_id), std::move(complete_cb)));
    return;
  }

  DCHECK(complete_cb);
  InitAndConstructRemoteDecoder(std::move(command_buffer_id),
                                std::move(complete_cb));
}

void MojoVideoDecoder::OnChannelTokenReady(
    media::mojom::CommandBufferIdPtr command_buffer_id,
    base::OnceClosure complete_cb,
    const base::UnguessableToken& channel_token) {
  if (channel_token) {
    command_buffer_id = media::mojom::CommandBufferId::New();
    command_buffer_id->channel_token = std::move(channel_token);
    command_buffer_id->route_id = gpu_factories_->GetCommandBufferRouteId();
  }
  InitAndConstructRemoteDecoder(std::move(command_buffer_id),
                                std::move(complete_cb));
}

void MojoVideoDecoder::InitAndConstructRemoteDecoder(
    media::mojom::CommandBufferIdPtr command_buffer_id,
    base::OnceClosure complete_cb) {
  // Create |video_frame_handle_releaser| interface receiver, and bind
  // |mojo_video_frame_handle_releaser_| to it.
  mojo::PendingRemote<mojom::VideoFrameHandleReleaser>
      video_frame_handle_releaser_pending_remote;
  mojo::PendingReceiver<mojom::VideoFrameHandleReleaser>
      video_frame_handle_releaser_receiver =
          video_frame_handle_releaser_pending_remote
              .InitWithNewPipeAndPassReceiver();
  mojo_video_frame_handle_releaser_ =
      base::MakeRefCounted<MojoVideoFrameHandleReleaser>(
          std::move(video_frame_handle_releaser_pending_remote), task_runner_);

  mojo::ScopedDataPipeConsumerHandle remote_consumer_handle;
  mojo_decoder_buffer_writer_ = MojoDecoderBufferWriter::Create(
      writer_capacity_, &remote_consumer_handle);

  // Use `mojo::MakeSelfOwnedReceiver` for MediaLog so logs may go through even
  // after `MojoVideoDecoder` is destructed.
  mojo::PendingReceiver<mojom::MediaLog> media_log_pending_receiver;
  auto media_log_pending_remote =
      media_log_pending_receiver.InitWithNewPipeAndPassRemote();
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<MojoMediaLogService>(media_log_->Clone()),
      std::move(media_log_pending_receiver));

  remote_decoder_->Construct(client_receiver_.BindNewEndpointAndPassRemote(),
                             std::move(media_log_pending_remote),
                             std::move(video_frame_handle_releaser_receiver),
                             std::move(remote_consumer_handle),
                             std::move(command_buffer_id), target_color_space_);
  get_mojo_instance_counter()++;
  std::move(complete_cb).Run();
}

void MojoVideoDecoder::OnWaiting(WaitingReason reason) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  waiting_cb_.Run(reason);
}

void MojoVideoDecoder::RequestOverlayInfo(bool restart_for_transitions) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(request_overlay_info_cb_);

  overlay_info_requested_ = true;
  request_overlay_info_cb_.Run(
      restart_for_transitions,
      BindToCurrentLoop(base::BindRepeating(
          &MojoVideoDecoder::OnOverlayInfoChanged, weak_this_)));
}

void MojoVideoDecoder::OnOverlayInfoChanged(const OverlayInfo& overlay_info) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (has_connection_error_)
    return;
  remote_decoder_->OnOverlayInfoChanged(overlay_info);
}

void MojoVideoDecoder::Stop() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  has_connection_error_ = true;
  ReportInitialPlaybackErrorUMA();

  // |init_cb_| is likely to reentrantly destruct |this|, so we check for that
  // using an on-stack WeakPtr.
  // TODO(sandersd): Update the VideoDecoder API to be explicit about what
  // reentrancy is allowed, and therefore which callbacks must be posted.
  base::WeakPtr<MojoVideoDecoder> weak_this = weak_this_;

  if (init_cb_)
    std::move(init_cb_).Run(StatusCode::kMojoDecoderStoppedBeforeInitDone);

  if (!weak_this)
    return;

  for (auto& pending_decode : pending_decodes_) {
    std::move(pending_decode.second).Run(DecodeStatus::DECODE_ERROR);
    if (!weak_this)
      return;
  }
  pending_decodes_.clear();

  if (reset_cb_)
    std::move(reset_cb_).Run();
}

void MojoVideoDecoder::ReportInitialPlaybackErrorUMA() {
  if (initial_playback_outcome_reported_)
    return;

  DCHECK(get_mojo_instance_counter() > 0);
  DVLOG(3) << "Report Media.MojoVideoDecoder.InitialPlaybackErrorCodecCounter:"
           << get_mojo_instance_counter();

  UMA_HISTOGRAM_COUNTS_100(kMojoVideoDecoderInitialPlaybackErrorCodecCounterUMA,
                           get_mojo_instance_counter());
  initial_playback_outcome_reported_ = true;
}

}  // namespace media
