cdm_helpers.h revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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#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/dev/buffer_dev.h"
18#include "ppapi/cpp/instance.h"
19#include "ppapi/cpp/logging.h"
20
21namespace media {
22
23// cdm::Buffer implementation that provides access to memory owned by a
24// pp::Buffer_Dev.
25// This class holds a reference to the Buffer_Dev throughout its lifetime.
26// TODO(xhwang): Find a better name. It's confusing to have PpbBuffer,
27// pp::Buffer_Dev and PPB_Buffer_Dev.
28class PpbBuffer : public cdm::Buffer {
29 public:
30  static PpbBuffer* Create(const pp::Buffer_Dev& buffer, uint32_t buffer_id) {
31    PP_DCHECK(buffer.data());
32    PP_DCHECK(buffer.size());
33    PP_DCHECK(buffer_id);
34    return new PpbBuffer(buffer, buffer_id);
35  }
36
37  // cdm::Buffer implementation.
38  virtual void Destroy() OVERRIDE { delete this; }
39
40  virtual uint32_t Capacity() const OVERRIDE { return buffer_.size(); }
41
42  virtual uint8_t* Data() OVERRIDE {
43    return static_cast<uint8_t*>(buffer_.data());
44  }
45
46  virtual void SetSize(uint32_t size) OVERRIDE {
47    PP_DCHECK(size <= Capacity());
48    if (size > Capacity()) {
49      size_ = 0;
50      return;
51    }
52
53    size_ = size;
54  }
55
56  virtual uint32_t Size() const OVERRIDE { return size_; }
57
58  pp::Buffer_Dev buffer_dev() const { return buffer_; }
59
60  uint32_t buffer_id() const { return buffer_id_; }
61
62 private:
63  PpbBuffer(pp::Buffer_Dev buffer, uint32_t buffer_id)
64      : buffer_(buffer),
65        buffer_id_(buffer_id),
66        size_(0) {}
67  virtual ~PpbBuffer() {}
68
69  pp::Buffer_Dev buffer_;
70  uint32_t buffer_id_;
71  uint32_t size_;
72
73  DISALLOW_COPY_AND_ASSIGN(PpbBuffer);
74};
75
76class PpbBufferAllocator {
77 public:
78  explicit PpbBufferAllocator(pp::Instance* instance)
79      : instance_(instance),
80        next_buffer_id_(1) {}
81  ~PpbBufferAllocator() {}
82
83  cdm::Buffer* Allocate(uint32_t capacity);
84
85  // Releases the buffer with |buffer_id|. A buffer can be recycled after
86  // it is released.
87  void Release(uint32_t buffer_id);
88
89 private:
90  typedef std::map<uint32_t, pp::Buffer_Dev> AllocatedBufferMap;
91  typedef std::multimap<uint32_t, std::pair<uint32_t, pp::Buffer_Dev> >
92      FreeBufferMap;
93
94  pp::Buffer_Dev AllocateNewBuffer(uint32_t capacity);
95
96  pp::Instance* const instance_;
97  uint32_t next_buffer_id_;
98  AllocatedBufferMap allocated_buffers_;
99  FreeBufferMap free_buffers_;
100
101  DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator);
102};
103
104class DecryptedBlockImpl : public cdm::DecryptedBlock {
105 public:
106  DecryptedBlockImpl() : buffer_(NULL), timestamp_(0) {}
107  virtual ~DecryptedBlockImpl() { if (buffer_) buffer_->Destroy(); }
108
109  virtual void SetDecryptedBuffer(cdm::Buffer* buffer) OVERRIDE {
110    buffer_ = static_cast<PpbBuffer*>(buffer);
111  }
112  virtual cdm::Buffer* DecryptedBuffer() OVERRIDE { return buffer_; }
113
114  virtual void SetTimestamp(int64_t timestamp) OVERRIDE {
115    timestamp_ = timestamp;
116  }
117  virtual int64_t Timestamp() const OVERRIDE { return timestamp_; }
118
119 private:
120  PpbBuffer* buffer_;
121  int64_t timestamp_;
122
123  DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl);
124};
125
126class VideoFrameImpl : public cdm::VideoFrame {
127 public:
128  VideoFrameImpl();
129  virtual ~VideoFrameImpl();
130
131  virtual void SetFormat(cdm::VideoFormat format) OVERRIDE {
132    format_ = format;
133  }
134  virtual cdm::VideoFormat Format() const OVERRIDE { return format_; }
135
136  virtual void SetSize(cdm::Size size) OVERRIDE { size_ = size; }
137  virtual cdm::Size Size() const OVERRIDE { return size_; }
138
139  virtual void SetFrameBuffer(cdm::Buffer* frame_buffer) OVERRIDE {
140    frame_buffer_ = static_cast<PpbBuffer*>(frame_buffer);
141  }
142  virtual cdm::Buffer* FrameBuffer() OVERRIDE { return frame_buffer_; }
143
144  virtual void SetPlaneOffset(cdm::VideoFrame::VideoPlane plane,
145                              uint32_t offset) OVERRIDE {
146    PP_DCHECK(plane < kMaxPlanes);
147    plane_offsets_[plane] = offset;
148  }
149  virtual uint32_t PlaneOffset(VideoPlane plane) OVERRIDE {
150    PP_DCHECK(plane < kMaxPlanes);
151    return plane_offsets_[plane];
152  }
153
154  virtual void SetStride(VideoPlane plane, uint32_t stride) OVERRIDE {
155    PP_DCHECK(plane < kMaxPlanes);
156    strides_[plane] = stride;
157  }
158  virtual uint32_t Stride(VideoPlane plane) OVERRIDE {
159    PP_DCHECK(plane < kMaxPlanes);
160    return strides_[plane];
161  }
162
163  virtual void SetTimestamp(int64_t timestamp) OVERRIDE {
164    timestamp_ = timestamp;
165  }
166  virtual int64_t Timestamp() const OVERRIDE { return timestamp_; }
167
168 private:
169  // The video buffer format.
170  cdm::VideoFormat format_;
171
172  // Width and height of the video frame.
173  cdm::Size size_;
174
175  // The video frame buffer.
176  PpbBuffer* frame_buffer_;
177
178  // Array of data pointers to each plane in the video frame buffer.
179  uint32_t plane_offsets_[kMaxPlanes];
180
181  // Array of strides for each plane, typically greater or equal to the width
182  // of the surface divided by the horizontal sampling period.  Note that
183  // strides can be negative.
184  uint32_t strides_[kMaxPlanes];
185
186  // Presentation timestamp in microseconds.
187  int64_t timestamp_;
188
189  DISALLOW_COPY_AND_ASSIGN(VideoFrameImpl);
190};
191
192class AudioFramesImpl : public cdm::AudioFrames_2 {
193 public:
194  AudioFramesImpl() : buffer_(NULL), format_(cdm::kUnknownAudioFormat) {}
195  virtual ~AudioFramesImpl() {
196    if (buffer_)
197      buffer_->Destroy();
198  }
199
200  // AudioFrames implementation.
201  virtual void SetFrameBuffer(cdm::Buffer* buffer) OVERRIDE {
202    buffer_ = static_cast<PpbBuffer*>(buffer);
203  }
204  virtual cdm::Buffer* FrameBuffer() OVERRIDE {
205    return buffer_;
206  }
207  virtual void SetFormat(cdm::AudioFormat format) OVERRIDE {
208    format_ = format;
209  }
210  virtual cdm::AudioFormat Format() const OVERRIDE {
211    return format_;
212  }
213
214  cdm::Buffer* PassFrameBuffer() {
215    PpbBuffer* temp_buffer = buffer_;
216    buffer_ = NULL;
217    return temp_buffer;
218  }
219
220 private:
221  PpbBuffer* buffer_;
222  cdm::AudioFormat format_;
223
224  DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl);
225};
226
227}  // namespace media
228
229#endif  // MEDIA_CDM_PPAPI_CDM_HELPERS_H_
230