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

#ifndef SERVICES_MEDIA_COMMON_RATE_CONTROL_BASE_H_
#define SERVICES_MEDIA_COMMON_RATE_CONTROL_BASE_H_

#include <deque>

#include "base/synchronization/lock.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/services/media/common/cpp/linear_transform.h"
#include "mojo/services/media/common/interfaces/media_common.mojom.h"
#include "mojo/services/media/common/interfaces/rate_control.mojom.h"

namespace mojo {
namespace media {

class RateControlBase : public RateControl {
 public:
  // Default constructor and destructor
  RateControlBase();
  ~RateControlBase() override;

  bool Bind(InterfaceRequest<RateControl> request);
  bool is_bound() const { return binding_.is_bound(); }

  // Close any existing connections to clients, clear any pending rate changes
  // and set the clock rate to 0/1.
  void Reset();

  // TODO(johngro): snapshotting the current transform requires an evaluation of
  // all the pending timeline transformations.  Currently, we allow users to
  // schedule an arbitrary number of pending transformations.  This could cause
  // DoS hazards if a malicious (or just poorly written) application is
  // schedules a ton of transformations, and then something like the mixer
  // threads in the audio server is forced to collapse all of these
  // transformations in order to mix then next set of outbound audio frames.
  //
  // A simple way to avoid this would be to allow the user to have only one
  // pending transformation at any point in time.
  //
  // It would be nice to be able to simply return the transformation and use
  // Rvalue references in calling code to access the temporary snapshot, but
  // style does not permit us to use Rvalue references in such a way.
  //
  // Also; the way pending transformations get applied probably needs to be
  // re-worked.  Currently, when we snapshot, we collapse any pending
  // transformations which should have occurred relative to LocalClock::now()
  // into the current transformation.  For both video and audio, however, we are
  // always mixing/composing for a point in time in the near future, not for
  // right now.  We really want to given the mixer compositor a view of what the
  // transformation is going to be at the mix/composition point, not what it is
  // now.  Additionally, since audio process many frames at a time, we need to
  // give the audio mixer some knowledge of when we think the snapshotted
  // transformation is going to change next.  The audio mixer wants to mix up to
  // that point, but not past it, and then fetch the new transformation before
  // proceeding.
  void SnapshotCurrentTransform(LinearTransform* out,
                                uint32_t* generation = nullptr);

  // RateControl interface
  //
  void GetCurrentTransform(const GetCurrentTransformCallback& cbk) override;
  void SetTargetTimelineID(uint32_t id) override;
  void SetCurrentQuad(TimelineQuadPtr quad) override;
  void SetRate(int32_t reference_delta, uint32_t target_delta) override;
  void SetRateAtReferenceTime(int32_t  reference_delta,
                              uint32_t target_delta,
                              int64_t  reference_time) override;
  void SetRateAtTargetTime(int32_t  reference_delta,
                           uint32_t target_delta,
                           int64_t  target_time) override;
  void CancelPendingChanges() override;

 protected:
  void ApplyPendingChangesLocked(int64_t target_now);
  void AdvanceGenerationLocked() {
    // bump the generation counter.  Do not use the value 0.
    while (!(++generation_)) {}
  }
  void OnIllegalRateChange(int32_t numerator, uint32_t denominator);

  Binding<RateControl> binding_;
  uint32_t target_timeline_id = TimelineTransform::kLocalTimeID;

  //  Transformation state.
  //
  //  Note: We use the LinearTransforms such that space A is the target timeline
  //  and space B is the reference timeline.  Applying this convention,
  //  transforming from target to reference is the "forward" transformation and
  //  is always defined.  Transforming from reference to target is the "reverse"
  //  transformation, and is only defined when we are not paused.
  //  <pedantic>
  //  OK; It is defined, but the equation has a singularity and the mapping is
  //  not 1-to-1.
  //  </pedantic>.
  base::Lock transform_lock_;
  LinearTransform current_transform_;
  std::deque<LinearTransform> reference_pending_changes_;
  std::deque<LinearTransform> target_pending_changes_;
  uint32_t generation_ = 1;
};

}  // namespace media
}  // namespace mojo

#endif  // SERVICES_MEDIA_COMMON_RATE_CONTROL_BASE_H_
