11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann#ifndef TEST_VIDEO_SOURCE_H_ 111b362b15af34006e6a11974088a46d42b903418eJohann#define TEST_VIDEO_SOURCE_H_ 121b362b15af34006e6a11974088a46d42b903418eJohann 131b362b15af34006e6a11974088a46d42b903418eJohann#include <cstdio> 141b362b15af34006e6a11974088a46d42b903418eJohann#include <cstdlib> 151b362b15af34006e6a11974088a46d42b903418eJohann#include <string> 161b362b15af34006e6a11974088a46d42b903418eJohann#include "test/acm_random.h" 171b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx/vpx_encoder.h" 181b362b15af34006e6a11974088a46d42b903418eJohann 191b362b15af34006e6a11974088a46d42b903418eJohannnamespace libvpx_test { 201b362b15af34006e6a11974088a46d42b903418eJohann 215ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// Helper macros to ensure LIBVPX_TEST_DATA_PATH is a quoted string. 225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// These are undefined right below GetDataPath 235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// NOTE: LIBVPX_TEST_DATA_PATH MUST NOT be a quoted string before 245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// Stringification or the GetDataPath will fail at runtime 255ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define TO_STRING(S) #S 265ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define STRINGIFY(S) TO_STRING(S) 271b362b15af34006e6a11974088a46d42b903418eJohann 285ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// A simple function to encapsulate cross platform retrieval of test data path 295ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic std::string GetDataPath() { 305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang const char *const data_path = getenv("LIBVPX_TEST_DATA_PATH"); 315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang if (data_path == NULL) { 325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#ifdef LIBVPX_TEST_DATA_PATH 335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // In some environments, we cannot set environment variables 345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // Instead, we set the data path by using a preprocessor symbol 355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang // which can be set from make files 365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang return STRINGIFY(LIBVPX_TEST_DATA_PATH); 375ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#else 385ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang return "."; 395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#endif 401b362b15af34006e6a11974088a46d42b903418eJohann } 415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang return data_path; 425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang} 431b362b15af34006e6a11974088a46d42b903418eJohann 445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// Undefining stringification macros because they are not used elsewhere 455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#undef TO_STRING 465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#undef STRINGIFY 475ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang 485ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic FILE *OpenTestDataFile(const std::string& file_name) { 495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang const std::string path_to_source = GetDataPath() + "/" + file_name; 501b362b15af34006e6a11974088a46d42b903418eJohann return fopen(path_to_source.c_str(), "rb"); 511b362b15af34006e6a11974088a46d42b903418eJohann} 521b362b15af34006e6a11974088a46d42b903418eJohann 531b362b15af34006e6a11974088a46d42b903418eJohann// Abstract base class for test video sources, which provide a stream of 541b362b15af34006e6a11974088a46d42b903418eJohann// vpx_image_t images with associated timestamps and duration. 551b362b15af34006e6a11974088a46d42b903418eJohannclass VideoSource { 561b362b15af34006e6a11974088a46d42b903418eJohann public: 571b362b15af34006e6a11974088a46d42b903418eJohann virtual ~VideoSource() {} 581b362b15af34006e6a11974088a46d42b903418eJohann 591b362b15af34006e6a11974088a46d42b903418eJohann // Prepare the stream for reading, rewind/open as necessary. 601b362b15af34006e6a11974088a46d42b903418eJohann virtual void Begin() = 0; 611b362b15af34006e6a11974088a46d42b903418eJohann 621b362b15af34006e6a11974088a46d42b903418eJohann // Advance the cursor to the next frame 631b362b15af34006e6a11974088a46d42b903418eJohann virtual void Next() = 0; 641b362b15af34006e6a11974088a46d42b903418eJohann 651b362b15af34006e6a11974088a46d42b903418eJohann // Get the current video frame, or NULL on End-Of-Stream. 661b362b15af34006e6a11974088a46d42b903418eJohann virtual vpx_image_t *img() const = 0; 671b362b15af34006e6a11974088a46d42b903418eJohann 681b362b15af34006e6a11974088a46d42b903418eJohann // Get the presentation timestamp of the current frame. 691b362b15af34006e6a11974088a46d42b903418eJohann virtual vpx_codec_pts_t pts() const = 0; 701b362b15af34006e6a11974088a46d42b903418eJohann 711b362b15af34006e6a11974088a46d42b903418eJohann // Get the current frame's duration 721b362b15af34006e6a11974088a46d42b903418eJohann virtual unsigned long duration() const = 0; 731b362b15af34006e6a11974088a46d42b903418eJohann 741b362b15af34006e6a11974088a46d42b903418eJohann // Get the timebase for the stream 751b362b15af34006e6a11974088a46d42b903418eJohann virtual vpx_rational_t timebase() const = 0; 761b362b15af34006e6a11974088a46d42b903418eJohann 771b362b15af34006e6a11974088a46d42b903418eJohann // Get the current frame counter, starting at 0. 781b362b15af34006e6a11974088a46d42b903418eJohann virtual unsigned int frame() const = 0; 791b362b15af34006e6a11974088a46d42b903418eJohann 801b362b15af34006e6a11974088a46d42b903418eJohann // Get the current file limit. 811b362b15af34006e6a11974088a46d42b903418eJohann virtual unsigned int limit() const = 0; 821b362b15af34006e6a11974088a46d42b903418eJohann}; 831b362b15af34006e6a11974088a46d42b903418eJohann 841b362b15af34006e6a11974088a46d42b903418eJohann 851b362b15af34006e6a11974088a46d42b903418eJohannclass DummyVideoSource : public VideoSource { 861b362b15af34006e6a11974088a46d42b903418eJohann public: 871b362b15af34006e6a11974088a46d42b903418eJohann DummyVideoSource() : img_(NULL), limit_(100), width_(0), height_(0) { 881b362b15af34006e6a11974088a46d42b903418eJohann SetSize(80, 64); 891b362b15af34006e6a11974088a46d42b903418eJohann } 901b362b15af34006e6a11974088a46d42b903418eJohann 911b362b15af34006e6a11974088a46d42b903418eJohann virtual ~DummyVideoSource() { vpx_img_free(img_); } 921b362b15af34006e6a11974088a46d42b903418eJohann 931b362b15af34006e6a11974088a46d42b903418eJohann virtual void Begin() { 941b362b15af34006e6a11974088a46d42b903418eJohann frame_ = 0; 951b362b15af34006e6a11974088a46d42b903418eJohann FillFrame(); 961b362b15af34006e6a11974088a46d42b903418eJohann } 971b362b15af34006e6a11974088a46d42b903418eJohann 981b362b15af34006e6a11974088a46d42b903418eJohann virtual void Next() { 991b362b15af34006e6a11974088a46d42b903418eJohann ++frame_; 1001b362b15af34006e6a11974088a46d42b903418eJohann FillFrame(); 1011b362b15af34006e6a11974088a46d42b903418eJohann } 1021b362b15af34006e6a11974088a46d42b903418eJohann 1031b362b15af34006e6a11974088a46d42b903418eJohann virtual vpx_image_t *img() const { 1041b362b15af34006e6a11974088a46d42b903418eJohann return (frame_ < limit_) ? img_ : NULL; 1051b362b15af34006e6a11974088a46d42b903418eJohann } 1061b362b15af34006e6a11974088a46d42b903418eJohann 1071b362b15af34006e6a11974088a46d42b903418eJohann // Models a stream where Timebase = 1/FPS, so pts == frame. 1081b362b15af34006e6a11974088a46d42b903418eJohann virtual vpx_codec_pts_t pts() const { return frame_; } 1091b362b15af34006e6a11974088a46d42b903418eJohann 1101b362b15af34006e6a11974088a46d42b903418eJohann virtual unsigned long duration() const { return 1; } 1111b362b15af34006e6a11974088a46d42b903418eJohann 1121b362b15af34006e6a11974088a46d42b903418eJohann virtual vpx_rational_t timebase() const { 1131b362b15af34006e6a11974088a46d42b903418eJohann const vpx_rational_t t = {1, 30}; 1141b362b15af34006e6a11974088a46d42b903418eJohann return t; 1151b362b15af34006e6a11974088a46d42b903418eJohann } 1161b362b15af34006e6a11974088a46d42b903418eJohann 1171b362b15af34006e6a11974088a46d42b903418eJohann virtual unsigned int frame() const { return frame_; } 1181b362b15af34006e6a11974088a46d42b903418eJohann 1191b362b15af34006e6a11974088a46d42b903418eJohann virtual unsigned int limit() const { return limit_; } 1201b362b15af34006e6a11974088a46d42b903418eJohann 1211b362b15af34006e6a11974088a46d42b903418eJohann void SetSize(unsigned int width, unsigned int height) { 1221b362b15af34006e6a11974088a46d42b903418eJohann if (width != width_ || height != height_) { 1231b362b15af34006e6a11974088a46d42b903418eJohann vpx_img_free(img_); 1241b362b15af34006e6a11974088a46d42b903418eJohann raw_sz_ = ((width + 31)&~31) * height * 3 / 2; 125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang img_ = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, width, height, 32); 1261b362b15af34006e6a11974088a46d42b903418eJohann width_ = width; 1271b362b15af34006e6a11974088a46d42b903418eJohann height_ = height; 1281b362b15af34006e6a11974088a46d42b903418eJohann } 1291b362b15af34006e6a11974088a46d42b903418eJohann } 1301b362b15af34006e6a11974088a46d42b903418eJohann 1311b362b15af34006e6a11974088a46d42b903418eJohann protected: 1321b362b15af34006e6a11974088a46d42b903418eJohann virtual void FillFrame() { memset(img_->img_data, 0, raw_sz_); } 1331b362b15af34006e6a11974088a46d42b903418eJohann 1341b362b15af34006e6a11974088a46d42b903418eJohann vpx_image_t *img_; 1351b362b15af34006e6a11974088a46d42b903418eJohann size_t raw_sz_; 1361b362b15af34006e6a11974088a46d42b903418eJohann unsigned int limit_; 1371b362b15af34006e6a11974088a46d42b903418eJohann unsigned int frame_; 1381b362b15af34006e6a11974088a46d42b903418eJohann unsigned int width_; 1391b362b15af34006e6a11974088a46d42b903418eJohann unsigned int height_; 1401b362b15af34006e6a11974088a46d42b903418eJohann}; 1411b362b15af34006e6a11974088a46d42b903418eJohann 1421b362b15af34006e6a11974088a46d42b903418eJohann 1431b362b15af34006e6a11974088a46d42b903418eJohannclass RandomVideoSource : public DummyVideoSource { 1441b362b15af34006e6a11974088a46d42b903418eJohann public: 1451b362b15af34006e6a11974088a46d42b903418eJohann RandomVideoSource(int seed = ACMRandom::DeterministicSeed()) 1461b362b15af34006e6a11974088a46d42b903418eJohann : rnd_(seed), 1471b362b15af34006e6a11974088a46d42b903418eJohann seed_(seed) { } 1481b362b15af34006e6a11974088a46d42b903418eJohann 1491b362b15af34006e6a11974088a46d42b903418eJohann protected: 1501b362b15af34006e6a11974088a46d42b903418eJohann // Reset the RNG to get a matching stream for the second pass 1511b362b15af34006e6a11974088a46d42b903418eJohann virtual void Begin() { 1521b362b15af34006e6a11974088a46d42b903418eJohann frame_ = 0; 1531b362b15af34006e6a11974088a46d42b903418eJohann rnd_.Reset(seed_); 1541b362b15af34006e6a11974088a46d42b903418eJohann FillFrame(); 1551b362b15af34006e6a11974088a46d42b903418eJohann } 1561b362b15af34006e6a11974088a46d42b903418eJohann 1571b362b15af34006e6a11974088a46d42b903418eJohann // 15 frames of noise, followed by 15 static frames. Reset to 0 rather 1581b362b15af34006e6a11974088a46d42b903418eJohann // than holding previous frames to encourage keyframes to be thrown. 1591b362b15af34006e6a11974088a46d42b903418eJohann virtual void FillFrame() { 1601b362b15af34006e6a11974088a46d42b903418eJohann if (frame_ % 30 < 15) 1611b362b15af34006e6a11974088a46d42b903418eJohann for (size_t i = 0; i < raw_sz_; ++i) 1621b362b15af34006e6a11974088a46d42b903418eJohann img_->img_data[i] = rnd_.Rand8(); 1631b362b15af34006e6a11974088a46d42b903418eJohann else 1641b362b15af34006e6a11974088a46d42b903418eJohann memset(img_->img_data, 0, raw_sz_); 1651b362b15af34006e6a11974088a46d42b903418eJohann } 1661b362b15af34006e6a11974088a46d42b903418eJohann 1671b362b15af34006e6a11974088a46d42b903418eJohann ACMRandom rnd_; 1681b362b15af34006e6a11974088a46d42b903418eJohann int seed_; 1691b362b15af34006e6a11974088a46d42b903418eJohann}; 1701b362b15af34006e6a11974088a46d42b903418eJohann 1711b362b15af34006e6a11974088a46d42b903418eJohann// Abstract base class for test video sources, which provide a stream of 1721b362b15af34006e6a11974088a46d42b903418eJohann// decompressed images to the decoder. 1731b362b15af34006e6a11974088a46d42b903418eJohannclass CompressedVideoSource { 1741b362b15af34006e6a11974088a46d42b903418eJohann public: 1751b362b15af34006e6a11974088a46d42b903418eJohann virtual ~CompressedVideoSource() {} 1761b362b15af34006e6a11974088a46d42b903418eJohann 1771b362b15af34006e6a11974088a46d42b903418eJohann virtual void Init() = 0; 1781b362b15af34006e6a11974088a46d42b903418eJohann 1791b362b15af34006e6a11974088a46d42b903418eJohann // Prepare the stream for reading, rewind/open as necessary. 1801b362b15af34006e6a11974088a46d42b903418eJohann virtual void Begin() = 0; 1811b362b15af34006e6a11974088a46d42b903418eJohann 1821b362b15af34006e6a11974088a46d42b903418eJohann // Advance the cursor to the next frame 1831b362b15af34006e6a11974088a46d42b903418eJohann virtual void Next() = 0; 1841b362b15af34006e6a11974088a46d42b903418eJohann 1851b362b15af34006e6a11974088a46d42b903418eJohann virtual const uint8_t *cxdata() const = 0; 1861b362b15af34006e6a11974088a46d42b903418eJohann 187b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian virtual size_t frame_size() const = 0; 1881b362b15af34006e6a11974088a46d42b903418eJohann 189b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian virtual unsigned int frame_number() const = 0; 1901b362b15af34006e6a11974088a46d42b903418eJohann}; 1911b362b15af34006e6a11974088a46d42b903418eJohann 1921b362b15af34006e6a11974088a46d42b903418eJohann} // namespace libvpx_test 1931b362b15af34006e6a11974088a46d42b903418eJohann 1941b362b15af34006e6a11974088a46d42b903418eJohann#endif // TEST_VIDEO_SOURCE_H_ 195