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

#include "config/aom_config.h"

#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);
#if CONFIG_NEW_CSP
    ASSERT_FALSE(
        y4m_input_open(&y4m_, input_file_, NULL, 0, AOM_CSP_UNSPECIFIED, 0));
#else
    ASSERT_FALSE(
        y4m_input_open(&y4m_, input_file_, NULL, 0, AOM_CSP_UNKNOWN, 0));
#endif  // CONFIG_NEW_CSP
    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_
