blob: 3c1c5e559ea56634f4f263c6342234b8ca3d3333 [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 */
James Zerne1cbb132018-08-22 14:10:36 -070011#ifndef AOM_TEST_VIDEO_SOURCE_H_
12#define AOM_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
Neil Birkbeckeb895ef2018-03-14 17:51:03 -070074 char name_template[] = "/tmp/libaomtest.XXXXXX";
75 const int fd = mkstemp(name_template);
76 *file_name = name_template;
77 return fdopen(fd, "wb+");
Deb Mukherjee096224f2014-07-14 13:31:29 -070078#endif
Deb Mukherjee5820c5d2014-06-12 16:53:13 -070079}
80
Deb Mukherjee096224f2014-07-14 13:31:29 -070081class TempOutFile {
82 public:
clang-format3a826f12016-08-11 17:46:05 -070083 TempOutFile() { file_ = GetTempOutFile(&file_name_); }
Deb Mukherjee096224f2014-07-14 13:31:29 -070084 ~TempOutFile() {
85 CloseFile();
86 if (!file_name_.empty()) {
Deb Mukherjeea4635132014-08-11 13:44:27 -070087 EXPECT_EQ(0, remove(file_name_.c_str()));
Deb Mukherjee096224f2014-07-14 13:31:29 -070088 }
89 }
clang-format3a826f12016-08-11 17:46:05 -070090 FILE *file() { return file_; }
91 const std::string &file_name() { return file_name_; }
Deb Mukherjeea4635132014-08-11 13:44:27 -070092
93 protected:
Deb Mukherjee096224f2014-07-14 13:31:29 -070094 void CloseFile() {
95 if (file_) {
Deb Mukherjee4851b992014-08-14 14:59:50 -070096 fclose(file_);
Deb Mukherjee096224f2014-07-14 13:31:29 -070097 file_ = NULL;
98 }
99 }
Deb Mukherjee096224f2014-07-14 13:31:29 -0700100 FILE *file_;
101 std::string file_name_;
102};
103
John Koleszarb9180fc2012-05-16 15:27:00 -0700104// Abstract base class for test video sources, which provide a stream of
Yaowu Xuf883b422016-08-30 14:01:10 -0700105// aom_image_t images with associated timestamps and duration.
John Koleszarb9180fc2012-05-16 15:27:00 -0700106class VideoSource {
107 public:
108 virtual ~VideoSource() {}
109
110 // Prepare the stream for reading, rewind/open as necessary.
111 virtual void Begin() = 0;
112
113 // Advance the cursor to the next frame
114 virtual void Next() = 0;
115
116 // Get the current video frame, or NULL on End-Of-Stream.
Yaowu Xuf883b422016-08-30 14:01:10 -0700117 virtual aom_image_t *img() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700118
119 // Get the presentation timestamp of the current frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700120 virtual aom_codec_pts_t pts() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700121
122 // Get the current frame's duration
123 virtual unsigned long duration() const = 0;
124
125 // Get the timebase for the stream
Yaowu Xuf883b422016-08-30 14:01:10 -0700126 virtual aom_rational_t timebase() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700127
128 // Get the current frame counter, starting at 0.
129 virtual unsigned int frame() const = 0;
Jim Bankoski65d73882012-10-26 19:49:44 -0700130
131 // Get the current file limit.
132 virtual unsigned int limit() const = 0;
John Koleszarb9180fc2012-05-16 15:27:00 -0700133};
134
John Koleszarb9180fc2012-05-16 15:27:00 -0700135class DummyVideoSource : public VideoSource {
136 public:
Alex Converse797a2552015-01-15 13:56:55 -0800137 DummyVideoSource()
clang-format3a826f12016-08-11 17:46:05 -0700138 : img_(NULL), limit_(100), width_(80), height_(64),
Yaowu Xuf883b422016-08-30 14:01:10 -0700139 format_(AOM_IMG_FMT_I420) {
Alex Converse797a2552015-01-15 13:56:55 -0800140 ReallocImage();
John Koleszar2fb29ff2012-05-23 12:55:27 -0700141 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700142
Yaowu Xuf883b422016-08-30 14:01:10 -0700143 virtual ~DummyVideoSource() { aom_img_free(img_); }
John Koleszarb9180fc2012-05-16 15:27:00 -0700144
145 virtual void Begin() {
146 frame_ = 0;
147 FillFrame();
148 }
149
150 virtual void Next() {
151 ++frame_;
152 FillFrame();
153 }
154
Yaowu Xuf883b422016-08-30 14:01:10 -0700155 virtual aom_image_t *img() const { return (frame_ < limit_) ? img_ : NULL; }
John Koleszarb9180fc2012-05-16 15:27:00 -0700156
157 // Models a stream where Timebase = 1/FPS, so pts == frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700158 virtual aom_codec_pts_t pts() const { return frame_; }
John Koleszarb9180fc2012-05-16 15:27:00 -0700159
160 virtual unsigned long duration() const { return 1; }
161
Yaowu Xuf883b422016-08-30 14:01:10 -0700162 virtual aom_rational_t timebase() const {
163 const aom_rational_t t = { 1, 30 };
John Koleszarb9180fc2012-05-16 15:27:00 -0700164 return t;
165 }
166
167 virtual unsigned int frame() const { return frame_; }
168
Jim Bankoski65d73882012-10-26 19:49:44 -0700169 virtual unsigned int limit() const { return limit_; }
170
clang-format3a826f12016-08-11 17:46:05 -0700171 void set_limit(unsigned int limit) { limit_ = limit; }
Jim Bankoski943e4322014-07-17 06:31:50 -0700172
John Koleszarb9180fc2012-05-16 15:27:00 -0700173 void SetSize(unsigned int width, unsigned int height) {
John Koleszar2fb29ff2012-05-23 12:55:27 -0700174 if (width != width_ || height != height_) {
John Koleszar2fb29ff2012-05-23 12:55:27 -0700175 width_ = width;
176 height_ = height;
Alex Converse797a2552015-01-15 13:56:55 -0800177 ReallocImage();
178 }
179 }
180
Yaowu Xuf883b422016-08-30 14:01:10 -0700181 void SetImageFormat(aom_img_fmt_t format) {
Alex Converse797a2552015-01-15 13:56:55 -0800182 if (format_ != format) {
183 format_ = format;
184 ReallocImage();
John Koleszar2fb29ff2012-05-23 12:55:27 -0700185 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700186 }
187
188 protected:
clang-format3a826f12016-08-11 17:46:05 -0700189 virtual void FillFrame() {
190 if (img_) memset(img_->img_data, 0, raw_sz_);
191 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700192
Alex Converse797a2552015-01-15 13:56:55 -0800193 void ReallocImage() {
Yaowu Xuf883b422016-08-30 14:01:10 -0700194 aom_img_free(img_);
195 img_ = aom_img_alloc(NULL, format_, width_, height_, 32);
Alex Converse797a2552015-01-15 13:56:55 -0800196 raw_sz_ = ((img_->w + 31) & ~31) * img_->h * img_->bps / 8;
197 }
198
Yaowu Xuf883b422016-08-30 14:01:10 -0700199 aom_image_t *img_;
clang-format3a826f12016-08-11 17:46:05 -0700200 size_t raw_sz_;
John Koleszarb9180fc2012-05-16 15:27:00 -0700201 unsigned int limit_;
202 unsigned int frame_;
John Koleszar2fb29ff2012-05-23 12:55:27 -0700203 unsigned int width_;
204 unsigned int height_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700205 aom_img_fmt_t format_;
John Koleszarb9180fc2012-05-16 15:27:00 -0700206};
207
John Koleszarb9180fc2012-05-16 15:27:00 -0700208class RandomVideoSource : public DummyVideoSource {
Johanne3e63fb2012-07-23 14:55:32 -0700209 public:
Johann9ec25522012-07-23 15:06:12 -0700210 RandomVideoSource(int seed = ACMRandom::DeterministicSeed())
clang-format3a826f12016-08-11 17:46:05 -0700211 : rnd_(seed), seed_(seed) {}
Johanne3e63fb2012-07-23 14:55:32 -0700212
John Koleszarb9180fc2012-05-16 15:27:00 -0700213 protected:
Johanne3e63fb2012-07-23 14:55:32 -0700214 // Reset the RNG to get a matching stream for the second pass
215 virtual void Begin() {
216 frame_ = 0;
Johann9ec25522012-07-23 15:06:12 -0700217 rnd_.Reset(seed_);
Johanne3e63fb2012-07-23 14:55:32 -0700218 FillFrame();
219 }
220
John Koleszarb9180fc2012-05-16 15:27:00 -0700221 // 15 frames of noise, followed by 15 static frames. Reset to 0 rather
222 // than holding previous frames to encourage keyframes to be thrown.
223 virtual void FillFrame() {
Deb Mukherjeebdbaa5b2014-07-18 03:06:07 -0700224 if (img_) {
225 if (frame_ % 30 < 15)
clang-format3a826f12016-08-11 17:46:05 -0700226 for (size_t i = 0; i < raw_sz_; ++i) img_->img_data[i] = rnd_.Rand8();
Deb Mukherjeebdbaa5b2014-07-18 03:06:07 -0700227 else
228 memset(img_->img_data, 0, raw_sz_);
229 }
John Koleszarb9180fc2012-05-16 15:27:00 -0700230 }
Johanne3e63fb2012-07-23 14:55:32 -0700231
232 ACMRandom rnd_;
Johann9ec25522012-07-23 15:06:12 -0700233 int seed_;
John Koleszarb9180fc2012-05-16 15:27:00 -0700234};
235
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700236// Abstract base class for test video sources, which provide a stream of
237// decompressed images to the decoder.
238class CompressedVideoSource {
239 public:
240 virtual ~CompressedVideoSource() {}
241
242 virtual void Init() = 0;
243
244 // Prepare the stream for reading, rewind/open as necessary.
245 virtual void Begin() = 0;
246
247 // Advance the cursor to the next frame
248 virtual void Next() = 0;
249
250 virtual const uint8_t *cxdata() const = 0;
251
Tom Fineganeb2325e2014-02-19 14:17:55 -0800252 virtual size_t frame_size() const = 0;
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700253
Tom Fineganeb2325e2014-02-19 14:17:55 -0800254 virtual unsigned int frame_number() const = 0;
Yunqing Wang15dffcf2012-10-04 12:59:36 -0700255};
256
Yaowu Xuc27fc142016-08-22 16:08:15 -0700257} // namespace libaom_test
John Koleszarb9180fc2012-05-16 15:27:00 -0700258
James Zerne1cbb132018-08-22 14:10:36 -0700259#endif // AOM_TEST_VIDEO_SOURCE_H_