// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_CDM_PPAPI_PPAPI_CDM_BUFFER_H_ #define MEDIA_CDM_PPAPI_PPAPI_CDM_BUFFER_H_ #include #include #include "base/compiler_specific.h" #include "base/macros.h" #include "build/build_config.h" #include "media/cdm/api/content_decryption_module.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/cpp/dev/buffer_dev.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/logging.h" namespace media { class PpbBufferAllocator; // cdm::Buffer implementation that provides access to memory owned by a // pp::Buffer_Dev. // This class holds a reference to the Buffer_Dev throughout its lifetime. // TODO(xhwang): Find a better name. It's confusing to have PpbBuffer, // pp::Buffer_Dev and PPB_Buffer_Dev. class PpbBuffer : public cdm::Buffer { public: static PpbBuffer* Create(const pp::Buffer_Dev& buffer, uint32_t buffer_id, PpbBufferAllocator* allocator); // cdm::Buffer implementation. void Destroy() override; uint32_t Capacity() const override; uint8_t* Data() override; void SetSize(uint32_t size) override; uint32_t Size() const override { return size_; } // Takes the |buffer_| from this class and returns it. // Note: The caller must ensure |allocator->Release()| is called later so that // the buffer can be reused by the allocator. // Since pp::Buffer_Dev is ref-counted, the caller now holds one reference to // the buffer and this class holds no reference. Note that other references // may still exist. For example, PpbBufferAllocator always holds a reference // to all allocated buffers. pp::Buffer_Dev TakeBuffer(); uint32_t buffer_id() const { return buffer_id_; } private: PpbBuffer(pp::Buffer_Dev buffer, uint32_t buffer_id, PpbBufferAllocator* allocator); ~PpbBuffer() override; pp::Buffer_Dev buffer_; uint32_t buffer_id_; uint32_t size_; PpbBufferAllocator* allocator_; DISALLOW_COPY_AND_ASSIGN(PpbBuffer); }; class PpbBufferAllocator { public: explicit PpbBufferAllocator(pp::Instance* instance) : instance_(instance), next_buffer_id_(1) {} ~PpbBufferAllocator() {} cdm::Buffer* Allocate(uint32_t capacity); // Releases the buffer with |buffer_id|. A buffer can be recycled after // it is released. void Release(uint32_t buffer_id); private: typedef std::map AllocatedBufferMap; typedef std::multimap> FreeBufferMap; pp::Buffer_Dev AllocateNewBuffer(uint32_t capacity); pp::Instance* const instance_; uint32_t next_buffer_id_; AllocatedBufferMap allocated_buffers_; FreeBufferMap free_buffers_; DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator); }; } // namespace media #endif // MEDIA_CDM_PPAPI_PPAPI_CDM_BUFFER_H_