// Copyright 2014 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 "media/cast/test/fake_media_source.h"

#include <utility>

#include "base/bind.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_fifo.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/media.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/cast/cast_sender.h"
#include "media/cast/test/utility/audio_utility.h"
#include "media/cast/test/utility/video_utility.h"
#include "starboard/types.h"
#include "ui/gfx/geometry/size.h"

// TODO(miu): Figure out why _mkdir() and _rmdir() are missing when compiling
// third_party/ffmpeg/libavformat/os_support.h (lines 182, 183).
// http://crbug.com/572986
#if defined(OS_WIN)
#include <direct.h>
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/ffmpeg/ffmpeg_deleters.h"
#include "media/filters/ffmpeg_glue.h"
#include "media/filters/in_memory_url_protocol.h"
#else
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/ffmpeg/ffmpeg_deleters.h"
#include "media/filters/ffmpeg_glue.h"
#include "media/filters/in_memory_url_protocol.h"
#endif  // defined(OS_WIN)

namespace {

static const int kSoundFrequency = 440;  // Frequency of sinusoid wave.
static const float kSoundVolume = 0.10f;
static const int kAudioFrameMs = 10;  // Each audio frame is exactly 10ms.
static const int kAudioPacketsPerSecond = 1000 / kAudioFrameMs;

// Bounds for variable frame size mode.
static const int kMinFakeFrameWidth = 60;
static const int kMinFakeFrameHeight = 34;
static const int kStartingFakeFrameWidth = 854;
static const int kStartingFakeFrameHeight = 480;
static const int kMaxFakeFrameWidth = 1280;
static const int kMaxFakeFrameHeight = 720;
static const int kMaxFrameSizeChangeMillis = 5000;

void AVFreeFrame(AVFrame* frame) { av_frame_free(&frame); }

base::TimeDelta PtsToTimeDelta(int64_t pts, const AVRational& time_base) {
  return pts * base::TimeDelta::FromSeconds(1) * time_base.num / time_base.den;
}

int64_t TimeDeltaToPts(base::TimeDelta delta, const AVRational& time_base) {
  return static_cast<int64_t>(
      delta.InSecondsF() * time_base.den / time_base.num + 0.5 /* rounding */);
}

}  // namespace

namespace cobalt {
namespace media {
namespace cast {

FakeMediaSource::FakeMediaSource(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    base::TickClock* clock, const FrameSenderConfig& audio_config,
    const FrameSenderConfig& video_config, bool keep_frames)
    : task_runner_(task_runner),
      output_audio_params_(AudioParameters::AUDIO_PCM_LINEAR,
                           media::GuessChannelLayout(audio_config.channels),
                           audio_config.rtp_timebase, 32,
                           audio_config.rtp_timebase / kAudioPacketsPerSecond),
      video_config_(video_config),
      keep_frames_(keep_frames),
      variable_frame_size_mode_(false),
      synthetic_count_(0),
      clock_(clock),
      audio_frame_count_(0),
      video_frame_count_(0),
      av_format_context_(NULL),
      audio_stream_index_(-1),
      playback_rate_(1.0),
      video_stream_index_(-1),
      video_frame_rate_numerator_(video_config.max_frame_rate),
      video_frame_rate_denominator_(1),
      video_first_pts_(0),
      video_first_pts_set_(false),
      weak_factory_(this) {
  CHECK(output_audio_params_.IsValid());
  audio_bus_factory_.reset(
      new TestAudioBusFactory(audio_config.channels, audio_config.rtp_timebase,
                              kSoundFrequency, kSoundVolume));
}

FakeMediaSource::~FakeMediaSource() {}

void FakeMediaSource::SetSourceFile(const base::FilePath& video_file,
                                    int final_fps) {
  DCHECK(!video_file.empty());

  LOG(INFO) << "Source: " << video_file.value();
  if (!file_data_.Initialize(video_file)) {
    LOG(ERROR) << "Cannot load file.";
    return;
  }
  protocol_.reset(
      new InMemoryUrlProtocol(file_data_.data(), file_data_.length(), false));
  glue_.reset(new FFmpegGlue(protocol_.get()));

  if (!glue_->OpenContext()) {
    LOG(ERROR) << "Cannot open file.";
    return;
  }

  // AVFormatContext is owned by the glue.
  av_format_context_ = glue_->format_context();
  if (avformat_find_stream_info(av_format_context_, NULL) < 0) {
    LOG(ERROR) << "Cannot find stream information.";
    return;
  }

  // Prepare FFmpeg decoders.
  for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) {
    AVStream* av_stream = av_format_context_->streams[i];
    AVCodecContext* av_codec_context = av_stream->codec;
    AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id);

    if (!av_codec) {
      LOG(ERROR) << "Cannot find decoder for the codec: "
                 << av_codec_context->codec_id;
      continue;
    }

    // Number of threads for decoding.
    av_codec_context->thread_count = 2;
    av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
    av_codec_context->request_sample_fmt = AV_SAMPLE_FMT_S16;

    if (avcodec_open2(av_codec_context, av_codec, NULL) < 0) {
      LOG(ERROR) << "Cannot open AVCodecContext for the codec: "
                 << av_codec_context->codec_id;
      return;
    }

    if (av_codec->type == AVMEDIA_TYPE_AUDIO) {
      if (av_codec_context->sample_fmt == AV_SAMPLE_FMT_S16P) {
        LOG(ERROR) << "Audio format not supported.";
        continue;
      }
      ChannelLayout layout = ChannelLayoutToChromeChannelLayout(
          av_codec_context->channel_layout, av_codec_context->channels);
      if (layout == CHANNEL_LAYOUT_UNSUPPORTED) {
        LOG(ERROR) << "Unsupported audio channels layout.";
        continue;
      }
      if (audio_stream_index_ != -1) {
        LOG(WARNING) << "Found multiple audio streams.";
      }
      audio_stream_index_ = static_cast<int>(i);
      source_audio_params_.Reset(
          AudioParameters::AUDIO_PCM_LINEAR, layout,
          av_codec_context->sample_rate,
          8 * av_get_bytes_per_sample(av_codec_context->sample_fmt),
          av_codec_context->sample_rate / kAudioPacketsPerSecond);
      source_audio_params_.set_channels_for_discrete(
          av_codec_context->channels);
      CHECK(source_audio_params_.IsValid());
      LOG(INFO) << "Source file has audio.";
    } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) {
      VideoPixelFormat format =
          AVPixelFormatToVideoPixelFormat(av_codec_context->pix_fmt);
      if (format != PIXEL_FORMAT_YV12) {
        LOG(ERROR) << "Cannot handle non YV12 video format: " << format;
        continue;
      }
      if (video_stream_index_ != -1) {
        LOG(WARNING) << "Found multiple video streams.";
      }
      video_stream_index_ = static_cast<int>(i);
      if (final_fps > 0) {
        // If video is played at a manual speed audio needs to match.
        playback_rate_ = 1.0 * final_fps * av_stream->r_frame_rate.den /
                         av_stream->r_frame_rate.num;
        video_frame_rate_numerator_ = final_fps;
        video_frame_rate_denominator_ = 1;
      } else {
        playback_rate_ = 1.0;
        video_frame_rate_numerator_ = av_stream->r_frame_rate.num;
        video_frame_rate_denominator_ = av_stream->r_frame_rate.den;
      }
      LOG(INFO) << "Source file has video.";
    } else {
      LOG(ERROR) << "Unknown stream type; ignore.";
    }
  }

  Rewind();
}

void FakeMediaSource::SetVariableFrameSizeMode(bool enabled) {
  variable_frame_size_mode_ = enabled;
}

void FakeMediaSource::Start(scoped_refptr<AudioFrameInput> audio_frame_input,
                            scoped_refptr<VideoFrameInput> video_frame_input) {
  audio_frame_input_ = audio_frame_input;
  video_frame_input_ = video_frame_input;

  LOG(INFO) << "Max Frame rate: " << video_config_.max_frame_rate;
  LOG(INFO) << "Source Frame rate: " << video_frame_rate_numerator_ << "/"
            << video_frame_rate_denominator_ << " fps.";
  LOG(INFO) << "Audio playback rate: " << playback_rate_;

  if (start_time_.is_null()) start_time_ = clock_->NowTicks();

  if (!is_transcoding_audio() && !is_transcoding_video()) {
    // Send fake patterns.
    task_runner_->PostTask(FROM_HERE,
                           base::Bind(&FakeMediaSource::SendNextFakeFrame,
                                      weak_factory_.GetWeakPtr()));
    return;
  }

  // Send transcoding streams.
  audio_algo_.Initialize(source_audio_params_);
  audio_algo_.FlushBuffers();
  audio_fifo_input_bus_ =
      AudioBus::Create(source_audio_params_.channels(),
                       source_audio_params_.frames_per_buffer());
  // Audio FIFO can carry all data fron AudioRendererAlgorithm.
  audio_fifo_.reset(new AudioFifo(source_audio_params_.channels(),
                                  audio_algo_.QueueCapacity()));
  audio_converter_.reset(new media::AudioConverter(source_audio_params_,
                                                   output_audio_params_, true));
  audio_converter_->AddInput(this);
  task_runner_->PostTask(FROM_HERE, base::Bind(&FakeMediaSource::SendNextFrame,
                                               weak_factory_.GetWeakPtr()));
}

void FakeMediaSource::SendNextFakeFrame() {
  UpdateNextFrameSize();
  scoped_refptr<VideoFrame> video_frame =
      VideoFrame::CreateBlackFrame(current_frame_size_);
  PopulateVideoFrame(video_frame.get(), synthetic_count_);
  ++synthetic_count_;

  const base::TimeTicks now = clock_->NowTicks();

  base::TimeDelta video_time = VideoFrameTime(++video_frame_count_);
  video_frame->set_timestamp(video_time);
  if (keep_frames_) inserted_video_frame_queue_.push(video_frame);
  video_frame_input_->InsertRawVideoFrame(video_frame,
                                          start_time_ + video_time);

  // Send just enough audio data to match next video frame's time.
  base::TimeDelta audio_time = AudioFrameTime(audio_frame_count_);
  while (audio_time < video_time) {
    if (is_transcoding_audio()) {
      Decode(true);
      CHECK(!audio_bus_queue_.empty()) << "No audio decoded.";
      std::unique_ptr<AudioBus> bus(audio_bus_queue_.front());
      audio_bus_queue_.pop();
      audio_frame_input_->InsertAudio(std::move(bus), start_time_ + audio_time);
    } else {
      audio_frame_input_->InsertAudio(
          audio_bus_factory_->NextAudioBus(
              base::TimeDelta::FromMilliseconds(kAudioFrameMs)),
          start_time_ + audio_time);
    }
    audio_time = AudioFrameTime(++audio_frame_count_);
  }

  // This is the time since FakeMediaSource was started.
  const base::TimeDelta elapsed_time = now - start_time_;

  // Handle the case when frame generation cannot keep up.
  // Move the time ahead to match the next frame.
  while (video_time < elapsed_time) {
    LOG(WARNING) << "Skipping one frame.";
    video_time = VideoFrameTime(++video_frame_count_);
  }

  task_runner_->PostDelayedTask(FROM_HERE,
                                base::Bind(&FakeMediaSource::SendNextFakeFrame,
                                           weak_factory_.GetWeakPtr()),
                                video_time - elapsed_time);
}

void FakeMediaSource::UpdateNextFrameSize() {
  if (variable_frame_size_mode_) {
    bool update_size_change_time = false;
    if (current_frame_size_.IsEmpty()) {
      current_frame_size_ =
          gfx::Size(kStartingFakeFrameWidth, kStartingFakeFrameHeight);
      update_size_change_time = true;
    } else if (clock_->NowTicks() >= next_frame_size_change_time_) {
      current_frame_size_ =
          gfx::Size(base::RandInt(kMinFakeFrameWidth, kMaxFakeFrameWidth),
                    base::RandInt(kMinFakeFrameHeight, kMaxFakeFrameHeight));
      update_size_change_time = true;
    }

    if (update_size_change_time) {
      next_frame_size_change_time_ =
          clock_->NowTicks() +
          base::TimeDelta::FromMillisecondsD(base::RandDouble() *
                                             kMaxFrameSizeChangeMillis);
    }
  } else {
    current_frame_size_ =
        gfx::Size(kStartingFakeFrameWidth, kStartingFakeFrameHeight);
    next_frame_size_change_time_ = base::TimeTicks();
  }
}

bool FakeMediaSource::SendNextTranscodedVideo(base::TimeDelta elapsed_time) {
  if (!is_transcoding_video()) return false;

  Decode(false);
  if (video_frame_queue_.empty()) return false;

  const scoped_refptr<VideoFrame> video_frame = video_frame_queue_.front();
  if (elapsed_time < video_frame->timestamp()) return false;
  video_frame_queue_.pop();

  // Use the timestamp from the file if we're transcoding.
  video_frame->set_timestamp(ScaleTimestamp(video_frame->timestamp()));
  if (keep_frames_) inserted_video_frame_queue_.push(video_frame);
  video_frame_input_->InsertRawVideoFrame(
      video_frame, start_time_ + video_frame->timestamp());

  // Make sure queue is not empty.
  Decode(false);
  return true;
}

bool FakeMediaSource::SendNextTranscodedAudio(base::TimeDelta elapsed_time) {
  if (!is_transcoding_audio()) return false;

  Decode(true);
  if (audio_bus_queue_.empty()) return false;

  base::TimeDelta audio_time = audio_sent_ts_->GetTimestamp();
  if (elapsed_time < audio_time) return false;
  std::unique_ptr<AudioBus> bus(audio_bus_queue_.front());
  audio_bus_queue_.pop();
  audio_sent_ts_->AddFrames(bus->frames());
  audio_frame_input_->InsertAudio(std::move(bus), start_time_ + audio_time);

  // Make sure queue is not empty.
  Decode(true);
  return true;
}

void FakeMediaSource::SendNextFrame() {
  // Send as much as possible. Audio is sent according to
  // system time.
  while (SendNextTranscodedAudio(clock_->NowTicks() - start_time_)) {
  }

  // Video is sync'ed to audio.
  while (SendNextTranscodedVideo(audio_sent_ts_->GetTimestamp())) {
  }

  if (audio_bus_queue_.empty() && video_frame_queue_.empty()) {
    // Both queues are empty can only mean that we have reached
    // the end of the stream.
    LOG(INFO) << "Rewind.";
    Rewind();
  }

  // Send next send.
  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FakeMediaSource::SendNextFrame, weak_factory_.GetWeakPtr()),
      base::TimeDelta::FromMilliseconds(kAudioFrameMs));
}

base::TimeDelta FakeMediaSource::VideoFrameTime(int frame_number) {
  return frame_number * base::TimeDelta::FromSeconds(1) *
         video_frame_rate_denominator_ / video_frame_rate_numerator_;
}

base::TimeDelta FakeMediaSource::ScaleTimestamp(base::TimeDelta timestamp) {
  return base::TimeDelta::FromSecondsD(timestamp.InSecondsF() / playback_rate_);
}

base::TimeDelta FakeMediaSource::AudioFrameTime(int frame_number) {
  return frame_number * base::TimeDelta::FromMilliseconds(kAudioFrameMs);
}

void FakeMediaSource::Rewind() {
  CHECK(av_seek_frame(av_format_context_, -1, 0, AVSEEK_FLAG_BACKWARD) >= 0)
      << "Failed to rewind to the beginning.";
}

ScopedAVPacket FakeMediaSource::DemuxOnePacket(bool* audio) {
  ScopedAVPacket packet(new AVPacket());
  if (av_read_frame(av_format_context_, packet.get()) < 0) {
    VLOG(1) << "Failed to read one AVPacket.";
    packet.reset();
    return packet;
  }

  int stream_index = static_cast<int>(packet->stream_index);
  if (stream_index == audio_stream_index_) {
    *audio = true;
  } else if (stream_index == video_stream_index_) {
    *audio = false;
  } else {
    // Ignore unknown packet.
    LOG(INFO) << "Unknown packet.";
    packet.reset();
  }
  return packet;
}

void FakeMediaSource::DecodeAudio(ScopedAVPacket packet) {
  // Audio.
  AVFrame* avframe = av_frame_alloc();

  // Make a shallow copy of packet so we can slide packet.data as frames are
  // decoded from the packet; otherwise av_packet_unref() will corrupt memory.
  AVPacket packet_temp = *packet.get();

  do {
    int frame_decoded = 0;
    int result = avcodec_decode_audio4(av_audio_context(), avframe,
                                       &frame_decoded, &packet_temp);
    CHECK(result >= 0) << "Failed to decode audio.";
    packet_temp.size -= result;
    packet_temp.data += result;
    if (!frame_decoded) continue;

    int frames_read = avframe->nb_samples;
    if (frames_read < 0) break;

    if (!audio_sent_ts_) {
      // Initialize the base time to the first packet in the file.
      // This is set to the frequency we send to the receiver.
      // Not the frequency of the source file. This is because we
      // increment the frame count by samples we sent.
      audio_sent_ts_.reset(
          new AudioTimestampHelper(output_audio_params_.sample_rate()));
      // For some files this is an invalid value.
      base::TimeDelta base_ts;
      audio_sent_ts_->SetBaseTimestamp(base_ts);
    }

    scoped_refptr<AudioBuffer> buffer = AudioBuffer::CopyFrom(
        AVSampleFormatToSampleFormat(av_audio_context()->sample_fmt,
                                     av_audio_context()->codec_id),
        ChannelLayoutToChromeChannelLayout(av_audio_context()->channel_layout,
                                           av_audio_context()->channels),
        av_audio_context()->channels, av_audio_context()->sample_rate,
        frames_read, &avframe->data[0],
        PtsToTimeDelta(avframe->pkt_pts, av_audio_stream()->time_base));
    audio_algo_.EnqueueBuffer(buffer);
    av_frame_unref(avframe);
  } while (packet_temp.size > 0);
  av_frame_free(&avframe);

  const int frames_needed_to_scale =
      playback_rate_ * av_audio_context()->sample_rate / kAudioPacketsPerSecond;
  while (frames_needed_to_scale <= audio_algo_.frames_buffered()) {
    if (!audio_algo_.FillBuffer(audio_fifo_input_bus_.get(), 0,
                                audio_fifo_input_bus_->frames(),
                                playback_rate_)) {
      // Nothing can be scaled. Decode some more.
      return;
    }

    // Prevent overflow of audio data in the FIFO.
    if (audio_fifo_input_bus_->frames() + audio_fifo_->frames() <=
        audio_fifo_->max_frames()) {
      audio_fifo_->Push(audio_fifo_input_bus_.get());
    } else {
      LOG(WARNING) << "Audio FIFO full; dropping samples.";
    }

    // Make sure there's enough data to resample audio.
    if (audio_fifo_->frames() <
        2 * source_audio_params_.sample_rate() / kAudioPacketsPerSecond) {
      continue;
    }

    std::unique_ptr<media::AudioBus> resampled_bus(media::AudioBus::Create(
        output_audio_params_.channels(),
        output_audio_params_.sample_rate() / kAudioPacketsPerSecond));
    audio_converter_->Convert(resampled_bus.get());
    audio_bus_queue_.push(resampled_bus.release());
  }
}

void FakeMediaSource::DecodeVideo(ScopedAVPacket packet) {
  // Video.
  int got_picture;
  AVFrame* avframe = av_frame_alloc();
  CHECK(avcodec_decode_video2(av_video_context(), avframe, &got_picture,
                              packet.get()) >= 0)
      << "Video decode error.";
  if (!got_picture) {
    av_frame_free(&avframe);
    return;
  }
  gfx::Size size(av_video_context()->width, av_video_context()->height);

  if (!video_first_pts_set_) {
    video_first_pts_ = avframe->pkt_pts;
    video_first_pts_set_ = true;
  }
  const AVRational& time_base = av_video_stream()->time_base;
  base::TimeDelta timestamp =
      PtsToTimeDelta(avframe->pkt_pts - video_first_pts_, time_base);
  if (timestamp < last_video_frame_timestamp_) {
    // Stream has rewound.  Rebase |video_first_pts_|.
    const AVRational& frame_rate = av_video_stream()->r_frame_rate;
    timestamp = last_video_frame_timestamp_ + (base::TimeDelta::FromSeconds(1) *
                                               frame_rate.den / frame_rate.num);
    const int64_t adjustment_pts = TimeDeltaToPts(timestamp, time_base);
    video_first_pts_ = avframe->pkt_pts - adjustment_pts;
  }

  scoped_refptr<media::VideoFrame> video_frame =
      VideoFrame::WrapExternalYuvData(
          media::PIXEL_FORMAT_YV12, size, gfx::Rect(size), size,
          avframe->linesize[0], avframe->linesize[1], avframe->linesize[2],
          avframe->data[0], avframe->data[1], avframe->data[2], timestamp);
  if (!video_frame) return;
  video_frame_queue_.push(video_frame);
  video_frame_queue_.back()->AddDestructionObserver(
      base::Bind(&AVFreeFrame, avframe));
  last_video_frame_timestamp_ = timestamp;
}

void FakeMediaSource::Decode(bool decode_audio) {
  // Read the stream until one video frame can be decoded.
  while (true) {
    if (decode_audio && !audio_bus_queue_.empty()) return;
    if (!decode_audio && !video_frame_queue_.empty()) return;

    bool audio_packet = false;
    ScopedAVPacket packet = DemuxOnePacket(&audio_packet);
    if (!packet) {
      VLOG(1) << "End of stream.";
      return;
    }

    if (audio_packet)
      DecodeAudio(std::move(packet));
    else
      DecodeVideo(std::move(packet));
  }
}

double FakeMediaSource::ProvideInput(media::AudioBus* output_bus,
                                     uint32_t frames_delayed) {
  if (audio_fifo_->frames() >= output_bus->frames()) {
    audio_fifo_->Consume(output_bus, 0, output_bus->frames());
    return 1.0;
  } else {
    LOG(WARNING) << "Not enough audio data for resampling.";
    output_bus->Zero();
    return 0.0;
  }
}

scoped_refptr<media::VideoFrame>
FakeMediaSource::PopOldestInsertedVideoFrame() {
  CHECK(!inserted_video_frame_queue_.empty());
  scoped_refptr<media::VideoFrame> video_frame =
      inserted_video_frame_queue_.front();
  inserted_video_frame_queue_.pop();
  return video_frame;
}

AVStream* FakeMediaSource::av_audio_stream() {
  return av_format_context_->streams[audio_stream_index_];
}

AVStream* FakeMediaSource::av_video_stream() {
  return av_format_context_->streams[video_stream_index_];
}

AVCodecContext* FakeMediaSource::av_audio_context() {
  return av_audio_stream()->codec;
}

AVCodecContext* FakeMediaSource::av_video_context() {
  return av_video_stream()->codec;
}

}  // namespace cast
}  // namespace media
}  // namespace cobalt
