Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / media / cdm / ppapi / cdm_helpers.cc
blob00e7595a001a0c01c1b90dd2a674b317d660b7cf
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/cdm/ppapi/cdm_helpers.h"
7 #include <algorithm>
9 #include "ppapi/cpp/core.h"
10 #include "ppapi/cpp/module.h"
12 namespace media {
14 // static
15 PpbBuffer* PpbBuffer::Create(const pp::Buffer_Dev& buffer,
16 uint32_t buffer_id,
17 PpbBufferAllocator* allocator) {
18 PP_DCHECK(buffer.data());
19 PP_DCHECK(buffer.size());
20 PP_DCHECK(buffer_id);
21 PP_DCHECK(allocator);
22 return new PpbBuffer(buffer, buffer_id, allocator);
25 void PpbBuffer::Destroy() {
26 delete this;
29 uint32_t PpbBuffer::Capacity() const {
30 return buffer_.size();
33 uint8_t* PpbBuffer::Data() {
34 return static_cast<uint8_t*>(buffer_.data());
37 void PpbBuffer::SetSize(uint32_t size) {
38 PP_DCHECK(size <= Capacity());
39 if (size > Capacity()) {
40 size_ = 0;
41 return;
44 size_ = size;
47 pp::Buffer_Dev PpbBuffer::TakeBuffer() {
48 PP_DCHECK(!buffer_.is_null());
49 pp::Buffer_Dev buffer;
50 std::swap(buffer, buffer_);
51 buffer_id_ = 0;
52 size_ = 0;
53 return buffer;
56 PpbBuffer::PpbBuffer(pp::Buffer_Dev buffer,
57 uint32_t buffer_id,
58 PpbBufferAllocator* allocator)
59 : buffer_(buffer), buffer_id_(buffer_id), size_(0), allocator_(allocator) {
62 PpbBuffer::~PpbBuffer() {
63 PP_DCHECK(!buffer_id_ == buffer_.is_null());
64 // If still owning the |buffer_|, release it in the |allocator_|.
65 if (buffer_id_)
66 allocator_->Release(buffer_id_);
69 cdm::Buffer* PpbBufferAllocator::Allocate(uint32_t capacity) {
70 PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
72 if (!capacity)
73 return NULL;
75 pp::Buffer_Dev buffer;
76 uint32_t buffer_id = 0;
78 // Reuse a buffer in the free list if there is one that fits |capacity|.
79 // Otherwise, create a new one.
80 FreeBufferMap::iterator found = free_buffers_.lower_bound(capacity);
81 if (found == free_buffers_.end()) {
82 // TODO(xhwang): Report statistics about how many new buffers are allocated.
83 buffer = AllocateNewBuffer(capacity);
84 if (buffer.is_null())
85 return NULL;
86 buffer_id = next_buffer_id_++;
87 } else {
88 buffer = found->second.second;
89 buffer_id = found->second.first;
90 free_buffers_.erase(found);
93 allocated_buffers_.insert(std::make_pair(buffer_id, buffer));
95 return PpbBuffer::Create(buffer, buffer_id, this);
98 void PpbBufferAllocator::Release(uint32_t buffer_id) {
99 if (!buffer_id)
100 return;
102 AllocatedBufferMap::iterator found = allocated_buffers_.find(buffer_id);
103 if (found == allocated_buffers_.end())
104 return;
106 pp::Buffer_Dev& buffer = found->second;
107 free_buffers_.insert(
108 std::make_pair(buffer.size(), std::make_pair(buffer_id, buffer)));
110 allocated_buffers_.erase(found);
113 pp::Buffer_Dev PpbBufferAllocator::AllocateNewBuffer(uint32_t capacity) {
114 // Always pad new allocated buffer so that we don't need to reallocate
115 // buffers frequently if requested sizes fluctuate slightly.
116 static const uint32_t kBufferPadding = 512;
118 // Maximum number of free buffers we can keep when allocating new buffers.
119 static const uint32_t kFreeLimit = 3;
121 // Destroy the smallest buffer before allocating a new bigger buffer if the
122 // number of free buffers exceeds a limit. This mechanism helps avoid ending
123 // up with too many small buffers, which could happen if the size to be
124 // allocated keeps increasing.
125 if (free_buffers_.size() >= kFreeLimit)
126 free_buffers_.erase(free_buffers_.begin());
128 // Creation of pp::Buffer_Dev is expensive! It involves synchronous IPC calls.
129 // That's why we try to avoid AllocateNewBuffer() as much as we can.
130 return pp::Buffer_Dev(instance_, capacity + kBufferPadding);
133 VideoFrameImpl::VideoFrameImpl()
134 : format_(cdm::kUnknownVideoFormat),
135 frame_buffer_(NULL),
136 timestamp_(0) {
137 for (uint32_t i = 0; i < kMaxPlanes; ++i) {
138 plane_offsets_[i] = 0;
139 strides_[i] = 0;
143 VideoFrameImpl::~VideoFrameImpl() {
144 if (frame_buffer_)
145 frame_buffer_->Destroy();
148 } // namespace media