| // 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 "cobalt/media/base/decoder_buffer.h" |
| #include "starboard/memory.h" |
| |
| namespace cobalt { |
| namespace media { |
| |
| DecoderBuffer::ScopedAllocatorPtr::ScopedAllocatorPtr(Allocator* allocator, |
| Type type, size_t size) |
| : allocator_(allocator), type_(type), ptr_(NULL) { |
| if (size > 0) { |
| DCHECK(allocator_); |
| ptr_ = static_cast<uint8_t*>( |
| allocator_->Allocate(type_, size + kPaddingSize, kAlignmentSize)); |
| if (ptr_) { |
| SbMemorySet(ptr_ + size, 0, kPaddingSize); |
| } |
| } |
| } |
| |
| DecoderBuffer::ScopedAllocatorPtr::~ScopedAllocatorPtr() { |
| // |allocator_| can be NULL for EOS buffer. |
| if (allocator_ && ptr_) { |
| allocator_->Free(type_, ptr_); |
| } |
| } |
| |
| DecoderBuffer::DecoderBuffer() |
| : allocator_(NULL), |
| type_(DemuxerStream::UNKNOWN), |
| allocated_size_(0), |
| size_(0), |
| data_(NULL, DemuxerStream::UNKNOWN, 0), |
| side_data_size_(0), |
| side_data_(NULL, DemuxerStream::UNKNOWN, 0), |
| splice_timestamp_(kNoTimestamp), |
| is_key_frame_(false) {} |
| |
| DecoderBuffer::DecoderBuffer(Allocator* allocator, Type type, size_t size) |
| : allocator_(allocator), |
| type_(type), |
| allocated_size_(size), |
| size_(size), |
| data_(allocator_, type, size), |
| side_data_size_(0), |
| side_data_(allocator_, type, 0), |
| splice_timestamp_(kNoTimestamp), |
| is_key_frame_(false) {} |
| |
| DecoderBuffer::DecoderBuffer(Allocator* allocator, Type type, |
| const uint8_t* data, size_t size, |
| const uint8_t* side_data, size_t side_data_size) |
| : allocator_(allocator), |
| type_(type), |
| allocated_size_(size), |
| size_(size), |
| data_(allocator_, type, size), |
| side_data_size_(side_data_size), |
| side_data_(allocator_, type, side_data_size), |
| splice_timestamp_(kNoTimestamp), |
| is_key_frame_(false) { |
| if (!data) { |
| CHECK_EQ(size_, 0u); |
| CHECK(!side_data); |
| return; |
| } |
| |
| SbMemoryCopy(data_.get(), data, size_); |
| |
| if (!side_data) { |
| CHECK_EQ(side_data_size, 0u); |
| return; |
| } |
| |
| DCHECK_GT(side_data_size_, 0u); |
| SbMemoryCopy(side_data_.get(), side_data, side_data_size_); |
| } |
| |
| DecoderBuffer::~DecoderBuffer() {} |
| |
| // static |
| scoped_refptr<DecoderBuffer> DecoderBuffer::Create(Allocator* allocator, |
| Type type, size_t size) { |
| DCHECK_GT(size, 0); |
| scoped_refptr<DecoderBuffer> decoder_buffer = |
| new DecoderBuffer(allocator, type, size); |
| if (decoder_buffer->has_data()) { |
| return decoder_buffer; |
| } |
| return NULL; |
| } |
| |
| // static |
| scoped_refptr<DecoderBuffer> DecoderBuffer::CopyFrom(Allocator* allocator, |
| Type type, |
| const uint8_t* data, |
| size_t data_size) { |
| // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. |
| CHECK(data); |
| scoped_refptr<DecoderBuffer> decoder_buffer = |
| new DecoderBuffer(allocator, type, data, data_size, NULL, 0); |
| if (decoder_buffer->has_data()) { |
| return decoder_buffer; |
| } |
| return NULL; |
| } |
| |
| // static |
| scoped_refptr<DecoderBuffer> DecoderBuffer::CopyFrom( |
| Allocator* allocator, Type type, const uint8_t* data, size_t data_size, |
| const uint8_t* side_data, size_t side_data_size) { |
| // If you hit this CHECK you likely have a bug in a demuxer. Go fix it. |
| CHECK(data); |
| CHECK(side_data); |
| scoped_refptr<DecoderBuffer> decoder_buffer = new DecoderBuffer( |
| allocator, type, data, data_size, side_data, side_data_size); |
| if (decoder_buffer->has_data() && decoder_buffer->has_side_data()) { |
| return decoder_buffer; |
| } |
| return NULL; |
| } |
| |
| // static |
| scoped_refptr<DecoderBuffer> DecoderBuffer::CreateEOSBuffer() { |
| return make_scoped_refptr(new DecoderBuffer); |
| } |
| |
| const char* DecoderBuffer::GetTypeName() const { |
| switch (type()) { |
| case DemuxerStream::AUDIO: |
| return "audio"; |
| case DemuxerStream::VIDEO: |
| return "video"; |
| case DemuxerStream::TEXT: |
| return "text"; |
| case DemuxerStream::UNKNOWN: |
| return "unknown"; |
| case DemuxerStream::NUM_TYPES: |
| // Fall-through to NOTREACHED(). |
| break; |
| } |
| NOTREACHED(); |
| return ""; |
| } |
| |
| std::string DecoderBuffer::AsHumanReadableString() { |
| if (end_of_stream()) { |
| return "end of stream"; |
| } |
| |
| std::ostringstream s; |
| s << "type: " << GetTypeName() |
| << " 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; |
| } |
| |
| } // namespace media |
| } // namespace cobalt |