// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/media/sandbox/media_source_demuxer.h"

#include <algorithm>
#include <memory>
#include <string>

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/sys_byteorder.h"
#include "cobalt/media/base/bind_to_current_loop.h"
#include "cobalt/media/base/demuxer.h"
#include "cobalt/media/base/pipeline_status.h"
#include "cobalt/media/filters/chunk_demuxer.h"
#include "starboard/memory.h"

namespace cobalt {
namespace media {
namespace sandbox {

namespace {

using base::Bind;
using ::media::BindToCurrentLoop;
using ::media::DecoderBuffer;
using ::media::DemuxerStream;
using ::media::ChunkDemuxer;

typedef base::Callback<void(::media::DecoderBuffer*)> AppendBufferCB;

const char kSourceId[] = "id";

// Stub log function.
void Log(const std::string& message) { SB_UNREFERENCED_PARAMETER(message); }

// Stub need key callback.
void NeedKeyCB(const std::string& type, std::unique_ptr<uint8[]> init_data,
               int init_data_size) {
  NOTREACHED();
}

bool IsMP4(const std::vector<uint8>& content) {
  return content.size() >= 8 && SbMemoryCompare(&content[4], "ftyp", 4) == 0;
}

std::vector<std::string> MakeStringVector(const char* string) {
  std::vector<std::string> result;
  result.push_back(string);
  return result;
}

bool AddSourceBuffer(bool is_mp4, ChunkDemuxer* demuxer) {
  const char kMP4Mime[] = "video/mp4";
  const char kAVCCodecs[] = "avc1.640028";
  const char kWebMMime[] = "video/webm";
  const char kVp9Codecs[] = "vp9";

  std::vector<std::string> codecs =
      MakeStringVector(is_mp4 ? kAVCCodecs : kVp9Codecs);
  ChunkDemuxer::Status status =
      demuxer->AddId(kSourceId, is_mp4 ? kMP4Mime : kWebMMime, codecs);
  CHECK_EQ(status, ChunkDemuxer::kOk);
  return status == ChunkDemuxer::kOk;
}

// Helper class to load an adaptive video file and call |append_buffer_cb| for
// every frame.
class Loader : public ::media::DemuxerHost {
 public:
  Loader(const std::vector<uint8>& content,
         const AppendBufferCB& append_buffer_cb)
      : valid_(true),
        ended_(false),
        append_buffer_cb_(append_buffer_cb),
        content_(content),
        offset_(0),
        read_in_progress_(false) {
    DCHECK(!append_buffer_cb.is_null());

    demuxer_ = new ChunkDemuxer(
        BindToCurrentLoop(Bind(&Loader::OnDemuxerOpen, base::Unretained(this),
                               IsMP4(content))),
        Bind(NeedKeyCB), Bind(Log));
    demuxer_->Initialize(
        this, ::media::BindToCurrentLoop(
                  Bind(&Loader::OnDemuxerStatus, base::Unretained(this))));
    while (valid_ && !ended_) {
      base::RunLoop().RunUntilIdle();
    }
  }

  bool valid() const { return valid_; }
  const ::media::VideoDecoderConfig& config() const { return config_; }

 private:
  void SetTotalBytes(int64 total_bytes) override {
    SB_UNREFERENCED_PARAMETER(total_bytes);
  }
  void AddBufferedByteRange(int64 start, int64 end) override {
    SB_UNREFERENCED_PARAMETER(start);
    SB_UNREFERENCED_PARAMETER(end);
  }
  void AddBufferedTimeRange(base::TimeDelta start,
                            base::TimeDelta end) override {
    SB_UNREFERENCED_PARAMETER(start);
    SB_UNREFERENCED_PARAMETER(end);
  }

  void SetDuration(base::TimeDelta duration) override {
    SB_UNREFERENCED_PARAMETER(duration);
  }
  void OnDemuxerError(::media::PipelineStatus error) override {
    valid_ = false;
  }
  void OnDemuxerOpen(bool is_mp4) {
    valid_ &= AddSourceBuffer(is_mp4, demuxer_);
    if (!valid_) {
      return;
    }
    ConsumeContent();
    if (!demuxer_->GetStream(DemuxerStream::VIDEO)) {
      valid_ = false;
      return;
    }
    while (valid_ && !ended_) {
      ConsumeContent();
      ProduceBuffer();
      base::RunLoop().RunUntilIdle();
    }
  }
  void OnDemuxerStatus(::media::PipelineStatus status) {
    if (status == ::media::PIPELINE_OK) {
      config_.CopyFrom(
          demuxer_->GetStream(DemuxerStream::VIDEO)->video_decoder_config());
    } else {
      valid_ = false;
    }
  }
  void ConsumeContent() {
    const float kLowWaterMarkInSeconds = 1.f;
    const size_t kMaxBytesToAppend = 5 * 1024 * 1024;

    ::media::Ranges<base::TimeDelta> ranges =
        demuxer_->GetBufferedRanges(kSourceId);
    if (offset_ < content_.size()) {
      base::TimeDelta range_end;
      if (ranges.size() != 0) {
        range_end = ranges.end(ranges.size() - 1);
      }
      if ((range_end - timestamp_of_last_buffer_).InSecondsF() >
          kLowWaterMarkInSeconds) {
        return;
      }
      size_t bytes_to_append =
          std::min(kMaxBytesToAppend, content_.size() - offset_);
      demuxer_->AppendData(kSourceId, &content_[0] + offset_, bytes_to_append);
      offset_ += bytes_to_append;
    }
    if (offset_ == content_.size()) {
      demuxer_->EndOfStream(::media::PIPELINE_OK);
      ++offset_;
    }
  }
  void ProduceBuffer() {
    if (!read_in_progress_) {
      read_in_progress_ = true;
      demuxer_->GetStream(DemuxerStream::VIDEO)
          ->Read(Bind(&Loader::OnDemuxerRead, base::Unretained(this)));
    }
  }
  void OnDemuxerRead(DemuxerStream::Status status,
                     const scoped_refptr<DecoderBuffer>& buffer) {
    // This should only happen during seeking which won't happen to this class.
    DCHECK_NE(status, DemuxerStream::kAborted);
    if (status == DemuxerStream::kConfigChanged) {
      config_.CopyFrom(
          demuxer_->GetStream(DemuxerStream::VIDEO)->video_decoder_config());
      ProduceBuffer();
      return;
    }
    DCHECK_EQ(status, DemuxerStream::kOk);
    if (buffer->IsEndOfStream()) {
      ended_ = true;
    } else {
      timestamp_of_last_buffer_ = buffer->GetTimestamp();
      append_buffer_cb_.Run(buffer);
    }
    read_in_progress_ = false;
  }

  bool valid_;
  bool ended_;
  AppendBufferCB append_buffer_cb_;
  const std::vector<uint8>& content_;
  size_t offset_;
  bool read_in_progress_;
  base::TimeDelta timestamp_of_last_buffer_;
  scoped_refptr<ChunkDemuxer> demuxer_;
  ::media::VideoDecoderConfig config_;
};

// This is a very loose IVF parser for fuzzing purpose and it ignores any
// invalid structure and just retrieves the frame data.
// IVF format (all data is little endian):
//   32 bytes file header starts with DKIF
//     (4 bytes frame size + 8 bytes timestamp + <size> bytes frame data)*
bool LoadIVF(const std::vector<uint8>& content,
             const AppendBufferCB& append_buffer_cb) {
  const size_t kIVFFileHeaderSize = 32;
  const size_t kIVFFrameHeaderSize = 12;
  if (content.size() < kIVFFileHeaderSize ||
      SbMemoryCompare(&content[0], "DKIF", 4) != 0) {
    return false;
  }
  size_t offset = kIVFFileHeaderSize;
  while (offset + kIVFFrameHeaderSize < content.size()) {
    uint32 frame_size = base::ByteSwapToLE32(
        *reinterpret_cast<const uint32*>(&content[offset]));
    offset += kIVFFrameHeaderSize;
    if (offset + frame_size > content.size()) {
      break;
    }
    append_buffer_cb.Run(::media::StreamParserBuffer::CopyFrom(
        &content[offset], frame_size, false));
    offset += frame_size;
  }
  return true;
}

}  // namespace

MediaSourceDemuxer::MediaSourceDemuxer(const std::vector<uint8>& content)
    : valid_(true) {
  // Try to load it as an ivf first.
  if (LoadIVF(content, Bind(&MediaSourceDemuxer::AppendBuffer,
                            base::Unretained(this)))) {
    config_.Initialize(
        ::media::kCodecVP9, ::media::VP9PROFILE_MAIN, ::media::VideoFrame::YV12,
        ::media::COLOR_SPACE_HD_REC709, math::Size(1, 1), math::Rect(1, 1),
        math::Size(1, 1), NULL, 0, false, false);
    valid_ = descs_.size() > 0;
    return;
  }

  Loader loader(
      content, Bind(&MediaSourceDemuxer::AppendBuffer, base::Unretained(this)));
  valid_ = loader.valid();
  if (valid_) {
    config_.CopyFrom(loader.config());
  } else {
    au_data_.clear();
    descs_.clear();
  }
}

void MediaSourceDemuxer::AppendBuffer(::media::DecoderBuffer* buffer) {
  AUDescriptor desc = {0};
  desc.is_keyframe = buffer->IsKeyframe();
  desc.offset = au_data_.size();
  desc.size = buffer->GetDataSize();
  desc.timestamp = buffer->GetTimestamp();

  au_data_.insert(au_data_.end(), buffer->GetData(),
                  buffer->GetData() + buffer->GetDataSize());
  descs_.push_back(desc);
}

const MediaSourceDemuxer::AUDescriptor& MediaSourceDemuxer::GetFrame(
    size_t index) const {
  DCHECK_LT(index, descs_.size());

  return descs_[index];
}

}  // namespace sandbox
}  // namespace media
}  // namespace cobalt
