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