// Copyright 2018 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 "local_codec_factory.h"

#include <lib/fidl/cpp/clone.h>
#include <lib/fit/function.h>
#include <lib/media/codec_impl/codec_admission_control.h>

#include <optional>

#include "codec_adapter_h264.h"
#include "codec_adapter_h264_multi.h"
#include "codec_adapter_mpeg2.h"
#include "codec_adapter_vp9.h"
#include "device_ctx.h"

namespace {

struct CodecAdapterFactory {
  bool is_enabled;
  fuchsia::mediacodec::CodecDescription description;

  // This typedef is just for local readability here, not for use outside this
  // struct.
  using CreateFunction = fit::function<std::unique_ptr<CodecAdapter>(
      std::mutex& lock, CodecAdapterEvents*, DeviceCtx*)>;

  bool multi_instance;

  CreateFunction create;
};

// TODO(dustingreen): Fix up this list to correspond to what
// CodecImpl+AmlogicVideo can actually handle so far, once there's at least one
// format in that list.  For now this list is here to allow covering some
// LocalCodecFactory code.
const CodecAdapterFactory kCodecFactories[] = {
    {
        true,  // is_enabled
        fuchsia::mediacodec::CodecDescription{
            .codec_type = fuchsia::mediacodec::CodecType::DECODER,
            // TODO(dustingreen): See TODO comments on this field in
            // codec_common.fidl.
            .mime_type = "video/h264",

            // TODO(fxbug.dev/13483): Make more of these true by implementing in
            // CodecAdapterH264Multi.
            .can_stream_bytes_input = true,
            .can_find_start = false,
            .can_re_sync = false,
            .will_report_all_detected_errors = false,

            .is_hw = true,

            // TODO(dustingreen): Determine if this claim of "true" is actually
            // the case.
            .split_header_handling = true,
        },
        true,  // multi_instance
        [](std::mutex& lock, CodecAdapterEvents* events, DeviceCtx* device) {
          return std::make_unique<CodecAdapterH264Multi>(lock, events, device);
        },
    },
    {
        false,  // is_enabled
        fuchsia::mediacodec::CodecDescription{
            .codec_type = fuchsia::mediacodec::CodecType::DECODER,
            // TODO(dustingreen): See TODO comments on this field in
            // codec_common.fidl.
            .mime_type = "video/mpeg2",

            // TODO(dustingreen): Determine which of these can safely indicate
            // more capability.
            .can_stream_bytes_input = false,
            .can_find_start = false,
            .can_re_sync = false,
            .will_report_all_detected_errors = false,

            .is_hw = true,

            // TODO(dustingreen): Determine if this claim of "true" is actually
            // the case.
            .split_header_handling = true,
        },
        false,  // multi_instance
        [](std::mutex& lock, CodecAdapterEvents* events, DeviceCtx* device) {
          return std::make_unique<CodecAdapterMpeg2>(lock, events, device);
        },
    },
    {
        true,  // is_enabled
        fuchsia::mediacodec::CodecDescription{
            .codec_type = fuchsia::mediacodec::CodecType::DECODER,
            // TODO(dustingreen): See TODO comments on this field in
            // codec_common.fidl.
            .mime_type = "video/vp9",

            // TODO(dustingreen): Determine which of these can safely indicate
            // more capability.
            .can_stream_bytes_input = false,
            .can_find_start = false,
            .can_re_sync = false,
            .will_report_all_detected_errors = false,

            .is_hw = true,

            // TODO(dustingreen): Determine if this claim of "true" is actually
            // the case.
            .split_header_handling = true,
        },
        true,  // multi_instance
        [](std::mutex& lock, CodecAdapterEvents* events, DeviceCtx* device) {
          return std::make_unique<CodecAdapterVp9>(lock, events, device);
        },
    },
    {
        true,  // is_enabled
        fuchsia::mediacodec::CodecDescription{
            .codec_type = fuchsia::mediacodec::CodecType::DECODER,
            // TODO(dustingreen): See TODO comments on this field in
            // codec_common.fidl.
            .mime_type = "video/h264-single",

            // TODO(dustingreen): Determine which of these can safely indicate
            // more capability.
            .can_stream_bytes_input = false,
            .can_find_start = false,
            .can_re_sync = false,
            .will_report_all_detected_errors = false,

            .is_hw = true,

            // TODO(dustingreen): Determine if this claim of "true" is actually
            // the case.
            .split_header_handling = true,
        },
        false,  // multi_instance
        [](std::mutex& lock, CodecAdapterEvents* events, DeviceCtx* device) {
          return std::make_unique<CodecAdapterH264>(lock, events, device);
        },
    },
    {
        true,  // is_enabled
        fuchsia::mediacodec::CodecDescription{
            .codec_type = fuchsia::mediacodec::CodecType::DECODER,
            // TODO(dustingreen): See TODO comments on this field in
            // codec_common.fidl.
            .mime_type = "video/h264-multi",

            // TODO(dustingreen): Determine which of these can safely indicate
            // more capability.
            .can_stream_bytes_input = false,
            .can_find_start = false,
            .can_re_sync = false,
            .will_report_all_detected_errors = false,

            .is_hw = true,

            // TODO(dustingreen): Determine if this claim of "true" is actually
            // the case.
            .split_header_handling = true,
        },
        true,  // multi_instance
        [](std::mutex& lock, CodecAdapterEvents* events, DeviceCtx* device) {
          return std::make_unique<CodecAdapterH264Multi>(lock, events, device);
        },
    },
    {
        true,  // is_enabled
        fuchsia::mediacodec::CodecDescription{
            .codec_type = fuchsia::mediacodec::CodecType::DECODER,
            // TODO(dustingreen): See TODO comments on this field in
            // codec_common.fidl.
            .mime_type = "video/h264-multi/test/force-context-save-restore",

            // TODO(dustingreen): Determine which of these can safely indicate
            // more capability.
            .can_stream_bytes_input = false,
            .can_find_start = false,
            .can_re_sync = false,
            .will_report_all_detected_errors = false,

            .is_hw = true,

            // TODO(dustingreen): Determine if this claim of "true" is actually
            // the case.
            .split_header_handling = true,
        },
        true,  // multi_instance
        [](std::mutex& lock, CodecAdapterEvents* events, DeviceCtx* device) {
          auto decoder = std::make_unique<CodecAdapterH264Multi>(lock, events, device);
          AmlogicDecoderTestHooks test_hooks = {
              .force_context_save_restore = true,
          };
          decoder->set_test_hooks(test_hooks);
          return decoder;
        },
    },
};

}  // namespace

// device - associated device.
LocalCodecFactory::LocalCodecFactory(DeviceCtx* device) : device_(device), factory_binding_(this) {
  // nothing else to do here
}

LocalCodecFactory::~LocalCodecFactory() {
  // We need ~factory_binding_ to run on shared_fidl_thread() else it's not safe
  // to un-bind unilaterally (without the channel closing).  Unless not bound in
  // the first place.
  ZX_DEBUG_ASSERT(thrd_current() == device_->driver()->shared_fidl_thread() ||
                  !factory_binding_.is_bound());

  // ~factory_binding_ here + fact that we're running on shared_fidl_thread()
  // (if Bind() previously called) means error_handler won't be running
  // concurrently with ~LocalCodecFactory and won't run after ~factory_binding_
  // here.
}

void LocalCodecFactory::SetErrorHandler(fit::closure error_handler) {
  ZX_DEBUG_ASSERT(!factory_binding_.is_bound());
  factory_binding_.set_error_handler(
      [this, error_handler = std::move(error_handler)](zx_status_t status) mutable {
        ZX_DEBUG_ASSERT(thrd_current() == device_->driver()->shared_fidl_thread());
        // This queues after the similar posting in CreateDecoder() (via
        // TryAddCodec()), so that LocalCodecFactory won't get deleted until
        // after previously-started TryAddCodec()s are done.
        device_->codec_admission_control()->PostAfterPreviouslyStartedClosesDone(
            [this, error_handler = std::move(error_handler)] {
              ZX_DEBUG_ASSERT(thrd_current() == device_->driver()->shared_fidl_thread());
              error_handler();
              // "this" is gone
            });
      });
  is_error_handler_set_ = true;
}

void LocalCodecFactory::Bind(zx::channel server_endpoint) {
  ZX_DEBUG_ASSERT(is_error_handler_set_);
  ZX_DEBUG_ASSERT(!factory_binding_.is_bound());

  // Go!  (immediately - if Bind() is called on IOCTL thread, this can result in
  // _immediate_ dispatching over on shared_fidl_thread()).
  factory_binding_.Bind(std::move(server_endpoint),
                        device_->driver()->shared_fidl_loop()->dispatcher());

  // All HW-accelerated local CodecFactory(s) must send OnCodecList()
  // immediately upon creation of the local CodecFactory.
  std::vector<fuchsia::mediacodec::CodecDescription> codec_descriptions;
  for (const CodecAdapterFactory& factory : kCodecFactories) {
    if (!factory.is_enabled) {
      continue;
    }
    codec_descriptions.push_back(fidl::Clone(factory.description));
  }
  factory_binding_.events().OnCodecList(std::move(codec_descriptions));
}

void LocalCodecFactory::CreateDecoder(
    fuchsia::mediacodec::CreateDecoder_Params video_decoder_params,
    ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> video_decoder) {
  if (!video_decoder_params.has_input_details()) {
    return;
  }

  if (!video_decoder_params.input_details().has_mime_type()) {
    // Without mime_type we cannot search for a decoder.
    return;
  }

  const CodecAdapterFactory* factory = nullptr;
  for (const CodecAdapterFactory& candidate_factory : kCodecFactories) {
    if (!candidate_factory.is_enabled) {
      continue;
    }
    if (candidate_factory.description.mime_type ==
        video_decoder_params.input_details().mime_type()) {
      factory = &candidate_factory;
      break;
    }
  }
  if (!factory) {
    // This shouldn't really happen since the main CodecFactory shouldn't be
    // asking this LocalCodecFactory for a codec fitting a description that's
    // not a description this factory previously delivered to the main
    // CodecFactory via OnCodecList().
    //
    // TODO(dustingreen): epitaph for video_decoder.
    //
    // ~video_decoder here will take care of closing the channel
    return;
  }

  // We also post to the same queue in the set_error_handler() lambda, so that
  // we know the LocalCodecFactory will remain alive until after this lambda
  // completes.
  //
  // The factory pointer remains valid for whole lifetime of this devhost
  // process.
  device_->codec_admission_control()->TryAddCodec(
      factory->multi_instance, [this, video_decoder_params = std::move(video_decoder_params),
                                video_decoder = std::move(video_decoder),
                                factory](std::unique_ptr<CodecAdmission> codec_admission) mutable {
        if (!codec_admission) {
          // We can't create another Codec presently.
          //
          // ~video_decoder will take care of closing the channel.
          return;
        }

        fidl::InterfaceHandle<fuchsia::sysmem::Allocator> sysmem =
            device_->video()->ConnectToSysmem();
        if (!sysmem) {
          return;
        }

        auto codec =
            std::make_unique<CodecImpl>(std::move(sysmem), std::move(codec_admission),
                                        device_->driver()->shared_fidl_loop()->dispatcher(),
                                        device_->driver()->shared_fidl_thread(),
                                        std::move(video_decoder_params), std::move(video_decoder));

        codec->SetLifetimeTracking(std::move(lifetime_tracking_));
        ZX_DEBUG_ASSERT(lifetime_tracking_.empty());

        codec->SetCodecMetrics(&device_->metrics());
        auto core_codec = factory->create(codec->lock(), codec.get(), device_);
        // Don't wait for CodecAdapter sub-class to call LogEvent().  Verify this is not
        // std::nullopt here, as any CodecAdapter sub-class in amlogic_video_decoder is allowed to
        // call LogEvent() and must override CoreCodecMetricsImplementation().
        ZX_DEBUG_ASSERT(core_codec->CoreCodecMetricsImplementation());
        codec->SetCoreCodecAdapter(std::move(core_codec));

        device_->device_fidl()->BindCodecImpl(std::move(codec));
      });
}

void LocalCodecFactory::CreateEncoder(
    fuchsia::mediacodec::CreateEncoder_Params encoder_params,
    ::fidl::InterfaceRequest<fuchsia::media::StreamProcessor> encoder_request) {
  // We have no encoders to provide.
  lifetime_tracking_.clear();
  // ~encoder_request
}

void LocalCodecFactory::AttachLifetimeTracking(zx::eventpair codec_end) {
  ZX_DEBUG_ASSERT(lifetime_tracking_.size() <=
                  fuchsia::mediacodec::CODEC_FACTORY_LIFETIME_TRACKING_EVENTPAIR_PER_CREATE_MAX);
  if (lifetime_tracking_.size() >=
      fuchsia::mediacodec::CODEC_FACTORY_LIFETIME_TRACKING_EVENTPAIR_PER_CREATE_MAX) {
    factory_binding_.Close(ZX_ERR_BAD_STATE);
    device_->device_fidl()->DeleteFactory(this);
    return;
  }
  lifetime_tracking_.emplace_back(std::move(codec_end));
}
