// 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.

#ifndef SRC_MEDIA_LIB_CODEC_IMPL_INCLUDE_LIB_MEDIA_CODEC_IMPL_CODEC_IMPL_H_
#define SRC_MEDIA_LIB_CODEC_IMPL_INCLUDE_LIB_MEDIA_CODEC_IMPL_CODEC_IMPL_H_

#include <fuchsia/media/drm/cpp/fidl.h>
#include <fuchsia/mediacodec/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/closure-queue/closure_queue.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>
#include <lib/stdcompat/variant.h>
#include <lib/thread-safe-deleter/thread_safe_deleter.h>
#include <zircon/compiler.h>

#include <list>
#include <queue>

#include <fbl/macros.h>

#include "codec_adapter.h"
#include "codec_adapter_events.h"
#include "codec_admission_control.h"
#include "codec_buffer.h"
#include "codec_packet.h"
#include "fake_map_range.h"

// The CodecImpl class can be used for both SW and HW codecs.
//
// Roughly speaking, this class converts the Codec FIDL interface which has
// cross-process pipelining of stream switches into a more synchronous
// in-process CodecAdapter interface which only has input and output data
// handled async, with stream control handled sync for the most part.
//
// This class also handles Codec protocol checks applicable to any Codec server.
//
// TODO(dustingreen): Pull CodecImpl out to a source_set, to be used by
// omx_codec_runner.h/cc also.

// Lifetime:
//
// A CodecImpl is created, either Bind()ed or destructed, and if Bind()ed, then
// later when the channel fails or there's a protocol error, calls the owner's
// error handler and the owner deletes the CodecImpl.  There is intentionally no
// way to re-use a CodecImpl for another Codec channel.

// Error handling:
//
// There are two types of errors, per-CodecImpl errors and per-devhost-process
// errors.
//
// Per-CodecImpl:
//
// We handle per-Codec protocol errors and the like by calling Unbind() on the
// CodecImpl, which fairly soon results in ~CodecImpl async, but does not exit
// the whole devhost process.  We also handle a few per-CodecImpl errors this
// way even though some of those are closer to being caused by per-devhost
// conditions, just in case.
//
// Per-devhost-process:
//
// In contrast, per-devhost error conditions, like the inability to post work to
// the shared_fidl_thread(), are handled by exiting the devhost, because those
// conditions are not really unique to any one CodecImpl.

class CodecImpl : public fuchsia::media::StreamProcessor,
                  public CodecAdapterEvents,
                  private CodecAdapter {
 public:
  using StreamProcessorParams = cpp17::variant<fuchsia::mediacodec::CreateDecoder_Params,
                                               fuchsia::mediacodec::CreateEncoder_Params,
                                               fuchsia::media::drm::DecryptorParams>;

  // The CodecImpl will take care of doing set_error_handler() on the sysmem
  // connection.  The sysmem connection should be set up to use the
  // shared_fidl_dispatcher.
  CodecImpl(fidl::InterfaceHandle<fuchsia::sysmem::Allocator> sysmem,
            std::unique_ptr<CodecAdmission> codec_admission,
            async_dispatcher_t* shared_fidl_dispatcher, thrd_t shared_fidl_thread,
            StreamProcessorParams params,
            fidl::InterfaceRequest<fuchsia::media::StreamProcessor> request);

  ~CodecImpl();

  // This is only intended for use by LocalCodecFactory in creating the
  // appropriate CodecAdapter.
  std::mutex& lock();

  void SetLifetimeTracking(std::vector<zx::eventpair> lifetime_tracking_eventpair);

  // The LocalCodecFactory optionally calls this method between construction and
  // SetCoreCodecAdapter().  If this method is not called, CodecImpl will treat
  // any call to onCoreCodecLogEvent() as a nop, and will not require that the
  // CodecAdapter sub-class implement CoreCodecMetricsImplementation().
  void SetCodecMetrics(CodecMetrics* codec_metrics);

  // The LocalCodecFactory calls this method once just after CodecImpl
  // construction and just before BindAsync().
  //
  // There's only one CodecAdapter for the lifetime of the CodecImpl.  This
  // mechanism intentionally doesn't permit switching input format to a
  // completely different format, and a CodecAdapter is free to reject any
  // format change it wants to reject.  Before giving up, a client that uses
  // per-stream input format overrides should go around one more time with a
  // freshly created Codec created directly with the new format if the client
  // gets a Codec failure having overridden the input format on a stream of a
  // Codec such that the stream's input format doesn't exactly match the Codec's
  // input format (at least for now).
  void SetCoreCodecAdapter(std::unique_ptr<CodecAdapter> codec_adapter);

  // BindAsync()
  //
  // This enables serving Codec (soon).
  //
  // Must be called on shared_fidl_thread.
  //
  // It remains permitted to cause ~CodecImpl (on shared_fidl_thread) after this
  // call.
  //
  // The core codec initialization and actual binding occur shortly later async
  // after the start of this call, possibly after this call has returned.  This
  // is to avoid core codec initialization slowing down the shared_fidl_thread()
  // which may be handling other stream data for a different CodecImpl instance.
  //
  // Any error, including those encountered before binding is fully complete,
  // will call error_handler on a clean stack on shared_fidl_thread(), after
  // this call (also on shared_fidl_thread()) returns.  If the client code runs
  // ~CodecImpl on shared_fidl_thread instead (before error_handler has run on
  // shared_fidl_thread), the error_handler will be deleted without being run.
  //
  // The error_handler is expected to trigger ~CodecImpl to run, either
  // synchronously during error_handler(), or shortly after async.  In other
  // words it's the responsibility of client code to delete the CodecImpl in a
  // timely manner during or soon after error_handler().  Until ~CodecImpl, the
  // CodecAdmission won't be released, and the channel itself won't be closed
  // (intentionally, to ensure the old instance is cleaned up before a new
  // instance is created based on a client retry triggered by server channel
  // closure).
  void BindAsync(fit::closure error_handler);

  //
  // Codec interface
  //
  void EnableOnStreamFailed() override;
  void SetInputBufferPartialSettings(
      fuchsia::media::StreamBufferPartialSettings input_settings) override;
  void SetOutputBufferPartialSettings(
      fuchsia::media::StreamBufferPartialSettings output_settings) override;
  void CompleteOutputBufferPartialSettings(uint64_t buffer_lifetime_ordinal) override;
  void FlushEndOfStreamAndCloseStream(uint64_t stream_lifetime_ordinal) override;
  void CloseCurrentStream(uint64_t stream_lifetime_ordinal, bool release_input_buffers,
                          bool release_output_buffers) override;
  void Sync(SyncCallback callback) override;
  void RecycleOutputPacket(fuchsia::media::PacketHeader available_output_packet) override;
  void QueueInputFormatDetails(uint64_t stream_lifetime_ordinal,
                               fuchsia::media::FormatDetails format_details) override;
  void QueueInputPacket(fuchsia::media::Packet packet) override;
  void QueueInputEndOfStream(uint64_t stream_lifetime_ordinal) override;

  // These are public so that CodecBuffer doesn't have to be a friend of CodecImpl.

  // This way CodecBuffer doesn't use the core_codec_bti_ directly.
  zx_status_t Pin(uint32_t options, const zx::vmo& vmo, uint64_t offset, uint64_t size,
                  zx_paddr_t* addrs, size_t addrs_count, zx::pmt* pmt);

  // Complain sync, then Unbind() async.  Even if more than one caller
  // complains, the async Unbind() work will only run once (but in such cases it
  // can be nice to see all the complaining in case multiple things fail at
  // once).  While more than one source of failure can complain, only one will
  // actually trigger Unbind() work, and the rest will just return knowing that
  // Unbind() work is started.  The Unbind() work itself will synchronize such
  // that other-thread sources of failure are no longer possible (can no longer
  // even complain) before deallocating "this".
  //
  // Callers to Fail() must not be holding lock_.  On return from Fail(), "this"
  // must not be touched as it can already be deallocated.
  void Fail(const char* format, ...);

  // Callers to FailLocked() must hold lock_ during the call.  On return from
  // FailLocked(), the caller can know that "this" is still allocated only up
  // to the point where the caller releases lock_.  Callers are encouraged not
  // to touch "this" after the call to FailLocked() besides releasing lock_,
  // for consistency with how Fail() is used; that said, the unlock itself is
  // safe.
  void FailLocked(const char* format, ...);
  // Report a devhost-fatal error.  This method never returns - instead we
  // fault the whole process.  This should only be used in cases where we
  // don't really expect an error, and where a client can't unilaterally induce
  // the error - but in case the error happens despite not being expected, we
  // want nice output that's easy to debug.
  void FailFatalLocked(const char* format, ...);

 private:
  // We keep a queue of Stream objects rather than just a single current stream
  // object, so we can track which streams are future-discarded and which are
  // not yet known to be future-discarded.  This difference matters because
  // clients are not required to process OnOutputConstraints() with
  // stream_lifetime_ordinal of a stream that the client has since told the
  // server to discard, so we don't want StreamControl ordering domain getting
  // stuck waiting on a client to catch up to an output config that the client
  // won't process.  Instead, the StreamControl ordering domain can ignore any
  // additional messages related to the discarded stream until the stream
  // discarding message is reached at which point the core codec's mid-stream
  // output config change is cancelled/forgotten when we reset the core codec.
  //
  // In addition, if we're behind, we can catch up by skipping past some
  // messages for future-discarded streams to catch up to non-discarded stream
  // input quicker.  Theoretically we could do even better by having the FIDL
  // thread delete messages previously queued to the StreamControl domain
  // regarding a stream that is now known to be discarded by the FIDL thread,
  // and collapse/combine CloseCurrentStream() messages, but that's unlikely to
  // help much in practice and would make the implementation more difficult to
  // read, and we can mitigate unbounded queuing by demanding that clients not
  // get too far ahead else we close the channel.  While forcing a client to
  // wait isn't great, if we don't, we can't impose a circuit-breaker limit on
  // the count and/or size of queued channel messages either - ideally setting
  // such a limit should be possible for any protocol, so at some convenient
  // point the client needs to wait or postpone, but only if the client is
  // written to be able to get far ahead in the first place.
  //
  // We also keep some stream-specific tracking information in here as a
  // reasonably clean way to ensure that a new stream's tracking info is
  // initialized properly.
  class Stream {
   public:
    // These mutations occur in Output ordering domain (shared_fidl_thread()):
    explicit Stream(uint64_t stream_lifetime_ordinal);
    uint64_t stream_lifetime_ordinal();
    void SetFutureDiscarded();
    bool future_discarded();
    void SetFutureFlushEndOfStream();
    __WARN_UNUSED_RESULT bool future_flush_end_of_stream();

    // These mutations occur in StreamControl ordering domain:
    ~Stream();
    // This can be called 0-N times for a given stream, and each call replaces
    // any previously-set details.
    void SetInputFormatDetails(std::unique_ptr<fuchsia::media::FormatDetails> input_format_details);
    // Can be nullptr if no per-stream details have been set, in which case the
    // caller should look at CodecImpl::initial_input_format_details_
    // instead.  The returned pointer is only valid up until the next call to to
    // SetInputFormatDetails() or when the stream is deleted, whichever comes
    // first.  This is only meant to be called on stream_control_thread_.
    const fuchsia::media::FormatDetails* input_format_details();
    // We send oob_bytes (if any) to the core codec just before sending a
    // packet to the core codec, but only when the stream has OOB data pending.
    // A new stream has OOB data initially pending, and it becomes pending again
    // if SetInputFormatDetails() is used and the oob_bytes don't match
    // the effective oob_bytes before.  This way we avoid causing extra
    // input format changes for the core codec.
    void SetOobConfigPending(bool pending);
    __WARN_UNUSED_RESULT bool oob_config_pending();
    void SetInputEndOfStream();
    __WARN_UNUSED_RESULT bool input_end_of_stream();
    void SetOutputEndOfStream();
    __WARN_UNUSED_RESULT bool output_end_of_stream();
    void SetFailureSeen();
    __WARN_UNUSED_RESULT bool failure_seen();

    // These methods are called on the core codec processing domain.  See also
    // comments on output_format_pending_.
    void SetOutputFormatPending();
    void ClearOutputFormatPending();
    __WARN_UNUSED_RESULT bool output_format_pending();

    void SetMidStreamOutputConstraintsChangeActive();
    void ClearMidStreamOutputConstraintsChangeActive();
    __WARN_UNUSED_RESULT bool is_mid_stream_output_constraints_change_active();

   private:
    const uint64_t stream_lifetime_ordinal_ = 0;
    bool future_discarded_ = false;
    bool future_flush_end_of_stream_ = false;
    // Starts as nullptr for each new stream with implicit fallback to
    // initial_input_format_details_, but can be overridden on a per-stream
    // basis with QueueInputFormatDetails().
    std::unique_ptr<fuchsia::media::FormatDetails> input_format_details_;
    // This defaults to _true_, so that we send the OOB bytes to the HW for each
    // stream, if we have any oob_bytes to send.
    bool oob_config_pending_ = true;
    bool input_end_of_stream_ = false;
    bool output_end_of_stream_ = false;
    bool failure_seen_ = false;

    // This defaults to _true_, so that we send OnOutputFormat() before the
    // first OnOutputFormat() of a stream.  We also set this back to true any
    // time the core codec indicates onOutputFormat(), and any time the core
    // codec indicates onCoreCodecMidStreamOutputConstraintsChange() with action
    // required true.
    bool output_format_pending_ = true;

    // It's not permitted for the core codec to emit output while a mid-stream
    // output constraints change is active.
    bool is_mid_stream_output_constraints_change_active_ = false;
  };

  // PortSettings
  //
  // The PortSettings wraps the port settings specified in StreamBufferPartialSettings.
  // TODO(afoxley) remove this class and just directly use StreamBufferPartialSettings now that it
  // no longer also wraps StreamBufferSettings
  class PortSettings {
   public:
    PortSettings(CodecImpl* parent, CodecPort port,
                 fuchsia::media::StreamBufferPartialSettings partial_settings);
    ~PortSettings();

    uint64_t buffer_lifetime_ordinal();

    uint64_t buffer_constraints_version_ordinal();

    uint32_t packet_count();
    uint32_t buffer_count();

    fuchsia::sysmem::CoherencyDomain coherency_domain();

    const fuchsia::media::StreamBufferPartialSettings& partial_settings();

    fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> TakeToken();

    // The caller should std::move() in the buffer_collection_info.  This call
    // is only valid if this instance was created from
    // StreamBufferPartialSettings, and this method hasn't been called before
    // on this instance.
    void SetBufferCollectionInfo(fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info);

    const fuchsia::sysmem::BufferCollectionInfo_2& buffer_collection_info();

    // We use SetBufferCollectionInfo(), but then take the VMOs back.  This
    // just happens to be more convenient than taking the VMOs before doing
    // SetBufferCollectionInfo().
    zx::vmo TakeVmo(uint32_t buffer_index);

    uint64_t vmo_usable_start(uint32_t buffer_index);
    uint64_t vmo_usable_size();

    bool is_secure();

    // Only call from FIDL thread.
    fidl::InterfaceRequest<fuchsia::sysmem::BufferCollection> NewBufferCollectionRequest(
        async_dispatcher_t* dispatcher);

    // Only call from FIDL thread.
    fuchsia::sysmem::BufferCollectionPtr& buffer_collection();

    // Only call from FIDL thread.
    void UnbindBufferCollection();

    // This condition is necessary (but not sufficient) for
    // IsOutputConfiguredLocked() to return true.
    bool is_complete_seen_output();
    void SetCompleteSeenOutput();

   private:
    CodecImpl* parent_ = nullptr;

    CodecPort port_ = kInvalidPort;

    std::unique_ptr<const fuchsia::media::StreamBufferConstraints> constraints_;
    std::unique_ptr<fuchsia::media::StreamBufferPartialSettings> partial_settings_;

    fuchsia::sysmem::BufferCollectionPtr buffer_collection_;

    // In the case of partial_settings_, the remainder of the settings arrive
    // from sysmem in a BufferCollectionInfo_2.  When that arrives from
    // sysmem, we move the VMOs into CodecBuffer(s), and the remainder of the
    // settings get stored here.
    std::unique_ptr<fuchsia::sysmem::BufferCollectionInfo_2> buffer_collection_info_;

    bool is_complete_seen_output_ = false;
  };

  // While we list this first in the member variables to hint that this gets
  // destructed last, the actual mechanism of destruction of the CodecAdmission
  // is via posting to the shared_fidl_thread(), because if we add more stuff in
  // various base classes of this class we want the destruction of
  // CodecAdmission to happen last.  The close processing won't be considered
  // done until after this is destructed.
  //
  // See codec_admission_control.h for comments re. how we'll avoid failing a
  // create that is requested by a client shortly after the client closes the
  // previous Codec channel, when there's a concurrency cap of 1 (for example).
  std::unique_ptr<CodecAdmission> codec_admission_;

  fuchsia::sysmem::AllocatorPtr sysmem_;

  async_dispatcher_t* shared_fidl_dispatcher_;
  thrd_t shared_fidl_thread_;
  // Nearly every task we post to shared_fidl_dispatcher_ is actually posted via
  // this ClosureQueue, which is how we avoid running previously-queued lambdas
  // that capture "this" or part of "this" after "this" is already gone.  The
  // ~CodecImpl ensures that task deletion occurs _before_ most of ~CodecImpl by
  // calling shared_fidl_queue_.StopAndClear().
  ClosureQueue shared_fidl_queue_;

  // Parts of CodecImpl are accessed from shared_fidl_thread(),
  // stream_control_thread_, and decoder thread(s) such as interrupt handling
  // thread(s).
  //
  // FXL_GUARDED_BY() is not directly usable in this class because this class
  // takes advantage of for example being able to read outside the lock from
  // something that can only be modified on the current thread.  Also, which
  // thread is relevant can vary by port, while FXL_GUARDED_BY() doesn't have
  // any way to tag indexes of an array differently.
  //
  // TODO(dustingreen): Implement some lock-like contexts including reader vs.
  // writer aspects so we can use FXL_GUARDED_BY() (just not with the lock
  // directly).
  //
  // TODO(dustingreen): Switch to fbl::Mutex and fbl::ConditionVariable, because
  // they complain instead of blocking if repeated acquisition is attempted, and
  // because one can check whether the current thread holds the lock (for assert
  // purposes).
  std::mutex lock_;

  //
  // Setup/teardown aspects.
  //

  // This starts unbinding.  When unbinding is done and CodecImpl is ready to
  // be destructed, client_error_handler_ is called, unless this is being called
  // during ~CodecImpl in which case client_error_handler_ is deleted without
  // running instead.
  //
  // UnbindLocked() can be called in response to a channel error (in which case
  // the binding_ itself is already unbound), or can be called in response to a
  // protocol error.  It can be called on any thread.
  //
  // On the caller's release of lock_ after this call, "this" may be
  // deallocated, if UnbindLocked() was called on a thread other than
  // fidl_thread().  For consistency and simplicity, all callers should
  // avoid touching any part of "this" after return from this method other than
  // releasing lock_.
  //
  // If the reason for un-binding is a failure, call Fail() or FailLocked()
  // instead, which will log an error before calling UnbindLocked() at the end.
  void UnbindLocked();
  // Like UnbindLocked(), but acquires the lock so the caller doesn't have to.
  // On return from this method, "this" may already have been deleted.
  void Unbind();
  // Part of the implementation of UnbindLocked() and ~CodecImpl, which ensures
  // that all relevant FIDL bindings are un-bound.  Calls to this method must
  // only occur on the FIDL thread.
  void EnsureUnbindCompleted();

  // TODO(fxbug.dev/35200): This isn't fully hooked up yet, so doesn't actually yet
  // indicate whether buffers are secure.  Enforce that
  // port_settings_[X].is_secure() is consistent with these.
  fuchsia::mediacodec::SecureMemoryMode OutputSecureMemoryMode();
  fuchsia::mediacodec::SecureMemoryMode InputSecureMemoryMode();
  fuchsia::mediacodec::SecureMemoryMode PortSecureMemoryMode(CodecPort port);
  bool IsPortSecureRequired(CodecPort port);
  bool IsPortSecurePermitted(CodecPort port);

  CodecMetrics* codec_metrics_ = nullptr;
  std::optional<media_metrics::StreamProcessorEvents2MetricDimensionImplementation>
      codec_metrics_implementation_dimension_;

  // The CodecAdapter is owned by the CodecImpl, and is listed near the top of
  // the local variables in CodecImpl so that it gets deleted near the end of
  // ~CodecImpl's implicit deletions (just in case, as of this writing).
  //
  // The CodecAdapter must not make any CodecAdapterEvents calls into CodecImpl
  // while there's no active stream, and there will be no active stream by the
  // time ~CodecImpl starts.  The CodecAdapter must be ok with being destructed
  // any time there's no active stream.
  //
  // TODO(dustingreen): Maybe it would be more convenient for the CodecAdapter
  // if CodecImpl made a Shutdown() call on it after stopping the last stream
  // and before destruction - but let's see how this goes without the Shutdown()
  // call for now.
  std::unique_ptr<CodecAdapter> codec_adapter_;

  const StreamProcessorParams params_;

  // Regardless of which type of codec was created, these track the input
  // FormatDetails.
  //
  // We keep a copy of the format details used to create the codec, and on a
  // per-stream basis those details are used as the default details, but can be
  // overridden with QueueInputFormatDetails().  A new stream will default back
  // to the FormatDetails used to create the codec unless that stream uses
  // QueueInputFormatDetails().  The QueueInputFormatDetails() is not persistent
  // across streams.
  //
  // The oob_bytes field can be null if the codec type or specific format
  // does not require oob_bytes.
  //
  // This points directly to a field of decoder_params_ (or encoder_params_),
  // which out-last all usages of this pointer.
  const fuchsia::media::FormatDetails* initial_input_format_details_ = nullptr;

  // Held here temporarily until DeviceFidl is ready to handle errors so we can
  // bind.
  fidl::InterfaceHandle<fuchsia::sysmem::Allocator> tmp_sysmem_;

  // Held here temporarily until DeviceFidl is ready to handle errors so we can
  // bind.
  fidl::InterfaceRequest<fuchsia::media::StreamProcessor> tmp_interface_request_;

  // This binding doesn't channel-own this CodecImpl.  The DeviceFidl owns all
  // the CodecImpl(s).  The DeviceFidl will SetErrorHandler() such that its
  // ownership drops if the channel fails.  The CodecImpl takes care of cleaning
  // itself up before calling the DeviceFidl's error handler, so that CodecImpl
  // is ready for destruction by the time DeviceFidl's error handler is called.
  fidl::Binding<fuchsia::media::StreamProcessor, CodecImpl*> binding_;

  // This is the zx::channel we get indirectly from binding_.Unbind() (we only
  // need the zx::channel part).  We delay closing the Codec zx::channel until
  // after removing the concurrency tally in ~CodecAdmission, so that a Codec
  // client can try again immediately on noticing channel closure without
  // potentially bouncing off still-existing old CodecAdmission.
  zx::channel codec_to_close_;
  bool was_bind_async_called_ = false;
  // This being true means BindAsync() reached the point where we can and must
  // fail via UnbindLocked() instead of just running the owner's error handler
  // directly.
  bool was_logically_bound_ = false;
  async::Loop stream_control_loop_;
  thrd_t stream_control_thread_ = 0;
  ClosureQueue stream_control_queue_;
  fit::closure owner_error_handler_;
  bool was_unbind_started_ = false;
  bool is_stream_control_done_ = false;
  bool was_unbind_completed_ = false;
  std::condition_variable wake_stream_control_condition_;
  std::condition_variable stream_control_done_condition_;
  std::vector<zx::eventpair> lifetime_tracking_;

  //
  // Codec protocol aspects.
  //

  // Some of the FIDL messages get handled or partly handled on the
  // StreamControl thread.
  void AddInputBuffer_StreamControl(CodecBuffer::Info buffer_info, CodecVmoRange vmo_range);
  void SetInputBufferPartialSettings_StreamControl(
      fuchsia::media::StreamBufferPartialSettings input_partial_settings);
  void FlushEndOfStreamAndCloseStream_StreamControl(uint64_t stream_lifetime_ordinal);
  void CloseCurrentStream_StreamControl(uint64_t stream_lifetime_ordinal,
                                        bool release_input_buffers, bool release_output_buffers);
  void Sync_StreamControl(ThreadSafeDeleter<SyncCallback> callback);
  void QueueInputFormatDetails_StreamControl(uint64_t stream_lifetime_ordinal,
                                             fuchsia::media::FormatDetails format_details);
  void QueueInputPacket_StreamControl(fuchsia::media::Packet packet);
  void QueueInputEndOfStream_StreamControl(uint64_t stream_lifetime_ordinal);
  // This method returns false if input buffers aren't configured enough so far,
  // or if sysmem-based buffers can't be confirmed to be allocated.  On
  // returning false, IsStoppingLocked() will already be true.
  bool CheckWaitEnsureInputConfigured(std::unique_lock<std::mutex>& lock);

  __WARN_UNUSED_RESULT bool IsStreamActiveLocked();

  void SetInputBufferSettingsCommon(
      std::unique_lock<std::mutex>& lock,
      fuchsia::media::StreamBufferPartialSettings* input_partial_settings);

  void SetOutputBufferSettingsCommon(
      std::unique_lock<std::mutex>& lock,
      fuchsia::media::StreamBufferPartialSettings* output_partial_settings);

  void SetBufferSettingsCommon(std::unique_lock<std::mutex>& lock, CodecPort port,
                               fuchsia::media::StreamBufferPartialSettings* partial_settings,
                               const fuchsia::media::StreamBufferConstraints& constraints);
  void EnsureBuffersNotConfigured(std::unique_lock<std::mutex>& lock, CodecPort port);

  // This is just validating that the _partial_ settings set by the client are
  // valid with respect to the constraints indicated to the client, without any
  // involvement of sysmem yet (but soon), so there's not a ton to validate
  // here.
  __WARN_UNUSED_RESULT bool ValidatePartialBufferSettingsVsConstraintsLocked(
      CodecPort port, const fuchsia::media::StreamBufferPartialSettings& partial_settings,
      const fuchsia::media::StreamBufferConstraints& constraints);

  void AddOutputBufferInternal(CodecBuffer::Info buffer_info, CodecVmoRange vmo_range);

  // Returns true if the port is done configuring (last buffer was added).
  // Returns false if the port is not done configuring or if Fail() was called;
  // currently the caller doesn't need to tell the difference between these two
  // very different cases.
  __WARN_UNUSED_RESULT bool AddBufferCommon(CodecBuffer::Info buffer_info, CodecVmoRange vmo_range);

  // Return value of false means FailLocked() has already been called.
  __WARN_UNUSED_RESULT bool CheckOldBufferLifetimeOrdinalLocked(CodecPort port,
                                                                uint64_t buffer_lifetime_ordinal);

  // Return value of false means FailLocked() has already been called.
  __WARN_UNUSED_RESULT bool CheckStreamLifetimeOrdinalLocked(uint64_t stream_lifetime_ordinal);

  // Return value of false means FailLocked() has already been called.
  __WARN_UNUSED_RESULT bool StartNewStream(std::unique_lock<std::mutex>& lock,
                                           uint64_t stream_lifetime_ordinal);
  void EnsureStreamClosed(std::unique_lock<std::mutex>& lock);
  void EnsureCodecStreamClosedLockedInternal();

  // Run all items in the sysmem_completion_queue_.  The item itself is run
  // outside the lock.  Returns true if any completions ran.
  bool RunAnySysmemCompletions(std::unique_lock<std::mutex>& lock);

  // Only sysmem completions get posted this way.  These essentially cut in line
  // before most of the body of all QueueInput...StreamControl methods when
  // those are blocked waiting for sysmem completion.
  void PostSysmemCompletion(fit::closure to_run);
  // Returns false if IsStoppingLocked() is already true - just to save the
  // caller the hassle of checking itself.
  bool WaitEnsureSysmemReadyOnInput(std::unique_lock<std::mutex>& lock);
  void RunAnySysmemCompletionsOrWait(std::unique_lock<std::mutex>& lock);

  bool is_on_stream_failed_enabled_ = false;

  // This is the stream_lifetime_ordinal of the current stream as viewed from
  // StreamControl ordering domain.  This is the stream lifetime ordinal that
  // gets removed from the head of the Stream queue when StreamControl is done
  // with the stream.
  uint64_t stream_lifetime_ordinal_ = 0;
  // This is the stream_lifetime_ordinal of the most recent stream as viewed
  // from the Output ordering domain (FIDL thread).  This is the stream lifetime
  // ordinal that we add to the tail of the Stream queue.
  uint64_t future_stream_lifetime_ordinal_ = 0;

  // The Output ordering domain (FIDL thread) adds items to the tail of this
  // queue, and the StreamControl ordering domain removes items from the head of
  // this queue.  This queue is how the StreamControl ordering domain knows
  // whether a stream is discarded or not.  If a stream isn't discarded then the
  // StreamControl domain can keep waiting for the client to process
  // OnOutputConstraints() for that stream.  If the stream has been discarded,
  // then StreamControl ordering domain cannot expect the client to ever process
  // OnOutputConstraints() for the stream, and the StreamControl ordering domain
  // can instead move on to the next stream.
  //
  // In addition, this can allow the StreamControl ordering domain to skip past
  // stream-specific items for a stream that's already known to be discarded by
  // the client.
  std::list<std::unique_ptr<Stream>> stream_queue_;
  // When no current stream, this is nullptr.  When there is a current stream,
  // this points to that stream, owned by stream_queue_.
  Stream* stream_ = nullptr;

  std::unique_ptr<const fuchsia::media::StreamBufferConstraints> input_constraints_;

  // This holds the most recent settings received from the client and accepted,
  // received via SetInputBufferPartialSettings() or
  // SetOutputBufferPartialSettings(). The settings
  // are retained as-received from the client. We discover some of the settings via
  // sysmem and store those in port_settings_.
  std::unique_ptr<PortSettings> port_settings_[kPortCount];

  // The most recent fully-configured input or output buffers had this
  // buffer_constraints_version_ordinal.  Even when !port_settings_[port], this
  // is used to detect whether the client has yet caught up to the
  // last_required_buffer_constraints_version_ordinal_[port].
  uint64_t last_provided_buffer_constraints_version_ordinal_[kPortCount] = {};

  // For CodecImpl, the initial StreamOutputConstraints can be the first sent
  // message. If sent that early, the StreamOutputConstraints is likely to
  // change again before any output data is emitted, but it _may not_.
  std::unique_ptr<const fuchsia::media::StreamOutputConstraints> output_constraints_;

  // The core codec indicated that it didn't like an output config that had this
  // buffer_constraints_version_ordinal set.  Normally this would lead to
  // mid-stream output format change, but in case the client starts a new stream
  // before that can happen, we go ahead and force the client to provide a newer
  // config with newer buffer_constraints_version_ordinal before we do format
  // detection for the new stream, just in case the core codec would be annoyed
  // if we ignored it's previous indication.  There's no reason to require every
  // core codec to consider how an incomplete mid-stream format change of an old
  // stream interacts with a new stream, so essentially force the mid-stream
  // format change to complete before start of the new stream (as far as the
  // core codec can tell).  The core codec still has to tolerate stopping the
  // old stream before mid-stream format change is complete, so it's possible
  // we'll eventually decide all core codecs need to just consider an incomplete
  // mid-stream format change to be cancelled by stopping the old stream, in
  // which case we could remove this member var.
  uint64_t core_codec_meh_output_buffer_constraints_version_ordinal_ = 0;

  // The server's buffer_lifetime_ordinal, per port.  In contrast to
  // port_settings_[port].buffer_lifetime_ordinal, this value is allowed to be
  // even when the previous odd buffer_lifetime_ordinal is over, due to buffer
  // de-allocation.
  uint64_t buffer_lifetime_ordinal_[kPortCount] = {};

  // This is the buffer_lifetime_ordinal from SetOutputBufferSettings() or
  // SetInputBufferSettings().  This is used for protocol enforcement, to
  // enforce that AddOutputBuffer() or AddInputBuffer() is part of the same
  // buffer_lifetime_ordinal.
  uint64_t protocol_buffer_lifetime_ordinal_[kPortCount] = {};

  // Allocating these values and sending these values are tracked separately,
  // so that we can more tightly enforce the protocol.  If a client tries to
  // act on a newer ordinal before the server has actually sent it, the server
  // will notice that invalid client behavior and close the channel (instead
  // of just tracking a single number, which would potentially let the client
  // drive the server into the weeds).
  //
  // The next value we'll use for output buffer_constraints_version_ordinal and
  // output format_details_version_ordinal.
  uint64_t next_output_buffer_constraints_version_ordinal_ = 1;
  // For format-only changes that don't require buffer re-allocation, we can
  // just increment the format details ordinal.
  uint64_t next_output_format_details_version_ordinal_ = 1;

  // Separately from ordinal allocation, we track the most recent ordinal that
  // we've actually sent to the client, to allow tighter protocol enforcement in
  // case of a hostile client.
  uint64_t sent_buffer_constraints_version_ordinal_[kPortCount] = {};
  uint64_t sent_format_details_version_ordinal_[kPortCount] = {};

  // The server has sent this version ordinal with
  // buffer_constraints_action_required true.  The server can safely ignore any
  // output configuration that's stale vs. this, because the client will soon
  // catch up to at least this version.  This includes a value for input also,
  // for consistency, but this is mainly for output.
  uint64_t last_required_buffer_constraints_version_ordinal_[kPortCount] = {};

  // This is set when stream_.output_end_of_stream is set.
  std::condition_variable output_end_of_stream_seen_;

  // This is a queue of lambdas that are to be run on the StreamControl domain
  // before any further QueueInput... processing on StreamControl.  Even before
  // the sysmem completion is on this queue, QueueInput...StreamControl() will
  // be blocked waiting for sysmem completion to be done, and helping run any
  // items that show up on this queue.
  //
  // This line-cutting queue avoids forcing a round-trip to ensure the client
  // isn't sending any input until after the codec knows about the allocated
  // buffers.  This also avoids un-binding the client's channel while we wait
  // for sysmem allocation to be complete - this is worth avoiding because if we
  // unbind then we also don't find out about PEER_CLOSED which would be at
  // least somewhat problematic if the client didn't also cause sysmem
  // allocation to fail.
  //
  // We use wake_stream_control_condition_ to wake any
  // QueueInput...StreamControl waiter that's blocked and helping run items on
  // this queue, since we of course also have to give up on the wait if we're
  // shutting down, which is an aspect in common with other StreamControl waits
  // so it's convenient to share the condition var.
  std::queue<fit::closure> sysmem_completion_queue_;

  // Avoid re-posting to StreamControl to run sysmem_completion_queue_ items if
  // there's already a posted runner lambda that'll notice a newly-added item.
  bool is_sysmem_runner_pending_ = false;

  //
  // Adapter-related
  //

  // This is called on Output ordering domain (FIDL thread) any time a message
  // is received which would be able to start a new stream.
  //
  // More complete protocol validation happens on StreamControl ordering domain.
  // The validation here is just to validate to degree needed to not break our
  // stream_queue_ and future_stream_lifetime_ordinal_.
  //
  // Returns true if it worked.  Returns false if FailLocked() has already been
  // called, in which case the caller probably wants to just return.
  __WARN_UNUSED_RESULT bool EnsureFutureStreamSeenLocked(uint64_t stream_lifetime_ordinal);

  // This is called on Output ordering domain (FIDL thread) any time a message
  // is received which would close a stream.
  //
  // More complete protocol validation happens on StreamControl ordering domain.
  // The validation here is just to validate to degree needed to not break our
  // stream_queue_ and future_stream_lifetime_ordinal_.
  //
  // Returns true if it worked.  Returns false if FailLocked() has already been
  // called, in which case the caller probably wants to just return.
  __WARN_UNUSED_RESULT bool EnsureFutureStreamCloseSeenLocked(uint64_t stream_lifetime_ordinal);

  // This is called on Output ordering domain (FIDL thread) any time a flush is
  // seen.
  //
  // More complete protocol validation happens on StreamControl ordering domain.
  // The validation here is just to validate to degree needed to not break our
  // stream_queue_ and future_stream_lifetime_ordinal_.
  //
  // Returns true if it worked.  Returns false if FailLocked() has already been
  // called, in which case the caller probably wants to just return.
  __WARN_UNUSED_RESULT bool EnsureFutureStreamFlushSeenLocked(uint64_t stream_lifetime_ordinal);

  void StartIgnoringClientOldOutputConfig(std::unique_lock<std::mutex>& lock);

  void GenerateAndSendNewOutputConstraints(std::unique_lock<std::mutex>& lock,
                                           bool buffer_constraints_action_required);

  void MidStreamOutputConstraintsChange(uint64_t stream_lifetime_ordinal);

  bool FixupBufferCollectionConstraintsLocked(
      CodecPort port, const fuchsia::media::StreamBufferConstraints& stream_buffer_constraints,
      const fuchsia::media::StreamBufferPartialSettings& partial_settings,
      fuchsia::sysmem::BufferCollectionConstraints* buffer_collection_constraints);

  void OnBufferCollectionInfo(CodecPort port, uint64_t buffer_lifetime_ordinal, zx_status_t status,
                              fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info);

  // When this method is called we know we're already on the correct thread per
  // the port.
  void OnBufferCollectionInfoInternal(
      CodecPort port, uint64_t buffer_lifetime_ordinal, zx_status_t allocate_status,
      fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info);

  // This is set if IsCoreCodecHwBased(), so CodecBuffer::Pin() can get the physical address info,
  // so DMA can be done directly from/to BufferCollection buffers.  We cache this just so we're not
  // constantly calling CoreCodecBti().
  zx::unowned_bti core_codec_bti_;

  cpp17::optional<FakeMapRange> fake_map_range_[kPortCount];

  // These are 1:1 with logical CodecBuffer(s).
  std::vector<std::unique_ptr<CodecBuffer>> all_buffers_[kPortCount];

  // For this bool to be true, there must be enough buffers in all_buffers_ and
  // the core codec must also be fully configured with regard to those buffers.
  bool is_port_buffers_configured_[kPortCount] = {};

  // This vector owns these buffers.
  //
  // TODO(dustingreen): Figure out if the HW has any particular interest in
  // packets (such as to avoid dynamic allocation to track queued parts of
  // buffers), or if HW portion of driver is fine just knowing about portions of
  // buffers.
  //
  // These are 1:1 with logical CodecPacket(s).
  std::vector<std::unique_ptr<CodecPacket>> all_packets_[kPortCount];

  //
  // Util aspects.
  //

  // For now, this is device_->driver()->shared_fidl_thread().  It could turn
  // out to be better to not share FIDL threads across Codec instances however.
  thrd_t fidl_thread();

  // Send OnFreeInputPacket() using shared_fidl_thread().  This can be called
  // on any thread other than shared_fidl_thread().
  void SendFreeInputPacketLocked(fuchsia::media::PacketHeader header);

  __WARN_UNUSED_RESULT bool IsInputConfiguredLocked();
  __WARN_UNUSED_RESULT bool IsOutputConfiguredLocked();
  __WARN_UNUSED_RESULT bool IsPortBuffersConfiguredCommonLocked(CodecPort port);

  // Either completely configured one way or another, or at least partially
  // configured using sysmem-style port settings.  Else the client isn't
  // behaving properly.
  __WARN_UNUSED_RESULT bool IsPortBuffersAtLeastPartiallyConfiguredLocked(CodecPort port);

  void vFail(bool is_fatal, const char* format, va_list args);
  void vFailLocked(bool is_fatal, const char* format, va_list args);

  void PostSerial(async_dispatcher_t* async, fit::closure to_run);
  // If |promise_not_on_previously_posted_fidl_thread_lambda| is true, the
  // caller is promising that it's not running in a lambda that was posted to
  // the fidl thread (running in a FIDL dispatch is fine).
  void PostToSharedFidl(fit::closure to_run);
  void PostToStreamControl(fit::closure to_run);
  __WARN_UNUSED_RESULT bool IsStoppingLocked();
  __WARN_UNUSED_RESULT bool IsStopping();

  __WARN_UNUSED_RESULT bool IsDecoder() const;
  __WARN_UNUSED_RESULT bool IsEncoder() const;
  __WARN_UNUSED_RESULT bool IsDecryptor() const;

  __WARN_UNUSED_RESULT const fuchsia::mediacodec::CreateDecoder_Params& decoder_params() const;
  __WARN_UNUSED_RESULT const fuchsia::mediacodec::CreateEncoder_Params& encoder_params() const;
  __WARN_UNUSED_RESULT const fuchsia::media::drm::DecryptorParams& decryptor_params() const;

  void LogEvent(media_metrics::StreamProcessorEvents2MetricDimensionEvent event_code) const;

  //
  // Core codec interfacing.
  //

  // true - maybe it's the core codec thread.
  // false - it's definitely not the core codec thread.
  __WARN_UNUSED_RESULT bool IsPotentiallyCoreCodecThread();

  void HandlePendingInputFormatDetails();

  // Only tell the core codec to ensure any current stream is stopped if
  // CoreCodecInit() was ever called.
  bool is_core_codec_init_called_ = false;

  bool is_core_codec_stream_started_ = false;

  //
  // For use by core codec:
  //

  // If the core codec needs to fail the whole CodecImpl, such as when/if new
  // FormatDetails are different than the initial FormatDetails and
  // the core codec doesn't support switching from the old to the new input
  // format details (for example due to needing different input buffer config).
  void onCoreCodecFailCodec(const char* format, ...) override;

  // The core codec should only call this method at times when there is a
  // current stream, not between streams.
  void onCoreCodecFailStream(fuchsia::media::StreamError error) override;

  void onCoreCodecResetStreamAfterCurrentFrame() override;

  // "Mid-stream" can mean at the start of a stream also - it's just required
  // that a stream be active currently.  The core codec must ensure that this
  // call is properly ordered with respect to onCoreCodecOutputPacket() and
  // onCoreCodecOutputEndOfStream() calls.
  //
  // A call to onCoreCodecMidStreamOutputConstraintsChange(true) must not be
  // followed by any more output (including EndOfStream) until the associated
  // output re-config is completed by a call to
  // CoreCodecMidStreamOutputBufferReConfigFinish().
  void onCoreCodecMidStreamOutputConstraintsChange(bool output_re_config_required) override;

  void onCoreCodecOutputFormatChange() override;

  void onCoreCodecInputPacketDone(CodecPacket* packet) override;

  void onCoreCodecOutputPacket(CodecPacket* packet, bool error_detected_before,
                               bool error_detected_during) override;

  void onCoreCodecOutputEndOfStream(bool error_detected_before) override;

  void onCoreCodecLogEvent(
      media_metrics::StreamProcessorEvents2MetricDimensionEvent event_code) override;

  //
  // Core codec.
  //
  // These are here to cleanly do a few asserts as we call out to the
  // codec_adapter_, and to make call sites look a bit nicer.
  //

  __WARN_UNUSED_RESULT
  std::optional<media_metrics::StreamProcessorEvents2MetricDimensionImplementation>
  CoreCodecMetricsImplementation() override;

  __WARN_UNUSED_RESULT bool IsCoreCodecRequiringOutputConfigForFormatDetection() override;

  __WARN_UNUSED_RESULT bool IsCoreCodecMappedBufferUseful(CodecPort port) override;

  __WARN_UNUSED_RESULT bool IsCoreCodecHwBased(CodecPort port) override;

  __WARN_UNUSED_RESULT zx::unowned_bti CoreCodecBti() override;

  void CoreCodecInit(const fuchsia::media::FormatDetails& initial_input_format_details) override;

  void CoreCodecSetSecureMemoryMode(
      CodecPort port, fuchsia::mediacodec::SecureMemoryMode secure_memory_mode) override;

  fuchsia::sysmem::BufferCollectionConstraints CoreCodecGetBufferCollectionConstraints(
      CodecPort port, const fuchsia::media::StreamBufferConstraints& stream_buffer_constraints,
      const fuchsia::media::StreamBufferPartialSettings& partial_settings) override;

  void CoreCodecSetBufferCollectionInfo(
      CodecPort port,
      const fuchsia::sysmem::BufferCollectionInfo_2& buffer_collection_info) override;

  fuchsia::media::StreamOutputFormat CoreCodecGetOutputFormat(
      uint64_t stream_lifetime_ordinal,
      uint64_t new_output_format_details_version_ordinal) override;

  void CoreCodecStartStream() override;

  void CoreCodecQueueInputFormatDetails(
      const fuchsia::media::FormatDetails& per_stream_override_format_details) override;

  void CoreCodecQueueInputPacket(CodecPacket* packet) override;

  void CoreCodecQueueInputEndOfStream() override;

  void CoreCodecStopStream() override;

  void CoreCodecResetStreamAfterCurrentFrame() override;

  void CoreCodecAddBuffer(CodecPort port, const CodecBuffer* buffer) override;

  void CoreCodecConfigureBuffers(CodecPort port,
                                 const std::vector<std::unique_ptr<CodecPacket>>& packets) override;

  void CoreCodecRecycleOutputPacket(CodecPacket* packet) override;

  void CoreCodecEnsureBuffersNotConfigured(CodecPort port) override;

  __WARN_UNUSED_RESULT
  std::unique_ptr<const fuchsia::media::StreamBufferConstraints> CoreCodecBuildNewInputConstraints()
      override;

  __WARN_UNUSED_RESULT
  std::unique_ptr<const fuchsia::media::StreamOutputConstraints> CoreCodecBuildNewOutputConstraints(
      uint64_t stream_lifetime_ordinal, uint64_t new_output_buffer_constraints_version_ordinal,
      bool buffer_constraints_action_required) override;

  void CoreCodecMidStreamOutputBufferReConfigPrepare() override;

  void CoreCodecMidStreamOutputBufferReConfigFinish() override;

  CodecImpl() = delete;
  CodecImpl(CodecImpl& to_copy) = delete;
  CodecImpl(CodecImpl&& to_move) = delete;
  CodecImpl& operator=(CodecImpl& to_assign) = delete;
};

#endif  // SRC_MEDIA_LIB_CODEC_IMPL_INCLUDE_LIB_MEDIA_CODEC_IMPL_CODEC_IMPL_H_
