// Copyright 2017 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/offloading_video_decoder.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/atomic_flag.h"
#include "base/task/post_task.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/decoder_buffer.h"
#include "media/base/video_frame.h"

namespace media {

// Helper class which manages cancellation of Decode() after Reset() and makes
// it easier to destruct on the proper thread.
class CancellationHelper {
 public:
  CancellationHelper(std::unique_ptr<OffloadableVideoDecoder> decoder)
      : cancellation_flag_(std::make_unique<base::AtomicFlag>()),
        decoder_(std::move(decoder)) {}

  // Safe to call from any thread.
  void Cancel() { cancellation_flag_->Set(); }

  void Decode(scoped_refptr<DecoderBuffer> buffer,
              const VideoDecoder::DecodeCB& decode_cb) {
    if (cancellation_flag_->IsSet()) {
      decode_cb.Run(DecodeStatus::ABORTED);
      return;
    }

    decoder_->Decode(std::move(buffer), decode_cb);
  }

  void Reset(const base::Closure& reset_cb) {
    // OffloadableVideoDecoders are required to have a synchronous Reset(), so
    // we don't need to wait for the Reset to complete. Despite this, we don't
    // want to run |reset_cb| before we've reset the cancellation flag or the
    // client may end up issuing another Reset() before this code runs.
    decoder_->Reset(base::DoNothing());
    cancellation_flag_.reset(new base::AtomicFlag());
    reset_cb.Run();
  }

  OffloadableVideoDecoder* decoder() const { return decoder_.get(); }

 private:
  std::unique_ptr<base::AtomicFlag> cancellation_flag_;
  std::unique_ptr<OffloadableVideoDecoder> decoder_;

  DISALLOW_COPY_AND_ASSIGN(CancellationHelper);
};

OffloadingVideoDecoder::OffloadingVideoDecoder(
    int min_offloading_width,
    std::vector<VideoCodec> supported_codecs,
    std::unique_ptr<OffloadableVideoDecoder> decoder)
    : min_offloading_width_(min_offloading_width),
      supported_codecs_(std::move(supported_codecs)),
      helper_(std::make_unique<CancellationHelper>(std::move(decoder))),
      weak_factory_(this) {
  DETACH_FROM_THREAD(thread_checker_);
}

OffloadingVideoDecoder::~OffloadingVideoDecoder() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // The |helper_| must always be destroyed on the |offload_task_runner_| since
  // we may still have tasks posted to it.
  if (offload_task_runner_)
    offload_task_runner_->DeleteSoon(FROM_HERE, std::move(helper_));
}

std::string OffloadingVideoDecoder::GetDisplayName() const {
  // This call is expected to be static and safe to call from any thread.
  return helper_->decoder()->GetDisplayName();
}

void OffloadingVideoDecoder::Initialize(const VideoDecoderConfig& config,
                                        bool low_delay,
                                        CdmContext* cdm_context,
                                        const InitCB& init_cb,
                                        const OutputCB& output_cb,
                                        const WaitingCB& waiting_cb) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(config.IsValidConfig());

  const bool disable_offloading =
      config.is_encrypted() ||
      config.coded_size().width() < min_offloading_width_ ||
      std::find(supported_codecs_.begin(), supported_codecs_.end(),
                config.codec()) == supported_codecs_.end();

  if (initialized_) {
    initialized_ = false;

    // We're transitioning from offloading to no offloading, so detach from the
    // offloading thread so we can run on the media thread.
    if (disable_offloading && offload_task_runner_) {
      offload_task_runner_->PostTaskAndReply(
          FROM_HERE,
          base::BindOnce(&OffloadableVideoDecoder::Detach,
                         base::Unretained(helper_->decoder())),
          // We must trampoline back trough OffloadingVideoDecoder because it's
          // possible for this class to be destroyed during Initialize().
          base::BindOnce(&OffloadingVideoDecoder::Initialize,
                         weak_factory_.GetWeakPtr(), config, low_delay,
                         cdm_context, init_cb, output_cb, waiting_cb));
      return;
    }

    // We're transitioning from no offloading to offloading, so detach from the
    // media thread so we can run on the offloading thread.
    if (!disable_offloading && !offload_task_runner_)
      helper_->decoder()->Detach();
  }

  DCHECK(!initialized_);
  initialized_ = true;

  // Offloaded decoders expect asynchronous execution of callbacks; even if we
  // aren't currently using the offload thread.
  InitCB bound_init_cb = BindToCurrentLoop(init_cb);
  OutputCB bound_output_cb = BindToCurrentLoop(output_cb);

  // If we're not offloading just pass through to the wrapped decoder.
  if (disable_offloading) {
    offload_task_runner_ = nullptr;
    helper_->decoder()->Initialize(config, low_delay, cdm_context,
                                   bound_init_cb, bound_output_cb, waiting_cb);
    return;
  }

  if (!offload_task_runner_) {
    offload_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
        {base::TaskPriority::USER_BLOCKING});
  }

  offload_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&OffloadableVideoDecoder::Initialize,
                     base::Unretained(helper_->decoder()), config, low_delay,
                     cdm_context, bound_init_cb, bound_output_cb, waiting_cb));
}

void OffloadingVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
                                    const DecodeCB& decode_cb) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(buffer);
  DCHECK(decode_cb);

  DecodeCB bound_decode_cb = BindToCurrentLoop(decode_cb);
  if (!offload_task_runner_) {
    helper_->decoder()->Decode(std::move(buffer), bound_decode_cb);
    return;
  }

  offload_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&CancellationHelper::Decode,
                                base::Unretained(helper_.get()),
                                std::move(buffer), bound_decode_cb));
}

void OffloadingVideoDecoder::Reset(const base::Closure& reset_cb) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  base::Closure bound_reset_cb = BindToCurrentLoop(reset_cb);
  if (!offload_task_runner_) {
    helper_->Reset(bound_reset_cb);
  } else {
    helper_->Cancel();
    offload_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&CancellationHelper::Reset,
                       base::Unretained(helper_.get()), bound_reset_cb));
  }
}

int OffloadingVideoDecoder::GetMaxDecodeRequests() const {
  // If we're offloading, try to parallelize decodes as well. Take care when
  // adjusting this number as it may dramatically increase memory usage and
  // reduce seek times. See http://crbug.com/731841.
  //
  // The current value of 2 was determined via experimental adjustment until a
  // 4K60 VP9 playback dropped zero frames.
  return offload_task_runner_ ? 2 : 1;
}

}  // namespace media
