- add sources.
[platform/framework/web/crosswalk.git] / src / media / cdm / ppapi / cdm_helpers.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/cdm/ppapi/cdm_helpers.h"
6
7 #include <utility>
8
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "build/build_config.h"
12 #include "media/cdm/ppapi/api/content_decryption_module.h"
13 #include "ppapi/c/pp_errors.h"
14 #include "ppapi/c/pp_stdint.h"
15 #include "ppapi/cpp/core.h"
16 #include "ppapi/cpp/dev/buffer_dev.h"
17 #include "ppapi/cpp/instance.h"
18 #include "ppapi/cpp/logging.h"
19 #include "ppapi/cpp/module.h"
20
21 namespace media {
22
23 cdm::Buffer* PpbBufferAllocator::Allocate(uint32_t capacity) {
24   PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
25
26   if (!capacity)
27     return NULL;
28
29   pp::Buffer_Dev buffer;
30   uint32_t buffer_id = 0;
31
32   // Reuse a buffer in the free list if there is one that fits |capacity|.
33   // Otherwise, create a new one.
34   FreeBufferMap::iterator found = free_buffers_.lower_bound(capacity);
35   if (found == free_buffers_.end()) {
36     // TODO(xhwang): Report statistics about how many new buffers are allocated.
37     buffer = AllocateNewBuffer(capacity);
38     if (buffer.is_null())
39       return NULL;
40     buffer_id = next_buffer_id_++;
41   } else {
42     buffer = found->second.second;
43     buffer_id = found->second.first;
44     free_buffers_.erase(found);
45   }
46
47   allocated_buffers_.insert(std::make_pair(buffer_id, buffer));
48
49   return PpbBuffer::Create(buffer, buffer_id);
50 }
51
52 void PpbBufferAllocator::Release(uint32_t buffer_id) {
53   if (!buffer_id)
54     return;
55
56   AllocatedBufferMap::iterator found = allocated_buffers_.find(buffer_id);
57   if (found == allocated_buffers_.end())
58     return;
59
60   pp::Buffer_Dev& buffer = found->second;
61   free_buffers_.insert(
62       std::make_pair(buffer.size(), std::make_pair(buffer_id, buffer)));
63
64   allocated_buffers_.erase(found);
65 }
66
67 pp::Buffer_Dev PpbBufferAllocator::AllocateNewBuffer(uint32_t capacity) {
68   // Always pad new allocated buffer so that we don't need to reallocate
69   // buffers frequently if requested sizes fluctuate slightly.
70   static const uint32_t kBufferPadding = 512;
71
72   // Maximum number of free buffers we can keep when allocating new buffers.
73   static const uint32_t kFreeLimit = 3;
74
75   // Destroy the smallest buffer before allocating a new bigger buffer if the
76   // number of free buffers exceeds a limit. This mechanism helps avoid ending
77   // up with too many small buffers, which could happen if the size to be
78   // allocated keeps increasing.
79   if (free_buffers_.size() >= kFreeLimit)
80     free_buffers_.erase(free_buffers_.begin());
81
82   // Creation of pp::Buffer_Dev is expensive! It involves synchronous IPC calls.
83   // That's why we try to avoid AllocateNewBuffer() as much as we can.
84   return pp::Buffer_Dev(instance_, capacity + kBufferPadding);
85 }
86
87 VideoFrameImpl::VideoFrameImpl()
88     : format_(cdm::kUnknownVideoFormat),
89       frame_buffer_(NULL),
90       timestamp_(0) {
91   for (uint32_t i = 0; i < kMaxPlanes; ++i) {
92     plane_offsets_[i] = 0;
93     strides_[i] = 0;
94   }
95 }
96
97 VideoFrameImpl::~VideoFrameImpl() {
98   if (frame_buffer_)
99     frame_buffer_->Destroy();
100 }
101
102 }  // namespace media