// 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/stream_parser_buffer.h"

#include <algorithm>
#include <memory>

#include "base/logging.h"
#include "cobalt/media/base/timestamp_constants.h"

namespace cobalt {
namespace media {

scoped_refptr<StreamParserBuffer> StreamParserBuffer::CreateEOSBuffer() {
  return base::WrapRefCounted(new StreamParserBuffer);
}

scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
    Allocator* allocator, const uint8_t* data, int data_size, bool is_key_frame,
    Type type, TrackId track_id) {
  scoped_refptr<StreamParserBuffer> stream_parser_buffer =
      base::WrapRefCounted(new StreamParserBuffer(
          allocator, data, data_size, NULL, 0, is_key_frame, type, track_id));
  if (!stream_parser_buffer->has_data()) {
    return NULL;
  }
  return stream_parser_buffer;
}

scoped_refptr<StreamParserBuffer> StreamParserBuffer::CopyFrom(
    Allocator* allocator, const uint8_t* data, int data_size,
    const uint8_t* side_data, int side_data_size, bool is_key_frame, Type type,
    TrackId track_id) {
  return base::WrapRefCounted(
      new StreamParserBuffer(allocator, data, data_size, side_data,
                             side_data_size, is_key_frame, type, track_id));
}

DecodeTimestamp StreamParserBuffer::GetDecodeTimestamp() const {
  if (decode_timestamp_ == kNoDecodeTimestamp())
    return DecodeTimestamp::FromPresentationTime(timestamp());
  return decode_timestamp_;
}

void StreamParserBuffer::SetDecodeTimestamp(DecodeTimestamp timestamp) {
  decode_timestamp_ = timestamp;
  if (preroll_buffer_.get()) preroll_buffer_->SetDecodeTimestamp(timestamp);
}

StreamParserBuffer::StreamParserBuffer()
    : decode_timestamp_(kNoDecodeTimestamp()),
      config_id_(kInvalidConfigId),
      track_id_(0),
      is_duration_estimated_(false) {}

StreamParserBuffer::StreamParserBuffer(Allocator* allocator,
                                       const uint8_t* data, int data_size,
                                       const uint8_t* side_data,
                                       int side_data_size, bool is_key_frame,
                                       Type type, TrackId track_id)
    : DecoderBuffer(allocator, type, data, data_size, side_data,
                    side_data_size),
      decode_timestamp_(kNoDecodeTimestamp()),
      config_id_(kInvalidConfigId),
      track_id_(track_id),
      is_duration_estimated_(false) {
  if (allocations().number_of_buffers() == 0) {
    return;
  }
  // TODO(scherkus): Should DataBuffer constructor accept a timestamp and
  // duration to force clients to set them? Today they end up being zero which
  // is both a common and valid value and could lead to bugs.
  if (data) {
    set_duration(kNoTimestamp);
  }

  if (is_key_frame) set_is_key_frame(true);
}

StreamParserBuffer::StreamParserBuffer(Allocator* allocator,
                                       Allocator::Allocations allocations,
                                       const uint8_t* side_data,
                                       int side_data_size, bool is_key_frame,
                                       Type type, TrackId track_id)
    : DecoderBuffer(allocator, type, allocations, side_data, side_data_size),
      decode_timestamp_(kNoDecodeTimestamp()),
      config_id_(kInvalidConfigId),
      track_id_(track_id),
      is_duration_estimated_(false) {
  // TODO(scherkus): Should DataBuffer constructor accept a timestamp and
  // duration to force clients to set them? Today they end up being zero which
  // is both a common and valid value and could lead to bugs.
  set_duration(kNoTimestamp);

  if (is_key_frame) set_is_key_frame(true);
}

StreamParserBuffer::~StreamParserBuffer() {}

int StreamParserBuffer::GetConfigId() const { return config_id_; }

void StreamParserBuffer::SetConfigId(int config_id) {
  config_id_ = config_id;
  if (preroll_buffer_.get()) preroll_buffer_->SetConfigId(config_id);
}

int StreamParserBuffer::GetSpliceBufferConfigId(size_t index) const {
  if (!splice_buffers_ || index >= splice_buffers().size()) {
    return GetConfigId();
  }
  return (*splice_buffers_)[index]->GetConfigId();
}

void StreamParserBuffer::ConvertToSpliceBuffer(
    const BufferQueue& pre_splice_buffers) {
  DCHECK(!splice_buffers_);
  DCHECK(duration() > base::TimeDelta())
      << "Only buffers with a valid duration can convert to a splice buffer."
      << " pts " << timestamp().InSecondsF() << " dts "
      << GetDecodeTimestamp().InSecondsF() << " dur "
      << duration().InSecondsF();
  DCHECK(!end_of_stream());

  // Splicing requires non-estimated sample accurate durations to be confident
  // things will sound smooth. Also, we cannot be certain whether estimated
  // overlap is really a splice scenario, or just over estimation.
  DCHECK(!is_duration_estimated_);

  // Make a copy of this first, before making any changes.
  scoped_refptr<StreamParserBuffer> overlapping_buffer = Clone();
  overlapping_buffer->set_splice_timestamp(kNoTimestamp);

  const scoped_refptr<StreamParserBuffer>& first_splice_buffer =
      pre_splice_buffers.front();

  // Ensure the given buffers are actually before the splice point.
  DCHECK(first_splice_buffer->timestamp() <= overlapping_buffer->timestamp());

  // TODO(dalecurtis): We should also clear |data|, but since that implies EOS
  // care must be taken to ensure there are no clients relying on that behavior.

  // Move over any preroll from this buffer.
  if (preroll_buffer_.get()) {
    DCHECK(!overlapping_buffer->preroll_buffer_.get());
    overlapping_buffer->preroll_buffer_.swap(preroll_buffer_);
  }

  // Rewrite |this| buffer as a splice buffer.
  SetDecodeTimestamp(first_splice_buffer->GetDecodeTimestamp());
  SetConfigId(first_splice_buffer->GetConfigId());
  set_timestamp(first_splice_buffer->timestamp());
  set_is_key_frame(first_splice_buffer->is_key_frame());
  DCHECK_EQ(type(), first_splice_buffer->type());
  track_id_ = first_splice_buffer->track_id();
  set_splice_timestamp(overlapping_buffer->timestamp());

  // The splice duration is the duration of all buffers before the splice plus
  // the highest ending timestamp after the splice point.
  DCHECK(overlapping_buffer->duration() > base::TimeDelta());
  DCHECK(pre_splice_buffers.back()->duration() > base::TimeDelta());
  set_duration(
      std::max(overlapping_buffer->timestamp() + overlapping_buffer->duration(),
               pre_splice_buffers.back()->timestamp() +
                   pre_splice_buffers.back()->duration()) -
      first_splice_buffer->timestamp());

  splice_buffers_.reset(new BufferQueue);
  // Copy all pre splice buffers into our wrapper buffer.
  for (BufferQueue::const_iterator it = pre_splice_buffers.begin();
       it != pre_splice_buffers.end(); ++it) {
    const scoped_refptr<StreamParserBuffer>& buffer = *it;
    DCHECK(!buffer->end_of_stream());
    DCHECK(!buffer->preroll_buffer().get());
    DCHECK(buffer->splice_buffers().empty());
    DCHECK(!buffer->is_duration_estimated());
    splice_buffers_->push_back(buffer->Clone());
    splice_buffers_->back()->set_splice_timestamp(splice_timestamp());
  }

  splice_buffers_->push_back(overlapping_buffer);
}

void StreamParserBuffer::SetPrerollBuffer(
    const scoped_refptr<StreamParserBuffer>& preroll_buffer) {
  DCHECK(!preroll_buffer_.get());
  DCHECK(!end_of_stream());
  DCHECK(!preroll_buffer->end_of_stream());
  DCHECK(!preroll_buffer->preroll_buffer_.get());
  DCHECK(preroll_buffer->splice_timestamp() == kNoTimestamp);
  DCHECK(preroll_buffer->splice_buffers().empty());
  DCHECK(preroll_buffer->timestamp() <= timestamp());
  DCHECK(preroll_buffer->discard_padding() == DecoderBuffer::DiscardPadding());
  DCHECK_EQ(preroll_buffer->type(), type());
  DCHECK_EQ(preroll_buffer->track_id(), track_id());

  preroll_buffer_ = preroll_buffer;
  preroll_buffer_->set_timestamp(timestamp());
  preroll_buffer_->SetDecodeTimestamp(GetDecodeTimestamp());

  // Mark the entire buffer for discard.
  preroll_buffer_->set_discard_padding(
      std::make_pair(kInfiniteDuration, base::TimeDelta()));
}

void StreamParserBuffer::set_timestamp(base::TimeDelta timestamp) {
  DecoderBuffer::set_timestamp(timestamp);
  if (preroll_buffer_.get()) preroll_buffer_->set_timestamp(timestamp);
}

scoped_refptr<StreamParserBuffer> StreamParserBuffer::Clone() const {
  if (end_of_stream()) {
    return StreamParserBuffer::CreateEOSBuffer();
  }

  scoped_refptr<StreamParserBuffer> clone = new StreamParserBuffer(
      allocator(), allocations(), side_data(), side_data_size(), is_key_frame(),
      type(), track_id());
  clone->SetDecodeTimestamp(GetDecodeTimestamp());
  clone->SetConfigId(GetConfigId());
  clone->set_timestamp(timestamp());
  clone->set_duration(duration());
  clone->set_is_duration_estimated(is_duration_estimated());
  clone->set_discard_padding(discard_padding());
  clone->set_splice_timestamp(splice_timestamp());
  const DecryptConfig* decrypt_config = this->decrypt_config();
  if (decrypt_config) {
    clone->set_decrypt_config(
        std::make_unique<DecryptConfig>(
          decrypt_config->encryption_mode(),
                          decrypt_config->key_id(), decrypt_config->iv(),
                          decrypt_config->subsamples(),
                          decrypt_config->encryption_pattern()));
  }

  return clone;
}

}  // namespace media
}  // namespace cobalt
