/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */
#ifndef AOM_TEST_Y4M_VIDEO_SOURCE_H_
#define AOM_TEST_Y4M_VIDEO_SOURCE_H_
#include <algorithm>
#include <memory>
#include <string>

#include "common/y4minput.h"
#include "test/video_source.h"

namespace libaom_test {

// This class extends VideoSource to allow parsing of raw yv12
// so that we can do actual file encodes.
class Y4mVideoSource : public VideoSource {
 public:
  Y4mVideoSource(const std::string &file_name, unsigned int start, int limit)
      : file_name_(file_name), input_file_(NULL), img_(new aom_image_t()),
        start_(start), limit_(limit), frame_(0), framerate_numerator_(0),
        framerate_denominator_(0), y4m_() {}

  virtual ~Y4mVideoSource() {
    aom_img_free(img_.get());
    CloseSource();
  }

  virtual void OpenSource() {
    CloseSource();
    input_file_ = OpenTestDataFile(file_name_);
    ASSERT_TRUE(input_file_ != NULL)
        << "Input file open failed. Filename: " << file_name_;
  }

  virtual void ReadSourceToStart() {
    ASSERT_TRUE(input_file_ != NULL);
    ASSERT_FALSE(
        y4m_input_open(&y4m_, input_file_, NULL, 0, AOM_CSP_UNKNOWN, 0));
    framerate_numerator_ = y4m_.fps_n;
    framerate_denominator_ = y4m_.fps_d;
    frame_ = 0;
    for (unsigned int i = 0; i < start_; i++) {
      Next();
    }
    FillFrame();
  }

  virtual void Begin() {
    OpenSource();
    ReadSourceToStart();
  }

  virtual void Next() {
    ++frame_;
    FillFrame();
  }

  virtual aom_image_t *img() const {
    return (frame_ < limit_) ? img_.get() : NULL;
  }

  // Models a stream where Timebase = 1/FPS, so pts == frame.
  virtual aom_codec_pts_t pts() const { return frame_; }

  virtual unsigned long duration() const { return 1; }

  virtual aom_rational_t timebase() const {
    const aom_rational_t t = { framerate_denominator_, framerate_numerator_ };
    return t;
  }

  virtual unsigned int frame() const { return frame_; }

  virtual unsigned int limit() const { return limit_; }

  virtual void FillFrame() {
    ASSERT_TRUE(input_file_ != NULL);
    // Read a frame from input_file.
    y4m_input_fetch_frame(&y4m_, input_file_, img_.get());
  }

  // Swap buffers with another y4m source. This allows reading a new frame
  // while keeping the old frame around. A whole Y4mSource is required and
  // not just a aom_image_t because of how the y4m reader manipulates
  // aom_image_t internals,
  void SwapBuffers(Y4mVideoSource *other) {
    std::swap(other->y4m_.dst_buf, y4m_.dst_buf);
    aom_image_t *tmp;
    tmp = other->img_.release();
    other->img_.reset(img_.release());
    img_.reset(tmp);
  }

 protected:
  void CloseSource() {
    y4m_input_close(&y4m_);
    y4m_ = y4m_input();
    if (input_file_ != NULL) {
      fclose(input_file_);
      input_file_ = NULL;
    }
  }

  std::string file_name_;
  FILE *input_file_;
  std::unique_ptr<aom_image_t> img_;
  unsigned int start_;
  unsigned int limit_;
  unsigned int frame_;
  int framerate_numerator_;
  int framerate_denominator_;
  y4m_input y4m_;
};

}  // namespace libaom_test

#endif  // AOM_TEST_Y4M_VIDEO_SOURCE_H_
