// 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 GARNET_LIB_MEDIA_TEST_INCLUDE_LIB_MEDIA_TEST_CODEC_CLIENT_H_
#define GARNET_LIB_MEDIA_TEST_INCLUDE_LIB_MEDIA_TEST_CODEC_CLIENT_H_

#include "codec_buffer.h"
#include "codec_output.h"

#include <fuchsia/mediacodec/cpp/fidl.h>

#include <lib/async-loop/cpp/loop.h>
#include <lib/fidl/cpp/binding.h>

#include <list>

// This class is just _a_ codec client, and should be read as an example only,
// and probably not a fully complete example either.  This class is just here
// to organize the code involved in setting up a Codec with input buffers and
// packets, feeding it input data in a single Stream, setting up the output
// buffers and packets, and ensuring that all input data is processed into
// output.
//
// A Codec client that wants to seek a logical stream or re-use a Codec to
// decode another logical stream would likely want to make more use of the
// stream_lifetime_ordinal to feed input data and to accept output data (vs.
// this example which has only one Stream lifetime which isn't visible outside
// this class. Re-using a Codec instance for a new stream is encouraged,
// especially when the output format isn't likely to change from stream to
// stream, which avoids re-configuring output buffers across the stream switch.
//
// The use of particular threads of execution to call this class is intended to
// clarify reasonable ordering and concurrency of messages sent and processed on
// the Codec interface.  There is no requirement that a Codec client use
// dedicated threads to achieve a permitted and useful ordering. The client does
// of course need to stay within the sequencing rules of the interface.
class CodecClient {
 public:
  // loop - The loop that all the FIDL work will run on.  We configure this
  // explicitly instead of using the default loop per thread mechanism, because
  // we want to be very sure that we'll be posting to the correct loop to send
  // messages using that loop's single thread, as ProxyController doesn't have
  // a lock_ in it.
  CodecClient(async::Loop* loop, fidl::InterfaceHandle<fuchsia::sysmem::Allocator> sysmem);
  ~CodecClient();

  // Separate from Start() because we don't wan this class to handle the Codec
  // creation, so the caller needs a server endpoint to send off to a Codec
  // server (via the CodecFactory).
  fidl::InterfaceRequest<fuchsia::media::StreamProcessor> GetTheRequestOnce();

  // Get the Codec into a state where it's ready to process input data.
  void Start();

  // On this thread, wait for an available input packet_index, and when one is
  // available, create a new Packet object to represent that packet_index
  // and return that.  The packet_index will be filled out, but not the rest of
  // the packet.  It's up to the caller to set stream_lifetime_ordinal and other
  // fields.
  //
  // Since in this example we're using a buffer per packet, waiting for a free
  // packet is also waiting for a free buffer, with the same index as
  // packet_index.
  //
  // To return eventually, this call relies on output being accepted on an
  // ongoing basis from the Codec using some other thread(s), processed, and
  // those output packets freed back to the codec.
  std::unique_ptr<fuchsia::media::Packet> BlockingGetFreeInputPacket();

  const CodecBuffer& GetInputBufferByIndex(uint32_t packet_index);
  const CodecBuffer& GetOutputBufferByIndex(uint32_t packet_index);

  void QueueInputFormatDetails(
      uint64_t stream_lifetime_ordinal,
      fuchsia::media::FormatDetails input_format_details);

  // Queue an input packet to the codec.
  void QueueInputPacket(std::unique_ptr<fuchsia::media::Packet> packet);

  void QueueInputEndOfStream(uint64_t stream_lifetime_ordinal);

  void FlushEndOfStreamAndCloseStream(uint64_t stream_lifetime_ordinal);

  // Use the current thread to do what is necessary to get an output packet.
  // Near the start, this will include configuring output buffers once.  In
  // steady state this thread will just wait for an output packet to show up or
  // the stream to be done.  If an end_of_stream packet shows up, this method
  // will return that packet.
  //
  // The returned Packet itself will remain valid and readable as long as
  // the caller keeps it around.  However, if the caller calls
  // BlockingGetEmittedOutput() again, the entire set of output buffers
  // can get deallocated and replacement buffers allocated, rendering the
  // meaning of the returned Packet only usable until
  // BlockingGetEmittedOutput() is called again.  This means the calling
  // code needs to go ahead and do whatever it wants to do with the output
  // data in the corresponding output buffer before calling this method again.
  //
  // A real client can delay output buffer re-configuration until previous
  // output data has been fully processed, or can ensure that old output buffers
  // remain live until the old output data is done with them (configuring new
  // output buffers doesn't inherently delete the old ones, but having both
  // around at once does use more resources concurrently).
  std::unique_ptr<CodecOutput> BlockingGetEmittedOutput();

  // Recycle an output packet for re-use.
  void RecycleOutputPacket(fuchsia::media::PacketHeader free_packet);

  void Stop();

  // On this thread, while the codec is being fed input data on
 private:
  friend class CodecStream;

  void PostToFidlThread(fit::closure to_run);

  void CallSyncAndWaitForResponse();

  void TrackOutputStreamLifetimeOrdinal(
      uint64_t output_stream_lifetime_ordinal);

  bool CreateAndSyncBufferCollection(
      fuchsia::sysmem::BufferCollectionSyncPtr* out_buffer_collection,
      fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken>*
          out_codec_sysmem_token);

  bool WaitForSysmemBuffersAllocated(
      fuchsia::sysmem::BufferCollectionSyncPtr* buffer_collection_param,
      fuchsia::sysmem::BufferCollectionInfo_2* out_buffer_collection_info);

  bool ConfigurePortBufferCollection(
      bool is_output, uint64_t new_buffer_lifetime_ordinal,
      uint64_t buffer_constraints_version_ordinal,
      uint32_t packet_count_for_server, uint32_t packet_count_for_client,
      uint32_t* out_packet_count,
      fuchsia::sysmem::BufferCollectionPtr* out_buffer_collection,
      fuchsia::sysmem::BufferCollectionInfo_2* out_buffer_collection_info);

  //
  // Events:
  //

  void OnStreamFailed(uint64_t stream_lifetime_ordinal);

  void OnInputConstraints(
      fuchsia::media::StreamBufferConstraints input_constraints);
  void OnFreeInputPacket(fuchsia::media::PacketHeader free_input_packet);

  // This example ignores any buffer constraints with
  // buffer_constraints_action_required false.
  //
  // As with any proper Codec client we must tolerate this event getting sent by
  // the server more times than would be necessary if it were only for the
  // client's benefit.  The server is allowed to force an output buffer
  // re-configuration just because it wants one.  This rule simplifies some
  // codec server implementations substantially and allows increased coverage of
  // format change handling in clients, at least in the sense of ever seeing
  // more than one of this message per Codec instance (though not quite to the
  // degree needed to fully cover client handling of true mid-stream format
  // changes).
  void OnOutputConstraints(
      fuchsia::media::StreamOutputConstraints output_config);

  // Ever output format is stream-specific with stream_lifetime_ordinal set, and
  // the server is required to elide any unnecessary OnOutputFormat messages
  // without any subsequent OnOutputPacket message to which the OnOutputFormat
  // applies.  The format continues to apply to all subsequent output packets of
  // the same stream until the stream ends or a new OnOutputFormat message is
  // sent by the server.
  void OnOutputFormat(
      fuchsia::media::StreamOutputFormat output_format);

  // Every output packet is stream-specific with stream_lifetime_ordinal set.
  void OnOutputPacket(fuchsia::media::Packet output_packet,
                      bool error_detected_before, bool error_detected_during);

  void OnOutputEndOfStream(uint64_t stream_lifetime_ordinal,
                           bool error_detected_before);
  std::mutex lock_;
  async::Loop* loop_ = nullptr;               // must override
  async_dispatcher_t* dispatcher_ = nullptr;  // must override
  fuchsia::media::StreamProcessorPtr codec_;
  // This only temporarily holds the Codec request that was created during the
  // constructor.  If the caller asks for this more than once, the subsequent
  // requests give back a !is_valid() request.
  fidl::InterfaceRequest<fuchsia::media::StreamProcessor> temp_codec_request_;

  fuchsia::sysmem::AllocatorPtr sysmem_;

  fuchsia::sysmem::BufferCollectionPtr input_buffer_collection_;
  fuchsia::sysmem::BufferCollectionPtr output_buffer_collection_;

  // We're use unique_ptr<> here only for it's optional-ness.
  std::unique_ptr<fuchsia::media::StreamBufferConstraints> input_constraints_;
  std::condition_variable input_constraints_exist_condition_;

  // In this example, we use buffer-per-packet mode, but for input buffers it
  // is allowed to share parts of a single buffer across all input packets.
  // This example doesn't yet demonstrate that mode however.
  //
  // TODO(dustingreen): There's not presently any input mode that allows any
  // packet to refer to any of a set of multiple buffers, but if we think that
  // would be of any real use, we could add it.  Either add that mode to Codec
  // interface and down, or remove this comment.
  //
  // The index into the vector is the same as packet_id, since we're running in
  // buffer-per-packet mode.
  std::vector<std::unique_ptr<CodecBuffer>> all_input_buffers_;
  // We don't even create the output buffers until after the output format is
  // known, which can require some input data first.
  std::vector<std::unique_ptr<CodecBuffer>> all_output_buffers_;

  // In contrast to buffers, packets don't really exist in full continuously.
  // The set of packet_index values is a thing, but each packet_index re-use is
  // really best thought of as a new fuchsia::media::Packet lifetime,
  // so that's how we represent the packets in this example - as created and
  // owned by their input and output arcs, not kept allocated continuously by
  // CodecClient.

  // This vector is used to track which input packet_id(s) are free.  A free
  // packet_id means the buffer at all_input_buffers_[packet_id] is free.  We
  // push to the end and pop from the end since that's what vector<> is good at.
  std::vector<uint32_t> input_free_list_;
  std::condition_variable input_free_list_not_empty_;

  // In this example, we do verify that the server is being sane with respect
  // to free/busy status of packets.  In general a client shouldn't let a
  // badly-behaved server cause the client to crash.
  //
  // true - free
  // false - not free (from when we queue a lambda that'll end up sending the
  //   packet to the codec, to when we receive the message from the codec saying
  //   the packet is free again)
  std::vector<bool> input_free_bits_;

  // Which output packets are free from the client point of view.  If the server
  // tries to emit the same packet more than once concurrently, these bits are
  // how we notice.
  std::vector<bool> output_free_bits_;

  // The server must order its output strictly by stream_lifetime_ordinal - once
  // a new stream_lifetime_ordinal has started the server can't output anything
  // with an older stream_lifetime_ordinal.
  uint64_t output_stream_lifetime_ordinal_ = 0;

  // In contrast to free input packets, we care about the content of emitted
  // output packets and their order.  In addition, OnOutputConstraints() is ordered
  // with respect to output packets, so we just queue those along with the
  // output packets to avoid any ambiguity.
  //
  // A client that is immediately processing every output packet and just tracks
  // the most recent output config would work as long as it always associates
  // an output packet with the closest prior StreamOutputConstraints.
  std::list<std::unique_ptr<CodecOutput>> emitted_output_;

  // For input, in this example we just know what the input format details are
  // and we send those to CodecFactory as part of CreateAudioDecoder_Params,
  // so we don't really need them as a member variable.

  // For output, we have StreamOutputConstraints here as a shared_ptr<> so we can
  // explicitly associate each output packet with the config that applies to the
  // output packet.
  //
  // Note that stream_lifetime_ordinal is nearly entirely orthogonal from which
  // config applies.  The only interaction is that sometimes a new stream will
  // happen to have a different format so will cause format_details to update.
  std::shared_ptr<const fuchsia::media::StreamOutputConstraints> last_output_constraints_;
  std::shared_ptr<const fuchsia::media::StreamOutputConstraints>
      last_required_output_constraints_;
  // Most non-test clients will want to track this per-stream, since a
  // StreamOutputFormat from an old stream_lifetime_ordinal() isn't relevant to
  // the current stream_lifetime_ordinal.  A server is not allowed to send
  // OnOutputFormat for an old stream_lifetime_ordinal.
  std::shared_ptr<const fuchsia::media::StreamOutputFormat> last_output_format_;
  // True if OnOutputFormat is more recent than OnOutputPacket.  This is
  // intentionally tracked regardless of whether last_output_format_ has
  // since been "forgotten" (set to nullptr) and regardless of whether the
  // stream has since switched to a new stream, because we require servers to
  // elide all unnecessary OnOutputFormat messages.  An OnOutputFormat without
  // any subsequent OnOutputPacket of the same stream is by definition
  // unnecessary.
  bool is_format_since_last_packet_ = false;
  // Becomes true when we get a new last_output_constraints_ with action
  // required, and becomes false just before taking the needed action based on
  // last_output_constraints_.
  bool output_constraints_action_pending_ = false;
  // Only odd values are allowed for buffer_lifetime_ordinal.
  uint64_t next_output_buffer_lifetime_ordinal_ = 1;
  uint64_t current_output_buffer_lifetime_ordinal_ = 0;

  // Invariant:
  // output_pending_ == (!emitted_output_.empty() ||
  // output_config_action_pending_)
  bool ComputeOutputPendingLocked() {
    return !emitted_output_.empty() || output_constraints_action_pending_;
  }
  bool output_pending_ = false;
  std::condition_variable output_pending_condition_;
};

#endif  // GARNET_LIB_MEDIA_TEST_INCLUDE_LIB_MEDIA_TEST_CODEC_CLIENT_H_
