18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/cdm/ppapi/cdm_helpers.h" 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <algorithm> 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include <utility> 98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/basictypes.h" 118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/compiler_specific.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "build/build_config.h" 138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "media/cdm/ppapi/api/content_decryption_module.h" 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/c/pp_stdint.h" 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/core.h" 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/dev/buffer_dev.h" 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/instance.h" 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/logging.h" 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ppapi/cpp/module.h" 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace media { 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// static 25116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPpbBuffer* PpbBuffer::Create(const pp::Buffer_Dev& buffer, 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32_t buffer_id, 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PpbBufferAllocator* allocator) { 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(buffer.data()); 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(buffer.size()); 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(buffer_id); 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(allocator); 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return new PpbBuffer(buffer, buffer_id, allocator); 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PpbBuffer::Destroy() { 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch delete this; 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdochuint32_t PpbBuffer::Capacity() const { 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return buffer_.size(); 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdochuint8_t* PpbBuffer::Data() { 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return static_cast<uint8_t*>(buffer_.data()); 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PpbBuffer::SetSize(uint32_t size) { 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(size <= Capacity()); 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (size > Capacity()) { 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_ = 0; 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_ = size; 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdochpp::Buffer_Dev PpbBuffer::TakeBuffer() { 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(!buffer_.is_null()); 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pp::Buffer_Dev buffer; 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::swap(buffer, buffer_); 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch buffer_id_ = 0; 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_ = 0; 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return buffer; 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 66116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPpbBuffer::PpbBuffer(pp::Buffer_Dev buffer, 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32_t buffer_id, 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PpbBufferAllocator* allocator) 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : buffer_(buffer), buffer_id_(buffer_id), size_(0), allocator_(allocator) { 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 72116680a4aac90f2aa7413d9095a592090648e557Ben MurdochPpbBuffer::~PpbBuffer() { 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PP_DCHECK(!buffer_id_ == buffer_.is_null()); 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If still owning the |buffer_|, release it in the |allocator_|. 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (buffer_id_) 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch allocator_->Release(buffer_id_); 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)cdm::Buffer* PpbBufferAllocator::Allocate(uint32_t capacity) { 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) PP_DCHECK(pp::Module::Get()->core()->IsMainThread()); 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!capacity) 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) pp::Buffer_Dev buffer; 868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) uint32_t buffer_id = 0; 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Reuse a buffer in the free list if there is one that fits |capacity|. 898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Otherwise, create a new one. 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FreeBufferMap::iterator found = free_buffers_.lower_bound(capacity); 918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (found == free_buffers_.end()) { 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(xhwang): Report statistics about how many new buffers are allocated. 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) buffer = AllocateNewBuffer(capacity); 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (buffer.is_null()) 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) buffer_id = next_buffer_id_++; 978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) buffer = found->second.second; 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) buffer_id = found->second.first; 1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) free_buffers_.erase(found); 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) allocated_buffers_.insert(std::make_pair(buffer_id, buffer)); 1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return PpbBuffer::Create(buffer, buffer_id, this); 1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void PpbBufferAllocator::Release(uint32_t buffer_id) { 1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!buffer_id) 1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AllocatedBufferMap::iterator found = allocated_buffers_.find(buffer_id); 1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (found == allocated_buffers_.end()) 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) pp::Buffer_Dev& buffer = found->second; 1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) free_buffers_.insert( 1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::make_pair(buffer.size(), std::make_pair(buffer_id, buffer))); 1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) allocated_buffers_.erase(found); 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)pp::Buffer_Dev PpbBufferAllocator::AllocateNewBuffer(uint32_t capacity) { 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Always pad new allocated buffer so that we don't need to reallocate 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // buffers frequently if requested sizes fluctuate slightly. 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const uint32_t kBufferPadding = 512; 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Maximum number of free buffers we can keep when allocating new buffers. 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const uint32_t kFreeLimit = 3; 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Destroy the smallest buffer before allocating a new bigger buffer if the 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // number of free buffers exceeds a limit. This mechanism helps avoid ending 1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // up with too many small buffers, which could happen if the size to be 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // allocated keeps increasing. 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (free_buffers_.size() >= kFreeLimit) 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) free_buffers_.erase(free_buffers_.begin()); 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Creation of pp::Buffer_Dev is expensive! It involves synchronous IPC calls. 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // That's why we try to avoid AllocateNewBuffer() as much as we can. 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return pp::Buffer_Dev(instance_, capacity + kBufferPadding); 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)VideoFrameImpl::VideoFrameImpl() 1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : format_(cdm::kUnknownVideoFormat), 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) frame_buffer_(NULL), 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) timestamp_(0) { 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) for (uint32_t i = 0; i < kMaxPlanes; ++i) { 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) plane_offsets_[i] = 0; 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) strides_[i] = 0; 1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)VideoFrameImpl::~VideoFrameImpl() { 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (frame_buffer_) 1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) frame_buffer_->Destroy(); 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace media 159