// Copyright 2014 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/filters/decoder_selector.h"

#include <algorithm>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "media/base/audio_decoder.h"
#include "media/base/cdm_context.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_log.h"
#include "media/base/media_switches.h"
#include "media/base/video_decoder.h"
#include "media/filters/decoder_stream_traits.h"
#include "media/filters/decrypting_demuxer_stream.h"

namespace media {

namespace {

const char kSelectDecoderTrace[] = "DecoderSelector::SelectDecoder";

bool SkipDecoderForRTC(const AudioDecoderConfig& /*config*/,
                       const AudioDecoder& /*decoder*/) {
  return false;
}

bool SkipDecoderForRTC(const VideoDecoderConfig& config,
                       const VideoDecoder& decoder) {
  // For now, we assume that RTC decoders are able to decode non-RTC streams,
  // presumably by configuring themselves based on the config's rtc bit.  Since
  // no decoders take any action at all based on it, this is as good as any.
  return config.is_rtc() && !decoder.IsOptimizedForRTC();
}

template <typename ConfigT, typename DecoderT>
DecoderPriority NormalDecoderPriority(const ConfigT& config,
                                      const DecoderT& decoder) {
  if (SkipDecoderForRTC(config, decoder))
    return DecoderPriority::kSkipped;

  return DecoderPriority::kNormal;
}

DecoderPriority ResolutionBasedDecoderPriority(const VideoDecoderConfig& config,
                                               const VideoDecoder& decoder) {
#if defined(OS_ANDROID)
  constexpr auto kSoftwareDecoderHeightCutoff = 360;
#elif BUILDFLAG(IS_CHROMEOS_ASH)
  constexpr auto kSoftwareDecoderHeightCutoff = 360;
#else
  constexpr auto kSoftwareDecoderHeightCutoff = 720;
#endif

  if (SkipDecoderForRTC(config, decoder))
    return DecoderPriority::kSkipped;

  // We only do a height check to err on the side of prioritizing platform
  // decoders.
  const auto at_or_above_software_cutoff =
      config.visible_rect().height() >= kSoftwareDecoderHeightCutoff;

  // Platform decoders are deprioritized below the cutoff, and non-platform
  // decoders are deprioritized above it.
  return at_or_above_software_cutoff == decoder.IsPlatformDecoder()
             ? DecoderPriority::kNormal
             : DecoderPriority::kDeprioritized;
}

template <typename ConfigT, typename DecoderT>
DecoderPriority SkipNonPlatformDecoders(const ConfigT& config,
                                        const DecoderT& decoder) {
  if (SkipDecoderForRTC(config, decoder))
    return DecoderPriority::kSkipped;

  return decoder.IsPlatformDecoder() ? DecoderPriority::kNormal
                                     : DecoderPriority::kSkipped;
}

void SetDefaultDecoderPriorityCB(VideoDecoderSelector::DecoderPriorityCB* out) {
  if (base::FeatureList::IsEnabled(kForceHardwareVideoDecoders)) {
    *out = base::BindRepeating(
        SkipNonPlatformDecoders<VideoDecoderConfig, VideoDecoder>);
  } else if (base::FeatureList::IsEnabled(kResolutionBasedDecoderPriority)) {
    *out = base::BindRepeating(ResolutionBasedDecoderPriority);
  } else {
    *out = base::BindRepeating(
        NormalDecoderPriority<VideoDecoderConfig, VideoDecoder>);
  }
}

void SetDefaultDecoderPriorityCB(AudioDecoderSelector::DecoderPriorityCB* out) {
  if (base::FeatureList::IsEnabled(kForceHardwareAudioDecoders)) {
    *out = base::BindRepeating(
        SkipNonPlatformDecoders<AudioDecoderConfig, AudioDecoder>);
  } else {
    // Platform audio decoders are not currently prioritized or deprioritized
    *out = base::BindRepeating(
        NormalDecoderPriority<AudioDecoderConfig, AudioDecoder>);
  }
}

}  // namespace

template <DemuxerStream::Type StreamType>
DecoderSelector<StreamType>::DecoderSelector(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    CreateDecodersCB create_decoders_cb,
    MediaLog* media_log)
    : task_runner_(std::move(task_runner)),
      create_decoders_cb_(std::move(create_decoders_cb)),
      media_log_(media_log) {
  DETACH_FROM_SEQUENCE(sequence_checker_);
  SetDefaultDecoderPriorityCB(&decoder_priority_cb_);
}

template <DemuxerStream::Type StreamType>
DecoderSelector<StreamType>::~DecoderSelector() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (select_decoder_cb_)
    ReturnNullDecoder();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::Initialize(StreamTraits* traits,
                                             DemuxerStream* stream,
                                             CdmContext* cdm_context,
                                             WaitingCB waiting_cb) {
  DVLOG(2) << __func__;
  DCHECK(traits);
  DCHECK(stream);

  traits_ = traits;
  stream_ = stream;
  cdm_context_ = cdm_context;
  waiting_cb_ = std::move(waiting_cb);
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::SelectDecoder(
    SelectDecoderCB select_decoder_cb,
    typename Decoder::OutputCB output_cb) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(select_decoder_cb);
  DCHECK(!select_decoder_cb_);
  select_decoder_cb_ = std::move(select_decoder_cb);
  output_cb_ = std::move(output_cb);
  config_ = traits_->GetDecoderConfig(stream_);

  TRACE_EVENT_ASYNC_BEGIN2("media", kSelectDecoderTrace, this, "type",
                           DemuxerStream::GetTypeName(StreamType), "config",
                           config_.AsHumanReadableString());

  if (!config_.IsValidConfig()) {
    DLOG(ERROR) << "Invalid stream config";
    ReturnNullDecoder();
    return;
  }

  // If this is the first selection (ever or since FinalizeDecoderSelection()),
  // start selection with the full list of potential decoders.
  if (!is_selecting_decoders_) {
    is_selecting_decoders_ = true;
    decoder_selection_start_ = base::TimeTicks::Now();
    CreateDecoders();
  }

  InitializeDecoder();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::FinalizeDecoderSelection() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!select_decoder_cb_);
  is_selecting_decoders_ = false;

  const std::string decoder_type = is_platform_decoder_ ? "HW" : "SW";
  const std::string stream_type =
      StreamType == DemuxerStream::AUDIO ? "Audio" : "Video";

  if (is_selecting_for_config_change_) {
    is_selecting_for_config_change_ = false;
    base::UmaHistogramTimes("Media.ConfigChangeDecoderSelectionTime." +
                                stream_type + "." + decoder_type,
                            base::TimeTicks::Now() - decoder_selection_start_);
  } else {
    // Initial selection
    base::UmaHistogramTimes(
        "Media.InitialDecoderSelectionTime." + stream_type + "." + decoder_type,
        base::TimeTicks::Now() - decoder_selection_start_);
  }

  if (is_codec_changing_) {
    is_codec_changing_ = false;
    base::UmaHistogramTimes(
        "Media.MSE.CodecChangeTime." + stream_type + "." + decoder_type,
        base::TimeTicks::Now() - codec_change_start_);
  }

  // Discard any remaining decoder instances, they won't be used.
  decoders_.clear();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::NotifyConfigChanged() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  is_selecting_for_config_change_ = true;

  DecoderConfig config = traits_->GetDecoderConfig(stream_);
  if (config.codec() != config_.codec()) {
    is_codec_changing_ = true;
    codec_change_start_ = base::TimeTicks::Now();
  }
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::PrependDecoder(
    std::unique_ptr<Decoder> decoder) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Decoders inserted directly should be given priority over those returned by
  // |create_decoders_cb_|.
  decoders_.insert(decoders_.begin(), std::move(decoder));

  if (is_selecting_decoders_)
    FilterAndSortAvailableDecoders();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::OverrideDecoderPriorityCBForTesting(
    DecoderPriorityCB decoder_priority_cb) {
  decoder_priority_cb_ = std::move(decoder_priority_cb);
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::CreateDecoders() {
  // Post-insert decoders returned by `create_decoders_cb_`, so that
  // any decoders added via `PrependDecoder()` are not overwritten and retain
  // priority (even if they are ultimately de-ranked by
  // `FilterAndSortAvailableDecoders()`)
  auto new_decoders = create_decoders_cb_.Run();
  std::move(new_decoders.begin(), new_decoders.end(),
            std::inserter(decoders_, decoders_.end()));
  FilterAndSortAvailableDecoders();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::InitializeDecoder() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!decoder_);

  if (decoders_.empty()) {
    // Decoder selection failed. If the stream is encrypted, try again using
    // DecryptingDemuxerStream.
    if (config_.is_encrypted() && cdm_context_) {
      InitializeDecryptingDemuxerStream();
      return;
    }

    ReturnNullDecoder();
    return;
  }

  // Initialize the first decoder on the list.
  decoder_ = std::move(decoders_.front());
  decoders_.erase(decoders_.begin());
  is_platform_decoder_ = decoder_->IsPlatformDecoder();
  TRACE_EVENT_ASYNC_STEP_INTO0("media", kSelectDecoderTrace, this,
                               GetDecoderName(decoder_->GetDecoderType()));

  DVLOG(2) << __func__ << ": initializing " << decoder_->GetDecoderType();
  const bool is_live = stream_->liveness() == DemuxerStream::LIVENESS_LIVE;
  traits_->InitializeDecoder(
      decoder_.get(), config_, is_live, cdm_context_,
      base::BindOnce(&DecoderSelector<StreamType>::OnDecoderInitializeDone,
                     weak_this_factory_.GetWeakPtr()),
      output_cb_, waiting_cb_);
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::OnDecoderInitializeDone(Status status) {
  DVLOG(2) << __func__ << ": " << decoder_->GetDecoderType()
           << " success=" << std::hex << status.code();
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!status.is_ok()) {
    // TODO(tmathmeyer) this was too noisy in media log. Batch all the logs
    // together and then send them as an informational notice instead of
    // using NotifyError.
    MEDIA_LOG(INFO, media_log_)
        << "Failed to initialize " << decoder_->GetDecoderType();

    // Try the next decoder on the list.
    decoder_.reset();
    InitializeDecoder();
    return;
  }

  RunSelectDecoderCB();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::ReturnNullDecoder() {
  DVLOG(1) << __func__ << ": No decoder selected";
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  decrypting_demuxer_stream_.reset();
  decoder_.reset();
  decoders_.clear();
  RunSelectDecoderCB();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::InitializeDecryptingDemuxerStream() {
  DCHECK(decoders_.empty());
  DCHECK(config_.is_encrypted());
  DCHECK(cdm_context_);
  TRACE_EVENT_ASYNC_STEP_INTO0("media", kSelectDecoderTrace, this,
                               "DecryptingDemuxerStream");

  decrypting_demuxer_stream_ = std::make_unique<DecryptingDemuxerStream>(
      task_runner_, media_log_, waiting_cb_);

  decrypting_demuxer_stream_->Initialize(
      stream_, cdm_context_,
      base::BindOnce(
          &DecoderSelector<StreamType>::OnDecryptingDemuxerStreamInitializeDone,
          weak_this_factory_.GetWeakPtr()));
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::OnDecryptingDemuxerStreamInitializeDone(
    PipelineStatus status) {
  DVLOG(2) << __func__ << ": status=" << status;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (status != PIPELINE_OK) {
    // Since we already tried every potential decoder without DDS, give up.
    ReturnNullDecoder();
    return;
  }

  // Once DDS is enabled, there is no going back.
  // TODO(sandersd): Support transitions from encrypted to unencrypted.
  stream_ = decrypting_demuxer_stream_.get();
  cdm_context_ = nullptr;

  // We'll use the decrypted config from now on.
  config_ = traits_->GetDecoderConfig(stream_);
  DCHECK(!config_.is_encrypted());

  // Try decoder selection again now that DDS is being used.
  CreateDecoders();
  InitializeDecoder();
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::RunSelectDecoderCB() {
  DCHECK(select_decoder_cb_);
  TRACE_EVENT_ASYNC_END2(
      "media", kSelectDecoderTrace, this, "type",
      DemuxerStream::GetTypeName(StreamType), "decoder",
      base::StringPrintf(
          "%s (%s)",
          decoder_ ? GetDecoderName(decoder_->GetDecoderType()).c_str()
                   : "null",
          decrypting_demuxer_stream_ ? "encrypted" : "unencrypted"));

  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(std::move(select_decoder_cb_), std::move(decoder_),
                     std::move(decrypting_demuxer_stream_)));
}

template <DemuxerStream::Type StreamType>
void DecoderSelector<StreamType>::FilterAndSortAvailableDecoders() {
  std::vector<std::unique_ptr<Decoder>> decoders = std::move(decoders_);
  std::vector<std::unique_ptr<Decoder>> deprioritized_decoders;

  for (auto& decoder : decoders) {
    // Skip the decoder if this decoder doesn't support encryption for a
    // decrypting config
    if (config_.is_encrypted() && !decoder->SupportsDecryption())
      continue;

    // Run the predicate on this decoder.
    switch (decoder_priority_cb_.Run(config_, *decoder)) {
      case DecoderPriority::kSkipped:
        continue;
      case DecoderPriority::kNormal:
        decoders_.push_back(std::move(decoder));
        break;
      case DecoderPriority::kDeprioritized:
        deprioritized_decoders.push_back(std::move(decoder));
        break;
    }
  }

  // Post-insert deprioritized decoders
  std::move(deprioritized_decoders.begin(), deprioritized_decoders.end(),
            std::inserter(decoders_, decoders_.end()));
}

// These forward declarations tell the compiler that we will use
// DecoderSelector with these arguments, allowing us to keep these definitions
// in our .cc without causing linker errors. This also means if anyone tries to
// instantiate a DecoderSelector with anything but these two specializations
// they'll most likely get linker errors.
template class DecoderSelector<DemuxerStream::AUDIO>;
template class DecoderSelector<DemuxerStream::VIDEO>;

}  // namespace media
