blob: 92c919446ee211032aa3b81f5f33d0630f3da151 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/media/shell_media_platform_starboard.h"
#include <limits>
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/aligned_memory.h"
#include "media/audio/shell_audio_streamer.h"
#include "media/base/shell_buffer_factory.h"
#include "media/base/shell_cached_decoder_buffer.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/configuration.h"
#include "starboard/media.h"
namespace media {
namespace {
const size_t kMediaBufferAlignment = SB_MEDIA_BUFFER_ALIGNMENT;
const size_t kVideoFrameAlignment = SB_MEDIA_VIDEO_FRAME_ALIGNMENT;
// This may be zero, which should disable GPU memory buffer allocations.
const size_t kGPUMemoryBufferBudget = SB_MEDIA_GPU_BUFFER_BUDGET;
const size_t kMainMemoryBufferBudget = SB_MEDIA_MAIN_BUFFER_BUDGET;
const size_t kSmallAllocationThreshold = 768U;
} // namespace
ShellMediaPlatformStarboard::ShellMediaPlatformStarboard(
cobalt::render_tree::ResourceProvider* resource_provider)
: resource_provider_(resource_provider),
video_data_allocator_(resource_provider_, 0,
std::numeric_limits<size_t>::max(),
kVideoFrameAlignment),
video_frame_provider_(new ShellVideoFrameProvider) {
DCHECK(!Instance());
if (kGPUMemoryBufferBudget > 0) {
gpu_memory_buffer_space_ = resource_provider->AllocateRawImageMemory(
kGPUMemoryBufferBudget, kMediaBufferAlignment);
DCHECK(gpu_memory_buffer_space_);
DCHECK(gpu_memory_buffer_space_->GetMemory());
DCHECK_GE(gpu_memory_buffer_space_->GetSizeInBytes(),
kGPUMemoryBufferBudget);
gpu_memory_pool_.set(starboard::make_scoped_ptr(new nb::MemoryPool(
gpu_memory_buffer_space_->GetMemory(),
gpu_memory_buffer_space_->GetSizeInBytes(),
true /* verify_full_capacity */, kSmallAllocationThreshold)));
}
DCHECK_LE(0, kMainMemoryBufferBudget > 0);
main_memory_buffer_space_.reset(static_cast<uint8*>(
base::AlignedAlloc(kMainMemoryBufferBudget, kMediaBufferAlignment)));
DCHECK(main_memory_buffer_space_);
main_memory_pool_.set(starboard::make_scoped_ptr(new nb::MemoryPool(
main_memory_buffer_space_.get(), kMainMemoryBufferBudget,
true, /* verify_full_capacity */
kSmallAllocationThreshold)));
ShellBufferFactory::Initialize();
ShellAudioStreamer::Initialize();
SetInstance(this);
}
ShellMediaPlatformStarboard::~ShellMediaPlatformStarboard() {
DCHECK_EQ(Instance(), this);
SetInstance(NULL);
ShellAudioStreamer::Terminate();
ShellBufferFactory::Terminate();
}
void* ShellMediaPlatformStarboard::AllocateBuffer(size_t size) {
if (kGPUMemoryBufferBudget) {
return gpu_memory_pool_->Allocate(size, kMediaBufferAlignment);
}
return main_memory_pool_->Allocate(size, kMediaBufferAlignment);
}
void ShellMediaPlatformStarboard::FreeBuffer(void* ptr) {
if (kGPUMemoryBufferBudget) {
return gpu_memory_pool_->Free(ptr);
}
return main_memory_pool_->Free(ptr);
}
scoped_refptr<DecoderBuffer>
ShellMediaPlatformStarboard::ProcessBeforeLeavingDemuxer(
const scoped_refptr<DecoderBuffer>& buffer) {
// TODO: Completely remove GPU buffer for the new DecoderBuffer
// implementation.
return buffer;
}
bool ShellMediaPlatformStarboard::IsOutputProtected() {
if (SbMediaIsOutputProtected()) {
return true;
}
return SbMediaSetOutputProtection(true);
}
} // namespace media