// 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 "cobalt/build/build_config.h"
#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_);
#if SB_API_VERSION >= 10
    int padding = SbMediaGetBufferPadding(DemuxerStreamTypeToSbMediaType(type));
    int alignment =
        SbMediaGetBufferAlignment(DemuxerStreamTypeToSbMediaType(type));
#else   // SB_API_VERSION >= 10
    int padding = COBALT_MEDIA_BUFFER_PADDING;
    int alignment = COBALT_MEDIA_BUFFER_ALIGNMENT;
#endif  // SB_API_VERSION >= 10
    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
