/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "vie_file_capture_device.h"

#include <assert.h>

#include "common_types.h"
#include "critical_section_wrapper.h"
#include "event_wrapper.h"
#include "module_common_types.h"
#include "vie_autotest_defines.h"
#include "vie_capture.h"
#include "tick_util.h"

// This class ensures we are not exceeding the max FPS.
class FramePacemaker {
 public:
  explicit FramePacemaker(uint32_t max_fps)
      : time_per_frame_ms_(1000 / max_fps) {
    frame_start_ = webrtc::TickTime::MillisecondTimestamp();
  }

  void SleepIfNecessary(webrtc::EventWrapper* sleeper) {
    uint64_t now = webrtc::TickTime::MillisecondTimestamp();
    if (now - frame_start_ < time_per_frame_ms_) {
      sleeper->Wait(time_per_frame_ms_ - (now - frame_start_));
    }
  }

 private:
  uint64_t frame_start_;
  uint64_t time_per_frame_ms_;
};

ViEFileCaptureDevice::ViEFileCaptureDevice(
    webrtc::ViEExternalCapture* input_sink)
    : input_sink_(input_sink),
      input_file_(NULL) {
  mutex_ = webrtc::CriticalSectionWrapper::CreateCriticalSection();
}

ViEFileCaptureDevice::~ViEFileCaptureDevice() {
  delete mutex_;
}

bool ViEFileCaptureDevice::OpenI420File(const std::string& path,
                                        int width,
                                        int height) {
  webrtc::CriticalSectionScoped cs(*mutex_);
  assert(input_file_ == NULL);

  input_file_ = std::fopen(path.c_str(), "rb");
  if (input_file_ == NULL) {
    return false;
  }

  frame_length_ = 3 * width * height / 2;
  width_  = width;
  height_ = height;
  return true;
}

void ViEFileCaptureDevice::ReadFileFor(uint64_t time_slice_ms,
                                       uint32_t max_fps) {
  webrtc::CriticalSectionScoped cs(*mutex_);
  assert(input_file_ != NULL);

  unsigned char* frame_buffer = new unsigned char[frame_length_];

  webrtc::EventWrapper* sleeper = webrtc::EventWrapper::Create();

  uint64_t start_time_ms = webrtc::TickTime::MillisecondTimestamp();
  uint64_t elapsed_ms = 0;

  while (elapsed_ms < time_slice_ms) {
    FramePacemaker pacemaker(max_fps);
    int read = std::fread(frame_buffer, 1, frame_length_, input_file_);

    if (std::feof(input_file_)) {
      std::rewind(input_file_);
    }
    input_sink_->IncomingFrame(frame_buffer, read, width_, height_,
                               webrtc::kVideoI420,
                               webrtc::TickTime::MillisecondTimestamp());

    pacemaker.SleepIfNecessary(sleeper);
    elapsed_ms = webrtc::TickTime::MillisecondTimestamp() - start_time_ms;
  }

  delete sleeper;
  delete[] frame_buffer;
}

void ViEFileCaptureDevice::CloseFile() {
  webrtc::CriticalSectionScoped cs(*mutex_);
  assert(input_file_ != NULL);

  std::fclose(input_file_);
}
