2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
10 #ifndef TEST_VIDEO_SOURCE_H_
11 #define TEST_VIDEO_SOURCE_H_
19 #include "test/acm_random.h"
20 #include "vpx/vpx_encoder.h"
22 namespace libvpx_test {
24 // Helper macros to ensure LIBVPX_TEST_DATA_PATH is a quoted string.
25 // These are undefined right below GetDataPath
26 // NOTE: LIBVPX_TEST_DATA_PATH MUST NOT be a quoted string before
27 // Stringification or the GetDataPath will fail at runtime
28 #define TO_STRING(S) #S
29 #define STRINGIFY(S) TO_STRING(S)
31 // A simple function to encapsulate cross platform retrieval of test data path
32 static std::string GetDataPath() {
33 const char *const data_path = getenv("LIBVPX_TEST_DATA_PATH");
34 if (data_path == NULL) {
35 #ifdef LIBVPX_TEST_DATA_PATH
36 // In some environments, we cannot set environment variables
37 // Instead, we set the data path by using a preprocessor symbol
38 // which can be set from make files
39 return STRINGIFY(LIBVPX_TEST_DATA_PATH);
47 // Undefining stringification macros because they are not used elsewhere
51 static FILE *OpenTestDataFile(const std::string& file_name) {
52 const std::string path_to_source = GetDataPath() + "/" + file_name;
53 return fopen(path_to_source.c_str(), "rb");
56 static FILE *GetTempOutFile(std::string *file_name) {
60 char tmppath[MAX_PATH];
61 if (GetTempPathA(MAX_PATH, tmppath)) {
62 // Assume for now that the filename generated is unique per process
63 if (GetTempFileNameA(tmppath, "lvx", 0, fname)) {
64 file_name->assign(fname);
65 return fopen(fname, "wb+");
77 file_ = GetTempOutFile(&file_name_);
81 if (!file_name_.empty()) {
82 EXPECT_EQ(0, remove(file_name_.c_str()));
88 const std::string& file_name() {
100 std::string file_name_;
103 // Abstract base class for test video sources, which provide a stream of
104 // vpx_image_t images with associated timestamps and duration.
107 virtual ~VideoSource() {}
109 // Prepare the stream for reading, rewind/open as necessary.
110 virtual void Begin() = 0;
112 // Advance the cursor to the next frame
113 virtual void Next() = 0;
115 // Get the current video frame, or NULL on End-Of-Stream.
116 virtual vpx_image_t *img() const = 0;
118 // Get the presentation timestamp of the current frame.
119 virtual vpx_codec_pts_t pts() const = 0;
121 // Get the current frame's duration
122 virtual unsigned long duration() const = 0;
124 // Get the timebase for the stream
125 virtual vpx_rational_t timebase() const = 0;
127 // Get the current frame counter, starting at 0.
128 virtual unsigned int frame() const = 0;
130 // Get the current file limit.
131 virtual unsigned int limit() const = 0;
135 class DummyVideoSource : public VideoSource {
137 DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) {
141 virtual ~DummyVideoSource() { vpx_img_free(img_); }
143 virtual void Begin() {
148 virtual void Next() {
153 virtual vpx_image_t *img() const {
154 return (frame_ < limit_) ? img_ : NULL;
157 // Models a stream where Timebase = 1/FPS, so pts == frame.
158 virtual vpx_codec_pts_t pts() const { return frame_; }
160 virtual unsigned long duration() const { return 1; }
162 virtual vpx_rational_t timebase() const {
163 const vpx_rational_t t = {1, 30};
167 virtual unsigned int frame() const { return frame_; }
169 virtual unsigned int limit() const { return limit_; }
171 void set_limit(unsigned int limit) {
175 void SetSize(unsigned int width, unsigned int height) {
176 if (width != width_ || height != height_) {
178 raw_sz_ = ((width + 31)&~31) * height * 3 / 2;
179 img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, width, height, 32);
186 virtual void FillFrame() { if (img_) memset(img_->img_data, 0, raw_sz_); }
193 unsigned int height_;
197 class RandomVideoSource : public DummyVideoSource {
199 RandomVideoSource(int seed = ACMRandom::DeterministicSeed())
204 // Reset the RNG to get a matching stream for the second pass
205 virtual void Begin() {
211 // 15 frames of noise, followed by 15 static frames. Reset to 0 rather
212 // than holding previous frames to encourage keyframes to be thrown.
213 virtual void FillFrame() {
215 if (frame_ % 30 < 15)
216 for (size_t i = 0; i < raw_sz_; ++i)
217 img_->img_data[i] = rnd_.Rand8();
219 memset(img_->img_data, 0, raw_sz_);
227 // Abstract base class for test video sources, which provide a stream of
228 // decompressed images to the decoder.
229 class CompressedVideoSource {
231 virtual ~CompressedVideoSource() {}
233 virtual void Init() = 0;
235 // Prepare the stream for reading, rewind/open as necessary.
236 virtual void Begin() = 0;
238 // Advance the cursor to the next frame
239 virtual void Next() = 0;
241 virtual const uint8_t *cxdata() const = 0;
243 virtual size_t frame_size() const = 0;
245 virtual unsigned int frame_number() const = 0;
248 } // namespace libvpx_test
250 #endif // TEST_VIDEO_SOURCE_H_