/*
 * 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_IVF_VIDEO_SOURCE_H_
#define AOM_TEST_IVF_VIDEO_SOURCE_H_

#include <cstdio>
#include <cstdlib>
#include <new>
#include <string>

#include "aom_ports/sanitizer.h"
#include "test/video_source.h"

namespace libaom_test {
const unsigned int kCodeBufferSize = 256 * 1024 * 1024;
const unsigned int kIvfFileHdrSize = 32;
const unsigned int kIvfFrameHdrSize = 12;

static unsigned int MemGetLe32(const uint8_t *mem) {
  return (mem[3] << 24) | (mem[2] << 16) | (mem[1] << 8) | (mem[0]);
}

// This class extends VideoSource to allow parsing of ivf files,
// so that we can do actual file decodes.
class IVFVideoSource : public CompressedVideoSource {
 public:
  explicit IVFVideoSource(const std::string &file_name)
      : file_name_(file_name), input_file_(nullptr),
        compressed_frame_buf_(nullptr), frame_sz_(0), frame_(0),
        end_of_file_(false) {}

  virtual ~IVFVideoSource() {
    delete[] compressed_frame_buf_;

    if (input_file_) fclose(input_file_);
  }

  virtual void Init() {
    // Allocate a buffer for read in the compressed video frame.
    compressed_frame_buf_ = new uint8_t[kCodeBufferSize];
    ASSERT_NE(compressed_frame_buf_, nullptr) << "Allocate frame buffer failed";
    ASAN_POISON_MEMORY_REGION(compressed_frame_buf_, kCodeBufferSize);
  }

  virtual void Begin() {
    input_file_ = OpenTestDataFile(file_name_);
    ASSERT_NE(input_file_, nullptr)
        << "Input file open failed. Filename: " << file_name_;

    // Read file header
    uint8_t file_hdr[kIvfFileHdrSize];
    ASSERT_EQ(kIvfFileHdrSize, fread(file_hdr, 1, kIvfFileHdrSize, input_file_))
        << "File header read failed.";
    // Check file header
    ASSERT_TRUE(file_hdr[0] == 'D' && file_hdr[1] == 'K' &&
                file_hdr[2] == 'I' && file_hdr[3] == 'F')
        << "Input is not an IVF file.";

    FillFrame();
  }

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

  void FillFrame() {
    ASSERT_NE(input_file_, nullptr);
    uint8_t frame_hdr[kIvfFrameHdrSize];
    // Check frame header and read a frame from input_file.
    if (fread(frame_hdr, 1, kIvfFrameHdrSize, input_file_) !=
        kIvfFrameHdrSize) {
      end_of_file_ = true;
    } else {
      end_of_file_ = false;

      frame_sz_ = MemGetLe32(frame_hdr);
      ASSERT_LE(frame_sz_, kCodeBufferSize)
          << "Frame is too big for allocated code buffer";
      ASAN_UNPOISON_MEMORY_REGION(compressed_frame_buf_, kCodeBufferSize);
      ASSERT_EQ(frame_sz_,
                fread(compressed_frame_buf_, 1, frame_sz_, input_file_))
          << "Failed to read complete frame";
      ASAN_POISON_MEMORY_REGION(compressed_frame_buf_ + frame_sz_,
                                kCodeBufferSize - frame_sz_);
    }
  }

  virtual const uint8_t *cxdata() const {
    return end_of_file_ ? nullptr : compressed_frame_buf_;
  }
  virtual size_t frame_size() const { return frame_sz_; }
  virtual unsigned int frame_number() const { return frame_; }

 protected:
  std::string file_name_;
  FILE *input_file_;
  uint8_t *compressed_frame_buf_;
  size_t frame_sz_;
  unsigned int frame_;
  bool end_of_file_;
};

}  // namespace libaom_test

#endif  // AOM_TEST_IVF_VIDEO_SOURCE_H_
