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