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