blob: e986ffb3733fc0cbfe0073bde5ab75beda0cbfd5 [file] [log] [blame]
John Koleszarb9180fc2012-05-16 15:27:00 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
John Koleszarb9180fc2012-05-16 15:27:00 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
John Koleszarb9180fc2012-05-16 15:27:00 -070010 */
11#ifndef TEST_VIDEO_SOURCE_H_
12#define TEST_VIDEO_SOURCE_H_
Johanne3e63fb2012-07-23 14:55:32 -070013
Deb Mukherjee096224f2014-07-14 13:31:29 -070014#if defined(_WIN32)
James Zern18bd24b2015-10-06 23:05:15 -070015#undef NOMINMAX
James Zern5d912012015-09-29 20:28:47 -070016#define NOMINMAX
17#define WIN32_LEAN_AND_MEAN
Deb Mukherjee096224f2014-07-14 13:31:29 -070018#include <windows.h>
19#endif
Yunqing Wang15dffcf2012-10-04 12:59:36 -070020#include <cstdio>
21#include <cstdlib>
22#include <string>
Johanne3e63fb2012-07-23 14:55:32 -070023#include "test/acm_random.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070024#include "aom/aom_encoder.h"
John Koleszarb9180fc2012-05-16 15:27:00 -070025
Yaowu Xuc27fc142016-08-22 16:08:15 -070026namespace libaom_test {
John Koleszarb9180fc2012-05-16 15:27:00 -070027
Yaowu Xu97aa09f2016-10-12 08:25:39 -070028// Helper macros to ensure LIBAOM_TEST_DATA_PATH is a quoted string.
Joshua Littab9160d2013-11-04 13:47:30 -080029// These are undefined right below GetDataPath
Yaowu Xu97aa09f2016-10-12 08:25:39 -070030// NOTE: LIBAOM_TEST_DATA_PATH MUST NOT be a quoted string before
Joshua Littab9160d2013-11-04 13:47:30 -080031// Stringification or the GetDataPath will fail at runtime
32#define TO_STRING(S) #S
33#define STRINGIFY(S) TO_STRING(S)
Yunqing Wang15dffcf2012-10-04 12:59:36 -070034
Joshua Littab9160d2013-11-04 13:47:30 -080035// A simple function to encapsulate cross platform retrieval of test data path
36static std::string GetDataPath() {
Yaowu Xu97aa09f2016-10-12 08:25:39 -070037 const char *const data_path = getenv("LIBAOM_TEST_DATA_PATH");
Joshua Littab9160d2013-11-04 13:47:30 -080038 if (data_path == NULL) {
Yaowu Xu97aa09f2016-10-12 08:25:39 -070039#ifdef LIBAOM_TEST_DATA_PATH
Joshua Littab9160d2013-11-04 13:47:30 -080040 // In some environments, we cannot set environment variables
41 // Instead, we set the data path by using a preprocessor symbol
42 // which can be set from make files
Yaowu Xu97aa09f2016-10-12 08:25:39 -070043 return STRINGIFY(LIBAOM_TEST_DATA_PATH);
Joshua Littab9160d2013-11-04 13:47:30 -080044#else
45 return ".";
46#endif
Yunqing Wang15dffcf2012-10-04 12:59:36 -070047 }
Joshua Littab9160d2013-11-04 13:47:30 -080048 return data_path;
49}
Yunqing Wang15dffcf2012-10-04 12:59:36 -070050
Joshua Littab9160d2013-11-04 13:47:30 -080051// Undefining stringification macros because they are not used elsewhere
52#undef TO_STRING
53#undef STRINGIFY
54
clang-format3a826f12016-08-11 17:46:05 -070055inline FILE *OpenTestDataFile(const std::string &file_name) {
Joshua Littab9160d2013-11-04 13:47:30 -080056 const std::string path_to_source = GetDataPath() + "/" + file_name;
Yunqing Wang15dffcf2012-10-04 12:59:36 -070057 return fopen(path_to_source.c_str(), "rb");
58}
59
Deb Mukherjeea4635132014-08-11 13:44:27 -070060static FILE *GetTempOutFile(std::string *file_name) {
61 file_name->clear();
Deb Mukherjee096224f2014-07-14 13:31:29 -070062#if defined(_WIN32)
63 char fname[MAX_PATH];
Deb Mukherjeea4635132014-08-11 13:44:27 -070064 char tmppath[MAX_PATH];
65 if (GetTempPathA(MAX_PATH, tmppath)) {
66 // Assume for now that the filename generated is unique per process
67 if (GetTempFileNameA(tmppath, "lvx", 0, fname)) {
68 file_name->assign(fname);
69 return fopen(fname, "wb+");
70 }
Deb Mukherjee096224f2014-07-14 13:31:29 -070071 }
Deb Mukherjeea4635132014-08-11 13:44:27 -070072 return NULL;
Deb Mukherjee096224f2014-07-14 13:31:29 -070073#else
Deb Mukherjeea4635132014-08-11 13:44:27 -070074 return tmpfile();
Deb Mukherjee096224f2014-07-14 13:31:29 -070075#endif
Deb Mukherjee5820c5d2014-06-12 16:53:13 -070076}
77
Deb Mukherjee096224f2014-07-14 13:31:29 -070078class TempOutFile {
79 public:
clang-format3a826f12016-08-11 17:46:05 -070080 TempOutFile() { file_ = GetTempOutFile(&file_name_); }
Deb Mukherjee096224f2014-07-14 13:31:29 -070081 ~TempOutFile() {
82 CloseFile();
83 if (!file_name_.empty()) {
Deb Mukherjeea4635132014-08-11 13:44:27 -070084 EXPECT_EQ(0, remove(file_name_.c_str()));
Deb Mukherjee096224f2014-07-14 13:31:29 -070085 }
86 }
clang-format3a826f12016-08-11 17:46:05 -070087 FILE *file() { return file_; }
88 const std::string &file_name() { return file_name_; }
Deb Mukherjeea4635132014-08-11 13:44:27 -070089
90 protected:
Deb Mukherjee096224f2014-07-14 13:31:29 -070091 void CloseFile() {
92 if (file_) {
Deb Mukherjee4851b992014-08-14 14:59:50 -070093 fclose(file_);
Deb Mukherjee096224f2014-07-14 13:31:29 -070094 file_ = NULL;
95 }
96 }
Deb Mukherjee096224f2014-07-14 13:31:29 -070097 FILE *file_;
98 std::string file_name_;
99};
100
John Koleszarb9180fc2012-05-16 15:27:00 -0700101// Abstract base class for test video sources, which provide a stream of
Yaowu Xuf883b422016-08-30 14:01:10 -0700102// aom_image_t images with associated timestamps and duration.
John Koleszarb9180fc2012-05-16 15:27:00 -0700103class VideoSource {
104 public:
105 virtual ~VideoSource() {}
106
107 // Prepare the stream for reading, rewind/open as necessary.
108 virtual void Begin() = 0;
109
110 // Advance the cursor to the next frame
111 virtual void Next() = 0;
112
113 // Get the current video frame, or NULL on End-Of-Stream.
Yaowu Xuf883b422016-08-30 14:01:10 -0700114 virtual aom_image_t *img() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700115
116 // Get the presentation timestamp of the current frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700117 virtual aom_codec_pts_t pts() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700118
119 // Get the current frame's duration
120 virtual unsigned long duration() const = 0;
121
122 // Get the timebase for the stream
Yaowu Xuf883b422016-08-30 14:01:10 -0700123 virtual aom_rational_t timebase() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700124
125 // Get the current frame counter, starting at 0.
126 virtual unsigned int frame() const = 0;
Jim Bankoski65d73882012-10-26 19:49:44 -0700127
128 // Get the current file limit.
129 virtual unsigned int limit() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700130};
131
John Koleszarb9180fc2012-05-16 15:27:00 -0700132class DummyVideoSource : public VideoSource {
133 public:
Alex Converse797a2552015-01-15 13:56:55 -0800134 DummyVideoSource()
clang-format3a826f12016-08-11 17:46:05 -0700135 : img_(NULL), limit_(100), width_(80), height_(64),
Yaowu Xuf883b422016-08-30 14:01:10 -0700136 format_(AOM_IMG_FMT_I420) {
Alex Converse797a2552015-01-15 13:56:55 -0800137 ReallocImage();
John Koleszar2fb29ff2012-05-23 12:55:27 -0700138 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700139
Yaowu Xuf883b422016-08-30 14:01:10 -0700140 virtual ~DummyVideoSource() { aom_img_free(img_); }
John Koleszarb9180fc2012-05-16 15:27:00 -0700141
142 virtual void Begin() {
143 frame_ = 0;
144 FillFrame();
145 }
146
147 virtual void Next() {
148 ++frame_;
149 FillFrame();
150 }
151
Yaowu Xuf883b422016-08-30 14:01:10 -0700152 virtual aom_image_t *img() const { return (frame_ < limit_) ? img_ : NULL; }
John Koleszarb9180fc2012-05-16 15:27:00 -0700153
154 // Models a stream where Timebase = 1/FPS, so pts == frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700155 virtual aom_codec_pts_t pts() const { return frame_; }
John Koleszarb9180fc2012-05-16 15:27:00 -0700156
157 virtual unsigned long duration() const { return 1; }
158
Yaowu Xuf883b422016-08-30 14:01:10 -0700159 virtual aom_rational_t timebase() const {
160 const aom_rational_t t = { 1, 30 };
John Koleszarb9180fc2012-05-16 15:27:00 -0700161 return t;
162 }
163
164 virtual unsigned int frame() const { return frame_; }
165
Jim Bankoski65d73882012-10-26 19:49:44 -0700166 virtual unsigned int limit() const { return limit_; }
167
clang-format3a826f12016-08-11 17:46:05 -0700168 void set_limit(unsigned int limit) { limit_ = limit; }
Jim Bankoski943e4322014-07-17 06:31:50 -0700169
John Koleszarb9180fc2012-05-16 15:27:00 -0700170 void SetSize(unsigned int width, unsigned int height) {
John Koleszar2fb29ff2012-05-23 12:55:27 -0700171 if (width != width_ || height != height_) {
John Koleszar2fb29ff2012-05-23 12:55:27 -0700172 width_ = width;
173 height_ = height;
Alex Converse797a2552015-01-15 13:56:55 -0800174 ReallocImage();
175 }
176 }
177
Yaowu Xuf883b422016-08-30 14:01:10 -0700178 void SetImageFormat(aom_img_fmt_t format) {
Alex Converse797a2552015-01-15 13:56:55 -0800179 if (format_ != format) {
180 format_ = format;
181 ReallocImage();
John Koleszar2fb29ff2012-05-23 12:55:27 -0700182 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700183 }
184
185 protected:
clang-format3a826f12016-08-11 17:46:05 -0700186 virtual void FillFrame() {
187 if (img_) memset(img_->img_data, 0, raw_sz_);
188 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700189
Alex Converse797a2552015-01-15 13:56:55 -0800190 void ReallocImage() {
Yaowu Xuf883b422016-08-30 14:01:10 -0700191 aom_img_free(img_);
192 img_ = aom_img_alloc(NULL, format_, width_, height_, 32);
Alex Converse797a2552015-01-15 13:56:55 -0800193 raw_sz_ = ((img_->w + 31) & ~31) * img_->h * img_->bps / 8;
194 }
195
Yaowu Xuf883b422016-08-30 14:01:10 -0700196 aom_image_t *img_;
clang-format3a826f12016-08-11 17:46:05 -0700197 size_t raw_sz_;
John Koleszarb9180fc2012-05-16 15:27:00 -0700198 unsigned int limit_;
199 unsigned int frame_;
John Koleszar2fb29ff2012-05-23 12:55:27 -0700200 unsigned int width_;
201 unsigned int height_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700202 aom_img_fmt_t format_;
John Koleszarb9180fc2012-05-16 15:27:00 -0700203};
204
John Koleszarb9180fc2012-05-16 15:27:00 -0700205class RandomVideoSource : public DummyVideoSource {
Johanne3e63fb2012-07-23 14:55:32 -0700206 public:
Johann9ec25522012-07-23 15:06:12 -0700207 RandomVideoSource(int seed = ACMRandom::DeterministicSeed())
clang-format3a826f12016-08-11 17:46:05 -0700208 : rnd_(seed), seed_(seed) {}
Johanne3e63fb2012-07-23 14:55:32 -0700209
John Koleszarb9180fc2012-05-16 15:27:00 -0700210 protected:
Johanne3e63fb2012-07-23 14:55:32 -0700211 // Reset the RNG to get a matching stream for the second pass
212 virtual void Begin() {
213 frame_ = 0;
Johann9ec25522012-07-23 15:06:12 -0700214 rnd_.Reset(seed_);
Johanne3e63fb2012-07-23 14:55:32 -0700215 FillFrame();
216 }
217
John Koleszarb9180fc2012-05-16 15:27:00 -0700218 // 15 frames of noise, followed by 15 static frames. Reset to 0 rather
219 // than holding previous frames to encourage keyframes to be thrown.
220 virtual void FillFrame() {
Deb Mukherjeebdbaa5b2014-07-18 03:06:07 -0700221 if (img_) {
222 if (frame_ % 30 < 15)
clang-format3a826f12016-08-11 17:46:05 -0700223 for (size_t i = 0; i < raw_sz_; ++i) img_->img_data[i] = rnd_.Rand8();
Deb Mukherjeebdbaa5b2014-07-18 03:06:07 -0700224 else
225 memset(img_->img_data, 0, raw_sz_);
226 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700227 }
Johanne3e63fb2012-07-23 14:55:32 -0700228
229 ACMRandom rnd_;
Johann9ec25522012-07-23 15:06:12 -0700230 int seed_;
John Koleszarb9180fc2012-05-16 15:27:00 -0700231};
232
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700233// Abstract base class for test video sources, which provide a stream of
234// decompressed images to the decoder.
235class CompressedVideoSource {
236 public:
237 virtual ~CompressedVideoSource() {}
238
239 virtual void Init() = 0;
240
241 // Prepare the stream for reading, rewind/open as necessary.
242 virtual void Begin() = 0;
243
244 // Advance the cursor to the next frame
245 virtual void Next() = 0;
246
247 virtual const uint8_t *cxdata() const = 0;
248
Tom Fineganeb2325e2014-02-19 14:17:55 -0800249 virtual size_t frame_size() const = 0;
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700250
Tom Fineganeb2325e2014-02-19 14:17:55 -0800251 virtual unsigned int frame_number() const = 0;
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700252};
253
Yaowu Xuc27fc142016-08-22 16:08:15 -0700254} // namespace libaom_test
John Koleszarb9180fc2012-05-16 15:27:00 -0700255
256#endif // TEST_VIDEO_SOURCE_H_