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.
5 #include "media/base/video_frame_pool.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/synchronization/lock.h"
15 class VideoFramePool::PoolImpl
16 : public base::RefCountedThreadSafe
<VideoFramePool::PoolImpl
> {
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
);
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
34 size_t GetPoolSizeForTesting() const { return frames_
.size(); }
37 friend class base::RefCountedThreadSafe
<VideoFramePool::PoolImpl
>;
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
);
47 std::list
<scoped_refptr
<VideoFrame
> > frames_
;
49 DISALLOW_COPY_AND_ASSIGN(PoolImpl
);
52 VideoFramePool::PoolImpl::PoolImpl() : is_shutdown_(false) {}
54 VideoFramePool::PoolImpl::~PoolImpl() {
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_
);
67 scoped_refptr
<VideoFrame
> frame
;
69 while (!frame
.get() && !frames_
.empty()) {
70 scoped_refptr
<VideoFrame
> pool_frame
= frames_
.front();
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
) {
78 frame
->set_timestamp(timestamp
);
84 frame
= VideoFrame::CreateFrame(
85 format
, coded_size
, visible_rect
, natural_size
, timestamp
);
88 return VideoFrame::WrapVideoFrame(
89 frame
, frame
->visible_rect(), frame
->natural_size(),
90 base::Bind(&VideoFramePool::PoolImpl::FrameReleased
, this, frame
));
93 void VideoFramePool::PoolImpl::Shutdown() {
94 base::AutoLock
auto_lock(lock_
);
99 void VideoFramePool::PoolImpl::FrameReleased(
100 const scoped_refptr
<VideoFrame
>& frame
) {
101 base::AutoLock
auto_lock(lock_
);
105 frames_
.push_back(frame
);
108 VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) {
111 VideoFramePool::~VideoFramePool() {
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
,
125 size_t VideoFramePool::GetPoolSizeForTesting() const {
126 return pool_
->GetPoolSizeForTesting();