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 // See VideoFramePool::CreateFrame() for usage.
21 scoped_refptr
<VideoFrame
> CreateFrame(VideoPixelFormat format
,
22 const gfx::Size
& coded_size
,
23 const gfx::Rect
& visible_rect
,
24 const gfx::Size
& natural_size
,
25 base::TimeDelta timestamp
);
27 // Shuts down the frame pool and releases all frames in |frames_|.
28 // Once this is called frames will no longer be inserted back into
32 size_t GetPoolSizeForTesting() const { return frames_
.size(); }
35 friend class base::RefCountedThreadSafe
<VideoFramePool::PoolImpl
>;
38 // Called when the frame wrapper gets destroyed.
39 // |frame| is the actual frame that was wrapped and is placed
40 // in |frames_| by this function so it can be reused.
41 void FrameReleased(const scoped_refptr
<VideoFrame
>& frame
);
45 std::list
<scoped_refptr
<VideoFrame
> > frames_
;
47 DISALLOW_COPY_AND_ASSIGN(PoolImpl
);
50 VideoFramePool::PoolImpl::PoolImpl() : is_shutdown_(false) {}
52 VideoFramePool::PoolImpl::~PoolImpl() {
56 scoped_refptr
<VideoFrame
> VideoFramePool::PoolImpl::CreateFrame(
57 VideoPixelFormat format
,
58 const gfx::Size
& coded_size
,
59 const gfx::Rect
& visible_rect
,
60 const gfx::Size
& natural_size
,
61 base::TimeDelta timestamp
) {
62 base::AutoLock
auto_lock(lock_
);
63 DCHECK(!is_shutdown_
);
65 scoped_refptr
<VideoFrame
> frame
;
67 while (!frame
.get() && !frames_
.empty()) {
68 scoped_refptr
<VideoFrame
> pool_frame
= frames_
.front();
71 if (pool_frame
->format() == format
&&
72 pool_frame
->coded_size() == coded_size
&&
73 pool_frame
->visible_rect() == visible_rect
&&
74 pool_frame
->natural_size() == natural_size
) {
76 frame
->set_timestamp(timestamp
);
82 frame
= VideoFrame::CreateFrame(format
, coded_size
, visible_rect
,
83 natural_size
, timestamp
);
85 // Zero-initialize each plane of the buffer.
86 const size_t num_planes
= VideoFrame::NumPlanes(frame
->format());
87 for (size_t i
= 0; i
< num_planes
; ++i
) {
88 memset(frame
->data(i
),
90 VideoFrame::PlaneSize(frame
->format(),
92 frame
->coded_size()).GetArea());
96 scoped_refptr
<VideoFrame
> wrapped_frame
= VideoFrame::WrapVideoFrame(
97 frame
, frame
->visible_rect(), frame
->natural_size());
98 wrapped_frame
->AddDestructionObserver(
99 base::Bind(&VideoFramePool::PoolImpl::FrameReleased
, this, frame
));
100 return wrapped_frame
;
103 void VideoFramePool::PoolImpl::Shutdown() {
104 base::AutoLock
auto_lock(lock_
);
109 void VideoFramePool::PoolImpl::FrameReleased(
110 const scoped_refptr
<VideoFrame
>& frame
) {
111 base::AutoLock
auto_lock(lock_
);
115 frames_
.push_back(frame
);
118 VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) {
121 VideoFramePool::~VideoFramePool() {
125 scoped_refptr
<VideoFrame
> VideoFramePool::CreateFrame(
126 VideoPixelFormat format
,
127 const gfx::Size
& coded_size
,
128 const gfx::Rect
& visible_rect
,
129 const gfx::Size
& natural_size
,
130 base::TimeDelta timestamp
) {
131 return pool_
->CreateFrame(format
, coded_size
, visible_rect
, natural_size
,
135 size_t VideoFramePool::GetPoolSizeForTesting() const {
136 return pool_
->GetPoolSizeForTesting();