// Copyright (c) 2012 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. #include "media/base/decoder_buffer.h" namespace media { // Allocates a block of memory which is padded for use with the SIMD // optimizations used by FFmpeg. static uint8* AllocateFFmpegSafeBlock(int size) { uint8* const block = reinterpret_cast(base::AlignedAlloc( size + DecoderBuffer::kPaddingSize, DecoderBuffer::kAlignmentSize)); memset(block + size, 0, DecoderBuffer::kPaddingSize); return block; } DecoderBuffer::DecoderBuffer(int size) : size_(size), side_data_size_(0), is_key_frame_(false) { Initialize(); } DecoderBuffer::DecoderBuffer(const uint8* data, int size, const uint8* side_data, int side_data_size) : size_(size), side_data_size_(side_data_size), is_key_frame_(false) { if (!data) { CHECK_EQ(size_, 0); CHECK(!side_data); return; } Initialize(); DCHECK_GE(size_, 0); memcpy(data_.get(), data, size_); if (!side_data) { CHECK_EQ(side_data_size, 0); return; } DCHECK_GT(side_data_size_, 0); memcpy(side_data_.get(), side_data, side_data_size_); } DecoderBuffer::~DecoderBuffer() {} void DecoderBuffer::Initialize() { CHECK_GE(size_, 0); data_.reset(AllocateFFmpegSafeBlock(size_)); if (side_data_size_ > 0) side_data_.reset(AllocateFFmpegSafeBlock(side_data_size_)); splice_timestamp_ = kNoTimestamp(); } // static scoped_refptr DecoderBuffer::CopyFrom(const uint8* data, int data_size) { // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. CHECK(data); return make_scoped_refptr(new DecoderBuffer(data, data_size, NULL, 0)); } // static scoped_refptr DecoderBuffer::CopyFrom(const uint8* data, int data_size, const uint8* side_data, int side_data_size) { // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. CHECK(data); CHECK(side_data); return make_scoped_refptr(new DecoderBuffer(data, data_size, side_data, side_data_size)); } // static scoped_refptr DecoderBuffer::CreateEOSBuffer() { return make_scoped_refptr(new DecoderBuffer(NULL, 0, NULL, 0)); } std::string DecoderBuffer::AsHumanReadableString() { if (end_of_stream()) { return "end of stream"; } std::ostringstream s; s << "timestamp: " << timestamp_.InMicroseconds() << " duration: " << duration_.InMicroseconds() << " size: " << size_ << " side_data_size: " << side_data_size_ << " is_key_frame: " << is_key_frame_ << " encrypted: " << (decrypt_config_ != NULL) << " discard_padding (ms): (" << discard_padding_.first.InMilliseconds() << ", " << discard_padding_.second.InMilliseconds() << ")"; if (decrypt_config_) s << " decrypt:" << (*decrypt_config_); return s.str(); } void DecoderBuffer::set_timestamp(base::TimeDelta timestamp) { DCHECK(!end_of_stream()); timestamp_ = timestamp; } void DecoderBuffer::CopySideDataFrom(const uint8* side_data, int side_data_size) { if (side_data_size > 0) { side_data_size_ = side_data_size; side_data_.reset(AllocateFFmpegSafeBlock(side_data_size_)); memcpy(side_data_.get(), side_data, side_data_size_); } else { side_data_.reset(); side_data_size_ = 0; } } } // namespace media