cdm_helpers.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
15f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant// Copyright 2013 The Chromium Authors. All rights reserved. 25f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant// Use of this source code is governed by a BSD-style license that can be 35f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant// found in the LICENSE file. 45f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant#include "media/cdm/ppapi/cdm_helpers.h" 6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant 75f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include <utility> 85f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 95f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "base/basictypes.h" 105f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "base/compiler_specific.h" 115f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "build/build_config.h" 125f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "media/cdm/ppapi/api/content_decryption_module.h" 135f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/c/pp_errors.h" 145f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/c/pp_stdint.h" 155f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/cpp/core.h" 165f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/cpp/dev/buffer_dev.h" 175f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/cpp/instance.h" 185f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/cpp/logging.h" 195f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant#include "ppapi/cpp/module.h" 205f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 215f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnantnamespace media { 225f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 235f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnantcdm::Buffer* PpbBufferAllocator::Allocate(int32_t capacity) { 245f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant PP_DCHECK(pp::Module::Get()->core()->IsMainThread()); 255f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 265f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant if (capacity <= 0) 275f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant return NULL; 285f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 295f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant pp::Buffer_Dev buffer; 305f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant uint32_t buffer_id = 0; 315f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant 325f9b133e2cd3b000056bdda641b94ebb611d4653Howard Hinnant // Reuse a buffer in the free list if there is one that fits |capacity|. 33 // Otherwise, create a new one. 34 FreeBufferMap::iterator found = free_buffers_.lower_bound(capacity); 35 if (found == free_buffers_.end()) { 36 // TODO(xhwang): Report statistics about how many new buffers are allocated. 37 buffer = AllocateNewBuffer(capacity); 38 if (buffer.is_null()) 39 return NULL; 40 buffer_id = next_buffer_id_++; 41 } else { 42 buffer = found->second.second; 43 buffer_id = found->second.first; 44 free_buffers_.erase(found); 45 } 46 47 allocated_buffers_.insert(std::make_pair(buffer_id, buffer)); 48 49 return PpbBuffer::Create(buffer, buffer_id); 50} 51 52void PpbBufferAllocator::Release(uint32_t buffer_id) { 53 if (!buffer_id) 54 return; 55 56 AllocatedBufferMap::iterator found = allocated_buffers_.find(buffer_id); 57 if (found == allocated_buffers_.end()) 58 return; 59 60 pp::Buffer_Dev& buffer = found->second; 61 free_buffers_.insert( 62 std::make_pair(buffer.size(), std::make_pair(buffer_id, buffer))); 63 64 allocated_buffers_.erase(found); 65} 66 67pp::Buffer_Dev PpbBufferAllocator::AllocateNewBuffer(int32_t capacity) { 68 // Always pad new allocated buffer so that we don't need to reallocate 69 // buffers frequently if requested sizes fluctuate slightly. 70 static const int kBufferPadding = 512; 71 72 // Maximum number of free buffers we can keep when allocating new buffers. 73 static const int kFreeLimit = 3; 74 75 // Destroy the smallest buffer before allocating a new bigger buffer if the 76 // number of free buffers exceeds a limit. This mechanism helps avoid ending 77 // up with too many small buffers, which could happen if the size to be 78 // allocated keeps increasing. 79 if (free_buffers_.size() >= static_cast<uint32_t>(kFreeLimit)) 80 free_buffers_.erase(free_buffers_.begin()); 81 82 // Creation of pp::Buffer_Dev is expensive! It involves synchronous IPC calls. 83 // That's why we try to avoid AllocateNewBuffer() as much as we can. 84 return pp::Buffer_Dev(instance_, capacity + kBufferPadding); 85} 86 87VideoFrameImpl::VideoFrameImpl() 88 : format_(cdm::kUnknownVideoFormat), 89 frame_buffer_(NULL), 90 timestamp_(0) { 91 for (int32_t i = 0; i < kMaxPlanes; ++i) { 92 plane_offsets_[i] = 0; 93 strides_[i] = 0; 94 } 95} 96 97VideoFrameImpl::~VideoFrameImpl() { 98 if (frame_buffer_) 99 frame_buffer_->Destroy(); 100} 101 102} // namespace media 103