/*
 *  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.
 */

#ifndef TEST_TESTSUPPORT_FRAME_READER_H_
#define TEST_TESTSUPPORT_FRAME_READER_H_

#include <stdio.h>

#include <optional>
#include <string>

#include "api/scoped_refptr.h"
#include "api/video/resolution.h"

namespace webrtc {
class I420Buffer;
namespace test {

// Handles reading of I420 frames from video files.
class FrameReader {
 public:
  struct Ratio {
    int num = 1;
    int den = 1;
  };

  static constexpr Ratio kNoScale = Ratio({.num = 1, .den = 1});

  virtual ~FrameReader() {}

  // Reads and returns next frame. Returns `nullptr` if reading failed or end of
  // stream is reached.
  virtual rtc::scoped_refptr<I420Buffer> PullFrame() = 0;

  // Reads and returns next frame. `frame_num` stores unwrapped frame number
  // which can be passed to `ReadFrame` to re-read this frame later. Returns
  // `nullptr` if reading failed or end of stream is reached.
  virtual rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num) = 0;

  // Reads and returns frame specified by `frame_num`. Returns `nullptr` if
  // reading failed.
  virtual rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num) = 0;

  // Reads next frame, resizes and returns it. `frame_num` stores unwrapped
  // frame number which can be passed to `ReadFrame` to re-read this frame
  // later. `resolution` specifies resolution of the returned frame.
  // `framerate_scale` specifies frame rate scale factor. Frame rate scaling is
  // done by skipping or repeating frames.
  virtual rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num,
                                                   Resolution resolution,
                                                   Ratio framerate_scale) = 0;

  // Reads frame specified by `frame_num`, resizes and returns it. Returns
  // `nullptr` if reading failed.
  virtual rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num,
                                                   Resolution resolution) = 0;

  // Total number of retrievable frames.
  virtual int num_frames() const = 0;
};

class YuvFrameReaderImpl : public FrameReader {
 public:
  enum class RepeatMode { kSingle, kRepeat, kPingPong };

  // Creates the frame reader for a YUV file specified by `filepath`.
  // `resolution` specifies width and height of frames in pixels. `repeat_mode`
  // specifies behaviour of the reader at reaching the end of file (stop, read
  // it over from the beginning or read in reverse order). The file is assumed
  // to exist, be readable and to contain at least 1 frame.
  YuvFrameReaderImpl(std::string filepath,
                     Resolution resolution,
                     RepeatMode repeat_mode);

  ~YuvFrameReaderImpl() override;

  virtual void Init();

  rtc::scoped_refptr<I420Buffer> PullFrame() override;

  rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num) override;

  rtc::scoped_refptr<I420Buffer> PullFrame(int* frame_num,
                                           Resolution resolution,
                                           Ratio framerate_scale) override;

  rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num) override;

  rtc::scoped_refptr<I420Buffer> ReadFrame(int frame_num,
                                           Resolution resolution) override;

  int num_frames() const override { return num_frames_; }

 protected:
  class RateScaler {
   public:
    int Skip(Ratio framerate_scale);

   private:
    std::optional<int> ticks_;
  };

  const std::string filepath_;
  Resolution resolution_;
  const RepeatMode repeat_mode_;
  int num_frames_;
  int frame_num_;
  int frame_size_bytes_;
  int header_size_bytes_;
  FILE* file_;
  RateScaler framerate_scaler_;
};

class Y4mFrameReaderImpl : public YuvFrameReaderImpl {
 public:
  // Creates the frame reader for a Y4M file specified by `filepath`.
  // `repeat_mode` specifies behaviour of the reader at reaching the end of file
  // (stop, read it over from the beginning or read in reverse order). The file
  // is assumed to exist, be readable and to contain at least 1 frame.
  Y4mFrameReaderImpl(std::string filepath, RepeatMode repeat_mode);

  void Init() override;
};

std::unique_ptr<FrameReader> CreateYuvFrameReader(std::string filepath,
                                                  Resolution resolution);

std::unique_ptr<FrameReader> CreateYuvFrameReader(
    std::string filepath,
    Resolution resolution,
    YuvFrameReaderImpl::RepeatMode repeat_mode);

std::unique_ptr<FrameReader> CreateY4mFrameReader(std::string filepath);

std::unique_ptr<FrameReader> CreateY4mFrameReader(
    std::string filepath,
    YuvFrameReaderImpl::RepeatMode repeat_mode);

}  // namespace test
}  // namespace webrtc

#endif  // TEST_TESTSUPPORT_FRAME_READER_H_
