// Copyright 2013 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/base/video_frame_pool.h"

#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/default_tick_clock.h"

namespace media {

class VideoFramePool::PoolImpl
    : public base::RefCountedThreadSafe<VideoFramePool::PoolImpl> {
 public:
  PoolImpl();

  // See VideoFramePool::CreateFrame() for usage. Attempts to keep |frames_| in
  // LRU order by always pulling from the back of |frames_|.
  scoped_refptr<VideoFrame> CreateFrame(VideoPixelFormat format,
                                        const gfx::Size& coded_size,
                                        const gfx::Rect& visible_rect,
                                        const gfx::Size& natural_size,
                                        base::TimeDelta timestamp);

  // Shuts down the frame pool and releases all frames in |frames_|.
  // Once this is called frames will no longer be inserted back into
  // |frames_|.
  void Shutdown();

  size_t get_pool_size_for_testing() {
    base::AutoLock auto_lock(lock_);
    return frames_.size();
  }

  void set_tick_clock_for_testing(const base::TickClock* tick_clock) {
    tick_clock_ = tick_clock;
  }

 private:
  friend class base::RefCountedThreadSafe<VideoFramePool::PoolImpl>;
  ~PoolImpl();

  // Called when the frame wrapper gets destroyed. |frame| is the actual frame
  // that was wrapped and is placed in |frames_| by this function so it can be
  // reused. This will attempt to expire frames that haven't been used in some
  // time. It relies on |frames_| being in LRU order with the front being the
  // least recently used entry.
  void FrameReleased(scoped_refptr<VideoFrame> frame);

  base::Lock lock_;
  bool is_shutdown_ GUARDED_BY(lock_) = false;

  struct FrameEntry {
    base::TimeTicks last_use_time;
    scoped_refptr<VideoFrame> frame;
  };

  base::circular_deque<FrameEntry> frames_ GUARDED_BY(lock_);

  // |tick_clock_| is always a DefaultTickClock outside of testing.
  const base::TickClock* tick_clock_;

  DISALLOW_COPY_AND_ASSIGN(PoolImpl);
};

VideoFramePool::PoolImpl::PoolImpl()
    : tick_clock_(base::DefaultTickClock::GetInstance()) {}

VideoFramePool::PoolImpl::~PoolImpl() {
  DCHECK(is_shutdown_);
}

scoped_refptr<VideoFrame> VideoFramePool::PoolImpl::CreateFrame(
    VideoPixelFormat format,
    const gfx::Size& coded_size,
    const gfx::Rect& visible_rect,
    const gfx::Size& natural_size,
    base::TimeDelta timestamp) {
  base::AutoLock auto_lock(lock_);
  DCHECK(!is_shutdown_);

  scoped_refptr<VideoFrame> frame;
  while (!frame && !frames_.empty()) {
    scoped_refptr<VideoFrame> pool_frame = std::move(frames_.back().frame);
    frames_.pop_back();

    if (pool_frame->format() == format &&
        pool_frame->coded_size() == coded_size &&
        pool_frame->visible_rect() == visible_rect &&
        pool_frame->natural_size() == natural_size) {
      frame = pool_frame;
      frame->set_timestamp(timestamp);
      frame->metadata()->Clear();
      break;
    }
  }

  if (!frame) {
    frame = VideoFrame::CreateZeroInitializedFrame(
        format, coded_size, visible_rect, natural_size, timestamp);
    // This can happen if the arguments are not valid.
    if (!frame) {
      LOG(ERROR) << "Failed to create a video frame";
      return nullptr;
    }
  }

  scoped_refptr<VideoFrame> wrapped_frame = VideoFrame::WrapVideoFrame(
      *frame, frame->format(), frame->visible_rect(), frame->natural_size());
  wrapped_frame->AddDestructionObserver(base::Bind(
      &VideoFramePool::PoolImpl::FrameReleased, this, std::move(frame)));
  return wrapped_frame;
}

void VideoFramePool::PoolImpl::Shutdown() {
  base::AutoLock auto_lock(lock_);
  is_shutdown_ = true;
  frames_.clear();
}

void VideoFramePool::PoolImpl::FrameReleased(scoped_refptr<VideoFrame> frame) {
  base::AutoLock auto_lock(lock_);
  if (is_shutdown_)
    return;

  const base::TimeTicks now = tick_clock_->NowTicks();
  frames_.push_back({now, std::move(frame)});

  // After this loop, |stale_index| is the index of the oldest non-stale frame.
  // Such an index must exist because |frame| is never stale.
  int stale_index = -1;
  constexpr base::TimeDelta kStaleFrameLimit = base::TimeDelta::FromSeconds(10);
  while (now - frames_[++stale_index].last_use_time > kStaleFrameLimit) {
    // Last frame should never be included since we just added it.
    DCHECK_LE(static_cast<size_t>(stale_index), frames_.size());
  }

  if (stale_index)
    frames_.erase(frames_.begin(), frames_.begin() + stale_index);
}

VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) {}

VideoFramePool::~VideoFramePool() {
  pool_->Shutdown();
}

scoped_refptr<VideoFrame> VideoFramePool::CreateFrame(
    VideoPixelFormat format,
    const gfx::Size& coded_size,
    const gfx::Rect& visible_rect,
    const gfx::Size& natural_size,
    base::TimeDelta timestamp) {
  return pool_->CreateFrame(format, coded_size, visible_rect, natural_size,
                            timestamp);
}

size_t VideoFramePool::GetPoolSizeForTesting() const {
  return pool_->get_pool_size_for_testing();
}

void VideoFramePool::SetTickClockForTesting(const base::TickClock* tick_clock) {
  pool_->set_tick_clock_for_testing(tick_clock);
}

}  // namespace media
