// 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 <vector>

#include "starboard/media.h"
#include "starboard/memory.h"

namespace cobalt {
namespace media {
namespace {
SbMediaType DemuxerStreamTypeToSbMediaType(DemuxerStream::Type type) {
  switch (type) {
    case DemuxerStream::AUDIO:
      return kSbMediaTypeAudio;
    case DemuxerStream::VIDEO:
      return kSbMediaTypeVideo;
    case DemuxerStream::UNKNOWN:
    case DemuxerStream::TEXT:
    case DemuxerStream::NUM_TYPES:
      break;
  }
  NOTREACHED();
  return kSbMediaTypeAudio;
}
}  // namespace

DecoderBuffer::ScopedAllocatorPtr::ScopedAllocatorPtr(Allocator* allocator,
                                                      Type type, size_t size)
    : allocator_(allocator), type_(type) {
  if (size > 0) {
    DCHECK(allocator_);
    int padding = SbMediaGetBufferPadding(DemuxerStreamTypeToSbMediaType(type));
    int alignment =
        SbMediaGetBufferAlignment(DemuxerStreamTypeToSbMediaType(type));
    allocations_ = allocator_->Allocate(size + padding, alignment,
                                        static_cast<intptr_t>(type));
    static bool logged_warning = false;
    if (padding > 0) {
      if (allocations_.number_of_buffers() > 0) {
        const int kMaxPadding = 1024;
        if (padding > kMaxPadding) {
          if (!logged_warning) {
            LOG(WARNING) << "Media buffer padding is larger than "
                         << kMaxPadding
                         << ", this will cause extra allocations.";
            logged_warning = true;
          }
          std::vector<char> zeros(padding + 1, 0);
          allocations_.Write(size, zeros.data(), padding);
        } else {
          char zeros[kMaxPadding + 1] = {0};
          allocations_.Write(size, zeros, padding);
        }
        allocations_.ShrinkTo(size);
      }
    }
  }
}

DecoderBuffer::ScopedAllocatorPtr::~ScopedAllocatorPtr() {
  // |allocator_| can be NULL for EOS buffer.
  if (allocator_) {
    allocator_->Free(allocations_);
  }
}

DecoderBuffer::DecoderBuffer() : data_(NULL, DemuxerStream::UNKNOWN, 0) {}

DecoderBuffer::DecoderBuffer(Allocator* allocator, Type type, size_t size)
    : data_(allocator, type, size) {}

DecoderBuffer::DecoderBuffer(Allocator* allocator, Type type,
                             const uint8_t* data, size_t size,
                             const uint8_t* side_data, size_t side_data_size)
    : data_(allocator, type, size), side_data_size_(side_data_size) {
  if (!data) {
    CHECK_EQ(size, 0u);
    return;
  }
  if (allocations().number_of_buffers()) {
    allocations().Write(0, data, size);
  }
  if (side_data_size_ > 0) {
    DCHECK(side_data);
    side_data_.reset(new uint8_t[side_data_size_]);
    SbMemoryCopy(side_data_.get(), side_data, side_data_size_);
  }
}

DecoderBuffer::DecoderBuffer(Allocator* allocator, Type type,
                             Allocator::Allocations allocations,
                             const uint8_t* side_data, size_t side_data_size)
    : data_(allocator, type, allocations.size()),
      side_data_size_(side_data_size) {
  int offset = 0;
  for (int i = 0; i < allocations.number_of_buffers(); ++i) {
    this->allocations().Write(offset, allocations.buffers()[i],
                              allocations.buffer_sizes()[i]);
    offset += allocations.buffer_sizes()[i];
  }
  if (side_data_size_ > 0) {
    side_data_.reset(new uint8_t[side_data_size_]);
    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 base::WrapRefCounted(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: " << data_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
