Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: media/cdm/ppapi/cdm_helpers.h

Issue 26155003: Add CdmWrapper to support multiple CDM versions in CdmAdapter. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add cdm_helpers.h Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
xhwang 2013/10/15 20:42:33 This file is copied from cdm_wrapper.cc, with smal
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MEDIA_CDM_PPAPI_CDM_HELPERS_H_
6 #define MEDIA_CDM_PPAPI_CDM_HELPERS_H_
7
8 #include <map>
9 #include <utility>
10
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "build/build_config.h"
14 #include "media/cdm/ppapi/api/content_decryption_module.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/pp_stdint.h"
17 #include "ppapi/cpp/core.h"
18 #include "ppapi/cpp/dev/buffer_dev.h"
19 #include "ppapi/cpp/instance.h"
20 #include "ppapi/cpp/logging.h"
21 #include "ppapi/cpp/module.h"
xhwang 2013/10/15 20:42:33 Includes are trimmed to reflect what we use.
22
23 namespace media {
24
25 // cdm::Buffer implementation that provides access to memory owned by a
26 // pp::Buffer_Dev.
27 // This class holds a reference to the Buffer_Dev throughout its lifetime.
28 // TODO(xhwang): Find a better name. It's confusing to have PpbBuffer,
29 // pp::Buffer_Dev and PPB_Buffer_Dev.
30 class PpbBuffer : public cdm::Buffer {
31 public:
32 static PpbBuffer* Create(const pp::Buffer_Dev& buffer, uint32_t buffer_id) {
33 PP_DCHECK(buffer.data());
34 PP_DCHECK(buffer.size());
35 PP_DCHECK(buffer_id);
36 return new PpbBuffer(buffer, buffer_id);
37 }
38
39 // cdm::Buffer implementation.
40 virtual void Destroy() OVERRIDE { delete this; }
41
42 virtual int32_t Capacity() const OVERRIDE { return buffer_.size(); }
43
44 virtual uint8_t* Data() OVERRIDE {
45 return static_cast<uint8_t*>(buffer_.data());
46 }
47
48 virtual void SetSize(int32_t size) OVERRIDE {
49 PP_DCHECK(size >= 0);
50 PP_DCHECK(size < Capacity());
51 if (size < 0 || size > Capacity()) {
52 size_ = 0;
53 return;
54 }
55
56 size_ = size;
57 }
58
59 virtual int32_t Size() const OVERRIDE { return size_; }
60
61 pp::Buffer_Dev buffer_dev() const { return buffer_; }
62
63 uint32_t buffer_id() const { return buffer_id_; }
64
65 private:
66 PpbBuffer(pp::Buffer_Dev buffer, uint32_t buffer_id)
67 : buffer_(buffer),
68 buffer_id_(buffer_id),
69 size_(0) {}
70 virtual ~PpbBuffer() {}
71
72 pp::Buffer_Dev buffer_;
73 uint32_t buffer_id_;
74 int32_t size_;
75
76 DISALLOW_COPY_AND_ASSIGN(PpbBuffer);
77 };
78
79 class PpbBufferAllocator {
80 public:
81 explicit PpbBufferAllocator(pp::Instance* instance)
82 : instance_(instance),
83 next_buffer_id_(1) {}
84 ~PpbBufferAllocator() {}
85
86 cdm::Buffer* Allocate(int32_t capacity);
87
88 // Releases the buffer with |buffer_id|. A buffer can be recycled after
89 // it is released.
90 void Release(uint32_t buffer_id);
91
92 private:
93 typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap;
94 typedef std::multimap<int, std::pair<uint32_t, pp::Buffer_Dev> >
95 FreeBufferMap;
96
97 // Always pad new allocated buffer so that we don't need to reallocate
98 // buffers frequently if requested sizes fluctuate slightly.
99 static const int kBufferPadding = 512;
100
101 // Maximum number of free buffers we can keep when allocating new buffers.
102 static const int kFreeLimit = 3;
103
104 pp::Buffer_Dev AllocateNewBuffer(int capacity);
105
106 pp::Instance* const instance_;
107 uint32_t next_buffer_id_;
108 AllocatedBufferMap allocated_buffers_;
109 FreeBufferMap free_buffers_;
110
111 DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator);
112 };
113
114 cdm::Buffer* PpbBufferAllocator::Allocate(int32_t capacity) {
115 PP_DCHECK(pp::Module::Get()->core()->IsMainThread());
xhwang 2013/10/15 20:42:33 This was IsMainThread() in cdm_wrapper.cc. I am no
116
117 if (capacity <= 0)
118 return NULL;
119
120 pp::Buffer_Dev buffer;
121 uint32_t buffer_id = 0;
122
123 // Reuse a buffer in the free list if there is one that fits |capacity|.
124 // Otherwise, create a new one.
125 FreeBufferMap::iterator found = free_buffers_.lower_bound(capacity);
126 if (found == free_buffers_.end()) {
127 // TODO(xhwang): Report statistics about how many new buffers are allocated.
128 buffer = AllocateNewBuffer(capacity);
129 if (buffer.is_null())
130 return NULL;
131 buffer_id = next_buffer_id_++;
132 } else {
133 buffer = found->second.second;
134 buffer_id = found->second.first;
135 free_buffers_.erase(found);
136 }
137
138 allocated_buffers_.insert(std::make_pair(buffer_id, buffer));
139
140 return PpbBuffer::Create(buffer, buffer_id);
141 }
142
143 void PpbBufferAllocator::Release(uint32_t buffer_id) {
144 if (!buffer_id)
145 return;
146
147 AllocatedBufferMap::iterator found = allocated_buffers_.find(buffer_id);
148 if (found == allocated_buffers_.end())
149 return;
150
151 pp::Buffer_Dev& buffer = found->second;
152 free_buffers_.insert(
153 std::make_pair(buffer.size(), std::make_pair(buffer_id, buffer)));
154
155 allocated_buffers_.erase(found);
156 }
157
158 pp::Buffer_Dev PpbBufferAllocator::AllocateNewBuffer(int32_t capacity) {
159 // Destroy the smallest buffer before allocating a new bigger buffer if the
160 // number of free buffers exceeds a limit. This mechanism helps avoid ending
161 // up with too many small buffers, which could happen if the size to be
162 // allocated keeps increasing.
163 if (free_buffers_.size() >= static_cast<uint32_t>(kFreeLimit))
164 free_buffers_.erase(free_buffers_.begin());
165
166 // Creation of pp::Buffer_Dev is expensive! It involves synchronous IPC calls.
167 // That's why we try to avoid AllocateNewBuffer() as much as we can.
168 return pp::Buffer_Dev(instance_, capacity + kBufferPadding);
169 }
170
171 class DecryptedBlockImpl : public cdm::DecryptedBlock {
172 public:
173 DecryptedBlockImpl() : buffer_(NULL), timestamp_(0) {}
174 virtual ~DecryptedBlockImpl() { if (buffer_) buffer_->Destroy(); }
175
176 virtual void SetDecryptedBuffer(cdm::Buffer* buffer) OVERRIDE {
177 buffer_ = static_cast<PpbBuffer*>(buffer);
178 }
179 virtual cdm::Buffer* DecryptedBuffer() OVERRIDE { return buffer_; }
180
181 virtual void SetTimestamp(int64_t timestamp) OVERRIDE {
182 timestamp_ = timestamp;
183 }
184 virtual int64_t Timestamp() const OVERRIDE { return timestamp_; }
185
186 private:
187 PpbBuffer* buffer_;
188 int64_t timestamp_;
189
190 DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl);
191 };
192
193 class VideoFrameImpl : public cdm::VideoFrame {
194 public:
195 VideoFrameImpl();
196 virtual ~VideoFrameImpl();
197
198 virtual void SetFormat(cdm::VideoFormat format) OVERRIDE {
199 format_ = format;
200 }
201 virtual cdm::VideoFormat Format() const OVERRIDE { return format_; }
202
203 virtual void SetSize(cdm::Size size) OVERRIDE { size_ = size; }
204 virtual cdm::Size Size() const OVERRIDE { return size_; }
205
206 virtual void SetFrameBuffer(cdm::Buffer* frame_buffer) OVERRIDE {
207 frame_buffer_ = static_cast<PpbBuffer*>(frame_buffer);
208 }
209 virtual cdm::Buffer* FrameBuffer() OVERRIDE { return frame_buffer_; }
210
211 virtual void SetPlaneOffset(cdm::VideoFrame::VideoPlane plane,
212 int32_t offset) OVERRIDE {
213 PP_DCHECK(0 <= plane && plane < kMaxPlanes);
214 PP_DCHECK(offset >= 0);
215 plane_offsets_[plane] = offset;
216 }
217 virtual int32_t PlaneOffset(VideoPlane plane) OVERRIDE {
218 PP_DCHECK(0 <= plane && plane < kMaxPlanes);
219 return plane_offsets_[plane];
220 }
221
222 virtual void SetStride(VideoPlane plane, int32_t stride) OVERRIDE {
223 PP_DCHECK(0 <= plane && plane < kMaxPlanes);
224 strides_[plane] = stride;
225 }
226 virtual int32_t Stride(VideoPlane plane) OVERRIDE {
227 PP_DCHECK(0 <= plane && plane < kMaxPlanes);
228 return strides_[plane];
229 }
230
231 virtual void SetTimestamp(int64_t timestamp) OVERRIDE {
232 timestamp_ = timestamp;
233 }
234 virtual int64_t Timestamp() const OVERRIDE { return timestamp_; }
235
236 private:
237 // The video buffer format.
238 cdm::VideoFormat format_;
239
240 // Width and height of the video frame.
241 cdm::Size size_;
242
243 // The video frame buffer.
244 PpbBuffer* frame_buffer_;
245
246 // Array of data pointers to each plane in the video frame buffer.
247 int32_t plane_offsets_[kMaxPlanes];
248
249 // Array of strides for each plane, typically greater or equal to the width
250 // of the surface divided by the horizontal sampling period. Note that
251 // strides can be negative.
252 int32_t strides_[kMaxPlanes];
253
254 // Presentation timestamp in microseconds.
255 int64_t timestamp_;
256
257 DISALLOW_COPY_AND_ASSIGN(VideoFrameImpl);
258 };
259
260 VideoFrameImpl::VideoFrameImpl()
261 : format_(cdm::kUnknownVideoFormat),
262 frame_buffer_(NULL),
263 timestamp_(0) {
264 for (int32_t i = 0; i < kMaxPlanes; ++i) {
265 plane_offsets_[i] = 0;
266 strides_[i] = 0;
267 }
268 }
269
270 VideoFrameImpl::~VideoFrameImpl() {
271 if (frame_buffer_)
272 frame_buffer_->Destroy();
273 }
274
275 class AudioFramesImpl : public cdm::AudioFrames_1,
276 public cdm::AudioFrames_2 {
277 public:
278 AudioFramesImpl() : buffer_(NULL), format_(cdm::kAudioFormatS16) {}
279 virtual ~AudioFramesImpl() {
280 if (buffer_)
281 buffer_->Destroy();
282 }
283
284 // AudioFrames implementation.
285 virtual void SetFrameBuffer(cdm::Buffer* buffer) OVERRIDE {
286 buffer_ = static_cast<PpbBuffer*>(buffer);
287 }
288 virtual cdm::Buffer* FrameBuffer() OVERRIDE {
289 return buffer_;
290 }
291 virtual void SetFormat(cdm::AudioFormat format) OVERRIDE {
292 format_ = format;
293 }
294 virtual cdm::AudioFormat Format() const OVERRIDE {
295 return format_;
296 }
297
298 cdm::Buffer* PassFrameBuffer() {
xhwang 2013/10/15 20:42:33 Added this function so that we can transfer owners
299 PpbBuffer* temp_buffer = buffer_;
300 if (buffer_)
301 buffer_ = NULL;
302 return temp_buffer;
303 }
304
305 private:
306 PpbBuffer* buffer_;
307 cdm::AudioFormat format_;
308
309 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl);
310 };
311
312 } // namespace media
313
314 #endif // MEDIA_CDM_PPAPI_CDM_HELPERS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698