Home | History | Annotate | Download | only in base
      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->SetTimestamp(kNoTimestamp());
     79         break;
     80       }
     81   }
     82 
     83   if (!frame) {
     84     frame = VideoFrame::CreateFrame(
     85         format, coded_size, visible_rect, natural_size, kNoTimestamp());
     86   }
     87 
     88   return VideoFrame::WrapVideoFrame(
     89       frame, base::Bind(&VideoFramePool::PoolImpl::FrameReleased, this, frame));
     90 }
     91 
     92 void VideoFramePool::PoolImpl::Shutdown() {
     93   base::AutoLock auto_lock(lock_);
     94   is_shutdown_ = true;
     95   frames_.clear();
     96 }
     97 
     98 void VideoFramePool::PoolImpl::FrameReleased(
     99     const scoped_refptr<VideoFrame>& frame) {
    100   base::AutoLock auto_lock(lock_);
    101   if (is_shutdown_)
    102     return;
    103 
    104   frames_.push_back(frame);
    105 }
    106 
    107 VideoFramePool::VideoFramePool() : pool_(new PoolImpl()) {
    108 }
    109 
    110 VideoFramePool::~VideoFramePool() {
    111   pool_->Shutdown();
    112 }
    113 
    114 scoped_refptr<VideoFrame> VideoFramePool::CreateFrame(
    115     VideoFrame::Format format,
    116     const gfx::Size& coded_size,
    117     const gfx::Rect& visible_rect,
    118     const gfx::Size& natural_size,
    119     base::TimeDelta timestamp) {
    120   return pool_->CreateFrame(format, coded_size, visible_rect, natural_size,
    121                             timestamp);
    122 }
    123 
    124 size_t VideoFramePool::GetPoolSizeForTesting() const {
    125   return pool_->GetPoolSizeForTesting();
    126 }
    127 
    128 }  // namespace media
    129