Index: media/base/video_frame_pool.cc |
diff --git a/media/base/video_frame_pool.cc b/media/base/video_frame_pool.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4c5a5e31e22d1a6ab64b7c852299640ae7f8e3df |
--- /dev/null |
+++ b/media/base/video_frame_pool.cc |
@@ -0,0 +1,128 @@ |
+// 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 <list> |
+ |
+#include "base/bind.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/synchronization/lock.h" |
+ |
+namespace media { |
+ |
+class VideoFramePool::PoolImpl |
+ : public base::RefCountedThreadSafe<VideoFramePool::PoolImpl> { |
+ public: |
+ PoolImpl(); |
+ |
+ // Returns a frame from the pool that matches the specified |
+ // parameters or creates a new frame if no suitable frame exists in |
+ // the pool. The pool is drained if no matching frame is found. |
+ scoped_refptr<VideoFrame> CreateFrame(VideoFrame::Format 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 GetPoolSizeForTesting() const { return frames_.size(); } |
+ |
+ 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. |
+ void FrameReleased(const scoped_refptr<VideoFrame>& frame); |
+ |
+ base::Lock lock_; |
+ bool is_shutdown_; |
+ std::list<scoped_refptr<VideoFrame> > frames_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PoolImpl); |
+}; |
+ |
+VideoFramePool::PoolImpl::PoolImpl() : is_shutdown_(false) {} |
+ |
+VideoFramePool::PoolImpl::~PoolImpl() { |
+ DCHECK(is_shutdown_); |
+} |
+ |
+scoped_refptr<VideoFrame> VideoFramePool::PoolImpl::CreateFrame( |
+ VideoFrame::Format 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 = frames_.front(); |
+ frames_.pop_front(); |
+ |
+ 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->SetTimestamp(kNoTimestamp()); |
+ break; |
+ } |
+ } |
+ |
+ if (!frame) { |
+ frame = VideoFrame::CreateFrame( |
+ format, coded_size, visible_rect, natural_size, kNoTimestamp()); |
+ } |
+ |
+ return VideoFrame::WrapVideoFrame( |
+ frame, base::Bind(&VideoFramePool::PoolImpl::FrameReleased, this, frame)); |
+} |
+ |
+void VideoFramePool::PoolImpl::Shutdown() { |
+ base::AutoLock auto_lock(lock_); |
+ is_shutdown_ = true; |
+ frames_.clear(); |
+} |
+ |
+void VideoFramePool::PoolImpl::FrameReleased( |
+ const scoped_refptr<VideoFrame>& frame) { |
+ base::AutoLock auto_lock(lock_); |
+ if (is_shutdown_) |
+ return; |
+ |
+ frames_.push_back(frame); |
+} |
+ |
+VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) { |
+} |
+ |
+VideoFramePool::~VideoFramePool() { |
+ pool_->Shutdown(); |
+} |
+ |
+scoped_refptr<VideoFrame> VideoFramePool::CreateFrame( |
+ VideoFrame::Format 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_->GetPoolSizeForTesting(); |
+} |
+ |
+} // namespace media |