Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / base / video_frame_pool.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/base/video_frame_pool.h"
6
7 #include <list>
8
9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/synchronization/lock.h"
12
13 namespace media {
14
15 class VideoFramePool::PoolImpl
16     : public base::RefCountedThreadSafe<VideoFramePool::PoolImpl> {
17  public:
18   PoolImpl();
19
20   // Returns a frame from the pool that matches the specified
21   // parameters or creates a new frame if no suitable frame exists in
22   // the pool. The pool is drained if no matching frame is found.
23   scoped_refptr<VideoFrame> CreateFrame(VideoFrame::Format format,
24                                         const gfx::Size& coded_size,
25                                         const gfx::Rect& visible_rect,
26                                         const gfx::Size& natural_size,
27                                         base::TimeDelta timestamp);
28
29   // Shuts down the frame pool and releases all frames in |frames_|.
30   // Once this is called frames will no longer be inserted back into
31   // |frames_|.
32   void Shutdown();
33
34   size_t GetPoolSizeForTesting() const { return frames_.size(); }
35
36  private:
37   friend class base::RefCountedThreadSafe<VideoFramePool::PoolImpl>;
38   ~PoolImpl();
39
40   // Called when the frame wrapper gets destroyed.
41   // |frame| is the actual frame that was wrapped and is placed
42   // in |frames_| by this function so it can be reused.
43   void FrameReleased(const scoped_refptr<VideoFrame>& frame);
44
45   base::Lock lock_;
46   bool is_shutdown_;
47   std::list<scoped_refptr<VideoFrame> > frames_;
48
49   DISALLOW_COPY_AND_ASSIGN(PoolImpl);
50 };
51
52 VideoFramePool::PoolImpl::PoolImpl() : is_shutdown_(false) {}
53
54 VideoFramePool::PoolImpl::~PoolImpl() {
55   DCHECK(is_shutdown_);
56 }
57
58 scoped_refptr<VideoFrame> VideoFramePool::PoolImpl::CreateFrame(
59     VideoFrame::Format format,
60     const gfx::Size& coded_size,
61     const gfx::Rect& visible_rect,
62     const gfx::Size& natural_size,
63     base::TimeDelta timestamp) {
64   base::AutoLock auto_lock(lock_);
65   DCHECK(!is_shutdown_);
66
67   scoped_refptr<VideoFrame> frame;
68
69   while (!frame && !frames_.empty()) {
70       scoped_refptr<VideoFrame> pool_frame = frames_.front();
71       frames_.pop_front();
72
73       if (pool_frame->format() == format &&
74           pool_frame->coded_size() == coded_size &&
75           pool_frame->visible_rect() == visible_rect &&
76           pool_frame->natural_size() == natural_size) {
77         frame = pool_frame;
78         frame->set_timestamp(timestamp);
79         break;
80       }
81   }
82
83   if (!frame) {
84     frame = VideoFrame::CreateFrame(
85         format, coded_size, visible_rect, natural_size, timestamp);
86   }
87
88   return VideoFrame::WrapVideoFrame(
89       frame, frame->visible_rect(), frame->natural_size(),
90       base::Bind(&VideoFramePool::PoolImpl::FrameReleased, this, frame));
91 }
92
93 void VideoFramePool::PoolImpl::Shutdown() {
94   base::AutoLock auto_lock(lock_);
95   is_shutdown_ = true;
96   frames_.clear();
97 }
98
99 void VideoFramePool::PoolImpl::FrameReleased(
100     const scoped_refptr<VideoFrame>& frame) {
101   base::AutoLock auto_lock(lock_);
102   if (is_shutdown_)
103     return;
104
105   frames_.push_back(frame);
106 }
107
108 VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) {
109 }
110
111 VideoFramePool::~VideoFramePool() {
112   pool_->Shutdown();
113 }
114
115 scoped_refptr<VideoFrame> VideoFramePool::CreateFrame(
116     VideoFrame::Format format,
117     const gfx::Size& coded_size,
118     const gfx::Rect& visible_rect,
119     const gfx::Size& natural_size,
120     base::TimeDelta timestamp) {
121   return pool_->CreateFrame(format, coded_size, visible_rect, natural_size,
122                             timestamp);
123 }
124
125 size_t VideoFramePool::GetPoolSizeForTesting() const {
126   return pool_->GetPoolSizeForTesting();
127 }
128
129 }  // namespace media